基于ARM和Linux的嵌入式平臺的構(gòu)建
2013/11/27 10:50:47
進入后PC 時代以來, 伴隨著設(shè)計和制造技術(shù)的發(fā)展, 集成電路從當初的晶體管集成發(fā)展到現(xiàn)在的IP 集成, 即SoC(System on Chip ) 設(shè)計技術(shù)。促使嵌入式系統(tǒng)滲透到了當今社會中的各個行業(yè), 并且發(fā)揮越來越重要的作用。嵌入式系統(tǒng)一般可定義為以應(yīng)用為中心、以計算機技術(shù)為基礎(chǔ)、軟硬件可裁剪、適用于應(yīng)用系統(tǒng)且對功能、成本、體積、功耗有嚴格要求的專用計算機系統(tǒng),它的主要特點是嵌入、應(yīng)用。
隨著各種嵌入式設(shè)備功能越來越強大, 在設(shè)備中使用嵌入式操作系統(tǒng)也成為必然。Linux 操作系統(tǒng)具有開放源代碼、易于移植、資源豐富、免費等特點, 在嵌入式領(lǐng)域的地位越來越重要。嵌入式Linux 和PC 上的Linux是同一套內(nèi)核代碼, 只是裁剪的程度不一樣, 所以, 很多在PC 上開發(fā)的軟件, 經(jīng)過交叉編譯后可以直接在嵌入式設(shè)備上運行。本文主要涉及到Bootloader 移植和Linux-2.6.32.2 內(nèi)核的移植、根文件系統(tǒng)移植、在S3C2440平臺上構(gòu)建完整的嵌入式開發(fā)平臺三個方面。
1 交叉開發(fā)環(huán)境的建立
在進行嵌入式軟件開發(fā)之前, 必須要在PC 上建立ARM 的交叉編譯環(huán)境。交叉編譯就是在PC 平臺上生成可以在ARM 平臺上運行的代碼。其中主要包括ARM 的交叉編譯器arm-elf-gcc 和交叉連接器arm-elf-ld 。本文采用的交叉編譯器的版本是gcc -3.4.5 -glibc -2.3.6 。
交叉編譯流程如圖1 所示。
BootLoader 的啟動一般分為兩個階段, 第一階段的代碼主要是用匯編語言編寫, 主要的功能是完成硬件設(shè)備的初始化, 為加載第二階段的代碼準備RAM 空間, 設(shè)置好堆棧; 第二階段主要用C 語言編寫, 檢測內(nèi)存映射, 將內(nèi)核映像和根文件系統(tǒng)從Nand Flash 讀到RAM中, 為內(nèi)核啟動設(shè)置參數(shù), 引導內(nèi)核。
U-Boot 的源代碼可以從ftp://ftp.denx.de/pub/u-boot/進行下載, 本文使用的U-Boot 版本是U-Boot2009.08 。
移植U-Boot 的關(guān)鍵步驟如下:
?。?) 首先, 將include/configs 目錄下的smdk2410.h 復制并改名為mini2440.h , 根據(jù)U-Boot 的說明可以知道,如果要使用開發(fā)板board/<board_name > , 則先執(zhí)行“make <board_nAME > ”_config 命令進行配置, 然后執(zhí)行“make all ” , 生成可執(zhí)行文件。所以, 修改U-Boot 頂層的Makefile 文件, 添加下面一行mini2440_config : unconfig@ $ (MKCONFIG) $ (@:_config = ) arm arm920t mini2440frank s3c24x0 。這里有幾個重要的參數(shù),arm 指CPU 的架構(gòu),arm920t 指CPU 的類型,s3c24x0 指CPU 的型號。這樣就可以使用make mini2440_config 這條命令進行配置。
?。?)本文使用的U-Boot 是從Nand Flash 啟動的, CPU可以直接訪問Nand Flash 中前4 KB 代碼, 利用這4 KB代碼把U-Boot 中絕大部分代碼拷貝到內(nèi)存中[ 3]。其中下面的代碼就是調(diào)用C 語言中的Nand Flash 的讀寫函數(shù), 該函數(shù)主要把Nand Flash 中4 KB 以后的代碼復制到RAM 中。在編寫nand_read_ll 的函數(shù)時, 注意參考Nand Flash 的數(shù)據(jù)手冊, 對大頁和小頁的Nand Flash , 其讀寫的命令和時序是不同的。
@copy U-Boot to RAM
ldr r0,=TEXT_BASE
mov r1,#0x0
mov r2,#0x60000
bl nand_read_ll
tst r0,#0x0
beq ok_nand_read
由于在后面加載Linux 內(nèi)核和根文件系統(tǒng)時, 使用的是tftp 方式, 所以必須添加DM9000EP 網(wǎng)卡的驅(qū)動。在mini2440.h 文件中, 其主要的配置如下:
#define CONFIG_DRIVER_DM9000 1
#define CONFIG_NET_MULTI 1
#define CONFIG_DM9000_NO_SROM 1
#define CONFIG_DM9000_BASE 0x20000300
#define DM9000_DATA (CONFIG_DM9000_BASE +4)
其中,CONFIG_DM9000_BASE 宏是最重要的, 因為它定義的是網(wǎng)卡的地址, 不同的網(wǎng)卡有不同的地址,DM9000EP 訪問的基址為0x20000000, 之所以再偏移0x300 是由它的特性決定的。
?。?) 要正確引導Linux 內(nèi)核, 還需要配置下面幾個重要的宏定義, 這幾個宏定義不同, 意味著引導Linux 內(nèi)核的方式也不同。
#define CONFIG_BOOTARGS"noinitrd root=/dev/mtdblock3
init=/linuxrc console=ttySAC0,115200 mem=64M"
其中,root =/dev/mtdblock3 是由Linux 中的Nand Flash 分區(qū)所決定的, 意味著Nand Flash 的第4 個分區(qū)為根文件系統(tǒng)。
#define CONFIG_BOOTCOMMAND"nand read 0x32000000 0x60000 0x560000;bootm 0x32000000"
這個宏定義是將Nand Flash 中0x60000 -0x560000( 和kernel 分區(qū)一致) 的內(nèi)容讀到內(nèi)存0x32000000 中, 然后用bootm 命令來執(zhí)行。
要正常地引導Linux 內(nèi)核, 必須要具備如下幾個條件:
?。?)CPU 寄存器
R0=0 ;
R1= 機器類型ID ; 對于ARM 結(jié)構(gòu)的CPU, 其機器類
型ID 在linux/arch/arm/tools/mach-types ;
R2=啟動參數(shù)標記列表在RAM 中起始基地址。
?。?)CPU 工作模式
必須禁止中斷(IRQs 和FIQs ) ;
CPU 必須為SVC 模式。
(3)Cach 和MMU 的設(shè)置
MMU 必須關(guān)閉;
指令Cach 可以打開也可以關(guān)閉;
數(shù)據(jù)Cach 必須關(guān)閉。
3 Linux2.6.32.2 內(nèi)核的移植
3.1 內(nèi)核的獲取
Linux 內(nèi)核的更新很快, 可以從http://www.kernel.org/pub/linux/kernel/ 得到最新的Linux 內(nèi)核版本, 本文使用的Linux 內(nèi)核版本是Linux -2.6.32.2, 交叉編譯工具使用符合EABI 標準的arm-linux-gcc-4.3.2 。
3.2 內(nèi)核的移植
可以在內(nèi)核的根目錄下, 運行make menuconfig 命令, 對內(nèi)核進行適當?shù)牟眉簦?以適應(yīng)硬件平臺。
對內(nèi)核進行適當?shù)牟眉簦?以適應(yīng)硬件平臺。
?。?) 修改Makefile 文件
欲設(shè)置Linux 的默認平臺為ARM 平臺, 需進入Linux-2.6.32 文件夾中, 修改此目錄下的Makefile 文件。
export KBUILD_BUILDHOST := $(SUBARCH)
ARCH ?=arm // 使用的目標平臺
CROSS_COMPILE ?=arm-linux- // 使用的交叉編譯器,
這里使用系統(tǒng)默認的編譯器
?。?) 關(guān)于機器碼
在啟動內(nèi)核時, 根據(jù)BootLoader 傳入的機器碼(MACH_TYPE) 來決定應(yīng)啟動哪種目標平臺[ 6], 本開發(fā)平臺的機器碼為1999 。機器碼存放在文件opt/kernel/linux-2.6.32.2/arch/arm/tools/mach-types 中。
mini2440 MACH_MINI2440 MINI2440 1999 // 機器碼
如果機器碼不匹配, 引導內(nèi)核不成功, 則會出現(xiàn)如下的錯誤提示:
Uncompressing
Linux……………………………………………………………………………done, booting the kernel.
(3) 修改時鐘源
將/kernel/linux -2.6.32.2/arch/arm/mach -s3c2440/ 目錄下的mach-smdk2440.c 文件改名為mach-mini2440.c。
因為mini2440 和mach-smdk2440.c 極其相似, 以該文件為基礎(chǔ)進行修改, 在mach -mini2440.c 文件中將staticvoid__init smdk2440_map_io ( void ) 函數(shù)中的晶振頻率修改為mini2440 開發(fā)板上實際使用的12000000。
?。?) 為內(nèi)核打上yaffs2 補丁
?、資affs2 文件系統(tǒng)是專門針對嵌入式設(shè)備, 特別是使用Nand Flash 作為存儲器的嵌入式設(shè)備而創(chuàng)建的一種文件系統(tǒng), 使用yaffs2 就可以支持大頁的Nand Flash。
進入yaffs2 源代碼目錄執(zhí)行如下命令:
#./patch -ker.sh c /opt/FriendlyARM/mini2440/linux -2.6.32.2
②配置內(nèi)核以支持Yaffs2 文件系統(tǒng)
在Linux 內(nèi)核源代碼根目錄運行make xconfig, 在“File systems ” 選項中, 找到“Miscellaneous filesystems ” 菜單項, 找到“YAFFS2 file system support ” 并選中它, 這樣就在內(nèi)核中添加了yaffs2 文件系統(tǒng)的支持, 保存并退出。然后在命令行中, 執(zhí)行make zImage 。
?。?) 修改Nand Flash 分區(qū)信息
?、僭趍ach-mini2440.c 文件中添加Nand Flash 的分區(qū)信息, 下面的代碼將Nand Flash 分成了4 個分區(qū), 第1 分區(qū)也是BootLoader 所在的分區(qū), 對應(yīng)dev/mtdblock0 ;第2 個分區(qū)是U-Boot 的參數(shù)分區(qū), 對應(yīng)dev/mtdblock1 ;第3 個分區(qū)是內(nèi)核分區(qū), 對應(yīng)dev/mtdblock2 ; 第4 個分區(qū)為根文件系統(tǒng)分區(qū)對應(yīng)dev/mtdblock3 。分區(qū)結(jié)構(gòu)圖如表1 所示。
表1 128 MB Nand Flash 的分區(qū)結(jié)構(gòu)圖 border="0" alt="" /> 其部分實現(xiàn)代碼如下:
static struct mtd_partition mini2440_default_nand_part[] ={
[0] = {
.name="U-boot",
.offset= 0,
.size= 0x00040000,
}
其中name 是分區(qū)的名字,offset 是偏移的開始地址,size是分區(qū)的大小, 其余部分的分區(qū)與此類似。
②下面代碼是添加Nand Flash 的設(shè)置表, 因為板子上只有一片Nand Flash, 因此也就只有一個設(shè)置表。
static struct s3c2410_nand_set mini2440_nand_sets[] = {
[0] = {
.name= "NAND",
.nr_chips= 1,
.nr_partitions=
ARRAY_SIZE(mini2440_default_nand_part),
.partitions= mini2440_default_nand_part,
}
}
?、凵厦娴脑O(shè)置完成后, 還需要將Nand Flash 設(shè)備注冊到系統(tǒng)中。下面這段代碼就是將Nand Flash 設(shè)備添加到開發(fā)板的設(shè)備列表結(jié)構(gòu)。
static struct platform_device *mini2440_devices [] __initdata
= {
&s3c_device_nand,
}
?、茉趍ini2440_machine_init 函數(shù)中添加平臺的數(shù)據(jù)信息。
static void __init mini2440_machine_init(void){
s3c_device_nand.dev.platform_data=&mini2440_nand_info;
}
現(xiàn)在可以進入kernel/linux-2.6.32.2/arch/arm/boot 目錄,然后執(zhí)行下面的命令, 就會在該目錄下生成uImage.img格式的、U-Boot 可以引導的內(nèi)核鏡象。
Mkimage – n ‘linux-2.6.32.2 ’ –A arm – O linux–T kernel –C none – a 0x30008000 – e 0x30008000 –d zImage uImage.img
至此, 可以把生成的uImage.img 格式的鏡像文件復制到tftp 目錄下, 使用tftp 進行下載。
3.3 文件系統(tǒng)
所謂根文件系統(tǒng), 就是創(chuàng)建各個目錄, 例如在/bin 、/sbin/ 目錄下存放各種可執(zhí)行的程序, 在/etc 目錄下存放配置文件, 在/lib 目錄下存放庫文件。
可以利用Busybox 工具創(chuàng)建根文件系統(tǒng),Bosybox 是一個遵循GPL v2 協(xié)議的開源項目, 它在編寫過程中對文件大小進行優(yōu)化, 并考慮了系統(tǒng)資源有限( 例如內(nèi)存)的情況, 使用Busybox 可以自動生成根文件系統(tǒng)所需的bin、sbin、usr 目錄和linuxrc 文件, 可以使用make menuconfig對Busybox 的選項進行配置。
?。?) 進入opt/kernel, 創(chuàng)建一個shell 腳本用于構(gòu)建根文件系統(tǒng)的各個目錄, 并且為其增加執(zhí)行權(quán)限;(2)Linux 中的init 進程會根據(jù)etc/inittab 文件創(chuàng)建其他子進程, 下面代碼是inittab 文件中的內(nèi)容, 說明了系統(tǒng)啟動后首先執(zhí)行的腳本文件是rcS, 虛擬的終端是串口0, 當按下ctr+alt+del 時重啟系統(tǒng),inittab 文件的作用就是控制系統(tǒng)啟動時和啟動后一些程序的運行。
#etc/inittab
::sysinit:/etc/init.d/rcS
s3c2410_serial0::askfirst:-/bin/sh
::ctrlaltdel:/sbin/reboot
::shutdown:/bin/umount -a-r
?。?) 創(chuàng)建etc/init.d/rcS 文件, 這是一個腳本文件, 可以在里面添加要自動執(zhí)行的一些命令。
#! /bin/sh
PATH=/sbin:/bin:/usr/sbin:/usr/bin
runlevel=S // 運行的級別
prevlevel=N
umask 022 // 文件夾的掩碼
mount -a // 掛載/etc/fstab/ 文件指定的所有的文件系統(tǒng)
mdev-s
/bin/hostname -F /etc/sysconfig/HOSTNAME// 主機的名字
使用yaffs 源碼提供的工具制作文件系統(tǒng)的映像文件。由于128 MB 的Nand Flash 是大頁結(jié)構(gòu), 所以需要使用相應(yīng)的大頁制作工具; 使用命令mkyaffs2image rootfsrootfs.img 生成根文件系統(tǒng)映像文件。
本文通過對U-Boot 移植和Linux 內(nèi)核移植的討論,給出了移植U-Boot 和Linux 到大多數(shù)開發(fā)板的關(guān)鍵部分。由于移植的復雜性, 不可能包括全部步驟, 但通過本文的闡述可以了解移植的基本流程和關(guān)鍵點, 為移植不同版本到其他硬件平臺提供了參考, 也為應(yīng)用程序的開發(fā)搭建了一個比較完整的嵌入式平臺。
隨著各種嵌入式設(shè)備功能越來越強大, 在設(shè)備中使用嵌入式操作系統(tǒng)也成為必然。Linux 操作系統(tǒng)具有開放源代碼、易于移植、資源豐富、免費等特點, 在嵌入式領(lǐng)域的地位越來越重要。嵌入式Linux 和PC 上的Linux是同一套內(nèi)核代碼, 只是裁剪的程度不一樣, 所以, 很多在PC 上開發(fā)的軟件, 經(jīng)過交叉編譯后可以直接在嵌入式設(shè)備上運行。本文主要涉及到Bootloader 移植和Linux-2.6.32.2 內(nèi)核的移植、根文件系統(tǒng)移植、在S3C2440平臺上構(gòu)建完整的嵌入式開發(fā)平臺三個方面。
1 交叉開發(fā)環(huán)境的建立
在進行嵌入式軟件開發(fā)之前, 必須要在PC 上建立ARM 的交叉編譯環(huán)境。交叉編譯就是在PC 平臺上生成可以在ARM 平臺上運行的代碼。其中主要包括ARM 的交叉編譯器arm-elf-gcc 和交叉連接器arm-elf-ld 。本文采用的交叉編譯器的版本是gcc -3.4.5 -glibc -2.3.6 。
交叉編譯流程如圖1 所示。
圖1 嵌入式系統(tǒng)交叉編譯流程
2 BootLoader 引導加載程序
BootLoader 是一段在系統(tǒng)上電時開始執(zhí)行的程序,用以初始化硬件設(shè)備, 準備好軟件環(huán)境, 設(shè)置好啟動參數(shù), 最后引導操作系統(tǒng), 與PC 上的BIOS 程序相似。當前開放源碼的Linux 引導程序主要有x86 架構(gòu)的LILO、GRUB, 對于ARM 架構(gòu)的主要有Vivi 和U-Boot 。本文使用U-Boot 作為引導程序。U-Boot(Universal Boot Loader) ,即通用的BootLoader , 遵循GPL 條款開放源代碼。U-Boot相對于Vivi 功能更加強大, 也更方便后續(xù)程序的調(diào)試。BootLoader 的啟動一般分為兩個階段, 第一階段的代碼主要是用匯編語言編寫, 主要的功能是完成硬件設(shè)備的初始化, 為加載第二階段的代碼準備RAM 空間, 設(shè)置好堆棧; 第二階段主要用C 語言編寫, 檢測內(nèi)存映射, 將內(nèi)核映像和根文件系統(tǒng)從Nand Flash 讀到RAM中, 為內(nèi)核啟動設(shè)置參數(shù), 引導內(nèi)核。
U-Boot 的源代碼可以從ftp://ftp.denx.de/pub/u-boot/進行下載, 本文使用的U-Boot 版本是U-Boot2009.08 。
移植U-Boot 的關(guān)鍵步驟如下:
?。?) 首先, 將include/configs 目錄下的smdk2410.h 復制并改名為mini2440.h , 根據(jù)U-Boot 的說明可以知道,如果要使用開發(fā)板board/<board_name > , 則先執(zhí)行“make <board_nAME > ”_config 命令進行配置, 然后執(zhí)行“make all ” , 生成可執(zhí)行文件。所以, 修改U-Boot 頂層的Makefile 文件, 添加下面一行mini2440_config : unconfig@ $ (MKCONFIG) $ (@:_config = ) arm arm920t mini2440frank s3c24x0 。這里有幾個重要的參數(shù),arm 指CPU 的架構(gòu),arm920t 指CPU 的類型,s3c24x0 指CPU 的型號。這樣就可以使用make mini2440_config 這條命令進行配置。
?。?)本文使用的U-Boot 是從Nand Flash 啟動的, CPU可以直接訪問Nand Flash 中前4 KB 代碼, 利用這4 KB代碼把U-Boot 中絕大部分代碼拷貝到內(nèi)存中[ 3]。其中下面的代碼就是調(diào)用C 語言中的Nand Flash 的讀寫函數(shù), 該函數(shù)主要把Nand Flash 中4 KB 以后的代碼復制到RAM 中。在編寫nand_read_ll 的函數(shù)時, 注意參考Nand Flash 的數(shù)據(jù)手冊, 對大頁和小頁的Nand Flash , 其讀寫的命令和時序是不同的。
@copy U-Boot to RAM
ldr r0,=TEXT_BASE
mov r1,#0x0
mov r2,#0x60000
bl nand_read_ll
tst r0,#0x0
beq ok_nand_read
由于在后面加載Linux 內(nèi)核和根文件系統(tǒng)時, 使用的是tftp 方式, 所以必須添加DM9000EP 網(wǎng)卡的驅(qū)動。在mini2440.h 文件中, 其主要的配置如下:
#define CONFIG_DRIVER_DM9000 1
#define CONFIG_NET_MULTI 1
#define CONFIG_DM9000_NO_SROM 1
#define CONFIG_DM9000_BASE 0x20000300
#define DM9000_DATA (CONFIG_DM9000_BASE +4)
其中,CONFIG_DM9000_BASE 宏是最重要的, 因為它定義的是網(wǎng)卡的地址, 不同的網(wǎng)卡有不同的地址,DM9000EP 訪問的基址為0x20000000, 之所以再偏移0x300 是由它的特性決定的。
?。?) 要正確引導Linux 內(nèi)核, 還需要配置下面幾個重要的宏定義, 這幾個宏定義不同, 意味著引導Linux 內(nèi)核的方式也不同。
#define CONFIG_BOOTARGS"noinitrd root=/dev/mtdblock3
init=/linuxrc console=ttySAC0,115200 mem=64M"
其中,root =/dev/mtdblock3 是由Linux 中的Nand Flash 分區(qū)所決定的, 意味著Nand Flash 的第4 個分區(qū)為根文件系統(tǒng)。
#define CONFIG_BOOTCOMMAND"nand read 0x32000000 0x60000 0x560000;bootm 0x32000000"
這個宏定義是將Nand Flash 中0x60000 -0x560000( 和kernel 分區(qū)一致) 的內(nèi)容讀到內(nèi)存0x32000000 中, 然后用bootm 命令來執(zhí)行。
要正常地引導Linux 內(nèi)核, 必須要具備如下幾個條件:
?。?)CPU 寄存器
R0=0 ;
R1= 機器類型ID ; 對于ARM 結(jié)構(gòu)的CPU, 其機器類
型ID 在linux/arch/arm/tools/mach-types ;
R2=啟動參數(shù)標記列表在RAM 中起始基地址。
?。?)CPU 工作模式
必須禁止中斷(IRQs 和FIQs ) ;
CPU 必須為SVC 模式。
(3)Cach 和MMU 的設(shè)置
MMU 必須關(guān)閉;
指令Cach 可以打開也可以關(guān)閉;
數(shù)據(jù)Cach 必須關(guān)閉。
3 Linux2.6.32.2 內(nèi)核的移植
3.1 內(nèi)核的獲取
Linux 內(nèi)核的更新很快, 可以從http://www.kernel.org/pub/linux/kernel/ 得到最新的Linux 內(nèi)核版本, 本文使用的Linux 內(nèi)核版本是Linux -2.6.32.2, 交叉編譯工具使用符合EABI 標準的arm-linux-gcc-4.3.2 。
3.2 內(nèi)核的移植
可以在內(nèi)核的根目錄下, 運行make menuconfig 命令, 對內(nèi)核進行適當?shù)牟眉簦?以適應(yīng)硬件平臺。
對內(nèi)核進行適當?shù)牟眉簦?以適應(yīng)硬件平臺。
?。?) 修改Makefile 文件
欲設(shè)置Linux 的默認平臺為ARM 平臺, 需進入Linux-2.6.32 文件夾中, 修改此目錄下的Makefile 文件。
export KBUILD_BUILDHOST := $(SUBARCH)
ARCH ?=arm // 使用的目標平臺
CROSS_COMPILE ?=arm-linux- // 使用的交叉編譯器,
這里使用系統(tǒng)默認的編譯器
?。?) 關(guān)于機器碼
在啟動內(nèi)核時, 根據(jù)BootLoader 傳入的機器碼(MACH_TYPE) 來決定應(yīng)啟動哪種目標平臺[ 6], 本開發(fā)平臺的機器碼為1999 。機器碼存放在文件opt/kernel/linux-2.6.32.2/arch/arm/tools/mach-types 中。
mini2440 MACH_MINI2440 MINI2440 1999 // 機器碼
如果機器碼不匹配, 引導內(nèi)核不成功, 則會出現(xiàn)如下的錯誤提示:
Uncompressing
Linux……………………………………………………………………………done, booting the kernel.
(3) 修改時鐘源
將/kernel/linux -2.6.32.2/arch/arm/mach -s3c2440/ 目錄下的mach-smdk2440.c 文件改名為mach-mini2440.c。
因為mini2440 和mach-smdk2440.c 極其相似, 以該文件為基礎(chǔ)進行修改, 在mach -mini2440.c 文件中將staticvoid__init smdk2440_map_io ( void ) 函數(shù)中的晶振頻率修改為mini2440 開發(fā)板上實際使用的12000000。
?。?) 為內(nèi)核打上yaffs2 補丁
?、資affs2 文件系統(tǒng)是專門針對嵌入式設(shè)備, 特別是使用Nand Flash 作為存儲器的嵌入式設(shè)備而創(chuàng)建的一種文件系統(tǒng), 使用yaffs2 就可以支持大頁的Nand Flash。
進入yaffs2 源代碼目錄執(zhí)行如下命令:
#./patch -ker.sh c /opt/FriendlyARM/mini2440/linux -2.6.32.2
②配置內(nèi)核以支持Yaffs2 文件系統(tǒng)
在Linux 內(nèi)核源代碼根目錄運行make xconfig, 在“File systems ” 選項中, 找到“Miscellaneous filesystems ” 菜單項, 找到“YAFFS2 file system support ” 并選中它, 這樣就在內(nèi)核中添加了yaffs2 文件系統(tǒng)的支持, 保存并退出。然后在命令行中, 執(zhí)行make zImage 。
?。?) 修改Nand Flash 分區(qū)信息
?、僭趍ach-mini2440.c 文件中添加Nand Flash 的分區(qū)信息, 下面的代碼將Nand Flash 分成了4 個分區(qū), 第1 分區(qū)也是BootLoader 所在的分區(qū), 對應(yīng)dev/mtdblock0 ;第2 個分區(qū)是U-Boot 的參數(shù)分區(qū), 對應(yīng)dev/mtdblock1 ;第3 個分區(qū)是內(nèi)核分區(qū), 對應(yīng)dev/mtdblock2 ; 第4 個分區(qū)為根文件系統(tǒng)分區(qū)對應(yīng)dev/mtdblock3 。分區(qū)結(jié)構(gòu)圖如表1 所示。
表1 128 MB Nand Flash 的分區(qū)結(jié)構(gòu)圖 border="0" alt="" /> 其部分實現(xiàn)代碼如下:
static struct mtd_partition mini2440_default_nand_part[] ={
[0] = {
.name="U-boot",
.offset= 0,
.size= 0x00040000,
}
其中name 是分區(qū)的名字,offset 是偏移的開始地址,size是分區(qū)的大小, 其余部分的分區(qū)與此類似。
②下面代碼是添加Nand Flash 的設(shè)置表, 因為板子上只有一片Nand Flash, 因此也就只有一個設(shè)置表。
static struct s3c2410_nand_set mini2440_nand_sets[] = {
[0] = {
.name= "NAND",
.nr_chips= 1,
.nr_partitions=
ARRAY_SIZE(mini2440_default_nand_part),
.partitions= mini2440_default_nand_part,
}
}
?、凵厦娴脑O(shè)置完成后, 還需要將Nand Flash 設(shè)備注冊到系統(tǒng)中。下面這段代碼就是將Nand Flash 設(shè)備添加到開發(fā)板的設(shè)備列表結(jié)構(gòu)。
static struct platform_device *mini2440_devices [] __initdata
= {
&s3c_device_nand,
}
?、茉趍ini2440_machine_init 函數(shù)中添加平臺的數(shù)據(jù)信息。
static void __init mini2440_machine_init(void){
s3c_device_nand.dev.platform_data=&mini2440_nand_info;
}
現(xiàn)在可以進入kernel/linux-2.6.32.2/arch/arm/boot 目錄,然后執(zhí)行下面的命令, 就會在該目錄下生成uImage.img格式的、U-Boot 可以引導的內(nèi)核鏡象。
Mkimage – n ‘linux-2.6.32.2 ’ –A arm – O linux–T kernel –C none – a 0x30008000 – e 0x30008000 –d zImage uImage.img
至此, 可以把生成的uImage.img 格式的鏡像文件復制到tftp 目錄下, 使用tftp 進行下載。
3.3 文件系統(tǒng)
所謂根文件系統(tǒng), 就是創(chuàng)建各個目錄, 例如在/bin 、/sbin/ 目錄下存放各種可執(zhí)行的程序, 在/etc 目錄下存放配置文件, 在/lib 目錄下存放庫文件。
可以利用Busybox 工具創(chuàng)建根文件系統(tǒng),Bosybox 是一個遵循GPL v2 協(xié)議的開源項目, 它在編寫過程中對文件大小進行優(yōu)化, 并考慮了系統(tǒng)資源有限( 例如內(nèi)存)的情況, 使用Busybox 可以自動生成根文件系統(tǒng)所需的bin、sbin、usr 目錄和linuxrc 文件, 可以使用make menuconfig對Busybox 的選項進行配置。
?。?) 進入opt/kernel, 創(chuàng)建一個shell 腳本用于構(gòu)建根文件系統(tǒng)的各個目錄, 并且為其增加執(zhí)行權(quán)限;(2)Linux 中的init 進程會根據(jù)etc/inittab 文件創(chuàng)建其他子進程, 下面代碼是inittab 文件中的內(nèi)容, 說明了系統(tǒng)啟動后首先執(zhí)行的腳本文件是rcS, 虛擬的終端是串口0, 當按下ctr+alt+del 時重啟系統(tǒng),inittab 文件的作用就是控制系統(tǒng)啟動時和啟動后一些程序的運行。
#etc/inittab
::sysinit:/etc/init.d/rcS
s3c2410_serial0::askfirst:-/bin/sh
::ctrlaltdel:/sbin/reboot
::shutdown:/bin/umount -a-r
?。?) 創(chuàng)建etc/init.d/rcS 文件, 這是一個腳本文件, 可以在里面添加要自動執(zhí)行的一些命令。
#! /bin/sh
PATH=/sbin:/bin:/usr/sbin:/usr/bin
runlevel=S // 運行的級別
prevlevel=N
umask 022 // 文件夾的掩碼
mount -a // 掛載/etc/fstab/ 文件指定的所有的文件系統(tǒng)
mdev-s
/bin/hostname -F /etc/sysconfig/HOSTNAME// 主機的名字
使用yaffs 源碼提供的工具制作文件系統(tǒng)的映像文件。由于128 MB 的Nand Flash 是大頁結(jié)構(gòu), 所以需要使用相應(yīng)的大頁制作工具; 使用命令mkyaffs2image rootfsrootfs.img 生成根文件系統(tǒng)映像文件。
本文通過對U-Boot 移植和Linux 內(nèi)核移植的討論,給出了移植U-Boot 和Linux 到大多數(shù)開發(fā)板的關(guān)鍵部分。由于移植的復雜性, 不可能包括全部步驟, 但通過本文的闡述可以了解移植的基本流程和關(guān)鍵點, 為移植不同版本到其他硬件平臺提供了參考, 也為應(yīng)用程序的開發(fā)搭建了一個比較完整的嵌入式平臺。
提交
查看更多評論
其他資訊
超越傳統(tǒng)直覺,MATLAB/Simulink助力重型機械的智能化轉(zhuǎn)型
新大陸自動識別精彩亮相2024華南國際工業(yè)博覽會
派拓網(wǎng)絡(luò)被Forrester評為XDR領(lǐng)域領(lǐng)導者
智能工控,存儲強基 | ??低晭砭手黝}演講
展會|Lubeworks路博流體供料系統(tǒng)精彩亮相AMTS展會