uClinux交叉编译综合文档。

交叉编译busybox

可以参考《嵌入式系统设计与应用开发》(郑灵翔)一书131页,以及http://hi.baidu.com/zengzhaonong/blog/item/b0895436d24c33dea2cc2b03.html
主要过程:
(1)下载,打补丁。这里使用ELFS版本的busybox v1.8.2.
(2)修改Makefile:
ARCH = arm
CROSS_COMPILE = arm-iwmmxt-linux-gnueabi-
(3)make menuconfig
注意,[]Don't use /usr这个选项不要选,这样在最后的_install目录下会有/usr/bin和/usr/sbin目录(“不选这个选项会覆盖主机自身的/usr目录内容”的说法纯粹属于以讹传讹,何况如果使用非超级用户权限进行make和make install,对主机的/usr目录根本没有写权限)。另外要选择静态链接。其他可参考上述两处资料。mdev是udev的简化版。shell使用ash就够了。
(4)修改applets/applets.c文件,注释掉下面的行:
/*
#if ENABLE_STATIC && defined(__GLIBC__) && !defined(__UCLIBC__)
#warning Static linking against glibc produces buggy executables
#warning (glibc does not cope well with ld --gc-sections).
#warning See sources.redhat.com/bugzilla/show_bug.cgi?id=3400
#warning Note that glibc is unsuitable for static linking anyway.
#warning If you still want to do it, remove -Wl,--gc-sections
#warning from top-level Makefile and remove this warning.
#error Aborting compilation.
#endif
*/ (否则编译无法通过)
(5)make && make install
生成_install目录。完成。 

 

内核交叉编译除错

(1)pcmcia驱动无pcmcia_cs.o,是因为Makefile中没有配置生成pcmcia_cs.o的规则(如果选择mainstone或lubbock则会生成)。
于是暂时先去掉对pcmcia的支持,需要时再自行移植驱动。

(2)mtd驱动中__ioremap的警告,忽略;但最后链接阶段报错:
drivers/built-in.o: In function `init_xsbase27x':
hiddev.c:(.init.text+0x2898): undefined reference to `__ioremap'
hiddev.c:(.init.text+0x28c4): undefined reference to `__ioremap'
make: *** [.tmp_vmlinux1] 错误 1

应该将__ioremap改成ioremap。这是API的一个变化,可以对比mainstone的mtd/maps驱动得知。

 

修改内核配置文件

要移植内核到一个新的开发板,需要修改的内核配置文件主要有:
(1)根Makefile
主要是修改ARCH和CROSS_COMPILE的定义。例如:
ARCH=arm CROSS_COMPILE=arm-iwmmxt-linux-gnueabi-
当然也可以不修改,只是在编译内核时每个make命令后面都要加上上述两个选项。

(2)Kconfig
要将新的开发板信息在make menuconfig/xconfig...时体现在配置选项菜单上,就必须修改Kconfig文件。主要包括arch/arm/Kconfig和arch/arm/mach-pxa/Kconfig,形如MACH_MAINSTONE。在2.4内核中则对应于arch/arm/config.in文件,形如CONFIG_ARCH_MAINSTONE。

arch/arm/Kconfig中设置相关配置:
例如:
config LEDS
bool "Timer and CPU usage LEDs"
depends on ARCH_CDB89712 || ARCH_CO285 || ARCH_EBSA110 || ARCH_EBSA285 || ARCH_IMX || ARCH_INTEGRATOR || ARCH_LUBBOCK || MACH_MAINSTONE || ARCH_NETWINDER || ARCH_OMAP || ARCH_P720T || ARCH_PXA_IDP || ARCH_SA1100 || ARCH_SHARK || ARCH_VERSATILE || ARCH_AT91 || MACH_TRIZEPS4 || ARCH_DAVINCI || ARCH_KS8695 || MACH_XSBASE270

另外还有驱动相关的Kconfig文件:例如drivers/mtd/maps/Kconfig中,需要加入开发板的FLASH存储器配置选项。
config MTD_XSBASE270
tristate "CFI Flash device mapped on Emdoor XSBASE270 eval board"
depends on MACH_XSBASE270 && MTD_CFI_INTELEXT
select MTD_PARTITIONS
help
This provides a driver for the on-board flash of the Emdoor
'XSBASE270' evaluation board.


arch/arm/mach-pxa/Kconfig中添加:
config MACH_XSBASE270
bool "Emdoor XSBASE270 Developemnt Platform"
select PXA27x


(3)arch/arm/mach-pxa/Makefile
将新移植的硬件平台加入编译。可如下加入平台文件xsbase270.c的编译项:
obj-$(CONFIG_MACH_XSBASE270) += xsbase270.o

MTD设备driver的porting

MTD设备主要指FLASH存储器。由于主要的文件系统是存放在FLASH上的,因此必须要针对硬件平台移植配置相应的MTD驱动程序。
相关文件包括:
drivers/mtd/maps/Kconfig
drivers/mtd/maps/Makefile
drivers/mtd/maps/xsbase270-flash.c

(1)drivers/mtd/maps/Kconfig中,需要加入开发板的FLASH存储器配置选项。
config MTD_XSBASE270
tristate "CFI Flash device mapped on Emdoor XSBASE270 eval board"
depends on MACH_XSBASE270 && MTD_CFI_INTELEXT
select MTD_PARTITIONS
help
This provides a driver for the on-board flash of the Emdoor
'XSBASE270' evaluation board.

(2)drivers/mtd/maps/Makefile中,加入驱动程序代码的编译:
obj-$(CONFIG_MTD_XSBASE270) += xsbase270-flash.o

(3)drivers/mtd/maps/xsbase270-flash.c
根据lubbock-flash.c和mainstone-flash.c修改。

注意2.4到2.6的kernel API发生了变化,如struct map_info中的buswidth变成了bankwidth。
kernel API可以从下面的网站查询:
http://www.kernel-api.org/docs/online/2.6.17/annotated.html

关于machine types 编号

在arch/arm/tools/mach-types 文件中分配,由arch/arm/tools/gen-mach-types工具来产生include/asm-arm/mach-types.h头文件。
由于MACH_XSBASE270被定义为1141,因此在arch/arm/boot/compressed/head-xscale.S 加入
#ifdef CONFIG_MACH_XSBASE270
mov r7, #(MACH_TYPE_XSBASE270 & 0xff)
orr r7, r7, #(MACH_TYPE_XSBASE270 & 0xff00)
#endif

不能使用单条mov指令,因为1141不是MOV指令所能直接操作的立即数。

在bootloader中如何把正确的machine type传给Linux内核呢?
在使用函数指针kernel(0, MACH_TYPE_XSBASE270)时,第一个参数是r0=0,第二个参数是r1=machine type,这样就将machine type传递给内核。在bootloader的include/board/xsbase270.h中定义即可:
#define MACH_TYPE_XSBASE270 1141

Linux内核编译时链接地址的确定?

Bootloader中使用函数指针来转向内核。例如 thekernel=KERNEL_DRAM_BASE,这告诉bootloader从KERNEL—_DRAM_BASE开始的地方就是内核起始处,bootloader确实会把FLASH存储器中的内核映像加载到(或说解压到)KERNEL_DRAM_BASE开始的内存地址处开始运行。
那么,在编译内核时,如何确定其链接地址(加载到内存中运行的地址)就是bootloader中指定的KERNEL_DRAM_BASE呢?
zImage的链接脚本是vmlinux.lds,是arch/arm/boot/compressed目录下的vmlinux.lds.in生成的。
在arch/arm/boot/Makefile中定义了:
ifeq ($(CONFIG_ARCH_PXA),y)
ZRELADDR = 0xa0008000
endif

#
# We now have a PIC decompressor implementation. Decompressors running
# from RAM should not define ZTEXTADDR. Decompressors running directly
# from ROM or Flash must define ZTEXTADDR (preferably via the config)
#

ZTEXTADDR就是解压缩代码的ram偏移地址,ZRELADDR是内核ram启动的偏移地址,这里看到指定ZRELADDR的地址为0xa0008000。PXA270的SDRAM起始地址为0xa0000000,偏移量0x8000是怎么来的呢?

在内核文档kernel/Document/arm/Booting 文件中有:
Calling the kernel image

Existing boot loaders: MANDATORY
New boot loaders: MANDATORY

There are two options for calling the kernel zImage. If the zImage is stored in flash, and is linked correctly to be run from flash, then it is legal for the boot loader to call the zImage in flash directly.

The zImage may also be placed in system RAM (at any location) and called there. Note that the kernel uses 16K of RAM below the image to store page tables. The recommended placement is 32KiB into RAM.

看来在image下面用了32K(0x8000)的空间存放内核页表。


在bootloader的include/board/xsbase270.h(目标板配置头文件)中定义了:
#define KERNEL_DRAM_BASE 0xA0008000
这样就把bootloader和内核联系起来了。

---------------------------------------------------------------------
[参考资料]http://blog.chinaunix.net/u/24474/showart_249872.html

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值