注意路徑一定要寫對,否則將不會有效。重新登錄系統(不必重啟機器,開始->logout 即可),使以上設置生效,在命令行輸入arm-linux-gcc –v,會出現如下信息,這說明交叉編譯環境已經成功安裝。
七、Bootloader文件的原理、移植和編譯
1、uboot代碼移植
首先執行如下命令,分別創建工作目錄/opt/FriendlyARM/mini6410/linux和臨時目錄,并把光盤中linux 目錄中的所有文件都復制到/tmp/linux 目錄中,
#mkdir –p /opt/FriendlyARM/mini6410/linux
#mkdir /tmp/linux
然后在工作目錄/opt/FriendlyARM/mini6410/linux 中執行解壓安裝U-boot 源代碼
#tar xvzf /tmp/linux/ u-boot-mini6410-20101106.tar.gz
將u-boot代碼加壓到opt/FriendlyARM/mini6410/linux/u-boot-mini6410目錄下。
uboot代碼目錄結構:
板級移植需要修改的板級配置文件:
在 opt/FriendlyARM/mini6410/linux/u-boot-mini6410目錄下找到makefile文件,打開文件可以看到幾個相關的編譯選項,如下:
mini6410_nand_config-ram128 // 為系統內存128M,從NANDFLASH啟動的設備生成編譯配置文件
mini6410_sd_config-ram128 // 為系統內存128M,從SD卡啟動的設備生成編譯配置文件
mini6410_nand_config-ram256 // 為系統內存256M,從NANDFLASH啟動的設備生成編譯配置文件
mini6410_sd_config-ram256 // 為系統內存256M,從SD卡啟動的設備生成編譯配置文件
進入uboot源代碼根目錄:cd /opt/FriendlyARM/mini6410/linux/u-boot-mini6410
生成配置文件:make mini6410_nand_config-ram256
開始編譯:make
最終生成u-boot.bin文件,用于下載到FLASH上。為了便于區分,可以將u-boot.bin文件改名為u-boot_nand-ram256.bin。
另外,我們也可以選擇編譯用于SD卡啟動的uboot文件。
要把新編譯生成的u-boot.bin下載到開發板的FLASH上,需要先用SD卡上的uboot啟動6410開發板,SD卡啟動在串口下顯示如下用戶菜單:
[f]:輸入f,格式化FLASH,如上圖所示,
[v]:輸入v,將uboot.bin文件下載到FLSAH上,如下圖所示:
注意,下載uboot時需要使用dnw.exe工具,且只有先輸入v以后,dnw.exe工具上的狀態才會顯示[USB:ok]
將uboot下載到FLASH以后,切換啟動開關后,單板重新上電,啟動FLASH上的uboot,如下圖所示:
上面菜單中的選項,首先要了解[k],下載linux內核鏡像文件,下載內核文件之前,我們需要先編譯得到linux內核文件。
八、Linux內核文件的原理、移植和編譯
1、Liinux內核代碼移植
進入工作目錄/opt/FriendlyARM/mini6410/linux 執行,如下命令,生成生成linux-2.6.38 目錄,如下圖所示
#tar xvzf /tmp/linux/ linux-2.6.38-20110325.tar.gz
2、Linux內核代碼編譯,首先進入linux-2.6.38 目錄,
#make distclean
【2】配置內核,生成新的配置文件 .config
#make menuconfig ARCH=arm
Tiny6410開發板已經為我們準備好了相關的配置文件,所以這一步可以省略。Tiny6410原配的是4.3寸的觸摸屏,所以使用config_mini6410_n43作為內核編譯的配置文件。
【3】編譯內核
#make uImage ARCH=arm CROSS_COMPILE=arm-linux-
輸入#make zImage,開始編譯內核,在arch/arm/boot 目錄下生成linux 內核映象文件zImage。
將編譯得到的內核鏡像文件zImage通過uboot下載到FLASH上運行,
內核在啟動期間進行的最后操作之一就是安裝根文件系統,并讀取根文件系統中的配置文件,所以接下來我們要學習根文件系統。
九、制作用于Linux內核啟動的根文件系統
1、根文件系統的作用和工作原理
首先,根文件系統是Linux(或者說是UNIX類)操作系統運行時所需要的特有文件系統。根文件系統不僅具有普通文件系統的存儲數據文件的功能,還被操作系統用來存儲運行時所需要的一些特殊文件。這些特殊文件包括:busybox (提供 shell 命令集)、配置文件(通常位于/etc目錄下用來初始化和布局你的文件系統)、設備文件(位于/dev目錄下)、必要的庫文件。設備文件實際上保存著對應設備的一些相關參數,操作系統通過使用它們來與應用程序進行接口,并與設備進行交互。因此根文件系統是Linux運行時所必須的。
另外,為了讓內核文件的大小合適,不可能把所有的功能都編譯到內核文件中,所以有些內核需要的功能是以內核模塊的形式存在的(例如一些驅動程序)。為了使內核文件在運行的時候可以找到并加載這些內核模塊, 就需要將內核模塊保存在根文件系統中。其實根文件系統就是一個普通的文件,它的制作過程是:
(1)按照Linux內核要求,制作根文件系統的所需要的根目錄和子目錄,
(2)將內核運行需要的文件編譯并保存到正確的目錄,
(3)使用專門的工具將整個目錄轉換成合適的鏡像文件,這個文件可以直接燒寫到存儲設備上去。
2、手動創建根文件系統目錄和文件:這個工作和系統的存儲介質無關
#mkdir rootfs
#cd rootfs
#mkdir bin dev etc lib proc sbin sys usr mnt tmp var
#mkdir usr/bin usr/lib usr/sbin lib/modules
(2)創建設備文件(如果不創建這兩個設備文件,在文件系統啟動時會出現錯誤信息,不能初始化控制臺。)
#cd dev/
#mknod -m 666 console c 5 1
#mknod -m 666 null c 1 3
#cd..
(3)安裝/etc目錄
/etc目錄下是一些配置文件etc/inittab etc/profile etc/fstab etc/init.d/rcs和具體硬件無關,各種機器上的這些配置文件大同小異可以復用。
因為這些配置文件和系統啟動相關,所以在學習配置文件之前,先簡單了解一下系統的啟動過程:
在linux內核啟動到start_kernel()函數的最后,通過調用init()函數,創建第一個核心線程,核心線程主要進行一些外設初始化工作,包括調用do_basic_setup()完成外設及其驅動程序的加載和初始化,完成文件系統初始化和root文件系統的安裝。當do_basic_setup()函數返回init(),init()又打開了/dev/console設備,重定向三個標準的輸入輸出文件stdin、stdout和stderr到控制臺,最后,搜索文件系統中的init程序(sbin目錄下的init文件,其實也是busybox文件)或者由init=命令行參數指定的程序,并使用 execve()系統調用加載執行init程序。此時Linux完成內核啟動,開始運行init程序,init程序需要讀取配置文件/etc/inittab。所以inittab是系統執行的第一個配置文件。當 Busybox 的初始化程序執行時,首先試圖在/etc 下查找啟動文件inittab,如果找到則按照inittab 文件定義的順序執行;如果找不到inittab,則默認執行/etc/init.d/rcS 腳本,之后啟動相應的 shell。在 Busybox 的inittab 文件中,通常定義系統初始化時執行的也是/etc/init.d/rcS 腳本。也就是說,無論inittab 文件的存在與否,Busybox 初始化時,都會先執行rcS 腳本。
所以,接下來我們需要學習的是:
1、inittab文件結構
2、rcS腳本語法
inittab文件中每個登記項的結構都是一樣的,分別以冒號“:”分隔的4個字段。具體如下:
identifier : run_level : action : process
其中,各字段以及與其相關的說明如下:
identifier:登記項標識符,最多為4個字符。用于惟一地標識/etc/inittab文件中的每一個登記項
run_level:系統運行級,即執行登記項的init級別。用于指定相應的登記項適用于哪一個運行級,即在哪一個運行級中被處理。如果該字段為空,那么相應的登記項將適用于所有的運行級。在該字段中,可以同時指定一個或多個運行級,其中各運行級分別以數字0.1.2.3.4.5.6或字母a、b、c表示,且無需對其進行分隔。
action:動作關鍵字。用于指定init進程對相應進程(在“process”字段定義)所實施的動作。具體動作包括:
1、boot:
2、bootwait:
3、initdefault:
4、off:
5、once:
6、ondemand:
7、powerfail
8、powerwait
9、respawn
10、sysinit
11、wait:
process:所要執行的shell命令。任何合法的shell語法均適用于該字段。
嵌入式Linux系統的inittab文件沒有運行級別的概念,所以大致的內容如下:
::sysinit:/etc/init.d/rcS ## 指定系統啟動后首先執行的文件
::respawn:-/bin/login -f root ## 自動作為root賬戶登錄
::askfirst:-/bin/sh ## 類似respawn,它將會促使init在控制臺上顯示“Please press Enter to active this console”的信息,并在重新啟動之前等待用戶按下enter鍵
::ctrlaltdel:/sbin/reboot ## 設置ctrl+alt+del鍵對應的動作(重啟文件系統)
::shutdown:/bin/umount -a -r ## 設置關機時對應的動作(卸載所有文件系統)
::restart:/sbin/init ## 設置系統重啟時對應的動作(運行的init程序)
創建etc/init.d/rcS文件:rcS文件是一個腳本文件,借助這個腳本可以設置各種程序開機后自動運行,也可進行其他系統設置,類似于Windows系統中的自動批處理文件。
#!/bin/sh ## 符號#!用來告訴系統它后面的參數是用來執行該文件的程序
PATH=/sbin:/bin:/usr/sbin:/usr/bin ## 首先設置了PATH環境變量,只是為了后續命令使用方便
runlevel=S
prevlevel=N
umask 022
export PATH runlevel prevlevel
/bin/hostname zinix
/bin/mount -n -t usbfs none /proc/bus/usb
echo /sbin/mdev > /proc/sys/kernel/hotplug
/sbin/mdev -s
/bin/hotplug
# mounting file system specified in /etc/fstab
mkdir -p /dev/pts
mkdir -p /dev/shm
注意最后還要改變它的屬性使它能夠執行
創建etc/fstab文件:fstab文件描述系統中各種文件系統的信息,應用程序讀取這個文件,然后根據其內容進行自動掛載的工作
device mount-point type options dump fsck order
文件中各字段的意義如下:
1)device:要掛接的設備,如/dev/mtdblockl;
2)mount-point:掛接點;
3)type:文件系統類型;
4)options:掛接參數,以逗號隔開;
5)dump和fsck order:用來決定控制dump、fsck程序的行為。
創建用戶和組文件:
在etc目錄下增加passwd和group兩個文件。首先增加passwd文件,passwd一共由7個字段組成,6個冒號將其隔開。其含義分別為:
1)用戶名;
2)是否有加密口令,x表示有,不填表示無,采用MD5、DES加密;
3)用戶ID;
4)組ID;
5)注釋字段;
6)登錄目錄;
7)所使用的shell程序。
passwd的內容為root:x:0:0:root:/root:/bin/sh
只有增加了passwd文件,啟動以后命令行才會顯示[root@zinix /]# ,否則只會顯示[@zinix /]#
group共由4個字段組成,3個冒號將其隔開。含義分別為:
1)組名;
2)是否有加密口令,同passwd;
3)組ID;
4)指向各用戶名指針的數組。
/home/work/rootby/etc/group內容如下:
root:x:0:
安裝glibc庫
在開發板上需要加載器和動態庫,執行如下幾個命令:
$mkdir-p/home/work/rootby/lib
$cd/home/tools/gcc-3.4.5-glibc-2.3.6/arm-linux/lib
$cp*.SO*/home/work/rootby/lib-d
(4)編譯內核模塊
#make modules ARCH=arm CROSS_COMPILE=arm-linux-
(5)安裝內核模塊
#make modules_install ARCH=arm INSTALL_MOD_PATH=/XXX/rootfs
3、使用BusyBox制作根文件系統
BusyBox的作用與原理:根文件系統的目錄下面除了放置內核運行需要的內核模塊文件以外,還需要放置提供給用戶使用的系統命令,例如:ls、cat之類。這些命令如果重頭開發就太沒意思了,所以有人搞了個busybox,這玩意編譯完以后其實也就是一個應用程序,但是它實現了Linux系統大部分的命令(它的編譯也需要使用make menuconifg命令生成指導編譯的配置文件),將編譯得到的busybox文件放置到根文件系統特定的目錄,然后再建立一些軟連接,這樣面向用戶的Linux系統命令就移植完成了。
bsuybox的編譯視頻:
打開busybox自帶的FTP服務器:
方案1:在bin目錄下創建軟鏈接:ln -s busybox tcpsvd
這個tcpsvd就可以啟動ftp服務器。然后輸入命令:#tcpsvd 0 21 ftpd -w / &
// 上面的0表示對所有ip地址都進行偵聽
// 21指定ftp服務器的默認端口
// ftpd -w這里的參數-w表示client可以對目錄執行寫操作
// 可以使用-t和-T參數設置client在沒有任何操作的最大時間之后ftpd主動斷開client連接
// 默認-t為2分鐘=2 * 60,-T為1小時=1 * 60 * 60
// / ftp服務器開發的目錄
// & 表示啟用一個新的進程運行FTP服務器,否則當前shell被阻塞,直到下發Ctrl+c
設置以后,在IE瀏覽器輸入:ftp://192.168.1.230/,可以訪問單板上的 / 目錄。
方案2:設置inetd.conf,并運行inetd。不知什么原因,暫時沒搞定這個方案。
4、使用Initramfs制作根文件系統
【1】首先要通過make menuconfig ARCH=arm 配置Linux內核,
General Setup -> Initial RAM filesystem and RAM disk
【2】再選擇創建好的根文件系統目錄所在的路徑:xxx/rootfs
【3】在根文件系統目錄建立一個軟連接:ln -s ./bin/busybox init
【4】重新編譯內核:make uImage ARCH=arm CROSS_COMPILE=arm-linux-
【5】將編譯好的內核文件下載到設備上運行即可(配置了Initramfs,編譯得到的內核文件uImage比正常情況下大,因為內核文件已經包含了根文件系統)
5、使用NFS文件系統
在調試階段,需要頻繁的修改應用程序,每次都把編譯好的文件下載到FLASH上進行調試并不是一個好主意(FLASH有壽命且下載時間也比較長),而使用NFS(網絡文件系統)是一個好方法。所以接下來我們要重點介紹uboot啟動菜單中的選項。
通過命令可以設置網絡啟動參數:
nfsroot 是連接6410開發板的Linux主機的IP 地址,如果你使用了虛擬機,該地址是虛擬機中Fedora9 的IP 地址,也就是直接提供NFS 服務的Linux 系統IP 地址。
這里我機器使用的IP地址是192.168.1.200。
“ip=”后面:
第一項(192.168.1.230)是目標板的臨時IP(注意不要和局域網內其他IP 沖突);
第二項(192.168.1.200)是開發主機的IP;
第三項(192.168.1.200)是目標板上網關(GW)的設置;
第四項(255.255.255.0)是子網掩碼;
第五項是開發主機的名字(一般無關緊要,可隨便填寫)
eth0 是網卡設備的名稱
介紹完之后,再輸入[q],進入uboot的shell界面,如下圖所示,輸入help,可以查看shell下的所有命令。
例如,輸入bdinfo命令,可以查看單板信息:
輸入printenv命令可以查詢系統內部的環境變量,包括啟動參數