一、linux系統(tǒng)介紹
Linux是一套免費(fèi)使用和自由傳播的類Unix操作系統(tǒng),是一個(gè)基于POSIX和UNIX的多用戶、多任務(wù)、支持多線程和多CPU的操作系統(tǒng)。它能運(yùn)行主要的UNIX工具軟件、應(yīng)用程序和網(wǎng)絡(luò)協(xié)議。它支持32位和64位硬件。Linux繼承了Unix以網(wǎng)絡(luò)為核心的設(shè)計(jì)思想,是一個(gè)性能穩(wěn)定的多用戶網(wǎng)絡(luò)操作系統(tǒng)。它主要用于基于Intel x86系列CPU的計(jì)算機(jī)上。
Linux以它的高效性和靈活性著稱,Linux模塊化的設(shè)計(jì)結(jié)構(gòu),使得它既能在價(jià)格昂貴的工作站上運(yùn)行,也能夠在廉價(jià)的PC機(jī)上實(shí)現(xiàn)全部的Unix特性,具有多任務(wù)、多用戶的能力。Linux是在GNU公共許可權(quán)限下免費(fèi)獲得的,是一個(gè)符合POSIX標(biāo)準(zhǔn)的操作系統(tǒng)。Linux操作系統(tǒng)軟件包不僅包括完整的Linux操作系統(tǒng),而且還包括了文本編輯器、高級(jí)語言編譯器等應(yīng)用軟件。它還包括帶有多個(gè)窗口管理器的X-Windows圖形用戶界面,如同我們使用Windows NT一樣,允許我們使用窗口、圖標(biāo)和菜單對(duì)系統(tǒng)進(jìn)行操作。
二、linux啟動(dòng)流程
1、讀取MBR的信息,啟動(dòng)Boot Manager ,Windows使用NTLDR作為Boot Manager,如果您的系統(tǒng)中安裝多個(gè)版本的Windows,您就需要在NTLDR中選擇您要進(jìn)linux系統(tǒng)入的系統(tǒng)。Linux通常使用功能強(qiáng)大,配置靈活的GRUB作為Boot Manager,將在啟動(dòng)管理章節(jié)中向您介紹它的使用方式。
2、加載系統(tǒng)內(nèi)核,啟動(dòng)init進(jìn)程 ,init進(jìn)程是Linux的根進(jìn)程,所有的系統(tǒng)進(jìn)程都是它的子進(jìn)程。
3、init進(jìn)程讀取“/etc/inittab”文件中的信息,并進(jìn)入預(yù)設(shè)的運(yùn)行級(jí)別,按順序運(yùn)行該運(yùn)行級(jí)別對(duì)應(yīng)文件夾下的腳本。腳本通常以“start”參數(shù)啟動(dòng),并指向一個(gè)系統(tǒng)中的程序。 通常情況下,“/etc/rcS.d/”目錄下的啟動(dòng)腳本首先被執(zhí)行,然后是“/etc/rcN.d/”目錄。例如您設(shè)定的運(yùn)行級(jí)別為3,那么它對(duì)應(yīng)的啟動(dòng)目錄為“/etc/rc3.d/”。
4、根據(jù)“/etc/rcS.d/”文件夾中對(duì)應(yīng)的腳本啟動(dòng)Xwindow服務(wù)器“xorg”,Xwindow為L(zhǎng)inux下的圖形用戶界面系統(tǒng)。
5、啟動(dòng)登錄管理器,等待用戶登錄 ,Ubuntu系統(tǒng)默認(rèn)使用GDM作為登錄管理器,您在登錄管理器界面中輸入用戶名和密碼后,便可以登錄系統(tǒng)。
三、Linux Zynq GPIO中斷源
注冊(cè)中斷:對(duì)每個(gè)pin進(jìn)行循環(huán)遍歷for (pin_num = 0; pin_num 《 min_t(int, ZYNQ_GPIO_NR_GPIOS, (int)chip-》ngpio); pin_num++)
gpio_irq = irq_find_mapping(irq_domain, pin_num); 將GPIO號(hào)映射為L(zhǎng)inux系統(tǒng)中斷號(hào)。
在Linux中斷系統(tǒng)中,一個(gè)irq_domain表示一個(gè)中斷控制器,其內(nèi)中斷由0開始編號(hào)(尚存在疑問)
unsigned int irq_find_mapping(struct irq_domain *domain, irq_hw_number_t hwirq)
將一個(gè)中斷控制器上的某個(gè)硬件中斷映射為某個(gè)Linux系統(tǒng)中斷。
[cpp] view plain copy/**
* struct irq_domain - Hardware interrupt number translation object
* @link: Element in global irq_domain list.
* @name: Name of interrupt domain
* @ops: pointer to irq_domain methods
* @host_data: private data pointer for use by owner. Not touched by irq_domain
* core code.
*
* Optional elements
* @of_node: Pointer to device tree nodes associated with the irq_domain. Used
* when decoding device tree interrupt specifiers.
* @gc: Pointer to a list of generic chips. There is a helper function for
* setting up one or more generic chips for interrupt controllers
* drivers using the generic chip library which uses this pointer.
*
* Revmap data, used internally by irq_domain
* @revmap_direct_max_irq: The largest hwirq that can be set for controllers that
* support direct mapping
* @revmap_size: Size of the linear map table @linear_revmap[]
* @revmap_tree: Radix map tree for hwirqs that don‘t fit in the linear map
* @linear_revmap: Linear table of hwirq-》virq reverse mappings
*/
struct irq_domain {
struct list_head link;
const char *name;
const struct irq_domain_ops *ops;
void *host_data;
/* Optional data */
struct device_node *of_node;
struct irq_domain_chip_generic *gc;
/* reverse map data. The linear map gets appended to the irq_domain */
irq_hw_number_t hwirq_max;
unsigned int revmap_direct_max_irq;
unsigned int revmap_size;
struct radix_tree_root revmap_tree;
unsigned int linear_revmap[];
};
revmap_direct_max_irq: 小于該值的中斷,Linux中斷號(hào)和硬件中斷號(hào)相同,直接返回。
revmap_size: 線性反向映射(似乎要求域內(nèi)IRQ從零開始,有點(diǎn)矛盾),小于該值的hwirq直接利用linear_revmap做查找。
否則用radix tree來查找映射。
irq_set_chip_and_handler(gpio_irq, &zynq_gpio_irqchip, handle_simple_irq);
調(diào)用irq_get_desc_lock(irq, &flags, 0);,獲取irq對(duì)應(yīng)的irq_desc。并設(shè)定irq_desc的chip:desc-》irq_data.chip = chip;
調(diào)用irq_reserve_irq(irq);,將allocated_irqs中斷位圖中相應(yīng)的中斷標(biāo)識(shí)為已占用。
調(diào)用__irq_set_handler,將irq_desc中的handle_irq設(shè)定:desc-》handle_irq = handle;
irq_set_chip_data(gpio_irq, (void *)gpio);
這個(gè)比較簡(jiǎn)單,將要用私有的變量關(guān)聯(lián)到irq,desc-》irq_data.chip_data = data;
set_irq_flags(gpio_irq, IRQF_VALID);
總體調(diào)用:
irq_set_handler_data(irq_num, (void *)gpio);
這里的irq_num是通過irq_num = platform_get_irq(pdev, 0);獲取的系統(tǒng)配置文件里面的irq配置。這個(gè)函數(shù)也簡(jiǎn)單,實(shí)質(zhì)為:desc-》irq_data.handler_data = data;
irq_set_chained_handler(irq_num, zynq_gpio_irqhandler);
這個(gè)函數(shù)實(shí)質(zhì)為:desc-》handle_irq = handle;
最終調(diào)用關(guān)系為:調(diào)用zynq_gpio_irqhandler,然后在該函數(shù)中通過調(diào)用generic_handle_irq來調(diào)用最終的handle_simple_irq。
評(píng)論