钢板防护罩做网站,网站建设填空题,陕西富通建设有限公司网站,html代码怎么运行一. uboot启动流程
_main 函数中会调用 board_init_f 函数#xff0c;本文简单分析一下 board_init_f 函数。 二. board_init_f 函数 board_init_f 函数主要有两个工作#xff1a; (1) 初始化一系列外设#xff0c;比如串口、定时器#xff0c;或者打印一些消息等。…一. uboot启动流程
_main 函数中会调用 board_init_f 函数本文简单分析一下 board_init_f 函数。 二. board_init_f 函数 board_init_f 函数主要有两个工作 (1) 初始化一系列外设比如串口、定时器或者打印一些消息等。 (2) 初始化 gd 的各个成员变量uboot 会将自己重定位到 DRAM 最后面的地址区域也就 是将自己拷贝到 DRAM 最后面的内存区域中。 这么做的目的是给 Linux 腾出空间防止 Linux kernel 覆盖掉 uboot 将 DRAM 前面的区域完整的空出来。 在拷贝之前肯定要给 uboot 各部分 分配好内存位置和大小比如 gd 应该存放到哪个位置 malloc 内存池应该存放到哪个位置等 等。这些信息都保存在 gd 的成员变量中因此要对 gd 的这些成员变量做初始化。最终形成一 个完整的内存“分配图”在后面重定位 uboot 的时候就会用到这个内存“分配图”。 下面简单分析一下 board_init_f 函数。 board_init_f 函数定义在文件 common/board_f.c 中定义代码如下 1035 void board_init_f(ulong boot_flags)
1036 {
1037 #ifdef CONFIG_SYS_GENERIC_GLOBAL_DATA
1038 /*
1039 * For some archtectures, global data is initialized and used
1040 * before calling this function. The data should be preserved.
1041 * For others, CONFIG_SYS_GENERIC_GLOBAL_DATA should be defined
1042 * and use the stack here to host global data until relocation.
1043 */
1044 gd_t data;
1045
1046 gd data;
1047
1048 /*
1049 * Clear global data before it is accessed at debug print
1050 * in initcall_run_list. Otherwise the debug print probably
1051 * get the wrong vaule of gd-have_console.
1052 */
1053 zero_global_data();
1054 #endif
1055
1056 gd-flags boot_flags;
1057 gd-have_console 0;
1058
1059 if (initcall_run_list(init_sequence_f))
1060 hang();
1061
1062 #if !defined(CONFIG_ARM) !defined(CONFIG_SANDBOX) \
1063 !defined(CONFIG_EFI_APP)
1064 /* NOTREACHED - jump_to_copy() does not return */
1065 hang();
1066 #endif
1067 } 第 1037~1054行代码无效因为没有定义 CONFIG_SYS_GENERIC_GLOBAL_DATA。 第 1056 行初始化 gd-flagsboot_flags0 。 第 1057 行设置 gd-have_console0 。 重点在第 1059 行 通过 initcall_run_list 函数 来运行初始化序列 init_sequence_f 里面的一些 列函数init_sequence_f 里面包含了一系列的初始化函数。 init_sequence_f 也是定义在文件 common/board_f.c 中由于 init_sequence_f 的内容比较长里面有大量的条件编译代码这里 为了缩小篇幅将条件编译部分删除掉了。 去掉条件编译以后的 init_sequence_f 函数 的 前半部分代码 如下 (因为 init_sequence_f 函数后半部分是内存分配下一篇文章再分析) /*****************去掉条件编译语句后的 init_sequence_f***************/
1 static init_fnc_t init_sequence_f[] {
2 setup_mon_len,
3 initf_malloc,
4 initf_console_record,
5 arch_cpu_init, /* basic arch cpu dependent setup */
6 initf_dm,
7 arch_cpu_init_dm,
8 mark_bootstage, /* need timer, go after init dm */
9 board_early_init_f,
10 timer_init, /* initialize timer */
11 board_postclk_init,
12 get_clocks,
13 env_init, /* initialize environment */
14 init_baud_rate, /* initialze baudrate settings */
15 serial_init, /* serial communications setup */
16 console_init_f, /* stage 1 init of console */
17 display_options, /* say that we are here */
18 display_text_info, /* show debugging info if required */
19 print_cpuinfo, /* display cpu info (and speed) */
20 show_board_info,
21 INIT_FUNC_WATCHDOG_INIT
22 INIT_FUNC_WATCHDOG_RESET
23 init_func_i2c,
24 announce_dram_init,
25 /* TODO: unify all these dram functions? */
26 dram_init, /* configure available RAM banks */
27 post_init_f,
28 INIT_FUNC_WATCHDOG_RESET
29 testdram,
30 INIT_FUNC_WATCHDOG_RESET
31 INIT_FUNC_WATCHDOG_RESET
......
62 NULL,
63 }; 第 2 行 setup_mon_len 函数设置 gd 的 mon_len 成员变量此处为 __bss_end -_start 也就 是整个代码的长度即 uboot的镜像大小 。 第 3 行 initf_malloc 函数初始化 gd 中跟 malloc 有关的成员变量比如 malloc_limit 此函 数会设置 gd-malloc_limit CONFIG_SYS_MALLOC_F_LEN0X400 。 malloc_limit 表示 malloc 内存池大小。 第 4 行 initf_console_record 函数 如 果 定 义 了 宏 CONFIG_CONSOLE_RECORD 和 宏 CONFIG_SYS_MALLOC_F_LEN 则此函数就会调用函数 console_record_init 但是 IMX6ULL 的 uboot 没有定义宏 CONFIG_CONSOLE_RECORD 所以此函数直接返回 0 。 第 5 行 arch_cpu_init 函数应该与架构相关的初始化。 第 6 行 initf_dm 函数驱动模型的一些初始化。 第 7 行 arch_cpu_init_dm 函数未实现。 第 8 行 mark_bootstage 函数应该是和啥标记有关的 第 9 行 board_early_init_f 函数板子相关的早期的一些初始化设置 I.MX6ULL 用来初始 化串口的 IO 配置 。 第 10 行 timer_init 函数初始化定时器 Cortex-A7 内核有一个定时器这里初始化的就 Cortex- A 内核的那个定时器。通过这个定时器来为 uboot 提供时间。就跟 Cortex-M 内核 Systick 定时 器一样。关于 Cortex-A 内部定时器的详细内容请参考文档 《 ARM ArchitectureReference Manual ARMv7-A and ARMv7-R edition.pdf 》 的“ Chapter B8 The Generic Timer ”章节。 第 11 行 board_postclk_init 函数 对于 I.MX6ULL 来说是设置 VDDSOC 电压。 第 12 行 get_clocks 函数用于获取一些时钟值 I.MX6ULL 获取的是 sdhc_clk 时钟也就 是 SD 卡外设的时钟。 第 13 行 env_init 函数是和环境变量有关的设置 gd 的成员变量 env_addr 也就是环境变 量的保存地址。 第 14 行 init_baud_rate 函数用于初始化波特率根据环境变量 baudrate 来初始化 gd-baudrate 。 第 15 行serial_init 函数初始化串口。 第 16 行console_init_f 函数设置 gd-have_console 为 1 表示有个控制台此函数也将前面 暂存在缓冲区中的数据通过控制台打印出来。 第 17 行 display_options 函数 通过串口输出一些信息 U-Boot 2016.03 (Jul 07 2023 - 17:11:27 0800)第 18 行 display_text_info 打印一些文本信息如果开启 UBOOT 的 DEBUG 功能的话就 会输出 text_base 、 bss_start 、 bss_end 形式如下 debug(U-Boot code: %08lX - %08lX BSS: - %08lX\n,text_base, bss_start, bss_end); 开启 UBOOT 的 DEBUG 功能的方法 在 include/configs下有不用开发板的配置头文件IMX6ULL使用的是 mx6ullevk.h可以在mx6ullevk.h文件中加 #define DEBUG 重新编译后的 uboot镜像文件烧录到设备就可以打印 uboot的debug信息。 Board: I.MX6U ALPHA|MINI 第 19 行 print_cpuinfo 函数用于打印 CPU 信息打印结果如下 CPU: Freescale i.MX6ULL rev1.1 792 MHz (running at 396 MHz)
CPU: Industrial temperature grade (-40C to 105C) at 35C
Reset cause: POR第 20 行 show_board_info 函数用于打印板子信息会调用 checkboard 函数打印如下 第 21 行 INIT_FUNC_WATCHDOG_INIT 初始化看门狗对于 I.MX6ULL 来说是空函数 第 22 行 INIT_FUNC_WATCHDOG_RESET 复位看门狗对于 I.MX6ULL 来说是空函数 第 23 行 init_func_i2c 函数用于初始化 I2C 初始化完成以后会输出如下、 I2C: ready第 24 行 announce_dram_init 函数 此函数很简单就是输出字符串“ DRAM: ” 第 26 行 dram_init 函数并非真正的初始化 DDR 只是设置 gd-ram_size 的值对于正点原 子 I.MX6ULL 开发板 EMMC 版本核心板来说就是 512MB 。 串口打印如下 第 27 行 post_init_f 函数此函数用来完成一些测试初始化 gd-post_init_f_time 第 29 行 testdram 函数测试 DRAM 空函数。 以上是 board_init_f 函数的前半部分。 具体是初始化一系列外设比如串口、定时器或者打印一些消息等。 下一篇文章简单分析 board_init_f函数的后半部分代码具体是内存分配的部分。