八、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 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 小节

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

  当前分配的区域如下:

  

猜你喜欢

转载自www.cnblogs.com/kele-dad/p/8987831.html