我建構的目标平台為BeagleBone Black,
'http://beagleboard.org/'。
交叉編譯工具為Sourcery CodeBench Lite,
'http://www.mentor.com/'。
要建構Linux,很簡單,隻有3個部分,
1,bootloader,即啟動引導程式,我選擇U-Boot。
2,Linux核心。
3,應用程式。
我還沒研究是什麼決定了32位和64位。
我主要的資料,
Running Linux
介紹Linux的書,這才叫入門級,了解下Linux的思想即可,書的内容可能有些過時,
這本書不是介紹怎麼使用Linux的。如果想知道怎麼使用Linux,
可看看Linux Pocket Guide,很薄。
鳥哥的書也不錯,感覺挺詳細的,好于大部分書,我沒看。
我連shell腳本都不會寫呢,很多指令沒用過,這與建構Linux關系不大。
Building Embedded Linux Systems
教建構嵌入式Linux的,了解下思想即可。
http://www.linuxfromscratch.org/
教建構各種Linux的網站,最關鍵的是網站給出了Linux由哪些應用程式構成。
我沒有用網站中的方式,sed那種指令不會。也是了解下思想即可。
If you can’t explain it simply, you don’t understand it well enough.
--Albert Einstein
===============================================================================
BeagleBone Black有4種啟動方式,我選擇用SD卡。
準備SD卡,将SD卡插到電腦中,在我的系統中被識别為/dev/sdb。
分區:
# fdisk /dev/sdb
用法很簡單,輸入'm',就可得到幫助。
第一個分區64M,類型為FAT32 (LBA),加上啟動标記。
第二個分區為餘下的全部,類型預設為Linux,不必改。
參考過程是這樣的,
輸入'o',建立一個空DOS分區表,這會清除所有分區。
輸入'p',會列出分區清單,此時應該沒有。
輸入'n'來添加新分區,直接'enter',接受預設為主分區,'enter'接受預設為第一分區,
'enter'接受預設的開始扇區,輸入'+64M',設定分區大小為64M。
輸入't',來改變分區類型,自動選擇了第一個分區,輸入l可列出所有分區清單的代碼,
輸入'c'選擇W95 FAT32(LBA)。
輸入'a',在第一分區設定可啟動标記。
輸入'n','enter'主分區,'enter'第二個,'enter'起始扇區,'enter'結束扇區。
輸入'w',将改動寫入分區表。
格式化:
# mkfs.vfat -F 32 /dev/sdb1
# mkfs.ext4 /dev/sdb2
第一個分區用來放U-Boot,闆子啟動後就會找一個叫MLO的檔案,編譯U-Boot後,就會生成
一個MLO,不必擔心。
第二個分區用來放Linux系統。
sdb2被格式化後,裡面自動有個lost+found,檔案系統的結構中正好有一條:
/lost+found: Filesystem-specific recoverable data
===============================================================================
我的檔案系統目錄結構
/
/bin --> /usr/bin/
/boot/
/dev/
/etc/
/home/
/home/root
/lib --> /usr/lib/
/mnt/
/proc/
/run/
/sbin --> /usr/bin/
/sys/
/tmp
/usr/
/usr/app/
/usr/bin/
/usr/include/
/usr/lib/
/usr/sbin --> bin/
/usr/share/
/usr/share/man/
/var/
/var/run --> /run/
===============================================================================
編譯時的一些配置等,我為了友善調用,放到這裡,不要看。
$ export PATH=$PATH:/home/spy/Software/arm-2013.11/bin
$ export PATH=$PATH:/home/spy/Work/U-Boot/u-boot/tools
$ export CROSS_COMPILE=arm-none-linux-gnueabi-
# chown -R 0:0
# chgrp -v tty /usr/app/util-linux/bin/wall
# chown -R spy:users
找readelf結果中帶"Shared library"的行
readelf -ld | grep "Shared library"
以可讀寫重新挂載根檔案系統
mount -n -o remount,rw /
放到交叉編譯器搜尋庫中的程式庫
libcap,pam,ncurses,gdbm,db,iptables
coreutils與util-linux重複的指令。
kill
shadow與util-linux重複的指令。
{login,nologin,su}
shadow與coreutils重複的指令。
groups
===============================================================================
下面是編譯軟體的過程
U-Boot
============ http://www.denx.de/wiki/U-Boot/WebHome
$ export PATH=$PATH:/home/spy/Software/arm-2013.11/bin
$ export CROSS_COMPILE=arm-none-linux-gnueabi-
$ make O=../u-boot distclean
$ make O=../u-boot am335x_boneblack_config
$ make O=../u-boot all
--------------------------------------------------------------------------------
源碼中正好有am335x_boneblack這個配置檔案,對應我的開發闆,想知道可用的配置檔案
看README吧,它會告訴你到另一個檔案中找。
忘了是編譯U-Boot還是Linux核心的時候,提示我的系統中缺少bc,用你的包管理器安上就好了。
編譯完後,現在就可以找找成就感了,
将MLO和u-boot.img複制到SD卡的第一個分區裡;
将序列槽調試用的線與計算機相連,啟動序列槽調試程式,如Putty。
将SD卡插入開發闆,保持按下闆子上的啟動選擇鍵,插上電源,闆子會從SD卡啟動,
可以松開啟動選擇鍵了。
Putty的視窗上會列印一些資訊,你會看到一個1秒的倒計時,然後U-Boot會運作環境變量中
已經設定好的一些列指令,比如将Linux核心載入記憶體,但此時還沒有核心檔案,U-Boot會
停留在它自己的指令行中,你可以輸入指令,如reset,這會讓闆子重新開機,倒計時的時候
按下計算機上的任意鍵,U-Boot就不會運作環境變量中的指令了,可玩一玩下面的示範。
給出U-Boot中的一些示範,輸入help可顯示所有指令。
help後接指令,可顯示該指令的幫助。如"help help"。
U-Boot# mmc rescan
U-Boot# mmc list
OMAP SD/MMC: 0
OMAP SD/MMC: 1
U-Boot# mmc dev
mmc0 is current device
U-Boot# mmc part
Partition Map for MMC device 0 -- Partition Type: DOS
Part Start Sector Num Sectors UUID Type
1 2048 131072 29942d7e-01 0c Boot
2 133120 15390720 29942d7e-02 83
U-Boot# ls mmc 0:1
100688 mlo
308232 u-boot.img
510 uenv.txt
3 file(s), 0 dir(s)
U-Boot# ls mmc 0:2
<DIR> 4096 .
<DIR> 4096 ..
<SYM> 7 bin
<DIR> 4096 boot
<DIR> 4096 dev
<DIR> 4096 etc
<DIR> 4096 home
<SYM> 7 lib
<DIR> 4096 lost+found
<DIR> 4096 mnt
<DIR> 4096 proc
<DIR> 4096 run
<SYM> 7 sbin
<DIR> 4096 sys
<DIR> 4096 tmp
<DIR> 4096 usr
<DIR> 4096 var
U-Boot# mmcinfo
Device: OMAP SD/MMC
Manufacturer ID: 3
OEM: 5344
Name: SU08G
Tran Speed: 50000000
Rd Block Len: 512
SD version 3.0
High Capacity: Yes
Capacity: 7.4 GiB
Bus Width: 4-bit
U-Boot# mmc dev 1
mmc1(part 0) is current device
U-Boot# mmcinfo
Device: OMAP SD/MMC
Manufacturer ID: fe
OEM: 14e
Name: MMC02
Tran Speed: 52000000
Rd Block Len: 512
MMC version 4.41
High Capacity: No
Capacity: 1.8 GiB
Bus Width: 4-bit
U-Boot# mmc dev 0
mmc0 is current device
U-Boot#
fatls,ext4ls也可以顯示檔案,但對應某種檔案系統。
Linux
============ http://www.kernel.org/
核心配置檔案我在'https://github.com/beagleboard/kernel/tree/3.13/configs'找的,
複制一份名字改'.config'放到O指定的目錄中。
這樣就可以用'make oldconfig'了。
我的核心版本是Linux-3.13.5,并沒有提示新的配置。
如果要修改的話,要注意systemd對核心的配置是有要求的,我并沒有改。
$ export PATH=$PATH:/home/spy/Software/arm-2013.11/bin
$ export PATH=$PATH:/home/spy/Work/U-Boot/u-boot/tools
$ export CROSS_COMPILE=arm-none-linux-gnueabi-
$ make O=../linux ARCH=arm help
$ make O=../linux ARCH=arm mrproper
$ make O=../linux ARCH=arm oldconfig
$ make O=../linux ARCH=arm LOADADDR=0x80008000 uImage
$ make O=../linux ARCH=arm LOADADDR=0x80008000 dtbs
$ make O=../linux ARCH=arm LOADADDR=0x80008000 modules
$ make O=../linux ARCH=arm LOADADDR=0x80008000 INSTALL_MOD_PATH=/home/spy/Work/root modules_install
$ make O=../linux ARCH=arm LOADADDR=0x80008000 INSTALL_FW_PATH=/home/spy/Work/fw firmware_install
$ make O=../linux ARCH=arm LOADADDR=0x80008000 INSTALL_HDR_PATH=/home/spy/Work/root/hdr headers_install
--------------------------------------------------------------------------------
'make help'是否指定ARCH,輸出内容是不同的。
uImage就是壓縮後的Linux核心,編譯時需要mkimage這個工具,編譯U-Boot的時候會生成那個工具,
是以我編譯核心之前指定了該工具的目錄。
-dts --> device tree source
-dtb --> device tree blob
-dtbo --> device tree blob overlay
-dtc --> device tree compile
沒研究為什麼編譯裝置樹是dtbs,是在make help的幫助中看到的。
核心的配置中指定了很多把驅動編譯成子產品的,這部分需要'make modules'來單獨編譯。
我建構完的系統并沒有用到這些modules,插個U盤是可用的。
編譯完成後,可在輸出檔案夾的'arch/arm/boot'找到zImage, uImage和dts子檔案夾,
dts裡面有am335x-boneblack.dtb。zImage也是核心,也可以用,但我用的uImage。
最後那三個安裝目錄自己選個更好的吧。
modules會安在'lib/modules'和'lib/firmware'2個檔案夾中。
firmware也安在'lib/firmware'中,但與modules中的不同。我目前不知道firmware是幹什麼的。
headers還是需要安裝的,它就像glibc那樣,編譯程式時被調用。
--------------------------------------------------------------------------------
下面可以驗證了。
将uImage檔案,dts檔案夾複制到SD卡第二個分區的/boot/裡。
其實dts中應該隻需am335x-boneblack.dtb。
啟動開發闆前應該了解下U-Boot如何載入Linux。
提示:我的研究在後面。現在可不必研究直接看我的處理。
編譯後的U-Boot是不能引導uImage的,通過printenv看U-Boot的環境變量,可看到
它找的是zImage,而且am335x-boneblack.dtb是在/boot/中找,不是/boot/dts/。
如果将zImage和am335x-boneblack.dtb放到/boot中應該能引導。
為了符合我的要求,要修改環境變量,可以用editenv修改環境變量後saveenv。
但還是别這麼做了,我不知道它把環境變量儲存到哪裡去了。我以為把MLO和u-boot.img換回
原始的可以恢複預設的環境變量值,但不是這樣,把SD卡格式化後也沒用。
有可能是存到eMMC中了,我想盡各種辦法破壞eMMC的資料,用了
'dd if=/dev/zero of=/dev/mmcblk1'也不行。
除了mmcblk1還有個mmcblk1boot,可能是存到那裡了,記着那個裝置比較奇怪,沒有驗證。
最後用'env default -a'然後'saveenv'恢複預設了。
另一個方法是建立一個uEnv.txt檔案,将它和MLO放到一起,内容如下。
該檔案中的環境變量會覆寫掉預設的環境變量。
一共6行,最後一行空白。
改動不是很大,bootfile修改了核心名字,
loadfdt中隻是在目錄中加了“dts/”,
mmcloados主要是把bootz改成bootm。
mmcroot把隻讀改成了讀寫,原因是systemd啟動後會建立一個machine-id到/etc中。
也許有其他辦法,如/etc/fstab檔案,但我為了簡單沒建立那個檔案。
mmcargs隻是在後面指定了init為systemd,也有其他方法,如init為指向systemd的軟連結。
啟動BeagleBone Black,待核心啟動後會列印很多資訊,最後你将目睹“kernel panic”,
這是因為我們目前并沒有init程式,為了找到成就感,你可以編譯下面
靜态連結的“Hello world!”,放到某個目錄中,然後在U-Boot的mmcargs變量中
把init指定為那個hello。
hello.c
$ arm-none-linux-gnueabi-gcc -o hello -static hello.c
再次啟動,最後你看到的将是"Hello world!"。
下面就是應用程式了,可根據我的提示自行安排順序,我曾經的順序不是這樣的。
主要的過程就是glibc,bash,coreutils,util-linux,systemd,shadow,
這些中間的都是被依賴的程式。
bash需要libgcc_s.so.1,它位于gcc中,但編譯gcc時間較長,gcc還依賴5個程式。
迫不及待驗證編譯結果的話可以先把交叉編譯器中的庫複制到開發闆系統中,
我當初就那麼做的。
glibc是程式庫了,幾乎動态連結的程式都要用到了,"Hello world"中的printf函數都需要。
bash是個shell,提供了人與計算機互動的界面。
coreutils裡有很多常用指令,如'ls'。
util-linux也是有很多指令,如mount,login,fdisk。
systemd是個init程式。
shadow是和登陸相關的,主要是把'/etc/passwd'檔案裡的密碼變成“x”,
裡面有login,passwd,useradd等指令。
其實系統系統後的第一個程式是systemd,但它的文檔較少,不了解是怎麼工作的,
是以先保證其他的能工作,再研究。
至于怎麼編譯,源碼中會有README,INSTALL等文檔。
需要注意的是我建構的系統與大多數Linux不同,我把所有程式都安裝在了
/usr/app/{程式}/中。這是我改進Linux的開始,咱有大計劃呀!
我的想法如下,
對于程式庫,依舊在/usr/lib/中搜尋,裡面除了子檔案夾都是軟連結,指向app中
相應的程式庫。
對于/usr/bin/中的程式,也是軟連結。
對于/etc/中的配置檔案,其實有些程式不在那個目錄找配置檔案了,如果還在那個目錄找,
那麼裡面不是軟連結,就是傳統的配置檔案。
glibc
============ [/usr/local] http://www.gnu.org/software/libc/
>
< bash, //這2個依賴和被依賴的,僅供參考,肯定不全的,下面也一樣。
$ export PATH=$PATH:/home/spy/Software/arm-2013.11/bin
$ cd /home/spy/Work/sources/glibc/glibc-build
$ ../glibc-2.19/configure --prefix=/usr/app/glibc --build=x86_64-unknown-linux-gnu --host=arm-none-linux-gnueabi
$ make
$ make install install_root=/home/spy/Work/sources/glibc/glibc
--------------------------------------------------------------------------------
源碼中并沒有makefile檔案,這需要運作configure來生成。
通過“configure --help”檢視可用的選項。
prefix為安裝目錄;
build和host用來指定系統類型。可看看autoconf的手冊中“Specifying target triplets”。
我們編譯程式是用在其他的系統中,如果不指定install_root,它就要往prefix指定的目錄安了,
不要這樣,我的路徑還好,如果是/usr/lib/,那就破壞了你正使用的系統,不過我用的是普通使用者,
應該沒權限往那個目錄安。
有了install_root,就會安裝到/home/spy/Work/sources/glibc/glibc/usr/app/glibc,看看
makefile檔案就會明白原理。
那麼把prefix指定為那個完整的目錄,不使用install_root行不行呢。最好别這樣。
建構完glibc,其中的ld.so并不是在/lib/或/usr/lib/中找程式庫,而是在glibc的庫
被安裝到的目錄中找,即'/usr/app/glibc/lib'。
可見,這個prefix會記錄到生成的程式中,是以最好别讓目錄那麼長,那麼亂。
問題又來了,ld.so竟然不在/usr/lib/中找程式庫,這可是傳說中的預設目錄啊。
我的處理是在建構的系統中運作ldconfig,在bash中說。
gmp
============ [/usr/local] https://gmplib.org/
>
< mpfr,mpc,isl,cloog,gcc
$ export PATH=$PATH:/home/spy/Software/arm-2013.11/bin
$ cd /home/spy/Work/sources/gmp/gmp-build
$ ../gmp-5.1.3/configure --prefix=/usr/app/gmp --build=x86_64-unknown-linux-gnu --host=arm-none-linux-gnueabi
$ make
$ make install DESTDIR=/home/spy/Work/sources/gmp/gmp
--------------------------------------------------------------------------------
這個和下面的4個都是為gcc服務的。
這裡的安裝目錄用的是DESTDIR,看看源代碼裡的文檔吧。
libtool: install: warning: remember to run `libtool --finish /usr/local/lib'
安裝時遇到個警告,這個應該和ldconfig這個指令有關,應該是為了glibc的ld程式能找到這個庫,我沒執行這一步。
mpfr
============ [/usr/local] http://www.mpfr.org/
> gmp,
< mpc,gcc
$ export PATH=$PATH:/home/spy/Software/arm-2013.11/bin
$ cd /home/spy/Work/sources/mpfr/mpfr-build
$ ../mpfr-3.1.2/configure --prefix=/usr/app/mpfr --build=x86_64-unknown-linux-gnu --host=arm-none-linux-gnueabi --with-gmp=/home/spy/Work/sources/gmp/gmp/usr/app/gmp
$ make
$ make install DESTDIR=/home/spy/Work/sources/mpfr/mpfr
--------------------------------------------------------------------------------
修改lib/libmpfr.la,
# Libraries that this one depends upon.
dependency_libs=' -L/home/spy/Work/sources/gmp/gmp/usr/app/gmp/lib /usr/app/gmp/lib/libgmp.la'
到
# Libraries that this one depends upon.
dependency_libs=' -L/home/spy/Work/sources/gmp/gmp/usr/app/gmp/lib /home/spy/Work/sources/gmp/gmp/usr/app/gmp/lib/libgmp.la'
也就是把目錄改成完整的,這個過程的原因見mpc。
--------------------------------------------------------------------------------
libtool: install: warning: remember to run `libtool --finish /usr/local/lib'
警告依舊,不管他,怕他影響我正使用系統中的庫。
應該還會看到其他警告,如某個.la檔案被moved,答案也是見mpc。
mpc
============ [/usr/local] http://www.multiprecision.org/
> gmp,mpfr
< gcc
$ export PATH=$PATH:/home/spy/Software/arm-2013.11/bin
$ cd /home/spy/Work/sources/mpc/mpc-build
$ ../mpc-1.0.2/configure --prefix=/usr/app/mpc --build=x86_64-unknown-linux-gnu --host=arm-none-linux-gnueabi --with-gmp=/home/spy/Work/sources/gmp/gmp/usr/app/gmp --with-mpfr=/home/spy/Work/sources/mpfr/mpfr/usr/app/mpfr
$ make
$ make install DESTDIR=/home/spy/Work/sources/mpc/mpc
--------------------------------------------------------------------------------
修改.la檔案,
# Libraries that this one depends upon.
dependency_libs=' -L/home/spy/Work/sources/gmp/gmp/usr/app/gmp/lib -L/home/spy/Work/sources/mpfr/mpfr/usr/app/mpfr/lib /usr/app/mpfr/lib/libmpfr.la /usr/app/gmp/lib/libgmp.la -lm'
到
# Libraries that this one depends upon.
dependency_libs=' -L/home/spy/Work/sources/gmp/gmp/usr/app/gmp/lib -L/home/spy/Work/sources/mpfr/mpfr/usr/app/mpfr/lib /home/spy/Work/sources/mpfr/mpfr/usr/app/mpfr/lib/libmpfr.la /home/spy/Work/sources/gmp/gmp/usr/app/gmp/lib/libgmp.la -lm'
--------------------------------------------------------------------------------
libtool: install: warning: remember to run `libtool --finish /usr/local/lib'
isl
============ [/usr/local] http://freecode.com/projects/isl
> gmp
< gcc
$ export PATH=$PATH:/home/spy/Software/arm-2013.11/bin
$ cd /home/spy/Work/sources/isl/isl-build
$ ../isl-0.12.2/configure --prefix=/usr/app/isl --build=x86_64-unknown-linux-gnu --host=arm-none-linux-gnueabi --with-gmp-prefix=/home/spy/Work/sources/gmp/gmp/usr/app/gmp --with-gmp-exec-prefix=/home/spy/Work/sources/gmp/gmp/usr/app/gmp
$ make
$ make install DESTDIR=/home/spy/Work/sources/isl/isl
--------------------------------------------------------------------------------
# Libraries that this one depends upon.
dependency_libs=' -L/home/spy/Work/sources/gmp/gmp/usr/app/gmp/lib /usr/app/gmp/lib/libgmp.la'
# Libraries that this one depends upon.
dependency_libs=' -L/home/spy/Work/sources/gmp/gmp/usr/app/gmp/lib /home/spy/Work/sources/gmp/gmp/usr/app/gmp/lib/libgmp.la'
--------------------------------------------------------------------------------
libtool: warning: remember to run 'libtool --finish /usr/local/lib'
cloog
============ [/usr/local] http://www.bastoul.net/cloog/index.php
> isl,gmp
< gcc
$ export PATH=$PATH:/home/spy/Software/arm-2013.11/bin
$ cd /home/spy/Work/sources/cloog/cloog-build
$ ../cloog-0.18.1/configure --prefix=/usr/app/cloog --build=x86_64-unknown-linux-gnu --host=arm-none-linux-gnueabi --with-isl=system --with-isl-prefix=/home/spy/Work/sources/isl/isl/usr/app/isl --with-isl-exec-prefix=/home/spy/Work/sources/isl/isl/usr/app/isl --with-gmp-prefix=/home/spy/Work/sources/gmp/gmp/usr/app/gmp --with-gmp-exec-prefix=/home/spy/Work/sources/gmp/gmp/usr/app/gmp
修改Makefile libcloog-isl.la:
libcloog_isl_la_LDFLAGS = -version-info 4:0:0
-L/home/spy/Work/sources/isl/isl/usr/local/lib
am_libcloog_isl_la_rpath = -rpath /home/spy/Work/sources/isl/isl/usr/app/isl/lib
$ make
$ make install DESTDIR=/home/spy/Work/sources/cloog/cloog
--------------------------------------------------------------------------------
# Libraries that this one depends upon.
dependency_libs=' -L/home/spy/Work/sources/isl/isl/usr/app/isl/lib -L/home/spy/Work/sources/gmp/gmp/usr/app/gmp/lib /usr/app/isl/lib/libisl.la /usr/app/gmp/lib/libgmp.la'
# Libraries that this one depends upon.
dependency_libs=' -L/home/spy/Work/sources/isl/isl/usr/app/isl/lib -L/home/spy/Work/sources/gmp/gmp/usr/app/gmp/lib /home/spy/Work/sources/isl/isl/usr/app/isl/lib/libisl.la /home/spy/Work/sources/gmp/gmp/usr/app/gmp/lib/libgmp.la'
--------------------------------------------------------------------------------
--with-isl=system 目的是使用之前編譯的isl,cloog源碼中有也有份isl。
gcc
============ [/usr/local] http://gcc.gnu.org/
> gmp,mpfr,mpc,isl,cloog
< bash
$ export PATH=$PATH:/home/spy/Software/arm-2013.11/bin
$ cd /home/spy/Work/sources/gcc/gcc-build
$ ../gcc-4.8.2/configure --prefix=/usr/app/gcc --build=x86_64-unknown-linux-gnu --host=arm-none-linux-gnueabi --target=arm-none-linux-gnueabi --enable-shared --enable-threads --enable-languages=c --with-gmp=/home/spy/Work/sources/gmp/gmp/usr/app/gmp --with-mpfr=/home/spy/Work/sources/mpfr/mpfr/usr/app/mpfr --with-mpc=/home/spy/Work/sources/mpc/mpc/usr/app/mpc --with-isl=/home/spy/Work/sources/isl/isl/usr/app/isl --with-cloog=/home/spy/Work/sources/cloog/cloog/usr/app/cloog
$ make
$ make install DESTDIR=/home/spy/Work/sources/gcc/gcc
--------------------------------------------------------------------------------
gcc就是編譯器了,我們編譯軟體就靠它了,gcc也包含一些庫,我們的bash要用到。
gcc的配置選項太多了,我隻額外用了
--enable-shared --enable-threads --enable-languages=c
也不知道是否需要。
我編譯了50分鐘,現在是2014年,我這2手筆記本比較差了,
CPU 1.86GHz,記憶體2G的,DDR2的,單條1G。
bash
============ http://www.gnu.org/software/bash/
> glibc,gcc
<
$ export PATH=$PATH:/home/spy/Software/arm-2013.11/bin
$ cd /home/spy/Work/sources/Bash/bash-build
$ ../bash-4.3/configure --prefix=/usr/app/bash --build=x86_64-unknown-linux-gnu --host=arm-none-linux-gnueabi --without-bash-malloc --with-installed-readline
$ make
$ make DESTDIR=/home/spy/Work/sources/Bash/bash install
--------------------------------------------------------------------------------
--without-bash-malloc --with-installed-readline
對這2個不太了解,隻是為了bash簡單點。
不知道readline幹什麼的,我建構的系統沒有安readline。
--------------------------------------------------------------------------------
在這裡推薦個工具,readelf,這是binutils中的一個指令。可檢視二進制檔案的資訊,
我用它主要是為了看到所依賴的庫。
$ readelf -hld bin/bash
-a選項是列印所有的資訊,我們用-hld就可以了。
看看我們編譯後的bash,它需要gcc中的libgcc_s.so.1,而我電腦中的bash卻不需要那個庫。
--------------------------------------------------------------------------------
有了shell,我們就可以在開發闆中驗證我們編譯的結果了。
至此,我們編譯了glibc,gmp,mpfr,mpc,isl,cloog,gcc,bash。
在複制到SD卡之前,我想應該先把mpfr,mpc,isl,cloog中的改動改回來。
根據prefix,将編譯後的程式複制到SD卡,/usr/lib/和/usr/bin/中添加相應的軟連結。
我并不是在這個時候才制作的軟連結,每編譯過一個程式,發現有bin和lib檔案夾,
就把軟連結做好了,直接複制到SD卡中就可以了。
至于怎麼制作,我不擅長,寫個腳本應該比較好,但我沒學。
/etc/中不必有配置檔案。
在uEnv.txt中,把bootargs的init改為/usr/bin/bash。
如果就這樣啟動的話,會提示找不到libgcc_s.so.1,因為這個庫不在ld.so的搜尋路徑中。
目前的搜尋路徑是/usr/app/glibc/lib。
是以/usr/app/glibc/lib中有個libgcc_s.so.1就可以了,可以放一個軟連結,就像/usr/lib中的。
不要擔心,這隻是臨時的。
接下來我們要在開發闆中運作ldconfig,這是glibc的一部分,它會讀取ld.so.conf檔案中的
路徑,然後建立一個ld.so.cache檔案,這樣ld.so就能利用ld.so.cache找到那些路徑中的庫了。
ld.so.conf檔案不存在,而我們建構的系統還沒有文本編輯器,是以要在啟動之前建立該檔案。
内容就是
/usr/lib
很多文本檔案都以空行結尾,我們也這麼做吧。
那麼這個檔案要放到哪裡呢,一般是/etc/中,但在我們建構的系統中,ldconfig是到
/usr/app/glibc/etc/中找,是以要放到這個目錄中。
好,可以啟動開發闆了,進到shell之後,運作ldconfig。
把/usr/app/glibc/lib中的libgcc_s.so.1删掉,重新開機,看看是不是可以正常運作了?
這樣的方法并不好,應該讓編譯glibc的時候可以指定ld.so的搜尋路徑。
其實我當初用了更不好的方法,我在核心參數中指定了LD_LIBRARY_PATH。
雖然我們沒安什麼程式,但bash是有内置指令的,比如切換目錄的'cd',檢視
目前目錄的'pwd'。
coreutils
============ http://www.gnu.org/software/coreutils/
>
<
$ export PATH=$PATH:/home/spy/Software/arm-2013.11/bin
$ cd /home/spy/Work/sources/coreutils/coreutils-build
也許要先編譯一遍本地版的,先看下面的解釋。
$ ../coreutils-8.22/configure --prefix=/usr/app/coreutils --build=x86_64-unknown-linux-gnu --host=arm-none-linux-gnueabi --enable-install-program=arch,hostname
修改Makefile,.x.1對象,$(abs_top_builddir) 改 /home/spy/Work/sources/coreutils
$ make
$ make install DESTDIR=/home/spy/Work/sources/coreutils/coreutils
--------------------------------------------------------------------------------
--enable-install-program=arch,hostname
預設不安那2個,這樣就安了。
coreutils裡面有我最喜歡的'ls'指令,編譯完後,可在開發闆中驗證下。
linux-pam
============ [/usr] http://linux-pam.org/
>
< util-linux,libcap,
$ cd /home/spy/Work/sources/pam/linux-pam-build
$ ../Linux-PAM-1.1.8/configure --prefix=/usr/app/linux-pam --build=x86_64-unknown-linux-gnu --host=arm-none-linux-gnueabi
$ make
$ make install DESTDIR=/home/spy/Work/sources/pam/linux-pam
--------------------------------------------------------------------------------
pam與認證有關,如果沒有這個,編譯util-linux的時候就不會有login。
util-linux的配置中并沒有指定pam的選項,是以安裝後,我把pam複制一份
放到我交叉編譯器搜尋庫的目錄中了。
我也嘗試過把gcc依賴的庫放到交叉編譯器搜尋庫的目錄中,但遇到了新的問題,
時間關系,沒有研究。
pam的庫中也有個la檔案,根據pam所放的目錄,做類似下面的修改。
libpam_misc.la
# Libraries that this one depends upon.
dependency_libs=' /home/spy/Software/arm-2013.11/arm-none-linux-gnueabi/libc/usr/lib/libpam.la -ldl'
include/security/
我當初記錄了這個東西,有點忘了,可能是依賴pam頭檔案的程式在那個目錄找而不是include/。
編譯其他程式的時候如果提示找不到頭檔案,可改下目錄。
util-linux
============ ftp://ftp.kernel.org/pub/linux/utils/util-linux/
> pam,ncurses
<
我這裡的編譯并沒有用ncurses,如果你要用的話,可先看看後面我編譯ncurses的步驟。
$ export PATH=$PATH:/home/spy/Software/arm-2013.11/bin
$ cd /home/spy/Work/sources/util-linux/util-linux-build
$ ../util-linux-2.24.1/configure --prefix=/usr/app/util-linux --build=x86_64-unknown-linux-gnu --host=arm-none-linux-gnueabi --without-ncurses
$ make
$ su
# make install DESTDIR=/home/spy/Work/sources/util-linux/util-linux
--------------------------------------------------------------------------------
--without-ncurses
我當初還沒編譯ncurses,是以加了這個選項,我不知道ncurses是幹什麼的,這樣等以後
出問題的時候就知道它是幹什麼的了。
libcap
============ https://sites.google.com/site/fullycapable/
> pam
< systemd,
$ export PATH=$PATH:/home/spy/Software/arm-2013.11/bin
将makefile要引入的檔案做如下修改。
CC := arm-none-linux-gnueabi-gcc
BUILD_CC := gcc
AR := arm-none-linux-gnueabi-ar
RANLIB := arm-none-linux-gnueabi-ranlib
LIBATTR := no
$ cd /home/spy/Work/sources/libcap/libcap-2.24
$ make
$ make prefix=/usr/app/libcap lib=lib FAKEROOT=/home/spy/Work/sources/libcap/libcap install
--------------------------------------------------------------------------------
完成以上步驟,複制一份和交叉編譯器的庫放到一起。
systemd
========== [/usr] http://www.freedesktop.org/wiki/Software/systemd/
> libcap
<
$ export PATH=$PATH:/home/spy/Software/arm-2013.11/bin
$ cd /home/spy/Work/sources/systemd/systemd-build
修改configure,避免rpl_malloc的錯誤
if test "$cross_compiling" = yes; then :
ac_cv_func_malloc_0_nonnull=no 改成 yes
$ ../systemd-211/configure --prefix=/usr/app/systemd --with-rootprefix=/usr/app/systemd/root --build=x86_64-unknown-linux-gnu --host=arm-none-linux-gnueabi --disable-seccomp --disable-blkid --disable-kmod --disable-pam --disable-libcryptsetup --disable-audit --disable-acl --disable-xattr --disable-selinux --disable-xz --disable-tcpwrap --disable-gcrypt --disable-qrencode --disable-microhttpd --disable-python-devel --without-python --disable-gudev --disable-apparmor --disable-dbus
$ make
$ make install DESTDIR=/home/spy/Work/sources/systemd/systemd
--------------------------------------------------------------------------------
--with-rootprefix=/usr/app/systemd/root
由于安裝的時候會有一些東西安裝在了app檔案夾之外,指定這個選項為安裝路徑内部就可以了,
root是我随便起的,但最好與其他檔案夾獨立。
後面那些都是可選的軟體包,我全禁用了。
今天一看,竟然有個kmod,我可以告訴你,我建構完的系統好像不能自動載入子產品,也許和這個有關吧。
kmod我後面也安了。
--------------------------------------------------------------------------------
編譯時看到了很多這樣的資訊,不知道是什麼:
libsystemd_internal_la-bus-message.o (symbol from plugin): warning: memset used with constant zero length parameter; this could be due to transposed parameters
/home/spy/Software/arm-2013.11/arm-none-linux-gnueabi/libc/usr/include/bits/poll2.h: In function 'bus_poll':
/home/spy/Software/arm-2013.11/arm-none-linux-gnueabi/libc/usr/include/bits/poll2.h:71:2: warning: call to '__ppoll_chk_warn' declared with attribute warning: ppoll called with fds buffer too small file nfds entries [enabled by default]
return __ppoll_chk (__fds, __nfds, __timeout, __ss, __bos (__fds));
/*------------------------------------------------------------------------------
曾經沒有login時遇到的問題,
localhost login: root
&nbs
http://bbs.ickey.cn/group-topic-id-26263-dialog-1.html#postlist