【1】基于TQ2440的MP3设计——【4、U-Boot 移植与改写】

来源:互联网 发布:java培训班有证吗 编辑:程序博客网 时间:2024/05/17 07:37

2、U-Boot 移植

从网上下载源码 u-boot-2010.12,实现如下功能:

1)支持S3C2440;

2)支持串口协议;

3)支持网卡芯片DM9000;

4)支持不同Nand Flash 的读写

5)支持IIC 接口EEPROM 的操作,并可保存ENV;

6)支持烧写yaffs/yaffs2 文件系统映象;

7)支持使用DNW工具,通过USB device 口进行文件传输。


a、U-Boot 的启动过程分为Stage1 和Stage 2 两个阶段。

U-Boot 的Stage 1 位于start.S 文件,使用汇编语言编写。针对ARM920T 体系的start.S 文件,流程如下:

硬件初始化,如CPU寄存器SDRAM等;为加载Stage2 准备内存空间;设置好栈堆指针sp,并跳转到Stage2的C函数入口点:

(1) 设置异常向量表。ARM 处理器包括复位、未定义指令、SWI、预取终止、数据终止、IRQ、FIQ 七种异常。异常向量从地址0 开始,  每个向量是一条 4 字节的跳转语句。

(2) 设置 CPSR 寄存器的模式位域,设置 CPU 模式为 SVC 模式 
(3) 关闭看门狗 
(4) 设置 CPU 工作频率,高速总线频率,外围总线频率 
(5) 设置 CP15 协处理器。CP15 是系统控制和内存管理协处理器。U-Boot 设置 CP15 的目的是声明 ICach(e指令 Cache)和 DCache

(数据 Cache)失效,然后禁止 MMU 和 Cache。 
(6) 配置储存区控制寄存器 BWSCON、BANKCON1-7。 
(7) 配置堆栈空间。配置代码段的开始地址、动态内存区长度、全局数据的大小以及分配 IRQ 和 FIQ 的栈空间。 
(8) 初始化 RO、RW、ZI 段。 
(9) 进入 C 代码。利用 LDR 伪操作将 C 语言的入口地址装入 PC(程序指针寄存器),从而跳转到 C 代码去运行。 


Stage 2 用C语言实现。主要工作是:(1)命令行模式处理串口输入的命令(2)引导Linux内核。

1)初始化本阶段使用到的硬件设备,如USB,声卡等;

2)将内核映像和根文件系统映像从flash上读到内存中;

3)设置好系统的启动参数后调用内核。



b、移植U-Boot

从ftp://ftp.denx.de/pub/u-boot/下载 U-Boot 源码;先删除与我们硬件无关的文件。

board:以Samsung 的smdk2410 为模板,其他的都删了。

arm:即CPU,我们的CPU 为arm920t,其余的删了。


(1)修改Makefile。

主要是针对 ARCH(CPU 体系架构) 和CROSS_COMPILE 变量(定义交叉编译器的前缀名)。

ARCH   ?= arm 

CROSS_COMPILE  ?= arm-linux- 

(2)增加目标板的编译选项。

EmbedSky_config: unconfig

@$(MKCONFIG) $(@:_config=) arm arm920t EmbedSky NULL s3c24x0

EmbedSky_config 表示增加名为EmbedSky_config 的编译目标;arm 指 arm 体系结构; arm920t 表示编译cpu/arm920t 子目录;EmbedSky 表示编译 board/EmbedSky子目录;s3c24x0 表示编译 cpu/arm920t/s3c24x0 子目录。

(3)参考 smdk2410 建立 EmbedSky 目标板目录

cp -fr board/smdk2410 board/EmbedSky  

cd board/EmbedSky  

mv smdk2410.c EmbedSky .c 

(4)修改 EmbedSky  目录的Makefile

vim Makefile 

遵守 make 编译规则,将 

COBJS := smdk2410.o flash.o
改为 

COBJS := EmbedSky.o flash.o boot_init.o 

(5)建立目标板头文件

cd include/configs 

cp -fr smdk2410.h EmbedSky.h 

vim EmbedSky.h 

加入如下语句使 U-Boot 支持 USB 烧写和 DM9000 网卡: 

#define CONFIG_USB_DEVICE 1 

#ifdef CONFIG_USB_DEVICE 

#define CONFIG_USE_IRQ   1 

 

#define CONFIG_DRIVER_DM9000   1 

#define CONFIG_DM9000_USE_16BIT  1 

#define CONFIG_DM9000_BASE   0x20000000 

#define DM9000_IO       0x20000000   

#define DM9000_DATA      0x20000004 

(6)编译

cd ${U-ROOT} 

make mini2440_config 

make 


编译完成后在${U-ROOT}目录生成如下映像文件: 

u-boot.bin:原始二进制文件,下载到 ROM 运行 

u-boot:ELF 格式映像文件,可加载到 SDRAM 调试 

u-boot.srec:Motorola S-Record 格式映像 

System map:U-Boot 映像符号表,各符号的链接地址 

编译成功表示初步移植无误,但是这个 u-boot.bin 在改写之前还不能用于本硬件系统。 


c、改写U-Boot

上面移植的 U-Boot 只能从Nor Flash 启动。但我们的 MP3 制作好之后是从  NAND Flash 启动的,所以必需改写 U-Boot 代码使其具有从 Nand Flash 启动的功能。


S3C2440 的引脚 OM[1:0]控制系统的启动方式:

(1)上电时如果 OM=10,处理器就从 BANK 0 的 NOR Flash 读取代码;

(2)如果 OM=00,处理器把 NAND Flash 的前4KB 内容读取到内部的启动 RAM 中,然后将该启动 RAM 映射到地址 0 处并开始运行。启动代码一般是 100KB 以上,远大于启动 RAM 的容量,所以如果要从Nand Flash 启动,需要在 Boot 代码开始不久后,将代码从 NAND Flash 搬运到SDRAM 中,在 SDRAM 中继续运行。


系统启动后自动判断当前系统是从 NOR Flash 启动的还是从 NAND Flash 启动的,对于从 NOR Flash 启动的情况使用 NOR Flash 的读取方式来拷贝自身到 SDRAM,对与从 NAND Flash启动的情况则使用 NAND Flash 的读取函数来拷贝自身到 SDRAM,然后跳转到SDRAM 中继续执行。


改写 U-Boot ,使其具备从 NAND Flash 启动:

(1)系统启动时会自动判断

系统判断:无论从NOR Flash 启动还是从 NAND Flash 启动,地址 0x0 处始终为指令"b Reset", 机器码为 0xEA00000B。

对于从 NAND Flash 启动的情况,其开始 4KB 的代码会复制到 CPU内部 4KB 的启动 RAM 中

对于从 NOR Flash 启动的情况,NOR Flash 的开始地址即为 0,因为 NOR Flash 必须通过一定的命令序列才能写入数据,所以可以根据这点差别来分辨是从 NAND Flash 还是 NOR Flash 启动。分辨方法是向地址 0x0 写入一个数据,然后读出来,如果没有改变的话就是 NOR Flash 启动,否则就是 从 NAND Flash 启动,将这个功能包装在 bBootFrmNORFlash()函数中。然后将启动方式判断、拷贝代码到 SDRAM 系列功能包装在 CopyCode2Ram()函数当中。


增加读取 Nand Flash 的函数 nand_read()。 读取的的方法是依次向 IO端口写命令、地址,然后从IO 端口读出数据。


修改 start.S 文件。让代码调用CopyCodeRam()函数,不执行原来的指令。


调试U-Boot :调试使用 JTAG 硬件调试器和 ADX Debugger 软件,可实现对照源代码调试。先用 objdump 生成反汇编代码: 

arm-softfloat-linux-gnu-objdump –S u-boot >u-boot.S 

将 u-boot 目录拷贝到 Windows 中,选择 ADX 的 Load Image 加载 u-boot 到内存,然后加载 u-boot.S 反汇编文件即可调试 U-Boot。 使用 JTAG 连线连接主机和目标板,使用 Windows 下的  Jtag  工具将其烧写到 NAND Flash 的地址 0 处。使用串口连线连接好主机和目标板,打开 SecureCRT 看到 U-Boot 的输出文字,即表示 U-Boot 移植成功。 
0 0
原创粉丝点击