如果想要知道一些概念,這篇是很好的總整理:
[
uClinux for Linux Programmers ]
大致上的摘要是這樣:
uClinux 給沒有 MMU 的 CPU 使用,因此不支援原來
Linux 的 Virtual Memory (VM) 環境。
沒有 VM,process 不能於 run time 時期增加 process
address space,所以 brk/sbrk() 無法被實做,
也不能用 tmpfs,因為它依賴於 VM 的支援。
沒有 VM,每一支 uClinux app 都要在 run time 時由系統來作 relocation。
而且是 sequential && contiguous. 的排在 file system 內,一次就得載入
整個程式 於連續的 physical memory 上,所以只能用 romfs。
傳統的 power of 2 memory allocation 機制在這裡會造成許多浪費
(例如要 33k 會給 64k),所以可選其他的 memory allocation 機制
,例如 page_alloc2 或 kmalloc2。
page_alloc2 以 4k 為單位分配 (例如要 33k 會給 36k)
kmalloc2 以 8k 為判斷,大於 8k 的需求從 free memory 的底部拿,
小於 8k 的從 free memory 的起始處拿。這樣的好處是減少由
短暫而多次的 allocation --- 如網路程式的 buffer --- 引起的碎片問題。
沒有 VM,對應用程式來說,就沒有 dynamic stack 可用,一旦程式超出
stack 範圍,會引發不可預期的結果。程式要自己知道需要多大的 stack,
在 compile time 就必須決定好。
heap 也不能使用 VM 機制,所以 uClinux 使用了 kernel free memory
當作一個大的 system memory pool.
對於應用程式與程序來說,uClinux 沒有提供 fork();只提供替代的 vfork(),
有別於 fork(),
使用 vfork() 會使得 parent process suspend 直到
child process 結束 或 執行 exec() 為止。
fork() 發生後,parent & child process 有各自的資源 (address space 與 stack),
parent & child process 沒有任何共用的東西。
反觀 vfork() ,它會使得 child process 與 parent process 共用 stack。
因此 vfork() 後,parent process suspend 了,若此時 child process 從現在的
stack frame 返回上層,則會影響到 parent process stack ---
應用程式必須自行注意,確保不會發生這種情形!(心得:難怪
網路上有人建議 busybox API 加上 fork_and_exit())!
另外,child process 也必須使用 _exit() 而不能用 exit() ,
原因也是因為 stack 共用。
沒有 VM,uClinux 的程式只能使用 flat executable format (bFLT),
這有兩種型態:
一、code text & data 都是 relocatable
二、Compile 出 PIC 碼 (Position Independent Code)
只有部份 data 需要 relocation 即可。
其中第二項衍生出 XIP (eXecute In Place) ,就是程式可以直接在 ROM
上面執行的方式,因為 ROM 是 read only,可以被多個 instance share 使用。
因為 romfs 上面的程式是 contiguously 排放的,這使得 romfs 是唯一可支援
XIP 的 file system。
從這裡可推出這樣的關係:做出 XIP 系統 需要 compiler 支援 PIC 碼。目前
只有 m68k & ARM 有這樣的 gcc compiler.
編出 bFLT 的程式,其實就是先編出 ELF 格式,再由 linker 轉換。只要
compile 選項使用 -Wl,-elf2flt 即可作到。另外例如 -Wl,-elf2flt=s16384 這樣
可以指定 stack 為 16k,toolchain default stack is 4k。(心得:有時
default 是不夠的)
再來談到 shared library,僅僅想用gcc -shared 選項,無法幫你在 bFLT
格式中製作 shared library。(心得:下面有 Analog Device 網站上
的好文詳細描述如何製作 shared library for uClinux)
這裡只提一個重要概念,shared library 必須是 XIP ,否則在每個
uClinux application 都會產生一份 copy --- 這種情形比 static linking
還要糟糕!
結論:伴隨著 NOMMU,uClinux 衍生出這些 與 Linux 的不同處
uClinux 應用程式開發者,需要自行注意。
摘要(完)
[
認識 bFLT ],當然增加概念,但是對於開發程式,沒有直接幫助。
另外,下面這幾篇好文,並沒有排在 google 的前面,但是對於在 uClinux
下開發程式, 極有幫助,特此紀錄之。
1.
Executable file formats 2.
elf2flt 的說明3.
用 flthdr (flat header)工具來看 bFLT 檔案4.
Creating Libries一些 uClinux mailing list 的摘要:
[
Problems building for uClinux ]: Jamie Lokier 有教讀者一些 narrow down problem 的方法,很實用!
還有遇到 error: no memory region specified for loadable section `.plt` 的現象,是因為 linker 遇到 .plt .got ,使其無法 link 成 BFLT program--- 這個 error 在 porting program for uClinux 時很常遇到.
1. BFLT program 的製作 ,其實就是 compile 出 elf 後,再用 elf2flt 轉換成 BFLT format program,一般都用 CFLAGS += -elf2flt 告訴 compiler 在 link time 時幫我們轉換。
2. 若您的程式有自己的 lib ,而且是 static link 的方式,則 lib 先只是作成 elf ,然後 archive 起來 ,用 ranlib 做出 library index (方便 linking ,可有可無),等到和 program linking 時才使用 elf2flt 轉換成 BFLT.
#