基于S3C6410的u-boot SD卡启动方式的分析与移植

更新时间:2024-05-24 02:40:01 阅读量: 综合文库 文档下载

说明:文章内容仅供预览,部分内容可能不全。下载后的文档,内容与下面显示的完全一致。下载之前请确认下面内容是否您想要的,是否完整无缺。

U-Boot SD卡启动方式的分析与移植

——基于S3C6410平台

摘要:BootLoader在嵌入式系统的开发及产品升级过程中有重要作用。U-Boot以其结构清晰、功能强大、跨平台支持等优势而应用广泛,同时结合SD卡设备方便携带、操作简单的特点,本文分析了U-Boot SD卡启动原理并进行了实际移植工作,在U-Boot中增加了SD卡启动的支持。实验结果表明使用本文的方法可正确实现U-Boot的SD卡启动,并可进行操作系统内核的加载。

关键词:U-Boot SD卡启动

1 前言

近年来,伴随着信息技术与电子技术的高速发展,嵌入式技术已经被广泛地应用于人们日常的生产生活中,以嵌入式处理器为核心的各种智能终端不断出现,这些智能终端大都安装有嵌入式操作系统以支持更多功能丰富的应用程序。随着科技的不断进步以及终端设备功能的不断加强,智能终端已经可以被视为一台微型的计算机系统。

类似于通用的PC机操作系统,嵌入式操作系统也需要在硬件设备初始化后由引导加载程序将系统内核加载至内存中运行。通用Bootloader(universal boot loader,U-Boot)是遵循GPL条款的开放源代码项目,它不仅可以引导多种操作系统,同时还支持多种体系架构的CPU。U-Boot代码结构清晰,功能丰富,具有良好的网络技术支持,同时移植方便,这些特点使得U-Boot在嵌入式系统中获得了广泛的应用。

S3C6410是三星公司推出的一款基于ARM11架构的通用嵌入式处理器,该款处理器性能卓越,接口丰富,能够满足大多数嵌入式设备的需求。因此,本文首先介绍了U-Boot的工作原理,然后基于S3C6410处理器进行了U-Boot硬件相关部分的分析与移植,并且添加了U-Boot目前尚未支持的SD卡启动模式的代码。

2 U-Boot工作原理

2.1 U-Boot代码结构简介

U-Boot的源码目录结构比较简单,大部分目录通过其名字就可获知该目录下源码功能

1与平台或开发板相关;○2通用函数库;○3设备驱动的信息。这些目录可以划分为四大类:○

4U-Boot工具、示例程序、文档。 程序;○

在分析和移植的过程中我们主要关注的是硬件相关部分的源码,涉及到的目录主要有board、cpu以及include这三个,其主要功能如表(1)所示。

表(1) U-Boot主要硬件相关目录 目录 board cpu include 说明 存放电路板相关的目录文件。每种型号电路板对应一个目录。 存放CPU相关的目录文件,例如arm920t、arm1176等目录。 在configs子目录中存放着相关开发板的配置文件。 2.2 U-Boot操作模式 U-Boot有两种操作模式:一种为启动加载模式,一种为下载模式。上电后U-Boot即工作在启动加载模式,此模式下U-Boot会自动完成基本硬件的初始化以及操作系统内核的加载和运行,整个过程没有用户介入,这种模式一般应用于产品发布时。下载模式一般用于系

统开发阶段,此模式下U-Boot不会自动加载操作系统,开发者可以通过命令与U-Boot进行交互,实现程序的下载、固化或者调试过程,U-Boot所提供的丰富的操作命令大大提高了系统的开发效率。 2.3 U-Boot启动流程

U-Boot的启动过程分为两阶段。第一阶段由汇编语言实现,与具体硬件平台相关;第二阶段由可读性和可移植性较好的C语言实现,实现U-Boot的主要功能。这要设计的优点在于可以把针对于硬件的代码与系统的通用代码划分开,使得系统的移植工作主要针对于第一阶段代码的修改,而无需或只需少量修改第二阶段代码,简化了移植过程,提高了系统开发效率。

1硬件设备的初始化;○2为加载bootloaderU-Boot第一阶段代码实现的主要功能有:○

3复制bootloader第二阶段代码到RAM空间第二阶段准备RAM空间(即初始化SDRAM);○

4设置堆栈;○5跳转到第二阶段C代码入口处。其流程(U-Boot拷贝其全部代码到RAM);○

如图(1)所示。

开始重定位代码设置中断向量表初始化堆栈将CPU设置为管理模式跳转到C入口初始化内存结束 图(1) U-Boot第一阶段代码启动流程

当系统完成代码搬运并设置好C语言使用的堆栈等信息后,就会跳转到内存中的第二阶

1继续初始化相关硬件设段代码C语言入口处继续运行。第二阶段代码完成的主要功能有:○

2检测系统内存映射;○3加载内核映像及根文件系统备(如串口、系统时钟及定时器等);○

4设置内核启动参数;○5调用内核。阶段2的程序流程如图(2)所示。 映像;○

开始读取环境变量到内存指定位置初始化CPU初始化定时器初始化网络设备初始化环境变量调用main_loop函数初始化环境变量bootdelay秒内有串口输入?YN初始化串口检测系统内存映射循环读取串口执行相应命令执行bootcmd变量命令初始化NAND FLASH结束 图(2) U-Boot第二阶段执行流程

由图中可以看出,第二阶段的U-Boot会继续对硬件设备进行初始化,为内核的加载执行进行相关环境的配置,并在设置好相应的交互终端设备后等待用户bootdelay秒,如果在该时间段内串口有输入,则U-Boot进入下载模式,循环读取串口命令并执行;如果串口没有输入,则U-Boot执行启动加载模式代码,将操作系统内核加载到内存并执行。

3 S3C6410 U-Boot SD卡启动模式分析

3.1 U-Boot代码搬移原理

当系统上电后,CPU从运行地址处加载代码并执行,S3C6410的CPU起始运行地址是0x00000000,而真正执行代码的SDRAM设备被映射到了起始地址为0x50000000的内存空间上,对此S3C6410处理器主要有两种解决方案:一是将类似于NOR Flash的存储设备挂接在起始地址0的内存空间上,这种设备的特点是掉电不丢失其存储数据、接口以及访问指令和内存相同,并且其上可直接执行程序,称为XIP (eXecute In Place)设备,这样就可以实现CPU在地址0处加载并执行指令的目的;另一种方案是S3C6410有一块8K大小的称为Stepping Stone的内部RAM区域,该区域被映射到了地址空间0处。选择其他设备启动时,上电后系统会将U-Boot代码的前8K自动复制到Stepping Stone区域执行,同样达到了在地址0处执行代码的目的。

但使用上文提到的两种方案都存在各自的问题。Nor Flash虽然可以直接执行代码,但其执行速度不如SDRAM快;虽然内部RAM区域在速度上可以取得理想效果,但其大小只有8K,而编译好U-Boot文件大多大于8K,根本放不下一个完整的U-Boot。基于以上理由,U-Boot在第一阶段代码的执行过程中便有了代码搬移这一步骤,其思路为在U-Boot的前8K代码中,设置好最基本的环境后就将U-Boot全部代码从存储设备拷贝到内存中,并跳到内存中执行后续代码段,这样就达到了使U-Boot在内存中运行的目的。 3.2 S3C6410 SD卡启动原理

S3C6410支持多种启动方式,包括NOR Flash启动、Nand Flash启动、MODEM启动、iROM启动等方式。其中iROM启动方式即从internal ROM中启动,这种模式可以提供对SD卡的支持。由于SD卡设备简单易用并且方便携带,故本文针对SD卡启动方式进行分析并移植。

S3C6410 SD卡启动流程如图(3)所示。

S3C6410ARM1176JZF-SSDRAMController24SDRAMSteppingStone(8KB)D-TCM(16KB)1iROM(BL0)(32KB)3HS-MMCControllerOneNANDControllerNandControllerBooting DeviceBL2BL1OSF/S 图(3) SD卡启动流程

当选择SD卡启动时,处理器上电后,会运行iROM中的固件程序,这个程序被称为BootLoader0(BL0),它会在进行一些必要的初始化工作后,从SD卡指定位置中读取8K的U-Boot代码到内部Stepping Stone中运行,这段代码被称为BootLoader1(BL1)。BL1即U-Boot

的前8K代码,这段代码会随后从SD卡中加载BL2(即整个U-Boot程序)到内存中并跳到相应地址处运行。 3.3 SD卡设备空间布局

从SD卡启动时,系统上电后BL0程序会从SD卡特定位置加载BL1代码,因此BL1代码必须放置在预先约定好的位置上。根据三星公司官方文档,SD卡的空间布局如图(4)所示。

[SD/MMC 1Block = 512Byte]SD/MMC DeviceRecommendationUser File SystemKernelBL2BL1(8K)MandatorySignatureReserved(512Byte)(512Byte)1116

图(4) SD卡空间布局

由图中可以看出,我们要使用SD卡启动系统,必须将BL1的8K代码烧写到从SD卡末端起第18个块的起始地址处,同时最好将BL2紧邻BL1放在其前面的数据块中。

4 U-Boot移植主要步骤

U-Boot支持三星公司的smdk6400开发板,本文所采用的硬件平台和smdk6400开发板相似,因此本文在smdk6400开发板相关文件的基础上实现U-Boot的移植。但smdk6400并不支持SD卡启动方式,因此需要我们在移植过程中根据上文内容自行修改。移植的主要过程及关键步骤如下:

4.1 开发板U-Boot项目框架搭建

(1) 复制board/samsung目录下的smdk6400目录,并重命名为chd6410;

(2) 进入chd6410目录,将smdk6400.c文件重命名为chd6410.c,并将Makefile内

容中smdk6400.o修改为chd6410.o;

(3) 复制include/configs/smdk6400.h,并重命名为chd6410.h; (4) 修改U-Boot根目录下Makefile文件,将smdk6400_config的相关内容复制一份

并将其更名为chd6410_config;

(5) 复制nand_spl/board/samsung目录下的smdk6400目录,并重命名为chd6410; 4.2 配置文件修改

U-Boot的功能配置文件是include/configs/chd6410.h头文件,通过在该文件中开启或关闭一些宏,或者修改一些宏的定义值,可以达到对U-Boot各项功能的配置目的,本文中对于该文件的修改主要包括以下几点:

(1) 修改处理器类型宏定义的值,将

#define MACH_TYPE 1270 改为

#define MACH_TYPE 2520;

(2) 增加DM9000网卡驱动程序支持。在该文件中添加以下宏定义:

#define CONFIG_NET_MULTI 1 #define CONFIG_DRIVER_DM9000 1 #define CONFIG_DM9000_NO_SROM 1 #define CONFIG_DM9000_USE_16BIT 1 #define CONFIG_DM9000_BASE 0x18000300

#define DM9000_IO #define DM9000_DATA

#define CONFIG_ETHADDR #define CONFIG_NETMASK #define CONFIG_IPADDR #define CONFIG_SERVERIP #define CONFIG_GATEWAYIP

CONFIG_DM9000_BASE (CONFIG_DM9000_BASE+4) 08:08:10:12:11:22 255.255.255.0 192.168.1.101 192.168.1.85 192.168.1.1

(3) 由于开发板没有NOR Flash,因此删除NOR Flash相关配置宏,并添加#define

CONFIG_SYS_NO_FLASH;

(4) 添加SD卡支持:

#define CONFIG_GENERIC_MMC 1 #define CONFIG_MMC 1 #define CONFIG_S3C64X0_MMC 1 #define CONFIG_CMD_MMC

#define CONFIG_ENV_IS_IN_MMC 1 #define CONFIG_SYS_MMC_ENV_DEV 0 (5) 定义配置为SD卡启动所需要的各常量值: #define CONFIG_SYS_MMC_U_BOOT_SIZE (512 * 1024) #defineMMC_LCD_VIDEO_BACKGROUND_SIZE \\ LCD_VIDEO_BACKGROUND_LOADSIZE #define MMC_INIT_REQUIRED 0 #defineTCM_BASE (0x0C004000) #define BL1_SIZE (8 * 1024) #define eFUSE_SIZE (1 * 1024) #define MMC_BLKSIZE (512) #define MMC_TOTAL_BLKCNT (*((volatile unsigned int*)(TCM_BASE - 0x4))) #define MMC_HIGH_CAPACITY (*((volatile unsigned int*)(TCM_BASE - 0x8))) #define MMC_UBOOT_POS_BACKWARD (0x300000) #define MMC_ENV_POS_BACKWARD (0x280000) #define MMC_BACKGROUND_POS_BACKWARD (0x260000) #defineMMC_UBOOT_POS(MMC_TOTAL_BLKCNT –\\

(MMC_UBOOT_POS_BACKWARD/MMC_BLKSIZE))

#define MMC_UBOOT_BLKCNT (CONFIG_SYS_MMC_U_BOOT_SIZE /\\

MMC_BLKSIZE)

#define CONFIG_SYS_MMC_U_BOOT_DST CONFIG_SYS_PHY_UBOOT_BASE #defineCONFIG_SYS_MMC_U_BOOT_START \\ CONFIG_SYS_MMC_U_BOOT_DST

4.3 添加SD卡启动支持

由以上分析得知,要支持SD卡启动,需要在第一阶段代码中将SD卡中BL2区域的数据(即U-Boot可执行文件)复制到SDRAM中,三星官方手册中指出BL0的代码有一个函数可以实现该功能:

图(5)拷贝SD卡数据的函数

因此移植的关键在于初始化内存之后利用该函数将U-Boot拷贝到内存中。为此我们将arch/arm/cpu/arm1176中的

bnand_boot 改为

bmmc_boot_copy

并定义mmc_boot_copy函数为: voidmmc_boot_copy(void) { volatile u32 *mmc_control4; __attribute__((noreturn)) void (*uboot)(void); mmc_control4 = (volatile u32 *)0x7C20008C; writel(readl(mmc_control4) | (0x3 << 16), mmc_control4);

copy_sd_mmc_to_mem(MMC_BOOT_CHANNEL,MMC_UBOOT_POS,

MMC_UBOOT_BLKCNT,

(uint *)(CONFIG_SYS_MMC_U_BOOT_START),

MMC_INIT_REQUIRED); uboot = (void *)(CONFIG_SYS_MMC_U_BOOT_START); (*uboot)(); }

4.4 其他杂项修改

经过了以上几个主要步骤,还需要根据具体需求进行一些代码的少量修改,如为了调试增加LED灯的显示代码,在初始化函数中增加DM9000网卡启动函数,修改命令行提示符等。

5 实验结果

修改好各代码文件后,交叉编译U-Boot工程,将编译后的u-boot.bin文件烧写到SD卡中,设置开发板为SD卡启动模式后上电,可以看到U-Boot正常启动并等待用户输入交互命令。

图(6)正常启动U-Boot

设置bootcmd环境变量后重启开发板,使U-Boot进入启动加载模式加载内核并执行,从终端信息中可以看到内核被正常加载。

图(7)加载操作系统

6 总结

本文详细分析了U-Boot的启动流程以及S3C6410 SD卡的启动原理,并基于理论分析进行了U-Boot的实际移植工作。结果表明最终移植好的U-Boot可应用于嵌入式系统中进行操作系统内核的加载。由于嵌入式开发的第一步工作就是对BootLoader进行移植并且U-Boot应用广泛,因此本文对于指导实际的嵌入式开发工作具有较好的实用价值。

参考文献

[1] 吴玉香,周建香,郭建勋.U-Boot在S3C2410上的移植及功能扩展[J].计算机工程与设计,2010,31(4):729-732

[2] 刘磊,张凤荔,秦志光.基于U-boot构建嵌入式Linux的Bootloader[J].计算机应用研究,2007,24(12):238-240

[3] 莱文,李勇译.链接器与加载器[M].北京:北京航空航天大学出版社,2009

[4] 俞甲子,石凡,潘爱民.程序员的自我修养——链接、装载与库[M].北京:电子工业出版社,2009

[5] 韦东山.嵌入式Linux应用开发完全手册[M].北京:人民邮电出版社,2008

本文来源:https://www.bwwdw.com/article/6so7.html

Top