第二阶段从lib_arm/board.c中的start_armboot函数开始,先看从这个函数开始的程序流程图。
图3 U-Boot第二阶段流程图
移植U-Boot的主要工作在于对硬件的初始化、驱动,所以下面讲解时将重点放在硬件的操作上。
(1)初始化本阶段要使用到的硬件设备。:最主要的是设置系统时钟、初始化串口,只要这两个设置好了,就可以从串口看到打印信息。
board_init函数设置MPLL、改变系统时钟,它是开发板相关的函数,在board/smdk2410/smdk2410.c中实现。值得注意的是,board_init函数中还保存了机器类型ID,这将在调用内核时传给内核,代码如下:
/* arch number of SMDK2410-Board */
gd->bd->bi_arch_number = MACH_TYPE_SMDK2410; /* 值为193 */
串口的初始化函数主要是serial_init,它设置UART控制器,是CPU相关的函数,在cpu/arm920t/s3c24x0/serial.c中实现。文件系统转换
(2)检测系统内存映射(memory
map)。对于特定的开发板,其内存的分布是明确的,所以可以直接设置。board/smdk2410/smdk2410.c中的dram_init函数
指定了本开发板的内存起始地址为0x30000000,大小为0x4000000。代码如下:
int dram_init (void)
{
gd->bd->bi_dram[0].start = PHYS_SDRAM_1;/* 即0x300000000 */
gd->bd->bi_dram[0].size = PHYS_SDRAM_1_SIZE;/* 即0x4000000 */
return 0;
}
这些设置的参数,将在后面向内核传递参数时用到。
(3)U-Boot命令的格式。
从图3可以知道,即使是内核的启动,也是通过U-Boot命令来实现的。U-Boot中每个命令都通过U_BOOT_CMD宏来定义,格式如下:
U_BOOT_CMD(name,maxargs,repeatable,command,"usage","help")
各项参数的意义为:
① name:命令的名字,注意,它不是一个字符串(不要用双引号括起来)。
② maxargs:最大的参数个数
③ repeatable:命令是否可重复,可重复是指运行一个命令后,下次敲回车即可再次运行。
④ command:对应的函数指针,类型为(*cmd)(struct cmd_tbl_s *, int, int, char *[])。
⑤ usage:简短的使用说明,这是个字符串。
⑥ help:较详细的使用说明,这是个字符串。
宏U_BOOT_CMD在include/command.h中定义:
#define U_BOOT_CMD(name,maxargs,rep,cmd,usage,help) \
cmd_tbl_t __u_boot_cmd_##name Struct_Section = {#name, maxargs, rep, cmd, usage, help}
Struct_Section也是在include/command.h中定义:
#define Struct_Section __attribute__ ((unused,section (".u_boot_cmd")))
比如对于bootm命令,它如此定义:
U_BOOT_CMD(
本文来自电脑杂谈,转载请注明本文网址:
http://www.pc-fly.com/a/jisuanjixue/article-66092-14.html
对这种日子是满意的
践踏别国疆域主权的霸道行为