|
ARM體系結(jié)構(gòu)
1、 請(qǐng)簡(jiǎn)述ARM處理器的特點(diǎn),至少說出5個(gè)以上的特點(diǎn)。(5分)
:低功耗;低成本,高性能,RISC結(jié)構(gòu);指令定長(zhǎng);支持Thumb(16位)/ARM(32位)雙指令集;體積。
2、 請(qǐng)寫出ARM內(nèi)核和ARM SoC處理器的異同,并舉例進(jìn)行說明。(5分)
:ARM內(nèi)核是ARM SoC處理器中的核心部分,所有ARM SoC都采用ARM的體系結(jié)構(gòu)和指令集,ARM SoC主要是在ARM 內(nèi)核基礎(chǔ)上繼承了Memory Controller,Interrtupt Controller,Timer,DMA Controller 以及像 GPIO,USB,IIC,LCD 等外設(shè)控制器。
3、 ARM內(nèi)核有多少種工作模式?請(qǐng)寫出這些工作模式的英文縮寫。(7分)
:ARM有7種工作模式,usr、sys、svc、irq,abt,und、fiq。
4、 ARM內(nèi)核有多少個(gè)寄存器,請(qǐng)列舉出這些寄存器的名字和數(shù)量。(5分)
:ARM有37個(gè)寄存器,(1)未分組寄存器:R0-R7,共8個(gè);(2)分組寄存器R8-R14,其中FIQ模式下有單獨(dú)的一組R8-R12共5個(gè),另外6種模式共用一組R8-R12,共5個(gè),USR和SYS模式共用一組R13-R14,共2個(gè),另外5種模式下各有獨(dú)自的一組R13-R14,共10個(gè);(3)程序計(jì)數(shù)器PC即R15寄存器,共1個(gè);(4)狀態(tài)寄存器CPSR,和5個(gè)備份狀態(tài)寄存器SPSR,共6個(gè);ARM總計(jì)37個(gè)寄存器。
5、 ARM通用寄存器中,有3個(gè)寄存器有特殊功能和作用,請(qǐng)寫出它們的名字和作用。(6分)
:R13:SP棧指針寄存器,用來保存程序執(zhí)行時(shí)的棧指針位置;R14:LR返回鏈接寄存器,用來保存程序執(zhí)行BL指令或模式切換時(shí)的返回原程序繼續(xù)執(zhí)行的地址;R15:PC程序計(jì)數(shù)器,保存程序執(zhí)行的當(dāng)前地址。
6、 請(qǐng)描述一下CPSR寄存器中相關(guān)Bit的情況和作用。(5分)
:條件位(指令進(jìn)行算術(shù)運(yùn)算后的結(jié)果是否有進(jìn)位,借位等),I位(IRQ異常允許位),F(xiàn)位(FIQ異常允許位),T位(ARM/Thumb工作狀態(tài)),模式位(處理器工作模式)
7、 請(qǐng)寫出以下相關(guān)ARM指令語句的注釋:(7分)
MOV R0, PC 把PC的值傳送到 R0寄存器,此時(shí)PC地址為當(dāng)前指令位置+8
ADD R0, R1, #1 把R1加上1的結(jié)果給R0寄存器
LDR R0, =0x56000010 是偽指令,把0x56000010放到R0寄存器中,采用文字池技術(shù)。
LDR PC, [PC, #4] 把當(dāng)前PC值加4位置的內(nèi)容賦值給PC,實(shí)現(xiàn)絕對(duì)跳轉(zhuǎn)
MRS R0, CPSR 把CPSR的值傳送給R0
BL LOOP 帶返回地址的跳轉(zhuǎn)指令,把下一條指令給LR后,跳轉(zhuǎn)到Loop 地址
STMFD R13!,{R0-R12} 壓棧指令,把R0到R12寄存器的值通過R13棧指針進(jìn)行壓棧保存,同時(shí)這個(gè)棧是滿遞減方式的棧。
8、 什么是立即數(shù)?請(qǐng)簡(jiǎn)要描述立即數(shù)在使用時(shí)有什么注意要點(diǎn)。(2分)
立即數(shù),主要是指尋址時(shí)直接在指令中出現(xiàn)的數(shù),在使用時(shí)注意(1)立即數(shù)前需要加#(2)ARM指令只有32位長(zhǎng),立即數(shù)在指令中占12位存儲(chǔ)空間,ARM用這12位空間8位表示有效數(shù)字-基數(shù)B,4位表示譯為的數(shù)M,按照把B循環(huán)右移M*2位,構(gòu)造成一個(gè)新的32位的數(shù),其它位補(bǔ)0,所以在使用立即數(shù)時(shí),要注意其是否合法。
9、 請(qǐng)問BL指令跳轉(zhuǎn)時(shí)LR寄存器保存的是什么內(nèi)容?并請(qǐng)簡(jiǎn)述原因。(3分)
BL跳轉(zhuǎn)時(shí),LR中保存的是執(zhí)行BL跳轉(zhuǎn)指令的下一條指令的地址,考慮流水線的情況,即當(dāng)前的PC-4。LR用來在需要返回程序時(shí)從LR中還原程序執(zhí)行的位置繼續(xù)執(zhí)行。
10、 請(qǐng)描述一下什么是處理器現(xiàn)場(chǎng),如何進(jìn)行保存現(xiàn)場(chǎng)?(5分)
每種工作模式下都包含R0-R15,CPSR這17個(gè)寄存器,程序的執(zhí)行當(dāng)前狀態(tài)就保存在這些寄存器中,稱為處理器現(xiàn)場(chǎng)。當(dāng)發(fā)生模式切換時(shí),由于其中的一些寄存器是多種模式下共用的寄存器,為了防止共用處理器寄存器中的值被破壞,所以需要保存原模式下的處理器現(xiàn)場(chǎng),利用STM批量存儲(chǔ)指令,把處理器現(xiàn)場(chǎng)對(duì)應(yīng)的寄存器保存到棧上,待還原時(shí)再出棧恢復(fù)(模式和返回地址)。其中保存現(xiàn)場(chǎng)的工作,硬件完成了CPSR模式的保存和PC返回地址的保存,其他寄存器的保存工作主要依靠軟件壓棧完成,其中LR因?yàn)榭赡鼙划惓L幚沓绦蛑械腂L跳轉(zhuǎn)指令修改,所以一般都需要軟件壓棧再保存。
11、 請(qǐng)描述一下什么是小尾端Littler-Endian存儲(chǔ)格式,如何編程確定處理器的存儲(chǔ)格式?(2分)
小尾端:低地址存低字節(jié),高地址存高字節(jié)。測(cè)試:按字節(jié)打印int型的0x12345678,如是小尾端,則先打78.(通過 union 的方式也可以實(shí)現(xiàn)測(cè)試是否是小尾端)
12、 請(qǐng)寫出一條完整的ARM軟件中斷指令,并簡(jiǎn)要描述其作用。(2分)
SWI 0x1。SWI指令觸發(fā)軟中斷異常,使程序的執(zhí)行流跳轉(zhuǎn)到異常向量表地址0x8,0x1是軟中斷的中斷號(hào),軟中斷處理程序可根據(jù)不同的中斷號(hào)調(diào)用對(duì)應(yīng)的處理子程序。一般SWI軟中斷都用于操作系統(tǒng)的系統(tǒng)調(diào)用。
13、 請(qǐng)描述一下ARM體系中異常向量表的概念。(7分)
異常向量表是從0x0地址開始,一共32個(gè)字節(jié),包含8個(gè)表項(xiàng),其中有1個(gè)保留不用,其他7個(gè)表項(xiàng)對(duì)應(yīng)7種異常發(fā)生后的跳轉(zhuǎn)位置,這7種異常發(fā)生后分別對(duì)應(yīng)到5種異常模式。每個(gè)表項(xiàng)里面放的一般都是一條跳轉(zhuǎn)指令,用來跳轉(zhuǎn)到真正的異常處理程序入口,通過B指令,或者LDR PC,[PC, #?] 的方式都可以實(shí)現(xiàn)此類跳轉(zhuǎn)。
14、 產(chǎn)生軟中斷和硬中斷異常時(shí),程序計(jì)數(shù)器跳轉(zhuǎn)到的地址是哪里?(2分)
軟中斷:0x8,硬中斷:0x18。
15、 請(qǐng)寫出發(fā)生異常后,在進(jìn)行異常響應(yīng)時(shí),硬件完成了哪些工作?(5分)
異常響應(yīng)時(shí):(1)硬件自動(dòng)保存程序的返回地址到要切換的工作模式下的LR中;(2)硬件自動(dòng)保存CPSR到要切換的工作模式下的SPSR中;(3)修改CPSR的模式位;(4)映射相應(yīng)模式下的寄存器;(5)設(shè)置PC跳轉(zhuǎn)到要進(jìn)入的異常向量表的入口地址。
ARM SOC編程開發(fā)
16、 請(qǐng)寫出一個(gè)ARM程序生成的bin文件映像中包含哪些內(nèi)容?(3分)
ARM生成的bin文件包含:RO,RW 兩個(gè)段,注意 ZI 段一般都不在 bin 文件中占用存儲(chǔ)空間。
17、 請(qǐng)寫出完整編譯生成bin文件的命令行:使用文件為 start.s main.c (5分)
armasm start.s –o start.o
armcc –c main.c –o main.o
armlink start.o main.o –first start.o –o main.axf
fromelf –bin main.axf –o main.bin
18、 請(qǐng)寫出armlink時(shí)經(jīng)常使用的參數(shù)選項(xiàng)及其作用,不少于3個(gè)。(3分)
-first 指定目標(biāo)二進(jìn)制文件哪個(gè)鏈接時(shí)放在存儲(chǔ)的最前面;-entry 指定程序的入口地址,即程序從哪里開始首先執(zhí)行;-ro-base 指定程序鏈接時(shí)RO段采用的內(nèi)部加載基址;-rw-base 指定RW段加載時(shí)的加載地址。
19、 請(qǐng)舉例說明在ARM處理器上進(jìn)行一次中斷處理和中斷異常處理的差異。(3分)
中斷處理相比異常處理,主要是中斷需要初始化中斷源和中斷控制器,中斷發(fā)生后在ISR中要清除相應(yīng)Pending位,而且要在進(jìn)入中斷處理程序一開始就清除。
20、 請(qǐng)寫出從中斷異常進(jìn)行返回時(shí),軟件編程要處理的事項(xiàng)和注意要點(diǎn)。(2分)
(1)返回地址LR的調(diào)整。(2)在恢復(fù)PC的同時(shí),恢復(fù)CPSR(恢復(fù)原來的模式,返回被打斷的地址。)
21、 請(qǐng)?jiān)敿?xì)描述我們?cè)赟3C2440開發(fā)板實(shí)驗(yàn)過程中進(jìn)行串口初始化的流程和要點(diǎn)。(5分)
時(shí)鐘頻率設(shè)置(MPLL,PCLK的設(shè)置),串口數(shù)據(jù)位8位,停止位1位,奇偶校驗(yàn)無,波特率設(shè)置需要根據(jù)PCLK代入公式進(jìn)行計(jì)算等
22、 請(qǐng)?jiān)敿?xì)描述我們?cè)赟3C2440開發(fā)板實(shí)驗(yàn)過程中進(jìn)行按鍵中斷觸發(fā)的流程和要點(diǎn)。(8分)
SVC和IRQ模式下的SP棧指針設(shè)置,IO管腳復(fù)用設(shè)置,設(shè)置按鈕的觸發(fā)模式(下降沿觸發(fā)),管腳的中斷模式使能,中斷掩碼寄存器屏蔽位打開,清除PND寄存器中的pending位,打開CPSR-I位;
23、 請(qǐng)說明S3C2440處理器,關(guān)于 memory map 的情況。(5分)
2440的memory分為8個(gè)bank,每個(gè)bank的固定大小為128M,每個(gè)bank均可以產(chǎn)生一個(gè)片選信號(hào),共1G的地址空間,8個(gè)片選信號(hào),bank0-bank5用來存放SROM器件,bank6和bank7用來存放SDRAM器件。
24、 請(qǐng)?jiān)敿?xì)描述 bootloader 啟動(dòng)代碼的設(shè)計(jì)流程,并說明你目前所實(shí)現(xiàn)的bootloader已經(jīng)完成的功能有哪些,實(shí)現(xiàn)中遇到了哪些困難和bug問題? (5分)
bootloader的設(shè)計(jì)流程:硬件的初始化(1)初始化看門狗(2)關(guān)中斷(3)設(shè)置處理器時(shí)鐘(4)初始化SDRAM器件(5)初始化串口(6)實(shí)現(xiàn)shell命令解釋器功能,(7) 提供通過串口的下載功能download和執(zhí)行功能Go。要求能夠講的出你自己實(shí)現(xiàn)bootloader過程中遇到的實(shí)際問題和解決辦法,這個(gè)很重要。
25、 請(qǐng)說明以下代碼中可能存在的3個(gè)bug,并給出解決辦法。(3分)
#define UART_BASE 0x50000000
#define UTRSTAT0 *(volatile unsigned int *) UART_BASE+0x10
#define UTXH0 *(volatile unsigned int *) UART_BASE+0x20
int main(void)
{
if( UTRSTAT0 & 0x4 == 0x4 )
UTXH0 = 'a';
return 0;
}
(1) UART_BASE+0x10應(yīng)該加上括號(hào)(2)& 的優(yōu)先級(jí)比 == 要低,所以要加括號(hào)。(3) if應(yīng)該改為while( !(UTRSTAT0 & 0x4) )
附加題:
請(qǐng)說明SRAM, SDRAM, Nor Flash 和Nand Flash的異同,并詳細(xì)描述各自編程上的注意要點(diǎn)。
異同見教材,編程上要注意說明 SRAM和NorFlash無須初始化就可以使用,SDRAM和NandFlash都需要初始化驅(qū)動(dòng)代碼才可以工作,NorFlash的寫需要靠芯片手冊(cè)規(guī)定的時(shí)序來做,STR指令不能夠直接寫入NorFlash和NandFlash,但可以直接寫入SRAM和SDRAM。 NandFlash器件是屬于IO方式進(jìn)行讀,和其他3種器件的總線讀方式不一樣,因此讀寫NandFlash需要相應(yīng)的驅(qū)動(dòng)。
Linux體系
答:ARM技術(shù)的設(shè)計(jì)者將ARM處理器在應(yīng)用中可能產(chǎn)生的狀態(tài)進(jìn)行了分類,并針對(duì)同一類型的異常狀態(tài)設(shè)定了一個(gè)固定的入口點(diǎn),當(dāng)異常產(chǎn)生時(shí),程序會(huì)自動(dòng)跳轉(zhuǎn)到對(duì)應(yīng)異常入口處進(jìn)行異常服務(wù)。
1.用戶模式:非特權(quán)模式,也就是正常程序執(zhí)行的模式,大部分任務(wù)在這種模式下 執(zhí)行。在用戶模式下,如果沒異常發(fā)生,不允許應(yīng)用程序自行改變處理器的工作模式,如果有異常發(fā)生,處理器會(huì)自動(dòng)切換工作模式
2.FIQ模式:也稱為快速中斷模式,支持高速數(shù)據(jù)傳輸和通道處理,當(dāng)一個(gè)高優(yōu)先級(jí)(fast)中斷產(chǎn)生時(shí)將會(huì)進(jìn)入這種模式。
3.IRQ模式:也稱為普通中斷模式,:當(dāng)一個(gè)低優(yōu)先級(jí)(normal)中斷產(chǎn)生時(shí)將會(huì)進(jìn)入 這種模式。在這模式下按中斷的處理器方式又分為向量中斷和非向量中斷兩種。通常的中斷處理都在IRQ模式下進(jìn)行。
4.SVC模式:稱之為管理模式,它是一種操作系統(tǒng)保護(hù)模式。當(dāng)復(fù)位或軟中斷指 令執(zhí)行時(shí)處理器將進(jìn)入這種模式。
5.中止模式:當(dāng)存取異常時(shí)將會(huì)進(jìn)入這種模式,用來處理存儲(chǔ)器故障、實(shí)現(xiàn)虛擬存儲(chǔ)或存儲(chǔ)保護(hù)。
6.未定義指令異常模式:當(dāng)執(zhí)行未定義指令時(shí)會(huì)進(jìn)入這種模式,主要是用來處理未 定義的指令陷阱,支持硬件協(xié)處理器的軟件仿真,因?yàn)槲炊x指令多發(fā)生在對(duì)協(xié)處理器的操作上。
7.系統(tǒng)模式:使用和User模式相同寄存器組的特權(quán)模式,用來運(yùn)行特權(quán)級(jí)的操作系統(tǒng)任務(wù)。
在這7種工作模式中,除了用戶模式以外,其他6種處理器模式可以稱為特權(quán)模式, 在這些模式下,程序可以訪問所有的系統(tǒng)資源,也可以任意地進(jìn)行處理器模式的切 換。
在這6種特權(quán)模式中,除了系統(tǒng)模式外的其他5種特權(quán)模式又稱為異常模式,每種 異常都對(duì)應(yīng)有自己的異常處理入口點(diǎn)
1.解釋命令ls -a | more具體含義.
ls -a命令顯示當(dāng)前目錄下的所有文件包括隱藏文件,并將ls -a命令的執(zhí)行結(jié)果通過管道傳送給more命令分
屏顯示。
2.LINUX中的管道指什么重定向又指什么
Linux中管道用 “|”表示,將一個(gè)命令的輸出,作為你一個(gè)命令的輸入。
重定向
3.GCC -g -o test.elf test.c的具體含義.
將源代碼test.c文件編譯連接成目標(biāo)文件test.elf文件,同時(shí)對(duì)test.elf設(shè)置gdb調(diào)試開關(guān)
4.淺述GCC編譯器在編譯時(shí)都有哪幾個(gè)過程
gcc編譯c源碼有四個(gè)步驟:預(yù)處理,編譯,匯編,鏈接。
5,在題3的基礎(chǔ)上編寫一MAKEFILE文件,要求能自動(dòng)完成編譯和清除功能
SRCS = $(wildcard *.c) -->定義變量SRCS,其職為當(dāng)前文件夾下所有.c文件
OBJS = $(SRCS:.c = .o) -->建SRCS中所有.c文件編譯成.o文件
CC = gcc --> 編譯器gcc
INCLUDES = -I/ --定義額外引用的頭文件路徑
LIBS = -I/ --定義額外使用的庫路徑名
CCFLAGS = -g -Wall -00 --CCFLAGS存放編譯選項(xiàng)
test.elf : $(OBJS) --test.elf是編譯的最終目標(biāo)文件,依賴于所有.o文件
$(CC) $^ -O $@ $(INCLUDES) $(LIBS) --$^代表$(OBJS),$@代表test.elf
%.o : %.c
$(CC) -c $< $CCFLAGS --將所有的.c文件編譯成.o目標(biāo)文件, $<代表所有的.c文件
clean:
rm *.o --清除所有的.o文件
. Linux中的用戶模式和內(nèi)核模式是什么含意?
MS-DOS等操作系統(tǒng)在單一的CPU模式下運(yùn)行,但是一些類Unix的操作系統(tǒng)則使用了雙模式,可以有效地實(shí)現(xiàn)時(shí)間共享。在Linux機(jī)器上,CPU要么處于受信任的內(nèi)核模式,要么處于受限制的用戶模式。除了內(nèi)核本身處于內(nèi)核模式以外,所有的用戶進(jìn)程都運(yùn)行在用戶模式之中。
內(nèi)核模式的代碼可以無限制地訪問所有處理器指令集以及全部?jī)?nèi)存和I/O空間。如果用戶模式的進(jìn)程要享有此特權(quán),它必須通過系統(tǒng)調(diào)用向設(shè)備驅(qū)動(dòng)程序或其他內(nèi)核模式的代碼發(fā)出請(qǐng)求。另外,用戶模式的代碼允許發(fā)生缺頁,而內(nèi)核模式的代碼則不允許。
在2.4和更早的內(nèi)核中,僅僅用戶模式的進(jìn)程可以被上下文切換出局,由其他進(jìn)程搶占。除非發(fā)生以下兩種情況,否則內(nèi)核模式代碼可以一直獨(dú)占CPU:
(1)它自愿放棄CPU;
(2)發(fā)生中斷或異常。
2.6內(nèi)核引入了內(nèi)核搶占,大多數(shù)內(nèi)核模式的代碼也可以被搶占。
1) Linux中主要有哪幾種內(nèi)核鎖?
2) Linux中的用戶模式和內(nèi)核模式是什么含意?
3) 怎樣申請(qǐng)大塊內(nèi)核內(nèi)存?
4) 用戶進(jìn)程間通信主要哪幾種方式?
5) 通過伙伴系統(tǒng)申請(qǐng)內(nèi)核內(nèi)存的函數(shù)有哪些?
6) 通過slab分配器申請(qǐng)內(nèi)核內(nèi)存的函數(shù)有?
7) Linux的內(nèi)核空間和用戶空間是如何劃分的(以32位系統(tǒng)為例)?
8) vmalloc()申請(qǐng)的內(nèi)存有什么特點(diǎn)?
9) 用戶程序使用malloc()申請(qǐng)到的內(nèi)存空間在什么范圍?
10) 在支持并使能MMU的系統(tǒng)中,Linux內(nèi)核和用戶程序分別運(yùn)行在物理地址模式還是虛擬地址模式?
11) ARM處理器是通過幾級(jí)也表進(jìn)行存儲(chǔ)空間映射的?
12) Linux是通過什么組件來實(shí)現(xiàn)支持多種文件系通的?
13) Linux虛擬文件系統(tǒng)的關(guān)鍵數(shù)據(jù)結(jié)構(gòu)有哪些?(至少寫出四個(gè))
14) 對(duì)文件或設(shè)備的操作函數(shù)保存在那個(gè)數(shù)據(jù)結(jié)構(gòu)中?
15) Linux中的文件包括哪些?
16) 創(chuàng)建進(jìn)程的系統(tǒng)調(diào)用有那些?
17) 調(diào)用schedule()進(jìn)行進(jìn)程切換的方式有幾種?
18) Linux調(diào)度程序是根據(jù)進(jìn)程的動(dòng)態(tài)優(yōu)先級(jí)還是靜態(tài)優(yōu)先級(jí)來調(diào)度進(jìn)程的?
19) 進(jìn)程調(diào)度的核心數(shù)據(jù)結(jié)構(gòu)是哪個(gè)?
20) 如何加載、卸載一個(gè)模塊?
21) 模塊和應(yīng)用程序分別運(yùn)行在什么空間?
22) Linux中的浮點(diǎn)運(yùn)算由應(yīng)用程序?qū)崿F(xiàn)還是內(nèi)核實(shí)現(xiàn)?《》
23) 模塊程序能否使用可鏈接的庫函數(shù)?
24) TLB中緩存的是什么內(nèi)容?
25) Linux中有哪幾種設(shè)備?
26) 字符設(shè)備驅(qū)動(dòng)程序的關(guān)鍵數(shù)據(jù)結(jié)構(gòu)是哪個(gè)?
27) 設(shè)備驅(qū)動(dòng)程序包括哪些功能函數(shù)?
28) 如何唯一標(biāo)識(shí)一個(gè)設(shè)備?
29) Linux通過什么方式實(shí)現(xiàn)系統(tǒng)調(diào)用?
30) Linux軟中斷和工作隊(duì)列的作用是什么?
7. 如何使用gdb調(diào)試多進(jìn)程
答:最常用的是attach方法,首先寫程序時(shí)在子進(jìn)程中調(diào)用sleep函數(shù)休眠30-60秒,
將程序編譯成可執(zhí)行文件,后臺(tái)運(yùn)行可執(zhí)行文件,ps -fu root查看進(jìn)程號(hào),gdb,
attach進(jìn)程號(hào),再使用stop暫停子進(jìn)程,設(shè)置一些斷點(diǎn)和一些watch,break設(shè)置斷點(diǎn)
,list命令察看源代碼,step單步運(yùn)行,next運(yùn)行下一步,continue繼續(xù)運(yùn)行,
print打印變量信息。
3.GCC -g -o test.elf test.c的具體含義 將test.c 文件編譯輸出為test.elf
帶上調(diào)試信息,可以用GDB調(diào)試用
4.淺述GCC編譯器在編譯時(shí)都有哪幾個(gè)過程 要經(jīng)歷四個(gè)相互關(guān)聯(lián)的步驟:預(yù)處理(也
稱預(yù)編譯,Preprocessing)、編譯(Compilation)、匯編(Assembly)和連接
(Linking)。 預(yù)處理(Preprocessing):命令gcc首先調(diào)用cpp進(jìn)行預(yù)處理,在預(yù)處理
過程中,對(duì)源代碼文件中的文件包含(include)、預(yù)編譯語句(如宏定義define等)進(jìn)
行分析。 編譯(Compilation):接著調(diào)用cc進(jìn)行編譯,這個(gè)階段根據(jù)輸入文件生成以
.o為后綴的目標(biāo)文件。 匯編(Assembly):匯編過程是針對(duì)匯編語言的步驟,調(diào)用as
進(jìn)行工作,一般來講,.s為后綴的匯編語言源代碼文件和匯編.s為后綴的匯編語言文
件經(jīng)過預(yù)編譯和匯編之后都生成以.o為后綴的目標(biāo)文件。 連接(Linking):當(dāng)所有的
目標(biāo)文件都生成之后,gcc就調(diào)用ld來完成最后的關(guān)鍵性工作,這個(gè)階段就是連接。在
連接階段,所有的目標(biāo)文件被安排在可執(zhí)行程序中的恰當(dāng)位置,同時(shí),該程序所調(diào)用
到的庫函數(shù)也從各自所在的檔案庫中連到合適的地方
13.淺談bootloader,kelnel,filesystem三者之間的關(guān)系. 嵌入式是linux啟動(dòng)過
程如下。 bootloader->kernel->filesystem->application 先是bootloader,
它是linux-kernel移植的基石,Bootloader是在系統(tǒng)啟動(dòng)之后、Kernel運(yùn)行之前所
執(zhí)行的第一段代碼,其任務(wù)是為調(diào)用Kernel準(zhǔn)備必要的軟硬件環(huán)境。完成bootlaoder
的移植后,就是kernel的移植。主要包括添加特定模塊的驅(qū)動(dòng),針對(duì)具體要求對(duì)內(nèi)核
進(jìn)行配置。這里有兩點(diǎn)要注意:一是有些參數(shù)要與所用的bootloader向?qū)?yīng),如nand
的分區(qū)參數(shù)。二是bootlaoder對(duì)特定模塊的驅(qū)動(dòng)在進(jìn)入kernel后便會(huì)有kernel接管
,并有kernel重新驅(qū)動(dòng)文件系統(tǒng)主要是建立根文件和一些系統(tǒng)功能的實(shí)現(xiàn),如bash。
用busybox很容易搞定。 3. Linux系統(tǒng)下.ko文件是什么文件?.so文件是什么文
件? Linux下面文件名不代表什么。但是從常識(shí)上講,.ko代碼是驅(qū)動(dòng)編譯成的格
式, .so文件一般是動(dòng)態(tài)庫文件
2、查看驅(qū)動(dòng)模塊中打印信息應(yīng)該使用什么命令?如何查看內(nèi)核中已有的字符設(shè)備的信息?如何查看正在使用的有哪些中斷號(hào)?
答:1) 查看驅(qū)動(dòng)模塊中打印信息的命令:dmesg
2) 查看字符設(shè)備信息可以用lsmod 和modprobe,lsmod可以查看模塊的依賴關(guān)系,modprobe在加載模塊時(shí)會(huì)加載其他依賴的模塊。
3)顯示當(dāng)前使用的中斷號(hào)cat /proc/interrupt
這幾天面試幾個(gè)想做安卓Linux驅(qū)動(dòng)的,總體感覺上驅(qū)動(dòng)基礎(chǔ)還是比較薄弱,大部分情況是雖然做過驅(qū)動(dòng),但是基本上都是采用內(nèi)核現(xiàn)成的,或者是開發(fā)板上已經(jīng)有的,單獨(dú)寫過模塊驅(qū)動(dòng)很少,驅(qū)動(dòng)機(jī)制理解不是很透徹.以下是幾個(gè)隨口問過的基礎(chǔ)問題,供參考.
1、字符型驅(qū)動(dòng)設(shè)備你是怎么創(chuàng)建設(shè)備文件的,就是/dev/下面的設(shè)備文件,供上層應(yīng)用程序打開使用的文件?
2、寫一個(gè)中斷服務(wù)需要注意哪些?如果中斷產(chǎn)生之后要做比較多的事情你是怎么做的?
3、自旋鎖和信號(hào)量在互斥使用時(shí)需要注意哪些?在中斷服務(wù)程序里面的互斥是使用自旋鎖還是信號(hào)量?還是兩者都能用?為什么?
4、原子操作你怎么理解?為了實(shí)現(xiàn)一個(gè)互斥,自己定義一個(gè)變量作為標(biāo)記來作為一個(gè)資源只有一個(gè)使用者行不行?
5、insmod 一個(gè)驅(qū)動(dòng)模塊,會(huì)執(zhí)行模塊中的哪個(gè)函數(shù)?rmmod呢?這兩個(gè)函數(shù)在設(shè)計(jì)上要注意哪些?遇到過卸載驅(qū)動(dòng)出現(xiàn)異常沒?是什么問題引起的?
6、在驅(qū)動(dòng)調(diào)試過程中遇到過oops沒?你是怎么處理的?
7、ioctl和unlock_ioctl有什么區(qū)別?
8、驅(qū)動(dòng)中操作物理絕對(duì)地址為什么要先ioremap?
9、設(shè)備驅(qū)動(dòng)模型三個(gè)重要成員是?platfoem總線的匹配規(guī)則是?在具體應(yīng)用上要不要先注冊(cè)驅(qū)動(dòng)再注冊(cè)設(shè)備?有先后順序沒?
1、字符型驅(qū)動(dòng)設(shè)備你是怎么創(chuàng)建設(shè)備文件的,就是/dev/下面的設(shè)備文件,供上層應(yīng)用程序打開使用的文件?
答:mknod命令結(jié)合設(shè)備的主設(shè)備號(hào)和次設(shè)備號(hào),可創(chuàng)建一個(gè)設(shè)備文件。
評(píng):這只是其中一種方式,也叫手動(dòng)創(chuàng)建設(shè)備文件。還有UDEV/MDEV自動(dòng)創(chuàng)建設(shè)備文件的方式,UDEV/MDEV是運(yùn)行在用戶態(tài)的程序,可以動(dòng)態(tài)管理設(shè)備文件,包括創(chuàng)建和刪除設(shè)備文件,運(yùn)行在用戶態(tài)意味著系統(tǒng)要運(yùn)行之后。那么在系統(tǒng)啟動(dòng)期間還有devfs創(chuàng)建了設(shè)備文件。一共有三種方式可以創(chuàng)建設(shè)備文件。
2、寫一個(gè)中斷服務(wù)需要注意哪些?如果中斷產(chǎn)生之后要做比較多的事情你是怎么做的?
答:中斷處理例程應(yīng)該盡量短,把能放在后半段(tasklet,等待隊(duì)列等)的任務(wù)盡量放在后半段。
評(píng):寫一個(gè)中斷服務(wù)程序要注意快進(jìn)快出,在中斷服務(wù)程序里面盡量快速采集信息,包括硬件信息,然后推出中斷,要做其它事情可以使用工作隊(duì)列或者tasklet方式。也就是中斷上半部和下半部。
第二:中斷服務(wù)程序中不能有阻塞操作。為什么?大家可以討論。
第三:中斷服務(wù)程序注意返回值,要用操作系統(tǒng)定義的宏做為返回值,而不是自己定義的OK,F(xiàn)AIL之類的。
3、自旋鎖和信號(hào)量在互斥使用時(shí)需要注意哪些?在中斷服務(wù)程序里面的互斥是使用自旋鎖還是信號(hào)量?還是兩者都能用?為什么?
答:使用自旋鎖的進(jìn)程不能睡眠,使用信號(hào)量的進(jìn)程可以睡眠。中斷服務(wù)例程中的互斥使用的是自旋鎖,原因是在中斷處理例程中,硬中斷是關(guān)閉的,這樣會(huì)丟失可能到來的中斷。
評(píng):回答的還可以。
4、原子操作你怎么理解?為了實(shí)現(xiàn)一個(gè)互斥,自己定義一個(gè)變量作為標(biāo)記來作為一個(gè)資源只有一個(gè)使用者行不行?
答:原子操作指的是無法被打斷的操作。我沒懂第二句是什么意思,自己定義一個(gè)變量怎么可能標(biāo)記資源的使用情況?其他進(jìn)程又看不見這個(gè)變量
評(píng):第二句話的意思是:
定義一個(gè)變量,比如 int flag =0;
if(flag == 0)
{
flag = 1;
操作臨界區(qū);
flag = 0;
}這樣可否?
5、insmod 一個(gè)驅(qū)動(dòng)模塊,會(huì)執(zhí)行模塊中的哪個(gè)函數(shù)?rmmod呢?這兩個(gè)函數(shù)在設(shè)計(jì)上要注意哪些?遇到過卸載驅(qū)動(dòng)出現(xiàn)異常沒?是什么問題引起的?
答:insmod調(diào)用init函數(shù),rmmod調(diào)用exit函數(shù)。這兩個(gè)函數(shù)在設(shè)計(jì)時(shí)要注意什么?卸載模塊時(shí)曾出現(xiàn)卸載失敗的情形,原因是存在進(jìn)程正在使用模塊,檢查代碼后發(fā)現(xiàn)產(chǎn)生了死鎖的問題。
評(píng):要注意在init函數(shù)中申請(qǐng)的資源在exit函數(shù)中要釋放,包括存儲(chǔ),ioremap,定時(shí)器,工作隊(duì)列等等。也就是一個(gè)模塊注冊(cè)進(jìn)內(nèi)核,退出內(nèi)核時(shí)要清理所帶來的影響,帶走一切不留下一點(diǎn)痕跡。
6、在驅(qū)動(dòng)調(diào)試過程中遇到過oops沒?你是怎么處理的?
沒有。。
評(píng):其他人可以接著說。
7、ioctl和unlock_ioctl有什么區(qū)別?
沒用過unlock_ioctl。。
評(píng):其他人可以接著說。
8、驅(qū)動(dòng)中操作物理絕對(duì)地址為什么要先ioremap?
答:因?yàn)閮?nèi)核沒有辦法直接訪問物理內(nèi)存地址,必須先通過ioremap獲得對(duì)應(yīng)的虛擬地址。
評(píng):其他人可以接著說。
9、設(shè)備驅(qū)動(dòng)模型三個(gè)重要成員是?platfoem總線的匹配規(guī)則是?在具體應(yīng)用上要不要先注冊(cè)驅(qū)動(dòng)再注冊(cè)設(shè)備?有先后順序沒?
這個(gè)真不知道。。
1
#define GPBCON (*(volatile unsigned long *)0x56000010)的理解
A:volatile
當(dāng)計(jì)算機(jī)需要一個(gè)數(shù)值的時(shí)候,會(huì)先把內(nèi)存中(ARM處理寄存器地址)的值讀取到寄存器(這
里指的是r0-r1....r15),然后下次在使用該值的時(shí)候就直接讀取寄存器(r0-r1....r15)中的值
了。加上volatile之后,程序就會(huì)在每次需要該值的時(shí)候都讀取一次內(nèi)存。這是為了防止某些原
因硬件會(huì)改變其值。
B:
(volatile unsigned long *)即為強(qiáng)制類型轉(zhuǎn)換;(volatile unsigned long *)0x56000010
的意思就是把0x56000010強(qiáng)制轉(zhuǎn)換為unsigned long類型的指針。這時(shí)(volatile unsigned long
*)0x56000010就可以看做是一個(gè)指針p了。*(volatile unsigned long*)0x56000010等價(jià)于*p 。
|
|