分类: 嵌入式
2010-12-17 09:54:02
一、获得U-Boot源码
直接从U-Boot的官方网站下载的源代码,版本是1.3.2.,放在src 目录下。将u-boot-1.3.2.tar.bz2拷贝了工作目录下,解压源码包:
[root@vm-dev 2410-s]# pwd
/root/2410-s
[root@vm-dev 2410-s]# cp /mnt/hgfs/e/u-boot-1.3.2.tar.bz2 ./
[root@vm-dev 2410-s]# tar jxvf u-boot-1.3.2.tar.bz2
[root@vm-dev 2410-s]# cd u-boot.1.3.2
二、建立板级支持包
在board目录下,每一块开发板都有一个对应的目录,因此我们需要为我们的开发板建 立一个目录,名字叫做up2410,并创建相应的文件:
[root@vm-dev u-boot-1.3.2]# cd board/
[root@vm-dev board]# mkdir up2410
[root@vm-dev board]# cp smdk2410/* up2410
[root@vm-dev board]# cd ../
上面的步骤中,我们把smdk2410目录下的所有文件都拷贝到了我们的up2410目录下, 因为我们的开发板和smdk2410开发板的配置差不多。
每 个 开 发 板 都 有 一 个 自 己 的 配 置 文 件 , 如 smdk2410 开 发 板 的 配 置 文 件 为 include/configs/smdk2410.h,我们也需要为我们的开发板建立自己的配置文件。可以直接从 smdk2410开发板的配置文件中修改而来。因此我们先把smdk2410的配置文件复制到我们 开发板的配置文件当中:
[root@vm-dev u-boot-1.3.2]# cp include/configs/smdk2410.h include/configs/up2410.h
然后,修改Makefile,使得可以配置我们的开发板:
[root@vm-dev u-boot-1.3.2]# vi Makefile
在Makefile中找到下面两行:
smdk2400_config : unconfig
@$(MKCONFIG) $(@:_config=) arm arm920t smdk2400 NULL s3c24x0
紧接这这两行添加如下两行:
up2410_config : unconfig
@$(MKCONFIG) $(@:_config=) arm arm920t up2410 NULL s3c24x0
注意第二行开始部分的空白是按TAB键获得的!红色的部分显示了不同处!
这样,我们自己的板级支持包就建好了。
三、添加代码,支持从Nand Flash启动
由于我们的开发板上没有Nor Flash,只能从Nand Flash启动。而U-Boot默认不支持从 Nand Flash启动,所以需要我们自己添加代码来实现从Nand Flash启动。
1、修改start.S文件
位于cpu/arm920t/目录下的start.S文件是开发板上电后运行的第一段代码,需要在 这个文件中添加内容,以支持从Nand Flash启动。
[root@vm-dev u-boot-1.3.2]# vi cpu/arm920t/start.S
首先,删掉start.S中的第181行和201行的下面内容:
#ifdef CONFIG_AT91RM9200
...............................................................
#endif
如果有这两句,这两句之间的内容将不会被编译。而我们的开发板需要执行这些内 容。然后,找到这一行:
#ifndef CONFIG_SKIP_RELOCATE_UBOOT
在紧接这这行的下面添加下面几行:
#ifdef CONFIG_S3C2410_NAND_BOOT
bl copy_myself
#else
再找到
ble copy_loop
在它的下面添加一行:
#endif
做 这 些 工 作 就 是 要 完 成 一 个 简 单 的 功 能 : 如 果 我 们 定 义 了 CONFIG_S3C2410_NAND_BOOT这个宏,那么就执行copy_myself这个子程序,否则就执 行#else下面的程序。copy_myself这个子程序的功能就是把U-Boot自身的代码从Nand Flash 拷贝到SDRAM中,需要我们自己实现,U-Boot自身并没有为我们实现。 我们把copy_myself也添加在start.S文件中。找到下面的一行:
_start_armboot: .word start_armboot
在这一行的下面添加如下的内容:
/*
*************************************************************************
*
* copy u-boot to ram
*
*************************************************************************
*/
#ifdef CONFIG_S3C2410_NAND_BOOT
copy_myself:
mov r10, lr @save return address to r10
ldr sp, DW_STACK_START
mov fp, #0
bl NF_Init
ldr r0, =UBOOT_RAM_BASE
mov r1, #0x0
mov r2, #0x30000
bl nand_read_whole
tst r0, #0x0
beq ok_nand_read
1: b 1b
ok_nand_read:
mov r0, #0x00000000
ldr r1, =UBOOT_RAM_BASE
mov r2, #0x400
go_next:
ldr r3, [r0], #4
ldr r4, [r1], #4
teq r3, r4
bne notmatch
subs r2, r2, #4
beq done_nand_read
bne go_next
notmatch:
1: b 1b
done_nand_read:
mov pc, r10
#endif
DW_STACK_START:
.word STACK_BASE+STACK_SIZE-4
上面是copy_myself的实现代码,添加完成以后,U-Boot启动时就会执行我们的这 段代码,将U-Boot的内容从Flash中拷贝到SDRAM中。 这样,start.S这个文件就修改完成了,保存刚才的修改。
#include
#include
#include
#define TACLS 0
#define TWRPH0 3
#define TWRPH1 0
#define U32 unsigned int
extern unsigned long nand_probe(unsigned long physadr);
static void NF_Reset(void)
{
int i;
NF_nFCE_L();
NF_CMD(0xFF);
for(i=0;i<10;i++);
NF_WAITRB();
NF_nFCE_H();
}
void NF_Init(void)
{
rNFCONF=(1<<15)|(1<<14)|(1<<13)|(1<<12)|(1<<11)|(TACLS<<8)|(TWRPH0<<4)|(TWRPH1<<0);
NF_Reset();
}
int nand_read_whole(unsigned char *buf, unsigned long start_addr, int size)
{
int i, j;
if ((start_addr & NAND_BLOCK_MASK) || (size & NAND_BLOCK_MASK))
return 1;
NF_nFCE_L();
for(i=0; i<10; i++);
i = start_addr;
while(i < start_addr + size) {
rNFCMD = 0;
rNFADDR = i & 0xff;
rNFADDR = (i >> 9) & 0xff;
rNFADDR = (i >> 17) & 0xff;
rNFADDR = (i >> 25) & 0xff;
NF_WAITRB();
for(j=0; j < NAND_SECTOR_SIZE; j++, i++) {
*buf = (rNFDATA & 0xff);
buf++;
}
}
NF_nFCE_H();
return 0;
}
上面就是nand.c文件的全部内容。为了使编译的时候能把这个文件编译进去,需要修改相应的Makefile:
[root@vm-dev u-boot-1.3.2]# vi board/up2410/Makefile
找到这一行:
COBJS := smdk2410.o flash.o
把这行的内容改为下面这行:
COBJS := smdk2410.o flash.o nand.o
即在行尾加上了nand.o,这样,编译的时候就会把nand.c编译进去,并进行链接。
3、修改up2410.h
前面提到,up2410.h是开发板的配置文件。关于nand.c中用到的一些宏或者其他需要 定义的,我们都放在up2410.h 中。注意,这里只介绍和从Nand 启动相关的配置,因为 up2410.h中还有很多其他配置,将在后面介绍!
[root@vm-dev u-boot-1.3.2]# vi include/configs/up2410.h
光标移动到文件的末尾,在文件的最后一个#endif的前面添加如下内容:
#define CONFIG_S3C2410_NAND_BOOT 1
#define STACK_BASE 0x33f00000
#define STACK_SIZE 0x8000
#define UBOOT_RAM_BASE 0x33f80000
#define CFG_NAND_BASE 0x4E000000
#define CFG_MAX_NAND_DEVICE 1
#define SECTORSIZE 512
#define NAND_SECTOR_SIZE SECTORSIZE
#define NAND_BLOCK_MASK (NAND_SECTOR_SIZE - 1)
#define ADDR_COLUMN 1
#define ADDR_PAGE 2
#define ADDR_COLUMN_PAGE 3
#define NAND_ChipID_UNKNOWN 0x00
#define NAND_MAX_FLOORS 1
#define NAND_MAX_CHIPS 1
#define WRITE_NAND_COMMAND(d, adr) do {rNFCMD = d;} while(0)
#define WRITE_NAND_ADDRESS(d, adr) do {rNFADDR = d;} while(0)
#define WRITE_NAND(d, adr) do {rNFDATA = d;} while(0)
#define READ_NAND(adr) (rNFDATA)
#define NAND_WAIT_READY(nand) {while(!(rNFSTAT&(1<<0)));}
#define NAND_DISABLE_CE(nand) {rNFCONF |= (1<<11);}
#define NAND_ENABLE_CE(nand) {rNFCONF &= ~(1<<11);}
#define NAND_CTL_CLRALE(nandptr)
#define NAND_CTL_SETALE(nandptr)
#define NAND_CTL_CLRCLE(nandptr)
#define NAND_CTL_SETCLE(nandptr)
#define CONFIG_MTD_NAND_VERIFY_WRITE 1
#define rNFCONF (*(volatile unsigned int *)0x4e000000)
#define rNFCMD (*(volatile unsigned char *)0x4e000004)
#define rNFADDR (*(volatile unsigned char *)0x4e000008)
#define rNFDATA (*(volatile unsigned char *)0x4e00000c)
#define rNFSTAT (*(volatile unsigned int *)0x4e000010)
#define rNFECC (*(volatile unsigned int *)0x4e000014)
#define rNFECC0 (*(volatile unsigned char *)0x4e000014)
#define rNFECC1 (*(volatile unsigned char *)0x4e000015)
#define rNFECC2 (*(volatile unsigned char *)0x4e000016)
#define NF_CMD(cmd) {rNFCMD=cmd;}
#define NF_ADDR(addr) {rNFADDR=addr;}
#define NF_nFCE_L() {rNFCONF&=~(1<<11);}
#define NF_nFCE_H() {rNFCONF|=(1<<11);}
#define NF_RSTECC() {rNFCONF|=(1<<12);}
#define NF_RDDATA() (rNFDATA)
#define NF_WRDATA(data) {rNFDATA=data;}
#define NF_WAITRB() {while(!(rNFSTAT&(1<<0)));}
这样,关于从Nand启动的修改就做完了。保存文件。
三、开发板的配置
前面已经提到,up2410.h是我们的开发板的配置文件,许多重要的内容都需要在这个文件中进行配置。
1、网卡配置
Smdk2410开发板上用的是CS8900网卡,而我们的开发板上使用的是AX88796网卡, 因此网卡的配置需要修改。找到下面三行:
#define CONFIG_DRIVER_CS8900 1 /* we have a CS8900 on-board */
#define CS8900_BASE 0x19000300
#define CS8900_BUS16 1 /* the Linux driver does accesses as shorts */
注释掉这三行,在这三行下面添加下面的两行:
#define CONFIG_DRIVER_DM9000 1
#define CONFIG_DRIVER_DM9000_BASE 0x10000000
#define DM9000_IO CONFIG_DM9000_BASE
#define DM9000_DATA (DM9000_IO + 2)
#define CONFIG_DM9000_USE_16BIT
这样定义主要是因为U-Boot中提供的DM9000X网卡驱动与我们的经典2410平台上使 用的DM9000A网卡有一定的不同之处,不能直接驱动我们的DM9000A网卡。因此,除了 这里对网卡的信息进行配置以外,还需要修改DM9000A网卡的驱动,将在后面介绍。
2、添加命令
U-Boot中提供了丰富的命令,smdk2410开发板配置了一部分命令,我们为我们的开发 板增加一些命令。找到下面的几行:
#define CONFIG_CMD_CACHE
#define CONFIG_CMD_DATE
#define CONFIG_CMD_ELF
在其下面添加下面几行:
#define CONFIG_CMD_REGINFO
#define CONFIG_CMD_NAND
#define CONFIG_CMD_PING
#define CONFIG_CMD_DLF
#define CONFIG_CMD_ENV
#define CONFIG_CMD_NET
这样就添加了一些我们需要的命令。
3、修改环境变量
环境变量是U-Boot运行时或者传递给内核的重要参数,需要正确设置。找到下面的一行:
#define CONFIG_BOOTDELAY 3
/*#define CONFIG_BOOTARGS "root=ramfs devfs=mount console=ttySA0,9600" */
/*#define CONFIG_ETHADDR 08:00:3e:26:0a:5b */
#define CONFIG_NETMASK 255.255.255.0
#define CONFIG_IPADDR 10.0.0.110
#define CONFIG_SERVERIP 10.0.0.1
/*#define CONFIG_BOOTFILE "elinos-lart" */
/*#define CONFIG_BOOTCOMMAND "tftp; bootm" */
#if defined(CONFIG_CMD_KGDB)
注意上面的#if defined(CONFIG_CMD_KGDB)处,需要做的修改都在这之前进行修 改。修改后的代码如下:
#define CONFIG_BOOTDELAY 3
#define CONFIG_BOOTARGS "root=/dev/mtdblock3 init=/linuxrc console=ttySAC0,115200"
#define CONFIG_ETHADDR 08:00:3e:26:0a:5b
#define CONFIG_NETMASK 255.255.255.0
#define CONFIG_IPADDR 192.168.1.131
#define CONFIG_SERVERIP 192.168.1.132
#define CONFIG_BOOTFILE "uImage"
#define CONFIG_BOOTCOMMAND "tftp; bootm"
#define CONFIG_CMDLINE_TAG 1
#define CONFIG_SETUP_MEMORY_TAGS 1
#define CONFIG_INITRD_TAG 1
#if defined(CONFIG_CMD_KGDB)
上面添加的环境变量在U-Boot 启动时作为U-Boot 的默认环境变量,如果不执行 saveenv命令,则这些变量只存在于SDRAM中;执行saveenv命令后,这些便量会保存到 Flash中,下次上电,在从Flash中把它读出来,作为环境变量使用。
4、修改命令提示符
找到下面一行:
#define CFG_PROMPT "SMDK2410 # " /* Monitor Command Prompt */
修改为:
#define CFG_PROMPT "[UP-2410 #]"
这样,U-Boot的命令提示符就是[UP-2410 #]。这样做只是为了使用的时候知道我们使用的是经典2410开发板上Bootloader,当然不改的话,也没有什么影响。
5、修改默认下载地址
找到下面的一行:
#define CFG_LOAD_ADDR 0x33000000 /* default load address */
这个变量定义的是在使用串口或者网卡下载文件到SDRAM时,如果不指定下载地 址,则下载到这个宏指定的默认地址。我们用下面的两行来替代:
#define CFG_LOAD_ADDR 0x30008000
#define CFG_TFTP_LOAD_ADDR 0x30008000
6、修改环境变量在Flash中的存储地址
找到下面的两行:
#define CFG_ENV_IS_IN_FLASH 1
#define CFG_ENV_SIZE 0x10000 /* Total Size of Environment Sector */
上面的定义说明环境变量是存在Flash中。我们的板子上只有Nand Flash,因此环境变 量只能存在Nand Flash中。因此,注释掉上面的两行,用下面的几行代替:
#define CFG_ENV_IS_IN_NAND 1
#define CFG_ENV_SIZE 0x4000
#define CFG_ENV_OFFSET (0x80000-0x4000)
表示环境变量存储在Nand Flash中,大小为16KB,起始地址是0.5M往下的16KB地址 处。这样的话,U-Boot占用的Flash地址是前0.5M,对U-Boot来说,已经足够了。
到这里,配置文件的修改就完成了。
四、修改网卡驱动
前面提到,我们的开发板上是DM9000A网卡,不能直接只用U-Boot提供的网卡驱 动,我们提供了这个网卡的驱动,由于修改的地方比较多,就不作详细解释了,直接给出这个驱动的实现代码。公有两个文件:dm9000x.c和dm9000x.h。这两个文件在我们的src目 录中存放。把这两个拷贝到u-boot源代码目录下的drivers/net下,替换掉U-Boot自身的驱动 文件。
[root@vm-dev u-boot-1.3.2]# cp /mnt/hgfs/e/dm9000x.c drivers/net/
cp:是否覆盖‘drivers/net/dm9000x.c’? y
[root@vm-dev u-boot-1.3.2]# cp /mnt/hgfs/e/dm9000x.h drivers/net/
cp:是否覆盖‘drivers/net/dm9000x.h’? y
[root@vm-dev u-boot-1.3.2]#
五、编译U-Boot
首先运行如下命令配置U-Boot:
[root@vm-dev u-boot-1.3.2]# make up2410_config
Configuring for up2410 board...
[root@vm-dev u-boot-1.3.2]#
然后运行make命令编译:
[root@vm-dev u-boot-1.3.2]# make
编译完成后,会在U-Boot的源代码目录下生成u-boot.bin文件。这个文件就是我们需要 的二进制文件。
六、烧写U-Boot
将编译得到的u-boot.bin拷贝到XP的D盘下,将我们光盘中的sjf2410-s.exe文件也拷贝 到D盘下。连接好开发板的电源、JTAG下载线,打开开发板的电源。在电脑桌面的左下角点击开始,找到运行:
四、修改网卡驱动
前面提到,我们的开发板上是DM9000A网卡,不能直接只用U-Boot提供的网卡驱 动,我们提供了这个网卡的驱动,由于修改的地方比较多,就不作详细解释了,直接给出这个驱动的实现代码。公有两个文件:dm9000x.c和dm9000x.h。这两个文件在我们的src目 录中存放。把这两个拷贝到u-boot源代码目录下的drivers/net下,替换掉U-Boot自身的驱动 文件。
[root@vm-dev u-boot-1.3.2]# cp /mnt/hgfs/e/dm9000x.c drivers/net/
cp:是否覆盖‘drivers/net/dm9000x.c’? y
[root@vm-dev u-boot-1.3.2]# cp /mnt/hgfs/e/dm9000x.h drivers/net/
cp:是否覆盖‘drivers/net/dm9000x.h’? y
[root@vm-dev u-boot-1.3.2]#
五、编译U-Boot
首先运行如下命令配置U-Boot:
[root@vm-dev u-boot-1.3.2]# make up2410_config
Configuring for up2410 board...
[root@vm-dev u-boot-1.3.2]#
然后运行make命令编译:
[root@vm-dev u-boot-1.3.2]# make
编译完成后,会在U-Boot的源代码目录下生成u-boot.bin文件。这个文件就是我们需要 的二进制文件。
六、烧写U-Boot
将编译得到的u-boot.bin拷贝到XP的D盘下,将我们光盘中的sjf2410-s.exe文件也拷贝 到D盘下。连接好开发板的电源、JTAG下载线,打开开发板的电源。在电脑桌面的左下角点击开始,找到运行: