内核的移植相对复杂,不可能一步到位,心急吃不了热豆腐,我们只有步步为营,方能步步为赢。本节的目的是修改内核,使得Linux-3.8.3内核适应于OK6410开发平台。外设的移植,在接下来的章节会一步一步完成。
1.1.1 mkimage工具
制作Linux内核的压缩镜像文件,需要使用到mkimage工具。mkimage这个工具位于u-boot-2013. 04中的tools目录下,它可以用来制作不压缩或者压缩的多种可启动镜像文件。mkimage在制作镜像文件的时候,是在原来的可执行镜像文件的前面加上一个16个byte(0x40)的头,用来记录参数所指定的信息,这样u-boot才能识别出制作出来的这个镜像是针对哪一个CPU体系结构、哪一种OS、哪种类型、加载到内存中的哪个位置、入口点在内存的哪个位置以及镜像名是什么等信息。在/u-boot-2013.04/tools目录下执行./mkimage,输出信息如下所示:
zhuzhaoqi@zhuzhaoqi-desktop:~/u-boot/u-boot-2013.04/u-boot-2013.04/tools$ ./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 -ddata_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
./mkimage -V ==> print version information and exit
表3. 1 CPU体系结构取值 | 表示的体系结构 | 取值 | 表示的体系结构 | alpha
| Alpha | arm | ARM | 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 |
|
针对上面的输出信息,-A 指定CPU的体系结构,也就是说,arch的取值可以是如表3. 1所示。
-O 指定操作系统类型,os可以取:openbsd、netbsd、freebsd、4_4bsd、linux、svr4、esix、solaris、irix、sco、dell、ncr、lynxos、vxworks、psos、qnx、u-boot、rtems、artos。
-T 指定镜像类型,type可以是:standalone、kernel、ramdisk、multi、firmware、script、filesystem。
-C 指定镜像压缩方式,comp可以是:none(不压缩)、gzip( 用gzip的压缩方式)、bzip2 (用bzip2的压缩方式)。
-a 指定镜像在内存中的加载地址,镜像下载到内存中时,要按照用mkimage制作镜像时,这个参数所指定的地址值来下载。
-e 指定镜像运行的入口点地址,这个地址就是-a参数指定的值加上0x40(因为前面有个mkimage添加的0x40个字节的头)。
-n 指定镜像名。
-d 指定制作镜像的源文件。
将u-boot-2013.04下的tools这个文件夹下中的mkimage工具复制到ubuntu系统的/user/bin下,这样可以直接当作操作命令使用。
1.1.2 配置menuconfig
make menuconfig是基于文本选单的图形化内核配置界面。
打开最顶层的Makefile,有这么两行代码。
ARCH ?= $(SUBARCH)
CROSS_COMPILE ?= $(CONFIG_CROSS_COMPILE:"%"=%)
ARCH针对何种CPU体系结构,OK6410的cpu是三星公司的S3C6410,为arm,那么这句就得修改成arm。CROSS_COMPILE是编译工具链,和u-boot配置一样。则需修改成:
ARCH ?= arm
CROSS_COMPILE ?= /usr/local/arm/4.4.1/bin/arm-linux-
进入arch/arm/mach-s3c64xx,有Kconfig文件,Kconfig作用是描述所属目录源文档相关的内核配置菜单,在执行make menuconfig时,将从Kconfig文件中读出菜单。打开Kconfig文件。其中:
# S3C6410 machine support
所支持的平台有:
config MACH_ANW6410
config MACH_MINI6410
config MACH_REAL6410
config MACH_SMDK6410
但是没有OK6410,这里就需要进行修改文件,使得Linux-3.8.3能适合运行在OK6410开发平台的内核,取以上的四种平台中的一种作为基础进行修改,这里就采用MINI6410。
在当前arch/arm/mach-s3c64xx文件下,复制一份mach-mini6410.c并且重命名为mach-ok6410.c。使用操作命令:
zhuzhaoqi@zhuzhaoqi-desktop:~/Linux/linux-3.8.3/arch/arm/mach-s3c64xx$ cp mach-mini6410.c mach-ok6410.c
打开mach-ok6410.c文件,将mini6410(MINI6410)修改为ok6410(OK6410),打开mach-ok6410.c。
zhuzhaoqi@zhuzhaoqi-desktop:~/Linux/linux-3.8.3/arch/arm/mach-s3c64xx$ gedit mach-ok6410.c
使用gedit最大的好处是可以很好的进行文本操作,使用替换功能,将mini6410 (MINI6410)替换成为ok6410(OK6410)。
在arch/arm/mach-s3c64xx目录下打开Makefile,找到如下:
obj-$(CONFIG_MACH_MINI6410) += mach-mini6410.o
在其后面添加ok6410的配置:
obj-$(CONFIG_MACH_OK6410) += mach-ok6410.o
添加这行代码则是告诉编译器要将ok6410.c编译进内核。
回到arch/arm/mach-s3c64xx目录下的Kconfig,打开文件,为OK6410添加配置菜单。在如下:
config MACH_MINI6410
后面添加OK6410的配置:
config MACH_OK6410
bool "OK6410"
select CPU_S3C6410
select SAMSUNG_DEV_ADC
select S3C_DEV_HSMMC
select S3C_DEV_HSMMC1
select S3C_DEV_I2C1
select SAMSUNG_DEV_IDE
select S3C_DEV_FB
select S3C_DEV_RTC
select SAMSUNG_DEV_TS
select S3C_DEV_USB_HOST
# select S3C_DEV_USB_HSOTG
select S3C_DEV_WDT
select SAMSUNG_DEV_KEYPAD
select SAMSUNG_DEV_PWM
select HAVE_S3C2410_WATCHDOG if WATCHDOG
select S3C64XX_SETUP_SDHCI
select S3C64XX_SETUP_I2C1
select S3C64XX_SETUP_IDE
select S3C64XX_SETUP_FB_24BPP
select S3C64XX_SETUP_KEYPAD
help
Machine support for the feiling OK6410
添加之后执行make menuconfig就会有ok6410选项。
进入arch/arm/tools,打开mach-types文件:
zhuzhaoqi@zhuzhaoqi-desktop:~/Linux/linux-3.8.3/arch/arm/tools$ gedit mach-types
可以看到如下:
machine_is_xxx CONFIG_xxxx MACH_TYPE_xxx number
mini6410 MACH_MINI6410 MINI6410 2520
mini6410的ID是2520,但是OK6410的ID是1626,这个在u-boot也曾经出现过,这就如每一个人都有自己相对应的ID,如果ID号不匹配,将导致u-boot无法启动内核,在mini6410后面添加如下。
ok6410 MACH_OK6410 OK6410 1626