Welcome 微信登录

首页 / 操作系统 / Linux / Linux2.6.32.2移植到Mini2440

1.移植内核的准备工作(1)使用的环境操作系统:Fedora 10交叉编译工具使用:arm-linux-gcc-4.3.22)获取内核获取内核的网址是:http://www.kernel.org/pub/linux/kernel/有很多方式可以获取 Linux 内核源代码,如果你的 Fedora10 平台可以上互联网,可以直
接在命令行输入以下命令获取到最原汁原味的 Linux-2.6.32.2:
   #wget http://www.kernel.org/pub/linux/kernel/v2.6/linux-2.6.32.2.tar.gz
当然你也可以先在 Windows 系统下使用迅雷等工具下载完,再复制到 Fedora10 中。
3)交叉编译工具交叉编译工具使用友善之臂的arm-linux-gcc-4.3.2,他们提供的编译器是符合EABI标准的编译器。其中关于EABI的介绍可以参看下面:1。什么是ABI
ABI,application binary interface (ABI),应用程序二进制接口。
既然是 接口,那就是某两种东西之间的沟通桥梁,此处有这些种情况:
A。应用程序 <-> 操作系统;
B。应用程序 <-> (应用程序所用到的)库
C 。应用程序各个组件之间
类似于API的作用是使得程序的代码间的兼容,ABI目的是使得程序的二进制(级别)的兼容。2。什么是OABI 和 EABI
OABI中的O,表示“Old”,“Lagacy”,旧的,过时的,OABI就是旧的/老的ABI。
EABI中的E,表示“Embedded”,是一种新的ABI。
EABI有时候也叫做GNU EABI。
OABI和EABI都是专门针对ARM的CPU来说的。
3。EABI的好处 / 为何要用EABI
A。支持软件浮点和硬件实现浮点功能混用
B。系统调用的效率更高
C。后今后的工具更兼容
D。软件浮点的情况下,EABI的软件浮点的效率要比OABI高很多。
4。OABI和EABI的区别
两种ABI在如下方面有区别:
A。调用规则(包括参数如何传递及如何获得返回值)
B。系统调用的数目以及应用程序应该如何去做系统调用
C。目标文件的二进制格式,程序库等
D。结构体中的 填充(padding/packing)和对齐。
E。
OABI:
* ABI flags passed to binutils: -mabi=apcs-gnu -mfpu=fpa
* gcc -dumpmachine: arm-unknown-linux
* objdump -x for compiled binary:

private flags = 2: [APCS-32] [FPA float format] [has entry point]
* "file" on compiled Debian binary:
ELF 32-bit LSB executable, ARM, version 1 (ARM), for GNU/Linux 2.2.0, dynamically linked (uses shared libs), for GNU/Linux 2.2.0, stripped
* "readelf -h | grep Flags""
Flags: 0x0
EABI:
* ABI flags passed by gcc to binutils: -mabi=aapcs-linux -mfloat-abi=soft -meabi=4
* gcc -dumpmachine: arm-unknown-linux-gnueabi
* objdump -x for compiled binary:
private flags = 4000002: [Version4 EABI] [has entry point]
* "file" on compiled binary (under Debian):
ELF 32-bit LSB executable, ARM, version 1 (SYSV), for GNU/Linux 2.4.17, dynamically linked (uses shared libs), for GNU/Linux 2.4.17, stripped
* "readelf -h | grep Flags""
Flags: 0x4000002, has entry point, Version4 EABI
 (4)硬件平台友善之臂的Mini2440NandFlash64MNorFlash2M的。NandFlash容量的不同,在后边制作根文件系统的时候会有所不同。2.修改内核以适应本开发板(1)假设我们把内核文件下载到了opt/mini2440/目录下,进行解压操作。 
#cd opt/mini2440#tar -zxvf linux-2.6.32.2.tar.gz
得到Linux-2.6.33.3文件夹(2)修改Makefile文件首先,我们要使Linux的默认的平台是arm平台,进入Linux-2.6.32.2文件夹中,修改此目录下的Makefile文件。修改成下面的代码,使其平台是ARM平台,交叉编译是arm-linux- 
export KBUILD_BUILDHOST := $(SUBARCH)ARCH   ?= arm   //使用的目标平台CROSS_COMPILE  ?= arm-linux-  //使用的交叉编译器,这里使用的系统默认的
接下来,测试一下Linux内核是否可以顺利的编译通过。 
#make s3c2410_defconfig //使用缺省的配置文件,也就是SMDK2440的缺省配置文件# make  //编译时间大约在20分钟左右
3)关于机器码很关键的一点是,在启动内核时,是根据bootloader传入的机器码(MACH_TYPE),来决定应启动哪种目标平台,在这一版本中,友善之臂申请了字节的机器码1999,在文件opt/mini2440/linux-2.6.32.2/arch/arm/tools/mach-types中。 
exeda    MACH_EXEDA    EXEDA    1994mx31sf005    MACH_MX31SF005    MX31SF005    1995f5d8231_4_v2    MACH_F5D8231_4_V2    F5D8231_4_V2    1996q2440    MACH_Q2440    Q2440    1997qq2440    MACH_QQ2440    QQ2440    1998mini2440    MACH_MINI2440    MINI2440    1999    //机器码colibri300    MACH_COLIBRI300    COLIBRI300    2000jades    MACH_JADES    JADES    2001spark    MACH_SPARK    SPARK    2002
如果传入的机器码和目标板的机器码不同时,经常出现下面的错误: 
Uncompressing Linux.................................................................................................................................. done, bootingthe kernel.运行到这就停止了。
U-Boot2010.03版本中也加入了mini2440机器码,在下面的文件中u-boot-2010.03/include/asm-arm/mach-typs.h,大约在1985行。 
#define MACH_TYPE_ARMATA 1993
#define MACH_TYPE_EXEDA 1994
#define MACH_TYPE_MX31SF005 1995
#define MACH_TYPE_F5D8231_4_V2 1996
#define MACH_TYPE_Q2440 1997
#define MACH_TYPE_QQ2440 1998
#define MACH_TYPE_MINI2440 1999
#define MACH_TYPE_COLIBRI300 2000
#define MACH_TYPE_JADES 2001
#define MACH_TYPE_SPARK 2002
/opt/mini2440/linux-2.6.32.2/arch/arm/mach-s3c2440目录下有一个mach-mini2440.c这个就是该版本自带的一个mini2440的文件。不过我们不使用它,直接将其删除。将/opt/mini2440/linux-2.6.32.2/arch/arm/mach-s3c2440目录下的mach-smdk2440.c复制一份,命名为mach-mini2440.c文件,因为,Mini2440smdk2440的结构最为相似,上面的外围的电路也很相似,所以在其基础上进行修改移植。打开刚刚改名的mach-mini2440.c,找到MACHINE_START(S3C2440, "SMDK2440")修改为下面的内容 
MACHINE_START(MINI2440, "FriendlyARM MINI2440 development board")
4)修改时钟源在mach-mini2440.c的第160static void __init smdk2440_map_io(void)函数中,把其中的16934400(代表原SMDK2440目标板上的晶振是 16.9344MHz)改为mini2440开发板上实际使用的12000000(代表 mini2440 开发板上的晶振12MHz,元器件标号为X2) 
static void __init mini2440_map_io(void){s3c24xx_init_io(mini2440_iodesc, ARRAY_SIZE(mini2440_iodesc));s3c24xx_init_clocks(12000000); //修改为 12000000s3c24xx_init_uarts(mini2440_uartcfgs, ARRAY_SIZE(mini2440_uartcfgs));}
gedit打开刚才复制得到的mach-mini2440.c文件,原来是smdk2440,所以将该文件中的所有的smdk2440替换成mini2440。除此之外,还要在mini2440_machine_init(void)函数中,把smdk_machine_init()函数调用注释掉,因为我们后面会编写自己的初始化函数,不需要调用smdk2440原来的。 
static void __init mini2440_machine_init(void){s3c24xx_fb_set_platdata(&mini2440_fb_info);s3c_i2c0_set_platdata(NULL);s3c_device_nand.dev.platform_data = &mini2440_nand_info; //添加没在官网提供的linux移植手册上看到有加这一句,刚开始没加编译正确,但是最后无法读出内核分区。platform_add_devices(mini2440_devices, ARRAY_SIZE(mini2440_devices));//smdk_machine_init();}
编译测试, 
#make mini2440_defconfig  //使用mini2440官方自带的配置文件#make zImage //编译内核,时间较长,最后会生成 zImage
    重新编译并把生成的内核文件 zImage(位于 arch/arm/boot 目录)下到板子中,可以看
到内核已经可以正常启动了,如下图,但此时大部分硬件驱动还没加,并且也没有文件系统,
因此还无法登陆。