程序员的圣诞节后-零
u-boot-2014.10代码分析及移植说明
1 ENTRY(_main)2 3 /* 4 * Set up initial C runtime environment and call board_init_f(0).5 */ 6 7 #if defined(CONFIG_SPL_BUILD) && defined(CONFIG_SPL_STACK) 8 ldr sp, =(CONFIG_SPL_STACK)9 #else 10 ldr sp, =(CONFIG_SYS_INIT_SP_ADDR)11 #endif 12 bic sp, sp, #7 /*8-byte alignment for ABI compliance*/ 13 mov r2, sp14 sub sp, sp, #GD_SIZE /*allocate one GD above SP*/ 15 bic sp, sp, #7 /*8-byte alignment for ABI compliance*/ 16 mov r9, sp /*GD is above SP*/ 17 mov r1, sp18 mov r0, #0
1 clr_gd:2 cmp r1, r2 /*while not at end of GD*/ 3 strlo r0, [r1] /*clear 32-bit GD word*/ 4 addlo r1, r1, #4 /*move to next*/ 5 blo clr_gd
_main位于crt0.S中,该段主要是给u-boot中最根本最重要的变量gd分配空间并清零。
gd是一个结构体变量,其地址被放置于r9寄存器中(如果没记错的话,以前的版本是放入r8寄存器的),它包含了u-boot程序中最重要的全局信息,包括时钟相关变量,页表,重定位信息等,另外还包括传递给内核的板级信息。
1 #if defined(CONFIG_SYS_MALLOC_F_LEN) && !defined(CONFIG_SPL_BUILD) 2 sub sp, sp, #CONFIG_SYS_MALLOC_F_LEN3 str sp, [r9, #GD_MALLOC_BASE]4 #endif 5 /*mov r0, #0 not needed due to above code*/ 6 bl board_init_f
定义relocation之前所需的堆空间地址,之后转入board_init_f程序,从此处起,SPL即BL1阶段代码和U-BOOT即BL2阶段代码分开走向了不同的路线。
如果未定义CONFIG_SYS_GENERIC_BOARD,则为/arch/arm/lib/board.c
如果定了CONFIG_SYS_GENERIC_BOARD,则为common/board_f.c。
想了想,先以/arch/arm/lib/board.c为例讲吧,毕竟这个是针对具体architecture(真实原因是common下那个我还没看过)
1 void board_init_f(ulongbootflag)2 {3 bd_t *bd;4 init_fnc_t **init_fnc_ptr;5 gd_t *id;6 ulongaddr, addr_sp;7 #ifdef CONFIG_PRAM8 ulongreg;9 #endif 10 void *new_fdt =NULL;11 size_t fdt_size = 0;12 13 memset((void *)gd, 0, sizeof(gd_t));
此处又重新将gd清零了,似乎有点多余啊,难道是针对SPL的?(原因是针对common/board_f.c的,该文件中的函数没有gd初始化)
1 gd->mon_len = (ulong)&__bss_end - (ulong)_start;2 #ifdef CONFIG_OF_EMBED3 /*Get a pointer to the FDT*/ 4 gd->fdt_blob =__dtb_dt_begin;5 #elif defined CONFIG_OF_SEPARATE 6 /*FDT is at end of image*/ 7 gd->fdt_blob = &_end;8 #endif 9 /*Allow the early environment to override the fdt address*/ 10 gd->fdt_blob = (void *)getenv_ulong("fdtcontroladdr", 16,11 (uintptr_t)gd->fdt_blob);
gd->mon_len为uboot大小。
CONFIG_OF_EMBED决定着是否将dtb编入uboot,libs-$(CONFIG_OF_EMBED) += dts/
CONFIG_OF_SEPARATE也是在同时编译dtb,但是分开编译,并未编入uboot中,Makefile中可以看出,但是没找到为何是放在_end后。
1 for (init_fnc_ptr = init_sequence; *init_fnc_ptr; ++init_fnc_ptr) {2 if ((*init_fnc_ptr)() != 0) {3 hang ();4 }5 }
该段则是进行一部分初始化,init_sequence为一个函数指针数组,
1 init_fnc_t *init_sequence[] ={2 arch_cpu_init, /*basic arch cpu dependent setup*/ 3 mark_bootstage,4 #ifdef CONFIG_OF_CONTROL5 fdtdec_check_fdt,6 #endif 7 #if defined(CONFIG_BOARD_EARLY_INIT_F) 8 board_early_init_f,9 #endif 10 timer_init, /*initialize timer*/ 11 #ifdef CONFIG_BOARD_POSTCLK_INIT12 board_postclk_init,13 #endif 14 #ifdef CONFIG_FSL_ESDHC15 get_clocks,16 #endif 17 env_init, /*initialize environment*/ 18 init_baudrate, /*initialze baudrate settings*/ 19 serial_init, /*serial communications setup*/ 20 console_init_f, /*stage 1 init of console*/ 21 display_banner, /*say that we are here*/ 22 print_cpuinfo, /*display cpu info (and speed)*/ 23 #if defined(CONFIG_DISPLAY_BOARDINFO) 24 checkboard, /*display board info*/ 25 #endif 26 #if defined(CONFIG_HARD_I2C) || defined(CONFIG_SYS_I2C) 27 init_func_i2c,28 #endif 29 dram_init, /*configure available RAM banks*/ 30 NULL,31 };
注意该处实际是个指向函数指针的数组,其好处我能想到的一点是末尾的NULL,通过指针为NULL判断作为结束标志。以下逐一分析各个初始化函数,
1.arch_cpu_init
该函数自然就是需要针对各个芯片自己实现了,通常可以在该函数中实现cache使能的控制
2.mark_bootstage
1 /*Record the board_init_f() bootstage (after arch_cpu_init())*/ 2 static int mark_bootstage(void)3 {4 bootstage_mark_name(BOOTSTAGE_ID_START_UBOOT_F, "board_init_f");5 6 return 0;7 }
算是uboot的流程中做个标记,bootstage_mark_name函数最终可以通过和板级自己实现的一个函数挂接,实现通过打印或者led灯等各种方式来反应uboot的进程。
3.fdtdec_check_fdt
检测fdt是否存在
4.board_early_init_f
早期的一些初始化
如需要,定义宏CONFIG_BOARD_EARLY_INIT_F,并实现该函数
5.timer_init
timer初始化,题外:u-boot中timer驱动的作用是为了实现delay,因此timer驱动也是围绕udelay展开的。
6.board_postclk_init
早期时钟相关初始化
如需要,定义宏CONFIG_BOARD_POSTCLK_INIT,并实现该函数
7.get_clocks
看起来实际主要是为了获取gd->arch.sdhc_clk时钟,即为了获取sdmmc时钟,不过并不是必要。
如需要,定义宏CONFIG_FSL_ESDHC,并实现该函数
8.env_init
初始化gd中的两个成员,即环境变量表的地址,以及valid值
9.init_baudrate
初始化gd中的波特率成员变量
该处设计BAUDRATE的一个宏定义
10.serial_init
初始化串口驱动
对应串口驱动中必须添加的两个函数default_serial_console,以及serial_device结构体的start成员函数
11.console_init_f
其实没啥,只是在存在CONFIG_PRE_CONSOLE_BUFFER的情况下会有个buffer初始化的过程
12.display_banner
打印uboot版本信息等
13.print_cpuinfo
这个是各个芯片自己实现,打印一些cpu相关信息
14.checkboard
打印board相关信息
15.init_func_i2c
如果有且需要i2c的话,初始化
16.dram_init
自己实现,gd->ram_size的初始化,当然也有吧dram_bank的初始化写在这里
整个init_sequence初始化就结束了。
剩下的下期再说。
转载于:https://www.cnblogs.com/iambobor/p/4185763.html
程序员的圣诞节后-零相关推荐
- 圣诞祝福网页_程序员式圣诞祝福,你没试过这种吧?
一年一度的圣诞节又来啦!在这个越来越被重视的节日里,每个人都有自己浪漫的方式,当然程序员也不例外. 让我们看看程序员如何为节日增添不同的气氛吧. 初级程序员的祝福 1.用canvas功能画出简单的圣诞 ...
- 程序员圣诞节相册源码_程序员分享圣诞刷屏源码,这次朋友圈千万不要再@微信官方了!...
明天就到圣诞节了 每年到这个时候,朋友圈里都会掀起@微信官方要「圣诞皮肤」的骚操作,最常见的就是加个圣诞小帽了. 当然这种事情很多 P 图软件都可以做到,但在使用这些软件时,经常会被要求绑定微信等个人 ...
- 为什么程序员都喜欢节后跳槽?内行人告诉你原因
哪个工作相对来说高薪?你脑海中的职业之一会有程序员.哪个职业跳槽最频繁?你脑海中的职业之一还是会有程序员! 程序员喜欢跳槽,这在行业里面已经算不上什么秘密. 互联网技术发展迅速,有很多的地方都需要优秀 ...
- 程序员过圣诞 | 用HTML写出绽放的烟花
文章目录 一.前言 二.创意名 三.效果展示 四.烟花代码 五.总结 一.前言 2022年圣诞节到来啦,圣诞节是基督教纪念耶稣诞生的重要节日.亦称耶稣圣诞节.主降生节,天主教亦称耶稣圣诞瞻礼.耶稣诞生 ...
- proteus如何添加stm32_一个应用软件程序员的单片机STM32零基础入门
为什么开始考虑搞嵌入式开发? 近5年来,从云计算.大数据到机器学习.AI,各种新潮的技术概念一波--接一波. 作为一名好奇心旺盛的软件程序员,每一个技术概念流行起来都会去凑凑热闹. 但,在我的技术栈里 ...
- 程序员祝福圣诞快乐的方式(内涵完整代码)
2022年圣诞节到来啦,很高兴这次我们又能一起度过~ 这次利用前端的一些简单的代码给不会前端的广大男性朋友知道如何哄对象❤️ 一.前言 圣诞将至,玩计算的大家还在发愁如何实现自己送个心爱的那个女孩什么 ...
- 【转载】给程序员的圣诞大礼★★春夏
计算机寓言之春 真爱与新生 1 两名学生 曾经有一名学生,他在课余时间里穿上古时侯的盔甲,随后他如今那些和他有类似想法的人在一起,模仿古代社会里的贵州和太太们. 另一名学生是计算机科学专业的,他问一名 ...
- 8年web前端开发老程序员告诉你如何零基础学习web前端
随着web前端的飞速发展,学习web前端的人员也是越来越多,在移动 互联网 时代,相信我们每个人的手机上都装有数十个APP,这些APP的开发其实也和当下热门的 Web 前端开发息息相关. 事实上,如今 ...
- java学了之后老忘_老程序员的建议,零基础学java,常见的误区和解决方法
写一篇经验分享的文章,现在很多人学习java 第一,觉得java很难, 第二,觉得java 找工作不好找, 第三,也有人说java饱和了, 现在确实是行业的要求越来越高了, 早在07年的时候把java ...
最新文章
- Del.icio.us应用工具杂烩
- 为节约而生:从标准Attention到稀疏Attention
- linux重启mysqlsystemctl_解决linux(centos7)重新安装mysql systemctl start mysqld.service时报错...
- Android内核学习笔记
- python入门基础系列_03python—9个基础常识-python小白入门系列
- splunk中 如何隐藏input_翻糖制作中,如何避免裂缝,如何隐藏裂缝,如何防粘?...
- loadRunner目录分析二
- STL_stack/queue
- java 流 flush_Java CharArrayWriter flush()方法
- 不懂就问,Spring 是如何判定原型循环依赖和构造方法循环依赖的?
- vector所存储对象地址在vector操作过程中发生变化
- R语言数据可视化---交互式图表recharts包
- Linux 进程间通信 无名管道(pipe)
- 视频教程-以太坊区块链实战视频教程(全球同步升级)-区块链
- 电影《检察风云》投资价值简单分析
- 帆软报表 异常汇总及方案.
- 每日一练——回文链表
- CF85D Sum of Medians
- ROS进阶学习的过程
- 给网页设计师和前端开发者看的前端性能优化