學做嵌入式Linux系統V0.1(完整版)

來源:互聯網
上載者:User

第一章 前言目的本文的目的,是講述嵌入式Linux系統的建立、開發的一般過程。製作一個小型的Linux的系統,可以移植至其它硬碟、磁碟片、優盤、flash rom……

做一個嵌入式Linux系統究竟要做哪些工作 做一個嵌入式Linux系統究竟需要做哪些工作?也就是本文究竟要講述哪些內容?我先介紹一個脈絡,可以做為我們後面工作的一個總的提綱:第一步、建立交叉編譯環境 沒有交叉開發經驗的讀者,可能一時很難接受這個概念。首先,要明白兩個概念:一般我們工作的機器,稱為開發機、主機;我們製作好的系統將要放到某台機器,如手機或另一台PC機,這台機我們稱為目標主機。我們一般開發機上已經有一套開發工具,我們稱之為原生開發套件,我們一般就是用它們來寫程式,那麼,那什麼又是交叉編譯環境呢?其實一點也不神秘,也就是在開發機上再安裝一套開發工具,這套開發工具編譯出來的程式,如核心、系統工作或者我們自己的程式,是放在目標主機上啟動並執行。那麼或許有初學者會問,直接用原生開發工具為目標主機編譯器不就完了?至少我當初是這麼想的。一般來說,我們的開發機都是X86平台,原生開發套件開發的工具,也針對X86平台,而我們的目標主機可能是PowerPC、IXP、MIPS……所以,我們的交叉編譯環境是針對某一類具體平台的。一般來講,交叉開發環境需要二進位工具程式、編譯器、C連結庫,嵌入式開發常用的這三類軟體是: Binutils Gcc uClibc 當然,GNU包含的工具套件不僅於此,你還要以根據實際需要,進行選擇

第二步、編譯核心 開發工具是針對某一類硬體平台,核心同樣也是。這一步,我們需要用第一步中建立的工具,對核心進行編譯,對於有核心編譯經驗的人來說,這是非常簡單的;

第三步、建立根檔案系統 也就是建立我們平常看到的bin、dev、proc……這一大堆目錄,以及一些必備的檔案;另外,我們還需要為我們的目標系統安裝一些常用的工具軟體,如ls、ifconfig……當然,一個辦法是找到這些工具的原始碼,用第一步建立的交叉編譯工具來編譯,但是這些軟體一是數量多,二是某些體積較大,不適合嵌入式系統,這一步,我們一般都是用busybox來完成的,包括系統引導軟體init; 最後,我們為系統還需要建立初始化的引導檔案,如inittab……

第四步、啟動系統 在這一步,我們把建立好的目標、檔案、程式、核心及模組全部拷貝到目標機儲存空間上,如硬碟。然後為系統安裝bootloader,對於嵌入式系統,有許多引導程式可供我們使用。不過它們許多都有硬體平台的限制。當然,如果你是工作在X86,可以直接用lilo來引導,事實上,本文就是採用的lilo。 做到這一步,將目標存放裝置掛上目標機,如果順利,就可以啟動系統了。 當然,針對某些特別的平台,不能像硬碟這樣拷貝了,需要讀卡機、燒錄……但是基本的方法是相通的!

第五步、最佳化和個人化系統 通過前四步,我們已經得到了一個可以正常工作的系統。在這一步裡,就是發揮你想像的時候了……

本文的工作環境項目根目錄/home/kendo/project ------>;我將它指定至PATH:$PRJROOT 子目錄及說明目錄 內容 bootloader 目標板的引導載入程式,如lilo等 build-tools 建立交叉編譯平台的工具源碼 debug 調試工具及所有相關包 doc 項目中用到的所有文檔 images 編譯好的核心映像,以及根檔案系統 kernel 各個版本的Linux核心源碼 rootfs 製作好的根檔案系統 sysapps 目標板將要用到的系統應用系統,比如thttpd,udhcpd等 tmp 存放臨時檔案 tools 編譯好的跨平台開發工具鏈以及C連結庫

工作的指令碼 #!/usr/bin

export PROJECT=skynet export PRJROOT=/home/${PROJECT} export TARGET=i386-linux export PREFIX=${PRJROOT}/tools export TARGET_PREFIX=${PREFIX}/${TARGET} export PATH=${PREFIX}/bin:/bin:/sbin:/usr/bin:/usr/sbin

cd $PRJROOT

第二章 建立交叉編譯環境在CU中發表的另一篇同名的貼子裡,我講述了一個全手工建立交叉編譯環境的方法。目前,建立交叉編譯環境,包括建立根檔案,一般來講,有兩種方法:手功建立可以得到最大程式的個人化定製,缺點是過程繁雜,特別是極易出錯,注意這個“極”字,包括有經驗的開發人員;自動建立無它,方便而。

因為前一篇文章中,已經講述了全手工建立交叉編譯環境的一般性方法,本文就不打算再重複這個步驟了,感興趣的朋友,可以再去搜尋那篇貼子,提醒一點的就是,在準備工具鏈的時候,要注意各個工具版本之間的搭配、每個工具需要哪些補丁,我建議你在google上針對這兩項搜尋一下,準備一個清單,否則…… 本章要講述的是自動建立交叉編譯環境的方法。目標,針對商業硬體平台,廠家都會為你提供一個開發包,我用過XX廠家的IXP425和MIPS的,非常地方便,記得我第一次接觸嵌入式開發,拿著這個開發包自動化建立交叉編譯環境、編譯核心、建立根檔案系統、建立Ram Disk,我反覆做了三四次,結果還不知道自己究竟做了些什麼,呵呵,夠傻吧…… 所以,建議沒有這方面經驗的讀者,還是首先嘗試一下手工建立的方法吧,而本章接下來的內容,是送給曾經被它深深傷害而不想再次去親曆這項工作而又想提高交率而又在通用平台上工作沒有商業開發包的朋友。

建立交叉開發工具鏈準備工具: buildroot-0.9.27.tar.tar 只需要一個軟體?對,其它的不用準備了,buildroot事實上是一個指令碼與補丁的集合,其它需要用到的軟體,如gcc、uClibc,你只需在buildroot中指明相應的版本,它會自動去給你下載。事實上,buildroot到網上去下載所需的所有工作是需要時間的,除非你的頻寬足夠,否則下載軟體時間或許會佔去80%,而我在做這項工作之間,所需的工作鏈全部都在我本地硬碟上,我解壓開buildroot後,建立dl檔案夾,將所有工具源碼的壓縮包拷貝進去,呵呵,buildroot就不用去網上下載了。

我的軟體清單: Linux-libc-headers-2.4.27.tar.bz2 Gcc-3.3.4.tar.bz2 binutils 2.15.91.0.2.tar.bz2 uClibc 0.9.27.tar.bz2 genext2fs_1.3.orig.tar.gz ccache-2.3.tar.gz

將它拷貝到${PRJROOT}/build-tools下,解壓 [root@skynet build-tools]# tar jxvf buildroot-0.9.27.tar.tar [root@skynet build-tools]#cd buildroot 配置它: [root@skynet build-tools]#make menuconfig Target Architecture (i386) --->; 選擇硬體平台,我的是i386 Build options --->; 編譯選項這個選項下重要的是(${PRJROOT}/tools) Toolchain and header file location?編譯好的工具鏈放在哪兒?如果你像我一樣,所有工具包都在本地,不需它到網上自動下載,可以把wget command選項清空; Toolchain Options --->; 工具鏈選項 --- Kernel Header Options 標頭檔它會自動去下載,不過應該保證與你將要用的核心是同一個版本; [] Use the daily snapshot of uClibc? 使用最近的uClibc的snapshot Binutils Version (binutils 2.15.91.0.2) --->; Binutils的版本 GCC compiler Version (gcc 3.4.2) --->; gcc 版本

Build/install c++ compiler and libstdc++? [ ] Build/install java compiler and libgcj? 支援的語言,我沒有選擇java [ ] Enable ccache support? 啟用ccache的支援,它用於編譯時間標頭檔的緩衝處理,用它來編譯器,第一次會有點慢,但是以後的速度可就很理想了,呵呵…… --- Gdb Options 根據你的需要,選擇gdb的支援

Package Selection for the target --->; 這一項我沒有選擇任意一項,因為我打算根檔案系統及busybox 等工具鏈建立成工,手工來做。 Target Options --->; 檔案系統類型,根據實際需要選,我用的ext2;

配置完成後,編譯它: [root@skynet build-tools]#make

這一項工作是非常花時間的,我的工具包全部在本地,也花去我一小時十三分的時間,如果全要下載,我估計網速正常也要多花一兩個鐘頭。

經過漫長的等待(事實上並不漫長,去打了幾把遊戲,很快過去了): …… make[1]: Leaving directory `/home/skynet/build-tools/buildroot/build_i386/genext2fs-1.3' touch -c /home/skynet/build-tools/buildroot/build_i386/genext2fs-1.3/genext2fs #-@find /home/skynet/build-tools/buildroot/build_i386/root/lib -type f -name /*.so/* | xargs /home/skynet/tools/bin/i386-linux-uclibc-strip --remove-section=.comment --remove-section=.note --strip-unneeded 2>;/dev/null || true; /home/skynet/build-tools/buildroot/build_i386/genext2fs-1.3/genext2fs -i 503 -b 1056 / -d /home/skynet/build-tools/buildroot/build_i386/root -q -D target/default/device_table.txt /home/skynet/build-tools/buildroot/root_fs_i386.ext2

大功告成!!!

清點戰利品讓我來看看它究竟做了哪些事情吧: [root@skynet skynet]# cd tools [root@skynet tools]# ls bin bin-ccache i386-linux i386-linux-uclibc include info lib libexec man usr

bin:所有的編譯工具,如gcc,都在這兒了,只是加了些指定的首碼; bin-ccache:如果在Toolchain optaion中沒有選擇對ccache的支援,就沒有這一項了; i386-linux:連結檔案;實際指向include i386-linux-uclibc:uclibc的相關工具; include:供交叉開發工具使用的標頭檔; info:gcc 的info檔案; lib:供交叉開發工具使用的連結庫檔案; ……

現在可以把編譯工具所在目錄XXX/bin添加至PATH了

測試載入器鏈如果你現在寫一個程式,用i386-linux-gcc來編譯,啟動並執行程式會告訴你: ./test: linked against GNU libc 因為程式運行庫會尋到預設的/lib:/usr/lib上面去,而我們目前的uclibc的庫並不在那裡(雖然對於目標機來講,這是沒有錯的),所以,也只能暫時靜態編譯,試試它能否工作了。當然,你也可以在建好根檔案系統後,試試用chroot……

第三章 編譯核心本章的工作,是為目標機建立一個合適的核心,對於建立核心,我想有兩點值得考慮的: 1、功能上的選擇,應該能夠滿足需要的情況下,盡量地小; 2、小不是最終目的,穩定才是;

所以,最好編譯核心前有一份目標機硬體平台清單以及所需功能清單,這樣,才能更合理地裁減核心。

準備工具 Linux核心源碼,我選用的是Linux-2.4.27.tar.bz2

編譯核心將Linux-2.4.27.tar.bz2拷貝至${PRJROOT}/kernel,解壓 #cd linux-2.4.27 //配置 # make ARCH=i386 CROSS_COMPILE=i386-linux- menuconfig //建立源碼的依存關係 # make ARCH=i386 CROSS_COMPILE=i386-linux- clean dep //建立核心映像 # make ARCH=i386 CROSS_COMPILE=i386-linux- bzImage ARCH指明了硬體平台,CROSS_COMPILE指明了這是交叉編譯,且編譯器的名稱為i386-linux-XXX,這裡沒有為編譯器指明路徑,是因為我前面已將其加入至環境變數PATH。

又是一個漫長的等待…… OK,編譯完成,673K,稍微大了點,要移到其它平台,或許得想辦法做到512以下才好,回頭來想辦法做這個工作。

安裝核心核心編譯好後,將核心及設定檔拷貝至${PRJROOT}/images下。 # cp arch/i386/boot/bzImage ${PRJROOT}/images/bzImage-2.4.27-rmk5 # cp vmlinux ${PRJROOT}/images/vmlinux-2.4.27-rmk5 # cp System.map ${PRJROOT}/images/System-2.4.27-rmk5 # cp .config ${PRJROOT}/images/2.4.27-rmk5

我採用了尾碼名的方式重新命名,以便管理多個不同版本的核心,當然,你也可以不用這樣,單獨為每個版本的核心在images下建立對應檔案夾也是可行的。

安裝核心模組完整核心的編譯後,剩下的工作就是建立及安裝模組了,因為我的核心並沒有選擇模組的支援(這樣擴充性差了一點,但是對於我的系統來說,功能基本上定死了,這樣影響也不太大),所以,剩下的步驟也省去了,如果你還需要模組的支援,應該: //建立模組 #make ARCH=i386 CROSS_COMPILE=i386-linux- modules //安裝核心模組至${PRJROOT}/images #make ARCH=i386 CROSS_COMPILE= i386-linux- / >;INSTALL_MOD_PATH=${PRJROOT}/images/modules-2.4.18-rmk5 / >;modules_install

最後一步是為模組建立依存關係,不能使用原生的depmod來建立,而需要使用交叉編譯工具。需要用到busybox中的depmod.pl指令碼,很可惜,我在busybox1.0.0中,並沒有找到這個指令碼,所以,還是借用了busybox0.63中scripts中的depmod.pl。將depmod.pl拷貝至${PREFIX}/bin目錄中,也就是交叉編譯工具鏈的bin目錄。 #depmod.pl / >;-k ./vmlinux –F ./System.map / >;-b ${PRJROOT}/images/modules-2.4.27-rmk5/lib/modules >; / >;${PRJROOT}/images/modules-2.4.27-rmk5/lib/modules/2.4.27-rmk5/modules.dep

註:後面討論移植核心和模組內容時,我只會提到核心的拷貝,因為我的系統並沒有模組的支援。如果你需要使用模組,只需按相同方法將其拷貝至相應目錄即可。

附,核心編譯清單附,核心選擇:核心編譯記錄: Code maturity level options 不選 Loadable module support 不選 Processor type and features 根據實際,選擇處理器類型 General setup --->;

Networking support

PCI support (Any) PCI access mode

PCI device name database

System V IPC

Sysctl support (ELF) Kernel core (/proc/kcore) format

Kernel support for ELF binaries

Power Management support

Memory Technology Devices (MTD) --->; MTD裝置,我用CF卡,不選

Parallel port support --->; 不選 Plug and Play configuration --->; 我的系統用不著隨插即用,不選

Block devices --->;

Loopback device support

RAM disk support (4096) Default RAM disk size (NEW)

Initial RAM disk (initrd) support

Multi-device support (RAID and LVM) --->; 不選

Networking options --->; 基本上都選了

ATA/IDE/MFM/RLL support --->; 用了預設的

Telephony Support --->; 不選

SCSI support --->; 不選

Fusion MPT device support --->; 不選

I2O device support --->; 不選

Network device support --->; 根據實際情況選擇

Amateur Radio support --->; 不選

IrDA (infrared) support --->; 不選

ISDN subsystem --->; 不選

Old CD-ROM drivers (not SCSI, not IDE) --->; 不選

Input core support --->; 不選

Character devices --->;

Virtual terminal

Support for console on virtual terminal

Standard/generic (8250/16550 and compatible UARTs) serial support

Support for console on serial port

Multimedia devices --->; 不選

File systems --->;

Kernel automounter version 4 support (also supports v3)

Virtual memory file system support (former shm fs)

/proc file system support

Second extended fs support

Console drivers --->;

VGA text console 調試時接顯示器用

剩下三個都不要 Sound --->; USB support --->; Kernel hacking --->;

第四章 建立根檔案系統 1、建立目錄構建工作空間時,rootfs檔案夾用來存放根檔案系統, #cd rootfs 根據根檔案系統的基本結構,建立各個對應的目錄: # mkdir bin dev etc lib proc sbin tmp usr var root home # chmod 1777 tmp # mkdir usr/bin usr/lib usr/sbin # ls dev etc lib proc sbin tmp usr var # mkdir var/lib var/lock var/log var/run var/tmp # chmod 1777 var/tmp

對於單使用者系統來說,root和home並不是必須的。準備好根檔案系統的骨架後,把前面建立的檔案安裝到對應的目錄中去。 2、拷貝連結庫把uclibc的庫檔案拷貝到剛才建立的lib檔案夾中: # cd ${PREFIX}/lib [root@skynet lib]# cp *-*.so ${PRJROOT}/rootfs/lib [root@skynet lib]# cp -d *.so.[*0-9] ${PRJROOT}/rootfs/lib

3、 拷貝核心映像和核心模組因為沒有模組,所以拷貝模組就省了,建立boot目錄,把剛才建立好的核心拷貝過來 # cd /home/kendo/control-project/daq-module/rootfs/ # mkdir boot # cd ${PRJROOT}/images # cp bzImages-2.4.18-rmk5 /home/kendo/control-project/daq-module/rootfs/boot

4、 建立/dev下邊的裝置檔案在linux中,所有的的裝置檔案都存放在/dev中,使用mknod命令建立基本的裝置檔案。 mknod命令需要root許可權,不過偶本身就是用的root使用者,本來是建立了一個使用者專門用於嵌入式製作的,不過後來忘記用了…… # mknod -m 600 mem c 1 1 # mknod -m 666 null c 1 3 # mknod -m 666 zero c 1 5 # mknod -m 644 random c 1 8 # mknod -m 600 tty0 c 4 0 # mknod -m 600 tty1 c 4 1 # mknod -m 600 ttyS0 c 4 64 # mknod -m 666 tty c 5 0 # mknod -m 600 console c 5 1 基本的裝置檔案建立好後,再建立必要的符號連結: # ln -s /proc/self/fd fd # ln -s fd/0 stdin # ln -s fd/1 stdout # ln -s fd/2 stderr # ls console fd mem null random stderr stdin stdout tty tty0 tty1 ttyS0 zero

裝置檔案也可以不用手動建立,聽說RedHat /dev下的指令碼MAKEDEV 可以實現這一功能,不過沒有試過……

基本上差不多了,不過打算用硬碟/CF卡來做存放裝置,還需要為它們建立相關檔案,因為我的CF在目標機器上是CF-to-IDE,可以把它們等同來對待,先看看Redhat 下邊had的相關屬性: # ls -l /dev/hda brw-rw---- 1 root disk 3, 0 Jan 30 2003 /dev/hda # ls -l /dev/hda1 brw-rw---- 1 root disk 3, 1 Jan 30 2003 /dev/hda1 對比一下,可以看出,had類型是b,即塊裝置,主編號為3,次編號從0遞增,根限位是 rw-rw----,即660,所以: # mknod -m 660 hda b 3 0 # mknod -m 660 hda1 b 3 1 # mknod -m 660 hda2 b 3 2 # mknod -m 660 hda3 b 3 3

5、添加基本的應用程式未來系統的應用程式,基本上可以分為三類: 基本系統工具,如ls、ifconfig這些…… 一些服務程式,管理工具,如WEB、Telnet…… 自己開發的應用程式

這裡先添加基本的系統工具,有想過把這些工具的代碼下載下來交叉編譯,不過實在是麻煩,用BusyBox,又精簡又好用…… 將busybox-1.00.tar.gz下載至sysapps目錄下,解壓: #tar zxvf busybox-1.00.tar.gz #cd busybox-1.00 //進入配置菜單 #make TARGET_ARCH=i386 CROSS=i386-linux- PREFIX=${PRJROOT}/rootfs menuconfig //建立依存關係 #make TARGET_ARCH=i386 CROSS= i386-linux- PREFIX=${PRJROOT}/rootfs dep //編譯 #make TARGET_ARCH=i386 CROSS= i386-linux- PREFIX=${PRJROOT}/rootfs //安裝 #make TARGET_ARCH=i386 CROSS= i386-linux- PREFIX=${PRJROOT}/rootfs install

# cd ${PRJROOT}/rootfs/bin # ls addgroup busybox chown delgroup echo kill ls mv ping rm sleep adduser chgrp cp deluser grep ln mkdir netstat ps rmdir umount ash chmod date dmesg hostname login mount pidof pwd sh vi 一下子多了這麼多命令…… 配置busybox的說明: A、如果編譯時間選擇了: Runtime SUID/SGID configuration via /etc/busybox.conf 系統每次運行命令時,都會出現“Using fallback suid method ” 可以將它去掉,不過我還是在/etc為其建了一個檔案busybox.conf搞定; B、 Do you want to build BusyBox with a Cross Compiler? (i386-linux-gcc) Cross Compiler prefix 這個指明交叉編譯器名稱(其實在編譯時間的命令列已指定過了……) C、安裝選項下的(${PRJROOT}/rootfs) BusyBox installation prefix,這個指明了編譯好後的工具的安裝目錄。 D、靜態編譯好還是動態編譯好?即是否選擇 [ ] Build BusyBox as a static binary (no shared libs) 動態編譯的最大好處是節省了寶貴空間,一般來說都是用動態編譯,不過我以前動態編譯出過問題(其實是庫的問題,不關busybox的事),出於慣性,我選擇了靜態編譯,為此多付出了107KB的空間。 E、其它命令,根據需要,自行權衡。

6、系統初始設定檔案核心啟動時,最後一個初始化動作就是啟動init程式,當然,大多數發行套件的Linux都使用了與System V init相仿的init,可以在網上下載System V init套件,下載下來交叉編譯。另外,我也找到一篇寫得非常不錯的講解如何編寫初始設定檔案的檔案,bsd-init,回頭附在後面。不過,對於嵌入式系統來講,BusyBox init可能更為合適,在第6步中選擇命令的時候,應該把init編譯進去。 #cd ${PRJROOT}/rootfs/etc #vi inittab 我的inittal檔案如下: #指定初始設定檔案 ::sysinit:/etc/init.d/rcS #開啟一個串口,傳輸速率為9600 ::respawn:/sbin/getty 9600 ttyS0 #啟動時執行的shell ::respawn:/bin/sh #重啟時動作 ::restart:/sbin/init #關機時動作,卸載所有檔案系統 ::shutdown:/bin/umount -a –r

儲存退出;

再來編寫rcS指令碼: #mkdir ${PRJROOT}/rootfs/etc/init.d #cd ${PRJROOT}/rootfs/etc/init.d #vi rcS 我的指令碼如下: #!/bin/sh

#Set Path PATH=/sbin:/bin export PATH

syslogd -m 60 klogd

#install /proc mount -n -t proc none /proc

#reinstall root file system by read/write mode(need: /etc/fstab) mount -n -o remount,rw /

#reinstall /proc mount -n -o remount,rw -t proc none /proc

#set lo ip address ifconfig lo 127.0.0.1

#set eth0 ip address #當然,這樣子做只是權宜之計,最後做的應該是在這一步引導網路啟動指令碼,像RedHat #那樣,自動讀取所有指定的設定檔來啟動 ifconfig eth0 192.168.0.68 netmask 255.255.255.0

#set route #同樣的,最終這裡應該是運行啟動路由的指令碼,讀取路由設定檔 route add default gw 192.168.0.1

#還差一個運行服務程式的指令碼,哪位有現成的嗎? #網卡/路由/服務這三步,事實上可以合在一步,在rcS這一步中,做一個迴圈,運行指定啟動目錄下的所有腳,先將就著這麼做吧,確保系統能夠正常啟動了,再來寫這個指令碼。

#set hostname hostname MyLinux

儲存退出。

編寫fstab檔案 #vi fstab 我的fstab很簡單: /dev/hda1 / ext2 defaults 1 1 none /proc proc defaults 0 0

第五章 讓MyLinux能夠啟動前一章,我們把編譯好的核心、應用程式、設定檔都拷貝至rootfs目錄對應的子目錄中去了,這一步,就是把這些檔案移植至目標機的儲存空間。這裡,我是先另外拿一塊硬碟,掛在我的開發機上做的測試,因為我的本本用來寫文檔,PC機用來做開發機,已經沒有另外的機器了……但是本章只是講述一個一般性的過程,並不影響你直接在目標主機上的工作。因為以後目標機識別硬碟序號都是hda,而我現在直接掛上去,則會是hdb、hdc……這樣,安裝lilo時有點麻煩(雖然也可以實現)。所以我想了另一個辦法: 把新硬碟掛在IDE0的primary上,進入linux後,會被認為是had; 原來主機的裝Redhat的硬碟,我將它從IDE0的primary上變到了IDE1 的primary,因為它的lilo早已裝好,基本上不影響系統的使用;

分區和格式化 BIOS中改為從第二個硬碟啟動;也就是從我原來開發機啟動,新的硬碟被識別成了had。 #fdisk /dev/hda 用d參數刪除已存在的所有分區用n參數建立一個分區,也是就/dev/hda1 格式化 #mkfs.ext2 /dev/hda1

安裝bootloader 因為我是X86平台,所以直接用了lilo,如果你是其這平台,當然,有許多優秀的bootloader供你選擇,你只需查看其相應的說明就可以了。 編譯lilo設定檔,我的設定檔名為target.lilo.conf,置於${PRJROOT}/rootfs/etc目錄。內容如下所示: boot=/dev/hda disk=/dev/hda bios=0x80 image=/boot/bzImage-2.4.18-rmk5 label=Linux root=/dev/hda1 append="root=/dev/hda1" read-only

//建立檔案夾,為mount做新準備 #mkdir /mnt/cf //把目標硬碟mount上來 #mount –t ext2 /dev/hdc1 /mnt/cf 回到rootfs #cd ${PRJROOT}/rootfs 拷貝所有檔案至目標硬碟 #cp –r * /mnt/cf

這樣,我們所有的檔案都被安裝至目標硬碟了,當然,它還不能引導,因為沒有bootloader。使用如下命令: # lilo -r /mnt/cf -C etc/target.lilo.conf Warning: LBA32 addressing assumed Added Linux * -r :改變根目標為/mnt/cf ,這樣設定檔其實就是/mnt/cf/etc/target.lilo.conf,也就是我們先前建立的檔案。當然,完成這一步,需要lilo22.3及以後版本,如果你的版本太舊,比如Redhat9.0內建的,就會出現下面的資訊: #lilo –r /mnt/cf –C etc/target.lilo.conf Fatal: open /boot/boot.b: No such file or directory 這時,你需要升級你的lilo,或者重新安裝一個。

啟動系統 #umount /mnt/cf #reboot

將BIOS改為從IDE0啟動,也就是目標硬碟。如果一切順利,你將順利進入一個屬於你的系統。

回頭再來看看我們的工作空間吧 [root@skynet lib]# df /dev/hda1 Filesystem 1K-blocks Used Available Use% Mounted on /dev/hda1 3953036 1628 3750600 1% /mnt/cf

總共花去了我1628KB的空間,看來是沒有辦法放到磁碟片裡邊去了^o^,不過一味求小,並不是我的目標。

[root@skynet skynet]# ls ${PRJROOT} bootloader build-tools debug doc images kernel rootfs sysapps tmp tools 這幾個目錄中的檔案,呵呵,與本文一開頭規劃的一樣

[root@skynet skynet]# ls build-tools/ buildroot buildroot-0.9.27.tar.tar 包含了buildroot源碼及壓縮包,事實上buildroot下邊還包括了GNU其它工具的源碼、編譯檔案等諸多內容,是我們最重要的一個檔案夾,不過到現在它已經沒有多大用處了,如果你喜歡,可以將它刪除掉(不建議)。

[root@skynet skynet]# ls images 2.4.18-rmk5 bzImage-2.4.18-rmk5 System-2.4.18-rmk5 vmlinux-2.4.18-rmk5 核心映像及設定檔等,如果你有模組,因為還有相應的目錄

[root@skynet skynet]# ls kernel/ linux-2.4.27 linux-2.4.27.tar.bz2 核心源碼及壓縮包

[root@skynet skynet]# ls rootfs/ bin boot dev etc home lib linuxrc proc root sbin tmp usr var 製作好的根檔案系統,重中之重,注意備份……

[root@skynet skynet]# ls sysapps/ busybox-1.00 busybox-1.00.tar.gz busybox-1.00源碼包,或許你還要繼續添加/刪除一些命令……

[root@skynet skynet]# ls tools bin i386-linux i386-linux-uclibc include info lib man 這個也很重要,我們製作好的交叉開發工具鏈。如果你要繼續開發程式,這個目錄重要性就很高了。

其它目錄暫時是空的。

第六章 完善MyLinux 關於進一步的調試,你可以在開發機上使用chroot /mnt/cf /bin/sh這樣的命令,以使我們在目標根檔案系統上工作。

支援多使用者因為我在編譯busybox時,已經將它的多使用者那一大堆命令編譯了進來。現在關鍵是的要為其建立相應的檔案;進入原來的開發機,進入rootfs目錄,切換根目錄 #chroot rootfs/ /bin/sh A、 建立/etc/passwd檔案,我的檔案內容如下: root:x:0:0:root:/root:/bin/bash B、 建立/etc/group檔案,我的檔案內容如下: root:x:0: bin:x:1: sys:x:2: kmem:x:3: tty:x:4: tape:x:5: daemon:x:6: disk:x:7: C、 為root建立密碼 #passwd root

試試用addgroup/addusr……這堆命令。然後重啟,從目標硬碟上啟動;從console口,9600登陸試試(因為我在inittab中啟用了ttyS0,我未來的目標機,是沒有顯卡的,需要從console口或SSH進去管理) MyLinux login: root Password:

BusyBox v1.00 (2004.10.10-04:43+0000) Built-in shell (ash) Enter 'help' for a list of built-in commands.

~ # 成功了……

增加WEB Server Busybox裡邊有httpd選項,不過我編譯時間並沒有選擇,所以還是自己來安裝。我使用的軟體是thttpd-2.25b.tar.gz,將它移至sysapps目錄下。 [root@skynet sysapps]# tar zxvf thttpd-2.25b.tar.gz [root@skynet sysapps]# cd thttpd-2.25b //配置 [root@skynet thttpd-2.25b]# CC=i386-linux-gcc ./configure --host=$TARGET …… i386-linux-gcc -static htpasswd.o -o htpasswd -lcrypt make[1]: warning: Clock skew detected. Your build may be incomplete. make[1]: Leaving directory `/home/skynet/sysapps/thttpd-2.25b/extras' //拷貝至根檔案目錄 [root@skynet thttpd-2.25b]# cp thttpd ${PRJROOT}/rootfs/usr/sbin //trip處理 [root@skynet thttpd-2.25b]# i386-linux-strip ${PRJROOT}/rootfs/usr/sbin/thttpd

from:  http://www.lslnet.com/linux/docs/linux-4529.htm

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.