Uboot启动流程国嵌2440视频培训电子教案Word文件下载.docx
- 文档编号:21630838
- 上传时间:2023-01-31
- 格式:DOCX
- 页数:9
- 大小:18.71KB
Uboot启动流程国嵌2440视频培训电子教案Word文件下载.docx
《Uboot启动流程国嵌2440视频培训电子教案Word文件下载.docx》由会员分享,可在线阅读,更多相关《Uboot启动流程国嵌2440视频培训电子教案Word文件下载.docx(9页珍藏版)》请在冰豆网上搜索。
msrcpsr,r0
/*关闭看门狗*/
…………
relocate:
/*把U-Boot重新定位到RAM*/
adrr0,_start/*r0是代码的当前位置*/
ldrr1,_TEXT_BASE/*_TEXT_BASE是RAM中的地址*/
cmpr0,r1/*比较r0和r1,判断当前是从Flash启动,还是RAM*/
beqstack_setup/*如果r0等于r1,跳过重定位代码*/
/*准备重新定位代码*/
ldrr2,_armboot_start
ldrr3,_bss_start
subr2,r3,r2/*r2得到armboot的大小*/
addr2,r0,r2/*r2得到要复制代码的末尾地址*/
copy_loop:
/*重新定位代码*/
ldmiar0!
{r3-r10}/*从源地址[r0]复制*/
stmiar1!
{r3-r10}/*复制到目的地址[r1]*/
cmpr0,r2/*复制数据块直到源数据末尾地址[r2]*/
blecopy_loop
/*初始化堆栈等*/
stack_setup:
ldrr0,_TEXT_BASE/*上面是128KiB重定位的u-boot*/
subr0,r0,#CFG_MALLOC_LEN/*向下是内存分配空间*/
subr0,r0,#CFG_GBL_DATA_SIZE/*然后是bdinfo结构体地址空间*/
#ifdefCONFIG_USE_IRQ
subr0,r0,#(CONFIG_STACKSIZE_IRQ+CONFIG_STACKSIZE_FIQ)
#endif
subsp,r0,#12/*为abort-stack预留3个字*/
clear_bss:
ldrr0,_bss_start/*找到bss段起始地址*/
ldrr1,_bss_end/*bss段末尾地址*/
movr2,#0x00000000/*清零*/
clbss_l:
strr2,[r0]
/*bss段地址空间清零循环...*/
addr0,r0,#4
cmpr0,r1
bneclbss_l
/*跳转到start_armboot函数入口,_start_armboot字保存函数入口指针*/
ldrpc,_start_armboot
_start_armboot:
.wordstart_armboot//start_armboot函数在lib_arm/board.c中实现
第二阶段
2.lib_arm/board.c
start_armboot是U-Boot执行的第一个C语言函数,完成系统初始化工作,进入主循环,处理用户输入的命令。
3.init_sequence[]
init_sequence[]数组保存着基本的初始化函数指针。
init_fnc_t*init_sequence[]={
cpu_init,/*基本的处理器相关配置--cpu/arm920t/cpu.c*/
board_init,/*基本的板级相关配置--board/smdk2410/smdk2410.c*/
interrupt_init,/*初始化中断处理--cpu/arm920t/s3c24x0/interrupt.c*/
env_init,/*初始化环境变量--common/cmd_flash.c*/
init_baudrate,/*初始化波特率设置--lib_arm/board.c*/
serial_init,/*串口通讯设置--cpu/arm920t/s3c24x0/serial.c*/
console_init_f,/*控制台初始化阶段1--common/console.c*/
display_banner,/*打印u-boot信息--lib_arm/board.c*/
dram_init,/*配置可用的RAM--board/smdk2410/smdk2410.c*/
display_dram_config,/*显示RAM的配置大小--lib_arm/board.c*/
NULL,
};
voidstart_armboot(void)
{
/*顺序执行init_sequence数组中的初始化函数*/
for(init_fnc_ptr=init_sequence;
*init_fnc_ptr;
++init_fnc_ptr){
if((*init_fnc_ptr)()!
=0){
hang();
}
/*配置可用的Flash*/
size=flash_init();
display_flash_config(size);
/*_armboot_start在u-boot.lds链接脚本中定义*/
mem_malloc_init(_armboot_start-CFG_MALLOC_LEN);
/*配置环境变量*/
env_relocate();
/*从环境变量中获取IP地址*/
gd->
bd->
bi_ip_addr=getenv_IPaddr("
ipaddr"
);
/*以太网接口MAC地址*/
……
devices_init();
/*获取列表中的设备*/
jumptable_init();
console_init_r();
/*完整地初始化控制台设备*/
enable_interrupts();
/*使能中断处理*/
/*通过环境变量初始化*/
if((s=getenv("
loadaddr"
))!
=NULL){
load_addr=simple_strtoul(s,NULL,16);
/*main_loop()循环不断执行*/
for(;
;
)/*死循环*//uboot界面上,会一直等待用户输入命令
main_loop();
/*主循环函数处理执行用户命令--common/main.c*/
}
命令实现
U-Boot作为Bootloader,具备多种引导内核启动的方式。
常用的go和bootm命令可以直接引导内核映像启动。
U-Boot与内核的关系主要是内核启动过程中参数的传递。
1.go命令的实现
/*common/cmd_boot.c*/
intdo_go(cmd_tbl_t*cmdtp,intflag,intargc,char*argv[])
ulongaddr,rc;
intrcode=0;
if(argc<
2){
printf("
Usage:
\n%s\n"
cmdtp->
usage);
return1;
addr=simple_strtoul(argv[1],NULL,16);
//类型转换
##Startingapplicationat0x%08lX...\n"
addr);
//转化地址为unsignedlong
rc=((ulong(*)(int,char[]))addr)(--argc,&
argv[1]);
/*运行程序*/
/*把
addr
转换成一个函数指针,函数原型类似于ulong
func(int
x,
char
y[]);
然后用
--argc
和
&
argv[1]
作为参数调用这个函数*/
if(rc!
=0)rcode=1;
##Applicationterminated,rc=0x%lX\n"
rc);
/*如果是运行linux,这条指令是否能运行?
*/
returnrcode;
go命令调用do_go()函数,跳转到某个地址执行的。
如果在这个地址准备好了自引导的内核映像,就可以启动了。
尽管go命令可以带变参,实际使用时不用来传递参数。
zImage是自解压文件
2.bootm命令的实现支持多操作系统
/*common/cmd_bootm.c*/
intdo_bootm(cmd_tbl_t*cmdtp,intflag,intargc,char*argv[])
…………
/*检查头部*/
if(crc32(0,(uchar*)data,len)!
=checksum){
puts("
BadHeaderChecksum\n"
SHOW_BOOT_PROGRESS(-2);
return1;
/*解压缩*/
switch(hdr->
ih_comp){
caseIH_COMP_NONE:
if(ntohl(hdr->
ih_load)==addr){
printf("
XIP%s..."
name);
}else{
#ifdefined(CONFIG_HW_WATCHDOG)||defined(CONFIG_WATCHDOG)
size_tl=len;
void*to=(void*)ntohl(hdr->
ih_load);
void*from=(void*)data;
Loading%s..."
while(l>
0){
size_ttail=(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;
caseIH_COMP_GZIP:
printf("
Uncompressing%s..."
if(gunzip((void*)ntohl(hdr->
ih_load),unc_len,
(uchar*)data,&
len)!
puts("
GUNZIPERROR-mustRESETboardtorecover\n"
SHOW_BOOT_PROGRESS(-6);
do_reset(cmdtp,flag,argc,argv);
#ifdefCONFIG_BZIP2
caseIH_COMP_BZIP2:
/*
*Ifwe'
vegotlessthan4MBofmalloc()space,
*useslowerdecompressionalgorithmwhichrequires
*atmost2300KBofmemory.
*/
i=BZ2_bzBuffToBuffDecompress((char*)ntohl(hdr->
ih_load),
&
unc_len,(char*)data,len,
CFG_MALLOC_LEN<
(4096*1024),0);
if(i!
=BZ_OK){
BUNZIP2ERROR%d-mustRESETboardtorecover\n"
i);
udelay(100000);
#endif/*CONFIG_BZIP2*/
default:
if(iflag)
enable_interrupts();
Unimplementedcompressiontype%d\n"
hdr->
ih_comp);
SHOW_BOOT_PROGRESS(-7);
………………
switch(hdr->
ih_os){
/*handledby(original)Linuxcase*/
caseIH_OS_LINUX:
do_bootm_linux(cmdtp,flag,argc,argv,
addr,len_ptr,verify);
break;
caseIH_OS_NETBSD:
do_bootm_netbsd(cmdtp,flag,argc,argv,
caseIH_OS_RTEMS:
do_bootm_rtems(cmdtp,flag,argc,argv,
caseIH_OS_VXWORKS:
do_bootm_vxworks(cmdtp,flag,argc,argv,
caseIH_OS_QNX:
do_bootm_qnxelf(cmdtp,flag,argc,argv,
bootm命令调用do_bootm函数。
这个函数专门用来引导各种操作系统映像,可以支持引导Linux、vxWorks、QNX等操作系统。
引导Linux的时候,调用do_bootm_linux()函数。
3.do_bootm_linux函数的实现
/*lib_arm/armlinux.c*/
voiddo_bootm_linux(cmd_tbl_t*cmdtp,intflag,intargc,char*argv[],
ulongaddr,ulong*len_ptr,intverify)
theKernel=(void(*)(int,int,uint))ntohl(hdr->
ih_ep);
…………
/*weassumethatthekernelisinplace*/
\nStartingkernel...\n\n"
theKernel(0,bd->
bi_arch_number,bd->
bi_boot_params);
/*启动内核,传递启动参数*/
do_bootm_linux()函数是专门引导Linux映像的函数,它还可以处理ramdisk文件系统的映像。
这里引导的内核映像和ramdisk映像,必须是U-Boot格式的。
U-Boot格式的映像可以通过mkimage工具来转换,其中包含了U-Boot可以识别的符号。
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- Uboot 启动 流程 2440 视频 培训 电子 教案