Linux-----内核移植篇

Linux内核移植         

        本次主要将linux-3.0的内核移植到S3C2440上:

        移植目录:~/fl2440/kernel/linux-3.0

        交叉编译器:buildroot-2012.08

        bootloader:u-boot-2010.09

       Target Board:FL2440

        开发环境:linux服务器

一、建立交叉编译环境

      **************************************************************************************************************

交叉编译介绍

**************************************************************************************************************

     一种计算机环境中运行的编译程序,能编译出在另外一种环境下运行的代码,我们就称这种编译器支持交叉编译。这个编译过程就叫交叉编译。简单地说,就是在一个平台上生成另一个平台上的可执行代码。这里需要注意的是所谓平台,实际上包含两个概念:体系结构(Architecture)、操作系统(Operating System)。同一个体系结构可以运行不同的操作系统;同样,同一个操作系统也可以在不同的体系结构上运行。举例来说,我们常说的x86 Linux平台实际上是Intel x86体系结构和Linux for x86操作系统的统称;而x86 WinNT平台实际上是Intel x86体系结构和Windows NT for x86操作系统的简称。

      我们需要在linux环境中编译出能在ARM上运行的可执行文件,于是我们手动配置buildroot-2012.08.最后交叉编译器的路径为/opt/buildroot-2012.08/arm920t/usr/bin/;

  二、源码包的获取及解压   

       本次主要移植linux-3.0的内核。

      首先获取源码包地址:http://pan.baidu.com/s/1mgws9Eo,然后解压源码包linux-3.0.tar.bz2在自己指定的目录下生成linux-3.0;

[xiaokai@centos6 kernel]$ tar -xjf linux-3.0.tar.bz2 

三、根目录下顶层Makefile的修改

/***************************************************************************************************************************

Makefile介绍及其作用

**************************************************************************************************************

       一个工程中的源文件不计其数,其按类型、功能、模块分别放在若干个目录中,makefile定义了一系列的规则来指定,哪些文件需要先编译,哪些文件需要后编译,哪些文件需要重新编译,甚至于进行更复杂的功能操作,因为 makefile就像一个Shell脚本一样,其中也可以执行操作系统的命令。

       于是我们需要通过修改Makefile来指定我们需要编译生成的文件供我们来使用。在这个文件中,我们需要修改的第一个地方是交叉编译器与平台的类型。

       通过搜索CROSS_COMPILE,找到定义交叉编译器的环境变量,执行如下修改:

 ARCH        ?= arm

CROSS_COMPILE   ?= /opt/buildroot-2012.08/arm920t/usr/bin/arm-linux-

注意:如果我们编译内核的时候出现如下这样一个错误提示:

make: ***    arm/kernel.git/arch/arm: Is a directory.  Stop.

这个错误是由在Makefile的 ARCH  ?= $(SUBARCH)这行的后面多了一个空格造成的;

如果出现如下这样一个错误提示:

make: /opt/buildroot-2012.08/arm920t/usr/bin/arm-linux-: Command not found

CHK     include/linux/version.h
          CHK     include/generated/utsrelease.h
         make[1]: `include/generated/mach-types.h' is up to date.
         CC      kernel/bounds.s
        /bin/sh: /opt/buildroot-2012.08/arm920t/usr/bin/arm-linux-: No such file or directory
        make[1]: *** [kernel/bounds.s] Error 1

这是因为/opt/buildroot-2012.08/arm920t/usr/bin/arm-linux-后多了一个空格;

所以,在编辑Makefile时候,每行结尾,一定要确认没有空格,直接是换行。

/*************************************************************************************************************

mkimage介绍

**************************************************************************************************************

mkimage是在制作镜像文件时候, 在原来的image文件前增加一个0x40字节长度的头,增加的头结构描述如下:

/*
 * Legacy format image header,
 * all data in network byte order (aka natural aka bigendian).
 */
typedef struct image_header {
    uint32_t    ih_magic;   /* Image Header Magic Number    */
    uint32_t    ih_hcrc;    /* Image Header CRC Checksum    */
    uint32_t    ih_time;    /* Image Creation Timestamp */
    uint32_t    ih_size;    /* Image Data Size      */
    uint32_t    ih_load;    /* Data  Load  Address      */
    uint32_t    ih_ep;      /* Entry Point Address      */
    uint32_t    ih_dcrc;    /* Image Data CRC Checksum  */
    uint8_t     ih_os;      /* Operating System     */
    uint8_t     ih_arch;    /* CPU architecture     */
    uint8_t     ih_type;    /* Image Type           */
    uint8_t     ih_comp;    /* Compression Type     */
    uint8_t     ih_name[IH_NMLEN];  /* Image Name       */
} image_header_t;
Image Name占用了32字节,其他信息占用了32字节

为什么要增加呢?

通常,u-boot为kernel提供一些kernel无法知道的信息,比如ramdisk在RAM中的地址。Kernel也必须为U-boot提供必要的信息,如通过mkimage这个工具(在u-boot代码的tools目录中)可以给zImage添加一个header,也就是使得通常编译的内核zImage添加一个数据头,把添加头后的image通常叫uImage,uImage是可以被U-boot直接引导的内核镜像。

下面介绍一下mkimage的用法:

Usage: ./mkimage -l image
          -l ==> list image header information
       ./mkimage [-x] -A arch -O os -T type -C comp -a addr -e ep -n name -d data_file[:data_file...] image
          -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)
       ./mkimage [-D dtc_options] -f fit-image.its fit-image


-A 设定架构类型,可取值参照u-boot-2012.09/common/image.c

取值 表示的CPU体系结构
alpha Alpha 
arm A RM 
x86 Intel x86
ia64 IA64
mips MIPS
mips64 MIPS 64 Bit
ppc PowerPC
s390 IBM S390
sh SuperH
sparc SPARC
sparc64 SPARC 64 Bit
m68k MC68000

-O 设定操作系统类型,可取值参照u-boot-2012.09boot/common/image.c

可以取以下值:
openbsd、netbsd、freebsd、4_4bsd、linux、svr4、esix、solaris、irix、sco、dell、ncr、lynxos、vxworks、psos、qnx、u-boot、rtems、artos
-T image类型,可取值参照u-boot-2012.09/common/image.c

可以取以下值:
standalone、kernel、ramdisk、multi、firmware、script、filesystem
-a 指定image在内存中的加载地址

映象下载到内存中时,要按照用mkimage制作映象时,这个参数所指定的地址值来下载
-e 指定image运行的入口点地址

这个地址就是-a参数指定的值加上0x40(因为前面有个mkimage添加的0x40个字节的头)
-C 指定压缩方式,压缩方式参考u-boot-2012.09/common/image.c

可以取以下值:
none 不压缩
gzip 用gzip的压缩方式
bzip2 用bzip2的压缩方式

-n  指定映象名

-d data_file[:data_file...] 制作image的源文件

所以说这个工具可以用来制作各种压缩或不压缩的可启动映象文件

于是我们下一步修改的地方应是添加mkimage工具。使系统在制作映象文件的时候,会在原来的可执行映象文件的前面加上一个0x40字节的头,记录参数所指定的信息。这样uboot才能识别这个映象是针对哪个CPU体系结构的,哪个OS的,哪种类型,加载内存中的哪个位置, 入口点在内存的那个位置以及映象名是什么。因而我们在559行下面添加如下:

             cp arch/arm/boot/zImage . -f

             mkimage -A arm -O linux -T kernel -C none -a 30008000 -e 30008040 -n "Linux Kernel" -d zImage linuxrom-s3c2440-xiao.bin

              rm -f zImage

在Makefile中所有需要执行的命令都需要以tab键开头;

为了在make distclean中删除生成的bin文件,我们需要在1206行添加如下命令:

         @rm -f linuxrom-*.bin

表示只有执行distclean时才会删除它。

四、拷贝mkimage

[xiaokai@centos6 linux-3.0]$ cp ../../bootloader/u-boot-2010.09/tools/mkimage .

将编译所需要的mkimage拷贝到当前目录下来;

 
 
 
 

五、修改时钟晶振频率(解决打印信息乱码,频率不同步现象)

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

[xiaokai@centos6 linux-3.0]$ vim arch/arm/mach-s3c2440/mach-smdk2440.c

进入mach-smdk2440.c后,搜索smdk2410_map_io函数里面改时钟,此时需要知道我们之前uboot移植时定义过SBC2410X的输入时钟;

[xiaokai@centos6 linux-3.0]$ vim ../../bootloader/u-boot-2010.09/include/configs/sbc2410x.h

打开此文件之后,搜索52行可以看到

#define CONFIG_SYS_CLK_FREQ 12000000        /* the SBC2410X has 12MHz input clock */

说明我们需要将初始化,因而在180行

s3c24xx_init_clocks(16934400);
改为:
s3c24xx_init_clocks(12000000);

六、修改对uart控制器的配置,配置为普通串口

由于三星默认的串口名为ttySAC,而我们根文件系统中/etc/inittab文件中的串口名称需与内核中的串口名称一致。由于我的根文件系统中/etc/inittab中的串口名称为s3c2440_serial0,因此需要修改内核中的串口名称。现在我们需要内核移到S3C2440上,通过修改samsung.c可以将串口设备使能并加载到内核上;

[xiaokai@centos6 linux-3.0]$ vim drivers/tty/serial/samsung.c

在这个文件中我们将57行串口设备名改为如下:

#define S3C24XX_SERIAL_NAME "ttyS"即可保存;

七、机器码的修改

 由于我uboot配置文件中是以mini2440为副本来移植的,在uboot移植工程中已将mini2440的ID号强制加载给Smdk2440。故此次Linux内核移植时为了以Smdk2440为模板来启动,而将mini2440本来的ID号1999改掉,如下:

-mini2440    MACH_MINI2440     MINI2440   999

+mini2440   MACH_MINI2440      MINI2440362

[xiaokai@centos6 linux-3.0]$ vim arch/arm/tools/mach-types

打开此文件后,在176行将看到MACHINE_START(S3C2440, "SMDK2440"),这里就是S3C2440的machine ID号。

八、拷贝.config文件

由于我们的开发板fl2440和mini2440的设计基本一样,所以我们以mini2440_defconfig为模板来生效我们需要执行或安装的一些功能模块;

[xiaokai@centos6 linux-3.0]$ cp arch/arm/configs/mini2440_defconfig .config

九、更改menuconfig配置对CPU的支持

[xiaokai@centos6 linux-3.0]$ export TERM=vt100

[xiaokai@centos6 linux-3.0]$ make menuconfig

                                            System Type ---> 

                                                          S3C2440 and S3C2442 Machines  --->

                                                            取消[ ]MINI2440 development board

                                                                 选中[*]SMDK2440

点击退出保存即可。

十、make

           即可生成我们需要的内核文件linuxrom-xiao.bin



 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值