Chinaunix首页 | 论坛 | 博客
  • 博客访问: 487533
  • 博文数量: 104
  • 博客积分: 3045
  • 博客等级: 少校
  • 技术积分: 1230
  • 用 户 组: 普通用户
  • 注册时间: 2008-02-29 10:18
文章分类

全部博文(104)

文章存档

2011年(72)

2010年(1)

2009年(1)

2008年(30)

分类:

2008-04-07 14:48:58

本文是参照super的文章进行的分析。自己根据实践修改并 分析的
添加如下文件
DECLARE_GLOBAL_DATA_PTR;   它在include/asm-arm/global—data.h中定义如下
 #define DECLARE_GLOBAL_DATA_PTR     register volatile gd_t *gd asm ("r8")
大概的意思是声明一个指向gd_t结构体变量的指针gd,并固定使用寄存器r8来存放该指针。而对gd_t结构体的定义从上面的第36行开始:
其中gd_t 的定义在它的定义的上面
typedef struct  global_data {    
 37         bd_t            *bd;     
 38         unsigned long   flags;   
 39         unsigned long   baudrate;
 40         unsigned long   have_console;   /* serial_init() was called */                        
 41         unsigned long   reloc_off;      /* Relocation Offset */  
 42         unsigned long   env_addr;       /* Address  of Environment struct */
 43         unsigned long   env_valid;      /* Checksum of Environment valid? */                  
 44         unsigned long   fb_base;        /* base address of frame buffer */
 45 #ifdef CONFIG_VFD
 46         unsigned char   vfd_type;       /* display type */       
 47 #endif
 48 #if 0
 49         unsigned long   cpu_clk;        /* CPU clock in Hz!             */
 50         unsigned long   bus_clk;                                                              
 51         unsigned long   ram_size;       /* RAM size */                                        
 52         unsigned long   reset_status;   /* reset status register at boot */
 53 #endif
 54         void            **jt;           /* jump table */
 55 } gd_t;
    其中,tag的定义在/include/asm-arm/setup.h中定义的
struct tag {
209         struct tag_header hdr;
210         union {
211                 struct tag_core         core;
212                 struct tag_mem32        mem;
213                 struct tag_videotext    videotext;
214                 struct tag_ramdisk      ramdisk;
215                 struct tag_initrd       initrd;
216                 struct tag_serialnr     serialnr;
217                 struct tag_revision     revision;
218                 struct tag_videolfb     videolfb;
219                 struct tag_cmdline      cmdline;
220
221                 /*
222                  * Acorn specific
223                  */
224                 struct tag_acorn        acorn;
225
226                 /*
227                  * DC21285 specific
228                  */
229                 struct tag_memclk       memclk;
230         } u;
231 };

加上如下代码用于设置tag传递给内核
 #define LINUX_PAGE_SIZE 4096
 36 static void setup_linux_tag(ulong param_base)
 37 {
 38         struct tag *params=(struct tag *)param_base;
 39         char *linux_cmd;
 40         char *p;
 41
 42         printf("setup linux parmeters at 0x%x\n",param_base);
 43         memset(params, 0, sizeof(struct tag));
 44
 45         /*step 1 :stup start tag*/
 46         params->hdr.tag=ATAG_CORE;
 47         params->hdr.size= tag_size(tag_core);
 48         params->u.core.flags=0;
 49         params->u.core.pagesize= LINUX_PAGE_SIZE;
 50         params->u.core.rootdev=0;
 51         params=tag_next(params); /*params 指向下一个tag
 52
 53
 54         /*setp 2: setup cmdline tag设置命令tag参数*/
 55         params->hdr.tag=ATAG_CMDLINE;
 56         linux_cmd=getenv("boottargs");
 57         if(linux_cmd==NULL){
 58                 printf("connot find linux cmdline ,use default.\n");
                        params->hdr.size =(sizeof(struct tag_header)+strlen(CONFIG_BOOTARGS)+1+40)>>2;
 60                 memcpy(params->u.cmdline.cmdline,CONFIG_BOOTARGS, strlen(CONFIG_BOOTARGS)+1);
 61
 62
 63         } else{
 64                 /*eat leading white space*/
 65                 for (p=linux_cmd; *p==' '; p++){
 66                 /*do nothing */
 67                 }
 68                 params->hdr.size =(sizeof (struct tag_header)+strlen(linux_cmd)+1+4)>>2;
 69                 memcpy(params->u.cmdline.cmdline, linux_cmd,strlen(linux_cmd)+1);
 70
 71                 }
 72         printf("linux command line is : \"%s\"\n", params->u.cmdline.cmdline);
 73         params=tag_next(params);
 74
 75         /*step3 : setp end tag*/
 76         params->hdr.tag=ATAG_NONE;
 77         params->hdr.size=0;
 78
 79
 80 }

此函数设置了3个tag 变量 用于传递参数
在do_boot 函数中添加如下代码
106 #if !defined(CONFIG_NIOS)
107         setup_linux_tag(gd->bd->bi_boot_params);
调用上面的函数设置 tag 变量
108         rc = ((ulong (*)(int, char *[]))addr) (0, gd->bd->bi_arch_number);
这句比较难理解。其实就是执行函数的指针,带有两个参数,然后调转到函数地址执行。等价于vivi中的call(0, mach_type, addr)。patch内容如下,参考修改:    完成后测试成功,
至此 ,do_boot 引导内核成功。


阅读(2050) | 评论(0) | 转发(0) |
0

上一篇:u-boot分析(二)

下一篇:crc 校验错误分析

给主人留下些什么吧!~~