接着上一节,板子开始做前期初始化工作。
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 const init_fnc_t init_sequence_f[] = { 2 setup_mon_len, /* 设置gd->mon_len为编译出来的u-boot.bin+bss段的大小 */ 3 initf_malloc, /* 设置内存池的大小 */ 4 log_init, /* log 设置初始化 */ 5 initf_bootstage, /* uses its own timer, so does not need DM,前置板级初始化启动时间设置 */ 6 initf_console_record,/* 平台信息记录初始化 */ 7 arch_cpu_init, /* basic arch cpu dependent setup */ 8 mach_cpu_init, /* SoC/machine dependent CPU setup */ 9 initf_dm, /* dm 初始化 */ 10 arch_cpu_init_dm, 11 #if defined(CONFIG_BOARD_EARLY_INIT_F) 12 board_early_init_f, /* 时钟和GPIO口设置 */ 13 #endif 14 #if !defined(CONFIG_M68K) 15 timer_init, /* initialize timer, 初始化定时器 */ 16 #endif 17 env_init, /* initialize environment, 初始化环境变量的地址 */ 18 init_baud_rate, /* initialze baudrate settings,初始化波特率设置 */ 19 serial_init, /* serial communications setup,串口初始化 */ 20 console_init_f, /* stage 1 init of console,在重定位之前使能串口功能 */ 21 display_options, /* say that we are here,打印当前banner 信息 */ 22 display_text_info, /* show debugging info if required,显示 debug 信息 */ 23 #if defined(CONFIG_DISPLAY_CPUINFO) 24 print_cpuinfo, /* display cpu info (and speed),显示CPU信息 */ 25 #endif 26 #if defined(CONFIG_DISPLAY_BOARDINFO) 27 show_board_info, /* 显示板子信息 */ 28 #endif 29 INIT_FUNC_WATCHDOG_INIT 30 INIT_FUNC_WATCHDOG_RESET 31 announce_dram_init, /* 准备显示 DRAM 大小 */ 32 dram_init, /* configure available RAM banks,DRAM 初始化,打印DRAM大小 */ 33 INIT_FUNC_WATCHDOG_RESET 34 INIT_FUNC_WATCHDOG_RESET 35 setup_dest_addr, /* 设置重定位地址,gd->relocaddr = 0x3400 0000 */ 36 reserve_round_4k, /* 4 字节对齐 */ 37 #ifdef CONFIG_ARM 38 reserve_mmu, /* 预留 MMU 区域,gd->relocaddr = 0x33FF 0000 */ 39 #endif 40 reserve_video, /* 预留 video 区,JZ2440 没开启 */ 41 reserve_trace, /* 预留 trace 区,JZ2440 没开启 */ 42 reserve_uboot, /* 预留 uboot 区,gd->start_addr_sp = gd->relocaddr -= gd->mon_len */ 43 reserve_malloc, /* 预留堆区,大小为 4M gd->start_addr_sp 指向 malloc 段基地址*/ 44 reserve_board, /* board 信息结构体分配区域 栈 gd->start_addr_sp 指向 bd 段 基地址*/ 45 setup_machine, /* /* 板子ID 如果定义则有,JZ2440 没有定义 */ */ 46 reserve_global_data,/* 预留 GD 区域,栈 gd->start_addr_sp 指向 gd 段 基地址*/ 47 reserve_fdt, /* 预留设备树区域,JZ2440 不涉及 */ 48 reserve_bootstage, /* 启动阶段区域,JZ2440 不涉及 */ 49 reserve_arch, /* 架构相关预留区,JZ2440 不涉及 */ 50 reserve_stacks, /* 栈区预留区,gd->start_addr_sp 指向 栈底基地址 */ 51 dram_init_banksize, /* DRAM 的大小初始化 */ 52 show_dram_config, /* 显示 DRAM 的配置 */ 53 display_new_sp, /* 显示新的栈地址 */ 54 INIT_FUNC_WATCHDOG_RESET 55 reloc_fdt, /* 设备树相关 不涉及 */ 56 reloc_bootstage, /* 启动阶段 不涉及 */ 57 setup_reloc, /* 建立重定向,设置 gd->rellocoff和新gd */ 58 NULL, 59 };
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 预留 MMU 表格区域 ---reserve_mmu
1 __weak int reserve_mmu(void) 2 { 3 #if !(defined(CONFIG_SYS_ICACHE_OFF) && defined(CONFIG_SYS_DCACHE_OFF)) 4 /* reserve TLB table ,PGTABLE_SIZE = 4096 * 4 */ 5 gd->arch.tlb_size = PGTABLE_SIZE; 6 /* gd->relocaddr = 0x3400 0000 - 4096 * 4 = 0x33FF C000 */ 7 gd->relocaddr -= gd->arch.tlb_size; 8 9 /* round down to next 64 kB limit, 64KB向下对齐 */ 10 /* gd->relocaddr = 0x33FF 0000 */ 11 gd->relocaddr &= ~(0x10000 - 1); 12 13 gd->arch.tlb_addr = gd->relocaddr; 14 debug("TLB table from %08lx to %08lx\n", gd->arch.tlb_addr, 15 gd->arch.tlb_addr + gd->arch.tlb_size); 16 #endif 17 return 0; 18 }
gd->relocaddr = 0x0x33FF 0000 指向 MMU 的基地址
8.2.5 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.6 堆区---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.7 预留 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.8 预留全局数据区域---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.9 栈区预留区---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 小节
代码执行完后,则返回,当前栈地址指向栈处,依然有大部分区域未分配。
当前分配的区域如下: