先给自己打个广告,本人的微信公众号正式上线了,搜索:张笑生的地盘,主要关注嵌入式软件开发,股票基金定投,足球等等,希望大家多多关注,有问题可以直接留言给我,一定尽心尽力回答大家的问题,二维码如下:
本文是根据韦东山视频教程整理的课程笔记!!
一 什么是bootloader
嵌入式芯片有很多启动方式,有支持内部flash启动,外部nand flash启动,外部nor flash启动,而对于大型的嵌入式产品来说,还需要跑操作系统,需要将程序重定位到ram中(可以是片内ram资源,也可以是片外的sdram),bootloader就是实现这样的功能,它从flash中读取代码加载到内存,可以类比PC机的启动方式,如下图:
所以bootloader代表一种加载flash程序到ram的方式,那么具体如何实现bootloader的功能呢,实现bootloader功能的代码有很多种,目前常用的是uboot,所以uboot就是一个单片机程序,只是这个单片机程序比较复杂,需要实现很多功能。
二 bootloader的目标
bootloader的目标就是启动内核,主要分为两大块:
1. 从flash上把内核读入到内存(sdram),在这个过程中,我们又需要实现:a,能操作flash;b,初始化sdram,时钟等其他
2. 启动内核,在这个过程中,我们需要实现:a,设置参数;b,跳转执行
三 uboot功能
我们说uboot是实现bootloader的程序代码,那么在这个程序中,我们需要实现哪些功能呢?
1. 要保证程序的正常运行,我们上电后需要关闭看门狗,初始化时钟
2. 读flash+写flash,为了开发方便,还有可能,从网络启动,需要能从网络读取加载代码,那么我们需要设置网卡;还有可能从usb设备启动,需要能从usb设备读取加载代码,那么我们需要设置usb驱动模块
3. 初始化sdram;
4. 启动内核;
以上操作,我们都称之为硬件初始化,是为了正常运行app做的基础工作,一般地,为了便于理解和分析,我们将读取内核之前的过程称之为uboot的第一阶段,读取内核并运行内核的阶段称之为第二阶段
四 分析标准的uboot代码
一般地,我们应该如何分析uboot代码呢?我们可以从makefile看起,分析makefile中做了哪些工作,用到了哪些source code,这样也方便我们了解这个代码框架结构。
针对韦东山老师的教程以及代码,有两个相关文件:
A. 第一个文件,也是所有单片机的程序入口,就是它的启动文件,是cpu/arm920T/start.S(因为s3c2440的内核是arm920T)
B. 另一个文件,就是链接脚本,是board/100ask24x0/u-boot.lds.
在start.S中主要实现了这些个函数操作:
设为svc管理模式-->关看门狗-->设置时钟-->屏蔽中断-->初始化sdram-->设置栈-->重定位从flash到ram-->清bss段-->调用c函数,读取并启动内核
start_armboot-->flash_init-->nand_init-->main_loop