随笔 - 7, 文章 - 3, 评论 - 22, 引用 - 0

导航

<2008年12月>
30123456
78910111213
14151617181920
21222324252627
28293031123
45678910

留言簿(0)

随笔档案

文章档案

搜索

最新评论

阅读排行榜

评论排行榜

2008年9月10日

关于c 实现 c++的多态性

 今天论坛上有人在问,如何用c 实现c++的继承, 我告诉他是结构加指针实现,虽然表达简单,但的确需要这两样东西,
    另外感觉继承主要好处就是实现多态性,那用c实现了多态性,估计也就用到了继承的优点
 以前是在vc编程难点剖析一书里看到过用c实现多态性的的方法,说到这本书还是要表扬一下的,vc编程难点剖析这本书写得很不错的,那时在新风雨,打5折买的,看来好东西,不一定价高,那本书的源码很简单,如下:
#include "stdio.h"
#include "stdlib.h"

//定义函数指针类型DISPLAYINTEGER,指向返回值为void,参数列表为(const int)的函数
typedef  void( *DISPLAYINTEGER)(const int);

//定义函数,将数字以十进制形式输出,该函数类型与DISPLAYINTEGER匹配
void DisplayDecimal(const int Number)
{
 printf("The decimal value is %d\n",Number);
}
//定义函数,将数字以八进制形式输出,该函数类型与DISPLAYINTEGER匹配
void DisplayOctal(const int Number)
{
 printf("The octal value is %o\n",Number);
}
//定义函数,将数字以十六进制形式输出,该函数类型与DISPLAYINTEGER匹配
void DisplayHexadecimal (const int Number)
{
 printf("The hexadecimal value is %x\n",Number);
}
/********************************************************************
定义通用的显示数字函数
DisplayFormat  DISPLAYINTEGER函数指针类型,实参可以是以上定义的
      三个函数之一。通过传递不同的实参,将数字以各种格式输出。
Number        准备输出的数字
********************************************************************/
void DisplayNumber(DISPLAYINTEGER  DisplayFormat,const int Number)
{
  //调用以实参传入的函数,以某种格式输出整型数字
 DisplayFormat(Number);
}

int main(int argc, char* argv[])
{
 int Number=0;

// 如果有数字形式的命令行参数,将其输出,否则输出0
   if(argc>1)  
        Number=atoi(argv[1]);
   //分别以三种格式将数字输出
 DisplayNumber(DisplayDecimal,Number);
    DisplayNumber(DisplayOctal,Number);
    DisplayNumber(DisplayHexadecimal,Number);

 return 0;
}
看起来通俗易懂,不过没有继承 的感觉

以前还在其他地方看到过类似c 实现继承的代码
下午我就简化了一段代码,并且编译执行了下,来实现c 的所谓继承,代码如下:
1.parent.h
#ifndef PARENT_H
#define PARENT_H

#include "child1.h"
#include "child2.h"


struct parent_type{
   unsigned int id;
   //char classname[20];
   char * name;
   struct{
     struct parent_handle * (*init)(void * pvoid);
     int (*fp1)(struct parent_handle *ph);
     //...
   }pfn;
   struct parent_type *next;
};


struct parent_handle{
    int i;
    union{
      struct child1_handle child_hdl1;
      struct child2_handle child_hdl2;
      //...
    }priv;
    struct parent_type *ptp;
};

2.parent.h

#include "stdafx.h"

#include "parent.h"

static struct parent_type *class_list;

int register_child(struct parent_type *p)
{
 p->next = class_list;
 class_list = p;
 return 0;
}

struct parent_handle * parent_init(void * pchild_priv, unsigned int id)
{
 struct parent_type *p;

 for (p = class_list; p; p = p->next)
  if (p->id == id)
   return p->pfn.init(pchild_priv);

 printf("unable to find matching child class\n");
 return NULL;
}

int parent_fp1(struct parent_handle *ph)
{
 if (!ph->ptp->pfn.fp1)
  return 0;

 return ph->ptp->pfn.fp1(ph);
}


int register_child(struct parent_type *p);

struct parent_handle * parent_init(void * pchild_priv, unsigned int id);

int parent_fp1(struct parent_handle *ph);


#endif

3. child1.h
#ifndef CHILD1_H
#define CHILD1_H

#define CHILD_1_ID 101

struct child1_handle
{
  char child1_decr[20];
  int  child1_data;
  //...
};

extern struct parent_type child_tp1;

struct parent_handle * child1_init(void * pvoid);
int child1_fp1(struct parent_handle *ph);

#endif

4.child1.c
#include "stdafx.h"

#include "parent.h"
#include "child1.h"


struct parent_type child_tp1= {CHILD_1_ID,"class child1",{&child1_init,&child1_fp1},0};
/*
struct parent_type  child1= {
 .id = CHILD_1_ID,
 .name  = "class child1",
 .fn = {
  .init   = &child1_init,
  .fp1   = &child1_fp1,
 },
};
*/


struct parent_handle * child1_init(void * pvoid)
{
 //int ret;
 struct child1_handle *h;
 struct parent_handle *ph = (struct parent_handle *)malloc(sizeof(struct parent_handle/* *h */));
 if (!ph)
  return NULL;
 ph->ptp = &child_tp1;

     //todo
  h = &ph->priv.child_hdl1;
  strcpy(h->child1_decr,"hello child1!");
  h->child1_data=*((int*)(pvoid));
     //...
 return ph;
}


int child1_fp1(struct parent_handle *ph)
{
  struct child1_handle *h = &ph->priv.child_hdl1;
  //todo
  printf("%s,data=%d\r\n",h->child1_decr,h->child1_data);
  //...

  return 0;
}

5.child2.h

#ifndef CHILD2_H
#define CHILD2_H


#define CHILD_2_ID 102

struct child2_handle
{
  int  child2_data;
  char child2_decr[20];
  //...
};

extern struct parent_type child_tp2;

int child2_fp1(struct parent_handle *ph);
struct parent_handle * child2_init(void * pvoid);

#endif

6.child2.c
#include "stdafx.h"

#include "parent.h"
#include "child2.h"


struct parent_type child_tp2= {CHILD_2_ID,"class child2",{&child2_init,&child2_fp1},0};
/*
struct parent_type  child1= {
 .id = CHILD_1_ID,
 .name  = "class child1",
 .fn = {
  .init   = &child1_init,
  .fp1   = &child1_fp1,
 },
};
*/


struct parent_handle * child2_init(void * pvoid)
{
 //int ret;
 struct child2_handle *h;
 struct parent_handle *ph = (struct parent_handle *)malloc(sizeof(struct parent_handle/* *h */));  //别忘了自己加deinit 把它释放
 if (!ph)
  return NULL;
 ph->ptp = &child_tp2;

     //todo
  h = &ph->priv.child_hdl2;
  strcpy(h->child2_decr,"hello child2!");
  h->child2_data=*((int*)(pvoid));
     //...
 return ph;
}


int child2_fp1(struct parent_handle *ph)
{
  struct child2_handle *h = &ph->priv.child_hdl2;

  //todo
  printf("%s,data=%d\r\n",h->child2_decr,h->child2_data);
  //...

  return 0;
}

最后是main.c

// testClass.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"

#include "parent.h"
#include "child1.h"
#include "child2.h"

static struct parent_handle *pchild_1_h,*pchild_2_h;

int main(int argc, char* argv[])
{
 //printf("Hello World!\n");
   int child1_priv=123;
   int child2_priv=456;
   register_child(&child_tp1);                 //注册子类1
   pchild_1_h = parent_init((void *)(&child1_priv),CHILD_1_ID);      //初始化子类1
   if(pchild_1_h)
     parent_fp1(pchild_1_h);                     //执行子类1的fp1函数

   register_child(&child_tp2);                 //注册子类2
   pchild_2_h = parent_init((void *)(&child2_priv),CHILD_2_ID);      //初始化子类2
   parent_fp1(pchild_2_h);                     //执行子类2的fp1函数
 return 0;
}

 

/*
用c++实现很简单
class parent
{
    virturl int fp1 ();
}

 class child1 :public parent
 {
    char child1_decr[20];
    int  child1_data;
     int fp1 ();

 }

 class child2 :public parent
 {
    char child2_decr[20];
    int  child2_data;
     int fp1 ();

 }


  parent * pa;
  child1 ch1b;
  
   pa= ch1b;

   pa->fp1;

*/

用c实现一些类似c++的功能还是有好处的,一方面多重继承开销大,而且在底层编程,c 用得比较多,所以总结了下,以后可能有点用

发表于 2008-09-10 23:05 liu090 阅读(925) | 评论 (5)编辑 收藏

2008年8月6日

根据extid 获得nandflash 的一些属性

2.6.14 内核MTD 中关于获得nand flash 的一些属性的方法:

设置READID 命令后开始读ID
1.读ID 第1byte
 maker_id = =read_byte;
2.读ID 第2byte
  device_id =read_byte;
3.读ID 第3byte
  cellinfo = read_byte;
4.读ID 第4byte
  extid = read_byte;

 根据该扩展id可计算
    1.page 大小:
 page_size = 1024 << (extid & 0x3);
    2. spare 大小: 
 extid >>= 2;
 spare_size = (8 << (extid & 0x01)) * (page_size  >> 9);
    3. block 大小: 
 extid >>= 2;
 block_size = (64 * 1024) << (extid & 0x03);
    4.bus width:
 extid >>= 2;
 bus width = (extid & 0x01) ? 16bit: 8bit;

发表于 2008-08-06 13:34 liu090 阅读(828) | 评论 (1)编辑 收藏

2007年12月18日

在cygwin下调试uboot-1.1.6 碰到的问题

为了方便,使用cygwin环境进行交叉编译uboot,所以又要做tool chain,搞了个ezx cross tool 的东西,来做.
因为网上有人说uboot.1.1.6用2.95的tool chain好象不行,就决定用3.3.6的tool chain,开始挺顺利的,大概
4-5小时编译后,居然没报什么错误,生成了3.3.6的arm tool chain,

然后开始用tool chain 编译改好的uboot,到ld时报错:
libgcc.a(udivdi3.oS) uses VFP instructions ,where as uboot does not 的错误

网上查了下,有位兄弟报的use hard fpa instrucitons ,where as  uboot does not

跟我差不多, 但有区别,他的是libgcc 的浮点库是使用hard fpa,而uboot不支持
我的是libgcc 的浮点库是使用 vfp,而uboot不支持,
其实uboot cpu/arm920t/config.mk中 定义的是msoft-fpa 就是说只支持软件浮点的
我看了ezx cross tool 下面关于浮点的设置文件arm-ezx.dat里面
GCC_EXTRA_CONFIG="--with-cpu=arm9tdmi --enable-cxx-flags=-mcpu=arm9tdmi --with-float=soft"
GLIBC_EXTRA_CONFIG="--without-fp"
的确是设置了soft fpa的选择,那为什么还会使用vfp,比较郁闷

后来查了gcc 的patch 文件,里面有部分关于VFP的patch
难道是patch 打错了,于是我就不对gcc 打patch ,
然后进行编译,哎又是4个多小时,其实前面没方向时已经又build 了好几次,一天也就能试验
两三次,这次编译好后,用来进行uboot 编译,居然报use hard fpa instrucitons ,where as  uboot does not
跟网上 那位兄弟一样的错误,不知道那位兄弟后来搞定了没有,可能他用的tool chain 的gcc是没打
fpu 的patch 引起的,对这样情况,网上到是有解决方法,就是把cpu/arm920t/config.mk中msoft-fpa的flag去掉,我试验了下也可以,但是我觉得这样不太好,
于是我有把gcc 3.3.6的patch 拿出来又看了下,我把有vfp相关的path 部分都换成soft-fpa ,
然后不说也知道,又是4个多小时,终于好了,这已经离第一发生该错误,有两天多时间了,这两天基本没做什么,就和tool chain 搅上了,与是用它来build uboot 1.1.6,这次终于成功了

把成功的经验贴出大家共享下,希望大家在搞embed linux 第1步,做交叉编译工具时,能顺利点,
另外如果,有linux 的环境,就用别人已经做好的tool chain,这样问题会少一点,
共享一个,比较新的arm tool chain 的网站:
http://www.freaknet.org/martin/crosstool/packages/


另外如果有什么更好的解决该问题的方法,请告诉我,谢谢

发表于 2007-12-18 19:35 liu090 阅读(1555) | 评论 (10)编辑 收藏

2007年7月5日

xip 的 bin 文件分析

xip 的 bin 文件分析
   
 
 一个bin 文件在存储上是按下面的结构存储的

     组成:标记(7)+Image开始地址(1)+Image长度(1) 
           记录0地址+记录0长+记录0校验和+记录0内容(文件内容)
        记录1地址+记录1长+记录1校验和+记录1内容(文件内容)
           ......
     最后一条记录是表示结束,Start = 0x00000000, Length = 0x8C072C3C是StartUp地址, Chksum = 0x00000000

     bin 文件的头部(不包括记录)可以用下面的结构表示
      struct BinFile{
                  BYTE signature[7]; // = { ''B'', ''0'', ''0'', ''0'', ''F'', ''F'', ''\a'' }
                  DWORD ImageStart
                  DWORD ImageLength
            };


一般xipkernel.bin,nk.bin 都符合正常bin文件格式,包含记录开始0,1,2 记录为特殊记录,2做为cece的标记,其后4byte表示 TOC地址(指向ROMHDR结构的数据),3记录开始都是文件记录,
  比如coredll.dll等等。。。

//---------------------------------------------------------------------------------------------------------------------------------------------------------------
  比如nk.bin 文件的viewbin 查看的内容:
//---------------------------------------------------------------------------------------------------------------------------------------------------------------
  ViewBin... nk.bin
Image Start = 0x8C201000, length = 0x00DE9910
Record [  0] : Start = 0x8C201000, Length = 0x00000040, Chksum = 0x00001A63         //->注意这里就是对应到结构struct Record{DWORD recaddress; DWORD reclength; DWORD chksum;void * recdata}的内容
 0x8C201000 : 4083F601 8096F601 3C18F801 64D7F901 @.......<...d...
 0x8C201010 : D025F701 0C85F601 6C26F701 C488F901 .%......l&......
 0x8C201020 : 10B6F601 0C85F601 5830F601 E086F901 ........X0......
 0x8C201030 : 2074F601 67776573 2E657865 00000000  t..gwes.exe....

 Chksum valid
Record [  1] : Start = 0x8C201040, Length = 0x00000008, Chksum = 0x0000032D
 0x8C201040 : 45434543 048FFE8C                   ECEC....                          //这里ECEC是我们设置的#define ROM_SIGNATURE 0x43454345 (Romldr.h),后面4byte就是pToc的内容

 Chksum valid
Record [  2] : Start = 0x8C201048, Length = 0x00000004, Chksum = 0x00000161
 0x8C201048 : 047FDE00                            ....            

 Chksum valid
Record [  3] : Start = 0x8C202000, Length = 0x000A37BC, Chksum = 0x043BF7FA
 0x8C202000 : 00000000 03407546 00000000 02000000 .....@uF........
 0x8C202010 : 78000000 D8530000 D8470000 20100100 x....S...G.. ...
 0x8C202020 : 53005900 53005400 45004D00 2F004700 S.Y.S.T.E.M./.G.

 。。。。。。

  Chksum valid
Record [131] : Start = 0x00000000, Length = 0x00000000, Chksum = 0x00000000
  Start address = 0x00000000
Checking record #129 for potential TOC (ROMOFFSET = 0x00000000)   
Found pTOC  = 0x8cfe8f04
ROMOFFSET = 0x00000000


//---------------------------------------------------------------------------------------------------------------------------------------------------------------
 xipkernel.bin viewbin 的内容:
//---------------------------------------------------------------------------------------------------------------------------------------------------------------
 ViewBin... xipkernel.bin
Image Start = 0x8C000000, length = 0x001BCE90
Record [  0] : Start = 0x8C000000, Length = 0x00000004, Chksum = 0x000001C3
 0x8C000000 : 0DCB01EA                            ....            

 Chksum valid
Record [  1] : Start = 0x8C000040, Length = 0x00000008, Chksum = 0x00000327
 0x8C000040 : 45434543 A0DA118C                   ECEC....                          //注意这里的A0DA118C 就是8C11DAF4  指向record9 就是pToc的值

 Chksum valid
Record [  2] : Start = 0x8C000048, Length = 0x00000004, Chksum = 0x0000018B
 0x8C000048 : A0DA1100                            ....            

 Chksum valid
Record [  3] : Start = 0x8C001000, Length = 0x000C5180, Chksum = 0x064E2C03
 0x8C001000 : 00000000 96F37746 00000000 02000000 ......wF........
 0x8C001010 : 55000000 DC2B0700 DC1F0700 41504953 U....+......APIS
 0x8C001020 : 02060500 3010008C 00000000 00000000 ....0...........
 0x8C001030 : B05A078C 7CA3078C 505B078C 0C5D078C .Z..|...P[...]..
 0x8C001040 : 745D078C 00000000 08000000 41005200 t]..........A.R.
 。。。。。。
 0x8C072C30 : 00000000 73746172 740A0D00 060000EA ....start.......                  //###################
 0x8C072C40 : FDFFFFEA FCFFFFEA FBFFFFEA FAFFFFEA ................

 
 。。。。。。

 Chksum valid
Record [  9] : Start = 0x8C11DAA0, Length = 0x00000054, Chksum = 0x00000CB3         //就是上面的pToc所指块,是一个ROMHDR结构
 0x8C11DAA0 : FF01F501 00000002 0000008C 90CE1B8C ................
 0x8C11DAB0 : 08000000 0010208C 0000278C 00E0E68F ...... ...'.....
 0x8C11DAC0 : 01000000 F0FF1A8C 00000000 00000000 ................
 0x8C11DAD0 : 05000000 00000000 10101010 00000000 ................
 0x8C11DAE0 : 00000000 C2010200 1022008C 00000000 ........."......
 0x8C11DAF0 : 00000000                            ....            

 Chksum valid
Record [ 10] : Start = 0x8C11DAF4, Length = 0x0000018C, Chksum = 0x0000895E
 0x8C11DAF4 : 07000000 005C33FC 84B2C701 00BE0C00 .....\3.........
 0x8C11DB04 : D4BF118C CCDE0F8C 3CDF0F8C 0000008C ........<.......
 0x8C11DB14 : 07000000 00A1CC46 EAB0C701 00600300 .......F.....`..
 0x8C11DB24 : DCBF118C 6CFD1A8C 9CDF0F8C 00F0128C ....l...........
 0x8C11DB34 : 07100000 0052626B C5B0C701 00380100 .....Rbk.....8..
 0x8C11DB44 : E8BF118C DCFD1A8C 4CFE1A8C 0020178C ........L.... ..

。。。。。。

 Chksum valid
Record [ 14] : Start = 0x00000000, Length = 0x8C072C3C, Chksum = 0x00000000      //这就是xipkernel.bin的最后一条记录其内容表示0x8C072C3C 是startup 的入口地址 //################### 那行就是
  Start address = 0x8C072C3C                                               //060000EA=>EA000060  的一条跳转指令 (1110[cond always] +1010[branch]+offset)
Checking record #9 for potential TOC (ROMOFFSET = 0x00000000)
Found pTOC  = 0x8c11daa0
ROMOFFSET = 0x00000000
Done.

 

//---------------------------------------------------------------------------------------------------------------------------------------------------------------
 xip.bin viewbin 的内容: 是上面两个bin的结合
//---------------------------------------------------------------------------------------------------------------------------------------------------------------
ViewBin... xip.bin
Image Start = 0x8C000000, length = 0x00FEA910
   Start address = 0x8C072C3C
Checking record #9 for potential TOC (ROMOFFSET = 0x00000000)
Found pTOC  = 0x8c11daa0
ROMOFFSET = 0x00000000

Checking record #9 for potential TOC (ROMOFFSET = 0xFF134B9C)   //-》FF134B9C-》ECB464 =14m多??????
Checking record #144 for potential TOC (ROMOFFSET = 0x00000000)
Found pTOC  = 0x8cfe8f04
ROMOFFSET = 0x00000000


//---------------------------------------------------------------------------------------------------------------------------------------------------------------
 chain.bin viewbin 的内容: 是上面两个bin的结合
//---------------------------------------------------------------------------------------------------------------------------------------------------------------
ViewBin... chain.bin 
Image Start = 0x8C200000, length = 0x00000528
Record [  0] : Start = 0x8C200000, Length = 0x00000528, Chksum = 0x0000084B
 0x8C200000 : 02000000 0000008C 90CE1B00 00002000 .............. .   //填充xipkernel部分的_XIPCHAIN_ENTRY 的内容
 0x8C200010 : 01000100 00000000 5849504B 45524E45 ........XIPKERNE
 0x8C200020 : 4C000000 00000000 00000000 00000000 L...............
 0x8C200030 : 00000000 00000000 00000000 00000000 ................
 0x8C200040 : 00000000 00000000 00000000 00000000 ................
 0x8C200050 : 00000000 00000000 00000000 00000000 ................
 0x8C200060 : 00000000 00000000 00000000 00000000 ................
 0x8C200070 : 00000000 00000000 00000000 00000000 ................
 0x8C200080 : 00000000 00000000 00000000 00000000 ................
 0x8C200090 : 00000000 00000000 00000000 00000000 ................
 0x8C2000A0 : 00000000 00000000 00000000 00000000 ................
 0x8C2000B0 : 00000000 00000000 00000000 00000000 ................
 0x8C2000C0 : 00000000 00000000 00000000 00000000 ................
 0x8C2000D0 : 00000000 00000000 00000000 00000000 ................
 0x8C2000E0 : 00000000 00000000 00000000 00000000 ................
 0x8C2000F0 : 00000000 00000000 00000000 00000000 ................
 0x8C200100 : 00000000 00000000 00000000 00000000 ................
 0x8C200110 : 00000000 00000000 00000000 00000000 ................
 0x8C200120 : 00000000 00000000 00000000 00000000 ................
 0x8C200130 : 00000000 00000000 00000000 00000000 ................
 0x8C200140 : 00000000 00000000 00000000 00000000 ................
 0x8C200150 : 00000000 00000000 00000000 00000000 ................
 0x8C200160 : 00000000 00000000 00000000 00000000 ................
 0x8C200170 : 00000000 00000000 00000000 00000000 ................
 0x8C200180 : 00000000 00000000 00000000 00000000 ................
 0x8C200190 : 00000000 00000000 00000000 00000000 ................
 0x8C2001A0 : 00000000 00000000 00000000 00000000 ................
 0x8C2001B0 : 00000000 00000000 00000000 00000000 ................
 0x8C2001C0 : 00000000 00000000 00000000 00000000 ................
 0x8C2001D0 : 00000000 00000000 00000000 00000000 ................
 0x8C2001E0 : 00000000 00000000 00000000 00000000 ................
 0x8C2001F0 : 00000000 00000000 00000000 00000000 ................
 0x8C200200 : 00000000 00000000 00000000 00000000 ................
 0x8C200210 : 00000000 00000000 00000000 00000000 ................
 0x8C200220 : 00000000 00000000 00000000 00000000 ................
 0x8C200230 : 00000000 00000000 00000000 00000000 ................
 0x8C200240 : 00000000 00000000 00000000 00000000 ................
 0x8C200250 : 00000000 00000000 00000000 00000000 ................
 0x8C200260 : 00000000 00000000 00000000 00000000 ................
 0x8C200270 : 00000000 00000000 00000000 00000000 ................
 0x8C200280 : 00000000 00000000 00000000 00000000 ................
 0x8C200290 : 00000000 0010208C 1099DE00 00009001 ...... .........   //0010208C 开始就是 填充nk部分的_XIPCHAIN_ENTRY 的内容
 0x8C2002A0 : 02000100 00000000 4E4B0000 00000000 ........NK......
 0x8C2002B0 : 00000000 00000000 00000000 00000000 ................
 0x8C2002C0 : 00000000 00000000 00000000 00000000 ................
 0x8C2002D0 : 00000000 00000000 00000000 00000000 ................
 0x8C2002E0 : 00000000 00000000 00000000 00000000 ................
 0x8C2002F0 : 00000000 00000000 00000000 00000000 ................
 0x8C200300 : 00000000 00000000 00000000 00000000 ................
 0x8C200310 : 00000000 00000000 00000000 00000000 ................
 0x8C200320 : 00000000 00000000 00000000 00000000 ................
 0x8C200330 : 00000000 00000000 00000000 00000000 ................
 0x8C200340 : 00000000 00000000 00000000 00000000 ................
 0x8C200350 : 00000000 00000000 00000000 00000000 ................
 0x8C200360 : 00000000 00000000 00000000 00000000 ................
 0x8C200370 : 00000000 00000000 00000000 00000000 ................
 0x8C200380 : 00000000 00000000 00000000 00000000 ................
 0x8C200390 : 00000000 00000000 00000000 00000000 ................
 0x8C2003A0 : 00000000 00000000 00000000 00000000 ................
 0x8C2003B0 : 00000000 00000000 00000000 00000000 ................
 0x8C2003C0 : 00000000 00000000 00000000 00000000 ................
 0x8C2003D0 : 00000000 00000000 00000000 00000000 ................
 0x8C2003E0 : 00000000 00000000 00000000 00000000 ................
 0x8C2003F0 : 00000000 00000000 00000000 00000000 ................
 0x8C200400 : 00000000 00000000 00000000 00000000 ................
 0x8C200410 : 00000000 00000000 00000000 00000000 ................
 0x8C200420 : 00000000 00000000 00000000 00000000 ................
 0x8C200430 : 00000000 00000000 00000000 00000000 ................
 0x8C200440 : 00000000 00000000 00000000 00000000 ................
 0x8C200450 : 00000000 00000000 00000000 00000000 ................
 0x8C200460 : 00000000 00000000 00000000 00000000 ................
 0x8C200470 : 00000000 00000000 00000000 00000000 ................
 0x8C200480 : 00000000 00000000 00000000 00000000 ................
 0x8C200490 : 00000000 00000000 00000000 00000000 ................
 0x8C2004A0 : 00000000 00000000 00000000 00000000 ................
 0x8C2004B0 : 00000000 00000000 00000000 00000000 ................
 0x8C2004C0 : 00000000 00000000 00000000 00000000 ................
 0x8C2004D0 : 00000000 00000000 00000000 00000000 ................
 0x8C2004E0 : 00000000 00000000 00000000 00000000 ................
 0x8C2004F0 : 00000000 00000000 00000000 00000000 ................
 0x8C200500 : 00000000 00000000 00000000 00000000 ................
 0x8C200510 : 00000000 00000000 00000000 00000000 ................
 0x8C200520 : 00000000 00000000                   ........        

 Chksum valid
Record [  1] : Start = 0x00000000, Length = 0x00000000, Chksum = 0x00000000
  Start address = 0x00000000
只有1条有效记录,一条记录分成两部分对应xipkernel.bin 和nk.bin,使用结构
typedef struct _XIPCHAIN_ENTRY {
    LPVOID  pvAddr;                 // address of the XIP       // 根据这个地址可以找到pToc!!!!!!
    DWORD   dwLength;               // the size of the XIP
    DWORD   dwMaxLength;            // the biggest it can grow to
    USHORT  usOrder;                // where to put into ROMChain_t
    USHORT  usFlags;                // flags/status of XIP
    DWORD   dwVersion;              // version info
    CHAR    szName[XIP_NAMELEN];    // Name of XIP, typically the bin file's name, w/o .bin
    DWORD   dwAlgoFlags;            // algorithm to use for signature verification
    DWORD   dwKeyLen;               // length of key in byPublicKey
    BYTE    byPublicKey[596];       // public key data
} XIPCHAIN_ENTRY, *PXIPCHAIN_ENTRY;

 

 

//其他相关结构:
typedef struct ROMHDR {
    ULONG   dllfirst;               // first DLL address
    ULONG   dlllast;                // last DLL address
    ULONG   physfirst;              // first physical address
    ULONG   physlast;               // highest physical address
    ULONG   nummods;                // number of TOCentry's
    ULONG   ulRAMStart;             // start of RAM
    ULONG   ulRAMFree;              // start of RAM free space
    ULONG   ulRAMEnd;               // end of RAM
    ULONG   ulCopyEntries;          // number of copy section entries
    ULONG   ulCopyOffset;           // offset to copy section
    ULONG   ulProfileLen;           // length of PROFentries RAM
    ULONG   ulProfileOffset;        // offset to PROFentries
    ULONG   numfiles;               // number of FILES
    ULONG   ulKernelFlags;          // optional kernel flags from ROMFLAGS .bib config option
    ULONG   ulFSRamPercent;         // Percentage of RAM used for filesystem
                                        // from FSRAMPERCENT .bib config option
                                        // byte 0 = #4K chunks/Mbyte of RAM for filesystem 0-2Mbytes 0-255
                                        // byte 1 = #4K chunks/Mbyte of RAM for filesystem 2-4Mbytes 0-255
                                        // byte 2 = #4K chunks/Mbyte of RAM for filesystem 4-6Mbytes 0-255
                                        // byte 3 = #4K chunks/Mbyte of RAM for filesystem > 6Mbytes 0-255

    ULONG   ulDrivglobStart;        // device driver global starting address
    ULONG   ulDrivglobLen;          // device driver global length
    USHORT  usCPUType;              // CPU (machine) Type
    USHORT  usMiscFlags;            // Miscellaneous flags
    PVOID   pExtensions;            // pointer to ROM Header extensions
    ULONG   ulTrackingStart;        // tracking memory starting address
    ULONG   ulTrackingLen;          // tracking memory ending address
} ROMHDR;

发表于 2007-07-05 22:36 liu090 阅读(2477) | 评论 (3)编辑 收藏

2007年5月22日

关于mult-xip bin 的一些资料整理

关于mult-xip  bin 的一些资料整理
参考  http://www.cnblogs.com/yakin/archive/2005/07/20/196572.aspx
      http://msdn2.microsoft.com/en-us/library/aa451015.aspx
   http://embed.e800.com.cn/articles/2007/510/1178760966833421250_1.html


一.实现multbin
1.首先修改config.bib

 比如:
 #elif defined IMGMULTIBIN
;  NAME           START ADDR    SIZE       TYPE
;  ----------------------------------------------------------------
    NK            80220000      007DE000   RAMIMAGE  
    SHELL         809FE000      00100000   RAMIMAGE  
    APPS          80AFE000      00100000   RAMIMAGE  
    CHAIN         80BFE000      00002000   RESERVED ; XIP chain info
    RAM           80C00000      01000000   RAM       
    pdwXIPLoc     00000000      80BFE000   FIXUPVAR   ; XIP pTOC

    AUTOSIZE=ON           ;自动调整RAM 起始地址到 最近的 XIP region的末尾
    ROM_AUTOSIZE=ON       ;每个分隔的XIP regin 的大小自动调整
    DLLADDR_AUTOSIZE=ON   ;自动调整 dll地址空间大小根据 multiple XIP regions.
    XIPSCHAIN=80bfe000     ; 指定CHAIN region 在内存段的地址.
Note   This address is applicable for the example provided in the previous step of this procedure.
If you use a customized address for the CHAIN region or a different BSP, you will have to
update this variable to match your settings

 

pdwXIPLoc 必须定义START ADDR =00000000 SIZE=CHAIN的START ADDR
CHAIN 用来保存多个bin的chain info,CHAIN的位置和你bootloader代码有关,(cepc一般放在 NK region 后面)
所有的RAMIMAGE 必须在物理,虚拟地址上都连续
经验上每个bin 加32K (msdn:As a good practice, add the sizes of all files for a given region,
and then add an extra 32K as a buffer. Adding this extra amount provides room for the files to
reduce and expand as they change between each successive build)


2.修改platform.bib,把不同的部分放入到不动的region中 (其他bib也可以修改的)
比如
if IMGMULTIBIN
   shell.exe   $(_FLATRELEASEDIR)\shell.exe   SHELL   SH
   filesys.exe $(_FLATRELEASEDIR)\filesys.exe SHELL   SH
#else
   shell.exe   $(_FLATRELEASEDIR)\shell.exe   NK  SH
   filesys.exe $(_FLATRELEASEDIR)\filesys.exe NK  SH
#endif

表示把文件系统, shell放到 SHELL regin (shell.bin)


3.设置: 环境变量IMGMULTIBIN =1


4.在cfw.c中的OEMInit中的最后加上对InitRomChain的调用,来连接各个bin,最后连接到OEMRomChain 上!!!

void InitRomChain(void)
{
 static  ROMChain_t s_pNextRom[MAX_ROM] = {0};
 DWORD  dwRomCount = 0;
    DWORD       dwChainCount = 0;
    DWORD  *pdwCurXIP;
    DWORD       dwNumXIPs;
    PXIPCHAIN_ENTRY pChainEntry = NULL;

    if(pdwXIPLoc == NOT_FIXEDUP)
 {
        return;  //pdwXIPLoc 必须是 FIXUPVAR ,否则表示没有chain或者设置不对
    }

    // set the top bit to mark it as a virtual address
    pdwCurXIP = (DWORD*)(((DWORD)pdwXIPLoc) | 0x80000000);

    // first DWORD is number of XIPs
    dwNumXIPs = (*pdwCurXIP);  

    if(dwNumXIPs > MAX_ROM)
 {
      lpWriteDebugStringFunc(TEXT("ERROR: Number of XIPs exceeds MAX\n"));
      return;
    }

    pChainEntry = (PXIPCHAIN_ENTRY)(pdwCurXIP + 1);   //其实就是指向CHAIN 中chain info的相关信息

    while(dwChainCount < dwNumXIPs)
    {
        if ((pChainEntry->usFlags & ROMXIP_OK_TO_LOAD) &&  // flags indicates valid XIP
            *(LPDWORD)(((DWORD)(pChainEntry->pvAddr)) + ROM_SIGNATURE_OFFSET) == ROM_SIGNATURE)
        {
            s_pNextRom[dwRomCount].pTOC = *(ROMHDR **)(  ((DWORD)(pChainEntry->pvAddr)) + ROM_SIGNATURE_OFFSET + 4  );
            s_pNextRom[dwRomCount].pNext = NULL;

            if (dwRomCount != 0)
            {
                s_pNextRom[dwRomCount-1].pNext = &s_pNextRom[dwRomCount];
            }
            else
            {
                OEMRomChain = s_pNextRom;
            }
            dwRomCount++;
        }
        else
        {
            lpWriteDebugStringFunc( _T("Invalid XIP found\n") );
        }

        ++pChainEntry;
  dwChainCount++;
 }
}
 

 

//在romldr.h中 定义了上面的相关的
typedef struct _XIPCHAIN_ENTRY {
    LPVOID  pvAddr;                 // address of the XIP
    DWORD   dwLength;               // the size of the XIP
    DWORD   dwMaxLength;            // the biggest it can grow to
    USHORT  usOrder;                // where to put into ROMChain_t
    USHORT  usFlags;                // flags/status of XIP
    DWORD   dwVersion;              // version info
    CHAR    szName[XIP_NAMELEN];    // Name of XIP, typically the bin file's name, w/o .bin
    DWORD   dwAlgoFlags;            // algorithm to use for signature verification
    DWORD   dwKeyLen;               // length of key in byPublicKey
    BYTE    byPublicKey[596];       // public key data
} XIPCHAIN_ENTRY, *PXIPCHAIN_ENTRY;

#define ROMXIP_OK_TO_LOAD       0x0001
#define ROMXIP_IS_SIGNED        0x0002

#define ROM_SIGNATURE_OFFSET 64   //0x40
#define ROM_SIGNATURE 0x43454345     //cece 4byte    =>ROMHDR 在0x44偏移处,
//每个bin 都有个pToc指向ROMHDR开头的地址,看下面的bin 文件结构,在0x44offset处地址里面放的是ROMHDR地址,开始是-1,由romimage.exe来设置的


//有点糊涂了 再分析下bin文件的结构
struct BinFile{
BYTE signature[7]; // = { ''B'', ''0'', ''0'', ''0'', ''F'', ''F'', ''\a'' }
DWORD ImageStart
DWORD ImageLength
Record ImageRecords[RecordNum]
};


struct Record{
DWORD address;
DWORD length;
DWORD chksum;
};
在文件的最开端,会放置一个BinFile结构,imageStart和ImageLength分别对应镜像展开后在内存中存放的首地址和长度。
该结构中的RecordNum为不确定的,通常在最后一个记录之后增加一个address和Chksum都为0的纪录表示结束,
而这个表示结束的结构中的Length则标示其实际入口点。
可以用viewbin -r 去看下nk.bin:
Image Start = 0x8C200000, length = 0x00E158C8
  Start address = 0x8C201000
Checking record #22 for potential TOC (ROMOFFSET = 0xFF446658)
Checking record #177 for potential TOC (ROMOFFSET = 0x00000000)
Found pTOC  = 0x8d013950
ROMOFFSET = 0x00000000

ROMHDR ----------------------------------------
    DLL First           : 0x01E401E7 
    DLL Last            : 0x02000000 
    Physical First      : 0x8C200000 
    Physical Last       : 0x8D0158C8 
    RAM Start           : 0x8E600000 
    RAM Free            : 0x8E629000 
    RAM End             : 0x8FF00000 
    Kernel flags        : 0x00000002 
    Prof Symbol Offset  : 0x00000000 
    Num Copy Entries    :          1   
    Copy Entries Offset : 0x8CC7AE8C 
    Num Modules         :        166   
    Num Files           :         95   
    Kernel Debugger     :         No
    CPU                 :     0x01c2 (Thumb)
    Extensions          : 0x8C20266C

ROMHDR Extensions -----------------------------
    PID[0] = 0x00000000
    PID[1] = 0x00000000
    PID[2] = 0x00000000
    PID[3] = 0x00000000
    PID[4] = 0x00000000
    PID[5] = 0x00000000
    PID[6] = 0x00000000
    PID[7] = 0x00000000
    PID[8] = 0x00000000
    PID[9] = 0x00000000
    Next: 00000000

COPY Sections ---------------------------------
    Src: 0x8CD18DA8   Dest: 0x8E606000   CLen: 0x228      DLen: 0x22B4C

MODULES ---------------------------------------
    11/20/2006  03:20:28      268800  nk.exe
    11/20/2006  03:25:22      550400  coredll.dll
    11/20/2006  03:25:22      205824  filesys.exe
    11/20/2006  03:25:22      723968  gwes.exe
    11/20/2006  03:09:08       25600  device.exe
    .......................
    .......................
FILES ----------------------------------------
     11/20/2006  03:10:42  C_R_       2897      12461                ceconfig.h (ROM 0x8C55E4AC)
     11/20/2006  03:25:18  _HRS          0     694654                 wince.nls (ROM 0x8CE36984)
      5/09/2007  14:06:14  CHRS       3427      20574               initobj.dat (ROM 0x8C730280)
    .......................
    .......................
done.

分布结构:
Image :
Offset -----------
0x00 | ImageStart
|
|
0x40 | Rom Signature { 0x43454345 }
0x44 | Pointer to the ROMHDR for this Region
|
|
0x???? | ROMHDR{                <-pToc所指
| };
|


Chain file
struct _XIPCHAIN_ENTRY {
LPVOID pvAddr; // address of the XIP
DWORD dwLength; // the size of the XIP
DWORD dwMaxLength; // the biggest it can grow to
USHORT usOrder; // where to put into ROMChain_t
USHORT usFlags; // flags/status of XIP
DWORD dwVersion; // version info
CHAR szName[XIP_NAMELEN]; // Name of XIP, typically the bin file''s name, w/o .bin
DWORD dwAlgoFlags; // algorithm to use for signature verification
DWORD dwKeyLen; // length of key in byPublicKey
BYTE byPublicKey[596]; // public key data
};


Offset --------------------------
0x00 | DWORD Count;
0x04 | XIPCHAIN_ENTRY[1]{
| };
| XIPCHAIN_ENTRY[2]{
| };
| ...


二.关于OEMMultiBINNotify ,他是被blcommon 来调用,来让我们获得一个或多个 BIN regions的信息的
比如
用结构
typedef struct _MultiBINInfo_
{
    DWORD dwNumRegions;
 RegionInfo Region[BL_MAX_BIN_REGIONS];
} MultiBINInfo, *PMultiBINInfo;

定义一个MultiBINInfo    g_BINRegionInfo;全局变量在OEMMultiBINNotify中获得每个bin regins的信息

ReginInfo结构:
typedef struct _RegionInfo_
{
 DWORD dwRegionStart;
 DWORD dwRegionLength;
} RegionInfo, *PRegionInfo;

g_BINRegionInfo 被WriteRegionsToBootMedia 写regions到flash用到,
我用的是nandflash,
WriteRegionsToBootMedia中这段
// Look in the kernel region's extension area for a multi-BIN extension descriptor.
    // This region, if found, details the number, start, and size of each BIN region.
    //
    //for (nCount = 0, dwNumExts = 0 ; (nCount < g_BINRegionInfo.dwNumRegions) && !pChainInfo ; nCount++)
    for (nCount = 0, dwNumExts = 0 ; (nCount < g_BINRegionInfo.dwNumRegions); nCount++)
    {
        // Does this region contain nk.exe and an extension pointer?
        //
        pExt = (EXTENSION *)GetKernelExtPointer(g_BINRegionInfo.Region[nCount].dwRegionStart,
                                                g_BINRegionInfo.Region[nCount].dwRegionLength );
        if ( pExt != NULL)
        {
            // If there is an extension pointer region, walk it until the end.
            //
            while (pExt)
            {
                DWORD dwBaseAddr = g_BINRegionInfo.Region[nCount].dwRegionStart;
                pExt = (EXTENSION *)OEMMapMemAddr(dwBaseAddr, (DWORD)pExt);
                EdbgOutputDebugString("INFO: OEMLaunch: Found chain extenstion: '%s' @ 0x%x\r\n", pExt->name, dwBaseAddr);
                if ((pExt->type == 0) && !strcmp(pExt->name, "chain information"))
                {
                    pChainInfo = (PXIPCHAIN_SUMMARY) OEMMapMemAddr(dwBaseAddr, (DWORD)pExt->pdata);
                    dwNumExts = (pExt->length / sizeof(XIPCHAIN_SUMMARY));
                    EdbgOutputDebugString("INFO: OEMLaunch: Found 'chain information' (pChainInfo=0x%x  Extensions=0x%x).\r\n", (DWORD)pChainInfo, dwNumExts);
                    break;
                }
                pExt = (EXTENSION *)pExt->pNextExt;
            }
        }
        else {
            //  Search for Chain region. Chain region doesn't have the ROMSIGNATURE set
            DWORD   dwRegionStart = g_BINRegionInfo.Region[nCount].dwRegionStart;
            DWORD   dwSig = *(LPDWORD) OEMMapMemAddr(dwRegionStart, dwRegionStart + ROM_SIGNATURE_OFFSET);

            if ( dwSig != ROM_SIGNATURE) {
                //  It is the chain
                dwChainStart = dwRegionStart;
                dwChainLength = g_BINRegionInfo.Region[nCount].dwRegionLength;
                EdbgOutputDebugString("Found the Chain region: StartAddress: 0x%X; Length: 0x%X\n", dwChainStart, dwChainLength);
            }
        }
    }

    // nk.exe and an extension pointer  这个是什么意思,就是说nk.exe 包含一个扩展point是派什么用处的,那位知道告诉我


感觉是一个是bootlaod时的概念,一个是运行是的概念
bootlaoder时 :通过OEMMultiBINNotify 获得的信息来进行下载等应用

运行时,是根据config.bib中CHAIN的关于regions的信息,通过InitRomChain 来把他串起来,

 

三.toc block ,是和nand boot有关的东西

typedef struct _TOC {
    DWORD               dwSignature;
    // How to boot the images in this TOC.
    // This could be moved into the image descriptor if desired,
    // but I prefer to conserve space.
    BOOT_CFG            BootCfg;

    // Array of Image Descriptors.
    IMAGE_DESCRIPTOR    id[MAX_TOC_DESCRIPTORS];

//    UCHAR Pad[12];      // align on SECTOR_SIZE
    CHAININFO           chainInfo;
} TOC, *PTOC;           // 512 bytes


typedef struct _IMAGE_DESCRIPTOR {

    // File version info
    DWORD dwVersion;                    // e.g: build number
    DWORD dwSignature;                  // e.g: "EBOT", "CFSH", etc
    UCHAR ucString[IMAGE_STRING_LEN];   // e.g: "PocketPC_2002"

    DWORD dwImageType;      // IMAGE_TYPE_ flags
    DWORD dwTtlSectors;     // TTL image size in sectors.
                            // We store size in sectors instead of bytes
                            // to simplify sector reads in Nboot.

    DWORD dwLoadAddress;    // Virtual address to load image (ImageStart)
    DWORD dwJumpAddress;    // Virtual address to jump (StartAddress/LaunchAddr)

    // This array equates to a sector-based MXIP MultiBINInfo in blcommon.
    // Unused entries are zeroed.
    // You could chain image descriptors if needed.
    SG_SECTOR sgList[MAX_SG_SECTORS];

    // BinFS support to load nk region only
 //struct
 //{
  ULONG dwStoreOffset;    // byte offset - not needed - remove!
  //ULONG RunAddress;     // nk dwRegionStart address
  //ULONG Length;         // nk dwRegionLength in bytes
  //ULONG LaunchAddress;  // nk dwLaunchAddr
 //} NKRegion;

} IMAGE_DESCRIPTOR, *PIMAGE_DESCRIPTOR;

这些信息被写入block 1,
为nboot启动 nk,或 eboot提供信息的


感觉这块总是理不顺,如果那位能理得更清晰点,贴出来大家学习下,我也起到抛砖引玉的作用了

发表于 2007-05-22 15:11 liu090 阅读(2089) | 评论 (1)编辑 收藏

2007年2月13日

终于看到小企鹅了

调试lcd,发现驱动程序执行后有反映,但只能看到一个光标在闪,但看不到所谓的小企鹅
我估计驱动是没问题的,这块屏在wince下已经弄得很熟悉了,估计是什么东西没加
看到配置里面graphic device里的boot config 没选,选中后跳出三条好象和图片有关的
全部加入,一编译  , 下载后,###############################################
#########################################################################3
##########################################################################3
终于看到了无数人调lcd时看到的所谓的小企鹅,爽啊

发表于 2007-02-13 20:08 liu090 阅读(1729) | 评论 (1)编辑 收藏

2007年1月25日

我的博客开通了,心情不错

博客开通了,心情不错

发表于 2007-01-25 11:04 liu090 阅读(1235) | 评论 (1)编辑 收藏