Ubuntu12.04下建立交叉編譯環境、使用QEMU模擬Cortex-A9、QEMU運行uboot


一. 基礎環境

0. 安裝virtualbox

 下載最新virtualbox (4.2),安裝

1. 安裝ubuntu12.04

 下載ubuntu-12.04的dvd安裝iso,搜索下載

2. virtualbox安裝ubuntu時候,分配100G,的動態盤

3. 裝好ubuntu后, 安裝virtualbox增強功能,重啟

4. 設置共享文件夾,自動掛載+固定分配,重啟

5. sudo adduser xxx vboxsf,設置了用戶加到vboxsf組,獲取權限,重啟

6.  修改ubuntu源,網易很給力:

 

deb http://mirrors.163.com/ubuntu/ precise main restricted
deb http://mirrors.163.com/ubuntu/ precise-updates main restricted
deb http://mirrors.163.com/ubuntu/ precise universe
deb http://mirrors.163.com/ubuntu/ precise-updates universe
deb http://mirrors.163.com/ubuntu/ precise multiverse
deb http://mirrors.163.com/ubuntu/ precise-updates multiverse
deb http://mirrors.163.com/ubuntu/ precise-backports main restricted universe multiverse
deb http://mirrors.163.com/ubuntu/ precise-security main restricted
deb http://mirrors.163.com/ubuntu/ precise-security universe
deb http://mirrors.163.com/ubuntu/ precise-security multiverse
sudo apt-get update

 

 

二. 安裝交叉工具鏈

 

  1. sudo apt-get insatll gcc-arm-linux-gnueabi
  2. sudo apt-get insatll g++-arm-linux-gnueabi

注意:此處arm-linux-gnueabi-gdb沒有被安裝,可以自己編譯一個:

 

(1) 搜索下載 gdb-7.4.1.tar.bz2

(2) 安裝 

sudo apt-get install libncurses5-dev
termcap庫在這里

 

(3) 解壓配置

 

./configure --target=arm-linux-gnueabi
(4) 安裝

 

默認地址 /usr/local

sudo make install

(5) sudo ldconfig系統配置生效

(6) 可以使用了


 

 

三. 安裝Qemu

 

sudo apt-get install qemu qemu-system qemu-utils

 

 

四.  下載u-boot

www.denx.de是uboot的官網,denx軟件和硬件都有,工具鏈eldk也很好用,可以用eldk的工具鏈編譯,ftp下載時候,使用http方式的,不要使用ftp方式,可能看不見東西.

 

http://ftp.denx.de/pub/eldk/ - 工具鏈地址

 

http://ftp.denx.de/pub/u-boot/ - uboot地址

 

http://ftp.denx.de/pub/u-boot/u-boot-2012.04.tar.bz2 下載這個

 

五. 編譯uboot

編譯uboot需要確定板子,板子和cpu、soc等是密切相關的,看uboot源碼根目錄下的boards.cfg,可以知道所有支持的板子名字,對應的架構,cpu,廠商等,

因為我們要使用Qemu來模擬這個板子,所以要找到一個Qemu和uboot同時支持的板子,同時還是cortex-a9架構核心的.

boards.cfg中有一行:

 

 ca9x4_ct_vxp                 arm         armv7       vexpress            armltd

 

vexpress 是板子名,arm是架構arch,armv7是cpu,實際也是架構,armltd是廠商vendar
ca9x4_ct_vxp 是配置名。

同時,使用qemu-system-arm -M ?命令,能看到支持的板子列表,其中包括:

 

vexpress-a9          ARM Versatile Express for Cortex-A9 

就是說vexpress 這個板子,在uboot和qemu中,同時支持,且是cortex-a9的.

(1) export ARCH=arm

(2) export CROSS_COMPILE=arm-linux-gnueabi-

(3) make ca9x4_ct_vxp_config

(4) make

編譯成功后,源碼根目錄下出現 u-boot u-boot.bin等文件.

 

六. 運行

  1. qemu-system-arm -M vexpress-a9 -m 256M -nographic -kernel u-boot  此命令沒有圖形只有命令行輸出
  2. 或者
    1. qemu-system-arm -M vexpress-a9 -m 256M -serial stdio -kernel u-boot 此命令包括圖形和命令行輸出

    可以gdb調試:

    注意

    (1)  gdb調試

    qemu-system-arm -M vexpress-a9 -m 256M -kernel u-boot -S -s
    qemu-system-arm -m 256 -kernel u-boot -gdb tcp::1234 -S同一個意思

    -s 表示 -gdb tcp::1234

    -S 表示停下來,另一個終端可用arm-linux-gnueabi-gdb,啟動后用參數target remote tcp::1234連接

    當然,連接之前,需要用file 制定一個有符號的目標,比如u-boot .

    同時gdb的 directory命令可以制定源文件的搜索路徑.

     (2)  kernel 文件類型

     支持ld鏈接出來的elf文件,gdb調試端,需要用file加載相應的有調試信息符號的elf文件.

    七. 編譯運行linux內核

    1. 獲取內核

     

    ftp://ftp.kernel.org/pub/linux/kernel/v3.x/linux-3.8.tar.bz2
    2. 編譯

     

    export ARCH=arm

    export CROSS_COMPILE=arm-linux-gnueabi-

    make clean distclean

    make vexpress_defconfig

    make -j4

    3. 啟動

     

    qemu-system-arm -M vexpress-a9 -m 256M -kernel linux/linux-3.8/arch/arm/boot/zImage -append "console=tty0"

     

    八. 根文件系統

    1. busybox編譯

    (1) 下載源碼

    http://www.busybox.net/downloads/busybox-1.21.0.tar.bz2
    (2) 編譯

     

    export ARCH=arm

    export CROSS_COMPILE=arm-linux-gnueabi-

    make -j4

    make install

    (3) _install目錄就是所有的busybox編譯的結果

    2. 制作根文件系統目錄

    (0) 根目錄

    mkdir rootfs

    cd rootfs

    (1) 目錄結構

    mkdir bin etc dev lib proc tmp root home sys usr sbin var mnt

    (2) 運行庫-來自工具鏈

    cp -a /usr/arm-linux-gnueabi/lib/* lib

    (3) 配置文件-來自busybox

    cp -a <busybox_dir>/examples/bootfloppy/etc/* etc

    (4) busybox工具集

    cp -a <busybox_dir>/_install/* .

    (5) 設備文件

    sudo cp -a /dev/console /dev/loop0  /dev/loop1  /dev/null  /dev/ram0  /dev/tty  /dev/tty0  /dev/tty1  /dev/zero /dev

    (6) 修改mdev配置,mdev負責自動生成設備節點,mdev.conf是配置文件

    vi etc/mdev.conf

    1. controlC[0-9] 0:0 0660 =snd/
    2. pcm.* 0:0 0660 =snd/
    3. seq.* 0:0 0660 =snd/
    4. mix.* 0:0 0660 =snd/
    5. timer 0:0 0660 =snd/
    其他特殊要求的設備文件,同樣道理即可.

    (7) 修改啟動配置

    vi etc/init.d/rcS

    增加

     

    mount -n -t proc none /proc 

     

  3.  

    mount -n -t sysfs none /sys 

     

  4.  

    mdev -s 這句很重要,生成所有的設備節點

     

    如果用nfs的話,有了以上目錄就可以了

    3. 根文件系統鏡像

    dd if=/dev/zero of=rootfs.img bs=1M count=32 # 32M的鏡像

    mkfs.ext3 rootfs.img

    mkdir tmpfs

    sudo mount -o loop rootfs.img tmpfs

    sudo cp -a rootfs/* tmpfs/

    sudo umount tmpfs

     

    rootfs.img中就有了文件系統鏡像了,ext3格式.

    4. 文件系統鏡像啟動qemu - 此時不需要u-boot了,直接啟動內核指定參數即可

     

    qemu-system-arm -M vexpress-a9 -m 256M -kernel linux/linux-3.8/arch/arm/boot/zImage -append "root=/dev/mmcblk0 console=tty0 init=/linuxrc" -sd rootfs.img

     

     

    九. qemu網絡配置

    0. qemu支持tap網絡

    1. ubuntu-12.04本身內核支持了tun設備,所以不用再編譯模塊了.

    2. 安裝nfs

    (1) sudo apt-get install nfs-kernel-server

    (2) sudo vi /etc/exports

     /home/xxxx/work/rootfs/fs *(rw,sync,no_subtree_check,all_squash,insecure,anonuid=1000,anongid=1000)
    (3) service portmap restart

    (4) service nfs restart

    3. 修改qemu網絡啟動腳本

    sudo vi /etc/qemu-ifup

     

    #!/bin/sh  
    /sbin/ifconfig $1 172.20.0.1
    意思就是說host機器的ip是172.20.0.1

    4. nfs啟動內核

     

    sudo qemu-system-arm -M vexpress-a9 -m 256M -kernel linux/linux-3.8/arch/arm/boot/zImage -append "root=/dev/nfs nfsroot=172.20.0.1:/home/rda/work/rootfs/fs rw ip=172.20.0.2:172.20.0.1:172.20.0.1:255.255.255.0 init=/linuxrc console=tty0"   -net nic -net tap 

     

    ip=本機IP:對方IP:網關IP:掩碼

    nfsroot=nfs的地址 對方IP:路徑 - 和/etc/exports中導出的路徑一樣

     

    十. GDB和GDBServer的交叉編譯和使用

    1. gdbserver

    gdbserver很好用,作為設備端的應用為pc端gdb提供需要的信息,編譯也簡單

    (1) 下載源碼

    gdb-7.5.tar.bz2

     

    地址: ftp://prep.ai.mit.edu/pub/gnu/  

     

    (2) 編譯

    cd gdb-7.5/gdb/gdbserver

    ./configure --host=arm-linux-gnueabi --target=arm-linux-gnueabi

    make -j4

    即生成了gdbserver,file查看文件類型,copy到板子上

    (3) 使用

    板子上:

    ./gdbserver localhost:1234 helloworld # helloworld是程序,執行后等待連接

    PC上:

    arm-linux-gnueabi-gdb helloworld

    target remote 172.20.0.2:1234 

    以上連接上,就可以直接調試了

    2. gdb

    (1)  源碼 - gdb依賴termcap庫

     

    termcap-1.3.1.tar.gz

    地址: ftp://prep.ai.mit.edu/pub/gnu/ 

    (2) 交叉編譯termcap

    cd termcap-1.3.1

    ./configure

    后,修改Makefile如下

    vi Makefile

    CC = arm-linux-gnueabi-gcc

    AR = arm-linux-gnueabi-ar

    RANLIB = arm-linux-gnueabi-ranlib

    make

    (3) 交叉編譯GDB

    把剛編譯出的libtermcap.a復制到gdb-7.5/gdb

    cp -a libtermcap.a gdb-7.5/gdb

    cd gdb-7.5

    修改gdb/configure

    case $host_os in

        cygwin*)

           if test -d $srcdir/libtermcap; then

    ........

    esac

    ------->

    ac_cv_search_rgetent="libtermcap.a"

    配置

    ./configure --target=arm-linux-gnueabi --host=arm-linux-gnueabi 

    make -j4

    (4) 運行GDB

    GDB復制到板子上,就和調試PC程序一樣了.

     

十一. 問題

 1. 參考鏈接

http://www.linuxidc.com/Linux/2012-07/65478.htm

 

http://www.cnblogs.com/huqingyu/archive/2005/04/03/131102.html QEMU網絡

 

2. uboot出現問題
DRAM:  256 MiB
WARNING: Caches not enabled
Flash: ## Unknown flash on Bank 1 - Size = 0x00000000 = 0 MB
## Unknown flash on Bank 2 - Size = 0x00000000 = 0 MB
*** failed ***
### ERROR ### Please RESET the board ###

 

如果在檢測Flash failed后停止運行,是因為在 arch/arm/lib/board.c里面 board_init_r()函數里檢測Flash失敗后調用了hang(), 暫時先把hang()去掉就可以運行下去了。


3. gdb運行出現

 

"Remote ‘g’ packet reply is too long"
  在gdb/remote.c中
  注釋掉:
       
if (buf_len > 2 * rsa->sizeof_g_packet)            error (_(“Remote ‘g’ packet reply is too long: %s”), rs->buf); 

  並在后面添加:
 
if (buf_len > 2 * rsa->sizeof_g_packet) {       rsa->sizeof_g_packet = buf_len ;       for (i = 0; i < gdbarch_num_regs (gdbarch); i++)       {          if (rsa->regs[i].pnum == -1)          continue;           if (rsa->regs[i].offset >= rsa->sizeof_g_packet)          rsa->regs[i].in_g_packet = 0;          else          rsa->regs[i].in_g_packet = 1;       }    }
原因是gdbserver給的register個數過多,具體看代碼即可.

 

4. 高版本gdb可能會遇到調試錯誤,段錯誤等,可以換用低版本gdb,如gdb-7.0,gdb-6.8

gdb-7.0a這個版本是好用的.

5. 如果出現編譯錯誤

Werror相關的,那么配置的時候:

./configure --enable-werror=no ......

6. 注意gdbserver和gdb要用同一版本的 

7. gdb和gdbserver通信過程中,共享庫符號問題

因為板子上的庫路徑和pc庫路徑不同,所以pc上gdb可能出現加載不了動態庫的問題,方法是:

set solib-absolute-prefix /usr/arm-linux-gnueabi/

set solib-search-path /uar/arm-linux-gnueabi/lib/


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM