驅動工程師的面試問題

2021-06-08 08:38:51 字數 3597 閱讀 5102

1.nt式的驅動要匯入的標頭檔案是ntddk.h,wdm式的驅動要匯入的是wdm.h。

2.nt式不支援即插即用,通過服務來手動載入;wdm是即插即用, 通過inf來載入。

3.wdm在裝置建立和pnp訊息處理上有區別。

在和驅動通訊過程中,我們一般都會碰到應該選擇何種型別的緩衝型別進行通訊。本文將簡要的介紹一下這3中型別的io緩衝。 我想用的最多的就是 緩衝區裝置讀寫(buffered)這種io進行的。現在來說說io manager是如何對這3中型別的io進行處理的。

1.io manager接收到由上層下發來的請求,這裡假設這個請求既包含有輸入緩衝,又有輸出緩衝。這個看看deviceiocontrol中的引數中就可以既包含輸入緩衝,又可以有輸出緩衝。
2.io manager檢查這個irp是何種型別的。如果是緩衝區裝置讀寫(buffered)的,那麼io manager就會在nonpagepool中分配乙個輸入緩衝和輸出緩衝之間最大的乙個;如果是 直接讀取裝置(direct)形式的,那麼就會首先將上傳傳下來的緩衝建立乙個mdl給irp。而如果是neither型別的,那麼直接就使用應用層傳下來的緩衝。
3.io manager將irp分派給指定的驅動進行處理。
4.驅動中根據io型別,得到合適的緩衝位址。如果是 緩衝區裝置讀寫(buffered)的,那麼就是irp的inbuffer和outbuffer共同使用systembuffer;如果是 直接讀取裝置(direct),那麼inbuffer 和outbuffer使用mdladdress;而如果是neither那麼就使用type3buffer(inbuffer)和userbuffer(outbuffer).
5.驅動返回,這裡自然就是將io manager分配的記憶體中的outbuffer拷貝給應用層的buffer中了。
不過有些事需要值得注意的幾點:
1.使用者層傳下來的如果是 緩衝區裝置讀寫(buffered)型別的,那就直接使用即可。如果是直接讀取裝置(direct)型別的那麼需要注意的是,在使用的時候需要將虛擬位址鎖記憶體中進行使用。如果是neither,因為這個是應用層的虛擬位址,而且這個虛擬位址是有程序上下文限制的,使用這個的時候務必使在指定的程序上下文中進行操作,如果不在制定的上下文可是使用kestackattachprocess 將驅動attach到指定程序上面,然後在進行操作,不過要記得keunstackdetachprocess進行detach。
2.在進行緩衝移動中,如果是很大快記憶體,那麼最好是使用mdl的方式。因為緩衝區裝置讀寫(buffered)使用的是nonpagepool中分配記憶體,系統的nonpagepool是有限的,如何使用這種方式會降低系統效能。也可以使用neither的方式,缺陷上面已經說了。
static在宣告區域性變數時和在宣告全域性變數時的區別:
1.全域性變數本身就是靜態儲存方式, 靜態全域性變數當然也是靜態儲存方式。 這兩者在儲存方式上並無不同。這兩者的區別雖在於非靜態全域性變數的作用域是整個源程式,當乙個源程式由多個原始檔組成時,非靜態的全域性變數在各個原始檔中都是有效的。 而靜態全域性變數則限制了其作用域, 即只在定義該變數的原始檔內有效, 在同一源程式的其它原始檔中不能使用它。由於靜態全域性變數的作用域侷限於乙個原始檔內,只能為該原始檔內的函式公用,因此可以避免在其它原始檔中引起錯誤。
2.static函式與普通函式作用域不同。僅在本檔案。只在當前原始檔中使用的函式應該說明為內部函式(static),內部函式應該在當前原始檔中宣告和定義。對於可在當前原始檔以外使用的函式,應該在乙個標頭檔案中宣告,要使用這些函式的原始檔要包含這個標頭檔案。
3.static全域性變數與普通的全域性變數有什麼區別:
static全域性變數只初使化一次,防止在其他檔案單元中被引用;
4.static區域性變數和普通區域性變數有什麼區別:
5.static函式與普通函式有什麼區別:
static函式在記憶體中只有乙份,普通函式在每個被呼叫中維持乙份拷貝
6.程式的區域性變數存在於(堆疊)中,全域性變數存在於(靜態區 )中,動態申請資料存在於( 堆)中。

7.__cdecl(俗稱c呼叫),__stdcall和__fastcall三種呼叫的不同點,他們作為函式的呼叫的三種方式,我們通過小例子來說明:

[plain]view plain

copy

int __stdcall test2(int a, int b)  

int __cdecl test(int x, int y)  

int __fastcall test3(int x, int y)  

int main()  

上邊的三種函式呼叫方式,如果預設,編譯器會預設使用__stdcall的呼叫方式,對於__cdecl這種呼叫方式,乙個很大的特點就是,呼叫完成後,由誰了完成棧的清理工作,通過反彙編上述**,

我們可以得到答案,這個必須由呼叫者自己執行 add esp,x;這個x由你的引數的個數決定的。

__stdcall的呼叫方式則與這種不同,調研前:

當進入函式體後:

我們可以清楚的看到當函式返回的時候,執行了 ret x,這個x同樣與引數的個數有關的。

__fastcall的也有自己的特點,我們從名字看就發現有些不一樣了,fast呼叫,很快的哦,那麼怎麼樣才能

快呢?一切取決於它在引數個數少於3時,使用暫存器傳引數,這樣會避免由於引數壓棧帶來的時間的開銷。

這裡是它自己與其他兩種的呼叫方式的不同,那麼它清棧的方式呢?

從這裡我們可以看到,由於前兩個引數傳遞使用的是暫存器,所以在返回清棧的時候,同樣使用ret x;

只不過它與引數的個數有關。

1. 互斥量與臨界區的作用非常相似,但互斥量是可以命名的,也就是說它可以跨越程序使用。所以建立互斥量需要的資源更多,所以如果只為了在程序內部是用的話使 用臨界區會帶來速度上的優勢並能夠減少資源佔用量。因為互斥量是跨程序的互斥量一旦被建立,就可以通過名字開啟它。

2. 互斥量(mutex),訊號燈(semaphore),事件(event)都可以被跨越程序使用來進行同步資料操作,而其他的物件與資料同步操作無關,但 對於程序和執行緒來講,如果程序和執行緒在執行狀態則為無訊號狀態,在退出後為有訊號狀態。所以可以使用waitforsingleobject來等待程序和 執行緒退出。

3. 通過互斥量可以指定資源被獨佔的方式使用,但如果有下面一種情況通過互斥量就無法處理,比如現在一位使用者購買了乙份三個併發訪問許可的資料庫系統,可以根 據使用者購買的訪問許可數量來決定有多少個執行緒/程序能同時進行資料庫操作,這時候如果利用互斥量就沒有辦法完成這個要求,訊號燈物件可以說是一種資源計數 器。

一、中斷:系統停止當前正在執行的程式而轉向其他服務,可能是因為優先順序高的請求

服務了,或者是因為人為安排中斷。中斷是屬於正常現象。  

異常:是由於軟體錯誤而引起的

二、中斷是cpu所具備的功能   --   硬體  

異常是軟體執行過程中的一種開發過程中沒有考慮到的程式錯誤   --   軟體 

linux驅動工程師面試

首先,我要說的是,就業成功最關鍵的因素在於紮實的基礎,很寬的知識面,豐富的實踐經驗.這些都是,工作學習中我們需要自己積累的內容,這些真的很重要,如果大家現在不是立馬就要找到乙份工作,建議把以上我提到的三點務必達到一定的要求,這些才是根本.當然,我寫這篇文章並不是向大家介紹怎麼學習,我想與大家分享的是...

驅動工程師 筆試題

一 選擇題 1 main 執行結果為 a.0 0 b.0 1 c.1 0 d.1 1 2 某檔案中定義的靜態全域性變數 或稱靜態外部變數 其作用域是 a.只限某個函式 b.本檔案 c.跨檔案 d.不限制作用域 3 設 int a 10 p a 則對陣列元素的正確引用是 a.a p b.p a c.p...

機器學習演算法工程師面試問題

手寫二叉樹前序遍歷 劍指offer青蛙跳台階問題 乙隻青蛙一次可以跳上1級台階,也可以跳上2級。求該青蛙跳上乙個n級的台階總共有多少種跳法?我 採用遞迴的方式做,f n f n 1 f n 2 n 3 f 1 1 f 2 2 面試官 如果不利用遞迴方式怎麼做?我 構建乙個vector向量,1,2,3...