一.关于嵌入式系统 Boot Loader 技术内幕
可以对Boot loader 有个大概的了解.
二.u-boot的介绍
1 U-Boot简介
U-Boot,全称Universal Boot Loader,是遵循GPL条款的开放源码项目。从FADSROM、8xxROM、PPCBOOT逐步发展演化而来。其源码目录、编译形式与Linux内 核很相似,事实上,不少U-Boot源码就是相应的Linux内核源程序的简化,尤其是一些设备的驱动程序,这从U-Boot源码的注释中能体现这一点。 但是U-Boot不仅仅支持嵌入式Linux系统的引导,当前,它还支持NetBSD, VxWorks, QNX, RTEMS, ARTOS, LynxOS嵌入式操作系统。其目前要支持的目标操作系统是OpenBSD, NetBSD, FreeBSD,4.4BSD, Linux, SVR4, Esix, Solaris, Irix, SCO, Dell, NCR, VxWorks, LynxOS, pSOS, QNX, RTEMS, ARTOS。这是U-Boot中Universal的一层含义,另外一层含义则是U-Boot除了支持PowerPC系列的处理器外,还能支持MIPS、 x86、ARM、NIOS、XScale等诸多常用系列的处理器。这两个特点正是U-Boot项目的开发目标,即支持尽可能多的嵌入式处理器和嵌入式操作 系统。就目前来看,U-Boot对PowerPC系列处理器支持最为丰富,对Linux的支持最完善。其它系列的处理器和操作系统基本是在2002年11 月PPCBOOT改名为U-Boot后逐步扩充的。从PPCBOOT向U-Boot的顺利过渡,很大程度上归功于U-Boot的维护人德国DENX软件工 程中心Wolfgang Denk[以下简称W.D]本人精湛专业水平和持着不懈的努力。当前,U-Boot项目正在他的领军之下,众多有志于开放源码BOOT LOADER移植工作的嵌入式开发人员正如火如荼地将各个不同系列嵌入式处理器的移植工作不断展开和深入,以支持更多的嵌入式操作系统的装载与引导。
选择U-Boot的理由:
① 开放源码;
② 支持多种嵌入式操作系统内核,如Linux、NetBSD, VxWorks, QNX, RTEMS, ARTOS, LynxOS;
③ 支持多个处理器系列,如PowerPC、ARM、x86、MIPS、XScale;
④ 较高的可靠性和稳定性;
④ 较高的可靠性和稳定性;
⑤ 高度灵活的功能设置,适合U-Boot调试、操作系统不同引导要求、产品发布等;
⑥ 丰富的设备驱动源码,如串口、以太网、SDRAM、FLASH、LCD、NVRAM、EEPROM、RTC、键盘等;
⑦ 较为丰富的开发调试文档与强大的网络技术支持;
U-Boot,全称Universal Boot Loader,是遵循GPL条款的开放源码项目。从FADSROM、8xxROM、PPCBOOT逐步发展演化而来。其源码目录、编译形式与Linux内 核很相似,事实上,不少U-Boot源码就是相应的Linux内核源程序的简化,尤其是一些设备的驱动程序,这从U-Boot源码的注释中能体现这一点。 但是U-Boot不仅仅支持嵌入式Linux系统的引导,当前,它还支持NetBSD, VxWorks, QNX, RTEMS, ARTOS, LynxOS嵌入式操作系统。其目前要支持的目标操作系统是OpenBSD, NetBSD, FreeBSD,4.4BSD, Linux, SVR4, Esix, Solaris, Irix, SCO, Dell, NCR, VxWorks, LynxOS, pSOS, QNX, RTEMS, ARTOS。这是U-Boot中Universal的一层含义,另外一层含义则是U-Boot除了支持PowerPC系列的处理器外,还能支持MIPS、 x86、ARM、NIOS、XScale等诸多常用系列的处理器。这两个特点正是U-Boot项目的开发目标,即支持尽可能多的嵌入式处理器和嵌入式操作 系统。就目前来看,U-Boot对PowerPC系列处理器支持最为丰富,对Linux的支持最完善。其它系列的处理器和操作系统基本是在2002年11 月PPCBOOT改名为U-Boot后逐步扩充的。从PPCBOOT向U-Boot的顺利过渡,很大程度上归功于U-Boot的维护人德国DENX软件工 程中心Wolfgang Denk[以下简称W.D]本人精湛专业水平和持着不懈的努力。当前,U-Boot项目正在他的领军之下,众多有志于开放源码BOOT LOADER移植工作的嵌入式开发人员正如火如荼地将各个不同系列嵌入式处理器的移植工作不断展开和深入,以支持更多的嵌入式操作系统的装载与引导。
选择U-Boot的理由:
① 开放源码;
② 支持多种嵌入式操作系统内核,如Linux、NetBSD, VxWorks, QNX, RTEMS, ARTOS, LynxOS;
③ 支持多个处理器系列,如PowerPC、ARM、x86、MIPS、XScale;
④ 较高的可靠性和稳定性;
④ 较高的可靠性和稳定性;
⑤ 高度灵活的功能设置,适合U-Boot调试、操作系统不同引导要求、产品发布等;
⑥ 丰富的设备驱动源码,如串口、以太网、SDRAM、FLASH、LCD、NVRAM、EEPROM、RTC、键盘等;
⑦ 较为丰富的开发调试文档与强大的网络技术支持;
2 U-Boot主要目录结构
- board 目标板相关文件,主要包含SDRAM、FLASH驱动;
- common 独立于处理器体系结构的通用代码,如内存大小探测与故障检测;
- cpu 与处理器相关的文件。如mpc8xx子目录下含串口、网口、LCD驱动及中断初始化等文件;
- driver 通用设备驱动,如CFI FLASH驱动(目前对INTEL FLASH支持较好)
- doc U-Boot的说明文档;
- examples可在U-Boot下运行的示例程序;如hello_world.c,timer.c;
- include U-Boot头文件;尤其configs子目录下与目标板相关的配置头文件是移植过程中经常要修改的文件;
- lib_xxx 处理器体系相关的文件,如lib_ppc, lib_arm目录分别包含与PowerPC、ARM体系结构相关的文件;
- net 与网络功能相关的文件目录,如bootp,nfs,tftp;
- post 上电自检文件目录。尚有待于进一步完善;
- rtc RTC驱动程序;
- tools 用于创建U-Boot S-RECORD和BIN镜像文件的工具;
- board 目标板相关文件,主要包含SDRAM、FLASH驱动;
- common 独立于处理器体系结构的通用代码,如内存大小探测与故障检测;
- cpu 与处理器相关的文件。如mpc8xx子目录下含串口、网口、LCD驱动及中断初始化等文件;
- driver 通用设备驱动,如CFI FLASH驱动(目前对INTEL FLASH支持较好)
- doc U-Boot的说明文档;
- examples可在U-Boot下运行的示例程序;如hello_world.c,timer.c;
- include U-Boot头文件;尤其configs子目录下与目标板相关的配置头文件是移植过程中经常要修改的文件;
- lib_xxx 处理器体系相关的文件,如lib_ppc, lib_arm目录分别包含与PowerPC、ARM体系结构相关的文件;
- net 与网络功能相关的文件目录,如bootp,nfs,tftp;
- post 上电自检文件目录。尚有待于进一步完善;
- rtc RTC驱动程序;
- tools 用于创建U-Boot S-RECORD和BIN镜像文件的工具;
3 U-Boot支持的主要功能
U-Boot可支持的主要功能列表
系统引导 支持NFS挂载、RAMDISK(压缩或非压缩)形式的根文件系统
支持NFS挂载、从FLASH中引导压缩或非压缩系统内核;
基本辅助功能强大的操作系统接口功能;可灵活设置、传递多个关键参数给操作系统,适合系统在不同开发阶段的调试要求与产品发布,尤对Linux支持最为强劲;
支持目标板环境参数多种存储方式,如FLASH、NVRAM、EEPROM;
CRC32校验,可校验FLASH中内核、RAMDISK镜像文件是否完好;
设备驱动串口、SDRAM、FLASH、以太网、LCD、NVRAM、EEPROM、键盘、USB、PCMCIA、PCI、RTC等驱动支持;
上电自检功能 SDRAM、FLASH大小自动检测;SDRAM故障检测;CPU型号;
特殊功能 XIP内核引导;
U-Boot可支持的主要功能列表
系统引导 支持NFS挂载、RAMDISK(压缩或非压缩)形式的根文件系统
支持NFS挂载、从FLASH中引导压缩或非压缩系统内核;
基本辅助功能强大的操作系统接口功能;可灵活设置、传递多个关键参数给操作系统,适合系统在不同开发阶段的调试要求与产品发布,尤对Linux支持最为强劲;
支持目标板环境参数多种存储方式,如FLASH、NVRAM、EEPROM;
CRC32校验,可校验FLASH中内核、RAMDISK镜像文件是否完好;
设备驱动串口、SDRAM、FLASH、以太网、LCD、NVRAM、EEPROM、键盘、USB、PCMCIA、PCI、RTC等驱动支持;
上电自检功能 SDRAM、FLASH大小自动检测;SDRAM故障检测;CPU型号;
特殊功能 XIP内核引导;
三.u-boot 移植支持MagicARM2200
1.MagicARM2200的核心板介绍:
DeviceARM2200工控板(6层PCB设计,支持ARM7)
* 2M字节NOR FLASH(0x80000000――0x801FFFFF)型号SST39VF1601
* 8M字节PSRAM(0x81000000――0x801FFFFF)型号MT45W4MW16
* 8M字节PSRAM(0x81000000――0x801FFFFF)型号MT45W4MW16
* 16M字节NAND FLASH
* 256字节E2PROM
* ARM7-LPC2290 (片内RAM 0x40000000――0x40004000)
* ARM7-LPC2290 (片内RAM 0x40000000――0x40004000)
* 以太网芯片DM9000E(0x83000000――0x833FFFFF)
2.U-BOOT移植
由于U-BOOT本身并不支持NXP系列的ARM,因此可以到NXP的官方网站下载一个基于U-BOOT的补丁(http://www.phytec.com/zip/uClinux_package.zip),下载解压之后,根据文件:getting started u-boot.pdf的操作提示,将补丁打上。打补丁后,将会出现下列文件:
patching file board/lpc2294/config.mk
patching file board/lpc2294/flash.c
patching file board/lpc2294/flash.c
patching file board/lpc2294/lowlevel_init.S
patching file board/lpc2294/lpc2294.c
patching file board/lpc2294/Makefile
patching file board/lpc2294/u-boot.lds
patching file cpu/arm7tdmi/config.mk
patching file cpu/arm7tdmi/cpu.c
patching file cpu/arm7tdmi/interrupts.c
patching file cpu/arm7tdmi/Makefile
patching file cpu/arm7tdmi/serial.c
patching file cpu/arm7tdmi/start.S
patching file drivers/rtl8019.c
patching file drivers/rtl8019.h
patching file include/asm-arm/arch-arm7tdmi/hardware.h
patching file include/configs/lpc2294.h
patching file Makefile
patching file board/lpc2294/lpc2294.c
patching file board/lpc2294/Makefile
patching file board/lpc2294/u-boot.lds
patching file cpu/arm7tdmi/config.mk
patching file cpu/arm7tdmi/cpu.c
patching file cpu/arm7tdmi/interrupts.c
patching file cpu/arm7tdmi/Makefile
patching file cpu/arm7tdmi/serial.c
patching file cpu/arm7tdmi/start.S
patching file drivers/rtl8019.c
patching file drivers/rtl8019.h
patching file include/asm-arm/arch-arm7tdmi/hardware.h
patching file include/configs/lpc2294.h
patching file Makefile
① board/lpc2294/config.mk主要用来配置TEXT_BASE的地址。TEXT_BASE用来确定U-BOOT中的stage2从 FLASH搬到RAM中的基地址,一般stage2大小都小于1M,因此可以配置为RAM的最高地址-1MB的空间作为TEXT_BASE的值,所以针对 MagicARM2200,我将其设置为0x81700000。
① include/configs/lpc2294.h主要是对相应的开发板进行各种参数配置。进行以下修改:
由于本实验箱的网络接口芯片采用的是DM9000E,因此注释掉关于RTL8019的配置
添加以下定义:
#define CONFIG_DRIVER_DM9000 1
#define CONFIG_DM9000_BASE 0x83000300
#define DM9000_IO CONFIG_DM9000_BASE
#define DM9000_DATA (CONFIG_DM9000_BASE+4)
#define CONFIG_DM9000_USE_16BIT
#define CONFIG_DM9000_BASE 0x83000300
#define DM9000_IO CONFIG_DM9000_BASE
#define DM9000_DATA (CONFIG_DM9000_BASE+4)
#define CONFIG_DM9000_USE_16BIT
修改 #define CFG_HZ (11059200/1000)
修改 #define CFG_MALLOC_LEN (128*1024 )
修改 #define CONFIG_ETHADDR 00:14:97:0f:15:d7
添加 #define CONFIG_LPC 1
以下的修改是关于NOR FLASH的相关配置
首先看一下SST39VF1601的datasheet
这个flash是16Mbit的也就是2MByte的大小
sector 2Kword 也就是4Kbyte
block 32Kword 也就是64Kbyte
这里要弄清楚这两个参数的目的主要是flash的擦除是要按照sector或block的方式来进行的,每种有不同的指令(flash.c都支持)。
这里我们选用block的方式,故2M的Flash有32个block(32*64KB=2MB)。这些参数都是要定义到头文件里面的,故修改如下
#define PHYS_FLASH_SIZE 0x00200000
#define CFG_MAX_FLASH_SECT (32)
#define CFG_ENV_ADDR (CFG_FLASH_BASE + 0x030000)
#define CFG_ENV_IS_IN_FLASH 1
#define CFG_ENV_SIZE 0x10000
#define CFG_ENV_SECT_SIZE 0x10000
#define CFG_FLASH_ADDR0 0x5555
#define CFG_FLASH_ADDR1 0x2aaa
#define CFG_FLASH_WORD_SIZE unsigned short
#define CFG_FLASH_READ0 0x0000
#define CFG_FLASH_READ1 0x0001
#define CFG_FLASH_READ2 0x0002
#define CFG_MONITOR_LEN (256 * 1024)
这里有几个参数先说明一下,
PHYS_FLASH_SIZE
这个参数定义Flash的容量,因为在flash初始化的时候,程序会去读flash的Manufacturer's ID和Device ID,然后会根据这个ID来匹配Flash的容量,SST39VF1601的参数如下:
Manufacturer's ID BFH
Device ID 234BH
CFG_MAX_FLASH_SECT
CFG_ENV_ADDR
CFG_ENV_SIZE
第一个参数确定最大的block的数量(我们是按照block来的),值为32(32*64KB = 2M)
第二个参数区定的u-boot环境变量的起始地址,由于Flash的擦除是按块或扇区的,所以需要对齐,我们使用64KB块方式,故我们把环境变量的首地址暂时设在0x30000(192KB)处。
第三个参数代表环境变量的大小,我们设置为0x10000,正好是一个block的大小。
CFG_FLASH_ADDR0
CFG_FLASH_ADDR1
CFG_FLASH_WORD_SIZE
前面两个参数是flash软件编程命令字中规定的地址,可以看datasheet。
第三个参数是Flash数据线工作的模式,我们的Flash工作于16bit模式,故这个定义为unsigned short。
CFG_FLASH_READ0
CFG_FLASH_READ1
CFG_FLASH_READ2
这些是用于查询Flash操作状态的,即是读FLASH状态时用的。在datasheet中有详细的说明。
② board/lpc2294/flash.c主要是用来对NOR FLASH进行各种操作。所以针对MagicARM2200对flash.c进行修改如下:
按照u-boot的启动流程,在board.c中首先要进行flash_init (),
首先我们分析一下里面的flash_get_size函数。根据前述Flash的特点(16bit的工作方式)把
addr2[CFG_FLASH_ADDR0] = (CFG_FLASH_WORD_SIZE)0x00AA00AA;
addr2[CFG_FLASH_ADDR1] = (CFG_FLASH_WORD_SIZE)0x00550055;
addr2[CFG_FLASH_ADDR0] = (CFG_FLASH_WORD_SIZE)0x00900090;
改为
addr2[CFG_FLASH_ADDR0] = (CFG_FLASH_WORD_SIZE)0x00AA;
addr2[CFG_FLASH_ADDR1] = (CFG_FLASH_WORD_SIZE)0x0055;
addr2[CFG_FLASH_ADDR0] = (CFG_FLASH_WORD_SIZE)0x0090;
这个函数中不识别device ID为234BH的SST39VF1601的片子,故给它添加上如下case代码在include/flash.h中添加宏#define FLASH_SST1601 0x004B
case (CFG_FLASH_WORD_SIZE)SST_ID_xF1601:
info->flash_id += FLASH_SST1601;
info->sector_count = 32;
info->size = 0x00200000;
break;
注释下面的代码是建立flash的block的分区地址表,我们的block的大小是64KB(0x10000)从下面的代码看出,
需要将
#ifdef CONFIG_LPC
info->start[i] = base + (i * 0x00020000);
info->start[i] = base + (i * 0x00020000);
#else
info->start[i] = base + (i * 0x00010000);
info->start[i] = base + (i * 0x00010000);
没有评论:
发表评论