1、 Linux設備中字符設備與塊設備有什麼主要的區別?請分別列舉一些實際的設備說出它們是屬於哪一類設備。 字符設備:字符設備是個能夠像字節流(類似文件)一樣被訪問的設備,由字符設備驅動程序來實現這種特性。字符設備驅動程序通常至少實現open,close,read和write系統調用。字符終端、串口、鼠標、鍵盤、攝像頭、聲卡和顯卡等就是典型的字符設備。
塊設備:和字符設備類似,塊設備也是通過/dev目錄下的文件系統節點來訪問。塊設備上能夠容納文件系統,如:u盤,SD卡,磁盤等。
字符設備和塊設備的區別僅僅在於內核內部管理數據的方式,也就是內核及驅動程序之間的軟件接口,而這些不同對用戶來講是透明的。在內核中,和字符驅動程序相比,塊驅動程序具有完全不同的接口。
2、查看驅動模塊中打印信息應該使用什麼命令?如何查看內核中已有的字符設備的信息?如何查看正在使用的有哪些中斷號?1) 查看驅動模塊中打印信息的命令:
dmesg2) 查看字符設備信息可以用
lsmod 和
modprobe,lsmod可以查看模塊的依賴關系,modprobe在加載模塊時會加載其他依賴的模塊。
3) 顯示當前使用的中斷號cat /proc/interrupt
3、Linux中引入模塊機制有什麼好處?
首先,模塊是預先注冊自己以便服務於將來的某個請求,然後他的初始化函數就立即結束。換句話說,
模塊初始化函數的任務就是為以後調用函數預先作准備。
好處:
1) 應用程序在退出時,可以不管資源的釋放或者其他的清除工作,但是模塊的退出函數卻必須仔細此撤銷初始化函數所作的一切。
2) 該機制有助於縮短模塊的開發周期。即:注冊和卸載都很靈活方便。
4、copy_to_user()和copy_from_user()主要用於實現什麼功能?一般用於file_operations結構的哪些函數裡面? 由於內核空間和用戶空間是不能互相訪問的,如果需要訪問就必須借助內核函數進行數據讀寫。copy_to_user():完成內核空間到用戶空間的復制,copy_from_user():是完成用戶空間到內核空間的復制。
一般用於file_operations結構裡的read,write,ioctl等內存數據交換作用的函數。當然,如果ioctl沒有用到內存數據復制,那麼就不會用到這兩個函數。
5、請簡述主設備號和次設備號的用途。如果執行mknod chartest c 4 64,創建chartest設備。請分析chartest使用的是那一類設備驅動程序。1)主設備號:主設備號標識設備對應的驅動程序。雖然現代的linux內核允許多個驅動程序共享主設備號,但我們看待的大多數設備仍然按照“一個主設備對應一個驅動程序”的原則組織。
次設備號:次設備號由內核使用,用於正確確定設備文件所指的設備。依賴於驅動程序的編寫方式,我們可以通過次設備號獲得一個指向內核設備的直接指針,也可將此設備號當作設備本地數組的索引。
2)chartest 由驅動程序4管理,該文件所指的設備是64號設備。(感覺類似於串口終端或者字符設備終端)。
6、設備驅動程序中如何注冊一個字符設備?分別解釋一下它的幾個參數的含義。注冊一個字符設備驅動有兩種方法:
1) void cdev_init(struct cdev *cdev, struct file_operations *fops)
該注冊函數可以將cdev結構嵌入到自己的設備特定的結構中。cdev是一個指向結構體cdev的指針,而fops是指向一個類似於file_operations結構(可以是file_operations結構,但不限於該結構)的指針.
2) int register_chrdev(unsigned int major, const char *namem , struct file)operations *fopen);
該注冊函數是早期的注冊函數,major是設備的主設備號,name是驅動程序的名稱,而fops是默認的file_operations結構(這是只限於file_operations結構)。對於
register_chrdev的調用將為給定的主設備號注冊0-255作為次設備號,並為每個設備建立一個對應的默認cdev結構。
7、請簡述中斷於DMA的區別。Linux設備驅動程序中,使用哪個函數注冊和注銷中斷處理程序?1)DMA:是一種無須CPU的參與就可以讓外設與系統內存之間進行雙向數據傳輸的硬件機制,使用DMA可以使系統CPU從實際的I/O數據傳輸過程中擺脫出來,從而大大提高系統的吞吐率.
中斷:是指CPU在執行程序的過程中,出現了某些突發事件時CPU必須暫停執行當前的程序,轉去處理突發事件,處理完畢後CPU又返回源程序被中斷的位置並繼續執行。
所以中斷和DMA的區別就是DMA不需CPU參與而
中斷是需要CPU參與的。
2)中斷注冊函數和中斷注銷函數注冊中斷:int request_irq(unsigned int irq, irqreturn_t (*handler)(int, void *, struct pt_regs *), unsigned long flags, const char *dev_name, void *dev_id);
參數意義依次是:中斷號,中斷處理函數,中斷管理有關的掩碼,中斷請求設備名,中斷信號線。
過程是:dev_name設備請求中斷->cpu分配中斷號->設置中斷管理的掩碼->分配中斷信號線->處理中斷函數->完成之後再根據設置情況返回原處理程序處繼續處理程序。
注銷中斷Void free_irq(unsigned int irq, void *dev_id);
釋放中斷和中斷信號線
8、中斷和輪詢哪個效率高?怎樣決定是采用中斷方式還是采用輪詢方式去實現驅動? 中斷是CPU處於被動狀態下來接受設備的信號,而輪詢是CPU主動去查詢該設備是否有請求。凡事都是兩面性,所以,看效率不能簡單的說那個效率高。如果是請求設備是一個頻繁請求cpu的設備,或者有大量數據請求的網絡設備,那麼輪詢的效率是比中斷高。如果是一般設備,並且該設備請求cpu的頻率比較底,則用中斷效率要高一些。主要是看請求頻率。
9、簡單描述在cs8900的驅動設計中, 發送數據frame和接收數據frame的過程。1)發送流程如下:(1) 網絡設備驅動程序從上層協議傳遞過來的sk_buff參數獲得數據包的有效數據和長度,將有效數據放入臨時緩沖區。
(2) 對於以太網,如果有效數據的長度小於以太網沖突檢測所要求的數據桢的最小長度,則給臨時緩沖區的末尾填充0
(3) 設置硬件寄存器,驅使網絡設備進行數據發送操作。
2)接收流程 網絡設備接收數據主要是
由中斷引發設備的中斷處理函數,中斷處理函數判斷中斷類型,如果為接收中斷,則讀取接受到的數據,分配sk_buff數據結構和數據緩沖區,將接收到的數據復制到數據緩沖區,並調用netif_rx()函數將sk_buff傳遞給上層協議。
10、Cs8900.c的驅動中,發送數據frame的過程為什麼需要關中斷?接收數據frame的過程為什麼不需要關中斷? 在發送過程中是不能被打斷的,在發送的過程中,不關中斷,這時候如果有一個中斷到來,那麼cpu有可能會去相應該中斷,如果該中斷需要改寫的數據是發送數據的緩沖區,那麼緩沖區將被改寫,這樣即使cpu相應完畢該中斷,再發送數據,接收方也不認識該數據不能接收。
在接收數據的時候,需要打開中斷,是因為要及時的相應接收到的數據。如果關閉該中斷,那麼接收方有可能因為相應優先級高的中斷而接收不到該數據。
11、簡單描述skbuff這個數據結構在網絡結構中所起到的作用,為什麼需要一個skbuff,它的分配和釋放主要都在什麼部位 sk_buff結構非常重要,它的含義為
“套接字緩沖區”,用於在linux網絡子系統中的蓋層之間傳遞數據。
當發送數據包時,linux內核的網絡處理模塊必須建立一個包含要傳輸的數據包的sk_buff,然後將sk_buff遞交給下層,各層在sk_buff中添加不同的協議頭直至交給網絡設備發送。同樣的,當網絡設備從網絡媒介上接受到數據包後,它必須將接受到的數據轉換為sk_buff數據結構並傳遞給上層,蓋層不拋去相應的協議頭直至交給用戶。分配sk_buff在接受一開始就應該分配,在發送完畢數據之後可以釋放sk_buff
12、字符型驅動設備怎麼創建設備文件 手動創建:mknod /dev/led c 250 0 其中dev/led 為設備節點 c 代表字符設備 250代表主設備號 0代表次設備號
還有UDEV/MDEV自動創建設備文件的方式,UDEV/MDEV是運行在用戶態的程序,可以動態管理設備文件,包括創建和刪除設備文件,運行在用戶態意味著系統要運行之後。在 /etc/init.d/rcS 腳本文件中會執行
mdev -s 自動創建設備節點。
13、寫一個中斷服務需要注意哪些?如果中斷產生之後要做比較多的事情你是怎麼做的? 中斷處理例程應該盡量短,把能放在後半段(tasklet,等待隊列等)的任務盡量放在後半段。
寫一個中斷服務程序要注意快進快出,在中斷服務程序裡面盡量快速采集信息,包括硬件信息,然後退出中斷,要做其它事情可以使用工作隊列或者tasklet方式。也就是中斷上半部和下半部。
第二:中斷服務程序中不能有阻塞操作。應為中斷期間是完全占用CPU的(即不存在內核調度),中斷被阻塞住,其他進程將無法操作;
第三:中斷服務程序注意返回值,要用操作系統定義的宏做為返回值,而不是自己定義的OK,FAIL之類的。
14、自旋鎖和信號量在互斥使用時需要注意哪些?在中斷服務程序裡面的互斥是使用自旋鎖還是信號量?還是兩者都能用?為什麼? 使用自旋鎖的進程不能睡眠,使用信號量的進程可以睡眠。
中斷服務例程中的互斥使用的是自旋鎖,原因是在中斷處理例程中,硬中斷是關閉的;但是要注意這樣會丟失可能到來的中斷。
15、原子操作你怎麼理解?為了實現一個互斥,自己定義一個變量作為標記來作為一個資源只有一個使用者行不行? 原子操作指的是無法被打斷的操作。
第二句話的意思是:
定義一個變量,比如 int flag =0;
if(flag == 0)
{
flag = 1;
操作臨界區;
flag = 0;
}
16、insmod 一個驅動模塊,會執行模塊中的哪個函數?rmmod呢?這兩個函數在設計上要注意哪些?遇到過卸載驅動出現異常沒?是什麼問題引起的? insmod調用init函數,rmmod調用exit函數。這兩個函數在設計時要注意什麼?卸載模塊時曾出現卸載失敗的情形,原因是存在進程正在使用模塊,檢查代碼後發現產生了死鎖的問題。
要注意在init函數中申請的資源在exit函數中要釋放,包括存儲,ioremap,定時器,工作隊列等等。也就是一個模塊注冊進內核,退出內核時要清理所帶來的影響,帶走一切不留下一點痕跡。
17、驅動中操作物理絕對地址為什麼要先ioremap? 因為內核沒有辦法直接訪問物理內存地址,必須先
通過ioremap獲得對應的虛擬地址。
18、設備驅動模型三個重要成員是?platfoem總線的匹配規則是?在具體應用上要不要先注冊驅動再注冊設備?有先後順序沒? 設備驅動模型三個重要成員是 總線、設備、驅動;
platfoem總線的匹配規則是:要匹配的設備和驅動都要注冊;
19、linux內核裡面,內存申請有哪幾個函數,各自的區別? Kmalloc() __get_free_page() mempool_create()
20、 IRQ和FIQ有什麼區別,在CPU裡面是是怎麼做的?
21int *a;
char *b;
a 和 b本身是什麼類型?
a、b裡面本身存放的只是一個地址,難道是這兩個地址有不同麼?
22、 中斷的上半部分和下半部分的問題:講下分成上半部分和下半部分的原因,為何要分?講下如何實現? 上半部分執行與硬件相關的處理要求快, 而有些驅動在中斷處理程序中又需要完成大量工作,這構成矛盾,所以Linux有所謂的bottom half機制,中斷處理程序中所有不要求立即完成的,在開中斷的環境下,由底半程序隨後完成.
Linux的底半處理實際上是建立在內核的
軟中斷機制上的.如何實現該機制?
兩種方式
【tasklet 工作隊列】1.定義和初始化struct tasklet_struct tlet;
tasklet_init(&tlet, jit_tasklet_fn, (unsigned long) data);
參數
第一個:定義的tasklet變量
第二個:函數
第三個:數據 傳遞給回調函數的數據
2. 定義函數void jit_tasklet_fn(unsigned long arg)
{
//中斷的底半部
執行該函數的時候,已經出中斷了
printk("in jit_tasklet_fn jiffies=%ld\n",jiffies);
}
3. 在需要調度的地方調用以下函數tasklet_schedule(&tlet);
一般在中斷函數當中調度在不晚於下一個時鐘滴答之前執行
【tasklet 和定期器的區別】
1. 執行時間定時器的執行:時間是確定的
tasklet :不確定的
2.tasklet 執行耗時的操作的23、內核函數mmap的實現原理,機制?mmap函數實現把一個文件映射到一個內存區域,從而我們可以像讀寫內存一樣讀寫文件,他比單純調用read/write也要快上許多。在某些時候我們可以把內存的內容拷貝到一個文件中實現內存備份,當然,也可以把文件的內容映射到內存來恢復某些服務。另外,
mmap實現共享內存也是其主要應用之一,mmap系統調用使得進程之間通過映射同一個普通文件實現共享內存。
24、驅動裡面為什麼要有並發、互斥的控制?如何實現?講個例子?25、spinlock自旋鎖是如何實現的? 自旋鎖在同一時刻只能被最多一個內核任務持有,所以一個時刻只有一個線程允許存在於臨界區中。這點可以應用在多處理機器、或運行在單處理器上的
搶占式內核中需要的鎖定服務。
26、信號量簡介 這裡也介紹下信號量的概念,因為它的用法和自旋鎖有相似的地方。
Linux中的信號量是一種睡眠鎖。如果有一個任務試圖獲得一個已被持有的信號量時,信號量會將其推入等待隊列,然後讓其睡眠。這時處理器獲得自由去執行其它代碼。當持有信號量的進程將信號量釋放後,在等待隊列中的一個任務將被喚醒,從而便可以獲得這個信號量。
27、 任務調度的機制?28、什麼是GPIO? general purpose input/output GPIO是相對於芯片本身而言的,如某個管腳是芯片的GPIO腳,則該腳可作為輸入或輸出高或低電平使用,當然某個腳具有復用的功能,即可做GPIO也可做其他用途。 也就是說你可以把這些引腳拿來用作任何一般用途的輸入輸出,例如用一根引腳連到led的一極來控制它的亮滅,也可以用一根(一些)引腳連到一個傳感器上以獲得該傳感器的狀態,這給cpu提供了一個方便的控制周邊設備的途經。如果沒有足夠多的gpio管腳,在控制一些外圍設備時就會力有不逮,這時可采取的方案是使用CPLD來幫助管理。
29、在Linux C中,ls這個命令是怎麼被執行的? 使用fork創建一個進程或exec函數族覆蓋原進程。30、LINUX下的Socket套接字和Windows下的WinSock有什麼共同點?請從C/C++語言a)都基於TCP/IP協議,都提供了面向連接的TCP SOCK和無連接的UDP SOCK。
b)都是一個sock結構體。
c)都是使用sock文件句柄進行訪問。
d)都具有緩沖機制。
31、一個計劃跑LINUX系統的ARM系統把bootloader燒錄進去後,上電後串口上沒有任何輸出,硬件和軟件各應該去檢查什麼? 提示: 1.跑LINUX的系統一般都需要外擴DRAM,一般的系統也經常有NOR或NAND FLASH
bootloader一般是由匯編和C編寫的裸奔程序[5分]