uboot 读书笔记【1】

来源:互联网 发布:mac版围棋对弈软件 编辑:程序博客网 时间:2024/06/06 19:00

UBoot user-customization 过程 ( for a certain medical system)

-u中基本变量和其展开过程

  • 输入make smdk2416_config
  • 跳转到目标位置
    smd2416_config: unconfig        $(MKCONFIG) $(@:_config=) arm xxx xx xxx        #跳入makeconfig
  • mkconfig 确定基本变量 ARCH,CPU,BOARD 【建立必要链接】,
    export出相关变量;变量导入到config.mk.基本配置完成
  • 输入make启动编译

以上是UBOOT的基本流程


链接和运行过程.

  • 根据运行的过程来看UBOOT是怎么完成它的功能的。
Created with Raphaël 2.1.2start.Sstart_armboot()(lib_arm/board.c)init_sequence()mainloop()dobootm(),liuxdobootm()
  • start.S ()一般在cpu目录下。 体系结构相关的代码里面。为上电后前期布局使用。注意代码跳转的地方:
    relocate:                                       adr     r0, _start           ldr     r1, _TEXT_BASE        ldr     r1, _TEXT_PHY_BASE         ldr     r2, _armboot_start        ldr     r3, _bss_start        sub     r2, r3, r2             add     r2, r0, r2     
  • start_armboot() 与板载内容相关,一般为初始化板载设备的,如串口,USB,LCD,NAND等之类的设备。位于lib_arm目录下board.c中。核心部分代码如下: gd参考这里;
void start_armboot (void){    init_fnc_t **init_fnc_ptr;//初始化的函数表    char *s;    gd_base = CFG_UBOOT_BASE + CFG_UBOOT_SIZE - CFG_MALLOC_LEN - CFG_STACK_SIZE - sizeof(gd_t);    gd = (gd_t*)(_armboot_start - CFG_MALLOC_LEN - sizeof(gd_t));    /* compiler optimization barrier needed for GCC >= 3.4 */    __asm__ __volatile__("": : :"memory");    memset ((void*)gd, 0, sizeof (gd_t));    gd->bd = (bd_t*)((char*)gd - sizeof(bd_t));    memset (gd->bd, 0, sizeof (bd_t));    monitor_flash_len = _bss_start - _armboot_start;    for (init_fnc_ptr = init_sequence; *init_fnc_ptr; ++init_fnc_ptr) {        if ((*init_fnc_ptr)() != 0) {            hang ();        }    }//各种初始化函数的执行, init_fnc_ptr 就在board.c中    mem_malloc_init (_armboot_start - CFG_MALLOC_LEN);    nand_init();//nand 初始化    /* IP Address */    gd->bd->bi_ip_addr = getenv_IPaddr ("ipaddr");    /* MAC Address */    {        int i;        ulong reg;        char *s, *e;        char tmp[64];        i = getenv_r ("ethaddr", tmp, sizeof (tmp));        s = (i > 0) ? tmp : NULL;        for (reg = 0; reg < 6; ++reg) {            gd->bd->bi_enetaddr[reg] = s ? simple_strtoul (s, &e, 16) : 0;            if (s)                s = (*e) ? e + 1 : e;        }#ifdef CONFIG_HAS_ETH1        i = getenv_r ("eth1addr", tmp, sizeof (tmp));        s = (i > 0) ? tmp : NULL;        for (reg = 0; reg < 6; ++reg) {            gd->bd->bi_enet1addr[reg] = s ? simple_strtoul (s, &e, 16) : 0;            if (s)                s = (*e) ? e + 1 : e;        }#endif//网络初始化    devices_init ();    /* get the devices list going. */ //设备初始化       jumptable_init ();  //跳转表初始化    console_init_r ();  /* fully init console as a device */ //terminal    /* enable exceptions */    enable_interrupts (); //中断    /* main_loop() can return to retry autoboot, if so just run it again. */    for (;;) {        main_loop ();    }    /* NOTREACHED - no way out of command loop except booting */}
  • init_sequence 函数
    init_sequence就是指的上面的那个init_fnc_ptr的初始化过程,init_fnc_ptr的列表如下(ARM的)
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 */    dram_init,      /* configure available RAM banks */    display_dram_config,    NULL,};
  • main_loop()
    前期一系列的初始化之后,进入main_loop主循环,main_loop只有两件事,一是 如果没什么事儿uboot进入内核启动,如果需要在uboot下配置,那就进入uboot的命令行。main_loop函数位于:/common/main.c中 As follows: ( 更细致的分析可以参考这里)
void main_loop (void){    run_command (p, 0);#if defined(CONFIG_BOOTDELAY) && (CONFIG_BOOTDELAY >= 0)    s = getenv ("bootdelay");    bootdelay = s ? (int)simple_strtol(s, NULL, 10) : CONFIG_BOOTDELAY;    debug ("### main_loop entered: bootdelay=%d\n\n", bootdelay);    s = getenv ("bootcmd");    debug ("### main_loop: bootcmd=\"%s\"\n", s ? s : "<UNDEFINED>");    if (bootdelay >= 0 && s && !abortboot (bootdelay)) {        parse_string_outer(s, FLAG_PARSE_SEMICOLON |                    FLAG_EXIT_FROM_LOOP);    }#endif  /* CONFIG_BOOTDELAY */    for (;;) {        len = readline (CFG_PROMPT);        flag = 0;   /* assume no special flags for now */        if (len > 0)            strcpy (lastcommand, console_buffer);        else if (len == 0)            flag |= CMD_FLAG_REPEAT;        if (len == -1)            puts ("<INTERRUPT>\n");        else            rc = run_command (lastcommand, flag);        if (rc <= 0) {            /* invalid command or not repeatable, forget it */            lastcommand[0] = 0;        }    }#endif /*CFG_HUSH_PARSER*/}
0 0
原创粉丝点击