基于S3C2410开发板的U-BOOT移植解决方案

引言
随着嵌入式系统的日趋复杂,它对大容量数据存储的需求越来越紧迫。而嵌入式设备低功耗、小体积以及低成本的要求,使硬盘无法得到广泛的应用。nand闪存设备就是为了满足这种需求而迅速发展起来的。目前关于u-boot的移植解决方案主要面向的是微处理器中的nor 闪存,如果能在微处理器上的nand 闪存中实现u-boot的启动,则会给实际应用带来极大的方便。
u-boot简介
u-boot 支持arm、 powerpc等多种架构的处理器,也支持linux、netbsd和vxworks等多种操作系统,主要用来开发嵌入式系统初始化代码bootloader。bootloader是芯片复位后进入操作系统之前执行的一段代码,完成由硬件启动到操作系统启动的过渡,为运行操作系统提供基本的运行环境,如初始化cpu、堆栈、初始化存储器系统等,其功能类似于pc机的bios。u-boot执行流程图如图1所示。
图1 u-boot启动流程图
nand闪存工作原理
s3c2410开发板的nand闪存由nand闪存控制器(集成在s3c2410 cpu中)和nand闪存芯片(k9f1208u0a)两大部分组成。当要访问nand闪存芯片中的数据时,必须通过nand闪存控制器发送命令才能完成。所以, nand闪存相当于s3c2410的一个外设,而不位于它的内存地址区。
nand闪存(k9f1208u0a)的数据存储结构分层为:1设备(device) = 4096 块(block);1块= 32页/行(page/row);1页= 528b = 数据块 (512b) + oob块 (16b)在每一页中,最后16个字节(又称oob)在nand闪存命令执行完毕后设置状态,剩余512个字节又分为前半部分和后半部分。可以通过nand闪存命令00h/01h/50h分别对前半部、后半部、oob进行定位,通过nand闪存内置的指针指向各自的首地址。
nand闪存的操作特点为:擦除操作的最小单位是块;nand闪存芯片每一位只能从1变为0,而不能从0变为1,所以在对其进行写入操作之前一定要将相应块擦除;oob部分的第6字节为坏快标志,即如果不是坏块该值为ff,否则为坏块;除oob第6字节外,通常用oob的前3个字节存放nand闪存的硬件ecc(校验寄存器)码;
从nand闪存启动u-boot的设计思路
如果s3c2410被配置成从nand闪存启动,上电后,s3c2410的nand闪存控制器会自动把nand闪存中的前4k数据搬移到内部ram中, 并把0x00000000设置为内部ram的起始地址, cpu从内部ram的0x00000000位置开始启动。因此要把最核心的启动程序放在nand闪存的前4k中。
由于nand闪存控制器从nand闪存中搬移到内部ram的代码是有限的,所以, 在启动代码的前4k里,必须完成s3c2410的核心配置,并把启动代码的剩余部分搬到ram中运行。在u-boot中, 前4k完成的主要工作就是u-boot启动的第一个阶段(stage1)。
根据u-boot的执行流程图,可知要实现从nand闪存中启动u-boot,首先需要初始化nand闪存,并从nand闪存中把u-boot搬移到ram中,最后需要让u-boot支持nand闪存的命令操作。
开发环境
本设计中目标板硬件环境如下:cpu为s3c2410,sdram为hy57v561620,nand闪存为64mb的k9f1208u0a。
主机软件环境为redhat9.0、 u-boot-1.1.3、gcc 2.95.3。修改u-boot的makefile,加入:
wch2410_config : unconfig
@./mkconfig $(@:_config=) arm arm920t wch2410 null s3c24x0
即将开发板起名为wch2410,接下来依次进行如下操作:
mkdir board/wch2410
cp board/smdk2410 board/wch2410
mv smdk2410.c wch2410.c
cp include/configs/smdk2410.h include/configs/wch2410.h
export path=/usr/local/arm/2.95.3/bin:$path
最后执行:
make wch2410_config
make all arch=arm
生成u-boot.bin,即通过了测试编译。
具体设计
支持nand闪存的启动程序设计
因为u-boot的入口程序是/cpu/arm920t/start.s,故需在该程序中添加nand闪存的复位程序,以及实现从nand闪存中把u-boot搬移到ram中的功能程序。
首先在/include/configs/wch2410.h中加入config_s3c2410_nand_boot, 如下:
#define config_s3c2410_nand_boot 1?? @支持从nand 闪存中启动
然后在/cpu/arm920t/start.s中添加
#ifdef config_s3c2410_nand_boot
copy_myself:
mov r10, lr
ldr sp, dw_stack_start@安装栈的起始地址
mov fp, #0@初始化帧指针寄存器
bl nand_reset@跳到复位c函数去执行,执行nand闪存复位
。..。..。
/*从nand闪存中把u-boot拷贝到ram*/
ldr r0, =uboot_ram_base@ 设置第1个参数: uboot在ram中的起始地址
mov r1, #0x0@ 设置第2个参数:nand闪存的起始地址
mov r2, #0x20000 @ 设置第3个参数: u-boot的长度(128kb)
bl nand_read_whole@ 调用nand_read_whole(),把nand闪存中的数据读入到ram中
tst r0, #0x0@ 如果函数的返回值为0,表示执行成功
beq ok_nand_read@ 执行内存比较,把ram中的前4k内容与nand闪存中的前4k内容进行比较, 如果完全相同, 则表示搬移成功
其中,nand_reset (),nand_read_whole()被加在/board/wch2410/wch2410.c中。
支持u-boot命令设计
在u-boot下对nand闪存的支持主要是在命令行下实现对nand闪存的操作。对nand闪存实现的命令为:nand info(打印nand flash信息)、nand device(显示某个nand闪存设备)、nand read(读取nand闪存)、nand write(写nand闪存)、nand erease(擦除nand闪存)、nand bad(显示坏块)等。
用到的主要数据结构有:struct nand_flash_dev、struct nand_chip。前者包括主要的芯片型号、存储容量、设备id、i/o总线宽度等信息;后者是具体对nand闪存进行操作时用到的信息。
a. 设置配置选项
修改/include/configs/wch2410.h,主要是在config_commands中打开cfg_cmd_nand选项。定义nand闪存控制器在sfr区中的起始寄存器地址、页面大小,定义nand闪存命令层的底层接口函数等。
b. 加入nand闪存芯片型号
在/include/linux/mtd/ nand_ids.h中对如下结构体赋值进行修改:
static struct nand_flash_dev nand_flash_ids[] = {
。..。..
{“samsung k9f1208u0a”, nand_mfr_samsung, 0x76, 26, 0, 3, 0x4000, 0},
。..。..。
}
这样对于该款nand闪存芯片的操作才能正确执行。
c. 编写nand闪存初始化函数
在/board/wch2410/wch2410.c中加入nand_init()函数。
void nand_init(void)
{
/* 初始化nand闪存控制器, 以及nand闪存芯片 */
nand_reset();
/* 调用nand_probe()来检测芯片类型 */
printf (“%4lu mb\n”, nand_probe(cfg_nand_base) 》》 20);
}
该函数在启动时被start_armboot()调用。
最后重新编译u-boot并将生成的u-boot.bin烧入nand闪存中,目标板上电后从串口输出如下信息:
u-boot 1.1.3 (nov 14 2006 - 11:29:50)
u-boot code: 33f80000 -》 33f9c9e4 bss: -》 33fa0b28
ram configuration:
bank #0: 30000000 64 mb
## unknown flash on bank 0: id 0xffff, size = 0x00000000 = 0 mb
flash: 0 kb
nand: 64 mb
in:  serial
out: serial
err: serial
hit any key to stop autoboot: 0
wch2410 #
结语
以往将u-boot移植到arm9平台中的解决方案主要针对的是arm9中的nor闪存,因为nor闪存的结构特点致使应用程序可以直接在其内部运行,不用把代码读到ram中,移植过程相对简单。从nand闪存中启动u-boot的设计难点在于nand闪存需要把u-boot的代码搬移到ram中,并要让u-boot支持nand闪存的命令操作。本文介绍了实现这一设计的思路及具体程序。移植后,u-boot在嵌入式系统中运行良好。


CPU-Z 1.91推出,支持AI协处理器新Centaur x86 CPU
845单端甲类功放电路图 (含电源电路)
未来制造业投资有望迎来恢复性增长 国内工业机器人需求或出现拐点
[组图]MC145152频率合成器及其应用
MSP430单片机实现PWM控制LED灯的设计
基于S3C2410开发板的U-BOOT移植解决方案
微差压气体压力传感器的功能特点及应用领域
iPhone8发布会今天来搞事情了
基于MSP430的传感器技术(2)
天阳科技加入欧拉开源社区 推动开源云生态快速发展
DAC0832输出转电压的运放电路图
E拆解:华为AI音响
中国半导体技术大会CSTIC 2018整体介绍
DeepMind把GAN又玩出了新花样!推出的是双视频判别器GAN
拼多多将苹果iPhone 12全系纳入百亿补贴
通信高压直流电源的特点_通信高压直流电源的优点
基于运放实现交流信号的平移
3.5G/HSDPA技术架构与手机开发要点
安全可靠的接口IP—汽车神经网络的构筑者
面对网站黑客的劫持以及窃听,我们有何应对措施