Lele was written in 2021
Uboot启动流程
U-Boot启动过程
(国嵌)
开发板上电后,执行U-Boot的第一条指令,然后顺序执行U-Boot启动函数。看一下board/smdk2410/这个链接脚本,可以知道目标程序的各部分链接顺序。第一个要链接的是cpu/arm920t/,那么U-Boot的入口指令一定位于这个程序中。下面分两阶段介绍启动流程:
第一阶段
1.cpu/arm920t/
这个汇编程序是U-Boot的入口程序,开头就是复位向量的代码。
_start: b reset . */
add r0, r0, #4
cmp r0, r1
bne clbss_l
/* 跳转到start_armboot函数入口,_start_armboot字保存函数入口指针 */
ldr pc, _start_armboot
_start_armboot: .word start_armboot .\n", addr);
rc = ((ulong (*)(int, char []))addr) (--argc, &argv[1]); /* 运行程序 */
if (rc != 0) rcode = 1;
printf ("## Application terminated, rc = 0x%lX\n", rc); /*如果是运行linux,这条指令是否能运行*/
return rcode;
}
go命令调用do_go()函数,跳转到某个地址执行的。如果在这个地址准备好了自引导的内核映像,就可以启动了。尽管go命令可以带变参,实际使用时不用来传递参数。
2.bootm命令的实现
/* common/ */
int do_bootm (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
{
…… ……
/* 检查头部 */
if (crc32 (0, (uchar *)data, len) != checksum) {
puts ("Bad Header Checksum\n");
SHOW_BOOT_PROGRESS (-2);
return 1;
}
…… ……
/*解压缩*/
switch (hdr->ih_comp) {
case IH_COMP_NONE:
if(ntohl(hdr->ih_load) == addr) {
printf (" XIP %s ... ", name);
} else {
#if defined(CONFIG_HW_WATCHDOG) || defined(CONFIG_WATCHDOG)
size_t l = len;
void *to = (void *)ntohl(hdr->ih_load);
void *from = (void *)data;
printf (" Loading %s ... ", name);
while (l > 0) {
size_t tail = (l > CHUNKSZ) CHUNKSZ : l;
WATCHDOG_RESET();
memmove (to, from, tail);
to += tail;
from += tail;
l -= tail;
}
#else /* !(CONFIG_HW_WATCHDOG || CONFIG_WATCHDOG) */
memmove ((void *) ntohl(hdr->ih_load), (uchar *)data, len);
#endif /* CONFIG_HW_WATCHDOG || CONFIG_WATCHDOG */
}
break;
case IH_COMP_GZIP:
printf (" Uncompressing %s ... ", name);
if (gunzip ((void *)ntohl(hdr->ih_load), unc_len,
(uchar *)data, &len) != 0) {
puts ("GUNZIP ERROR - must RESET board to reco
Uboot启动流程 来自淘豆网m.daumloan.com转载请标明出处.