码迷,mamicode.com
首页 > 系统相关 > 详细

七,移植linux-3.9.9内核

时间:2018-08-16 01:04:25      阅读:538      评论:0      收藏:0      [点我收藏+]

标签:3.2   conf   xxx   结构   image   code   env   tco   交叉编译   

文档时间:2018-08-15

交叉编译器:arm-linux-gcc-4.3.2

Ubuntu版本:16.04

kernel版本:linux-3.9.9

 

1,分析 uboot 如何启动内核

通过之前对环境变量保存的分析可知,uboot是通过 bootcmd 来启动内核的,在 include/configs/jz2440.h 中我们有定义:

#define CONFIG_BOOTCOMMAND "nand read 0x30000000 kernel; bootm 0x30000000" //bootcmd  

有以下图片可知:执行 bootcmd 时,会将内核代码从nand 读到内存30000000 处,然后开始执行。 

技术分享图片

 由于要执行 bootm 命令,所以我们需要打开与 bootm 命令相关的文件进行分析,从名字可知,需要打开 cmd_bootm.c (位于 common 目录下)文件,找到对应的 do_bootm 函数:

(PS:一般与 xxx 命令相关的文件都在 common 目录下,名为cmd_xxx.c)

技术分享图片

如上图,可以看出,do_bootm 会执行 boot_os 里的所有函数,进入到 boot_os 结构体中:

技术分享图片

发现,虽然函数很多,但是与启动内核有关的只有 do_bootm_linux 函数,进入到 do_bootm_linux 函数 (位于 arch/arm/lib/bootm.c 文件中):

技术分享图片

发现 do_bootm_linux 函数最终会 跳转执行 boot_prep_linux 和 boot_jump_linux 函数,首先分析 boot_prep_linux 函数(位于 bootm.c 文件中):

static void boot_prep_linux(bootm_headers_t *images)
{
    char *commandline = getenv("bootargs");      //从环境变量中获取 bootargs 的值

  。。。。。。。
        setup_board_tags(&params);      
        setup_end_tag(gd->bd);    //将 tag 参数保存在指定位置
    } else {
        printf("FDT and ATAGS support not compiled in - hanging\n");
        hang();
    }
    do_nonsec_virt_switch();
}

 

 从代码可以看出来,boot_prep_linux,主要功能是将 tag 参数保存到指定位置,比如 bootargs 环境变量 tag,串口 tag

接下来分析 boot_jump_linux 函数(位于 bootm.c 文件中):

static void boot_jump_linux(bootm_headers_t *images, int flag)
{
    unsigned long machid = gd->bd->bi_arch_number;      //获取机器id (在 board/samsung/jz2440/jz2440.c 中设置,为 MACH_TYPE_SMDK2410(193))
    char *s;
    void (*kernel_entry)(int zero, int arch, uint params);
    unsigned long r2;
    int fake = (flag & BOOTM_STATE_OS_FAKE_GO);

    kernel_entry = (void (*)(int, int, uint))images->ep;    //获取 kernel的入口地址,此处应为 30000000

    s = getenv("machid");        //从环境变量里获取机器id (本例中还未在环境变量里设置过机器 id)
    if (s) {            //判断环境变量里是否设置机器id
        strict_strtoul(s, 16, &machid);    //如果设置则用环境变量里的机器id
        printf("Using machid 0x%lx from environment\n", machid);
    }

    debug("## Transferring control to Linux (at address %08lx)"         "...\n", (ulong) kernel_entry);
    bootstage_mark(BOOTSTAGE_ID_RUN_OS);
    announce_and_cleanup(fake);

    if (IMAGE_ENABLE_OF_LIBFDT && images->ft_len)
        r2 = (unsigned long)images->ft_addr;
    else
        r2 = gd->bd->bi_boot_params;    //获取 tag参数地址,gd->bd->bi_boot_params在 setup_start_tag 函数里设置
if (!fake) kernel_entry(0, machid, r2); }  //进入内核

 

通过分析可以看出,最终进入内核的函数为 :

kernel_entry(0, machid, r2)

该函数向内核传递了三个参数,分别为:

(1),0  (2),机器id  (3),参数列表地址,即 tag 地址

 到此 uboot 的任务就结束了,接下来内核代码便开始执行

 

2,移植 kernel-3.9.9

1),下载 3.9.9内核源码

下载地址为:https://mirrors.edge.kernel.org/pub/linux/kernel/

然后拷贝到 Ubuntu 中(可以用FileZilla Client工具拷贝),输入以下命令进行解压:

tar -zxvf linux-3.9.9.tar.gz 

 

2),配置,编译内核

 

七,移植linux-3.9.9内核

标签:3.2   conf   xxx   结构   image   code   env   tco   交叉编译   

原文地址:https://www.cnblogs.com/zhyy-mango/p/9477973.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!