你好!这里是风筝的博客,欢迎和我一起交流。
如果本篇博客对您有帮助,或许可以在下方评论给我留个言。
PS:我是韦老大的学生^_^
先附上uboot的下载地址:ftp://ftp.denx.de/pub/u-boot/
这里我移植的是uboot2016.11版本,交叉编译链为4.3.2版本,JZ2440开发板一块
话不多说,开始分析。
移植之前,我们要知道两点:
u-boot的stage1代码通常放在cpux/start.S文件中,他用汇编语言写成;
u-boot的stage2代码通常放在lib_xxxx/board.c文件中,他用C语言写成。
带着这两句,我们来分析源码可知:
1 set the cpu to SVC32 mode
2 turn off the watchdog
3 mask all IRQs by setting all bits in the INTMR - default
4 设置时钟比例
5 调用汇编函数lowlevel_init,设置内存控制器
6 bl _main 语句跳到crt0.S文件,进入_main
6.1 ldr sp, =(CONFIG_SYS_INIT_SP_ADDR)设置栈
6.2 调用C函数board_init_f进行单板初始化
6.2.1 调用C函数init_sequence_f:
6.2.1.1 调用C函数board_early_init_f设置系统时钟、设置GPIO
6.2.1.2 调用C函数timer_init
6.2.1.3 调用C函数reserve_uboot
......
6.2.1.4 调用C函数jump_to_copy,函数中relocate_code进行重定位
6.3 b relocate_code重定位代码:
6.3.1 从NOR FLASH把代码复制到SDRAM
6.3.2 程序里有些地址在链接时不能确定,要到运行前才能确定:fixabs
6.4 清除bbs段
6.5 调用C函数board_init_r:第2阶段的代码
6.5.1 调用C函数initr_nand:
6.5.1.1 调用C函数nand_init初始化NAND FLASH
6.5.1.1.1 调用C函数nand_init_chip选中NAND FLASH
6.5.1.1.1.1调用C函数board_nand_init初始化时序
6.5.1.1.1.2 调用C函数nand_scan扫描NAND FALSH
6.5.1.1.1.2.1 调用C函数nand_scan_ident
6.5.1.1.1.2.1.1 调用C函数nand_set_defaults设置默认功能
6.5.1.1.1.2.1.1.1 C函数nand_command,发命令or来发列地址、行地址
6.5.1.1.1.2.1.2 调用C函数nand_get_flash_type读出NAND FALSH类型
6.5.1.1.1.3 调用C函数nand_register注册NAND FALSH
6.5.2 调用C函数initr_env初始化环境参数
6.5.2.1 调用C函数set_default_env设置默认环境变量
6.5.3 调用C函数initr_net初始化网卡
6.5.3.1 调用C函数eth_initialize
6.5.3.1.1 调用C函数board_eth_init初始化CS8900网卡
6.5.4 调用C函数run_main_loop
可以看出在6.2.1.4 调用C函数jump_to_copy进行重定位,但是6.3时也会进行重定位,也许我们可以把jump_to_copy这个函数注释掉。
所以现在我们来试试修改代码
附上一份目录
大概是这样的,可能会少了几个文件夹
├── api 存放uboot提供的接口函数
├── arch 与体系结构相关的代码,uboot的重头戏
├── board 根据不同开发板定制的代码,代码也不少
├── common 通用的代码,涵盖各个方面,已命令行处理为主
├── disk 磁盘分区相关代码
├── doc 文档,一堆README开头的文件
├── drivers 驱动,很丰富,每种类型的设备驱动占用一个子目录
├── examples 示例程序
├── fs 文件系统,支持嵌入式开发板常见的文件系统
├── include 头文件,已通用的头文件为主
├── lib 通用库文件
├── nand_spl NAND存储器相关代码
├── net 网络相关代码,小型的协议栈
├── onenand_ipl
├── post 加电自检程序
└── tools 辅助程序,用于编译和检查uboot目标文件