LDD3的1-3章, 第7章,第10章的學習筆記

Chapter1, Chapter2

(1) 實際上, current 不真正地是一個全局變量, 它產生一個指針指向結構 task_struct

printk(KERN_INFO "The process is \"%s\" (pid %i)\n", current->comm, current->pid);

存於 current->comm 的命令名稱是由當前進程執行的程序文件的基本名稱( 截短到 15 個字符, 如果需要 ). 

(2)在device driver的makefile中, ifneq ($(KERNELRELEASE),)判斷是否在內核根目錄下;–C  $(KERNELDIR) 指定了內核源代碼的位置,其中保存有內核的頂層 makefile文件;

Chapter3

(1)主設備號和次設備號 

主設備號表示設備對應的驅動程序; 

次設備號由內核使用,用於正確確定設備文件所指的設備。

內核用 dev_t 類型(<linux/types.h>)來保存設備編號,dev_t 是一個 32 位的數,12 位表示主設備

號,20爲表示次設備號。在實際使用中,是通過<linux/kdev_t.h>中定義的宏來轉換格式,如下: 

 (dev_t)->à主設備號、次設備號   MAJOR(dev_t dev)

  MINOR(dev_t dev)

 主設備號、次設備號->(dev_t)    MKDEV(int major,int minor)

int register_chrdev_region(dev_t first, unsigned int count,char *name);   //指定設備編號 

int alloc_chrdev_region(dev_t *dev, unsigned int firstminor,unsigned int count, char *name);   //動態生成設備編號 

void unregister_chrdev_region(dev_t first, unsigned int count);      //釋放設備編號

(2)一些重要的數據結構ile_operations、file 和inode,它們的定義都在<linux/fs.h>。

(3) 字符設備的註冊【參考LDD3 上新/老方法】

(4) 設備是不允許移位的, 通過調用 nonseekable_open 通知內核你的設備不支持 llseek

Chapter7

(1) int time_after(unsigned long a, unsigned long b);

(2) wait_event_interruptible_timeout, interrupt的意思是說, 當進入等待後, 我們進程可以被信號打斷, return值爲-ERESTARTSYS

(3)delay, cpu_relex是佔CPU的.sleep和schedure不佔CPU去休眠.

(4)定時器的實現(參考7.4)

Chapter10 中斷處理

(1)Linux的中斷處理程序分爲兩個部分:上半部(top half)和下半部(bottom half)。

上半部的功能是“登記中斷”。當一箇中斷髮生時,就把設備驅動程序中中斷例程的下半部掛到該設備的下半部執行隊列中去,然後就等待新的中斷的到來。這樣,上半部執行的速度就會很快,就可以接受所負責設備產生的更多中斷。上半部之所以要快,是因爲它是完全屏蔽中斷的,其它的中斷只能等到這個中斷處理程序執行完畢以後才能申請,不能得到及時的處理。快速的中斷處理程序就可以對設備產生的中斷儘可能多地進行服務。

下半部是可中斷的,而上半部是不可中斷的。上半部只是將下半部放入了它們所負責的設備的中斷處理隊列中去,然後就什麼都不管了。因此,下半部幾乎做了中斷處理程序所有的工作

由於下半部是可中斷的,所以在它運行期間,如果其它的設備產生了中斷,這個下半部可以暫時的中斷掉,等到那個設備的上半部運行完了,再回頭來運行它。

(2)Linux內核定義了兩種類型的中斷,快速的和慢速的,這兩者之間的一個區別是慢速中斷自身還可以被中斷,而快速中斷則不能。

(3)軟中斷是利用硬件中斷的概念,用軟件方式進行模擬,實現宏觀上的異步執行效果。硬中斷是外部設備對CPU的中斷,軟中斷通常是硬中斷服務程序對內核的中斷,信號則是由內核(或其它進程)對某個進程的中斷。

(4) 在/proc文件系統下,又兩個文件提供了中斷的信息。

從左到右分別是,

irq的序號, 在各自cpu上發生中斷的次數,可編程中斷控制器,設備名稱(request_irq的dev_name字段)

$cat /proc/interrupts 
           CPU0       CPU1       
  0: 2822434225          0    IO-APIC-edge  timer
  1:         12         45    IO-APIC-edge  i8042
  6:          3          0    IO-APIC-edge  floppy
  7:          0          0    IO-APIC-edge  parport0
  8:         13          0    IO-APIC-edge  rtc
  9:          0          0   IO-APIC-level  acpi
 12:        105        431    IO-APIC-edge  i8042
 14:        169  179654525    IO-APIC-edge  ide0
 50:          0          0   IO-APIC-level  uhci_hcd:usb4
 58:          0          0   IO-APIC-level  uhci_hcd:usb5
 74:       6870  651949183         PCI-MSI  ahci
 82:        193          0         PCI-MSI  HDA Intel
 90:         28  675362729         PCI-MSI  eth0
225:          0          0   IO-APIC-level  ehci_hcd:usb1, uhci_hcd:usb2
233:          0          0   IO-APIC-level  uhci_hcd:usb3
NMI:          0          0 
LOC: 2820592939 2820592942 
ERR:          0
MIS:          0

/proc/stat 文件中有一行記錄的機器從啓動依賴,各個中斷序號發生中斷的次數。

這一行以intr開頭,接下來的第一個數字是總的中斷數目,之後就是分別的中斷數目,從0開始。

$cat /proc/stat  | grep intr
intr 4329441883 2822466790 57 0 0 4 0 3 0 13 0 0 0 536 0 179654982 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 651956087 0 0 0 0 0 0 0 193 0 0 0 0 0 0 0 675363218 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0

(5) 主板上有8條IRQ(IRQ0-7)線連接到8位的ISA擴展槽。還有另外的8條(IRQ8-15)連接到16位的增強型ISA槽。所以,在一臺典型的ISA總線的PC機中總共有16條IRQ請求線。其中,IRQ0優先級最高,IRQ7的優先級最低。IRQ8-15的優先級有點特殊,IRQ8-15與IRQ2具有相同的優先等級

(6) 中斷共享. 

--SA_SHIRQ 位必須在 flags 參數中指定, 當請求中斷時. 

--dev_id 參數必須是獨特的. 任何模塊地址空間的指針都行, 但是 dev_id 明確地不能設置爲 NULL.

內核保持着一個與中斷相關聯的共享處理者列表, 並且 dev_id 可認爲是區別它們的簽名

--中斷線空閒.

--所有這條線的已經註冊的處理者也指定共享這個 IRQ.

無論何時 2 個或多個驅動在共享中斷線, 並且硬件中斷在這條線上中斷處理器, 內核爲這個中斷調用每個註冊的處理者, 傳遞它的 dev_id 給每個. 因此, 一個共享的處理者必須能夠識別它自己的中斷並且應當快速退出當它自己的設備沒有被中斷時. 確認返回 IRQ_NONE 無論何時你的處理者被調用並且發現設備沒被中斷.

void *dev_id 

用作共享中斷線的指針. 它是一個獨特的標識, 用在當釋放中斷線時以及可能還被驅動用來指向它自己的私有數據區(來標識哪個設備在中斷). 如果中斷沒有被共享, dev_id 可以設置爲 NULL, 但是使用這個項指向設備結構不管如何是個好主意

一、中斷類: 

    1. 中斷類型: 在request_irq(irq, handler, flags, devname, dev_id)中使用

    #define SA_SHIRQ            共享中斷(舊版本的,2.6.19之前的內核)

    #define IRQF_SHARED         共享中斷(新版本的)

    #define SA_INTERRUPT        快速中斷(舊版本的)

    #define IRQF_DISABLED       快速中斷(新版本的)

    #define IRQF_SAMPLE_RANDOM  表示本中斷源可以用作隨機數生成器的熵池

 

    2. 中斷的觸發類型: 在set_irq_type(irq, type)中使用

    #define IRQ_TYPE_NONE           0x00000000     未指明類型

    #define IRQ_TYPE_EDGE_RISING    0x00000001     上升沿觸發

    #define IRQ_TYPE_EDGE_FALLING   0x00000002     下降沿觸發
    #define IRQ_TYPE_EDGE_BOTH      (IRQ_TYPE_EDGE_FALLING | IRQ_TYPE_EDGE_RISING)
    #define IRQ_TYPE_LEVEL_HIGH     0x00000004     高電平觸發

    #define IRQ_TYPE_LEVEL_LOW      0x00000008     低電平觸發

    #define IRQ_TYPE_SENSE_MASK     0x0000000f     /* Mask of the above */
    #define IRQ_TYPE_PROBE          0x00000010     /* Probing in progress */

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章