create android or linux cross compile toolChains

1. git下prebuilt这个project:

 git clone git://android.git.kernel.org/platform/prebuilt.git

 

 

 

2. GNU ARM 工具链

要下载 GNU 工具链,请访问 CodeSourcery 下载站点(见 参考资料)并选择 IA32 GNU/Linux TAR 文件:

arm-2008q3-72-arm-none-linux-gnueabi-i686-pc-linux-gnu.tar.bz2

有针对主要客户机操作系统的各种 GNU 版本,但本文主要关注在 Linux® 下安装和使用工具链的 Lite 版本。
由于 ARM 设计在其发展过程中已经经历不同的版本,所以这个 Lite 包包含了处理器设计的 3 个最常见版本的不同 C 库,这 3 个版本是 ARM v4T、ARM v5T 和 ARM 7。
接下来,使用 bunzip2 命令将文件提取到您的主目录。

 

清单 1. 提取下载后的 GNU 工具链
          $ bunzip2 arm-2008q3-72-arm-none-linux-gnueabi-i686-pc-linux-gnu.tar.bz2$ tar -xvf arm-2008q3-72-arm-none-linux-gnueabi-i686-pc-linux-gnu.tar  .  .  .  (Files listed while being extracted from the archive.)  .  .  .$
现在,修改您的 PATH 环境变量以访问工具链的 bin 目录。这样,工具就可以使用了。

配置 Linux 以使用 GNU 工具链
在工具链的下载页面,您还可以找到几个有用的 PDF 文件和一份详细的入门指南,它们归档了所包含的工具。本文仅提供精简的介绍,帮助您设置好并运行工具链。
如果从事的 ARM 编程超出 Intel® 处理器编程,另一种方法是将符号链接添加到您的 /usr/local/bin 目录,它引用工具链 bin 目录中的工具。通过这种方式,您可以使用快捷方式(比如 as)交互地运行 arm-none-linux-gnueabi-as 命令。清单 2 给出了如何设置这些符号链接的示例。

 

清单 2. 设置引用 ARM 工具的符号链接

 # cd /usr/local/bin# which arm-none-linux-gnueabi-as/home/bzimmerly/Sourcery_G++_Lite/bin/arm-none-linux-gnueabi-as# ln -s /home/bzimmerly/Sourcery_G++_Lite/bin/arm-none-linux-gnueabi-as as# ls -l aslrwxrwxrwx 1 bzimmerly bzimmerly 76 2009-03-13 02:48 as -> /home/bzimmerly/Sourcery_G++_Lite/bin/arm-none-linux-gnueabi-as# ./as --versionGNU assembler (Sourcery G++ Lite 2008q1-126) 2.18.50.20080215Copyright 2007 Free Software Foundation, Inc.This program is free software; you may redistribute it under the terms ofthe GNU General Public License version 3 or later.This program has absolutely no warranty.This assembler was configured for a target of `arm-none-linux-gnueabi'.#

使用 which 命令查找该命令的完整路径名,这样方便将其复制粘贴到 ln 命令。然后,使用 ln -s 命令创建符号链接。完成之后,列出符号链接并运行它,核实是否已经成功创建。通过创建引用 GNU 工具链 bin 目录中的所有工具的简单符号链接,您就不需要输入冗长的名字了。当然,每次运行汇编程序时,输入 as 总比输入 arm-none-linux-gnueabi-as 容易!

为 ARM 架构编写程序
有许多关于用流行的 C 语言编写 ARM 程序的指南,但关于用汇编语言编写的指南却很少。在本文,我打算打破传统,用汇编语言编写程序 —— 这通常被认为是编程的 “邪端”。这是一个简单的 “Hello World” 类型的程序,其目标是针对特定的 ARM Linux 版本。

本文描述的示例程序被设计为运行在运行 Android Linux 的 T-Mobile G1 移动电话上。它是用通用的方式编写的,因此也可以运行在其他基于 ARM 的 Linux 平台上(仅进行标准的系统调用)。然而,您至少要使用 2.6.16 版本的 Linux 内核,它允许您使用新的 Embedded Application Binary Interface (EABI) 内核系统调用。
注意:要阅读有关为硬件进行 ARM 编程而不是在 Linux 下进行编程的文章,请查看 参考资料 小节提供的 Embedded.com 文章链接。
使用您最喜欢的编辑器,通过清单 3 中的代码创建一个称为 build 的脚本。这个脚本运行 GNU ARM 汇编程序,其后是一个连接器(linker)。创建这个程序的目的是实现一个非常小的可执行程序,所以我使用连接器开关 --strip-all 去除所有调试信息。创建该脚本之后,发出 chmod +x build 命令让它变成可执行脚本。

 

清单 3. 构建 ARM Linux Hello World 应用程序

#!/bin/bashecho Building the ARM Linux Hello World...arm-none-linux-gnueabi-as -alh -o hw.o hw.S > hw.lstarm-none-linux-gnueabi-ld --strip-all -o hw hw.o
接下来,创建名为 hw.S 的源模块,并将清单 4 中的代码添加到其中。

 

清单 4. ARM Linux Hello World
                                @filename: hw.S.text.align 2.global _start@ ssize_t sys_write(unsigned int fd, const char * buf, size_t count)@         r7                 r0      r1                r2_start:    adr     r1, msg         @ Address    mov     r0, #1          @ STDOUT    mov     r2, #16         @ Length    mov     r7, #4          @ sys_write    svc     0x00000000@ int sys_exit(int status)@     r7       r0    mov     r0, #0          @ Return code    mov     r7, #1          @ sys_exit    svc     0x00000000.align 2msg:    .asciz "Hello Android!/n/n"


在 GNU 汇编语言的语法中,“at” 符号 (@) 用于指定行注释。汇编语言忽略 @ 之后的任何内容,直至行末。

这个程序使用两个标准的 Linux 系统调用:sys_write 和 sys_exit。在这两个调用中,以上的汇编语言代码等效于 C 语言的注释形式。这样可以更加容易看到 ARM 寄存器如何恰当地映射到系统调用使用的调用参数。需要记住一个规则,参数是自左至右的,从 r0 到 r6。寄存器 r7 很特别,因为它存储使用的系统调用号码。

svc 0x00000000 指令告诉 ARM 处理器调用 “超级用户”,在本例中是 Linux 内核。


测试 ARM 程序

这个工具链为调试底层程序提供流行的 GDB。当程序的运行目标是带有 JTAT 或 ICE 单元的单板计算机时,您可以使用 Sourcery G++ Lite 调试器 (gdb) 远程调试 ARM 代码。

如果您希望像我一样测试代码 —— 在运行在移动电话上的 Android Linux 系统上 —— 您需要使用配套的 USB 连接线将电话连接到工作站,然后使用 Android 软件开发工具箱的 adb push 命令将该程序转移到移动电话中。在移动电话上,在一个包含可执行代码 (/data/local/bin) 的目录中,通过发出 chmod 555 hw 命令让程序变得可执行。(Android 上的 chmod 命令不使用 +x,所以 555 是必要的)。

最后,使用 adb shell 命令连接到电话,并使用 cd 切换到正确的目录,然后使用 ./hw 运行它。如果一切按计划进行,程序的响应应该和在我手机上的响应一样,会出现问候语 “Hello Android!”。

 


3. Android Linux kernel 编译环境

 

a)准备交叉编译工具链
android代码树中有一个prebuilt项目,包含了我们编译内核所需的交叉编译工具。
注意:虽然Prebuilt下包含了交叉编译工具,但是编译时有可能会出现“/bin/sh: arm-eabi-gcc: not found”
这样的错误,因此最好从CodeSourcery上面载用于交叉编译的工具链:
http://www.codesourcery.com/gnu_toolchains/arm/download.html

选择   EABI

 

解压缩交叉编译工具链:
 $ cd /usr/local/
 $ sudo cp
~/arm-2010q1-202-arm-none-linux-gnueabi-i686-pc-linux-gnu.tar.bz2
 $ sudo tar jxvf arm-2010q1-202-arm-none-linux-gnueabi-i686-pc-linux-gnu.tar.bz2
此时会解压出来一个叫做arm-2010q1的一个目录,这里面就是工具链了。

 

设置一下环境变量:
 $ export PATH=$PATH:/usr/local/arm2007q3/bin
好了,到此,基本的内核编译环境就搞好了。

 

b)设定环境变量

$ emacs ~/.bashrc
增加如下两行:
export
PATH=$PATH:~/android/prebuilt/linux-x86/toolchain/arm-eabi-4.4.0/bin
export ARCH=arm
保存后,同步变化:
$ source ~/.bashrc

 

c)获得合适的内核源代码
$ cd ~/android
获得内核源代码仓库
$ git clone git://android.git.kernel.org/kernel/common.git   kernel
$ cd kernel
$ git branch

 

显示
* android-2.6.27
说明你现在在android- 2.6.27这个分支上,也是kernel/common.git的默认主分支。
显示所有head分支:
$ git branch -a
显示
* android-2.6.27
remotes/origin/HEAD -> origin/android-2.6.27
remotes/origin/android-2.6.25
remotes/origin/android-2.6.27
remotes/origin/android-2.6.29
remotes/origin/android-goldfish-2.6.27
remotes/origin/android-goldfish-2.6.29
我们选取最新的android-goldfish-2.6.29,其中goldfish是 android的模拟器模拟的CPU。
$ git checkout -b android-goldfish-2.6.29 origin/android-goldfish-2.6.29
$ git branch
显示
android-2.6.27
* android-goldfish-2.6.29
我们已经工作在android-goldfish-2.6.29分支上了。

 

d)设定交叉编译参数
打开kernel目录下的Makefile文件,
1. ARCH        ?= $(SUBARCH) 改为: ARCH        ?= arm
2. 把CROSS_COMPILE指向刚才下载的prebuilt中的arm-eabi编译器
CROSS_COMPILE ?= arm-eabi-
注意:如果是按照上述方法重新下载的交叉编译工具则按照下面方法修改
CROSS_COMPILE ?= arm-none-linux-gnueabi-
这个就是刚刚的下载和解压的工具链的前缀了,旨在告诉make,在编译的时候要使用我们的工具链。
3. 把LDFLAGS_BUILD_ID = $(patsubst -Wl$(comma)%,%,/
$(call ld-option, -Wl$(comma)–build-id,))
这一行注释掉,并且添加一个空的LDFLAGS_BUILD_ID定义,如下:
LDFLAGS_BUILD_ID =
把它注释掉的原因是目前android的内核还不支持这个选项。--build-id选项,主要是用于在生成的elf
可执行文件中加入一个内置的id,这样在core dump,或者debuginfo的时候就可以很快定位这个模块是
哪次build的时候弄出来的。这样就可以避免,每次都把整个文件做一遍效验,然后才能得到该文件的是由
哪次build产生的。对于内核开发者来说,这是很不错的想法,可以节约定位模块版本和其影响的时间。
目前,该功能还出于early stage的状态,未来的android或许会支持,但至少目前的版本是不支持的。
所以,用#注释掉即可,或者害怕不保险的话,就加入LDFLAGS_BUILD_ID=空,这样即使编译的时候用了,
也只是一个空格而已。

e)编译内核映像
$ cd ~/android/kernel
$ make goldfish_defconfig
$ make


f)测试生成的内核映像
$ emulator -avd myavd -kernel ~/android/kernel/arch/arm/boot/zImage

 

 

 


4.google android内核编译方法

 

google的android很多人都希望在gphone没有出来之前,把它移植到相关的硬件平台上去。网上看了不少文章,总的感觉是:在这一步走得最远的就是openmoko的一个大师级别的黑客Ben “Benno” Leslie,他曾经试图把目前google发布的android移植到openmoko的平台上去,并且做了10000多行代码的尝试。最终虽然由于open moko采用比较老的arm 920t的内核,而android采用较新的arm926-ej-s内核,而且使用了新的内核的一些新特性,导致移植失败,但是anyway,他已经做了足够多的前期工作了,尔后的宣布成功移植android到real target板子上的人,大多是在他提供的patch的基础上继续走下去做出来的。

 下面是一些有用的参考,希望有助于对此感兴趣的开发人员:

(1)Ben “Benno” Leslie的关于andorid移植到openmoko的个人博客地址:
http://benno.id.au/blog/

(2)早期宣布成功移植android到zauraus-sl-c760的详细方法描述的链接:
http://euedge.com/blog/2007/12/06/google-android-runs-on-sharp-zaurus-sl-c760/

(3)后续的根据上述先行者们的工作,成功移植android到zauraus-c3000的方法:
http://androidzaurus.seesaa.net/article/74237419.html

(4)本文是参考下面的wiki,接合个人的实践写出来的,对原文的作者表示一下感谢:
http://wiki.droiddocs.net/Compilation_of_Android_kernel

很羡慕这些人阿!

不过很可惜,偶的开发板是s3c2410的,恰好是arm920t的核心的。。。估计移植上去戏不是很大,需要重写很多代码,毕竟偶跟benno相差得太远太远了,同样是开发人员,差距咋就那么大呢?!

(毕竟google仅仅开放了kernel的源代码而已,他们需要开放的东西还很多。)

在这里把关于android内核编译方法简单写一下,或许对希望移植内核的朋友能有些帮助:

(看了Benno的移植过程以后,觉得即使你能够编译google开放出来的内核,意义也不是特别大,因为这个内核中加入了为了支持qemu的很多东西,而这些代码似乎对希望移植到真机上的朋友来说,没有任何意义,反而是一种阻碍)。

1)从CodeSourcery上面载用于交叉编译的工具链:
http://www.codesourcery.com/gnu_toolchains/arm/download.html

我在这里选择的是->ARM GNU/Linux,以及IA32-GNU/Linux。有文章说应该选择ARM EABI,我不知道了,没有测试过,反正我选择的这个编译的内核也是可以跑起来的:P

2)下载google的android linux的内核源代码:
http://code.google.com/p/android/downloads/list

主要是这个文件:linux-2.6.23-android-m3-rc20.tar.gz

3)把下载到的内核和交叉编译工具解压缩,并最好把工具链的路径放到PATH里面去

解压缩内核: $ mkdir -p android $ cd android $ tar xzvf ../linux-2.6.23-android-m3-rc20.tar.gz 会解压出来一个叫做kernel的目录,google的android的linux内核就在里面了。解压缩交叉编译工具链: $ cd /usr/local/ $ sudo cp ~/arm-2007q3-51-arm-none-linux-gnueabi-i686-pc-linux-gnu.tar.bz2 . $ sudo tar zxvf arm-2007q3-51-arm-none-linux-gnueabi-i686-pc-linux-gnu.tar.bz2此时会解压出来一个叫做arm2007q3的一个目录,这里面就是工具链了。设置一下环境变量: $ export PATH=$PATH:/usr/local/arm2007q3/bin好了,到此,基本的内核编译环境就搞好了。4)现在是要得到android的内核编译参数的配置文件的时候了,该文件需要从已经安装好的android的模拟器中得到才行。所以安装android的sdk也是必须的,这一步不太明白的朋友可以参考我以前发的android命令行体验的文章。首先启动android模拟器,然后通过adb得到模拟器中提供的内核配置文件: $emulator & $adb pull /proc/config.gz .这时候adb工具会连接模拟器,并从它里面下载一个叫做config.gz的文件到你的当前目录下。把它拷贝到你的kernel目录: $cd ~/android/kernel $cp ~/config.gz . 解压缩该文件,并重命名为.config,这一步做了就可以跳过make menuconfig之类的内核参数设置动作了。 $gunzip config.gz $mv config .config5)修改kernel目录中的Makefile文件,用emacs或vi打开该Makefile修改CROSS_COMPILE变量为:CROSS_COMPILE=arm-none-linux-gnueabi-这个就是刚刚的下载和解压的工具链的前缀了,旨在告诉make,在编译的时候要使用我们的工具链。在Makefile中注释掉LDFLAGS_BUILD_ID这个变量:例如将如下定义:LDFLAGS_BUILD_ID = $(patsubst -Wl$(comma)%,%,/          $(call ld-option, -Wl$(comma)--build-id,))修改为:LDFLAGS_BUILD_ID=#LDFLAGS_BUILD_ID = $(patsubst -Wl$(comma)%,%,/#          $(call ld-option, -Wl$(comma)--build-id,))把它注释掉的原因是目前android的内核还不支持这个选项。--build-id选项,主要是用于在生成的elf可执行文件中加入一个内置的id,这样在core dump,或者debuginfo的时候就可以很快定位这个模块是哪次build的时候弄出来的。这样就可以避免,每次都把整个文件做一遍效验,然后才能得到该文件的是由哪次build产生的。对于内核开发者来说,这是很不错的想法,可以节约定位模块版本和其影响的时间。目前,该功能还出于early stage的状态,未来的android或许会支持,但至少目前的版本是不支持的。所以,用#注释掉即可,或者害怕不保险的话,就加入LDFLAGS_BUILD_ID=空,这样即使编译的时候用了,也只是一个空格而已。对这个--build-id选项感兴趣的朋友,可以访问下面的网址,它的作者已经解释得非常明白了:http://fedoraproject.org/wiki/Releases/FeatureBuildId6)终于可以开始make了。 $ make不出意外的话,应该整个过程都会非常顺利,最终会在~/android/kernel/arch/arm/boot目录下面生成一个zImage,这个就是我们要的内核映像了。7)激动人心的时刻终于到来了,我们可以测试一下刚刚编译出来的内核可以不可以用了。 $emulator -kernel ~/android/kernel/arch/arm/boot/zImage当看到red eye在晃来晃去,最终显示出来android的界面的时候,一颗悬着的心总算放下了。android的proc里面的version如下:# cat versionLinux version 2.6.23 (wayne@wayne) (gcc version 4.2.1 (CodeSourcery Sourcery G++ Lite 2007q3-51)) #1 Sat Jan 19 18:11:44 HKT 2008

从这里就可以看出,这是自己编译的kernel,而不是人家sdk里面自带的kernel-qemu了。

android自带的sdk里面的kernel映像的version应该是:

# cat version

Linux version 2.6.23-gcc3bc3b4 (arve@arvelnx.corp.google.com) (gcc version 4.2.1) #3 Tue Oct 30 16:28:18 PDT 2007

hoho, 这里不会把这个开发者的email暴露出来了吧。。。

android的cpuinfo如下:

Processor : ARM926EJ-S rev 5 (v5l)

BogoMIPS : 313.75

Features : swp half thumb fastmult vfp edsp java

CPU implementer : 0x41

CPU architecture: 5TEJ

CPU variant : 0x0

CPU part : 0x926

CPU revision : 5

Cache type : write-through

Cache clean : not required

Cache lockdown : not supported

Cache format : Harvard

I size : 4096

I assoc : 4

I line length : 32

I sets : 32

D size : 65536

D assoc : 4

D line length : 32

D sets : 512

Hardware : Goldfish

Revision : 0000

Serial : 0000000000000000

 

 

 

 

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值