Exynos4412 Uboot 移植(四)—— Uboot引导内核过程分析

bootloader 要想启动内核,可以直接跳到内核的第一个指令处,即内核的起始地址,这样便可以完成内核的启动工作了。但是要想启动内核还需要满足一些条件,如下所示:

1、cpu 寄存器设置

    * R0 = 0
    * R1 = 机器类型 id
    * R2 = 启动参数在内存中的起始地址

2、cpu 模式

    * 禁止所有中断
    * 必须为SVC(超级用户)模式

3、Cache、MMU

    * 关闭 MMU
    * 指令Cache可以开启或者关闭
    * 数据Cache必须关闭

4、设备

    * DMA 设备应当停止工作

5、PC为内核的起始地址

     

      这些需求都由 boot loader 实现,在常用的 uboot 中完成一系列的初始化后最后通过 bootm 命令加载 linux 内核。bootm 向将内核映像从各种媒介中读出,存放在指定的位置;然后设置标记列表给内核传递参数;最后跳到内核的入口点去执行。


Uboot版本:u-boot-2013.01

一、bootm命令用法介绍如下:

       在 common/cmd_bootm.c 中可以看到bootm 的定义:


可以看到 bootm 命令使调用了do_bootm 函数

do_bootm 函数

在cmd_bootm.c 第586行可以看到do_bootm函数的定义(为方便阅读,对其中一些代码进行了删减,完整代码请阅读uboot源码):

[cpp]  view plain   copy
  在CODE上查看代码片 派生到我的代码片
  1. /*******************************************************************/  
  2. /* bootm - boot application image from image in memory */  
  3. /*******************************************************************/  
  4.   
  5. int do_bootm(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])  
  6. {  
  7.     ulong       iflag;  
  8.     ulong       load_end = 0;  
  9.     int     ret;  
  10.     boot_os_fn  *boot_fn;  
  11.   
  12.     if (bootm_start(cmdtp, flag, argc, argv))// 获取镜像信息  
  13.         return 1;  
  14.   
  15.     iflag = disable_interrupts(); // 关闭中断  
  16.   
  17.     usb_stop();// 关闭usb设备  
  18.   
  19.     ret = bootm_load_os(images.os, &load_end, 1);//加载内核  
  20.   
  21.     lmb_reserve(&images.lmb, images.os.load, (load_end - images.os.load));  
  22.   
  23.     if (images.os.type == IH_TYPE_STANDALONE) { //如有需要,关闭内核的串口  
  24.         if (iflag)  
  25.             enable_interrupts();  
  26.         /* This may return when 'autostart' is 'no' */  
  27.         bootm_start_standalone(iflag, argc, argv);  
  28.         return 0;  
  29.     }  
  30.   
  31.     boot_fn = boot_os[images.os.os];//获取启动参数  
  32.   
  33.     arch_preboot_os();//启动前准备  
  34.   
  35.     boot_fn(0, argc, argv, &images);//启动,不再返回  
  36.   
  37. #ifdef DEBUG  
  38.     puts("\n## Control returned to monitor - resetting...\n");  
  39. #endif  
  40.     do_reset(cmdtp, flag, argc, argv);  
  41.   
  42.     return 1;  
  43. }  
该函数的实现分为 3 个部分:

a -- 首先通过 bootm_start 函数分析镜像的信息;

b -- 如果满足判定条件则进入 bootm_load_os 函数进行加载;

c -- 加载完成后就可以调用 boot_fn 开始启动。

1、bootm_start

在cmd_bootm.c 第193行可以看到bootm_start函数的定义, 主要作用是填充内核相关信息

[cpp]  view plain   copy
  在CODE上查看代码片 派生到我的代码片
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值