mini2440系统移植篇之u-boot第二阶段C语言
来源:互联网 发布:网络视频监控施工方案 编辑:程序博客网 时间:2024/05/01 17:29
1. 第二阶段C语言
1.1. 初始化
由第一阶段汇编得知,最后跳到C语言的start_armboot,这个函数在lib_arm/board.c。
1.1.1. 全局结构体
程序一开始申请两个全局结构体gd和bd。gd是全局相关的变量,主要有波特率,环境变量地址,帧缓冲地址,还有一个flag。
typedefstructglobal_data {bd_t*bd;unsigned longflags;unsigned longbaudrate;unsigned longhave_console;/* serial_init() was called */unsigned longenv_addr;/* Address of Environment struct */unsigned longenv_valid;/* Checksum of Environment valid? */unsigned longfb_base;/* base address of frame buffer */#ifdef CONFIG_VFDunsigned charvfd_type;/* display type */#endifvoid**jt;/* jump table */} gd_t;/* * Global Data Flags */#defineGD_FLG_RELOC0x00001/* Code was relocated to RAM*/#defineGD_FLG_DEVINIT0x00002/* Devices have been initialized*/#defineGD_FLG_SILENT0x00004/* Silent mode*/#defineGD_FLG_POSTFAIL0x00008/* Critical POST test failed*/#defineGD_FLG_POSTSTOP0x00010/* POST seqeunce aborted*/#defineGD_FLG_LOGINIT0x00020/* Log Buffer has been initialized*/#define GD_FLG_DISABLE_CONSOLE0x00040/* Disable console (in & out) */bd主要是存储开发板信息,重要的有机器码arch_number,启动参数boot_params和内存配置,这些信息等到启动内核时,会传递给内核。typedef struct bd_info { intbi_baudrate;/* serial console baudrate */ unsigned longbi_ip_addr;/* IP Address */ struct environment_s *bi_env; ulong bi_arch_number;/* unique id for this board */ ulong bi_boot_params;/* where this board expects params */ struct/* RAM configuration */ {ulong start;ulong size; }bi_dram[CONFIG_NR_DRAM_BANKS];} bd_t;
bd主要是存储开发板信息,重要的有机器码arch_number,启动参数boot_params和内存配置,这些信息等到启动内核时,会传递给内核。
typedef struct bd_info { intbi_baudrate;/* serial console baudrate */ unsigned longbi_ip_addr;/* IP Address */ struct environment_s *bi_env; ulong bi_arch_number;/* unique id for this board */ ulong bi_boot_params;/* where this board expects params */ struct/* RAM configuration */ {ulong start;ulong size; }bi_dram[CONFIG_NR_DRAM_BANKS];} bd_t;
1.1.2. 硬件初始化
接下来是一个函数指针表,进行各种硬件初始化,其中比较重要的是板子初始化board_init、串口初始化serial_init。只要display_banner能打出信息,说明串口可以用了,这是为以后可以调试奠定了基础。除了这个函数指针数组,接下来还会有flash、网卡、环境变量等初始化。
init_fnc_t *init_sequence[] = {#if defined(CONFIG_ARCH_CPU_INIT)arch_cpu_init,/* basic arch cpu dependent setup */#endifboard_init,/* basic board dependent setup */#if defined(CONFIG_USE_IRQ)interrupt_init,/* set up exceptions */#endiftimer_init,/* initialize timer */env_init,/* initialize environment */init_baudrate,/* initialze baudrate settings */serial_init,/* serial communications setup */console_init_f,/* stage 1 init of console */display_banner,/* say that we are here */#if defined(CONFIG_DISPLAY_CPUINFO)print_cpuinfo,/* display cpu info (and speed) */#endif#if defined(CONFIG_DISPLAY_BOARDINFO)checkboard,/* display board info */#endif#if defined(CONFIG_HARD_I2C) || defined(CONFIG_SOFT_I2C)init_func_i2c,#endifdram_init,/* configure available RAM banks */#if defined(CONFIG_CMD_PCI) || defined (CONFIG_PCI)arm_pci_init,#endifdisplay_dram_config,NULL,};for (init_fnc_ptr = init_sequence; *init_fnc_ptr; ++init_fnc_ptr) {if ((*init_fnc_ptr)() != 0) {hang ();}}
1.2. 主循环
完成了相关的初始化后,u-boot进入一个死循环。
/* main_loop() can return to retry autoboot, if so just run it again. */
for (;;) {
main_loop ();
}
这个死循环获取环境变量bootdelay的值,然后进行倒计时,在这段时间内控制台有按键响应,则进入等待命令输入模式,超时根据bootcmd启动内核。我在这里加了一个run_command("menu",0),即进入命令模式后,执行一个菜单选项,用于一键升级内核-u-boot等操作,方便开发。
main_loop()
{
…
配置自动完成
获取bootdelay值
获取bootcmd值
没有按键按下,执行bootcmd启动内核,否则继续向下执行
run_command("menu",0); //==交互菜单
for()
{
len = readline (CONFIG_SYS_PROMPT); //==读输入
run_command (lastcommand, flag);
}
}
1.2.1. 加载内核
加载启动内核来至于run_command(bootcmd),首先是加载,把内核从flash拷贝到内存的指定位置。
加载内核
{
内核加载地址 image_header loader
内核运行地址 image_header ep
从Flash拷贝kernel到内存
nand read 内存地址(0x30007fc0) Flash偏移 大小
启动内核
bootm 内存地址(0x30008000)
}
1.2.2. 启动内核
启动内核,根据内核的编译地址和实际地址,决定要不要移动内核,启动内核之前,要设置给内核的参数,使用tag结构体。常用的保护5个tag,开头setup_start_tag结尾setup_end_tag ,内存setup_memory_tags,命令行setup_commandline_tag (bd, commandline),setup_initrd_tag (bd, images->rd_start, images->rd_end)。最后启动内核是一个函数指针theKernel = (void (*)(int, int, uint))images->ep;//image_header的入口地址,第一个参数固定是0,第2个是机器码,保存在上面提到的bd全局结构体,第三个是内核参数tag。bootloader巧妙地利用函数指针及传参规范将R0:0x0,R1:机器号,R2:参数地址传递给内核.
do_bootm
{
bootm_start
{
boot_get_kernel
{
memmove
}
xxx
do_bootm_linux
}
}
do_bootm_linux
{
theKernel = (void (*)(int, int, uint))images->ep;//image_header的入口地址
获取machid
在hyq2440.c board_init设置 gd->bd->bi_boot_params = 0x30000100;
这个就是tag起始地址
setup_start_tag (bd);
setup_memory_tags (bd);
setup_commandline_tag (bd, commandline); //根据bootargs设置tag
setup_initrd_tag (bd, images->rd_start, images->rd_end);
setup_end_tag (bd);
theKernel (0, machid, bd->bi_boot_params);
}
- mini2440系统移植篇之u-boot第二阶段C语言
- mini2440系统移植篇之u-boot分析
- mini2440系统移植篇之u-boot第一阶段汇编
- mini2440 u-boot 2009.11 系统移植
- u-boot移植(Mini2440)
- u-boot移植到mini2440之二
- u-boot移植到mini2440之三
- u-boot移植到mini2440之四
- U-boot-2009.03移植之十:第一阶段之修改/board/samsung/mini2440/mini2440.c
- u-boot移植到mini2440
- u-boot 第二阶段 硬件初始化之设置系统时钟
- U-BOOT 移植到友善之臂mini2440
- mini2440之U-Boot +linux+NFS文件系统移植
- 移植u-boot-2009.08到mini2440(一)基础配置篇
- u-boot第二阶段board.c分析
- u-boot系统移植
- U-boot-2009.03移植之十二:第二阶段——支持128M Nandflash
- u-boot-2009.11移植到mini2440(一)
- partioner编程
- Android生成带图片的二维码
- 一个简单的Python3爬虫获取两城市间铁路距离程序
- 【FreeMarker】四种变量的用法
- 破碎的砝码问题
- mini2440系统移植篇之u-boot第二阶段C语言
- 7.12
- 读《从0到1》
- leetcode_Search in Rotated Sorted Array II
- asp.net TextBox OnFocus OnBlur显示与消失
- Android studio导入开源项目
- 8.14
- 【BZOJ 4071】 [Apio2015]巴邻旁之桥
- uva 10048 Audiophobia floyd的变形