一,前言
居然看到uboot支持stm32的cortex-M4的内核,所以就编译来看看,直接编译通过了,所以代表着我可以直接在真实的板子上连接jlink单步调试了,先看看上电流程的代码吧~
二,编译
下载了6.0版本以上的arm-none编译即可通过编译。
export PATH=$PATH:/work/tools/gcc-arm-none-eabi-9-2019-q4-major/bin
make ARCH=arm CROSS_COMPILE=arm-none-eabi- distclean
rm -rf ./stm
make ARCH=arm CROSS_COMPILE=arm-none-eabi- O=stm stm32f429-discovery_defconfig
make ARCH=arm CROSS_COMPILE=arm-none-eabi- O=stm
三,分析源码
之前cortexA8的启动代码我也不细看,但是cortexM4内核应该更加容易,内容更加少了,所以先看下启动流程。
1)从reset开始,文件路径arch/arm/cpu/armv7m/start.S
2)进入arch/arm/lib/crt0.S中处理
a. bss段清0
b. 通过配置了CONFIG_HAS_CUSTOM_SYS_INIT_SP_ADDR,为SYS_INIT_SP_ADDR设置值0x10010000作为sp地址
c. 通过调用common/init/board_init.c中的board_init_f_alloc_reserve函数,预留gd的size为配置值CONFIG_SYS_MALLOC_F_LEN=0x2000,通过调用board_init_f_init_reserve将gd空间中gd size清0
d. 通过调用common/board_f.c中的board_init_f进行gd赋值及init_sequence_f中的函数初始化。接着就是一堆初始化,我全看了下,对如下几项做了笔记记录。
->initf_bootstage,之前没有关注过,原来是可以用来记录boot时间的。
config BOOTSTAGE
bool "Boot timing and reporting"
help
Enable recording of boot time while booting. To use it, insert
calls to bootstage_mark() with a suitable BOOTSTAGE_ID from
bootstage.h. Only a single entry is recorded for each ID.
->arch_cpu_init初始化,路径在arch/arm/mach-stm32/soc.c,对于stm32就是配置mpu。
->env_init,主要是要找evn存储介质的driver保存到gd->env_addr。
->serial_init里面进行了串口的初始,且调用了串口设备驱动drivers/serial/serial_stm32.c的_stm32_serial_setbrg来设置波特率。
->display_options开始通过串口打印标题了。
->misc_init_f里面包括了event_notify,这个event_notify蛮有意思的,也是遍历section中的数组,若传入的event和数组中的event名字一样就调用数组中的操作函数进行相关动作。可以理解为event来后需要触发的特别动作,就可以用这种方式。
->dram_init通过调用uclass_get_device来初始化设备,也就是说会调用device_probe函数的。
->setup_dest_addr,看到关键的relocaddr地址是可以通过打印_DEBUG来打印的。
gd->relocaddr = gd->ram_top;
debug("Ram top: %08llX\n", (unsigned long long)gd->ram_top);
->arch_reserve_mmu是预留一段mmu空间,此时ram_top的地址又会变小了。但是stm32没有mmu,此段调试下看看是否被调用,否则可以删除。
->后面有一系列的reserve_xx,蛮有意思的,都是预留空间,若配置且使用了,那么ram_relocaddr地址会越来越小。
->reserve_uboot有一句gd->start_addr_sp = gd->relocaddr。
->_dram_init_banksize,填充gd表,设置ram大小的。
->setup_bdinfo主要是设置外部sram的。
->display_new_sp通过debug打印sp最终地址。
->reloc_xx,也就是之前有reserve_xx就会赋值到gd_newXX,这样relocate汇编就会把gd_oldXX移动到gd_newXX。
->cyclic_unregister_all,看了下周期调用的只有wdg操作,最后unregister,难道之前register过,搜索了下确实wdt_start的时候有register。
接着汇编crt0.S就开始搬运ram和vector,最后调用board_init_r,此函数里面有init_sequence_r初始化列表,进行遍历初始化,只是此list的最后是run_main_loop,是一个for循环,不会再退出了。
四,qemu仿真看看
查看了下qemu是支持此开发板的,但是串口无信息,我没有用vscode来调试,所以不清楚情况,因为编译主要目的是实际板子调试用的。所以暂时忽略qemu仿真吧~
五,小结
看上去和arm的板子的启动流程类似,居然过程中还有relocate,有必要吗?重定向没细看,之后准备直接调试看下效果。但是cortex-M4还弄个uboot有必要吗?估计就是纯娱乐,而且发现2016版本uboot就已经支持cortexM4了,突然想到有关不带mmu的操作系统uclinux是否需要这样的uboot!
标签:调用,uboot,Apple,--,stm32,init,gd,board,arm From: https://blog.51cto.com/AppleCai/8062555