/*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地址不能在同一个网段.