u-boot启动文件

Posted zongzi10010

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了u-boot启动文件相关的知识,希望对你有一定的参考价值。

目录


title: u-boot(三)启动文件
tags: linux
date: 2018-09-24 20:56:05
---

u-boot(三)启动文件

汇编

cpu/arm920t/start.S

u-boot也是一个牛逼的单片机程序,所以也就需要:

  1. 硬件相关初始化
    1. 看门狗
    2. 时钟
    3. sdram
    4. nand copy程序
  2. 设置sp
  3. 接下去就是读取内核,启动内核等

程序实际的步骤是:

1.set the cpu to SVC32 mode
2.turn off the watchdog
3.mask all IRQs
4.判断是不是从内部ram启动还是仿真直接烧写到链接地址,如果不在正确的加载地址的话,执行cpu_init_crit
  cpu_init_crit执行SDRAM初始化
    flush v4 I/D caches,
    disable MMU stuff and caches,
    lowlevel_init 这个会去初始化sdram,这个函数在lowlevel_init.S in your board directory
                    也就是board100ask24x0lowlevel_init.S
5.Set up the stack
6.clock_init        board100ask24x0oot_init.c
7.relocate           自动识别当前是nor还是nand启动,nand启动时自动cp到内部ram中运行,所以可写
8.bss段清零
9.调用C函数 _start_armboot

堆栈设置如下

0x33F80000 uboot程序
·=-CFG_MALLOC_LEN malloc area
.=-CFG_GBL_DATA_SIZE bdinfo
.=-CONFIG_STACKSIZE_IRQ IRQ 的栈
.=-CONFIG_STACKSIZE_FIQ FRQ的栈
.=-12 leave 3 words for abort-stack
sp的初始位置

内存图:

技术分享图片

C:_start_armboot

文件路径:lib_armoard.c,这里就是u-boot执行C代码的地方了.

  • 分配了一个gd的结构体内存

    gd = (gd_t*)(_armboot_start - CFG_MALLOC_LEN - sizeof(gd_t));
    
    //在这里,_armboot_start=_start,根据链接脚本,这也就是代码段的起始=0x33F80000
    //也就是指向了内存图128的地方了
  • init_sequence这里执行一些初始化

    • board_init中设置了gd->bd->bi_arch_number = MACH_TYPE_S3C2440;,设置了一个参数gd->bd->bi_boot_params = 0x30000100;这个就是启动内核参数的地址
  • flash/nand 初始化

  • 堆栈初始化

  • 环境变量的设置存储(一种是代码写死,一种在FLASH上保存)
  • 进入主循环main_loop

代码摘要

void start_armboot (void)
{
//-----
    /* Pointer is writable since we allocated a register for it */
    gd = (gd_t*)(_armboot_start - CFG_MALLOC_LEN - sizeof(gd_t));    
//-----    
    //函数指针,初始化设备
    for (init_fnc_ptr = init_sequence; *init_fnc_ptr; ++init_fnc_ptr) {
        if ((*init_fnc_ptr)() != 0) {
            hang ();
        }
    }
//----  flash初始化,识别    
#ifndef CFG_NO_FLASH
    /* configure available FLASH banks */
    size = flash_init ();
    display_flash_config (size);
#endif /* CFG_NO_FLASH */    
////----  nand初始化   
#if (CONFIG_COMMANDS & CFG_CMD_NAND)
    puts ("NAND:  ");
    nand_init();        /* go init the NAND */
#endif
//------
    //分配堆
    /* armboot_start is defined in the board-specific linker script */
    mem_malloc_init (_armboot_start - CFG_MALLOC_LEN);
//-----
    //uboot的环境变量
    /* initialize environment */
    env_relocate ();
//-----
    //经过一系列的初始化
    /* main_loop() can return to retry autoboot, if so just run it again. */
    for (;;) {
        main_loop ();

}


init_fnc_t *init_sequence[] = {
    cpu_init,       /* basic cpu dependent setup */
    board_init,     /* basic board dependent setup */
    interrupt_init,     /* set up exceptions */
    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
    dram_init,      /* configure available RAM banks */
    display_dram_config,
    NULL,
};

int board_init (void)
{
    ---
    /* support both of S3C2410 and S3C2440, by www.100ask.net */
    if (isS3C2410)
    {
        /* arch number of SMDK2410-Board */
        gd->bd->bi_arch_number = MACH_TYPE_SMDK2410;
    }
    else
    {
        /* arch number of SMDK2440-Board */
        gd->bd->bi_arch_number = MACH_TYPE_S3C2440;
    }

    /* adress of boot parameters */
    gd->bd->bi_boot_params = 0x30000100;

}

C:main_loop

common/main.c

内核启动

这里实现了u-boot的倒计时,有打印命令,获取环境变量等,最关键的代码是

s = getenv ("bootcmd");    
if(倒计时结束)
{
    printf("Booting Linux ...
");            
    run_command (s, 0);
 }

实际的环境变量是bootcmd=nand read.jffs2 0x30007FC0 kernel; bootm 0x30007FC0,读取内核,启动内核

菜单处理(自定义实现)

如果倒计时结束前输入了空格,进入命令模式run_command("menu", 0);

命令处理

  1. 死循环
  2. 读取串口输入len = readline (CFG_PROMPT);
  3. 执行命令rc = run_command (lastcommand, flag);



以上是关于u-boot启动文件的主要内容,如果未能解决你的问题,请参考以下文章

移值2016的u-boot-第2篇-支持Nand flash启动

u-boot内核启动

U-Boot之启动第一阶段

u-boot从nand 启动时的问题解决记录

u-boot移植---代码修改---时钟修改SDRAM

嵌入式Linux9.U-Boot启动流程详解