本文是参照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 引导内核成功。
阅读(2096) | 评论(0) | 转发(0) |