韦东山移植学习----004uboot启动内核过程分析

uboot的最终目的是引导/启动内核

uboot 的第一阶段(板机配置,大同小异,多数用汇编写,也有一部分可以用c写)

a)设置SVC模式
b)关看门狗
c)屏蔽中断
d)初始化SDRAM
e)设置栈
f)设置时钟
g)初始化flash
h)代码从定位 flash->SDRAM
i)清除bss段
j)调用c函数
uboot的第二阶段(较为复杂的操作都在这个阶段,一般c函数写)

第二阶段主要是 (从flash上)读出内核 、设置启动参数、跳转到内核入口地址启动

u-boot-1.16\lib_arm\Armlinux.c
1、由于嵌入式linux没有分区表,因此必须程序写死,伪造分区表,通过4个启动参数构造分区表
–》在约定的位置(0x30001000),告诉内核启动信息(start_tag、memory_tag、command_tag_、end_tag)
跳转到内核启动地址()
问1:kernel是从哪里来?到哪里去?
=》从nand flash上来(是uImage,通过串口或者是网卡下载到nand flash上去),到加载地址上去
uImage ==头部 和 真正的kernel
=》uboot通过读取头部的 ih_head (加载地址,内核运行前先存放的地址)和 ip_ep(入口地址,内核运行的起始地址),判断一开始内核所在的位置是否在 ip_head - 64字节(头部大小)的位置上,如果不在,则把内核搬运到加载地址上
2、跳转到入口地址,启动内核
theKernel (0, bd->bi_arch_number, bd->bi_boot_params); //(传递板机编号–机器ID),运行完,控制权就交给内核
内核可以支持很多单板(机器), uboot有责任确定启动的机器是什么

在这里插入图片描述
启动内核
=》从flash上读出内核 (cmd: nand read.jffs 0x30007F00 Kernel)
==》flash的型号是什么?Nand?Nor?
==>nand/Nor flash 初始化,读功能(写功能,是为了调试方便)
==》搬到哪里去?SDRAM,SDRAM初始化
==》识别出Uimage (头部+真正的内核) ,获取头部里面的ih_head(加载地址:内核执行前先运行的地址) ih_ep(入口地址:内核的启动/起始地址)
=》启动内核 (cmd: bootm 0x3007f00)
==》没有分区表,因此要程序构造分区表,设置启动参数(start_tag、memory_tag、command_tag、end_tag)=>传递给内核
==>在ih_ep启动地址运行
Uboot的核心是命令 ----03在uboot增加命令
启动内核:
s =getenv("bootcmd ");
run_command(s,0)
控制界面
len = readline() //读入串口的数据
run_command(lastcommand,flag)

start.S-》start_armboor()-》Board.c->main_loop-》main.c

cpu_init_f
board_init_f==》Board.c
gd = (gd_t *) (CFG_GBL_DATA_ADDR);
memset((void ) gd, 0, sizeof(gd_t));
init_IRQ();
env_init(); /
initialize environment /
init_baudrate(); /
initialze baudrate settings /
serial_init(); /
serial communications setup /
console_init_f();
display_banner(); /
say that we are here /
checkboard();
timer_init();
/
initialize malloc() area /
mem_malloc_init();
malloc_bin_reloc();
/
relocate environment function pointers etc. /
env_relocate();
/
board MAC address /
s = getenv(“ethaddr”);
/
main_loop() can return to retry autoboot, if so just run it again. */
for (;? {
main_loop();==》main.C
}

main_loop()
==》s = getenv ("bootcmd");
# ifndef CFG_HUSH_PARSER
    {
        printf("Booting Linux ...\n");            
	    run_command (s, 0);
    }
# else

# ifdef CONFIG_MENUKEY
	if (menukey == CONFIG_MENUKEY) {
	    s = getenv("menucmd");
	    if (s) {
# ifndef CFG_HUSH_PARSER
		run_command (s, 0);
# else
		parse_string_outer(s, FLAG_PARSE_SEMICOLON |
				    FLAG_EXIT_FROM_LOOP);
# endif
	    }
	}
	eth_init(gd->bd);
run_command("menu", 0);
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值