接着上一节,板子开始做前期初始化工作。
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 小节
代码执行完后,则返回,当前栈地址指向栈处,依然有大部分区域未分配。
当前分配的区域如下: