2016年嵌入式軟件助理工程師認證考試試題題庫
答:
在Linux中啟動一個進程有手工啟動和調度啟動兩種方式:
(1)手工啟動
用戶在輸入端發出命令,直接啟動一個進程的啟動方式?梢苑譃椋
①前臺啟動:直接在SHELL中輸入命令進行啟動。
、诤笈_啟動:啟動一個目前并不緊急的進程,如打印進程。
(2)調度啟動
系統管理員根據系統資源和進程占用資源的情況,事先進行調度安排,指定任務運行的時間和場合,到時候系統會自動完成該任務。
27、簡述Bootloader有何作用?
答案要點:(1)首先,bootloader是在特定硬件平臺運行的程序,嚴重依賴于硬件平臺,需要移植;(2)是系統上電之后,第一個運行的程序,系統在上電或復位時通常都從地址 0x0 處開始執行,而在這個地址處安排的通常就是系統的 Boot Loader 程序;(3)bootloader程序的設計目標是啟動嵌入式操作系統,嵌入式操作系統的啟動需要一定的條件,這些條件由bootloader來滿足;(4)Bootloader一般具有對存儲器和網絡接口操作的功能;如擦除、讀寫Flash,通過USB、串口下載文件等
28、ARM處理器中,引起異常的原因是什么?
答:(1)、指令執行引起的異常
軟件中斷、未定義指令(包括所要求的協處理器不存在是的協處理器指令)、預取址中止(存儲器故障)、數據中止。
(2)、外部產生的中斷
復位、FIQ、IRQ。
29、程序、進程、線程有何區別?
答案要點:程序是編譯后形成的可執行代碼,是靜止的。進程是程序的一次執行,是活動的。線程是進程的可執行單元,同一進程的不同線程共享進程的資源和地址空間。
30、Linux系統中線程的同步方式有互斥量、信號量和條件變量等。假設現在需要設計一個多線程的應用程序,試分析一下以上幾種同步方式分別可在什么場合下使用(6分)。
參考答案:
Mutex互斥量,用于操作某個臨界資源時對該資源上鎖,以實現互斥地對獨占資源的使用(2分)
Semophore信號燈,信號燈內有一計數器,可以用于對多個同類資源的分配。當資源用完時,申請資源的線程會在信號量上睡眠,有線程釋放資源時,再將該線程喚醒繼續運行。(2分)
Condition條件變量,條件變量用于等待信號。當一個線程需要等待某個信號時,就可到條件變量上等待,當信號具備時,系統會喚醒該線程繼續運行。(2分)
31、簡述嵌入式系統的幾個重要特征?
答案要點:系統內核小;專用性強 ;系統精簡 ;高實時性的系統軟件 ;多任務的操作系統 ;需要專用的開發工具和環境。 答出上述4個并適當闡述的即可給滿分。
32、什么是程序的局部性原理?
答案要點:程序的局部性原理是指程序在執行過程中的一個較短時期內,它所執行的指令和訪問的存儲空間分別局限在一定的區域內。具體表現在時間局部性和空間局部性。時間局部性是指一條指令的一次執行和下一次執行、一個數據的一次訪問和下一次訪問,都集中在一個較短的時間內?臻g局部性是指程序執行了某條指令,則它相鄰的幾條指令也可能馬上執行。
33、簡述Busybox的工作原理。(4分)
參考答案:Busybox是通過一個程序去實現原來Linux的眾多命令程序。這樣可使原來3.5MB左右的工具包壓縮大約200KB大小一個程序,這對嵌入式系統非常重要(2分)。
為了使用的方便,Busybox通過創建其原文件的符號連接來達到傳遞具體執行命令的目的。例如,創建一個mv的符號連接,當用戶鍵入mv后,mv實際上會以C語言中的argv[0]傳遞給Busybox的主程序。這樣Busybox就可據此跳轉到相應的代碼去執行。(2分)
34、Linux作為嵌入式操作系統的優勢?
答:
Linux作為嵌入式操作系統的優勢主要有以下幾點:
1. 可應用于多種硬件平臺。Linux已經被移植到多種硬件平臺,這對于經費,時間受限制的研究與開發項目是很有吸引力的。原型可以在標準平臺上開發后移植到具體的硬件上,加快了軟件與硬件的開發過程。Linux采用一個統一的框架對硬件進行管理,從一個硬件平臺到另一個硬件平臺的改動與上層應用無關。(1分)
2. Linux的高度模塊化使添加部件非常容易。本身內置網絡支持,而目前嵌入式系統對網絡支持要求越來越高。(1分)
3. Linux是一個和Unix相似、以內核為基礎的、具有完全的內存訪問控制,支持大量硬件(包括X86,Alpha、ARM和Motorola等現有的大 部分芯片)等特性的一種通用操作系統。(1分)
4. Linux可以隨意地配置,不需要任何的許可證或商家的合作關系。其程序源碼全部公開,任何人可以修改并在GUN通用公共許可證(GNU General Public License)下發行。這樣,開發人員可以對操作系統進行定制,適應其特殊需要。(1分)
5. Linux帶有Unix用戶熟悉的完善的開發工具,幾乎所有的Unix系統的應用軟件都已移植到了Linux上。其強大的語言編譯器GCC,C++等也可以很容易得到,不但成熟完善,而且使用方便。(分)
35、簡述Linux需要進行進程調度的時機(6分)
參考答案:(每小點1分)
Linux執行進程調度一般是在以下情況發生的:
(1)正在執行的進程運行完畢;
(2)正在執行的進程調用阻塞原語將自己阻塞起來進入等待狀態;
(3)正在執行的進程調用了P原語操作,從而因資源不足而被阻塞;或調用了V原語操作激活了等待資源的進程隊列;
(4)執行中的進程提出I/O請求后被阻塞;
(5)系統分配的時間片已經用完;
以上都是CPU為不可剝奪方式下的引起進程調度的原因。在CPU方式是可剝奪時,還有下面的原因:
(6)就緒隊列中的某個進程的優先級變得高于當前運行進程的優先級,從而也將引起進程調度。
37、什么是符號鏈接,什么是硬鏈接?符號鏈接與硬鏈接的區別是什么?(6分)
參考答案:
鏈接分硬鏈接和符號鏈接。
符號鏈接可以建立對于文件和目錄的鏈接。符號鏈接可以跨文件系統,即可以跨磁盤分區。符號鏈接的文件類型位是l,鏈接文件具有新的i節點。(3分)
硬鏈接不可以跨文件系統。它只能建立對文件的鏈接,硬鏈接的文件類型位是-,且硬鏈接文件的i節點同被鏈接文件的i節點相同。(3分)
38、簡述Boot Loader 的兩種操作模式 (Operation Mode)?
答:
啟動加載(Boot loading)模式:這種模式也稱為"自主"(Autonomous)模式。也即 Boot Loader 從目標機上的某個固態存儲設備上將操作系統加載到 RAM 中運行,整個過程并沒有用戶的介入。這種模式是 Boot Loader 的正常工作模式,因此在嵌入式產品發布的時侯,Boot Loader 顯然必須工作在這種模式下。 (2.5分)
下載(Downloading)模式:在這種模式下,目標機上的 Boot Loader 將通過串口連接或網絡連接等通信手段從主機(Host)下載文件,比如:下載內核映像和根文件系統映像等。從主機下載的文件通常首先被 Boot Loader 保存到目標機的 RAM 中,然后再被 Boot Loader 寫到目標機上的FLASH 類固態存儲設備中。Boot Loader 的這種模式通常在第一次安裝內核與根文件系統時被使用;此外,以后的系統更新也會使用 Boot Loader 的這種工作模式。工作于這種模式下的 Boot Loader 通常都會向它的終端用戶提供一個簡單的命令行接口。(2.5分)
39、模塊的編程和普通程序的編程有哪些區別?(6分)
參考答案:
主要區別為:
(1)因為內核模塊運行在內核態,所以包含的頭文件是內核程序相關的頭文件,而普通程序則包含的是glibc的頭文件(1分)
(2)模塊程序沒有main函數,而是通過init_module函數在加載后初始化。(2分)
(3)模塊程序內可直接調用內核函數,而普通程序則只能通過系統調用使用內核函數。(2分)
(4)普通用戶程序可運行多次,而內核函數通常則只能加載1次(1分)。
41、 已知C語言程序有主程序模塊prog.c,prog.h,其中調用了另一模塊subr.c, subr.h中的功能。試寫出一個可將這兩個模塊編譯成可執行文件pr1的makefile。(5分)
參考答案:
[每行1分]
pr1: prog.o subr.o
gcc –o pr1 prog.o subr.o
prog.o: prog.c prog.h
gcc –c –o prog.o prog.c
subr.o: subr.c subr.h
gcc –c –o subr.o subr.c
43、簡述Linux的VFS機制及其特點?(5分)
參考答案:
VFS是一種抽象的文件機制,內核中對文件系統的相關操作系統實際上都通過操作VFS實現,也就是說VFS是對各具體文件系統的'抽象。(3分)
VFS使得內核其他部分無須關心不同文件系統之間的差異,使得Linux可以支持多種類型的文件系統。當然,因為增加了抽象層,會有類型轉換的開銷。(2分)
44、模塊的編程和普通程序的編程有哪些區別?(5分)
參考答案:
主要區別為:
(1)因為內核模塊運行在內核態,所以包含的頭文件是內核程序相關的頭文件,而普通程序則包含的是glibc的頭文件(1分)
(2)模塊程序沒有main函數,而是通過init_module函數在加載后初始化。(2分)
(3)模塊程序內可直接調用內核函數,而普通程序則只能通過系統調用使用內核函數。(2分)
45、BootLoader有哪幾種工作模式?各有什么特點(5分)
參考答案:啟動加載模式和下模式(2分)。前者“自主”,不需要用戶干預,后者可響應用戶的交互請求。(3分)
46、簡述嵌入式系統調試有哪幾種方式(5分)
參考答案:
模擬器方式(1分)、在線仿真器方式(1分)、監控器方式(1分)、在線調試器方式,如JTAG(2分)。
47、Qt/Embedded的主要特點是什么?(5分)
參考答案:
是一個專門為嵌入式系統設計的圖形用戶界面的工具包(1分)。支持UNIX和Windows平臺(1分)。采用面向對象的思想開發(1分),開發接口與桌面的Qt相同,因此桌面應用程序可方便的移植到Qt/E(1分)。不分層的架構使得其他運行速度很快(1分)。
48、簡述嵌入式系統的開發流程。
參考答案:
需求分析階段(1分)
體系結構設計(1分)
硬件/軟件設計(1分)
系統集成(1分)
代碼固化(1分)
49、簡述C語言中數組和指針的異同點。
參考答案:
相同點:(1)表達式中的數組名被編譯器當作一個指向該數組第一個元素的指針(1分)
(2)下標總是與指針偏移量相同(1分)
(3)在函數參數的聲明中,數組被編譯器當作一個指向該數組第一個元素的指針(1分)
不同點:(1)指針用于保存數據的地址,而數組用于保存數據(1分)
(2)指針是間接訪問而數組是直接訪問方式(1分)
50、什么是交叉編譯?為什么要采用交叉編譯(5分)
參考答案:所謂交叉編譯,是指在一個平臺上編譯生成在另一個平臺上運行的可執行程序。(3分)。之所以采用交叉編譯,是因為目標平臺上不具備直接運行開發環境的條件。(2分)
。
51、什么是符號鏈接,什么是硬鏈接?符號鏈接與硬鏈接的區別是什么?
參考答案:
鏈接分硬鏈接和符號鏈接。
符號鏈接可以建立對于文件和目錄的鏈接。符號鏈接可以跨文件系統,即可以跨磁盤分區。符號鏈接的文件類型位是l,鏈接文件具有新的i節點。(3分)
硬鏈接不可以跨文件系統。它只能建立對文件的鏈接,硬鏈接的文件類型位是-,且硬鏈接文件的i節點同被鏈接文件的i節點相同。(2分)
52、簡述Boot Loader的主要功能。
參考答案:
基本硬件設備初始化。(1分)
設置好堆棧。 (1分)
檢測系統內存映射(memory map)。 (1分)
將 kernel 映像和根文件系統映像從 flash 上讀到 RAM 空間中。(1分)
為內核設置啟動參數,調用內核。(1分)
53、嵌入式Linux系統的根文件系統通常應該包括哪個內容?
參考答案:
通常包括:init、libc庫、驅動模塊、必需的應用程序和系統配置腳本。(各1分)
54、
55、回答下面問題:
a) 對于整形變量A=0x12345678,請畫出在little endian及big endian的方式下在內存中是如何存儲的。
b) 在ARM系統中,函數調用的時候,參數是通過哪種方式傳遞的?
c) 中斷(interrupt,如鍵盤中斷)與異常(exception,如除零異常)有何區別?
答:
a) 0x12345678
little endian big endian 剛好反過來
高地址--〉 0x12 低地址--〉 0x12
0x34 0x34
0x56 0x56
低地址--〉 0x78 高地址--〉 0x78
b)
答:應用程序中使用中間寄存器及數據棧來傳遞參數。
在arm匯編中,如果第1~4個參數通過r0 -r3寄存器來傳遞,超過4個的使用數據棧進行傳遞,輸出函數由r0傳遞。
c)所謂中斷應該是指外部硬件產生的一個電信號,從cpu的中斷引腳進入,打斷cpu當前的運行;
所謂異常,是指軟件運行中發生了一些必須作出處理的事件,cpu自動產生一個陷入來打斷當前運行,轉入異常處理流程。
56、某Linux主機的/etc/rc.d/rc.inet1文件中有如下語句,請修正錯誤,并解釋其內容。
/etc/rc.d/rc.inet1:
……
ROUTE add –net default gw 192.168.0.101 netmask 255.255.0.0 metric 1
ROUTE add –net 192.168.1.0 gw 192.168.0.250 netmask 255.255.0.0 metric 1
答:修正錯誤:
(1)ROUTE應改為小寫:route;(2)netmask 255.255.0.0應改為:netmask 255.255.255.0;
(3)缺省路由的子網掩碼應改為:netmask 0.0.0.0;
(4)缺省路由必須在最后設定,否則其后的路由將無效。
解釋內容:
(1)route:建立靜態路由表的命令;(2)add:增加一條新路由;
(3)-net 192.168.1.0:到達一個目標網絡的網絡地址;
(4)default:建立一條缺省路由;(5)gw 192.168.0.101:網關地址;
(6)metric 1:到達目標網絡經過的路由器數(跳數)。
6.下述代碼取自u-boot,請對其加以逐行注釋和分析。
typedef int (init_fnc_t) (void);
init_fnc_t *init_sequence[] = {
cpu_init,
board_init,
env_init,
serial_init,
display_banner,
NULL,
};
init_fnc_t **init_fnc_ptr;
for (init_fnc_ptr = init_sequence; *init_fnc_ptr; ++init_fnc_ptr)
{
if ((*init_fnc_ptr)() != 0) {
hang ();
}
}
4.簡述2.4與2.6內核模塊機制的改變對編寫設備驅動程序的影響?
答:2.4內核中,模塊的編譯只需內核源碼頭文件;需要在包含linux/modules.h之前定義MODULE;編譯、連接后生成的內核模塊后綴為.o。2.6內核中,模塊的編譯需要配置過的內核源碼;編譯、連接后生成的內核模塊后綴為.ko;
在2.6 內核中,內核模塊必須調用宏module_init 與module_exit() 去注冊初始化與退 出函數。在2.4內核中,如果初始化函數命名為init_module()、退出函數命名為cleanup_module()。
2.4內核中,模塊自身通過MOD_INC_USE_COUNT、MOD_DEC_USE_COUNT宏來管理自己被使用的計數。2.6內核提供了更健壯、靈活的模塊計數管理接口try_module_get(&module)及module_put (& module)取代2.4中的模塊使用計數管理宏;模塊的使用計數不必由自身管理,而且在管理模塊使用計數時考慮到SMP與 PREEMPT機制的影響。
2.4 內核下,缺省情況時模塊中的非靜態全局變量及函數在模塊加載后會輸出到內核空間。2.6內核下,缺省情況時模塊中的非靜態全局變量及函數在模塊加載后不會輸出到內核空間,需要顯式調用宏EXPORT_SYMBOL。
57、論述一下問題
(1) ARM中引起異常的原因
(2) 在ARM體系中,異常中斷向量表的大小是多少,其中每個異常中斷占據多少字節
(3) 異常中斷的處理、返回過程。
答:(1)原因主要:
a.指令執行引起的異常
軟件中斷、未定義指令(包括所要求的協處理器不存在是的協處理器指令)、預取址中止(存儲器故障)、數據中止。
b.外部產生的中斷
復位、FIQ、IRQ。
(2)在ARM體系中,異常中斷向量表的大小為32字節,其中每個異常中斷占據4個字節大小,保留了4個字節空間。
(3)ARM處理器對異常中斷的響應過程是首先保存處理器當前狀態、中斷屏蔽位及CPSR寄存器中的各個條件標志位。這是通過將當前程序狀態寄存器CPSR的內容保存到將要執行的異常中斷對應的SPSR寄存器中實現的。其次設置當前程序狀態寄存器CPSR中相應的位。再次將寄存器LR_mode(R14_mode)設置成返回地址。最后將PC設置成該異常中斷的中斷向量地址,從而跳轉到對應的中斷處理程序處執行。
ARM處理器從異常中斷程序中返回的過程:首先恢復被中斷程序的處理器狀態,也就是將SPSR_mode 內容復制到CPSR。然后返回到發生異常中斷指令的下一條指令處執行,即將LR_mode(R14_mode)寄存器的內容復制到PC中。
58、在linux中如何編譯C程序,使之成為可執行文件(3分)?如何調試(3分)?
答案:
[問題1](3分)
1)檢查程序中.h文件所在的目錄,將其加入系統PATH中;
2)執行C編譯:#gcc [源文件名] -o [目標文件名]
3)改變目標文件為可執行文件:#chmod +x [目標文件名]
4)如需將多個可執行文件連續執行,可用vi生成批處理文件,最后記得將該批處理文件屬性改為可執行(同上一步)
[問題2](3分)
調試:在編譯時使用-g參數,就可以使用gdb進行調試。
59、時間片的大小對系統有什么影響?(3分)在選取時間片是應考慮哪些因素?(3分)
參考答案:
[問題1](3分)
在輪轉法中,時間片長度的選取非常重要,將直接影響系統開銷和響應時間。如果時間片長度很小,則調度程序剝奪處理機的次數頻繁,加重系統開銷;反之,如果時間片長度選擇過長,比方說一個時間片就能保證就緒隊列中所有進程都執行完畢,則輪轉法就退化成先進先出算法。
[問題2](3分)
影響時間片大小的主要因素有:系統響應時間、就緒進程數目和計算機處理能力
60、模塊的編程和普通程序的編程有哪些區別?(6分)
參考答案:
主要區別為:
(1)因為內核模塊運行在內核態,所以包含的頭文件是內核程序相關的頭文件,而普通程序則包含的是glibc的頭文件(1分)
(2)模塊程序沒有main函數,而是通過init_module函數在加載后初始化。(2分)
(3)模塊程序內可直接調用內核函數,而普通程序則只能通過系統調用使用內核函數。(2分)
(4)普通用戶程序可運行多次,而內核函數通常則只能加載1次(1分)。
61、什么是交叉編譯?為什么要采用交叉編譯(5分)
參考答案:所謂交叉編譯,是指在一個平臺上編譯生成在另一個平臺上運行的可執行程序。(3分)。之所以采用交叉編譯,是因為目標平臺上不具備直接運行開發環境的條件。(2分)
62、簡述嵌入式Linux系統的初始化過程(5分)
參考答案:
嵌入式Linux系統開機首先運行BootLoader,然后由BootLoader引導啟動內核,由內核檢查和初始化硬件設備,載入設備的驅動程序模塊,安裝root文件系統,然后內核將啟動一個名為init的進程(2分)。在init運行完成并啟動其它必要的后續進程后,系統開始運行,引導過程結束。init進程啟動時需要讀取inittab配置文件,該文件確定init在系統啟動和關機時的工作特性。(3分)
六、閱讀程序題
1. 管道是Linux中進程通信的一種方式,以下程序在父進程和子進程之間創建了一個管道,然后建立它們之間的通信,實現父進程向子進程寫數據的功能。說明標號所在行代碼的功能。
#include
#include
#include
#include
#include
int main()
{
int pipe_fd[2];
pid_t pid;
char buf_r[100];
char* p_wbuf;
int r_num;
memset(buf_r,0,sizeof(buf_r)); (1)
if(pipe(pipe_fd)<0) (2)
{
printf("pipe create error\n");
return -1;
}
if((pid=fork())==0) (3)
{
printf("\n");
close(pipe_fd[1]); (4)
sleep(2);
if((r_num=read(pipe_fd[0],buf_r,100))>0) (5)
{
printf( "%d numbers read from the pipe is %s\n",r_num,buf_r);
}
close(pipe_fd[0]); (6)
exit(0);
}
else if(pid>0) (7)
{
close(pipe_fd[0]); (8)
if(write(pipe_fd[1],"Hello",5)!=-1) (9)
printf("parent write1 success!\n");
if(write(pipe_fd[1]," Pipe",5)!=-1)
printf("parent write2 success!\n");
close(pipe_fd[1]); (10)
sleep(3);
waitpid(pid,NULL,0);
exit(0);
}
}
答案要點:(1) 將數據緩沖區清0 (2) 創建管道 (3) 創建子進程 (4) 關閉子進程寫描述符 (5) 子進程讀取管道內容 (6) 關閉子進程讀描述符 (7) 父進程運行控制語句 (8) 關閉父進程的讀描述符 (9) 將數據寫入緩沖區
(10) 關閉父進程寫描述符
2. 閱讀下面shell程序,寫出執行結果:
#!/bin/sh
for name in Tom Jack Harry
do
echo "$name is my friend"
done
1、答:
Tom is my friend
Jack is my friend
Harry is my friend
3. 用變量a給出下面的定義
a) 一個指向整型數的指針(A pointer to an integer)
b) 一個指向指針的的指針,它指向的指針是指向一個整型數(A pointer to a pointer to an integer)
c) 一個有10個整型數的數組(An array of 10 integers)
d) 一個有10個指針的數組,該指針是指向一個整型數的(An array of 10 pointers to integers)
e) 一個指向有10個整型數數組的指針(A pointer to an array of 10 integers)
2、答:
a) int *a; // A pointer to an integer
b) int **a; // A pointer to a pointer to an integer
c) int a[10]; // An array of 10 integers
d) int *a[10]; // An array of 10 pointers to integers
e) int (*a)[10]; // A pointer to an array of 10 integers
4. 根據下面給出的聲明和數據,對每個表達式進行求值并寫出他的值。在每個表達式進行求值是使用原來給出的值(也就是說,某個表達式的結果不影響后面的表達式)。假定ints數組在內存中的起始位置是100,整型值和指針的長度都是4字節。