九、uboot 代码流程分析---board_init_f


  接着上一节,板子开始做前期初始化工作。

8.1 board_init_f

  board_f.c (common) 

 1 /* 板子初次初始化。boot_flags = 0 */
 2 void board_init_f(ulong boot_flags)
 3 {
 4     gd->flags = boot_flags;
 5     gd->have_console = 0;
 6 
 7     if (initcall_run_list(init_sequence_f))
 8         hang();
 9 
10 #if !defined(CONFIG_ARM) && !defined(CONFIG_SANDBOX) && \
11         !defined(CONFIG_EFI_APP) && !CONFIG_IS_ENABLED(X86_64)
12     /* NOTREACHED - jump_to_copy() does not return */
13     hang();
14 #endif
15 }

  boot_flags 标志位0,且终端标志位也为0,在 initcall_run_list(init_sequence_f) 链表中执行板子初始化过程

8.2 init_sequence_f 函数数组

 1 static init_fnc_t init_sequence_f[] = {
 2     setup_mon_len,      ///< 设置gd->mon_len为编译出来的u-boot.bin+bss段的大小
 3     initf_malloc,   ///< 设置内存池的大小 gd->malloc_limit = 0x400, gd->malloc_ptr = 0
 4     initf_console_record,   ///< 为空,直接返回 0
 5     arch_cpu_init,        ///< 基本arch cpu相关设置, 未做初始化 
 6     mach_cpu_init,        ///< SoC/machine 相关CPU设置, 未作设置
 7     initf_dm,           ///< 驱动模型的初始化, 未开宏
 8     arch_cpu_init_dm,   ///< 驱动模型相关的 CPU 初始化, 未开宏
 9     mark_bootstage,        /* need timer, go after init dm */
10 #if defined(CONFIG_BOARD_EARLY_INIT_F)
11     board_early_init_f, ///< 时钟和 GPIO 的初始化
12 #endif
13 
14 #if defined(CONFIG_ARM) || defined(CONFIG_MIPS) || \
15         defined(CONFIG_BLACKFIN) || defined(CONFIG_NDS32) || \
16         defined(CONFIG_SH) || defined(CONFIG_SPARC)
17     timer_init,        ///<  定时器初始化
18 #endif
19 
20     env_init,        ///<  initialize environment, 初始化环境变量结构体 default_environment
21                     ///< env_dataflash.c 中是此时的实际调用
22     init_baud_rate,        /* 波特率设置 */
23     serial_init,        /* 串行通信初始化 */
24     console_init_f,        /* 在重定位之前使能串口功能 */
25     display_options,    /* 打印 uboot 版本信息 */
26     display_text_info,    /* 打印 uboot 配置信息 */
27     print_cpuinfo,        /* 显示 CPU 信息 */
28 #if defined(CONFIG_DISPLAY_BOARDINFO)
29     show_board_info,    ///< 显示板子信息,需要复写函数
30 #endif
31     announce_dram_init, ///< 打印了一个 DRAM: 字符串
32     /* TODO: unify all these dram functions? */
33 #if defined(CONFIG_ARM) || defined(CONFIG_X86) || defined(CONFIG_NDS32) || \
34         defined(CONFIG_MICROBLAZE) || defined(CONFIG_AVR32) || \
35         defined(CONFIG_SH)
36     dram_init,        /* 配置 DRAM 大小, gd->ram_size =     0x04000000 , 即 64MB*/
37 #endif
38     /*
39      * Now that we have DRAM mapped and working, we can
40      * relocate the code and continue running from DRAM.
41      *
42      * Reserve memory at end of RAM for (top down in that order):
43      *  - area that won't get touched by U-Boot and Linux (optional)
44      *  - kernel log buffer
45      *  - protected RAM
46      *  - LCD framebuffer
47      *  - monitor code
48      *  - board info struct
49      */
50     setup_dest_addr,    ///< 重定位地址设置 gd->relocaddr = gd->ram_top = 0x3400 0000
51     reserve_round_4k,
52     reserve_trace,  ///< trace 设置,移动gd->relocaddr,未配置,不动
53 #if !defined(CONFIG_BLACKFIN) && !defined(CONFIG_XTENSA)
54     reserve_uboot,  ///< 留出 uboot.bin 的空间 gd->relocaddr 下移后, gd->start_addr_sp = gd->relocaddr
55 #endif
56 #ifndef CONFIG_SPL_BUILD
57     reserve_malloc,
58     reserve_board,
59 #endif
60     setup_machine,  ///< 不做初始化
61     reserve_global_data,    ///< 初始化 global_data 的空间,gd->start_addr_sp -= sizeof(gd_t);
62     reserve_fdt,    ///< 未开特性
63     reserve_arch,   ///< 未做任务
64     reserve_stacks, ///< gd->start_addr_sp 16字节对齐
65     setup_dram_config,  ///< DRAM配置前面已经做了
66     show_dram_config,   ///< 显示 DRAM 的大小 64M
67     display_new_sp, ///< 打印当前栈
68     reloc_fdt,  ///< 未作配置
69     setup_reloc,    ///< gd->reloc_off = gd->relocaddr reloc_off 设置为栈顶
70     NULL,
71 };

8.2.1 setup_mon_len

1 /* 设置gd->mon_len为编译出来的u-boot.bin+bss段的大小 */
2 static int setup_mon_len(void)
3 {
4     gd->mon_len = (ulong)&__bss_end - (ulong)_start;
5     return 0;
6 }

  _start 的地址为 0

8.2.2 initf_malloc

 1 /* 设置内存池的大小 */
 2 int initf_malloc(void)
 3 {
 4 #if CONFIG_VAL(SYS_MALLOC_F_LEN)
 5     assert(gd->malloc_base);    /* Set up by crt0.S */
 6     gd->malloc_limit = CONFIG_VAL(SYS_MALLOC_F_LEN);
 7     gd->malloc_ptr = 0;
 8 #endif
 9 
10     return 0;
11 }

 8.2.3 设置重定位地址---setup_dest_addr

 1 /* 设置重定位地址 */
 2 static int setup_dest_addr(void)
 3 {
 4     debug("Monitor len: %08lX\n", gd->mon_len);
 5     /*
 6      * Ram is setup, size stored in gd !!
 7      */
 8     debug("Ram size: %08lX\n", (ulong)gd->ram_size);
 9 #ifdef CONFIG_SYS_SDRAM_BASE         /* JZ2440 = CONFIG_SYS_SDRAM_BASE = 0x30000000 */
10     gd->ram_top = CONFIG_SYS_SDRAM_BASE;
11 #endif
12     gd->ram_top += get_effective_memsize(); /* gd->ram_top = 0x30000000 + 0x400 0000 = 0x3400 0000 */
13     /* 此段依然返回 SDRAM 顶端地址 0x3400 0000 */
14     gd->ram_top = board_get_usable_ram_top(gd->mon_len);
15     gd->relocaddr = gd->ram_top;    /* 重定位地址为  0x3400 0000 */
16     debug("Ram top: %08lX\n", (ulong)gd->ram_top);
17     return 0;
18 }

  gd->relocaddr = 0x34000000 指向 SDRAM 的顶端

8.2.4 uboot 和 bss段---reserve_uboot

 1 /* 预留 uboot 区,gd->start_addr_sp = gd->relocaddr -= gd->mon_len  */
 2 static int reserve_uboot(void)
 3 {
 4     /*
 5      * reserve memory for U-Boot code, data & bss
 6      * round down to next 4 kB limit
 7      */
 8     gd->relocaddr -= gd->mon_len;
 9     gd->relocaddr &= ~(4096 - 1);
10 #if defined(CONFIG_E500) || defined(CONFIG_MIPS)
11     /* round down to next 64 kB limit so that IVPR stays aligned */
12     gd->relocaddr &= ~(65536 - 1);
13 #endif
14 
15     debug("Reserving %ldk for U-Boot at: %08lx\n", gd->mon_len >> 10,
16           gd->relocaddr);
17 
18     gd->start_addr_sp = gd->relocaddr;
19 
20     return 0;
21 }

  栈 gd->start_addr_sp 指向 uboot 段 基地址

8.2.5 堆区---reserve_malloc

 1 /* malloc 堆区预留大小 */
 2 static int reserve_malloc(void)
 3 {
 4     /*  PHYS_FLASH_1 = 0x00000000
 5         CONFIG_SYS_FLASH_BASE = PHYS_FLASH_1
 6         CONFIG_ENV_ADDR = CONFIG_SYS_FLASH_BASE + 0x070000 = 0x070000
 7         CONFIG_ENV_IS_IN_FLASH
 8         CONFIG_ENV_SIZE = 0x10000 */
 9     /* CONFIG_SYS_MALLOC_LEN = 4 * 1024 * 1024 = 0x40 0000 */
10     /* TOTAL_MALLOC_LEN = CONFIG_SYS_MALLOC_LEN */
11     gd->start_addr_sp = gd->start_addr_sp - TOTAL_MALLOC_LEN;
12     debug("Reserving %dk for malloc() at: %08lx\n",
13           TOTAL_MALLOC_LEN >> 10, gd->start_addr_sp);
14     return 0;
15 }

  栈 gd->start_addr_sp 指向 malloc 段 基地址

8.2.6 预留 bd 区域 --- reserve_board

 1 /* board 信息结构体分配区域 */
 2 static int reserve_board(void)
 3 {
 4     if (!gd->bd) {
 5         gd->start_addr_sp -= sizeof(bd_t);
 6         gd->bd = (bd_t *)map_sysmem(gd->start_addr_sp, sizeof(bd_t));
 7         memset(gd->bd, '\0', sizeof(bd_t));
 8         debug("Reserving %zu Bytes for Board Info at: %08lx\n",
 9               sizeof(bd_t), gd->start_addr_sp);
10     }
11     return 0;
12 }

  栈 gd->start_addr_sp 指向 bd 段 基地址

8.2.7 预留全局数据区域---reserve_global_data

1 /* 预留 GD 区域 */
2 static int reserve_global_data(void)
3 {
4     gd->start_addr_sp -= sizeof(gd_t);
5     gd->new_gd = (gd_t *)map_sysmem(gd->start_addr_sp, sizeof(gd_t));
6     debug("Reserving %zu Bytes for Global Data at: %08lx\n",
7           sizeof(gd_t), gd->start_addr_sp);
8     return 0;
9 }

  栈 gd->start_addr_sp 指向 gd 段 基地址

8.2.8 栈区预留区---reserve_stacks

 1 /* 栈区预留区,gd->start_addr_sp 指向 栈底基地址 */
 2 static int reserve_stacks(void)
 3 {
 4     /* make stack pointer 16-byte aligned */
 5     gd->start_addr_sp -= 16;
 6     gd->start_addr_sp &= ~0xf;
 7 
 8     /*
 9      * let the architecture-specific code tailor gd->start_addr_sp and
10      * gd->irq_sp
11      */
12     return arch_reserve_stacks();
13 }

  gd->start_addr_sp 指向 栈底基地址 

8.3 小节

  代码执行完后,则返回,当前栈地址指向栈处,依然有大部分区域未分配。

  当前分配的区域如下:

  


免责声明!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系本站邮箱yoyou2525@163.com删除。



 
粤ICP备18138465号  © 2018-2025 CODEPRJ.COM