这里先对我们的sd卡和内存的存储分布进行描述:
1 总内存为:0x30000000~0x40000000和0x40000000~0x50000000共512MB
uboot占用内存2MB,起始地址:0xc3e00000
启动时会将ZIMAGE放置0x30008000
将tag信息放置0x30000100
2 sd卡存储分布:存储信息定义include/movi.h
1~17(block) BL1 8KB
17~49(block) ENV 16KB
49~1073 BL2 512KB
1073~9265 ZIMAGE 4MB
9265~62513 ROOTFS 26MB
uboot第一阶段通过长跳转进入start_armboot函数即进入第二阶段,该函数位于lib_arm/board.c
此时整个完整的uboot在内存空间0xc3e00000处占2MB
1 463~479 uboot堆空间向下偏移方式分配空间给gd和gd->bd指针的数据结构,
gd的定义在70行:DECLARE_GLOBAL_DATA_PTR即gd绑定寄存器r8
2 483开始遍历init_sequence数组中的函数指针
3 遍历1:cpu_init 位于cpu/s5pc11x/cpu.c 这里什么也没做
4 遍历2:board_init 位于board/samsung/x210/x210.c 这里初始化网卡DM9000的一些寄存器
gd->bd->bi_arch_number赋值(机器码2456)gd->bd->bi_boot_params赋值(内核传参内存地址)(0x3000 0100)
5 遍历3:interrupt_init 位于cpu/s5pc11x/interrupts.c 将timer4定时为10ms一次溢出。
6 遍历4:env_init 位于common/env_auto.c ENV_IS_EMBEDDED宏未定义,
将gd->env_addr赋值为内存中默认的环境变量的首地址,gd->env_valid = 1(表明环境变量可用);
7 遍历5:init_baudrate 位于lib_arm/board.c 将环境变量中的波特率赋值给gd->bd->bi_baudrate = gd->baudrate
8 遍历6:serial_init 位于cpu/s5pc11x/serial.c 这里什么也没做
9 遍历7:console_init_f 位于common/console.c 这里只将gd->have_console = 1;
10 遍历8:display_banner 位于common/board.c 用串口打印版本信息。此时控制台未初始化printf会调用serial_puts输出
打印信息为“U-Boot 1.3.4 (Nov 5 2019 - 20:45:46) for x210”
11 遍历9:print_cpuinfo 位于cpu/s5pc11x/s5pc11o/speed.c 用于打印cpu时钟信息还打印"Serial = CLKUART "
12 遍历10:checkboard位于board/samsung/x210/x210.c中用于打印板子版本这里是printf(" Board: X210 ");
13 遍历11:dram_init 位于board/samsung/x210/x210.c就是gd->bd->bi_dram[]这个结构体进行赋值
14 遍历12:display_dram_config 位于lib_arm/board.c 用于计算dram的大小并且将其打印出来,同时遍历结束。
15 490~494 为详细分析会打印“Flash: 8 MB”
16 496~523 未编译
17 527 初始化堆管理器由于栈是向下减的所以我们设置栈在堆得上面 CFG_MALLOC_LEN=912KB
18 600~633 初始化mmc其实就是初始化mmc的结构体,这里根据我们的配置初始化了通道0和2对应的结构体为mmc_channel[0],mmc_channel[2]
并将其加入mmc_devices全局链表,我们还打印了通道2的容量“SD/MMC: 15193MB”
19 777行env_relocate (),初始化环境变量。先malloc一段内存作为环境变量空间,从sd中读取环境变量crc检验出错则用系统定义的环境变量,
将gd->env_addr指向这段内存空间。
20 789行从环境变量中获取IP地址赋值给gd->bd->bi_ip_addr
21 792~817从环境变量获取MAC地址赋值给gd->bd->bi_enetaddr[]
22 819行devices_init该函数位于common/devices.c,首先devlist是ListStruct结构体的二维指针,分配ListStruct和ListStruct一维指针空间
并被devlist指向,并在devlist中注册串口设备
23 825行jumptable_init ();将二维函数指针gd->jt 指向分配的函数指针空间,并填充函数
24 827行console_init_r控制台初始化,将标准输入,输出,错误的设备文件指针stdio_devices[0~2]设置为加入设备列表的串口设备指针
同时将gd->jt中相应的输入输出函数设置为串口的输入输出函数,gd->flags |= GD_FLG_DEVINIT表明最基本的系统设备已添加成功
同时打印: In: serial Out: serial Err: serial,表示可以使用标准输入输出设备,这里是指向串口设备
25 836行enable_interrupts函数为空,因为把中断的宏关了,uboot一般不需要中断
26 857~863从环境变量中读取"loadaddr"和"bootfile"分别赋值给全局变量load_addr和BootFile,因为环境变量中未设置所以保持原样
这两个变量与系统的启动有关
27 867行board_late_init函数为空
28 873行eth_initialize函数为空
28 888行x210_preboot_init初始化LCD,打印LOGO
29 893~906行判断进入启动模式还是更新模式,启动模式则进入main_loop
30 397~412进入启动倒计时,按下任意键打断启动进入shell模式
31 输入movi read kernel 30008000命令从sd卡中读取ZIMAGE到30008000中
32 输入bootm 30008000启动先进入do_bootm校验ZIMAGE文件调用do_bootm_linux
从环境变量中获取bootargs和machid将bootargs和内存容量。。。等信息分别制作成tag存放在0x30000100中
跳转内核入口传参为 0 机器码 tag地址