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

一、准备工作(使用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 support PCMCIA/CardBus总线的支持,不用设置
Kernel Features 用于设置内核的一些参数,比如是否支持内核抢占,是否支持动态修改系统时钟等
Boot options 启动参数:比如设置默认的命令行参数等,一般不用理会
Floating point emuulation 浮点运算仿真功能,目前linux还不支持硬件浮点运算,所以要选择一个浮点仿真器,一般选择“NWFPE math emulation”
Userspace binary formats 可执行文件格式,一般选择ELF
Power 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移植, s3c2440开发板, linux

添加新评论