最近在学习嵌入式Linux驱动开发,用的是qt210的板子,碰到了一个问题,试过各种方法都没有解决。
问题:ubuntu下编译好uboot和内核zImage,uboot直接烧写到sd卡中,然后利用uboot和tftp服务下载zImage到内存,下载成功了。但当执行bootm 20008000时,minicom中卡在boot with zImage,就没有下文了。
我重新编译了很多次uboot和zImage,甚至更换了linux系统,都还是一样的现象。实在无奈,对uboot又不了解,所以决定学习一下。学完再研究一下内核方面的知识。希望能解决这个问题。
如果有大神知道是什么原因,希望能给我留个言,不甚感激。
以下内容可能大部分来自网络或者书籍,本人仅是在学习过程做笔记。
1. uboot官方下载地址
2. uboot目录结构(最新版)
目录 | 说明 |
board | 与开发板相关,每种开发板对应其中一个子目录 |
common | 实现uboot命令行下支持的命令,每条命令都对应其中一个文件 |
cpu | 与CPU相关,每种CPU对应其中一个子目录 |
disk | 对磁盘的支持 |
doc | 文档目录 |
drivers | uboot支持的设备驱动程序都放在该目录 |
fs | 支持的文件系统 |
include | uboot使用的头文件,还有支持各种硬件平台的汇编文件、系统的配置文件和对文件系统支持的文件。其中子目录configs存放与开发板相关的配置头文件,子目录asm存放与CPU体系结构相关的头文件 |
lib | 与体系结构相关的库文件 |
net | 网络协议相关代码 |
tools | 生成uboot的工具 |
3. uboot启动的两个阶段
uboot启动分为两个阶段。第一阶段使用汇编来实现,它完成一些依赖于CPU体系结构的初始化,并调用第二阶段的代码。第二阶段则通常使用C语言来实现,这样可以实现更复杂的功能,而且代码会有更好的可读性和可移植性。
3.1 第一阶段
- 硬件初始化(关闭WATCHDOG、关中断、设置 CPU的速度和时钟频率、RAM初始化等,不是必需的)
- 为第二阶段准备RAM空间
- 复制第二阶段代码到RAM空间
- 设置栈
- 跳转到第二阶段代码的C入口点
3.2 第二阶段
- 初始化本阶段要使用的硬件
- 检测系统内存映射
- 将内核映像和根文件系加载到RAM空间中
- 为内核设置启动参数
- 调用内核
3.3 将内核存放在适当的位置后,直接跳到它的入口点即可调用内核,调用内核之前,下列条件要满足
(1)CPU寄存器的设置
- R0=0
- R1=机器类型ID;对于ARM结构的CPU,其机器类型ID在linux/arch/arm/tools/mach-types
- R2=启动参数标记列表在RAM中起始基地址
(2)CPU工作模式
- 必须禁止中断(IRQs和FIQs)
- CPU必须为SVC模式
(3)Cache和MMU的设置
- MMU必须关闭
- 指令Cache可以打开也可以关闭
- 数据Cache必须关闭
4. uboot引导内核分析
4.1 bootm命令使用方法:bootm [address] zImage
4.2 bootm命令在common/cmd_bootm.c中由do_bootm函数实现。
bootm获取当前内核的地址,默认地址或者bootm的第一个参数。默认的加载地址或传递给bootm命令的地址(优先)与实际的内核存放地址需要一致。