Chinaunix首页 | 论坛 | 博客
  • 博客访问: 100849
  • 博文数量: 65
  • 博客积分: 2520
  • 博客等级: 少校
  • 技术积分: 680
  • 用 户 组: 普通用户
  • 注册时间: 2010-05-22 15:10
文章分类

全部博文(65)

文章存档

2011年(1)

2010年(64)

我的朋友
最近访客

分类: 嵌入式

2010-06-18 18:48:41

1  设置环境变量,准备源码及相关补丁

1.1 设置环境变量

[arm@localhost arm]#vi ~/.bashrc

export PREFIX=/usr/local/arm/3.4.4

export TARGET=arm-linux

export SYSROOT=${PREFIX}/sysroot

export ARCH=arm

export CROSS_COMPILE=${TARGET}-

export PATH=${PREFIX}/bin:$PATH

export SRC=/home/arm/dev_home/btools/tchain3.4.4

1. 2 准备源码包

1.2.1 binuils

   名称:binutils-2.16.tar.gz
   下载地址:
1.2.2 gcc
   名称:gcc-3.4.4.tar.bz2
   下载地址:
1.2.3 glibc
   名称:glibc-2.3.5.tar.gz
         glibc-linuxthreads-2.3.5.tar.gz
   下载地址: 
            

1.2.4 linux kernel
   名称:linux-2.6.14.1.tar.gz
   下载地址:
1.3 准备补丁
1.3.1 ioperm.c.diff
   作用:打修正ioperm()函数.
   下载地址:~coldwell/toolchain/ioperm.c.diff
1.3.2 flow.c.diff
   作用:该补丁用于产生crti.o 和crtn.o 文件。
   下载地址:
branch&r1=1.563.4.2&r2=1.563.4.3
1.3.3 t-linux.diff
   作用:修改gcc 一处bug
   下载地址:~coldwell/toolchain/t-linux.diff
1.4    编译 GNU binutils
重新以arm 用户登陆,让新设置的环境变量起作用.
[arm@localhost arm]#su arm

[arm@localhost arm]#cd ${SRC}

[arm@localhost tchain3.4.4]#tar xzvf binutils-2.16.tar.gz

[arm@localhost tchain3.4.4]#mkdir -p BUILD/binutils-2.16

[arm@localhost binutils-2.16]#cd BUILD/binutils-2.16

[arm@localhost binutils-2.16]# ../../binutils-2.16/configure --prefix=${PREFIX} --target=${TARGET} \

--with-sysroot=${SYSROOT}

[arm@localhost binutils-2.16]#make

[arm@localhost binutils-2.16]#su root

[root@localhost binutils-2.16]#make install

[root@localhost binutils-2.16]#exit

[arm@localhost binutils-2.16]#

1.5 准备内核头文件
1.5.1 使用当前平台的gcc编译内核头文件

[arm@localhost tchain3.4.4]#cd ${KERNEL}

[arm@localhost kernel]#tar xvfz linux-2.6.14.1.tar.gz

[arm@localhost kernel]#cd  linux-2.6.14.1

[arm@localhost linux-2.6.14.1]#make ARCH=arm menuconfig

[arm@localhost linux-2.6.14.1]#make
1.5.2 复制内核头文件
[arm@localhost kernel]#su root

[root@localhost kernel]#mkdir -p ${SYSROOT}/usr/include

[root@localhost kernel]#cp -a include/linux ${SYSROOT}/usr/include/linux

[root@localhost kernel]#cp -a include/asm-i386 ${SYSROOT}/usr/include/asm

[root@localhost kernel]#cp -a include/asm-generic ${SYSROOT}/usr/include/asm-generic

[root@localhost kernel]#exit

[arm@localhost kernel]#

1.6     译编glibc 头文件

[arm@localhost kernel]#cd ${SRC}

[arm@localhost chain3.4.4]#tar xvfz glibc-2.3.5.tar.gz

[arm@localhost chain3.4.4]#patch -d glibc-2.3.5 -p1 < ioperm.c.diff

[arm@localhost glibc-2.3.5]#cd glibc-2.3.5

[arm@localhost glibc-2.3.5]#tar xvfz ../glibc-linuxthreads-2.3.5.tar.gz

[arm@localhost chain3.4.4]#cd ..

[arm@localhost chain3.4.4]#mkdir BUILD/glibc-2.3.5-headers

[arm@localhost chain3.4.4]#cd BUILD/glibc-2.3.5-headers

[arm@localhost glibc-2.3.5-headers]#../../glibc-2.3.5/configure --prefix=/usr --host=${TARGET} \

--enable-add-ons=linuxthreads –with-headers=${SYSROOT}/usr/include

[arm@localhost glibc-2.3.5-headers]#su root

[root@localhost glibc-2.3.5-headers]#make cross-compiling=yes install_root=${SYSROOT} install-headers

[root@localhost glibc-2.3.5-headers]#touch ${SYSROOT}/usr/include/gnu/stubs.h

[root@localhost glibc-2.3.5-headers]#touch ${SYSROOT}/usr/include/bits/stdio_lim.h

[root@localhost glibc-2.3.5-headers]#exit

[arm@localhost glibc-2.3.5-headers]#

注意: --prefix=/usr :是gcc 寻找库的搜索路径。
1.7     编译gcc 第一阶段

[arm@localhost glibc-2.3.5-headers]#cd ${SRC}

[arm@localhost chain3.4.4]#tar xjvf gcc-3.4.4.tar.bz2

[arm@localhost chain3.4.4]#patch -d gcc-3.4.4 -p1 < flow.c.diff

[arm@localhost chain3.4.4]#patch -d gcc-3.4.4 -p1 < t-linux.diff

[arm@localhost chain3.4.4]#mkdir -p BUILD/gcc-3.4.4-stage1

[arm@localhost chain3.4.4]#cd BUILD/gcc-3.4.4-stage1

[arm@localhost gcc-3.4.4-stage1]#../../gcc-3.4.4/configure --prefix=${PREFIX} --target=${TARGET} \

--enable-languages=c --with-sysroot=${SYSROOT}

    注意:不能加上"--disable-shared"选项。

[arm@localhost gcc-3.4.4-stage1]#make all-gcc

[arm@localhost gcc-3.4.4-stage1]#su root

[root@localhost gcc-3.4.4-stage1]#make install-gcc

[root@localhost gcc-3.4.4-stage1]#exit

[arm@localhost gcc-3.4.4-stage1]#



1.8     编译完整的glibc



[arm@localhost gcc-3.4.4-stage1] #cd ${SRC}

[arm@localhost tchain3.4.4]#mkdir BUILD/glibc-2.3.5

[arm@localhost tchain3.4.4]#cd BUILD/glibc-2.3.5

[arm@localhost glibc-2.3.5]#BUILD_CC=gcc CC=${CROSS_COMPILE}gcc AR=${CROSS_COMPILE}ar \

RANLIB=${CROSS_COMPILE}ranlib AS=${CROSS_COMPILE}as LD=${CROSS_COMPILE}ld \

../../glibc-2.3.5/configure --prefix=/usr --build=i386-redhat-linux --host=arm-unknown-linux-gnu \

--target=arm-unknown-linux-gnu --without-__thread --enable-add-ons=linuxthreads \

--with-headers=${SYSROOT}/usr/include

说明:   

  --prefix:            指定安装路径。

  --target:            指定目标平台。

  --host:              指定当前平台。

  --build:             指定编译平台。

  --with-sysroot:      用于指定编译所需要的头文件,及链接库。

  --enable-add-ons:    加入其它的库,如线程库等。

  --enable-languages:  指定gcc 所支持的语言。



[arm@localhost glibc-2.3.5]#make

[arm@localhost glibc-2.3.5]#su root

[root@localhost glibc-2.3.5]#make install_root=${SYSROOT} install

[root@localhost glibc-2.3.5]#exit

[arm@localhost glibc-2.3.5]#



1.9  编译完整的gcc



[arm@localhost glibc-2.3.5]#cd ${SRC}

[arm@localhost tchain3.4.4]#mkdir BUILD/gcc-3.4.4

[arm@localhost tchain3.4.4]#cd BUILD/gcc-3.4.4

[arm@localhost gcc-3.4.4]#../../gcc-3.4.4/configure --prefix=${PREFIX} --target=${TARGET} \

--enable-languages=c --with-sysroot=${SYSROOT}

[arm@localhost gcc-3.4.4]#make

[arm@localhost gcc-3.4.4]#su root

[root@localhost gcc-3.4.4]#make install

[root@localhost gcc-3.4.4]#exit

[arm@localhost gcc-3.4.4]#



2 GNU交叉工具链的下载



2.1 ARM 官方网站



   工具链的官方下载地址:

       

   可以从该站点下载2.95.3, 3.0 以及3.2 工具链

       ftp://ftp.arm.linux.org.uk/pub/armlinux/toolchain/cross-2.95.3.tar.bz2

       ftp://ftp.arm.linux.org.uk/pub/armlinux/toolchain/cross-3.0.tar.bz2

        ftp://ftp.arm.linux.org.uk/pub/armlinux/toolchain/cross-3.2.tar.bz2



3 GNU 交叉工具链的介绍与使用



3.1 常用工具介绍



        名称              归属                                        作用



 arm-linux-as        binutils    编译ARM 汇编程序



 arm-linux-ar        binutils    把多个.o 合并成一个.o 或静态库(.a)



 arm-linux-ranlib    binutils    为库文件建立索引,相当于arm-linux-ar -s



 arm-linux-ld        binutils    连接器(Linker), 把多个.o 或库文件连接成一个可执行文件

         名称               归属                                             作用



 arm-linux-objdump     binutils     查看目标文件(.o)和库(.a)的信息



 arm-linux-objcopy     binutils     转换可执行文件的格式



 arm-linux-strip       binutils     去掉elf 可执行文件的信息. 使可执行文件变小



 arm-linux-readelf     binutils     读elf 可执行文件的信息



 arm-linux-gcc         gcc          编译.c 或.S 开头的C 程序或汇编程序



 arm-linux-g++         gcc          编译c++程序



3.2 主要工具的使用



3.2.1 arm-linux-gcc 的使用



1. 编译C 文件,生成elf 可执行文件

h1.c 源文件  

#include

void hellofirst(void)

{

        printf("The first hello! \n");

}



h2.c 源文件

#include

void hellosecond(void)

{

        printf("The second hello! \n");

}



hello.c 源文件

#include

void hellosecond(void);

void hellofirst(void);



int main(int argc, char *argv[])

{

        hellofirst();

        hellosecond();

        return(0);

}

编译以上3 个文件,有如下几种方法:

方法 1:

[arm@localhost gcc]#arm-linux-gcc -c h1.c

[arm@localhost gcc]#arm-linux-gcc -c h2.c

[arm@localhost gcc]#arm-linux-gcc -o hello hello.c h1.o h2.o

方法2:

[arm@localhost gcc]#arm-linux-gcc -c h1.c h2.c

[arm@localhost gcc]#arm-linux-gcc -o hello hello.c h1.o h2.o

方法3:

[arm@localhost gcc]#arm-linux-gcc -c -o h1.o h1.c

[arm@localhost gcc]#arm-linux-gcc -c -o h1.o h1.c

[arm@localhost gcc]#arm-linux-gcc -o hello hello.c h1.o h2.o

方法4:

[arm@localhost gcc]#arm-linux-gcc -o hello hello.c h1.c h2.c

-c: 只编译不连接。

-o: 编译且连接。



2. 产生一个预处理文件

  当要看一个宏在源文件中产生的结果时,比较合适。

[arm@localhost gcc]#arm-linux-gcc -E h1.i h1.c

-E: 产生一个预处理文件.



3. 产生一个动态库

动态库是在运行时需要的库。

[arm@localhost gcc]#arm-linux-gcc -c -fpic h1.c h2.c

[arm@localhost gcc]#arm-linux-gcc -shared h1.o h2.o -o hello.so

[arm@localhost gcc]#arm-linux-gcc -o hello hello.c hello.so

把hello.so 拷贝到目标板的/lib  目录下,把可执行文件拷贝目标板的/tmp  目录下,在目标板上运                               hello.

#/tmp/hello

或把hello.so 和hello 一起拷贝到/tmp  目标下,并设置LD_LIBRARY_PATH 环境变量

#export LD_LIBRARY_PATH =/tmp:$LD_LIBRARY_PATH

#/tmp/hello



3.2.2 arm-linux-ar 和 arm-linux-ranlib 的使用



静态库是在编译时需要的库。

1. 建立一个静态库

[arm@localhost gcc]#arm-linux-ar -r libhello.a h1.o h2.o



2. 为静态库建立索引

[arm@localhost gcc]#arm-linux-ar -s libhello.a

[arm@localhost gcc]#arm-linux-ranlib libhello.a



3. 由静态库产生可执行文件

[arm@localhost gcc]#arm-linux-gcc -o hello hello.c -lhello -L./

[arm@localhost gcc]#arm-linux-gcc -o hello hello.c libhello.a

hello 文件可以直接拷贝到/tmp  目录下运行,不需libhello.a.



3.2.3 arm-linux-obj dump 的使用



1. 查看静态库或.o 文件的组成文件

[arm@localhost gcc]$ arm-linux-objdump -a libhello.a



2. 查看静态库或.o 文件的络组成部分的头部分

[arm@localhost gcc]$ arm-linux-objdump -h libhello.a



3. 把目标文件代码反汇编

[arm@localhost gcc]$ arm-linux-objdump -d libhello.a



3.2.4 arm-linux-readelf 的使用



1. 读elf 文件开始的文件头部


[arm@localhost gcc]$ arm-linux-readelf -h hello

ELF Header:

  Magic:       7f 45 4c 46 01 01 01 61 00 00 00 00 00 00 00 00

  Class:                                 ELF32

  Data:                                  2's complement, little endian

  Version:                              1 (current)

  OS/ABI:                               ARM

  ABI Version:                           0

  Type:                                  EXEC (Executable file)

  Machine:                               ARM

  Version:                               0x1

  Entry point address:                   0x82b4

  Start of program headers:              52 (bytes into file)

  Start of section headers:              10240 (bytes into file)

  Flags:                                 0x2, has entry point

  Size of this header:                   52 (bytes)

  Size of program headers:               32 (bytes)

  Number of program headers: 6

  Size of section headers:                40 (bytes)

  Number of section headers:              28

  Section header string table index: 25



2. 读elf 文件中所有ELF 的头部:

[arm@localhost gcc]#arm-linux-readelf -e hello

......



3. 显示整个文件的符号表

[arm@localhost gcc]#arm-linux-readelf -s hello

......



4. 显示使用的动态库

[arm@localhost gcc]#arm-linux-readelf -d hello

......



3.2.5 arm-linux-strip 的使用

1. 移除所有的符号信息

[arm@localhost gcc]#cp hello hello1

[arm@localhost gcc]#arm-linux-strip -strip-all hello

--strip-all: 是移除所有符号信息

[arm@localhost gcc]#ll

-rwxr-xr-x     1 arm root  2856        7 月  3 15:14 hello

-rwxr-xr-x     1 arm root 13682        7 月  3 15:13 hello1

被strip 后的hello 程序比原来的hello1 程序要小很多。



2. 移除调试符号信息

[arm@localhost gcc]#arm-linux-strip -g hello

[arm@localhost gcc]#ll

-rwxr-xr-x     1 arm root  4501        7 月  3 15:17 hello

-rwxr-xr-x     1 arm root 13682        7 月  3 15:13 hello1


3.2.6 arm-linux-copydump 的使用



生成可以执行的2 进制代码

[arm@localhost gcc]#arm-linux-copydump -O binary hello hello.bin



4 ARM GNU常用汇编语言介绍



4.1 ARM GNU 常用汇编伪指令介绍



1. abort

.abort: 停止汇编

.align abs-expr1, abs-expr2: 以某种对齐方式,在未使用的存储区域填充值. 第一个值表示对齐方式,4, 8,16 或32. 第

二个表达式值表示填充的值.

2. if...else...endif

.if

.else

.endif: 支持条件预编译

3. include

.include "file": 包含指定的头文件, 可以把一个汇编常量定义放在头文件中.

4. comm

.comm symbol, length:在bss 段申请一段命名空间,该段空间的名称叫symbol, 长度为length.                               Ld 连接器在连接会

为它留出空间.

5. data

.data subsection: 说明接下来的定义归属于subsection 数据段.

6. equ

.equ symbol, expression: 把某一个符号(symbol)定义成某一个值(expression).该指令并不分配空间.

7. global

.global symbol: 定义一个全局符号, 通常是为ld 使用.

8. ascii

.ascii "string": 定义一个字符串并为之分配空间.

9. byte

.byte expressions: 定义一个字节, 并为之分配空间.

10. short

.short expressions: 定义一个短整型,  并为之分配空间.

11. int

.int expressions: 定义一个整型,并为之分配空间.

12 long

.long expressions: 定义一个长整型, 并为之分配空间.

13 word

.word expressions: 定义一个字,并为之分配空间, 4bytes.

14. macro/endm

.macro: 定义一段宏代码, .macro 表示代码的开始, .endm 表示代码的结束.

15. req

name .req register name:  为寄存器定义一个别名.

16. code

.code [16|32]: 指定指令代码产生的长度, 16 表示Thumb 指令, 32 表示ARM 指令.

17. ltorg

.ltorg: 表示当前  下的定义在归于当前段,并为之分配空间.

4.2 ARM GNU 专有符号



1. @

表示注释从当前位置到                                尾的字符.

2. #

注释掉一整                  .

3. ;

新行分隔符.



4.3 操作码



1. NOP

   nop

   空操作, 相当于MOV r0, r0

2. LDR

      ldr , =

   相当于PC 寄存器或其它寄存器的长转移.



3.ADR

      adr

}



阅读(1019) | 评论(0) | 转发(1) |
给主人留下些什么吧!~~