当前位置: 首页 > 工具软件 > XX-Mini > 使用案例 >

linux--mini2440内核移植

陆卓
2023-12-01

移植linux2.6.29内核mini2440

移植环境:

主机:redhat 5

交叉编译器:arm-linux-gcc-4.3.2

开发板平台:S3C2440mini2440开发板)


下载Linux内核源代码 :https://www.kernel.org/pub/linux/kernel/

到该目录下下载内核。

修改配置文件

1.修改顶层Makefile文件
   直接将Makefile文件里面的        ln193
   ARCH ?= $(SUBARCH)
   CROSS_COMPILE ?=
   改为:
   ARCH ?= arm
   CROSS_COMPILE ?=arm-unknown-linux-gnueabi-   //我的完整的交叉编译工具名字为 arm-unknown-linux-gnueabi-gcc

2.修改时钟,不修改超级终端中会出现乱码
修改arch/arm/mach-s3c2440/mach-smdk2440.c        ln163

    static void __init smdk2440_map_io(void)

{

s3c24xx_init_io(smdk2440_iodesc, ARRAY_SIZE(smdk2440_iodesc));

s3c24xx_init_clocks(12000000);      //修改为 12000000,默认为 16934400

s3c24xx_init_uarts(smdk2440_uartcfgs, ARRAY_SIZE(smdk2440_uartcfgs));

}

3. 修改对nand的分区信息。要让内核知道nand flash的分区信息,设置成跟bootloader一致。

arch/arm/plat-s3c24xx/common-smdk.c中修改smdk_default_nand_part[],注意这个一定要跟bootloader的一致。在我的板子中修改如下:

static struct mtd_partition smdk_default_nand_part[] = {

[0] = {

.name = "U-boot",  //这里是bootloader所在的分区,可以放置u-boot

.size = 0x00060000,  //对应/dev/mtdblock0

.offset = 0,

},

[1] = {

.name = "param",  //这里是u-boot的参数区,其实也属于bootloader

.offset = 0x00060000,  //一部分,如果u-boot 比较大,可以把此区域覆盖掉

.size = 0x00020000,  //不会影响系统启动,对应/dev/mtdblock1

},

[2] = {

.name = "Kernel",//内核所在的分区,大小为 5M,足够放下大部分自己定制的巨型内核了,比如内核使用了更大的Linux Logo图片对应/dev/mtdblock2

.offset = 0x00080000,

.size = 0x00500000,

},

[3] = {

.name = "root",  //文件系统分区,主要用来存放yaffs2 文件系统内容,对应/dev/mtdblock3

.offset = 0x00580000,

.size = 1024 * 1024 * 1024,

},

};

 4 .  修改nand Flash的校验方式,去掉ECC校验
drivers/mtd/nand/s3c2410.c669行

chip->ecc.mode = NAND_ECC_SOFT;

改为 chip->ecc.mode = NAND_ECC_NONE;

注意:这个去掉ECC校验的问题,在内核中明确说明是不建议这样做的,因为这样就等于忽略了对NAND FLASH坏块的检测。而我一开始也是编译的时候就去掉了ECC校验的选项,原以为在编译选项中去掉就可以了,结果一直报这样的错:

end_request: I/O error, dev mtdblock2, sector 0

FAT: unable to read boot sector

VFS: Cannot open root device "mtdblock2" or unknown-block(31,2)

Please append a correct "root=" boot option; here are the available partitions:

1f00        192 mtdblock0 (driver?)

1f01       1856 mtdblock1 (driver?)

1f02      30720 mtdblock2 (driver?)

1f03      32768 mtdblock3 (driver?)

Kernel panic - not syncing: VFS: Unable to mount root fs on unknown-block(31,2)

后来发现配置中去掉的这个选项在代码中并没有完全去掉,只是去掉了硬件校验的方式,换成了软件校验。只有在代码中给改成NAND_ECC_NONE,才不会校验,但是这样是不提倡的。只有这样最后我的系统才起来.


5 .修改机器码,使之与bootloader的机器码相同,这里使用的是u-boot
linux 内核中定义机器码的位置
arch/arm/tools/mach-types

379行  s3c2440   ARCH_S3C2440  S3C2440   362

U-boot中的相关配置文件

 include/asm-arm/mach-types.h

375行  #define MACH_TYPE_S3C2440              362

(如一致则无需修改)



6.配置及编译内核
然后用S3C2410的默认配置文件
#cp arch/arm/configs/s3c2410_defconfig .config
#make menuconfig               //只需修改下面几项

[*] Enable loadable module support --->

       [*]   Module unloading

       [*]   Automatic kernel module loading

      选择这两个,剩下的可以去掉

System Type ---->

       [*] S3C2410 DMA support

       S3C2410 Machines --->

              [*] SMDK2410/A9M2410 

       S3C2440 Machines --->

              [*] SMDK2440

              [*] SMDK2440 with S3C2440 CPU module

//System Type这部分,只选这些,其他可以全部去掉,

Boot option ----->

    修改启动参数为:noinitrd root=/dev/mtdblock2 init=/linuxrc console=ttySAC0,115200

    可能根据个人板子的设置会不一样,我的是从Nand Flash中加载文件系统,其中mtdblock2是存放我的Linux文件系统的分区。不过,在bootloader可以传递内核参数的情况下这个设置是无效的。

 

Device Drivers --->

       <*> Memory Technology Device (MTD) support --->

              [*]   MTD partitioning support

              <*> NAND Device Support --->

                      <*>   NAND Flash support for S3C2410/S3C2440 SoC

                      [ ]    S3C2410 NAND Hardware ECC     //这个要去掉

       [*] Network device support --->

               [*]   Ethernet (10 or 100Mbit) ---> 

                   <*>   DM9000 support
Kernel Features ->
     [*]Use the ARM EABI to compile the kernel
     [*]  Allow old ABI binaries to run with this kernel



这里由于使用了codesourcery的工具链,此工具链支持EABI内核编译时也要选上,否则用这个编译器编出来的用户程序无法运行,最典型的错误是Busybox无法运行。

7. 内核增加yaffs2支持
到网上下载yaffs2源代码
yaffs2 代码 
进入 http://www.aleph1.co.uk/cgi-bin/viewcvs.cgi/,点击¡ Download GNU 
tarball¡,下载后出现 cvs-root.tar.gz 压缩包, 解压
tar ¨zxvf /mnt/hgfs/share/cvs-root.tar.gz ¨C /opt/studyarm 
cd /opt/stdudyarm/cvs/yaffs2/ 
./patch-ker.sh c /root/linux-2.6.29
上面命令完成下面三件事情: 
(1) 修改内核 fs/Kconfig 
    增加一行:source "fs/yaffs2/Kconfig" 
(2) 修改内核 fs/Kconfig 
    增加一行:ojb-$(CONFIG_YAFFS_FS) +=yaffs2/ 
(3) 在内核 fs/目录下创建 yaffs2 目录 
    将 yaffs2 源码目录下面的 Makefile.kernel 文件复制为内核 fs/yaffs2/Makefie; 
    将 yaffs2 源码目录的 Kconfig 文件复制到内核 fs/yaffs2 目录下; 
    将 yaffs2 源码目录下的*.c *.h 文件复制到内核 fs/yaffs2 目录下.
在内核根目录下执行:
配置yaffs2文件支持
File systems   --->
Miscellaneous filesystems --->
    <*>YAFFS2 file system support

到此为止,基本完成。

下面正式编译

#make zImage

会在arch/arm/boot/下面生成zImage文件,但是此文件不能直接在用uboot启动,需要用mkimage生成uboot可执行的文件。

 接着介绍使用mkimage生成镜像文件并下载运行的方法。
首先,用u-boot/tools/mkimage这个工具为你的内核加上u-boot引导所需要的文件头,具体做法如下:
[root@localhost tftpboot]#mkimage -n ‘linux-2.6.29′ -A arm -O linux -T kernel -C none -a 30008000 -e 30008040 -d zImage zImage.img
Image Name:   linux-2.6.29
Created:      Fri Jan 12 17:14:50 2009
Image Type:   ARM Linux Kernel Image (uncompressed)
Data Size:    1262504 Bytes = 1232.91 kB = 1.20 MB
Load Address: 0×30008000
Entry Point:  0×30008040

这里生成的zImage文件就可以通过uboot来引导了。

这里解释一下参数的意义:
        -A ==> set architecture to ‘arch’
        -O ==> set operating system to ‘os’
        -T ==> set image type to ‘type’
        -C ==> set compression type ‘comp’
        -a ==> set load address to ‘addr’ (hex)
        -e ==> set entry point to ‘ep’ (hex)
        -n ==> set image name to ‘name’
        -d ==> use image data from ‘datafile’
        -x ==> set XIP (execute in place)


    其中与内核引导最密切的是-e 30008000,也就是内核的入口地址。其它参数可以参考帮助信息。其它UBOOT格式的内核与原来相比,只是进行(可选)了压缩,并在前面加了一个0x40大小的头。这个头里放了内核的位置(0x30007fc0)和入口地址(0x30008000)和其它信息。
  bootm命令执行时,先对头部信息等进行校验,然后把头信息放到一个结构里面。最后根据内核类型调用相应的启动函数。对于Linux而言就是do_bootm_linux,在启动函数里面,有这么一个操作:theKernel = (void (*)(int, int, uint))ntohl(hdr->ih_ep);,这是最关键的一个操作,将内核的入口地址0x30008000赋给了theKernel,在启动函数的最后,使用theKernel (0, bd->bi_arch_number, bd->bi_boot_params);启动内核。
  根据传参规范,三个变量分别用r0,r1,r2传给内核,这样就巧妙地利用了函数指针进行了参数传递,实在是精妙!

上面讲完了内核的引导及传参,需要引起注意的就是在使用mkimage命令生成内核时,-e后面的地址要比-a后面的地址偏移0x40,原因很简单,就不再细说了。

之后内核还要移植DM900网卡。

现在内核还不能在开发板上运行,接下来我们还需要制作一个YAFFS的文件系统,这样有了文件系统内核才能在开发板上跑起来~



 类似资料: