Minicom:Linux下的終端程序,用於通過串口進行通信,在嵌入式Linux系統中,可以用於主機與目標系統通信,實現串口控制台的功能。
DHCP: 動態主機配置協議。運行實現該協議的服務的主機,通過對客戶發起的DHCP請求進行應答,可以動態的配置客戶機的IP地址等網絡信息。
TFTP: 一種FTP文件傳輸協議。由於實現相對簡單,常用於嵌入式系統獲取版本信息。在嵌入式Linux中,用於目標板從本機獲取Linux內核以及其他文件映像。
NFS:網絡文件系統。運行NFS客戶端的主機,可以從運行NFS服務端的主機安裝網絡文件系統,對於客戶機來說,使用該文件系統與使用本地文件系統沒有任何差別。NFS最常用於基於嵌入式Linux的應用開發的調試階段。
目標系統單板集成階段
作為一個嵌入式Linux系統,最終需要脫離開發環境獨立運行。因此,必須為目標系統准備獨立的文件系統,並配置相應的啟動腳本,服務程序等等。
動態主機配置協議(DHCP)是用來自動給客戶機器分配 TCP/IP 信息的網絡協議。在開發的過程中,目標系統並沒有自己的靜態IP地址,它是在啟動時向DHCP服務器申請,因此需要在主機上配置DHCP服務,以便在目標系統請求IP時,動態為它分配IP地址。
DHCP服務的配置文件為/etc/dhcpd.conf,通過修改該文件進行配置。
1.添加如下的配置信息,生成一個配置示例:
subnet 192.9.200.0 netmask 255.255.255.0{ default-lease-time 1209600; # two weeks max-lease-time 31557600; # one year group{ host target1{ hardware ethernet 00:01:EC:00:00:00; fixed-address 192.9.200.145; option root-path ”/ELDK/…/target”; } } } |
2.在該配置示例的基礎上做如下修改:
將“subnet 192.9.200.145”中的子網地址(192.9.200.145)替換為實際的主機子網地址;
1) 在“host target1”一行中,“target1”為目標板的名稱,將它替換為你希望的名稱;
2) 在“hardware ethernet 00:01:EC:00:00:00”一行中,是設置目標板的MAC地址,將其中的MAC地址替換為實際目標板的地址;
3) 在“fixed-address 192.9.200.145”一行中,是設置將要為該目標板分配的IP地址,把它替換為你想要為目標板分配的實際IP地址;
4) 在“option root-path “/ELDK/…/target””一行中,是設置nfs輸出的文件系統目錄,將它替換為實際要輸出的文件系統目錄。
3.重新啟動dhcp服務,使用如下命令:
# /etc/rc.d/init.d/dhcpd start
4.為避免每次啟動主機都要手工啟動dhcp服務,使用如下命令使得dhcp服務在每次系統啟動時都默認執行:
# chkconfig dhcpd on
配置TFTP
在目標系統的開發過程中,Linux內核是從主機下載到目標系統上解壓並運行的,因此主機必須提供這種文件傳輸服務。Tftp是一種簡單的文件傳輸協議,多用於嵌入系統應用中,因此主機需要配置tftp服務,供下載內核時使用。
1. Tftp服務的配置文件為/etc/xinetd.d/tftp,其內容如下:
service tftp { socket-type=dgram protocol=udp wait=yes user=root server=/usr/sbin/in.tftpd server-args=-s /tftpboot disable=no } |
2.修改配置參數:
Tftp配置參數比較簡單,只需將server-args的參數配置為圖中所示的“-s /tftpboot” ,其他使用默認配置即可。
srver-args參數是一個目錄,該目錄中包含要下載到目標系統中去的linux內核映像文件。
3.在主機上創建/tftp目錄,以供存放內核:
使用如下命令創建/tftp目錄:
# mkdir /tftp
這樣,每次在重新編譯好用於目標系統的內核后,拷貝到該目錄下即可。
4.重新啟動tftp服務:
# killall-USRI xinetd
5.為避免每次啟動主機都要手工啟動tftp服務,使用如下命令使得tftp服務在每次系統啟動時都默認執行:
# chkconfig tftp on
配置NFS服務
網絡文件系統(NFS)是一種在網絡上的機器間共享文件的方法,在開發的過程中,目標系統沒有足夠的本地存儲設備供使用,它可以通過主機提供的NFS服務,使用在主機上的文件系統,就如同位於本地硬盤驅動器上一樣。
1.修改NFS配置文件:
NFS服務的配置文件為/etc/exports,其內容如下:
<nfs-export-dir> *(rw,no-root-squash,no-all-squash)
其中,<nfs-export-dir>表示NFS向目標提供的文件系統目錄,將它替換成具體的輸出目錄。例如:
/ELDK/hardhat/devkit/ppc/8xx/target是ppc/8xx系列目標板缺省安裝的文件系統;也可以是用戶自己為目標板裁減的文件系統目錄。
同時可以有輸出多個目錄,方便開發調試。
2.重新啟動NFS服務:
# /etc/rc/.d/init.d/nfs start。
確認NFS守護進程正在運行。
3.為避免每次啟動主機都要手工啟動nfs服務,使用如下命令使得nfs服務在每次系統啟動時都默認執行:
# chkconfig nfs on
配置內核
# cd / //進入根目錄
# mkdir /develop //建立開發目錄
# cp -r /ELDK1.0/target/kernel_src/linux /develop //拷貝內核源代碼到develop目錄
# cd /develop/linux
# make menuconfig
編譯內核
內核配置結束后,需要對內核源代碼進行編譯,得到目標系統運行所需的linux內核映象文件。
編譯內核的步驟為:
1) 進入linux源代碼目錄下:
# cd /develop/linux
2) 如果以前曾經編譯過內核,則清除所有舊的目標文件,如果沒有跳到第3步:
# make clean
3) 找出每個源文件的依賴性,並把它引入各個 Makefile 中:
# make dep
4) 編譯內核,生成內核映像文件:
# make ARCH=<arch> CROSS_COMPILE=<cross_compile> bzImage
此處的<arch>和<cross_compile>根據目標系統的實際體系架構填寫。例如:如果是目標系統是PowerPC架構,命令為:
# make ARCH=ppc CORSS_COMPILE=powerpc-linux- bzImage
完成上述步驟后,內核映像文件生成,它的位置在/develop/linux/arch/<ARCH>/boot/bzImage
目標系統的根文件系統
與其它操作系統不同,對嵌入式Linux系統而言,文件系統是必須的。我們必須為目標系統配置文件系統,Linux才能正常啟動。才能進行正常的調試和測試。
一 般而言,由於開發階段我們需要目標系統的文件系統可以任意修改,而且可以包含更多的程序以便於我們的調試與測試;而在產 品實際運行階段,我們希望的是目標系統使用盡可能少的存儲空間,使用盡可能少的內存。有更快的速度。針對這兩種不同的需求,在嵌入式Linux的開發當 中,針對開發階段與實際運行階段。我們一般使用不同的目標文件系統配置:
a.開發階段的目標文件系統
為了滿足開發階段對文件操作方便,文件系統容量需求比較大的情況,在開發階段,我們一般使用NFS(網絡文件系統)作為目標文件系統的根文件系統。
目標系統所使用的NFS根文件系統由開發主機上運行的NFS服務所提供。由於運行在開發主機上,主機使用硬盤作為存儲空間,因此目標系統對存儲空間的需求幾乎可以不受限制的得到滿足。
b.實際產品單板中的文件系統
單板中一般配置Flash作為存儲介質。嵌入式Linux系統需要將內核、應用程序以及需要的輔助工具(如登錄Shell、網絡服務等)存放在有限的flash中。
為 了做到在小容量介質中駐留Linux操作系統和應用程序。目前嵌入式Linux領域廣泛使用busybox構建一個最小 的有可操作Shell的板上Linux系統。Busybox是一個可以自由獲取的免費軟件。它將Linux常用的命令集成在一個可執行文件中,由於采用多 調用(MultiCall)的方式。Busybox能夠做到非常小的體積。
如果單板系統中需要使用函數庫,則可 以考慮使用uclibc。Uclibc同樣是可以免費獲取的軟件,它通過重寫C語言的 函數庫,以達到減小函數庫所占用存儲空間的目的。與標准的GNU C函數庫相比,uclibc能夠做到顯著節省存儲空間。一般而言,只需要使用 uclibc函數庫重新編譯應用程序,應用程序就可以在uclibc環境下執行。
根據單板應用程序的復雜程度以及最終的占用空間對比。單板可以采用如下兩種方式之一來構建系統:
靜態連接的busybox + 靜態連接的應用程序;
uclibc + 動態連接的busybox + 動態連接的應用程序.
1.目標機的啟動(目標機是指用於仿真開發板的PC):
容量小於1Mbyte的內核的啟動,在Linux平台下,使用命令:dd if=bzImage of=/dev/fd0 就可以制作所需要的啟動軟盤。
1.1容量大於1Mbyte的內核的啟動
由 於Linux操作系統啟動機制的限制,對於大於1Mbyte的內核,無法由代碼自身自行啟動,而是需要借助啟動裝載器 (Boot Loader)來啟動。對於軟盤而言,最適用的啟動裝載器就是SYSLINUX。制作使用SYSLINUX啟動Linux內核的軟盤的步驟如 下。
格式化軟盤,可以使用Shell命令:
mkfs –t msdos /dev/fd0
拷貝編譯的Linux內核到軟盤,使用如下Shell命令:
mount /dev/fd0 /mnt/floppy
cp bzImage /mnt/floppy
編輯軟盤上的syslinux.cfg,配置啟動參數,該文件缺省內容如下:
default linux(默認啟動Linux)
prompt 1(允許啟動提示)
timeout 600(設定超時時限為600);
label linux(此處增加一個名為Linux的啟動選項)
kernel bzImage(指明內核文件名為bzImage)
append root=/dev/nfs,rw ip=bootp(內核命令行參數)。
卸載軟盤,使用Shell命令:
umount /mnt/floppy
使該軟盤可以啟動,使用Shell命令:
syslinux /dev/fd0
1.2環境搭建
由於目標機在內核啟動階段需要從開發主機處獲取自身的網絡配置參數,並且最終從開發主機處安裝NFS根文件系統並正常啟動到shell提示符。所以首先要保證開發主機與目標機之間有正常的網絡連接。
由於目標機用戶獲取網絡配置信息的協議Bootp是運行在MAC層的。因此需要注意讓目標機與開發主機位於同一個二層網絡上,因為Bootp協議無法穿透有些IP路由器等網絡設備。
啟動開發主機並運行相應服務
DHCP服務,該服務為目標機自動配置IP地址、網關、NFS服務器地址、NFS服務目錄等信息。
NFS服務,該服務為目標機提供運行所需要的根文件系統。
1.3運行應用程序
通過一個簡單的“hello world”程序的編寫和運行,使用戶了解如何開發在主機開發應用程序,並使其運行在目標系統上。以下的c程序例子是基於PowerPC目標系統,使用ppc-8xx-的交叉開發工具鏈。步驟如下:
1. 在主機上,編寫“hello world”程序,如下:
# include<stdio.h>
int main(int argc,char**argv){
printf(“hello world!\n”);
return 0;
}
2. 使用交叉編譯器編譯可執行程序:
# ppc-8xx-gcc -o hello hello.c
3. 把可執行程序拷貝到主機向目標系統輸出的NFS文件系統的目錄中:
# cp hello /ELDK1.0/target/arch/ppc/target_fs
4. 在目標系統上運行hello程序:
#./hello
Hello world!
2.目標板的啟動
2.1制作BOOTROM
與目標機環境不同,由於實際的單板上並沒有現存的啟動程序,因此啟動目標板的第一步,就是要制作啟動並初始化目標板的BOOTROM程序。
2.1.1移植、調試Boot程序
我們使用移植后的U-Boot作為嵌入式Linux的Boot程序。U-Boot是一個可以從因特網上自由下載的開發源代碼的免費軟件,它可以支持多種CPU系列的目標系統的啟動,包括PowerPC、ARM 、X86等。
2.1.2產生燒寫BOOTROM所需的二進制文件
由於各種單板上BOOTROM配置情況的差異,包括BOOTROM容量、BOOTROM地址配置。以及不同CPU架構的單板的啟動機制的差別。需要我們對編譯生成的二進制文件進行相應的處理,才能正確的燒寫到芯片中。需要特別注意以下內容:
CPU上電后開始執行的地址,必須確保相應的跳轉指令位於此處,並正確的跳轉到程序的入口。
由於文件燒寫軟件的限制。為了將所有的代碼都能夠燒寫到芯片中,對於上電時候執行的代碼位於地址高端的CPU架構的單板,需要進行正確的填充,以確保啟動芯片與所配置的地址空間對應的物理位置上有相應的內容。
2.2燒寫BOOTROM
制作好BOOTROM的二進制文件以后,就需要把它燒寫的目標板所使用的BOOTROM芯片中。燒寫BOOTROM芯片一般用燒片器進行,啟動燒片器,選擇正確的BOOTROM芯片類型,裝入上一步中制作好的二進制文件,就可以進行燒寫了。