内核启动:http://blog.chinaunix.net/uid-26202349-id-4829000.html
可知道,最终会调用bootm命令。
点击(此处)折叠或打开
-
bootcmd=nand read C0008000 600000 400000; nand read 30A00000 B00000 180000; bootm C0008000 30A00000
从参数bootcmd可知道,启动过程,先从nand中读取内核(先跳过这部分)。然后启动内核,bootm.
解析common/cmd_bootm.c代码
------------------------1.命令定义--------------------
-
U_BOOT_CMD(
-
bootm, CFG_MAXARGS, 1, do_bootm,
-
"bootm - boot application image from memory\n",
-
"[addr [arg ...]]\n - boot application image stored in memory\n"
-
"\tpassing arguments 'arg ...'; when booting a Linux kernel,\n"
-
"\t'arg' can be the address of an initrd image\n"
-
....
-
);
------------------------------2.内核结构体------------------------------------
点击(此处)折叠或打开
-
static bootm_headers_t images; /* pointers to os/initrd/fdt images */
------------------------------3.启动内核函数调用------------------------------------
点击(此处)折叠或打开
-
int do_bootm (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
-
{
-
image_header_t *hdr;
-
//内核头部(含内核的加载地址和内核的入口地址)+真正内核=uImage
-
ulong addr;
-
ulong iflag;
-
const char *type_name;
-
uint unc_len = CFG_BOOTM_LEN;
-
uint8_t comp, type, os;
-
-
void *os_hdr;
-
ulong os_data, os_len;
-
ulong image_start, image_end;
-
ulong load_start, load_end;
-
ulong mem_start;
-
phys_size_t mem_size;
-
-
struct lmb lmb;
-
-
memset ((void *)&images, 0, sizeof (images));
-
..
-
-
mem_start = getenv_bootm_low();
-
mem_size = getenv_bootm_size();
-
-
-
/* 内核处理:get kernel image header, start address and length */
-
os_hdr = boot_get_kernel (cmdtp, flag, argc, argv,
-
&images, &os_data, &os_len);
-
if (os_len == 0) {
-
puts ("ERROR: can't get kernel image!\n");
-
return 1;
-
}
-
-
/* get image parameters */
-
switch (genimg_get_format (os_hdr)) {
-
...
-
}
-
-
image_start = (ulong)os_hdr;
-
load_end = 0;
-
type_name = genimg_get_type_name (type);
-
-
-
//判断压缩格式
-
switch (comp) {
-
case IH_COMP_NONE:
-
if (load_start == (ulong)os_hdr) {
-
printf (" XIP %s ... ", type_name);
-
} else {
-
printf (" Loading %s ... ", type_name);
-
-
memmove_wd ((void *)load_start,
-
(void *)os_data, os_len, CHUNKSZ);
-
}
-
load_end = load_start + os_len;
-
puts("OK\n");
-
break;
-
case IH_COMP_GZIP:
-
printf (" Uncompressing %s ... ", type_name);
-
if (gunzip ((void *)load_start, unc_len,
-
(uchar *)os_data, &os_len) != 0) {
-
puts ("GUNZIP: uncompress or overwrite error "
-
"- must RESET board to recover\n");
-
show_boot_progress (-6);
-
do_reset (cmdtp, flag, argc, argv);
-
}
-
-
load_end = load_start + os_len;
-
break;
-
#ifdef CONFIG_BZIP2
-
case IH_COMP_BZIP2:
-
printf (" Uncompressing %s ... ", type_name);
-
/*
-
* If we've got less than 4 MB of malloc() space,
-
* use slower decompression algorithm which requires
-
* at most 2300 KB of memory.
-
*/
-
int i = BZ2_bzBuffToBuffDecompress ((char*)load_start,
-
&unc_len, (char *)os_data, os_len,
-
CFG_MALLOC_LEN < (4096 * 1024), 0);
-
if (i != BZ_OK) {
-
printf ("BUNZIP2: uncompress or overwrite error %d "
-
"- must RESET board to recover\n", i);
-
show_boot_progress (-6);
-
do_reset (cmdtp, flag, argc, argv);
-
}
-
-
load_end = load_start + unc_len;
-
break;
-
#endif /* CONFIG_BZIP2 */
-
default:
-
if (iflag)
-
enable_interrupts();
-
printf ("Unimplemented compression type %d\n", comp);
-
show_boot_progress (-7);
-
return 1;
-
}
-
puts ("OK\n");
-
debug (" kernel loaded at 0x%08lx, end = 0x%08lx\n", load_start, load_end);
-
show_boot_progress (7);
-
-
if ((load_start < image_end) && (load_end > image_start)) {
-
debug ("image_start = 0x%lX, image_end = 0x%lx\n", image_start, image_end);
-
debug ("load_start = 0x%lx, load_end = 0x%lx\n", load_start, load_end);
-
-
if (images.legacy_hdr_valid) {
-
if (image_get_type (&images.legacy_hdr_os_copy) == IH_TYPE_MULTI)
-
puts ("WARNING: legacy format multi component "
-
"image overwritten\n");
-
} else {
-
puts ("ERROR: new format image overwritten - "
-
"must RESET the board to recover\n");
-
show_boot_progress (-113);
-
do_reset (cmdtp, flag, argc, argv);
-
}
-
}
-
-
show_boot_progress (8);
-
-
lmb_reserve(&lmb, load_start, (load_end - load_start));
-
-
#if defined(CONFIG_ZIMAGE_BOOT)
-
after_header_check:
-
os = hdr->ih_os;
-
#endif
-
-
//判断操作系统的类型
-
-
switch (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, &images); //如果当前镜像为linux内核,则通过do_bootm_linux进行内核引导
-
break;
-
-
...
-
}
--------------4.do_bootm_linux启用------------------------------
击(此处)折叠或打开
-
void do_bootm_linux (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[],bootm_headers_t *images)
-
{
-
ulong initrd_start, initrd_end;
-
ulong ep = 0;
-
bd_t *bd = gd->bd; //获取bd信息
-
char *s;
-
int machid = bd->bi_arch_number; //获取机器码
-
void (*theKernel)(int zero, int arch, uint params); //定义theKernel启动程序指针,内核运行地址
-
int ret;
-
-
#ifdef CONFIG_CMDLINE_TAG
-
char *commandline = getenv ("bootargs"); //获取bootargs参数
-
#endif
-
-
/* find kernel entry point */
-
-
if (images->legacy_hdr_valid) {
-
ep = image_get_ep (&images->legacy_hdr_os_copy);
-
-
} else {
-
puts ("Could not find kernel entry point!\n");
-
goto error;
-
}
-
theKernel = (void (*)(int, int, uint))ep; //将检索到的内核运行地址入口赋值给theKernel
-
-
s = getenv ("machid"); //获取机器码
-
if (s) {
-
machid = simple_strtoul (s, NULL, 16);
-
printf ("Using machid 0x%x from environment\n", machid);
-
}
-
-
-
cleanup_before_linux (); //为内核启动清空先关资源
-
-
theKernel (0, machid, bd->bi_boot_params); //启动内核,一去不复返
-
r0 r1 r2
-
-
/* does not return */
-
return;
-
-
error:
-
do_reset (cmdtp, flag, argc, argv);
-
return;
-
}
------------------------------------------------------------------------------
## Booting kernel from Legacy Image at 40000000 ...
Image Name: Linux-2.6.35.7
Created: 2013-09-15 7:42:33 UTC
Image Type: ARM Linux Kernel Image (uncompressed)
Data Size: 4009840 Bytes = 3.8 MB
Load Address: 20008000
Entry Point: 20008000 //ep值
Verifying Checksum ... OK
阅读(504) | 评论(0) | 转发(0) |