【正文】
? 它的實現(xiàn)過程可以用狀態(tài)機來描述。 嵌入式網(wǎng)絡(luò)技術(shù) TCP/IP協(xié)議簡介 ? TCP/IP協(xié)議是一套把因特網(wǎng)上的各種系統(tǒng)互連起來的協(xié)議組,保證因特網(wǎng)上數(shù)據(jù)的準(zhǔn)確快速傳輸 ? 參考開放系統(tǒng)互連 (OSI)模型, TCP/IP通常采用一種簡化的四層模型 : ? 應(yīng)用層 ? 傳輸層 ? 網(wǎng)絡(luò)層 ? 鏈路層 TCP協(xié)議的實現(xiàn) ? TCP協(xié)議是面向連接的、端對端的可靠通信協(xié)議。 塊設(shè)備不需要編寫 file_operations結(jié)構(gòu)里的 read和 write函數(shù),但是也需要 read和 write在request中調(diào)用。make zImage重新編譯內(nèi)核 。 ?用命令: make clean。 ? 修改 drivers/char/Makefile; 假設(shè)我們把所以必要的函數(shù)寫 , 則在“ L_OBJS := \” 行把“ ” 加到其中 。 添加一個簡單的字符設(shè)備 ? 確定主設(shè)備號 ? 編寫 file_operations中的函數(shù)以及中斷處理函數(shù)。 struct blk_dev_struct struct request 設(shè)備的控制 ? ioctl() 一般做法是: 首先差錯檢查, 然后用一個大的 switch語句(可能是內(nèi)嵌的)來處理所有可能的 ioctl命令。 ?釋放設(shè)備: release() 遞減設(shè)備使用的計數(shù)器 釋放設(shè)備文件中的私有數(shù)據(jù)所占空間 如果是獨占設(shè)備,則要清除忙標(biāo)志,使其他進(jìn)程可以使用 如果是最后一個釋放,則關(guān)閉設(shè)備 設(shè)備的讀寫操作 ? 字符設(shè)備: foo_read()和 foo_write() ? 塊設(shè)備 block_read和 block_write()——策略規(guī)程,不需要在驅(qū)動程序中實現(xiàn)。 遞增設(shè)備使用的計數(shù)器。 確定次設(shè)備號,根據(jù)需要可更新設(shè)備的 f_op。 打開與釋放 ? 打開設(shè)備: open() 檢查與設(shè)備有關(guān)的錯誤,如未準(zhǔn)備好。 }。 struct device_struct { const char * name。 它調(diào)用kernel_thread (init, NULL, 0), 創(chuàng)建 init進(jìn)程進(jìn)行系統(tǒng)配置 ( 其中包括所有設(shè)備的初始化工作 ) 。與具體設(shè)備相關(guān)。 ,初始化設(shè)備。它可以允許你在獨立于操作系統(tǒng)的部分進(jìn)行常規(guī)的編譯。 LINUX: 從技術(shù)上講,這個標(biāo)志不是必要的。 所有的內(nèi)核模塊都必須包含特定的標(biāo)志: __KERNEL__:這個標(biāo)志告訴頭文件此代碼將在內(nèi)核模塊中運行 , 而不是作為用戶進(jìn)程 。 ④調(diào)用系統(tǒng)調(diào)用 sys_create_module、sys_init_module,將 Mymodule鏈入到系統(tǒng)中去。 ② 將 Mymodule目標(biāo)文件讀進(jìn) insmod用戶進(jìn)程空間 , 成為一個映像 。 sc o d es i z en _ s y m b o l sn _ r e f sa d d ra d d rm o d u l en a m en a m en e x tn e x tm o d u l es y m b o l _ t a b l ei n t e r n a l _ s y m b o l 結(jié)構(gòu)m o d u l e _ r e f 結(jié)構(gòu)s t r i n g t a b l en a m e i sh e r e圖 1 m o d u l e 與 s y m b o l _ t a b l e 的 結(jié) 構(gòu) 示意 圖模塊基礎(chǔ) ——系統(tǒng)調(diào)用 ? Sys_create_module 為模塊分配空間 , 將模塊鏈入系統(tǒng)的模塊鏈中 ? Sys_init_module 初始化模塊 , 修正指針使模塊正常工作 ? Sys_delete_module 從系統(tǒng)模塊鏈中刪除模塊 , 釋放內(nèi)存空間 ? Sys_get_kernel_syms 將系統(tǒng)的所有符號表全部取出到用戶空間 核心空間i n s m o d 用戶進(jìn)程空間My mo du l e 目標(biāo)文件ke r ne lmo d ul eke r ne lsy m bo lmo d ul eAsy m bo lAke r ne l_ sy m結(jié)構(gòu)My m od ul eMy m od ul eMy s ym bo l磁盤內(nèi)存1234圖 i n s m od M y m o d u l e 的過程① insmod先調(diào)用系統(tǒng)調(diào)用 sys_get_kernel_syms,將當(dāng)前加到系統(tǒng)中的模塊和核心的符號表全部輸出到 kernel_sym結(jié)構(gòu)中 , 為后面使用 。 }。 struct module_ref { /*引用信息 */ struct module *module。 const char *name。 后面定義的是兩個零大小的數(shù)組聲明,便于動態(tài)分配空間。 struct module_ref ref[0]。 int n_refs。 struct symbol_table { int size。 /*三種狀態(tài):未初始化 , 運行 , 刪除 */ void (*cleanup)(void)。 /* size of module in pages */ void* addr。 /*符號表 */ const char *name。 struct module_ref *ref。 ? Use count:記錄使用本模塊的進(jìn)程數(shù)或模塊數(shù)。 void clean_module():模塊要求撤銷 init_module進(jìn)行的所有修改,使得模塊可以被安全的卸載。它遍歷 module_list,檢查被它裝入( AUTOCLEAN)并且不用( VISITED標(biāo)志)的模塊。修改核心的符號表,同時系統(tǒng)需要修改新 module依賴的所有module中的相關(guān)指針。 ? insmod調(diào)用 sys_create_module(),為新module分配一個 module數(shù)據(jù)結(jié)構(gòu),掛在module_list頭上 ,置新 module 狀態(tài)為UNINITIALIZED。 模塊基礎(chǔ) ——裝入 ? 符號表的記錄有兩個域:符號的名字( symbol name)和符號的值(一般是符號的地址)。kerneld裝入的 module,一般放在 /lib/modules/kernelversion目錄下。 守護(hù)進(jìn)程:在超級用戶下運行的一個用戶進(jìn)程,與核心建立一個 IPC通道。這個 dependency file放在 /lib/modules/[當(dāng)前kernel版本 ]/。 ? rmmod 把某個沒在用的 module 從 kerne中卸載 。 ? 所有聲明為 global的函數(shù)或變量都意味著被導(dǎo)出,可以被其他模塊使用。 ? 模塊可以使用的函數(shù): 自身定義; 其他 module提供; 內(nèi)核提供 ? 命令 ksyms – a:列出已經(jīng)加載的模塊的函數(shù)或變量。 ? 模塊之間的函數(shù)調(diào)用 內(nèi)核可以使用其它模塊或內(nèi)核的函數(shù),也可以 export一些函數(shù)供其他模塊或內(nèi)核使用。 ? 而且 module一般需要調(diào)用核心的資源,所以必須注意 module的版本和核心的版本的相配問題。 ? 一些與進(jìn)程相關(guān)的系統(tǒng)調(diào)用 模塊編程基礎(chǔ) ? 模塊的基本概念: 可以動態(tài)的加載到內(nèi)核中成為 kernel的一部分;加載后可以訪問內(nèi)核的數(shù)據(jù)結(jié)構(gòu); 用戶空間的程序或進(jìn)程可以通過某個模塊和內(nèi)核交互。 void ll_rw_block(int rw, int nr, struct buffer_head*bh[]); 輔助函數(shù) ——其他 ? int printk(const char* fmt, ...) include linux/ 在內(nèi)核中打印信息,是 printf的內(nèi)核版本 可能導(dǎo)致隱含的 I/O操作。0xff) 輔助函數(shù) ——設(shè)備的注冊和注銷 ? int register_chrdev(unsigned int major, const char *name, struct file_operations *fops) int register_blkdev(unsigned int major, const char *name, struct file_operations *fops) int unregister_chrdev(unsigned int major, const char *name) int unregister_blkdev(unsigned int major, const char *name) include linux/ include linux/ 輔助函數(shù) ——內(nèi)存空間轉(zhuǎn)換 ? inline void memcpy_tofs(void * to, const void * from, unsigned long n) inline void memcpy_fromfs(void * to, const void * from, unsigned long n) include asm/ ? define get_user(ptr) \ ((__typeof__(*(ptr)))__get_user((ptr),sizeof(*(ptr)))) define put_user(x,ptr) \ __put_user((unsigned long)(x),(ptr),sizeof(*(ptr))) include asm/ ? 在用戶空間和內(nèi)核空間拷貝內(nèi)存 ? 屬于隱含的 I/O操作,不要再臨界代碼中使用,因為它可能沖破cli()和 sti()的保護(hù) 輔助函數(shù) ——緩沖區(qū)管理 ? struct buffer_head *getblk(kdev_t dev, int block, int size)。設(shè)備號 ? kmalloc() ? kfree() kfree_s() ? 設(shè)備號由主、次設(shè)備號拼接而成。 ? 電梯算法: 讀在寫前 低次設(shè)備號請求在高次設(shè)備號前 低塊號在高塊 號前 drivers/block/ 輔助函數(shù) ——定時器管理 ? void add_timer(struct timer_list * timer) void del_timer(struct timer_list * timer) void init_timer(struct timer_list * timer) ? struct timer_list 輔助函數(shù) ——中斷管理 ? extern int request_irq(unsigned int irq, void (*handler)(int, void*, struct pt_regs *), unsigned long flags, const char *device, void *dev_id)。是用來保證一致性的策略機制。 Struct file *file 指向此設(shè)備的文件結(jié)構(gòu)的指針 。這個地址將被映射到 addr。 Int prot 下面中的一個: PROT_READ 可以讀的區(qū)域 。 ? mmap()函數(shù) Struct inode *inode Struct file *file Unsigned long addr 需要映射進(jìn)入的主存開始地址 。 返回 : 出錯返回 error。 一般用于做 case語句的switch參數(shù) 。 結(jié)構(gòu) : 首先差錯檢查 , 然后用一個大的 switch語句來處理所有可能的 io