嵌入式linux的移植的理論問題
移植是指將軟件從一個(gè)平臺(tái)遷移到另一個(gè)平臺(tái)
* 從一個(gè)硬件平臺(tái)移植到另一個(gè)硬件平臺(tái)
* 從一個(gè)操作系統(tǒng)移植到另一個(gè)操作系統(tǒng)
* 從一種軟件庫環(huán)境移植到另一個(gè)軟件庫環(huán)境
軟件進(jìn)行移植的容易程度即可移植性
Linux硬件平臺(tái):
在Linux內(nèi)核里,每一個(gè)處理器指令集對應(yīng)一個(gè)獨(dú)立的體系結(jié)構(gòu)architecture,比如alpha, arm,i386, mips, ppc
每個(gè)體系結(jié)構(gòu)可以有若干變種variant,或不同配置的硬件machine
統(tǒng)稱sub-architecture。以arm體系結(jié)構(gòu)舉例
* variants 包括arm7tdmi, arm926ejs, strongarm,xscale
* machine 包括edb7312, smdk2410, omap-h2
硬件平臺(tái)對C程序的影響:
處理器字長,定義為處理器一次能處理的數(shù)據(jù)位數(shù)。
字長等于處理器內(nèi)部數(shù)據(jù)通路的寬度,一般可以通過通用寄存器的寬度來判斷
處理器字長會(huì)影響int, long等C類型的長度
C代碼當(dāng)中需要使用確定大小的數(shù)據(jù)類型,可以使用顯式長度的類型u8, s8, u16, s16, u32, s32, u64, s64
數(shù)據(jù)對齊:
數(shù)據(jù)對齊是指數(shù)據(jù)塊的地址是某個(gè)特定大小的整數(shù)倍
* 32位處理器字對齊n*4
* 頁對齊n*PAGESIZE
* Cache line對齊n*CLINESIZE
數(shù)據(jù)訪問要求至少是字對齊的,多數(shù)情況下編譯器會(huì)處理數(shù)據(jù)訪問的對齊。不對齊訪問的例子
* char a[10];
* unsigned long* pl = (unsigned long *)(a+1);
* unsigned l = *pl;
字節(jié)順序:
字節(jié)順序byte order是指一個(gè)字中字節(jié)排列的順序
不同硬件可能采用不同byte order
* x86 little-endian
* ppc big-endian
Linux內(nèi)核將硬件的byte order放在asm/byteorder.h> 里面定義,__BIG_ENDIAN或__LITTLE_ENDIAN
在include/linux/byteorder /里面有幾個(gè)頭文件,定義了
* u23 __cpu_to_be32(u32);
* u32 __cpu_to_le32(u32);
* u32 __be32_to_cpu(u32);
* u32 __le32_to_cpus(u32);
時(shí)間:
軟件中的與時(shí)間相關(guān)的代碼也會(huì)影響移植
采用平臺(tái)無關(guān)的時(shí)間表達(dá)方法可以提高代碼可移植性
Linux內(nèi)核里面采用HZ來表示每秒鐘有多少個(gè)內(nèi)部時(shí)鐘滴答,以下對時(shí)間的描述是平臺(tái)無關(guān)的
* HZ
* (2*HZ)
* (HZ/2)
* (HZ/100)
* (2*HZ/100)
內(nèi)存頁面大小:
Linux使用虛擬內(nèi)存機(jī)制來管理內(nèi)存,內(nèi)存的使用基于頁面。
不同的體系結(jié)構(gòu)有不同的頁面大小
常用的32位處理器使用4kB頁面大小
部分體系結(jié)構(gòu)可以支持多種頁面大小
內(nèi)核在asm/page.h>里面定義PAGE_SIZE,PAGE_SHIFT
* PAGE_SIZE表示頁面大小
* PAGE_SHIFT表示頁面號(hào)在地址中的偏移量
* PAGE_SIZE=2^ PAGE_SHIFT
Linux操作系統(tǒng)移植:
工具鏈移植
* binutils (assembler, linker..)
* gcc (compiler, libgcc)
* glibc/uclibc
內(nèi)核移植
* arch implementation
* drivers porting
應(yīng)用程序移植
* C program recompile
* Implement absent library
Linux內(nèi)核的平臺(tái)相關(guān)代碼:
Linux內(nèi)核對多平臺(tái)有很好的支持 內(nèi)核的對外部接口是統(tǒng)一的,并且與平臺(tái)無關(guān)
內(nèi)核的大多數(shù)代碼也是與平臺(tái)無關(guān)的主要的體系結(jié)構(gòu)相關(guān)代碼存在于
* arch/architecture
* include/asm-architecture
比如arm體系的平臺(tái)相關(guān)代碼主要是
* arch/arm
* include/asm-arm
已有代碼向Linux內(nèi)核移植:
將已有代碼向內(nèi)核中移植有一些限制
* 內(nèi)核中沒有標(biāo)準(zhǔn)C庫支持
* 內(nèi)核中沒有象用戶程序那樣的內(nèi)存保護(hù)
* 內(nèi)核中不便使用浮點(diǎn)操作
* 內(nèi)核的堆棧是固定大小的,并且比較有限
* 在內(nèi)核中需要編程者考慮并發(fā)帶來的競爭與冒險(xiǎn),以及同步問題
Linux內(nèi)核移植:
Linux內(nèi)核代碼可以分為平臺(tái)相關(guān)部分和平臺(tái)無關(guān)部分
Linux內(nèi)核絕大部分代碼是平臺(tái)無關(guān)的,
可以被各種平臺(tái)所共享
* 調(diào)度算法
* 存儲(chǔ)器管理
* I/O子系統(tǒng)
* 網(wǎng)絡(luò)協(xié)議棧
依賴于特定硬件的代碼在Linux中采用條件編譯的方式區(qū)分
* ARCH = x86 即打開x86特有的代碼
* ARCH = arm 即打開arm特有的代碼
Linux內(nèi)核的arch目錄:
進(jìn)入arch目錄,每個(gè)體系結(jié)構(gòu)代碼都有一個(gè)子目錄
進(jìn)入arm目錄,在arm體系結(jié)構(gòu)下我們可以看到很多sub-arch的子目錄
實(shí)現(xiàn)sub-arch:
在sub-arch子目錄下,以mach-s3c2410為例 一個(gè)硬件平臺(tái)支持需要實(shí)現(xiàn)以下幾個(gè)硬件相關(guān)的文件
* mach-s3c2410.c, irq.c, clock.c, dma.c, gpio.c, pm.c,sleep.c, time.c
* 同時(shí)在include/asm-arm/arch-s3c2410要實(shí)現(xiàn)
Low-level IRQ helper macros
Debug output macros
Irq number definations
DMA definations
Memory mapping/translation
Reset operation
IDLE function
mach-smdk2410.c:
在mach-smdk2410.c中,我們要定義以下幾個(gè)內(nèi)容
smdk2410_iodesc,描述了所有保留的設(shè)備io地址。這個(gè)描述符是我們移植一個(gè)特定目標(biāo)板非常重要的地方
在這個(gè)板描述文件中還要定義
.phys_ram
.phys_io
.io_pg_offst
.boot_params
.map_io
.init_irq
.timer
map_io:
map_io里面需要實(shí)現(xiàn)設(shè)備io的初始化
在這里要用到smdk2410_iodesc描述符。該描述符是一個(gè)數(shù)組,其中每一項(xiàng)都描述了一個(gè)設(shè)備的IO映射
時(shí)鐘pll的設(shè)置、uart的設(shè)置都可以在map_io中調(diào)用
init_irq:
在這個(gè)調(diào)用里面,關(guān)于中斷的初始化將會(huì)被完成
* 清除中斷pending寄存器
* 注冊主要的中斷處理程序
* 設(shè)置系統(tǒng)中的設(shè)備中斷
timer:
timer是一個(gè)sys_timer類型的結(jié)構(gòu),它包含以下成員
-init 調(diào)用執(zhí)行硬件相關(guān)的timer初始化
-offset 調(diào)用返回自從上次timer中斷以來經(jīng)過的微秒數(shù)
-resume 調(diào)用執(zhí)行系統(tǒng)喚醒后的timer恢復(fù)操作,一般實(shí)現(xiàn)上和init里面的初始化一樣
應(yīng)用程序移植:
最理想情況下,程序可以不作更改,或僅僅打一些補(bǔ)丁,然后告訴編譯環(huán)境按照目標(biāo)環(huán)境要求編譯即可
* busybox
* bash
* sysv init
依賴某些平臺(tái)特性的應(yīng)用程序移植起來往往難度更大
* 圖形庫
* 為速度進(jìn)行優(yōu)化的代碼,比如編解碼器
軟件編程語言的跨平臺(tái)性直接影響軟件的可移植性。此外還有其他因素
軟件協(xié)議/源代碼的開放程度
應(yīng)用程序移植常見問題:
1依賴軟件造成移植性問題
* C庫版本問題
* 圖形庫帶來的問題
* 軟件依賴某些服務(wù)帶來問題
2網(wǎng)絡(luò)應(yīng)用在little-endian平臺(tái)上的處理
* 網(wǎng)絡(luò)傳遞數(shù)據(jù)是big-endian的
3軟件依賴特定平臺(tái)的特性
4平臺(tái)的數(shù)據(jù)一致性模型差異
linux操作系統(tǒng)文章專題:linux操作系統(tǒng)詳解(linux不再難懂)
評(píng)論