嵌入式ARM移植之三:移植 linux-2.6.26 内核

嵌入式ARM移植之三:移植 linux-2.6.26 内核

[b][color=#295200]嵌入式ARM移植之三:移植 linux-2.6.26 内核[/color][/b]
宿主机:
Kubuntu 8.04 (linux-2.6.24-19)
gcc-4.2.3
目标机:
s3c2440
交叉编译器(crosstool-0.43制作)
arm-linux-gcc-4.1.0
要移植的内核版本:
linux-2.6.26
文件系统:
cramfs
---------------------------------------------------------------------------------------------------
准备知识:
Linux
支持多种平台架构。在其源码的arch目录下,已经将各种支持的平台架构的源码分门别类。为了配置方便,在各种平台架构的目录下,一般都配有一个名为configs的目录。其中,放置着许多已经初步配置好的defconfig文件。通过这些defconfig文件,加快了我们配置内核的速度。
比如我所用的是一个arm架构的s3c2440板,那我就可以从arch/arm/configs/中找到s3c2410_defconfig,这是目前最匹配2440的一个默认配置文件了。使用:
$ make s3c2410_defconfig

$ cp arch/arm/configs/s3c2410_defconfig ./.config
执行上述命令后,将会在源码目录下生成相应的.config配置文件。通过
$ make menuconfig

$ make xconfig
可以进一步配置内核。最后执行
$ make zImage
生成我们所需的烧录文件
内核编译基本命令:
make mrproper ---
清理全部文件,包括.config和一些备份文件
make clean ---
清理生成文件,但会保留.config和一些模块文件。
make defconfig ---
生成包含全部默认选项的.config文件。这里用make s3c2410_defconfig替代
make oldconfig ---
在旧的.config基础上生成新的.config。如果只想在原来内核配置的基础上修改一些小地方,会省去不少麻烦
make config ---
基于文本的最为传统的配置界面,不推荐使用
make menuconfig ---
基于文本选单的配置界面,字符终端下推荐使用
make xconfig ---
基于图形窗口模式的配置界面,Xwindow下推荐使用
   
目的都是生成一个.config文件,这三个命令中,make xconfig的界面最为友好,如果你可以使用Xwindow,你就用这个好了,这个比较方便,也好设置。如果你不能使用Xwindow,那么就使用 make menuconfig好了。界面虽然比上面一个差点,总比make config的要好多了。
make ---
默认编译。
make bzImage ---
编译生成压缩的内核二进制文件,也会用make zImage替代
---------------------------------------------------------------------------------------------------
参考资料:

[url=http://www.edacn.net/html/84/83584-31369.html][color=#0000ff]Linux2.6.22.2
内核移植方法[/color][/url]


[url=http://blog.csdn.net/yang_dk/archive/2008/04/17/2300712.aspx][color=#800080]
移植内核2.6.24.4S3C2440[/color][/url]


[url=http://blog.csdn.net/hongjiujing/archive/2007/10/11/1820601.aspx][color=#0000ff]
对于Kernel panic - ……出错的一点总结![/color][/url]

---------------------------------------------------------------------------------------------------
移植linux-2.6.26内核(假设已下载linux-2.6.26.tar.bz2)
1.
解压源代码
$ tar jxvf linux-2.6.26.tar.bz2
$ cd linux-2.6.26
2.
更改Makefile
#ARCH        ?= $(SUBARCH)
#CROSS_COMPILE    ?=
ARCH        ?= arm
CROSS_COMPILE    ?= $HOME/toolchain/crosstool/gcc-4.1.0-glibc-2.3.2/arm-linux-gnu/bin/arm-linux-gnu-
3.
生成默认配置
$ make s3c2410_defconfig
4.
增加devfs文件系统支持
linux2.6.26
已经去掉devfs,为了内核支持devfs以及在启动时并在/sbin/init运行之前能自动挂载/devdevfs文件系统,修改fsKconfig文件。
linux-2.6.26/fs/Kconfig
修改的内容:
找到menu "Pseudo filesystems"
添加如下语句:
config DEVFS_FS
    bool "/dev file system support (OBSOLETE)"
    depends on EXPERIMENTAL
    help
      This is support for devfs, a virtual file system (like /proc) which
      provides the file system interface to device drivers, normally found
      in /dev. Devfs does not depend on major and minor number
      allocations. Device drivers register entries in /dev which then
      appear automatically, which means that the system administrator does
      not have to create character and block special device files in the
      /dev directory using the mknod command (or MAKEDEV script) anymore.
      This is work in progress. If you want to use this, you *must* read
      the material in , especially
      the file README there.
      Note that devfs no longer manages /dev/pts! If you are using UNIX98
      ptys, you will also need to mount the /dev/pts filesystem (devpts).
      Note that devfs has been obsoleted by udev,
      .
      It has been stripped down to a bare minimum and is only provided for
      legacy installations that use its naming scheme which is
      unfortunately different from the names normal Linux installations
      use.
      If unsure, say N.
config DEVFS_MOUNT
    bool "Automatically mount at boot"
    depends on DEVFS_FS
    help
      This option appears if you have CONFIG_DEVFS_FS enabled. Setting
      this to 'Y' will make the kernel automatically mount devfs onto /dev
      when the system is booted, before the init thread is started.
      You can override this with the "devfs=nomount" boot option.
      If unsure, say N.
config DEVFS_DEBUG
    bool "Debug devfs"
    depends on DEVFS_FS
    help
      If you say Y here, then the /dev file system code will generate
      debugging messages. See the file
      for more details.
      If unsure, say N.
5.
修改晶振( 可解决打印信息乱码问题 )
文件:arch/arm/mach-s3c2440/mach-smdk2440.c
    /*s3c24xx_init_clocks(16934400);*/
    s3c24xx_init_clocks(12000000);
6.
修改MTD分区
文件: arch/arm/plat-s3c24xx/common-smdk.c
/* fix mtd partition to be same with bootloader */
/* a flash all in 64M bit size have been devided into 4 partition: */
/*   1. boot : offset is 0 and size is 192k */
/*   2. kernel : offset is 0x30000 and size is 1856k */
/*   3. rootfs : offset is 0x200000 and size is 30M */
/*   4. ext-fs1 : offset is 0x2000000 and size is 32M */
static struct mtd_partition smdk_default_nand_part[] = {
    [0] = {
        .name    = "boot", /* default is "Boot Agent", by qspy */
        .size    = SZ_64K*3,  /* default is SZ_16K, qspy fix it to 192K*/
        .offset    = 0,
    },
    [1] = {
        .name    = "kernel", /* default is "S3C2410 flash partition 1", by qspy */
        .offset = SZ_64K*3,/* default is 0, by qspy */
        .size    = SZ_64K*29,/* default is SZ_2M, qspy fix it to 1856K*/
    },
    [2] = {
        .name    = "rootfs",/* default is "S3C2410 flash partition 2", by qspy */
        .offset = SZ_2M,/* default is SZ_4M, by qspy */
        .size    = SZ_1M*30,/* default is SZ_4M, qspy fix it to 30M*/
    },
    [3] = {
        .name    = "ext-fs1",/* default is "S3C2410 flash partition 2", by qspy */
        .offset    = SZ_32M,/* default is SZ_8M, by qspy */
        .size    = SZ_32M,/* default is SZ_2M, qspy fix it to 30M*/
    } /*,
    [4] = {
        .name    = "S3C2410 flash partition 4",
        .offset = SZ_1M * 10,
        .size    = SZ_4M,
    },
    [5] = {
        .name    = "S3C2410 flash partition 5",
        .offset    = SZ_1M * 14,
        .size    = SZ_1M * 10,
    },
    [6] = {
        .name    = "S3C2410 flash partition 6",
        .offset    = SZ_1M * 24,
        .size    = SZ_1M * 24,
    },
    [7] = {
        .name    = "S3C2410 flash partition 7",
        .offset = SZ_1M * 48,
        .size    = SZ_16M,
    } */
};
7.
关闭ECC校验
文件:drivers/mtd/nand/s3c2410.c
函数:s3c2410_nand_init_chip
        /*chip->ecc.mode        = NAND_ECC_SOFT; */
        chip->ecc.mode    = NAND_ECC_NONE;
8.
配置内核
$ make xconfig
其中有几项一定要修改的,分别是:
a.
启动
|---Boot options
|    |---Default kernel command string: [root=/dev/mtdblock2 rootfstype=cramfs init=/linuxrc console=ttySAC1,115200 devfs=mount mem=64]
分析:
/dev/mtdblock2
表示MTD分区的第2个分区存储根文件系统
rootfstype=cramfs
分区是cramfs类型,这项不加应该关系不大
init=/linuxrc
启动的首个脚本即根目录下的linuxrc
console=ttySAC1,115200
使用串口1作为串口调试,波特率设置为115200; 现在已经摒弃了以前使用ttyS0的写法
devfs=mount
/sbin/init运行之前能自动挂载/devdevfs文件系统
mem=64
存储器大小为64M
b. 增加devfs文件系统支持
|---File systems
|    |---Pseudo filesystems
|    |      |---/dev file system support
|    |      |      |---Automatically mount at boot
|    |      |      |---Debug devfs
这几项都是必选的
c.
芯片及系统类型
|---System Type
|    |---S3C2410 Machines
|    |      |---SMDK2410/A9M2410
支持2440时,这一项也是必选的,否则会编译不过

 

 

 

 

 

 

 

 

 

 

 

 

 

 

第一步:根据自己nand flash的分区情况,修改kernel中的相关参数:
由于kernel 2.6.22.3s3c2410中文件的组织风格有了变化,所以要修改的文件不再是 arch/arm/mach-s3c2410/devs.c,而是arch/arm/plat_s3c24xx/common-smdk.c。在其中找到分区的定义
smdk_default_nand_part[] = {
...
}
根据自己的分区情况修改其中的内容(分区情况可以通过bootloader查看)

第二步:修改nand flash的参数:
在同一个文件中找到
smdk_nand_info = {
.tacls=20,
.twrph0=60,
.twrph1=20,
...
}
改成
smdk_nand_info = {
.tacls=0,
.twrph0=30,
.twrph1=0,
...
}

第三步:修改ECC校验:
根据kernel官方网站上的说明,从2.6.22.3已经修改了ECC校验的问题(这也是我移植2.6.22.3的一个重要原因)。但实验下来发现,不管是用软件ECC还是硬件ECC都不行。只好改成NAND_ECC_NONE
driver/mtd/nand/s3c2410.c中找到s3c2410_nand_init_chip()函数,将其中的
chip->ecc.mode=NAND_ECC_SOFT;
改成
chip->ecc.mode=NAND_ECC_NONE;

第四步:修改Makefile文件:
修改其中的目标平台和交叉编译器为:
ARCH ?= arm
CROSS_COMPILE ?= arm-linux-

第五步:配置内核:
make menuconfig
注意,要将tmpfs选上,否则kernel找不到root分区。

第六步:编译内核:
make

到此内核的移植已经完成,但由于2.6.22.3中已经不包含devfs,所以还需要在root filesystem中配置console设备,否则将不能进入交互界面(不会出现提示符#)

第七步:配置console设备:
root filesystem/dev中,生成console设备:
mknod -m 600 console c 5 1

最后将kernelroot filesystem烧到nand flash中,kernel的移植即大功告成!^_^

由于2.6.22.3中用udev代替了devfs,下一步将进行udev的移植和配置。

成功移植busybox-1.7.0并加载mdev(udev的嵌入式版本)

上次成功移植完2.6.22.3后,由于没有启动udev,造成/dev下没有设备文件。也就是说所有的设备都没有挂接进来。
google在网上搜了一把。发现最新的busybox已经包含了udev的简化版本即mdev,且使用非常简单。
于是下载移植:

第一步:修改Makefile
Makefile中的ARCHCROSS_COMPILE修改为arm系列:
ARCH ?= arm
CROSS_COMPILE ?= arm-linux-

第二步:meke menuconfig
运行make menuconfig,选择你需要的选项。
在此选择

·  mdev

第三步:编译、安装
#make
#make install
这时会在你的编译目录下生成一个_install的目录,里面包含了生成的所有文件和目录结构。

第四步:查找所依赖的共享库
#cd _install/bin
#arm-linux-readelf -a ./busybox | grep "Shared library"
用上面的命令可以查到当前的busybox依赖哪些共享库(这些共享库一般可以在你的交叉编译器所在目录的lib下找到)

第五步:将生成的文件和共享库拷贝到你的root filesystem
_install中的目录结构和文件完全拷贝到你的root filesystem中。
然后将共享库拷贝到root filesystemlib目录中,并建立相关的链接文件

第六步:为mdev的运行准备环境
mdev需要改写/dev/sys两个目录。所以必须保证这两个目录是可写的(一般会用到sysfs,tmpfs。所以要重新编译内核)
然后在你的启动脚本文件中加入
/bin/mdev -s

最后:将新的内核、新的root filesystem烧到nand flash中就行了。

呵呵,下面要开始调试usb host了。进度一步一步的推进,好开心啊......

记得以前这里的哪位大侠提到2.6.21上已经解决了cramfsrootfs必须禁用ECC的问题,不过我暂时还不用cramfs,所以没去研究。
另外,我在2.6.142.6.18上使用yaffs/ramfs+yaffs可是保留着这个NAND_ECC_SOFT的,也没发现有什么问题。

 

你可能感兴趣的:(嵌入式ARM移植之三:移植 linux-2.6.26 内核)