從粵嵌嵌入式Linux培訓(xùn)出去的學(xué)生,面對的個問題就是投簡歷、面試,對于面試Linux相關(guān)崗位的人來說,先了解有哪些面試問題,是一件很重要的事。
1.Linux中的用戶模式和內(nèi)核模式分別是什么意思?
據(jù)了解,一些類Unix的操作系統(tǒng)則使用了雙模式,可以有效地實現(xiàn)時間共享。在Linux機器上,CPU要么是處于受信任的內(nèi)核模式,要么就是處于受限制的用戶模式。另外除了內(nèi)核本身處于內(nèi)核模式以外,所有的用戶進程都運行在用戶模式之中。
內(nèi)核模式的代碼可以無限制地訪問所有處理器指令集以及全部內(nèi)存和I/O空間。如果用戶模式的進程要享有此特權(quán),它必須通過系統(tǒng)調(diào)用向設(shè)備驅(qū)動程序或其他內(nèi)核模式的代碼發(fā)出請求。另外,用戶模式的代碼允許發(fā)生缺頁,而內(nèi)核模式的代碼則不允許。在2.4和更早的內(nèi)核中,僅僅用戶模式的進程可以被上下文切換出局,由其他進程搶占。除非發(fā)生以下兩種情況,否則內(nèi)核模式代碼可以一直獨占CPU:
(1)它自愿放棄CPU;
(2)發(fā)生中斷或異常。
2. Linux中主要有哪幾種內(nèi)核鎖?
嵌入式Linux培訓(xùn),Linux的內(nèi)核所從初的原子操作,到后來的信號量,從大內(nèi)核鎖到今天的自旋鎖。Linux的內(nèi)核鎖主要是自旋鎖和信號量。
自旋鎖多只能被一個可執(zhí)行線程持有,如果一個執(zhí)行線程試圖請求一個已被持有的自旋鎖,那么這個線程就會一直進行忙循環(huán)——旋轉(zhuǎn)——等待鎖重新可用。如果自旋鎖未被爭用,請求它的執(zhí)行線程便能立刻得到它并且繼續(xù)進行。自旋鎖可以在任何時刻防止多于一個的執(zhí)行線程同時進入臨界區(qū)。
Linux中的信號量是一種睡眠鎖。當(dāng)一個任務(wù)試圖獲得一個已被持有的信號量時,信號量會將其推入等待隊列,然后讓其睡眠。而當(dāng)持有信號量的進程將信號量釋放后,在等待隊列中的一個任務(wù)將被喚醒,從而便可以獲得這個信號量。信號量的睡眠特性,使得信號量適用于鎖會被長時間持有的情況;只能在進程上下文中使用,因為中斷上下文中是不能被調(diào)度的;另外當(dāng)代碼持有信號量時,不可以再持有自旋鎖。
總而言之,Linux內(nèi)核中的同步機制包括了原子操作、信號量、讀寫信號量和自旋鎖的API,另外一些同步機制,包括大內(nèi)核鎖、讀寫鎖、大讀者鎖、RCU (Read-Copy Update,顧名思義就是讀-拷貝修改),和順序鎖等。
3.怎樣申請大塊內(nèi)核內(nèi)存?
在Linux內(nèi)核環(huán)境下,申請大塊內(nèi)存的成功率隨著系統(tǒng)運行時間的增加而減少,雖然可以通過vmalloc系列調(diào)用申請物理不連續(xù)但虛擬地址連續(xù)的內(nèi)存,但畢竟其使用效率不高且在32位系統(tǒng)上vmalloc的內(nèi)存地址空間有限。所以,一般的建議是在系統(tǒng)啟動階段申請大塊內(nèi)存,但是其成功的概率也只是比較高而已,而不是。如果程序真的比較在意這個申請的成功與否,只能退用“啟動內(nèi)存”(Boot Memory)。下面就是申請并導(dǎo)出啟動內(nèi)存的一段示例代碼:
void* x_bootmem= NULL;
EXPORT_SYMBOL(x_bootmem);
unsigned long x_bootmem_size= 0;
EXPORT_SYMBOL(x_bootmem_size);
static int __init x_bootmem_setup(char *str)
{
x_bootmem_size= memparse(str, &str);
x_bootmem= alloc_bootmem(x_bootmem_size);
printk("Reserved %lu bytes from %p for xn",x_bootmem_size, x_bootmem);
return 1;
}
__setup("x-bootmem=", x_bootmem_setup);
可見其應(yīng)用還是比較簡單的,不過利弊總是共生的,它不可避免也有其自身的限制:
內(nèi)存申請代碼只能連接進內(nèi)核,不能在模塊中使用。
被申請的內(nèi)存不會被頁分配器和slab分配器所使用和統(tǒng)計,也就是說它處于系統(tǒng)的可見內(nèi)存之外,即使在將來的某個地方你釋放了它。
一般用戶只會申請一大塊內(nèi)存,如果需要在其上實現(xiàn)復(fù)雜的內(nèi)存管理則需要自己實現(xiàn)。
在不允許內(nèi)存分配失敗的場合,通過啟動內(nèi)存預(yù)留內(nèi)存空間將是我們的選擇。
嵌入式學(xué)習(xí)是一個循序漸進的過程,目前常見的是嵌入式開發(fā)Linux方向,掌握這些常見面試問題,嵌入式Linux培訓(xùn)相信大家都能順利通關(guān),找到自己理想的崗位。