搭建uClinux+arm+skyeye軟硬件開發(fā)環(huán)境
songbohr@gmail.com
http://blog.csdn.net/songbohr整理版
uClinux就是Micro-Control-Linux,它也是一個開放源碼的項目,uClinux的源代碼和開發(fā)工具可以免費從http://www.uclinux.org上下載得到。uClinux是專為那些沒有MMU(內存
管理單元)的嵌入式處理器開發(fā)的,和主流的Linux相比,uClinux有以下的特點:
1.簡化了內核加載方式,uClinux
的內核可以在Flash上直接運行:就是把uClinux的內核的可執(zhí)行映象燒寫到flash上,系統(tǒng)啟動時從Flash的某個地址開始逐句執(zhí)行;也可以加載到內存中運行
:把內核的壓縮文件存放在Flash上,系統(tǒng)啟動時讀取壓縮文件在內存里解壓,然后開始執(zhí)行。
2.采用了romfs文件系統(tǒng)作為root文件系統(tǒng):這種文件系統(tǒng)相對于一般的ext2文件系統(tǒng)要求更少的空間,首先內核支持romfs文件系統(tǒng)比支持
ext2文件系統(tǒng)需要更少的代碼,其次romfs文件系統(tǒng)相對簡單,建立文件系統(tǒng)superblock需要更少的存儲空間。Romfs文件系統(tǒng)不支持動態(tài)擦寫,對于系統(tǒng)需
要動態(tài)保存的數(shù)據(jù)采用RAM盤的方法處理,RAM盤采用ext2文件系統(tǒng)。
3.使用了Flat可執(zhí)行文件格式:elf格式有很大的文件頭,flat文件對文件頭和一些段信息做了簡化。
4.重寫了應用程序庫:
uClibc對libc做了精簡,uClinux對用戶程序采用靜態(tài)連接的形式。uClinux的開發(fā)環(huán)境
www.uclinux.org為uClinux提供了GNU的交叉編譯器,包括以下組件:Gcc交叉編譯器,即在宿主機上開發(fā)編譯目標上可運行的二進制文件;Binut
ils輔助工具,包括objdump、as、ld等;Gdb調試器。
1、如何編譯安裝skyeye?
編譯:
./configure --target=arm-elf --prefix=/usr/local
接下來執(zhí)行:
make lib
make
sudo make install
sudo make install_lib
使用make命令的時候可以加入一些選項參數(shù),例如:
不允許DBCT
$make NO_DBCT=1
不支持LCD
$make NO_LCD=1
不支持BFD庫
$make NO_BFD=1
不支持網(wǎng)絡設備
$make NO_NET=1
為了可以在shell 里面直接運用skyeye命令,將這個路徑/home/phil/skyeye-tools 加入到系統(tǒng)環(huán)境變量中
代碼:
$gedit /etc/environment
找到有PATH那一行,加入skyeye 路徑,比如下面所示
PATH="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/opt/slickedit/bin:/home/phil/skyeye-tools"
重啟系統(tǒng)后生效
也可
#vim .bash_profile
//編輯.bash_profile文件,找到PATH=$PATH:$HOME/bin,在其后面添加編譯器的路徑:/home/phil/skyeye-tools
#source .bash_profile
//重新加載.bash_profile文件
2、用apt-get安裝相關的庫包:
在安裝SkyEye之前,一定要確認你的系統(tǒng)中已經(jīng)安裝有如下軟件包:
gcc,
make,
vim(optional),
ssh,
subversion
binutils-dev (bfd)
atk-dev (libatk1.0-dev)
gtk+-2.0-dev (libgtk2.0-dev)
pkg-config
pango-dev (libpango1.0-dev)
freetype2-dev (libfreetype6-dev)
glib-dev (libglib2.0-dev)
x11-dev (libx11-dev)
建議您在終端里輸:
sudo apt-get install libgtk2.0-dev pkg-config libatk1.0-devlibpango1.0-dev libfreetype6-dev libglib2.0-dev libx11-dev binutils-devlibncurses5-dev libxpm-
dev
sudo apt-get install skyeye
用apt裝了skyeye 但是運行出出錯
phil@ubuntu-embedded:~$ skyeye
skyeye: error while loading shared libraries:libbfd-2.19.90.20090909.so: cannot open shared object file: No such fileor directory
解決方法:
phil@ubuntu-embedded:~$ ls /usr/lib -l | grep bfd
-rw-r--r-- 1 root root 863208 2009-10-29 23:51 libbfd-2.20.so
-rw-r--r-- 1 root root 6583840 2009-10-29 23:50 libbfd.a
lrwxrwxrwx 1 root root 14 2010-05-21 13:47 libbfd.so -> libbfd-2.20.so
phil@ubuntu-embedded:~$ sudo ln /usr/lib/libbfd-2.20.so /usr/lib/libbfd-2.19.90.20090909.so -s
phil@ubuntu-embedded:~$ ls /usr/lib -l | grep bfd
lrwxrwxrwx 1 root root 23 2010-05-21 16:11 libbfd-2.19.90.20090909.so -> /usr/lib/libbfd-2.20.so
-rw-r--r-- 1 root root 863208 2009-10-29 23:51 libbfd-2.20.so
-rw-r--r-- 1 root root 6583840 2009-10-29 23:50 libbfd.a
lrwxrwxrwx 1 root root 14 2010-05-21 13:47 libbfd.so -> libbfd-2.20.so
phil@ubuntu-embedded:~$ skyeye
3.安裝arm-elf交叉編譯器
//wget http://www.uClinux.org/pub/uClinux/m68k-elf-tools/arm-elf-tools-20030314.sh
wget http://opensrc.sec.samsung.com/download/arm-elf-tools-20040427.sh
執(zhí)行:
chmod a+x arm-elf-tools-20030314.sh
然后:
./arm-elf-tools-20030314.sh
ls /usr/local/bin/
你應能看到以arm-elf開頭的可執(zhí)行文件,其中arm-elf-gcc就是用來編譯你目標平臺的編譯器的,當然還有一些小工具,后面將一一講來。
在ubuntu安裝arm-elf-tools-20040427.sh
./arm-elf-tools-20040427.sh 后出現(xiàn)
tail : cannot open `+43' for reading : No such file or directory
錯誤
解決方法:
su切換為root用戶(必須切換,不然export是設在當前用戶)
然后先 export _POSIX2_VERSION=199209
再運行 ./arm-elf-tools-20040427.sh
即可!
5、測試你的arm-elf-gcc編譯器
先寫一個小程序hello.c
PHP 代碼:
#include <stdio.h>
int main(void)
{
int i;
for(i = 0; i < 6; i++){
printf("i = %d ",i);
printf("Hello, embedded linux!\n");
}
return 0;
}
然后執(zhí)行:
arm-elf-gcc -Wl,-elf2flt -o hello hello.c
-elf2flt參數(shù)是將elf文件格式轉為flat文件格式,這個工具是在你安裝交叉編譯器產生的。
或者你可以寫個Makefile文件,執(zhí)行:
make
這里是我的Makefile文件,僅供參考:
PHP 代碼:
# begin
CC = arm-elf-gcc
CFLAGS = -D__PIC__ -fpic -msingle-pic-base -O2 -pipe -Wall -g
LDFLAGS = -Wl,-elf2flt
LIBS =
OBJS = hello.o
all: hello
hello: $(OBJS)
$(CC) $(CFLAGS) $(LDFLAGS) -o hello $(OBJS) $(LIBS)
clean:
rm -rf *.o *.elf *.gdb hello
# end
如果編譯通過,就會產生hello可執(zhí)行文件。用下面的命令:
file hello
你會發(fā)現(xiàn),它是BFLT(binary FLAT),你目標平臺所支持的文件格式。
6、執(zhí)行你的hello程序
這里,我們將借助genromfs這個小工具來完成測試,這個工具就是你在安裝交叉編譯器時產生的,你可以直接使用它。
下skyeye-testsuite-1.3.0_rc1.tar.bz2包:
tar jxvf skyeye-testsuite-1.3.0_rc1.tar.bz2
cd skyeye-testsuite-1.3.0_rc1/uClinux/at91/uclinux_cs8900a#
mkdir romfs.img(建一個目錄,后面用)
mount -o loop romfs.img /mnt/xxx
cp -r /mnt/xxx/* romfs
另外,把你編譯好的可執(zhí)行程序拷貝到./romfs/bin目錄里,這里就是hello了!
genromfs -f romfs.img -d romfs/
注:可以用genromfs -h來獲得幫助!
OK!執(zhí)行下面的命令:
skyeye -e linux
cd /bin
hello
可以看到結果了嗎?
其實到了這一步,你就可以開發(fā)自己的程序了!
7.編譯我們的uClinux內核
wget http://www.uClinux.org/pub/uClinux/dist/uClinux-dist-20040408.tar.gz
首先解壓
代碼:
tar -zxvf uClinux-dist-20040408.tar.gz //tar zxvf uClinux-dist-20090618.tar.gz這里不能用2009版,我編譯時出現(xiàn)各種編譯問題,只好換回04版
這是在你解壓的目錄里面會生成一個 uClinux-dist目錄
shell 中進 uClinux-dist目錄,執(zhí)行make menuconfig進行配置:
代碼:
phil@ubuntu-embedded:~/skyeye-tools/uClinux-dist$ make menuconfig
然后再進行配置:在下面這個選項里面選擇GDB ARMulator
代碼:
--- Select the Vendor you wish to target
(GDB) Vendor
--- Select the Product you wish to target
(ARMulator) GDB Products
Kernel選擇2.4內核,Libc Version選擇uClibc //不能選擇2.6內核,編譯器版本太低,不支持
代碼:
(linux-2.4.x) Kernel Version
(uClibc) Libc Version
[ ] Default all settings (lose changes)
[ ] Customize Kernel Settings
[ ] Customize Vendor/User Settings
[ ] Update Default Vendor Settings
退出它會提示:
代碼:
Do you wish to save your new kernel configuration?
< Yes > < No >
選擇Yes
編譯:
make clean
make dep
make
編譯uClinux時提示arm-linux-gcc:command not found
解決方法:
uClinux是針對無MMU設備的Linux因此編譯時要用arm-elf-gcc交叉編譯器
先安裝上arm-elf-tools交叉編譯工具包
然后修改uClinux的配置文件使用arm-elf-XXX工具編譯
vi uClinux-dist/vendors/config/armnommu/config.arch
找到以下代碼段:
CROSS_COMPILE=arm-linux-
修改為
CROSS_COMPILE=arm-elf-
:wq
保存退出
重新編譯應該沒有問題
這個編譯過程比較長,耐心等待。
編譯成功后會在uClinux-dist目錄里面生成一個images目錄,這個目錄里面有四個文件:
image.bin:這是包含內核映像和 romfs文件系統(tǒng)映像,可以寫到Flash中的文件,
linux.data:包括內核所有的數(shù)據(jù)段
linux.text:包括內核所有的代碼段
romfs.img:文件系統(tǒng)
另外在uClinux-dist/linux-2.4.x目錄里面生成了兩個文件:linux和system.map
linux:linux內核文件
system.map:內核符號表
然后在uClinux-dist目錄里面建一個skyeye.conf文件,并鍵入以下配置文件
代碼:
#skyeye config file sample
cpu: arm7tdmi
mach: at91
mem_bank: map=M, type=RW, addr=0x00000000, size=0x00004000
mem_bank: map=M, type=RW, addr=0x01000000, size=0x00400000
mem_bank: map=M, type=R, addr=0x01400000, size=0x00400000, file=./boot.rom
mem_bank: map=M, type=RW, addr=0x02000000, size=0x00400000
mem_bank: map=M, type=RW, addr=0x02400000, size=0x00008000
mem_bank: map=M, type=RW, addr=0x04000000, size=0x00400000
mem_bank: map=I, type=RW, addr=0xf0000000, size=0x10000000
注意這個配置文件中需要boot.rom 文件系統(tǒng),但是我們并沒有生成boot.rom文件系統(tǒng),怎么辦?
ln -s images/romfs.img boot.rom
代碼:
wenwu@wenwu-desktop:/source/uClinux-dist$ ln -s images/romfs.img boot.rom
這是就可以在uClinux-dist 目錄里面看到boot.rom這個文件
下面就可以用skyeye運行我們自己編譯出來的內核了。
代碼:
wenwu@wenwu-desktop:/source/uClinux-dist$ skyeye -e linux-2.4.x/linux
target sim
...
load
...
run
8.模擬運行自己的應用程序
找到前面曾編譯的程序Hello.c,將編譯生成的BFLT格式的Hello移動到/uClinux-dist/romfs/bin中(注意在shell中用root)
然后重新編譯內核
#make
運行
#skyeye -e linux-2.4.x/linux
```
```
```
(省略)
Sash command shell(version 1.1.1)
/>cd bin
/bin>./Hello
Hello!This is Embedded Linux!
附錄:skyeye.conf中的選項
SkyEye模擬的硬件配置和模擬執(zhí)行行為由配置文件skyeye.conf中的選項確定。根據(jù)選項的功能,skyeye.conf的選項分為硬件配置選項和模擬執(zhí)行選項。根據(jù)參數(shù)的個數(shù),
skyeye.conf的選項主要由兩種組成:
單參數(shù)選項行
格式為:
symbol: value
symbol可以是硬件定義,如cpu、mach等,也可以是執(zhí)行控制定義,如log等。
value是symbol對應的值,可能是數(shù)字也可能是字符串。
多參數(shù)選項行
格式為:
symbol:opt1=value1,opt2=value2,......
opt1是參數(shù)名,value1是opt1對應的值,可能是數(shù)字也可能是字符串。
目前skyeye.conf的配置定義如下:
基本CPU核配置選項
目前存在的選項有:arm710、arm7tdmi、arm720t、arm920t、sa1100、sa1110、xscale
格式為
cpu: cpuname
注:cpuname表示一個代表cpu名字的字符串。
例如:
cpu: arm7tdmi
具體的開發(fā)板(包括CPU擴展)配置選項
目前存在的選項有:at91、ep7312、adsbitsy,pxa_Lubbock、lpc、s3c4510b、s3c44b0、cs89712、sa1100、at91rm92、sharp_lh7a400
格式為:
mach: machinename
注:cpuname表示一個代表基于特定CPU的開發(fā)板名字的字符串。
例如:
mach: at91
內存組配置選項
一個內存組內的地址是連續(xù)的,類型分為RAM SPACE, ROM SPACE, mapped IO SPACE
格式為:
mem_bank: map=M|I, type=RW|R, addr=0xXXXXXXXX, size=0xXXXXXXXX,file=imagefilename,boot=yes|no
map=M 表示 RAM/ROM SPACE, map=I 表示 mapped IO SPACE。
type=RW ,且如果map=M則表示RAM SPACE, type=R,且如果map=M則表示ROM SPACE。
addr=0xXXXXXX 表示內存組的起始物理地址(32bit,16進制)。
size =0xXXXXXX 表示內存組的大小(32bit,16進制) 。
file =imagefilename
file的值imagefilename是一個字符串,實際上表示了一個文件,一般是一個可以執(zhí)行的binary image格式的可執(zhí)行程序或OS內核文件或是一個binary image格式的根文件系統(tǒng)。如
果存在這個文件,SkyEye會把文件的內容直接寫到對應的模擬內存組地址空間中。
boot=yes/no,如果boot=yes,則SkyEye會把模擬硬件啟動后的第一條指令的地址定位到對應的內存組的起始地址。
例如:
mem_bank: map=M, type=RW, addr=0x00000000, size=0x00004000
mem_bank: map=M, type=R, addr=0x01400000, size=0x00400000, file=./boot.rom
mem_bank: map=M, type=RW, addr=0x10000000, size=0x00000800, file=./loader.bin,boot=yes
網(wǎng)絡芯片8019AS的配置
格式為 nic: state=on/off mac=xx:xx:xx:xx:xx:xx ethmod=tuntap/vnet hostip=dd.dd.dd.dd
注:xx表示兩位16進制數(shù),dd表示兩位10進制數(shù)
state表示模擬開始后,網(wǎng)絡芯片是否開始工作
mac表示模擬的nic的mac地址
ethmod表示skyeye所處主機上的網(wǎng)絡模擬方式, 目前有tuptap和vnet兩種模式。tuntap是linux kernel支持的一個點到點虛擬網(wǎng)絡實現(xiàn),vnet是skyeye實現(xiàn)的一個功能更多的一個
基于虛擬HUB的網(wǎng)絡。
hostip表示主機方與skyeye交互用的ip地址
例如:
net: state=on, mac=0:4:3:2:1:f, ethmod=tuntap, hostip=10.0.0.1
LCD的配置
格式為 lcd: state=on/off
state=on表示LCD處于接通狀態(tài); state=off 表示LCD處于關閉狀態(tài)。
例如:
lcd: state=on
skyeye的UART控制選項
uart選項可以控制skyeye在另一個與某個串口連接的終端上輸入/輸出字符
格式:
uart: fd_in=indevname, fd_out=outdevname
fd_in=indevname indevname表示用于輸入的設備文件名,其值為實際的串口設備文件/dev/ttySx
fd_out=outdevname outdevname表示用于輸出的設備文件名,其值為實際的串口設備文件/dev/ttySx
例如:
uart: fd_in=/dev/ttyS0, fd_out=/dev/ttyS0
skyeye的log控制選項
log選項用于控制skyeye輸出硬件系統(tǒng)的執(zhí)行狀態(tài)信息,包括每次執(zhí)行指令時的執(zhí)行指令值、寄存器值、各種硬件狀態(tài)等。
格式:
log: logon=0|1, logfile=filename, start=number1, end=number2, length=number3
logon=0|1|2|3,如果值等于0表示不進行記錄,如果值等于1表示記錄指令和指令地址流,如果值等于2表示記錄指令和指令地址和主要寄存器內容,如果值等于3表示記錄指令和指
令地址和所有的寄存器內容。
logfile=filename 其值是一個字符串,表示用于記錄信息的文件名
start=number1 其值是一個>=0的十進制整數(shù),表示系統(tǒng)執(zhí)行到第number1條指令時開始進行記錄
end =number2其值是一個>=0的十進制整數(shù),表示系統(tǒng)執(zhí)行到第number2條指令時停止記錄
length =number3其值是一個>=0的十進制整數(shù),表示只記錄系統(tǒng)最近執(zhí)行的number3條指令時的信息
格式:
log: logon=0, logfile=/tmp/sk1.log, start=100000, end=200000, length=100
參考文獻:
自己動手打造嵌入式Linux軟硬件開發(fā)環(huán)境 http://linux.chinaunix.net/doc/embedded/2005-01-13/764.shtml
在ubuntu7.10上搭建uClinux編譯開發(fā)環(huán)境并用Skyeye進行仿真http://forum.ubuntu.com.cn/viewtopic.php?t=88369&sid=9948fa118f9d824457625463193d77e2
uClinux+Skyeye open source simulator http://sourceforge.net/apps/trac/skyeye/wiki/uClinux
Getting Familiar with uClinux/ARM 2.6 http://opensrc.sec.samsung.com/Getting_Familiar_with_uClinuxARM2_6.html