Finally椒丧,I got it壹甥!
首先,查資料自覺(jué)用google壶熏。恕我直言句柠,除google外,其他的都是垃圾!
參考網(wǎng)上的教程溯职,參考Google精盅,基于自己的理解,終于走出了第一步谜酒,至此叹俏,記錄下來(lái),希望留給更多的人參考僻族。
環(huán)境如下:
開(kāi)發(fā)環(huán)境內(nèi)核版本:
thorn@ubuntu:~$ cat /proc/version
Linux version 4.4.0-63-generic (buildd@lcy01-31) (gcc version 5.4.0 20160609 (Ubuntu 5.4.0-6ubuntu1~16.04.4) ) #84-Ubuntu SMP Wed Feb 1 17:20:32 UTC 2017
thorn@ubuntu:~$ uname -a
Linux ubuntu 4.4.0-63-generic #84-Ubuntu SMP Wed Feb 1 17:20:32 UTC 2017 x86_64 x86_64 x86_64 GNU/Linux
thorn@ubuntu:~$
gcc版本:
thorn@ubuntu:~$ arm-linux-gnueabi-gcc -v
Using built-in specs.
COLLECT_GCC=arm-linux-gnueabi-gcc
COLLECT_LTO_WRAPPER=/usr/lib/gcc-cross/arm-linux-gnueabi/4.9/lto-wrapper
Target: arm-linux-gnueabi
Configured with: ../src/configure -v --with-pkgversion='Ubuntu/Linaro 4.9.3-13ubuntu2' --with-bugurl=file:///usr/share/doc/gcc-4.9/README.Bugs --enable-languages=c,c++,java,go,d,fortran,objc,obj-c++ --prefix=/usr --program-suffix=-4.9 --enable-shared --enable-linker-build-id --libexecdir=/usr/lib --without-included-gettext --enable-threads=posix --with-gxx-include-dir=/usr/arm-linux-gnueabi/include/c++/4.9.3 --libdir=/usr/lib --enable-nls --with-sysroot=/ --enable-clocale=gnu --enable-libstdcxx-debug --enable-libstdcxx-time=yes --enable-gnu-unique-object --disable-libitm --disable-libquadmath --enable-plugin --with-system-zlib --disable-browser-plugin --enable-java-awt=gtk --enable-gtk-cairo --with-java-home=/usr/lib/jvm/java-1.5.0-gcj-4.9-armel-cross/jre --enable-java-home --with-jvm-root-dir=/usr/lib/jvm/java-1.5.0-gcj-4.9-armel-cross --with-jvm-jar-dir=/usr/lib/jvm-exports/java-1.5.0-gcj-4.9-armel-cross --with-arch-directory=arm --with-ecj-jar=/usr/share/java/eclipse-ecj.jar --disable-libgcj --enable-objc-gc --enable-multiarch --enable-multilib --disable-sjlj-exceptions --with-arch=armv5t --with-float=soft --disable-werror --enable-multilib --enable-checking=release --build=x86_64-linux-gnu --host=x86_64-linux-gnu --target=arm-linux-gnueabi --program-prefix=arm-linux-gnueabi- --includedir=/usr/arm-linux-gnueabi/include
Thread model: posix
gcc version 4.9.3 (Ubuntu/Linaro 4.9.3-13ubuntu2)
qemu版本:
git clone git://git.qemu-project.org/qemu.git
cd qemu
git checkout remotes/origin/stable-2.4 -b stable-2.4
linux源碼內(nèi)核版本:
wget https://www.kernel.org/pub/linux/kernel/v3.x/linux-3.16.tar.xz
作為一個(gè)希望在嵌入式方向發(fā)展的同學(xué)她肯,目前還沒(méi)有真正的接觸過(guò)嵌入式linux開(kāi)發(fā),很是慚愧鹰贵,那么從模擬器開(kāi)始吧晴氨。
總共花了2個(gè)多小時(shí)的時(shí)間,包括下載代碼碉输。由于對(duì)其中的某些過(guò)程還不是很理解籽前,一路很是曲折。即便搭建起來(lái)了環(huán)境敷钾,還需要自己慢慢品味才行枝哄。
1. 首先下載Linux內(nèi)核,以流行的3.16為例的原因是阻荒,作為一個(gè)初學(xué)者挠锥,希望有更多的參考資料。
兩種方法:
- 使用git
git clone git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git - 直接下載3.16源代碼包
wget https://www.kernel.org/pub/linux/kernel/v3.x/linux-3.16.tar.xz
與大多數(shù)的搭建過(guò)程不同侨赡,我選擇了直接下載源碼蓖租,原因有2:
- 以源碼為基礎(chǔ),與大多數(shù)時(shí)候的開(kāi)發(fā)環(huán)境相符羊壹,且更有成就感
- 因?yàn)槭菈嚎s包蓖宦,源碼的下載速度更快
內(nèi)核下載完畢之后,解壓油猫。這些基本的操作大家都不會(huì)陌生稠茂。緊接下來(lái)的,安裝arm的交叉編譯鏈工具情妖,這一步特別關(guān)鍵睬关。很多參考資料直接給出了這樣的命令行sudo apt-get install gcc-arm-linux-gnueabi
,這是不嚴(yán)謹(jǐn)?shù)模驗(yàn)檎敝ぃS著gcc的更新电爹,相關(guān)的工具鏈會(huì)做更新。
然而內(nèi)核的編譯過(guò)程卻還是依賴著比較老的gcc工具鏈情竹,這會(huì)導(dǎo)致編譯過(guò)程中出現(xiàn)很多莫名其妙的問(wèn)題藐不,而這些問(wèn)題匀哄,對(duì)于新手的成長(zhǎng)弊大于利。
我在這個(gè)問(wèn)題上面花了太多的時(shí)間雏蛮,因?yàn)樵诰幾g的過(guò)程中總會(huì)出現(xiàn)莫名其妙的錯(cuò)誤涎嚼,改了一個(gè),又出現(xiàn)另一個(gè)挑秉,如:
- fatal error: linux/compiler-gcc5.h: No such file or directory
- Makefile:901: recipe for target 'init' failed
- scripts/Makefile.build:390: recipe for target 'init/mounts.o' failed
- multiple definition of `return_address
可能要開(kāi)始懷疑人生了法梯。
對(duì)于每一個(gè)版本的內(nèi)核,官方都會(huì)有推薦的工具鏈犀概,版本不一定越高越好立哑,匹配才行。
比如3.16的內(nèi)核姻灶,gcc用4.9的是ok的铛绰,那么可能需要自己手動(dòng)安裝。
thorn@ubuntu:/usr/bin$ ls -l
找到下面我們需要的關(guān)鍵信息产喉,即一個(gè)軟鏈接文件捂掰。
lrwxrwxrwx 1 root root 34 Feb 27 21:56 arm-linux-gnueabi-gcc -> /usr/bin/arm-linux-gnueabi-gcc-5
這個(gè)文件表明我們使用的arm-linux-gnueabi-gcc 實(shí)際上是arm-linux-gnueabi-gcc-5,那么就需要自己手動(dòng)安裝:
sudo apt-get install gcc-4.9-arm-linux-gnueabi
sudo apt-get install gcc-4.9-arm-linux-gnueabi-base
由于不知道有何區(qū)別曾沈,索性都安裝了下这嚣。
并不需要卸載老版本的gcc,安裝之后塞俱,只需要自己手動(dòng)更改默認(rèn)的gcc版本:
刪除arm-linux-gnueabi-gcc姐帚,它只是個(gè)到/usr/bin/arm-linux-gnueabi-gcc-5的軟鏈接
thorn@ubuntu:/usr/bin$ sudo rm /usr/bin/arm-linux-gnueabi-gcc
重新建立我們需要的軟鏈接
thorn@ubuntu:~/linux-3.16$ sudo ln -s /usr/bin/arm-linux-gnueabi-gcc-4.9 /usr/bin/arm-linux-gnueabi-gcc
做過(guò)了這一步再編譯,云開(kāi)見(jiàn)日障涯,以前莫名其妙的錯(cuò)誤都消失了罐旗。
那么
thorn@ubuntu:/usr/bin$ ls -l
后可以看到,gcc已經(jīng)指向正確:
lrwxrwxrwx 1 root root 34 Feb 27 21:56 arm-linux-gnueabi-gcc -> /usr/bin/arm-linux-gnueabi-gcc-4.9
編譯linux內(nèi)核:
生成vexpress開(kāi)發(fā)板的config文件
make CROSS_COMPILE=arm-linux-gnueabi- ARCH=arm O=./out_vexpress_3_16 vexpress_defconfig
網(wǎng)上資料有如下步驟像樊,據(jù)說(shuō)是如果不做這個(gè)步驟尤莺,后面qemu會(huì)起不來(lái)旅敷。按照這個(gè)步驟生棍,結(jié)果沒(méi)有問(wèn)題:
執(zhí)行如下命令:
make CROSS_COMPILE=arm-linux-gnueabi- ARCH=arm O=./out_vexpress_3_16 menuconfig
將System Type -->的Enable the L2x0 outer cache controller 取消
實(shí)際上,經(jīng)過(guò)測(cè)試媳谁,若不執(zhí)行這一步涂滴,即按照默認(rèn)的config來(lái)做,結(jié)果也ok晴音。
編譯:
make CROSS_COMPILE=arm-linux-gnueabi- ARCH=arm O=./out_vexpress_3_16 zImage -j2
編譯OK柔纵,截圖為證:
2. qemu模擬器的搭建(當(dāng)然有更直接的方式,apt安裝)
git clone git://git.qemu-project.org/qemu.git
cd qemu
git checkout remotes/origin/stable-2.4 -b stable-2.4
配置以前需要安裝若干個(gè)軟件包锤躁,慚愧的是自己并不知道這幾個(gè)軟件包的作用
sudo apt-get install zlib1g-dev libglib2.0-0 libglib2.0-dev libtool libtool libsdl1.2-dev autoconf
配置qemu搁料,為了使qemu代碼干凈,中間文件都生成到build目錄下
thorn@ubuntu:~/qemu$ mkdir build
thorn@ubuntu:~/qemu$ cd build/
thorn@ubuntu:~/qemu/build$ ../configure --target-list=arm-softmmu --audio-drv-list=
編譯,安裝
make
sudo make install
如果不是在root權(quán)限下郭计,一定要加上sudo霸琴,比如我之前不知,就出現(xiàn)了如下的錯(cuò)誤:
install -d -m 0755 "/usr/local/share/qemu"
cannot change permissions of ‘/usr/local/share/qemu’: No such file or directory
感謝google昭伸,我找到了這個(gè)error的解決辦法梧乘。
測(cè)試qemu和內(nèi)核能否運(yùn)行成功
qemu已經(jīng)安裝好了,內(nèi)核也編譯成功了庐杨,到這里測(cè)試一下选调,編譯出來(lái)的內(nèi)核是否OK,或者qemu對(duì)vexpress單板支持是否夠友好灵份。
命令如下:
thorn@ubuntu:~/linux-3.16/out_vexpress_3_16$ qemu-system-arm -M vexpress-a9 -m 512M -kernel /home/thorn/linux-3.16/out_vexpress_3_16/arch/arm/boot/zImage -nographic -append "console=ttyAMA0"
如果看到內(nèi)核啟動(dòng)過(guò)程中的打印仁堪,說(shuō)明前的搭建是成功的。
-M vexpress-a9 模擬vexpress-a9單板填渠,你可以使用-M ?參數(shù)來(lái)獲取該qemu版本支持的所有單板
-m 512M 單板運(yùn)行物理內(nèi)存512M
-kernel /home/ivan/kernel_git/linux/arch/arm/boot/zImage 告訴qemu單板運(yùn)行內(nèi)核鏡像路徑
-nographic 不使用圖形化界面枝笨,只使用串口
-append "console=ttyAMA0" 內(nèi)核啟動(dòng)參數(shù),這里告訴內(nèi)核vexpress單板運(yùn)行揭蜒,串口設(shè)備是哪個(gè)tty横浑。
以下命令殺死qemu-system-arm這個(gè)進(jìn)程:
ps -A | grep qemu-system-arm | awk '{print $1}' | xargs sudo kill -9
以上就是本人arm運(yùn)行環(huán)境的搭建過(guò)程,如有問(wèn)題屉更,歡迎評(píng)論徙融,參考如下:
3. 制作根文件系統(tǒng)
你會(huì)注意到,有panic瑰谜,我們還沒(méi)有制作根文件系統(tǒng)
Kernel panic - not syncing: VFS: Unable to mount root fs on unknown-block(0,0)
- 下載欺冀、編譯和安裝busybox
wget http://www.busybox.NET/downloads/busybox-1.20.2.tar.bz2
thorn@ubuntu:~/busybox-1.20.2$ make defconfig
thorn@ubuntu:~/busybox-1.20.2$ make CROSS_COMPILE=arm-linux-gnueabi-
thorn@ubuntu:~/busybox-1.20.2$ make install CROSS_COMPILE=arm-linux-gnueabi-
安裝完成后,會(huì)在busybox目錄下生成_install目錄萨脑,該目錄下的程序就是單板運(yùn)行所需要的命令隐轩。
- 形成根目錄結(jié)構(gòu)
先在Ubuntu主機(jī)環(huán)境下,形成目錄結(jié)構(gòu)渤早,里面存放的文件和目錄與單板上運(yùn)行所需要的目錄結(jié)構(gòu)完全一樣职车,然后再打包成鏡像(在開(kāi)發(fā)板看來(lái)就是SD卡),這個(gè)臨時(shí)的目錄結(jié)構(gòu)稱為根目錄鹊杖。
可以寫(xiě)一個(gè)腳本mkrootfs.sh完成這個(gè)任務(wù)
#!/bin/bash
sudo rm -rf rootfs
sudo rm -rf tmpfs
sudo rm -f a9rootfs.ext3
sudo mkdir rootfs
sudo cp ~/busybox-1.20.2/_install/* rootfs/ -raf
sudo mkdir -p rootfs/proc/
sudo mkdir -p rootfs/sys/
sudo mkdir -p rootfs/tmp/
sudo mkdir -p rootfs/root/
sudo mkdir -p rootfs/var/
sudo mkdir -p rootfs/mnt/
sudo cp ~/etc rootfs/ -arf
sudo cp -arf /usr/arm-linux-gnueabi/lib rootfs/
sudo rm rootfs/lib/*.a
sudo arm-linux-gnueabi-strip rootfs/lib/*
sudo mkdir -p rootfs/dev/
sudo mknod rootfs/dev/tty1 c 4 1
sudo mknod rootfs/dev/tty2 c 4 2
sudo mknod rootfs/dev/tty3 c 4 3
sudo mknod rootfs/dev/tty4 c 4 4
sudo mknod rootfs/dev/console c 5 1
sudo mknod rootfs/dev/null c 1 3
sudo dd if=/dev/zero of=a9rootfs.ext3 bs=1M count=32
sudo mkfs.ext3 a9rootfs.ext3
sudo mkdir -p tmpfs
sudo mount -t ext3 a9rootfs.ext3 tmpfs/ -o loop
sudo cp -r rootfs/* tmpfs/
sudo umount tmpfs
thorn@ubuntu:/$ sudo ./mkrootfs.sh
由于在根目錄下執(zhí)行這個(gè)sh文件悴灵,故需要加上sudo。
接下來(lái)骂蓖,就可以啟動(dòng)qemu來(lái)模擬vexpress開(kāi)發(fā)板了积瞒,命令參數(shù)如下:
sudo qemu-system-arm \
-M vexpress-a9 \
-m 512M \
-kernel /home/thorn/linux-3.16/out_vexpress_3_16/arch/arm/boot/zImage \
-nographic \
-append "root=/dev/mmcblk0 console=ttyAMA0" \
-sd a9rootfs.ext3
由于要讀寫(xiě)根目錄下的文件,故登下,執(zhí)行qemu時(shí)要加上sudo茫孔。
其中要注意的是叮喳,-sd a9rootfs.ext3,這個(gè)指的是絕對(duì)路徑缰贝,由于我是在根目錄下做這個(gè)的才避,所以元镀,-sd后面直接是a9rootfs.ext3。
執(zhí)行結(jié)果如下:
若是基于圖形化的啟動(dòng),如下:
sudo qemu-system-arm \
-M vexpress-a9 \
-serial stdio \
-m 512M \
-kernel /home/thorn/linux-3.16/out_vexpress_3_16/arch/arm/boot/zImage \
-append "root=/dev/mmcblk0 console=ttyAMA0 console=tty0" \
-sd a9rootfs.ext3
執(zhí)行結(jié)果如下:
當(dāng)然裤唠,后面的話龄广,我們最好是把所有的文件都集成在一個(gè)大文件目錄下拴测,簡(jiǎn)潔清晰垫蛆,而且,權(quán)限容易控制嗤攻。
其中的~/etc為啟動(dòng)配置文件毛嫉,后面可以基于此做一些個(gè)性化的啟動(dòng)配置。