2010.06在unsp2440上的移植(3)

一、 步骤五:U-boot支持TFTP、nfs网络下载

前面我们实现了使用串口下载并更新系统的功能,但是嵌入式系统的内核跟根文件系统都比较大,使用串口下载速度太慢,u-boot提供了通过TFTP、nfs等网络下载的功能支持,本节我们完成此项功能的移植与修改。

1) u-boot默认支持的是cs8900网卡,我们的开发板使用的是DM9000网卡,所以要做相应的修改。

首先要修改include/configs/unsp2440.h中的相关代码:

#define CONFIG_NET_MULTI

//#define CONFIG_CS8900 /* we have a CS8900 on-board */

//#define CONFIG_CS8900_BASE 0x19000300

//#define CONFIG_CS8900_BUS16 /* the Linux driver does accesses as shorts */

//屏蔽掉与cs8900有关的宏定义

#define CONFIG_DRIVER_DM9000 1

#define CONFIG_DM9000_NO_SROM 1

#define CONFIG_DM9000_BASE 0x18000300 //网卡片选地址

//网卡地址的选择:S3C2440片外寻址分成8个BLANK,每个BLANK的大小为128M,

//我们的开发板的网卡接在了BLANK3上,因此地址等于:128M*3*1024*1024=0x18000000,由于DM9000网卡本身的特性,IO地址需要从0x18000300开始,数据地址需要从0x18000304开始。

#define DM9000_IO 0x18000300

#define DM9000_DATA (0x18000300 + 4) //网卡数据地址

#define CONFIG_DM9000_USE_16BIT 1

 

2) 使用TFTP、NFS等服务必须配置相应的IP地址、网关等信息,我们同样需要修改include/congifs/unsp2440.h文件相应内容:

//给u-boot加上ping命令,用来测试网络通不通

#define CONFIG_CMD_PING

/ /恢复被注释掉的网卡MAC地址和修改你合适的开发板IP地址

#define CONFIG_ETHADDR   08:00:3e:26:0a:5b  //开发板MAC地址

#define CONFIG_NETMASK   255.255.255.0

#define CONFIG_IPADDR    192.168.1.105       //开发板IP地址

#define CONFIG_SERVERIP  192.168.1.103      //Linux主机IP地址

 

下面需要修改u-boot的源码以完成对unsp2440的支持:

3) 首先要修改dm9000网卡的总线宽度:board/samsung/unsp2440/lowlevel_init.S

将56行左右的

#define B3_BWSCON (DW16 + WAIT + UBLB)修改为:

#define B3_BWSCON (DW16)

 

4) 编译下载u-boot已测试网络情况

#ping 192.168.220.103

dm9000 i/o: 0x18000300, id: 0x90000a46

DM9000: running in 16 bit mode

MAC: 08:31:22:22:02:51

operating at 100M full duplex mode

Using dm9000 device

host 192.168.220.103 is alive

 

代表网络连接正确,为了验证TFTP是否可以使用,我们使用tftp更新u-boot.bin

首先在PC机上开启一个TFTP服务器,这里我们选取tftpd32.exe这款小软件作为TFTP服务器,首先双击打开此软件,显示以下界面,将要下载的文件u-boot.bin文件拷到与tftpd32.exe同一个目录下。

打开开发板终端:

#tftp 0x33000000 172.20.223.63:u-boot.bin

tftp:采用tftp协议 0x33000000:下载到内存的地址 172.20.223.63:服务器的地址,这里如果不填默认是:

#define CONFIG_SERVERIP  192.168.1.103      //unsp2440.h中此宏所定义的地址

 

终端中有如下显示:

dm9000 i/o: 0x18000300, id: 0x90000a46

DM9000: running in 16 bit mode

MAC: 08:31:22:22:02:51

operating at 100M full duplex mode

Using dm9000 device

TFTP from server 172.20.223.63; our IP address is 172.20.223.22

Filename 'u-boot.bin'.

Load address: 0x33000000

Loading: T ##########

done

Bytes transferred = 144644 (23504 hex)

 

表示下载成功。

二、 步骤六:U-boot支持TFTP下载启动linux内核、根文件系统

Linux内核的下载过程跟上节下载u-boot.bin基本一致,但是启动linux需要一些其他知识,下面我们来分析一下。

1) 首先是准备uzImage镜像

u-boot采用的linux镜像与我们使用make zImage编译出的镜像稍有不同,u-boot采用uzImage格式的镜像,uzImage是由zImage + 0x40字节的文件头组成。

经过编译后的u-boot在根目录下的tools目录中,会有个叫做mkimage的工具,他可以给zImage添加一个header,也就是说使得通常我们编译的内核zImage添加一个数据头信息部分。

使用: 中括号括起来的是可选的

mkimage [-x] -A arch -O os -T type -C comp -a addr -e ep -n name -d data_file[:data_file...] image

选项:

-A:set architecture to 'arch'        //用于指定CPU类型,比如ARM

-O:set operating system to 'os'     //用于指定操作系统,比如Linux

-T:set image type to 'type'           //用于指定image类型,比如Kernel

-C:set compression type 'comp'    //指定压缩类型

-a:set load address to 'addr' (hex) //指定image的载入地址

-e:set entry point to 'ep' (hex)     //内核的入口地址,一般为image的载入地址+0x40(信息头的大小)

-n:set image name to 'name'         //image在头结构中的命名

-d:use image data from 'datafile'   //无头信息的image文件名

-x:set XIP (execute in place)       //设置执行位置

 

先将u-boot下的tools中的mkimage复制到主机的/usr/local/bin目录下,这样就可以在主机的任何目录下使用该工具了。

现在我们进入kernel生成目录(一般是arch/arm/boot目录),然后执行如下命令,就会在该目录下生成 一个uImage.img的镜像文件,把他复制到tftp目录下,这就是我们所说的uImage

mkimage  -n 'linux-2.6.34'  -A arm  -O linux  -T kernel  -C none  -a 0x30008000  -e 0x30008000  -d zImage uImage.img

 

2) linux内核启动参数

前一节我们已经得到了u-boot所需要的linux镜像,下面我们设置linux启动所需要的参数,首先u-boot中机器号(match type)与内核必须统一,linux内核中的机器号为:

在kernel的arch/arm/tools/mach-types文件中针对不同的CPU定义了非常多的MACH_TYPE,我们找到379行左右:

     s3c2440 ARCH_S3C2440 S3C2440 362

同时arch/arm/mach-s3c2440/mach-smdk2440.c文件中smdk2440_machine_init函数

       MACHINE_START(S3C2440, "SMDK2440")    决定了当前内核的match type是362.

下面我们修改u-boot中的match-types与之匹配

在u-boot的include/asm-arm/mach-types.h文件中针对不同的CPU定义了非常多的MACH_TYPE,可以找到下面这个定义:

#define MACH_TYPE_S3C2440 362

 

我们增加以下定义:

#define MACH_TYPE_UNSP2440 362

 

修改 board/samsung/unsp2440/unsp2440.c文件中board_init函数

gd->bd->bi_arch_number = MACH_TYPE_SMDK2410;

为:

gd->bd->bi_arch_number = MACH_TYPE_UNSP2440;

 

重新编译,我们就能得到支持我们开发板内核的u-boot了。

3) 下载uzImage镜像:

下载linux内核到NAND FLASH中的具体地址,由内核中的FLASH分区表决定:

在arch/arm/plat-s3c24xx/common-smdk.c文件中可找到以下信息:

static struct mtd_partition smdk_default_nand_part[] =

{

       [0] =  {

                        .name = "bootloader",

                         .offset = 0, //boorloade分区起始地址

                         .size = 0x30000, //bootloader分区的大小

               },

              //bootloader分区与kernel分区之间0x30000---0x50000的地址用作存放linux参数分区

               //这个地址范围要与前面我们移植NAND驱动时定义的CONFIG_ENV_OFFSET保持统一

               [1] = {

                             .name = "kernel",

                             .offset = 0x50000, //kernel分区起始地址

                             .size = 0x300000, //kernel分区的大小

                          },

              [2] = {

                              .name = "root",

                              .offset = 0x350000, //root分区起始地址

                              .size = 0x3cac000, //root分区起始地址

                         },

};

 

下面我们使用命令行更新并下载内核:

#tftp 0x33000000 172.20.223.63:uImage.img

#nand erase 0x50000 0x300000                                //注意这两个数据的大小一定要跟上述表中的 kernel分区保持一致

#nand write 0x33000000 0x50000 0x300000         //将0x33000000中数据写入NAND FLASH中

启动内核:

#从ram中启动kernel

                #bootm 0x33000000

#从NAND FLASH中启动

                #nand read 0x33000000 0x50000 0x300000

                # bootm 0x33000000

#u-boot提供了另一个命令用来启动内核

          #nboot 0x33000000 0 0x50000        //nboot代表从nand中启动内核,0x33000000表示内核拷贝的地址,0 代表第一块FLASH,0x50000代表kernel镜像的起始位置,不用指定大小,这个命令会自动判断内核镜像的大小

           # bootm 0x33000000

 

如果没有问题的话,在终端中可以看到内核启动信息。

4)下载linux根文件系统

Linux根文件系统有各种各样的格式,有基于norFLASH的jffs2,基于NAND的cramfs与yaffs,基于网络的nfs等。

a) 这里首先我们先使用nfs根文件系统来启动我们的系统。

需要修改u-boot传递给linux 内核的启动参数,我们可以修改include/configs/unsp2440.h文件中的宏:

#define CONFIG_BOOTARGS "noinitrd root=/dev/nfs nfsroot=/home/dengwei/linux_system/root_src/rootfs_test/,rsize=1024,wsize=1024 ip=172.20.223.118:172.20.223.151:172.20.223.254:255.255.255.0::eth0:off init=/linuxrc console=ttySAC0"

 

或者直接在终端下通过命令行完成:

setenv bootargs noinitrd root=/dev/nfs nfsroot=/home/dengwei/linux_system/root_src/rootfs_test/,rsize=1024,wsize=1024 ip=172.20.223.118:172.20.223.151:172.20.223.254:255.255.255.0::eth0:off init=/linuxrc console=ttySAC0

 

b) 下面我们启动NAND FLASH中的根文件系统

NAND FLASH中常用两种格式的根文件系统:cramfs、yaffs

cramfs是压缩的只读根文件系统,u-boot直接支持

yaffs/yaffs2是未压缩的可读可写的文件系统,u-boot需要修改之后才能支持。

这里我们先烧写cramfs格式的根文件系统,下节再修改、移植支持yaffs格式根文件系统的u-boot。

cramfs格式的根文件系统制作请参考其它相关文章,假设我们现在已经有了此格式的根文件系统,并且名字为:rootfs.cramfs。

#tftp 0x33000000 172.20.223.63:rootfs.cramfs

#nand erase 0x350000 0x3cac000                                   //注意这两个数据的大小一定要跟上述表中的 root分区保持一致

#nand write 0x33000000 0x350000 0x3cac000            //将0x33000000中数据写入NAND FLASH中

启动内核,如果顺利的话可以观察到我们的根文件系统也顺利的启动起来了。

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/wwyspw.html