移植、裁减及配置Linux内核到s3c2440开发板

来源:互联网 发布:mac apache php 403 编辑:程序博客网 时间:2024/04/30 23:59

一、准备工作(使用tar xjvf命令解压linux-2.6.22.6.tar.bz2后,cd /work/system/linux-2.6.22.6)

1、修改顶层Makefile的185和186行,以指定特定CPU体系结构和交叉编译工具。

185 ARCH            ?= arm
186 CROSS_COMPILE   ?= arm-linux-

2、内核配置选项有几百个,配置者不可能一一配置,因此先输入make s3c2410_defconfig,以使用标准模板的配置

dennis@dennis-desktop:/work/system/linux-2.6.22.6$ make s3c2410_defconfig

3、使用make menuconfig进入图形配置界面,浏览基本配置

image

单击System Type ---- S3C2440 Machines

image

SMDK2440和SMDK2440 with S3C2440 CPU module已被选择(方括弧内有*号),表明编译出来的内核将支持由S3C2440组成的开发板

4、保存退出后,输入make zImage,大约半小时后将在arch/arm/boot目录生成内核文件zImage

5、将制作uImage的程序mkimage(位于编译后的u-boot源代码目录的tools子目录中)拷贝到/usr/bin目录

sudo     cp     /work/system/u-boot-1.1.6/tools/mkimage     /usr/bin/

6、输入make uImage后,内核构造系统将调用mkimage,通过zImage生成uImage(位于arch/arm/boot目录)。uImage是可供u-boot引导的linux内核,它在zImage前增加了64byte的头(这64byte的头有什么作用、里面包含什么内容,请参见“深入剖析u-boot”一文)

dennis@dennis-desktop:/work/system/linux-2.6.22.6$ ls -l arch/arm/boot/[uz]Image
-rw-r--r-- 1 dennis dennis 1511140 2010-04-01 10:43 arch/arm/boot/uImage
-rwxr-xr-x 1 dennis dennis 1511076 2010-04-01 10:41 arch/arm/boot/zImage

7、将uImage烧写到开发板的nand flash上

1)、使用网线将开发板与Linux机器物理连通

2)、配置Linux机器的ip地址为192.168.2.11

3)、配置开发板的ip地址为192.168.2.17

Dennis Yang > setenv ipaddr 192.168.2.17
Dennis Yang > saveenv
Saving Environment to NAND...
Erasing Nand...Writing to Nand... done

4)、确认开发板能与Linux机器通信

Dennis Yang > ping 192.168.2.11
host 192.168.2.11 is alive

5)、配置Linux机器上NFS服务器的配置文件/etc/exports,使NFS服务器共享/work/system/linux-2.6.22.6目录

/work/system/linux-2.6.22.6          *(rw,sync,no_root_squash)

后,重启NFS服务

sudo    /etc/init.d/nfs-kernel-server     restart

6)、将uImage下载到开发板RAM地址0x32000000处

Dennis Yang > nfs 0x32000000 192.168.2.11:/work/system/linux-2.6.22.6/arch/arm/boot/uImage

7)格式化nand flash某区段(起始地址为0x80000,长度为0x180000字节),并将位于RAM地址0x32000000的uImage烧写到该区段

Dennis Yang > nand erase 0x80000 0x180000

Dennis Yang > nand write.jffs2 0x32000000 0x80000 0x180000

8)、启动Linux。可以看到内核正确并被启动,但旋即输出乱码。这说明需要对Linux进行移植(修改源代码)

Dennis Yang > boot

NAND read: device 0 offset 0x80000, size 0x180000

Reading data from 0x1ffe00 -- 100% complete.
1572864 bytes read: OK
## Booting image at 32000000 ...
   Image Name:   Linux-2.6.22.6
   Created:      2010-04-01   2:43:59 UTC
   Image Type:   ARM Linux Kernel Image (uncompressed)
   Data Size:    1511076 Bytes =  1.4 MB
   Load Address: 30008000
   Entry Point:  30008000
   Verifying Checksum ... OK
OK

Starting kernel ...

Uncompressing Linux................................................................................................... done, booting the kernel.
鯸竾"骾7记浄77 悄3:癖;?虡?蘬儳{€$剜#"8€4梧f凣郻凣?f癎C?吾G4鞇`[

二、为S3C2440移植内核

1、修改晶振频率

S3C2440支持2种晶振频率:12MHZ和16MHZ。qq2440v3开发板使用的是12M的晶振,而内核源代码则采用的是16M频率,从而产生了错误的PCLK,因此导致内核向串口输出数据时使用了错误的波特率(正确的应是115200),这样在超级终端中看到的就是乱码。因此我们只需修改内核源代码中的晶振频率即可。

将arch/arm/mach-s3c2440/mach-smdk2440.c的第180行

s3c24xx_init_clocks(16934400);

改为:

s3c24xx_init_clocks(12000000);

2、修改nand flash分区表

这次内核正常启动,不再出现乱码,但未能成功挂载根文件系统。出现错误如下:

VFS: Mounted root (jffs2 filesystem).
Freeing init memory: 132K
Warning: unable to open an initial console.
Kernel panic - not syncing: No init found.  Try passing init= option to kernel.

仔细查看内核出错前的输出,发现内核在nand flash上创建了8个分区:

Creating 8 MTD partitions on "NAND 64MiB 3,3V 8-bit":
0x00000000-0x00004000 : "Boot Agent"
0x00000000-0x00200000 : "S3C2410 flash partition 1"
0x00400000-0x00800000 : "S3C2410 flash partition 2"
0x00800000-0x00a00000 : "S3C2410 flash partition 3"
0x00a00000-0x00e00000 : "S3C2410 flash partition 4"
0x00e00000-0x01800000 : "S3C2410 flash partition 5"
0x01800000-0x03000000 : "S3C2410 flash partition 6"
0x03000000-0x04000000 : "S3C2410 flash partition 7"

而内核从u-boot获得的启动参数(root=/dev/mtdblock2)表明,根文件系统放在nand flash的第3个分区上。

Kernel command line: noinitrd root=/dev/mtdblock2 console=ttySAC0 rootfstype=jffs2

这样一来,内核会到nand flash的0x00400000-0x00800000区间来挂载根文件系统,但事实上我们通过u-boot烧写根文件系统时,是将其烧写在nand flash的0x1200000-0x2200000这个区间的。所以内核不能成功挂载根文件系统。因此,我们必须修改内核对nand flash的分区定义,让第3个分区位于0x1200000-0x2200000这个区间。

修改arch/arm/plat-s3c24xx/common-smdk.c文件,将109-150行改为:

static struct mtd_partition smdk_default_nand_part[] = {
        [0] = {
                .name   = "Kernel",
                .size   = SZ_2M,
                .offset = 0,
        },
        [1] = {
                .name   = "YaffsRoot",
                .offset = MTDPART_OFS_APPEND,
                .size   = SZ_16M,
        },
        [2] = {
                .name   = "Jffs2Root",
                .offset = MTDPART_OFS_APPEND,
                .size   = SZ_16M,
        },
        [3] = {
                .name   = "FreePartition",
                .offset = MTDPART_OFS_APPEND,
                .size   = MTDPART_SIZ_FULL,
        }
};

三、配置并裁减内核

现在内核虽然可以正常工作,但作为嵌入式操作系统的Linux,是可以被裁减以适应我们的具体需要。下面我们就通过 make menuconfig 对内核进行配置和裁减,使得最终的内核尽量小,并实现支持:

1、nand flash驱动;2、jffs2文件系统 ;3、ELF格式的应用程序;4、串口驱动;5、ram disk(将内存当硬盘使用);6、ext2文件系统;7、环回设备(将物理文件

当硬盘使用、类似windows下的虚拟光驱);8、将目录挂载到内存(将内存当目录使用);9、能识别U盘FAT分区和NTFS分区上的中英文文件;10、更新和获取实时时钟;

11、watchdog驱动;12、I2C驱动;13、SPI驱动;14、framebuffer;

15、TCP/IP协议栈;16、开发板充当NFS客户端;17、将NFS服务器上的共享目录挂载为根文件系统;18、动态加载和卸载模块;19、开发板充当PC机的U盘;20、USB网卡DM9601

不支持:1、网卡驱动;2、声卡驱动

image

Code maturity level options选中则使未定型的功能组件出现在配置选项中,这样就可以显示更多的配置选项General setup杂项设置Block layer块设备层:用于设置块设备的一些总体参数,比如是否支持大于2TB的块设备、是否支持大于2TB的文件、设置I/O调度器等。一般使用默认值即可System Type系统类型:选择CPU架构、开发板类型等开发板相关的配置选项Bus supportPCMCIA/CardBus总线的支持,不用设置Kernel Features用于设置内核的一些参数,比如是否支持内核抢占,是否支持动态修改系统时钟等Boot options启动参数:比如设置默认的命令行参数等,一般不用理会Floating point emuulation浮点运算仿真功能,目前linux还不支持硬件浮点运算,所以要选择一个浮点仿真器,一般选择“NWFPE math emulation”Userspace binary formats可执行文件格式,一般选择ELFPower management options电源管理选项Neteworking网络协议选项:一般都选择“Networking support”以支持网络功能,选择“Packet socket”,以支持raw socket接口功能,选择“TCP/IP networking”以支持TCP/IP网络协议。通常在选择“Networking support”后使用默认配置Device Drivers设备驱动程序:几乎包含Linux的所有驱动程序File systems文件系统profiling support对系统的活动进行分析,仅供内核开发者使用Kernel hacking调试内核时的各种选项Security options安全选项,一般使用默认选项Cryptographic options加密选项Library routines库子程序:比如CRC32检验函数、zlib压缩函数等。不包含在内核源码中的第三方内核模块可能需要这些库,可以全不选,若内核中其它部分依赖它,会自动选上

 

在配置界面上对Linux进行配置时,对于[ ]选项可以按下“Y”键表示要编译进内核(即:该功能组件的二进制代码会进入最终的内核映像文件zImage中),“N”键表示不编译;对于< >选项,除了“Y”和“N”外,还可以按“M”键表示编译为模块(即:该功能组件的二进制代码并不进入zImage,但会单独形成一个后缀名为ko的文件。该ko文件就被称为模块,模块可以在操作系统启动后通过“insmod 模块文件名”将其加载进内核),以减小内核的大小。

执行以下配置:

1、选中Code maturity level options -- Prompt for development and/or incomplete code/drivers以便显示更多的配置选项
2、保持General setup的默认选择
3、保持Loadable module support的默认选择,以支持动态加载和卸载模块
4、保持Block layer的默认选择
5、System Type默认配置下,保留S3C2440 Machines 下的SMDK2440和SMDK2440 with S3C2440 CPU module,把其它类型的Machines全部去掉
6、保持Bus support的默认选择
7、保持Kernel Features的默认选择,不要选择Preemptible Kernel (EXPERIMENTAL)和Use the ARM EABI to compile the kernel
8、保持Boot options的默认选择
9、保持Floating point emulation的默认选择
10、去掉Userspace binary formats 下的“Kernel support for a.out and ECOFF binaries”,只保留“Kernel support for ELF binaries”
11、保持Power management options的默认选择
12、去掉Networking  --  Networking options下的“IP: IPsec transport mode”、“IP: IPsec tunnel mode”、“IP: IPsec BEET mode”
13、Device Drivers
1)、Memory Technology Device (MTD) support
    a)、去掉RedBoot partition table parsing
    b)、去掉RAM/ROM/Flash chip drivers的全部选项
    c)、保持NAND Device Support -- NAND Flash support for S3C2410/S3C2440 SoC,以支持nand flash驱动
2)、去掉Parallel port support的全部选项
3)、Block devices
    a)、保留Loopback device support以支持环回设备
    b)、保留RAM disk support以支持ram disk
4)、去掉对ATA/ATAPI/MFM/RLL support的支持
5)、选中SCSI device support -- SCSI device support -- SCSI disk support,以支持U盘(U盘在Linux中被识别为SCSI硬盘)
6)、Network device support
    a)、去掉Ethernet (10 or 100Mbit) -- DM9000 support,因为开发板上的网卡不是DM9000,而是CS8900
    b)、去掉Ethernet (1000 Mbit) 和 Ethernet (10000 Mbit)
    c)、USB Network Adapters下,选中Multi-purpose USB Networking Framework Davicom和DM9601 based USB 1.1 10/100 ethernet devices以支持USB网卡DM9601;去掉其它选项
7)、Input device support
    a)、去掉对Keyboards的支持
    b)、去掉对Mice的支持
8)、Character devices去掉Non-standard serial port support和Legacy (BSD) PTY support。仅保留Watchdog Timer Support -- S3C2410 Watchdog,以支持看门狗驱动;保留Serial drivers默认配置,以支持串口。
9)、I2C support保持默认配置,以支持I2C驱动
10)、SPI support选中Samsung S3C24XX series SPI和Bitbanging SPI master,以支持SPI驱动
11)、去掉Hardware Monitoring support
12)、LED devices去掉LED Support
13)、Multimedia devices去掉DAB adapters
14)、Graphics support保持默认设置,以支持frame buffer以及LCD(需修改LCD驱动源代码)
15)、HID Devices清除所有选项,这将导致不支持usb鼠标、键盘等
16)、USB support
    a)、选中USB Mass Storage support,以支持U盘
    b)、USB Gadget Support,选中Support for USB Gadgets,选择将USB Gadget Drivers -- File-backed Storage Gadget编译为模块。以支持将开发板充当PC机的U盘。(需修改udc驱动源代码)
17)、Real Time Clock保持默认设置,以支持更新和获取实时时钟(需修改RTC驱动源代码)

修改arch/arm/mach-s3c2440/mach-smdk2440.c,在其第175行处增加一行:

&s3c_device_rtc,


13、File systems
1)、保留Second extended fs support以支持ext2文件系统。去掉Ext3 journalling file system support、ROM file system support
2)、在DOS/FAT/NT Filesystems下选中除NTFS debugging support之外的全部选项,以支持FAT文件系统和NTFS文件系统;
3)、选中Pseudo filesystems -- Virtual memory file system support (former shm fs)。以支持将目录挂载到内存。
4)、Miscellaneous filesystems
    a)、保持Journalling Flash File System v2 (JFFS2) support。以支持jffs2文件系统
    b)、去掉Compressed ROM file system support (cramfs)
5)、Network File Systems
    a)、选中Provide NFSv3 client support。以支持开发板充当NFS客户端。
    b)、保持Root file system on NFS。以支持将NFS服务器上的共享目录挂载为根文件系统。
6)、Partition Types,去掉全部选项
7)、Native Language Support
    a)、选中Codepage 437 (United States, Canada)。以支持英文文件
    b)、Simplified Chinese charset (CP936, GB2312)。以支持中文文件
14、Kernel hacking,清除全部选项

四、验证内核功能

1、nand flash驱动

2、jffs2文件系统

由于根文件系统是jffs2文件系统并位于nand flash上,现在能正确加载根文件系统,说明内核已经支持这2个功能

3、ELF格式的应用程序

ls命令就是ELF格式的应用程序,现在能执行ls这样的命令,说明内核已经支持这个功能

4、串口驱动

已能通过超级终端接收和输入数据,说明内核已经支持这个功能

5、ram disk

6、ext2文件系统

mke2fs    /dev/ram3

mount  –t  ext2   /dev/ram3    /mnt

touch    /mnt/yangzhu

ls   /mnt 显示存在yangzhu这个文件

reboot后,重新执行

mount  –t  ext2   /dev/ram3    /mnt

显示错误。说明内核已经支持这2个功能。

7、环回设备

dd    if=/dev/zero    of=/test.img    bs=512    count=8190

losetup    /dev/loop0    /test.img

mke2fs    /dev/loop0

mount     -t    ext2    /dev/loop0    /mnt

touch    /mnt/yangzhu

ls    /mnt   可以看到存在文件yangzhu

umount    /dev/loop0

reboot后执行:

losetup    /dev/loop0    /test.img

mount     -t    ext2    /dev/loop0    /mnt

ls    /mnt   可以看到文件yangzhu仍然存在。说明内核已经支持这个功能。

8、将目录挂载到内存

mount    -t    tmpfs    none    /mnt

touch    /mnt/yangzhu

ls    /mnt 显示存在文件yangzhu

reboot后重新执行

mount    -t    tmpfs    none    /mnt

ls    /mnt 显示文件yangzhu不存在。说明内核已经支持这个功能。

9、能识别U盘FAT分区和NTFS分区上的中英文文件

插入格式化为FAT文件系统的U盘后,执行

mount    /dev/sda1    /mnt  (或者需要输入的是 mount    /dev/sda    /mnt)

ls    /mnt

可看到U盘上的中英文文件。

插入为格式化为NTFS文件系统的U盘后,执行

mount    -t    ntfs    -o    ro,nls=cp936    /dev/sda1    /mnt

ls    /mnt

可看到U盘上的中英文文件。

说明内核已经支持这个功能。

注:之所以要加入-o    ro这个选项,是因为目前linux对于NTFS分区的写入操作的支持很有限,并且不太完善。

10、更新和获取实时时钟

date -s 040210102010 #设置时间为 2010-04-02 10:10

hwclock -w #把刚刚设置的时间存入S3C2440 内部的RTC

reboot后使用date显示当前时间,变为了2010-04-02 10:11:02。说明内核已经支持这个功能。

11、watchdog驱动

# watchdog -t 1 /dev/watchdog
# killall watchdog
s3c2410-wdt: Unexpected close, not stopping watchdog!
#

U-Boot 1.1.6 (Sep  8 2009 - 11:22:15)

DRAM:  64 MB
Flash:  1 MB
NAND:

在开启watchdog功能后停止喂狗,结果系统重新启动。这说明内核已经支持这个功能。

注:暂不验证 12、I2C驱动;13、SPI驱动;14、framebuffer;剩余功能在下文中验证。

0 0