Linux内核到fl2440(s3c2440)移植(1)

/*2010.12.08--2010.12.24*/
/*kernel(linux-2.6.22.6)--到fl2440(s3c2440)移植(1)*/
/*操作系统: ubuntu-10.10*/
/*交叉编译工具: 编译uboot-1.1.4用cross-3.3.2.tar.bz2 ; 编译linux2.6.22.6用cross-3.4.1.tar.bz2*/

 

1.修改uboot1.1.4:
   (1) vi include/asm-arm/mach-types.h 添加:
#define MACH_TYPE_SMDK2440              362 /*和linux2.6.22.6中arch/arm/tools/mach-types中s3c2440序号对应*/

 

   (2) vi board/fl2440/fl2440.c
115行(gd->bd->bi_arch_number = MACH_TYPE_SMDK2410;)改为:
gd->bd->bi_arch_number = MACH_TYPE_SMDK2440;

 

   (3) vi include/configs/fl2440.c
添加:
#define CONFIG_SETUP_MEMORY_TAGS        1   /*允许向内核传递内存分布信息*/
#define CONFIG_CMDLINE_TAG      1   /*允许向内核传递命令行参数*/
#define CONFIG_BOOTCOMMAND "tftp 0x32000000 uImage;bootm 0x32000000"   /*通过TFTP下载主机上的uImage到开发板内存0x32000000,并启动内核*/
#define CONFIG_BOOTARGS         "noinitrd root=/dev/nfs nfsroot=192.168.0.22:/home/arm/rootfs ip=192.168.0.11:192.168.0.22:192.168.0.33:255.255.255.0::eth0:off init=/linuxrc console=ttySAC0,115200"  /*给内核的参数,参数意义可参考内核源码下的Documentation/nfsroot.txt*/

 

2.修改linux-2.6.22.6顶层Makefile:
   185行:ARCH            ?= $(SUBARCH) -> ARCH            ?= arm
   186行:CROSS_COMPILE   ?= -> CROSS_COMPILE   ?= arm-linux-

 

3.vi arch/arm/mach-s3c2440/mach-smdk2440.c
s3c24xx_init_clocks(16934400); -> s3c24xx_init_clocks(12000000); /*外部晶振12MHz*/

 

4.修改MTD分区:
vi arch/arm/plat-s3c24xx/common-smdk.c
修改smdk_default_nand_part函数为:
static struct mtd_partition smdk_default_nand_part[] = { [0] = { .name = "u-boot", .size = SZ_512K, .offset = 0, }, [1] = { .name = "kernel", .offset = MTDPART_OFS_APPEND, /*当前分区紧接上一分区*/ .size = SZ_2M, }, [2] = { .name = "yaffs", .offset = MTDPART_OFS_APPEND, .size = MTDPART_SIZ_FULL, /*当前分区大小为的FLASH空间*/ } };

5.添加yaffs文件系统支持:
tar zxvf yaffs_source.tar.gz   /*产生Development目录*/
cd Development/yaffs2/
./patch-ker.sh c ~/dev_home/kernel/linux-2.6.22.6/

配置内核(make menuconfig):
File systems-->Miscdllaneous filesystems--><*>YAFFS2 file system support
 

   到此内核已经可以跑了,只是因为缺少根文件系统所以最终会产生panic信息!


6.移植根文件系统:
   (1)建立根文件系统目录:
cd ~
mkdir rootfs
chmod 777 rootfs

 

   (2)修改NFS配置文件:
sudo vi /etc/exports
添加:/home/arm/rootfs *(rw,sync,no_root_squash,no_subtree_check)
重启NFS服务:
sudo /etc/init.d/nfs-kernel-server restart

 

   (3)用busybox建立根文件系统:
      <1>tar jxvf busybox-1.7.0.tar.bz2
cd busybox-1.7.0/


      <2>修改顶层Makefile:
vi Makefile
ARCH            ?= $(SUBARCH) -> ARCH            ?= arm
CROSS_COMPILE   ?= -> CROSS_COMPILE   ?= arm-linux- /*3.4.1*/

 

      <3>配置busybox:
make menuconfig
[1]                              Miscellaneous Utilities  --->

                 [] taskset要去掉

       如果不去掉,出错信息:
miscutils/taskset.c:17: error: parse error before ''*'' token
miscutils/taskset.c:18: warning: function declaration isn''t a prototype
miscutils/taskset.c: In function `__from_cpuset'':
miscutils/taskset.c:22: error: `CPU_SETSIZE'' undeclared (first use in this function)
miscutils/taskset.c:22: error: (Each undeclared identifier is reported only once
miscutils/taskset.c:22: error: for each function it appears in.)
miscutils/taskset.c:26: warning: implicit declaration of function `CPU_ISSET''
miscutils/taskset.c:26: error: `mask'' undeclared (first use in this function)
miscutils/taskset.c: In function `taskset_main'':
miscutils/taskset.c:47: error: `cpu_set_t'' undeclared (first use in this function)
miscutils/taskset.c:47: error: parse error before "mask"
miscutils/taskset.c:68: warning: implicit declaration of function `CPU_ZERO''
miscutils/taskset.c:68: error: `new_mask'' undeclared (first use in this function)
miscutils/taskset.c:69: error: `CPU_SETSIZE'' undeclared (first use in this function)
miscutils/taskset.c:71: warning: implicit declaration of function `CPU_SET''
miscutils/taskset.c:78: error: `mask'' undeclared (first use in this function)

 

[2]                              Linux Module Utilities  --->

          []Support version 2.2.x to 2.4.x Linux kernels 要去掉

如果不去掉的话,出错信息:
modutils/lib.a(insmod.o)(.text.insmod_main+0x360): In function `insmod_main'':
: undefined reference to `query_module''
modutils/lib.a(insmod.o)(.text.insmod_main+0x394): In function `insmod_main'':
: undefined reference to `query_module''
modutils/lib.a(insmod.o)(.text.insmod_main+0x440): In function `insmod_main'':
: undefined reference to `query_module''
modutils/lib.a(insmod.o)(.text.insmod_main+0x494): In function `insmod_main'':
: undefined reference to `query_module''
modutils/lib.a(insmod.o)(.text.insmod_main+0x570): In function `insmod_main'':
: undefined reference to `query_module''
modutils/lib.a(insmod.o)(.text.insmod_main+0xc10): In function `insmod_main'':
: undefined reference to `create_module''
collect2: ld returned 1 exit status
其他的配就可以了,这两个地方要是不去掉的话,编译不过。

 

      <4>make   /*编译*/

 

      <5>make CONFIG_PREFIX=/home/arm/rootfs/ install /*安装*/

 

      <6>安装glibc库:
cd /home/arm/rootfs/
mkdir lib
cp /usr/local/arm/3.4.1/arm-linux/lib/*.so*  /home/arm/rootfs/lib/ -d

 

   (4)构件etc目录:
mkdir etc
      <1>vi etc/inittab
添加如下内容:
#/etc/inittab
::sysinit:/etc/init.d/rcS
ttySAC0::askfirst:-/bin/sh
::ctrlaltdel:/sbin/reboot
::shutdown:/bin/umount -a -r

 

      <2>mkdir etc/init.d
vi etc/init.d/rcS
chmod +x etc/init.d/rcS
添加如下内容:
#!/bin/sh
ifconfig        eth0    192.168.0.11
mount   -a

 

      <3>vi etc/fstab
添加如下内容:
#device mount-point     type    options         dump    fsck    order
proc    /proc           proc    defaults        0       0
tmpfs   /tmp            tmpfs   defaults        0       0


   (5)静态构建设备文件(推荐使用下面的动态构建设备文件):
mkdir dev
cd dev/

sudo mknod console c 5 1
sudo mknod null c 1 3
sudo mknod ttySAC0 c 204 64
sudo mknod mtdblock0 b 31 0
sudo mknod mtdblock1 b 31 1
sudo mknod mtdblock2 b 31 2

 

   (6)动态构建设备文件:
mkdir dev

vi etc/fstab
添加:
sysfs   /sys            sysfs   defaults        0       0
tmpfs   /dev            tmpfs   defaults        0       0

 

vi etc/init.d/rcS
添加:
mount   -a
mkdir /dev/pts
mount -t devpts devpts /dev/pts
echo /sbin/mdev > /proc/sys/kernel/hotplug
mdev -s

 

vi etc/inittab
修改:
ttySAC0::askfirst:-/bin/sh -> s3c2410_serial0::askfirst:-/bin/sh

 

cd dev/

sudo mknod console c 5 1
sudo mknod null c 1 3

 

创建其它目录:
mkdir proc tmp mnt sys root

 

   (7)将该根文件系统烧到开发板NAND FLASH里:
      <1>cd /home/arm/rootfs
tar cvf ~/Desktop/rootfs.tar ./        /*压缩文件系统*/
这样在桌面上就会生成一个rootfs.rar的文件系统压缩包
cp ~/Desktop/rootfs.tar /home/arm/rootfs/root/
      
      <2>设置uboot从NFS挂载根文件系统:
setenv bootargs noinitrd root=/dev/nfs nfsroot=192.168.0.22:/home/arm/rootfs ip=192.168.0.11:192.168.0.22:192.168.0.33:255.255.255.0::eth0:off init=/linuxrc console=ttySAC0,115200

 

      <3>进入系统后(nfs方式)对ARM开发板进行操作:
mount -t yaffs /dev/mtdblock2(或者其它分区) /mnt
cd /root
tar xvf rootfs.rar -C /mnt /*这一步就是将根文件系统解压到我们的nandflash中了,也就是达到了“烧写”的效果*/
cd /mnt
ls /mnt /*如果这一步能够看到etc mnt dev等目录就可以了*/
如果你看到的只有一个rootfs目录,那就得执行:
mv rootfs/* ./
rmdir rootfs

 

      <4>重新启动系统,设置u-boot参数
进入u-boot命令等待状态,执行:
setenv bootargs noinitrd root=/dev/mtdblock2 rootfstype=yaffs console=ttySAC0 init=/linuxrc

saveenv
reset
之后就可以看到u-boot自动加载NAND FLASH里的根文件系统.

 

貌似这样加载的根文件系统第一次启动不能保存建立的文件,第二次开始就能正常保存了.

 

问题:
mount: mounting tmpfs on /tmp failed: Invalid argument
解决办法:添加tmpfs文件系统支持:
配置内核(make menuconfig):
File systems--->
   Pseudo filesystems--->
      [*]Virtual memory file system support(former shm fs)    

 

7.DM9000网卡驱动移植:
(1)增加DM9000平台设备:
vi arch/arm/plat-s3c24xx/common-smdk.c
   <1>46行左右添加头文件:
#if defined(CONFIG_DM9000) || defined(CONFIG_DM9000_MODULE) #include <linux/dm9000.h> #endif

   <2>添加DM9000的平台设备结构,增加以下代码:
#if defined(CONFIG_DM9000) || defined(CONFIG_DM9000_MODULE) /* DM9000 */ static struct resource s3c_dm9k_resource[] = { [0] = { .start = S3C2410_CS4, .end = S3C2410_CS4 + 3, .flags = IORESOURCE_MEM, }, [1] = { .start = S3C2410_CS4 + 4, .end = S3C2410_CS4 + 4 + 3, .flags = IORESOURCE_MEM, }, [2] = { .start = IRQ_EINT7, /* 中断号*/ .end = IRQ_EINT7, .flags = IORESOURCE_IRQ, } }; /* for the moment we limit ourselves to 16bit IO until some * better IO routines can be written and tested */ static struct dm9000_plat_data s3c_dm9k_platdata = { .flags = DM9000_PLATF_16BITONLY, }; static struct platform_device s3c_device_dm9k = { .name = "dm9000", .id = 0, .num_resources = ARRAY_SIZE(s3c_dm9k_resource), .resource = s3c_dm9k_resource, .dev = { .platform_data = &s3c_dm9k_platdata, } }; #endif /* CONFIG_DM9000 */

   <3>加入内核设备列表(把平台设备s3c_device_dm9k加入smdk_devs数组中):
增加以下代码(被宏CONFIG_ARCH_S3C2410包起来的为添加的代码):
static struct platform_device __initdata *smdk_devs[] = {
.
.
.

        #if defined(CONFIG_DM9000) || defined(CONFIG_DM9000_MODULE)
        &s3c_device_dm9k,
        #endif
.
.
.
};

 

(2)修改驱动源码:
vi drivers/net/dm9000.c
   <1>73行左右添加头文件:

#if defined(CONFIG_ARCH_S3C2410)
#include <asm/arch-s3c2410/regs-mem.h>
#endif

 

   <2>修改函数dm9000_probe(被宏CONFIG_ARCH_S3C2410包起来的为添加的代码):
static int
dm9000_probe(struct platform_device *pdev)
{
#if defined(CONFIG_ARCH_S3C2410)
        unsigned int oldval_bwscon;
        unsigned int oldval_bankcon4;
#endif

     struct dm9000_plat_data *pdata = pdev->dev.platform_data;
.
.
.

 PRINTK2("dm9000_probe()");

#if defined(CONFIG_ARCH_S3C2410)
 /*设置Bank4:总线宽度为16,使能nWait*/
        oldval_bwscon=*((volatile unsigned int *)S3C2410_BWSCON);
        *((volatile unsigned int *)S3C2410_BWSCON) = (oldval_bwscon & ~(3<<16)) | S3C2410_BWSCON_DW4_16 | S3C2410_BWSCON_WS4

| S3C2410_BWSCON_ST4;
 /*设置Bank3的时间参数*/
        oldval_bankcon4= *((volatile unsigned int *)S3C2410_BANKCON4);
        *((volatile unsigned int *)S3C2410_BANKCON4) = 0x1f7c;
#endif
.
.
.

if (!is_valid_ether_addr(ndev->dev_addr)){
                printk("%s: Invalid ethernet MAC address.  Please "
                       "set using ifconfig/n", ndev->name);

#if defined(CONFIG_ARCH_S3C2410)
        printk("Now use the defanult MAC address: 08:90:90:90:90:90/n");
        ndev->dev_addr[0] = 0x08;
        ndev->dev_addr[1] = 0x90;
        ndev->dev_addr[2] = 0x90;
        ndev->dev_addr[3] = 0x90;
        ndev->dev_addr[4] = 0x90;
        ndev->dev_addr[5] = 0x90;
#endif
}
.
.
.
out:
        printk("%s: not found (%d)./n", CARDNAME, ret);

#if defined(CONFIG_ARCH_S3C2410)
 /*恢复寄存器原来的值*/
        *((volatile unsigned int *)S3C2410_BWSCON) = oldval_bwscon;
        *((volatile unsigned int *)S3C2410_BANKCON4) = oldval_bankcon4;
#endif

 

   <3>注册中断时,指定触发方式
修改函数dm9000_open:
if (request_irq(dev->irq, &dm9000_interrupt, IRQF_SHARED, dev->name, dev))这句改为:
#if defined(CONFIG_ARCH_S3C2410)
        if (request_irq(dev->irq, &dm9000_interrupt, IRQF_SHARED|IRQF_TRIGGER_RISING, dev->name, dev))
#else
        if (request_irq(dev->irq, &dm9000_interrupt, IRQF_SHARED, dev->name, dev))
#endif

 

(3)配置内核(make menuconfig):
Device Drivers--->
   Network device support--->
      [*]Network device support
         Ethernet(10 or 100Mbit)--->
            <*>DM9000 support


增加对NFS支持:
File systems-->
   Network File Systems--->
      <*>NFS file system support
      [*]   Provide NFSv3 client support
      [*]      Provide client support for the NFSv3 ACL protocol extension
      [*]   Provide NFSv4 client support(EXPERIMENTAL)
      [*]   Root file system on NFS

 

注意:
1.如果内核中同时加载了CS8900A和DM9000,分别使用eth0,eth1表示它们.如果它们都是编进内核的,则eth0表示CS8900A,eth1表示DM9000.如果

作为模块加载,则根据它们的加载顺序先后使用eth0,eth1来表示.
2.如果要同时使用CS8900A和DM9000,它们的IP地址不能在同一个网段.

 

你可能感兴趣的:(c,function,struct,Module,reference,linux内核)