| |
|
开发:
C++知识库
Java知识库
JavaScript
Python
PHP知识库
人工智能
区块链
大数据
移动开发
嵌入式
开发工具
数据结构与算法
开发测试
游戏开发
网络协议
系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程 数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁 |
-> 嵌入式 -> imx6ull u-boot启动流程分析 -> 正文阅读 |
|
[嵌入式]imx6ull u-boot启动流程分析 |
一、程序入口 程序的链接由链接脚本决定的,所以可以通过u-boot.lds 来找到uboot的入口。 从上图可以看出入口为_start,该标签在vector.S中(\arch\arm\lib\vectors.S)
所以,设备一上电开始执行reset函数。
save_boot_params 没干啥事,直接跳转到save_boot_params_ret。然后关FIQ、IRQ中断,并且设置cpu到SVC32模式。设置中断向量地址寄存器的值为_start地址。 cpu_init_cp15主要设置CP15寄存器,涉及cache、MMU、TLBS。 cpu_init_crit :直接调用lowlevel_init
_main 重点函数:
board_init_f:调用一系列 initcall_run_list(init_sequence_f)如下: setup_mon_len:设置uboot镜像大小gd->mon_len fdtdec_setup:设置 gd->fdt_blob
trace_early_init: 设置早期的缓冲区 initf_malloc: 设置gd->malloc_limit= SYS_MALLOC_F_LEN和 gd->malloc_ptr=0 log_init:如果有LOG_DRIVER创建log_device initf_bootstage:空函数。 initf_console_record:空函数 arch_cpu_init: basic arch cpu dependent setup mach_cpu_init:空函数 initf_dm:驱动模型 非dtb的初始化
arch_cpu_init_dm:空函数 board_early_init_f:setup_iomux_uart get_clocks:获取gd->arch.sdhc_clk timer_init: 初始化A7内核定时器,为uboot提供时间基准
board_postclk_init:设置ldo 电压 env_init: 获取 gd->env_addr 、gd->env_valid init_baud_rate:从环境变量中获取波特率并设置到gd->baudrate。 console_init_f:stage 1 init of console display_options:打印版本相关内容 display_text_info:打印U-Boot code的 bss_start、bss_end print_cpuinfo: 打印cpu相关信息 show_board_info:获取dtb文件model属性的值,打印Model: Freescale i.MX6 ULL 14x14 EVK Board Board: MX6ULL 14x14 EVK init_func_i2c:iic相关初始化 init_func_spi:spi相关初始化 announce_dram_init: puts("DRAM: "); dram_init: gd->ram_size = imx_ddr_size(); setup_dest_addr:设置gd->ram_size=0x20000000 gd->ram_top= 0x80000000+ gd->ram_size =A0000000 gd->relocaddr = gd->ram_top reserve_round_4k: gd->relocaddr &= ~(4096 - 1); 4k对齐 reserve_mmu:设置:gd->arch.tlb_size=0x4000;gd->relocaddr -= gd->arch.tlb_size; gd->relocaddr &= ~(0x10000 - 1); gd->arch.tlb_addr = gd->relocaddr=9fff0000; reserve_video:该版本未使用 reserve_trace:该版本未使用 reserve_uboot: gd->relocaddr -= gd->mon_len; gd->relocaddr &= ~(4096 - 1); gd->start_addr_sp = gd->relocaddr=9ff24000; reserve_malloc: gd->start_addr_sp = gd->start_addr_sp - TOTAL_MALLOC_LEN =9ef22000; reserve_board: gd->start_addr_sp -= sizeof(bd_t)=9ef21fb0; gd->bd = (bd_t *)map_sysmem(gd->start_addr_sp, sizeof(bd_t)); setup_machine:新框架已经废弃 reserve_global_data:gd->start_addr_sp -= sizeof(gd_t)=9ef21eb0; gd->new_gd = (gd_t *)map_sysmem(gd->start_addr_sp, sizeof(gd_t)); reserve_fdt: gd->fdt_size = ALIGN(fdt_totalsize(gd->fdt_blob) + 0x1000, 32)=0x39200;
reserve_bootstage:该版本未使用 reserve_arch:该版本未使用 reserve_stacks:做gd->start_addr_sp 16字节对齐,然后留出16字节给abor-stack;得到gd->start_addr_sp=9ef33530 dram_init_banksize:
show_dram_config: 打印RAM 配置 和DRAM大小,日志如下:
display_new_sp: 打印gd->start_addr_sp :9ef18570 INIT_FUNC_WATCHDOG_RESET 复位看门狗 reloc_fdt:重定位fdt
reloc_bootstage:该版本未使用 setup_reloc:设置gd->reloc_off = gd->relocaddr - CONFIG_SYS_TEXT_BASE= 18724000; 拷贝gd 到gd->new_gd relocate_code : 拷贝代码到gd->relocaddr 处, 同时需要将记录相对位置调用关系的__rel_dyn段里面的内容加上gd->reloc_off写到gd->relocaddr 处,防止代码位置变动了,不能正确调用函数、全局变量等。 relocate_vectors: 将新的中断向量表地址写到vbar寄存器里面即可 ldr r0, [r9, #GD_RELOCADDR] /* r0 = gd->relocaddr / c_runtime_cpu_setup: 关闭 I-cache board_init_r:函数调用init_sequence_r里面每个函数。 initr_trace: 空函数 initr_reloc:标记重定位完成 gd->flags |= GD_FLG_RELOC | GD_FLG_FULL_MALLOC_INIT; initr_caches: 使能caches initr_reloc_global_data:
initr_barrier:空函数 initr_malloc:初始化malloc区域,malloc区域为紧挨着镜像文件下面malloc_start = gd->relocaddr - TOTAL_MALLOC_LEN; mem_malloc_init((ulong)map_sysmem(malloc_start, TOTAL_MALLOC_LEN), TOTAL_MALLOC_LEN); log_init:日志相关初始化。 initr_bootstage:空函数 initr_console_record :空函数 bootstage_relocate:空函数 initr_dm: dm相关初始化 board_init:板级初始化,包括 74XX 芯片,I2C、FEC、USB 和 QSPI 等
efi_memory_init:内存相关初始化 stdio_init_tables:stdio初始化 initr_serial:串口初始化 initr_announce: debug(“Now running in RAM - U-Boot at: %08lx\n”, gd->relocaddr); INIT_FUNC_WATCHDOG_RESET:看门狗复位 power_init_board:初始化电源芯片 initr_mmc:emmc初始化 initr_env:初始化环境变量 initr_secondary_cpu:初始化其他cpu核。 stdio_add_devices:各种输入输出设备的初始化。 initr_jumptable:gd->jt = malloc(sizeof(struct jt_funcs)); console_init_r:fully init console as a device show_board_info:
interrupt_init:初始化中断 initr_enable_interrupts:使能中断 timer_init:时钟初始化 initr_ethaddr:初始化网络地址,也就是获取 MAC 地址。读取环境变量“ethaddr”的值。 board_late_init:,板子后续初始化, initr_fastboot_setup: initr_net:初始化eth 复位phy initr_check_fastboot run_main_loop: uboot 启动以后会进入 3 秒倒计时,如果在 3 秒倒计时结束之前按下按下回车键,那么就 会进入 uboot 的命令模式,如果倒计时结束以后都没有按下回车键,那么就会自动启动 Linux 内 核 , 这 个 功 能 就 是 由 run_main_loop 函 数 来 完 成 的 。 |
|
嵌入式 最新文章 |
基于高精度单片机开发红外测温仪方案 |
89C51单片机与DAC0832 |
基于51单片机宠物自动投料喂食器控制系统仿 |
《痞子衡嵌入式半月刊》 第 68 期 |
多思计组实验实验七 简单模型机实验 |
CSC7720 |
启明智显分享| ESP32学习笔记参考--PWM(脉冲 |
STM32初探 |
STM32 总结 |
【STM32】CubeMX例程四---定时器中断(附工 |
|
上一篇文章 下一篇文章 查看所有文章 |
|
开发:
C++知识库
Java知识库
JavaScript
Python
PHP知识库
人工智能
区块链
大数据
移动开发
嵌入式
开发工具
数据结构与算法
开发测试
游戏开发
网络协议
系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程 数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁 |
360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年12日历 | -2024/12/29 9:15:00- |
|
网站联系: qq:121756557 email:121756557@qq.com IT数码 |
数据统计 |