在u-boot-1.1.6/common/main.c中的main_loop中
s = getenv ("bootcmd");// bootcmd=nand read.jffs2 0x30007FC0 kernel; bootm 0x30007FC0
run_command (s, 0);
在u-boot-1.1.6/common/cmd_nand.c中
if (s != NULL && (!strcmp(s, ".jffs2") || !strcmp(s, ".e") || !strcmp(s, ".i"))) { if (read) { /* read */ nand_read_options_t opts; memset(&opts, 0, sizeof(opts)); opts.buffer = (u_char*) addr; opts.length = size; opts.offset = off; opts.quiet = quiet; ret = nand_read_opts(nand, &opts); }
在u-boot-1.1.6/common/cmd_bootm.c中image_header_t *hdr = &header;
image_header_t *hdr = &header;
switch (hdr->ih_os) { default: /* handled by (original) Linux case */ case IH_OS_LINUX: #ifdef CONFIG_SILENT_CONSOLE fixup_silent_linux(); #endif do_bootm_linux (cmdtp, flag, argc, argv, addr, len_ptr, verify); break; case IH_OS_NETBSD: do_bootm_netbsd (cmdtp, flag, argc, argv, addr, len_ptr, verify); break;
我們知道内核image是由头与内核组成;头在u-boot-1.1.6/include/image.h定义;而内核加载地址0x30008000 再减去0x30007FC0刚好等于头的大小64;
#define IH_NMLEN 32 /* Image Name Length */ /* * all data in network byte order (aka natural aka bigendian) */ typedef struct image_header { uint32_t ih_magic; /* Image Header Magic Number */ uint32_t ih_hcrc; /* Image Header CRC Checksum */ uint32_t ih_time; /* Image Creation Timestamp */ uint32_t ih_size; /* Image Data Size */ uint32_t ih_load; /* Data Load Address */ //加载地址为:0x30008000 uint32_t ih_ep; /* Entry Point Address */ uint32_t ih_dcrc; /* Image Data CRC Checksum */ uint8_t ih_os; /* Operating System */ uint8_t ih_arch; /* CPU architecture */ uint8_t ih_type; /* Image Type */ uint8_t ih_comp; /* Compression Type */ uint8_t ih_name[IH_NMLEN]; /* Image Name */ } image_header_t;
而do_bootm_linux函数在u-boot-1.1.6/lib_arm/armlinux.c文件中定义
static struct tag *params;
void (*theKernel)(int zero, int arch, uint params);
image_header_t *hdr = &header;
bd_t *bd = gd->bd;
char *commandline = getenv ("bootargs"); //bootargs=noinitrd root=/dev/mtdblock3 init=/linuxrc console=ttySAC0,115200
theKernel = (void (*)(int, int, uint))ntohl(hdr->ih_ep); //头结构里面的内核入口地址
setup_start_tag (bd);//设置参数
setup_serial_tag (¶ms);
setup_revision_tag (¶ms);
setup_memory_tags (bd);
setup_commandline_tag (bd, commandline);
setup_initrd_tag (bd, initrd_start, initrd_end);
setup_videolfb_tag ((gd_t *) gd);
setup_end_tag (bd);
cleanup_before_linux ();
theKernel (0, bd->bi_arch_number, bd->bi_boot_params); //启动内核;gd->bd->bi_arch_number = MACH_TYPE_S3C2440; gd->bd->bi_boot_params = 0x30000100
static void setup_start_tag (bd_t *bd)//随便拎出几个设置函数看一下
{
params = (struct tag *) bd->bi_boot_params; //;//这就是参数保存的起始地址
params->hdr.tag = ATAG_CORE; //#define ATAG_CORE 0x54410001
params->hdr.size = tag_size (tag_core);
params->u.core.flags = 0;
params->u.core.pagesize = 0;
params->u.core.rootdev = 0;
params = tag_next (params);
}
static void setup_memory_tags (bd_t *bd)
{
int i;
for (i = 0; i < CONFIG_NR_DRAM_BANKS; i++) {
params->hdr.tag = ATAG_MEM; //#define ATAG_MEM 0x54410002
params->hdr.size = tag_size (tag_mem32);
params->u.mem.start = bd->bi_dram[i].start; //0x30000000 /* SDRAM Bank #1 */
params->u.mem.size = bd->bi_dram[i].size; //0x04000000 /* 64 MB */
params = tag_next (params);
}
}
static void setup_commandline_tag (bd_t *bd, char *commandline)
{
char *p;
if (!commandline)
return;
/* eat leading white space */
for (p = commandline; *p == ' '; p++);
/* skip non-existent command lines so the kernel will still
* use its default command line.
*/
if (*p == '\0')
return;
params->hdr.tag = ATAG_CMDLINE; //#define ATAG_CMDLINE 0x54410003
params->hdr.size =
(sizeof (struct tag_header) + strlen (p) + 1 + 4) >> 2;
strcpy (params->u.cmdline.cmdline, p);
params = tag_next (params);
}
static void setup_end_tag (bd_t *bd)
{
params->hdr.tag = ATAG_NONE;
params->hdr.size = 0;
}
在u-boot-1.1.6/include/asm/u-boot.h文件中,定义了存储u-boot启动项结构体bd_t
typedef struct bd_info { int bi_baudrate; /* serial console baudrate */ unsigned long bi_ip_addr; /* IP Address */ unsigned char bi_enetaddr[6]; /* Ethernet adress */ struct environment_s *bi_env; ulong bi_arch_number; /* unique id for this board */ ulong bi_boot_params; /* where this board expects params */ struct /* RAM configuration */ { ulong start; ulong size; } bi_dram[CONFIG_NR_DRAM_BANKS]; #ifdef CONFIG_HAS_ETH1 /* second onboard ethernet port */ unsigned char bi_enet1addr[6]; #endif } bd_t;
在u-boot-1.1.6/include/asm-arm/setup.h中定义了u-boot传递给内核的参数的结构体
struct tag { struct tag_header hdr; union { struct tag_core core; struct tag_mem32 mem; struct tag_videotext videotext; struct tag_ramdisk ramdisk; struct tag_initrd initrd; struct tag_serialnr serialnr; struct tag_revision revision; struct tag_videolfb videolfb; struct tag_cmdline cmdline; /* * Acorn specific */ struct tag_acorn acorn; /* * DC21285 specific */ struct tag_memclk memclk; } u; };
struct tag_header {
u32 size;
u32 tag;
};