学习韦东山视频之对u-boot的理解

来源:互联网 发布:体毛多 知乎 编辑:程序博客网 时间:2024/05/14 14:51

u-boot的主要目的就是启动内核

大部分的配置参数都是预先在include/configs/board_name.h下定义的,因此如果我们要移植我们自己的板子的话,这个文件必不可少,它描述了我们板子的配置情况如CPU型号,RAM大小等

 

SRCTREE:根目录下,源文件

mkconfig中[ "${BOARD_NAME}" ] ||BOARD_NAME="$1"的意思是如果BOARD_NAME没有被定义那么就执行BOARD_NAME="$1"否则不执行

$#:指令参数个数

在mkconfig中>表示新建一个文件,>>表示将该文件追加进去

脚本中if——fi,fi表示if的结束语句

start.S中主要做了什么工作:

1、设置CPU模式进入SVC32模式

2、关闭看门狗、屏蔽中断

3、设置栈指针

4、将代码复制到RAM中去

5、清除bss段

6、中断异常处理

u-boot第二部分代码是从\lib_arm\board.c中start_armboot()函数开始

主要是干了以下事情:

1、cpu, borad,interrupt的初始化,包括cache等,这些都于特定板子的配置有关。

2、环境变量的初始化

3、串口、控制台、RAM的初始化

4、在控制台上实时的显示系统配置等相关参数。

5、最后进入main_loop();函数(引导内核以及控制台)

u-boot命令的实现:

命令的实现主要是依靠main_loop中的run_commd函数来实现

run_command的主要流程:

1、把传进来的指令先\;解析,分割出一个个命令

2、提取参数(parse_line)

3、查找命令(find_cmd)

4、检测其参数

5、找到匹配的命令后,调用cmd_tbl_t->cmd执行

U-boot启动内核:

u-boot有个主函数main_loop(),它是通过发送命令来实现对内核的启动,启动过程如下:

1、向内核传递参数

2、从nand-flash读出内核放到SDRAM中kernel分区中运行

注意:u-boot的分区有4个:bootloader、param、kernel、root,这四个分区不是硬件分的,而是在u-boot程序中写死的。

上面说到mainloop函数是发送指令来启动内核的,没错,发送的指令为:

nandread.jffs2 0x30007FC0 kernel 将0x3007fc0中的数据复制到kernel分区中

bootm 0x30007fc0    从该地址启动内核

注:这里的read.jffs2并不是指定要什么特定的格式,而是用read.jffs2不需要块/页对齐,所以这个kernel的分区大小可以
参数中有两个值需要考虑,一个是加载地址,一个是入口地址

内核是uImage,它主要有头部和内核

头部主要是用于存放一些启动参数的比如说上面说到的加载地址和入口地址,执行命令需要先检测加载地址和内核真正存放的地址是否一样,如果不一样u-boot会把内核移动到加载地址所对应的地址

所以,加载地址不一定是程序中写的,也可以是0x31000000等等,只要它不影响到u-boot所用的空间就可以了(u-boot在SDRAM地址为0x33f4df74-0x34000000)

但为什么程序要写0x30007fc0,是因为当我们的内核正好处于头部指定的加载地址的话,那么就不用uboot的do_bootm函数来帮我们搬运内核了,这样可以节省启动时间(uImage的头部大小为64K)

bootm一共做了以下工作:

1.    读取头部
2.    将内核移动到加载地址
3.    启动内核
启动内核的关键函数是do_bootm中do_bootm_linux()这个函数调用thekernel函数

参数是通过标记列表tag来完成的,在程序中表示为:

setup_start_tag(bd);
setup_revision_tag (&params);
setup_memory_tags (bd);
setup_commandline_tag (bd, commandline);
setup_initrd_tag (bd, images->rd_start, images->rd_end);
setup_videolfb_tag ((gd_t *) gd);
setup_end_tag (bd);
这些函数是在do_bootm_linux中调用传递参数的

怎么传的呢?

内核跟u-boot设置好一个地址然后u-boot把数据保存在那里,然后内核过来取

Tag(标记列表)

存放的地址是在setup_start_tag (bd); 中params= (struct tag *) bd->bi_boot_params;这句话里bi_boot_params的值为0x30000100这句话在board_init中有所体现

每个标记列表最开始都会有一个头部大小,也就是这个列表的大小,然后是tag,之后是tag中的各种参数

0 0
原创粉丝点击