linux教程 第08課內(nèi)存與設(shè)備管理_第1頁
linux教程 第08課內(nèi)存與設(shè)備管理_第2頁
linux教程 第08課內(nèi)存與設(shè)備管理_第3頁
linux教程 第08課內(nèi)存與設(shè)備管理_第4頁
linux教程 第08課內(nèi)存與設(shè)備管理_第5頁
已閱讀5頁,還剩39頁未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報或認(rèn)領(lǐng)

文檔簡介

1、12程序的程序的鏈接鏈接和內(nèi)存和內(nèi)存裝入裝入3連續(xù)分配方式連續(xù)分配方式單一連續(xù)分配單一連續(xù)分配 這是最簡單的一種存儲管理方式,但只能用于單用戶、單任務(wù)的操作系統(tǒng)中。采用這種存儲管理方式時,可把內(nèi)存分為系統(tǒng)區(qū)和用戶區(qū)兩部分,系統(tǒng)區(qū)僅提供給OS使用,通常是放在內(nèi)存的低址部分;用戶區(qū)是指除系統(tǒng)區(qū)以外的全部內(nèi)存空間, 提供給用戶使用。 4固定分區(qū)分配固定分區(qū)分配 1. 劃分分區(qū)的方法劃分分區(qū)的方法 分區(qū)大小相等, 即使所有的內(nèi)存分區(qū)大小相等。 (2) 分區(qū)大小不等。 52. 內(nèi)存分配內(nèi)存分配 固定分區(qū)使用表 64.2.3 動態(tài)分區(qū)分配動態(tài)分區(qū)分配 1. 分區(qū)分配中的數(shù)據(jù)結(jié)構(gòu)分區(qū)分配中的數(shù)據(jù)結(jié)構(gòu) 空閑分

2、區(qū)表。 (2) 空閑分區(qū)鏈。 空閑鏈結(jié)構(gòu) 前向指針N20N個字節(jié)可用后向指針N207891011121314 設(shè)備驅(qū)動的分層結(jié)構(gòu) 15161718 設(shè)備驅(qū)動是Linux內(nèi)核的重要組成部分。驅(qū)動程序跟一般的用戶應(yīng)用程序不同,它工作在內(nèi)核態(tài),編程方法和使用的庫函數(shù)都跟用戶級的應(yīng)用程序有所區(qū)別。在Linux內(nèi)核中,設(shè)備驅(qū)動跟文件系統(tǒng)聯(lián)系緊密。每一個設(shè)備都是作為一個設(shè)備文件,交給文件系統(tǒng)去管理的。 設(shè)備驅(qū)動程序內(nèi)部是由一組函數(shù)組成的。函數(shù)由設(shè)備驅(qū)動的上層文件系統(tǒng)來調(diào)用,每一個函數(shù)被稱做一個入口點(diǎn)。入口點(diǎn)的集合被稱為設(shè)備驅(qū)動程序的上半部分,實現(xiàn)設(shè)備驅(qū)動與文件系統(tǒng)的接口。常用的入口點(diǎn)有:open、clos

3、e(或release)、read、write、ioctl等。 每一個函數(shù)的內(nèi)部實現(xiàn)被稱作驅(qū)動程序的下半部分,負(fù)責(zé)實現(xiàn)具體的設(shè)備操作。函數(shù)的內(nèi)部實現(xiàn)通常是靠系統(tǒng)調(diào)用提供的函數(shù)實現(xiàn)的,不能使用平常我們使用的用戶級的C語言庫函數(shù)。19Linux通過設(shè)備號來區(qū)分不同的設(shè)備。設(shè)備號由兩部分組成:主設(shè)備號MAJOR和次設(shè)備號MINOR。主設(shè)備號MAJOR指明對應(yīng)哪些設(shè)備驅(qū)動。一般一個主設(shè)備號對應(yīng)一個驅(qū)動程序。次設(shè)備號MINOR用來區(qū)分同一個驅(qū)動程序控制下的不同的獨(dú)立的設(shè)備。例如:硬盤的主設(shè)備名稱為hd。在/dev目錄下hd即為硬盤。/dev/hda、/dev/hdb等是系統(tǒng)的第一個硬盤和第二個硬盤。而hd

4、a0和hda1分別是第一個硬盤上的第一個分區(qū)和第二個分區(qū)。/proc/devices列出所有現(xiàn)在正在使用的設(shè)備號。20Linux操作系統(tǒng)將所有的設(shè)備全部看成文件,并通過文件的操作界面進(jìn)行操作,用戶程序可以像對其他文件一樣對此設(shè)備文件進(jìn)行操作。這意味著: 由于每一個設(shè)備至少由文件系統(tǒng)的一個文件代表,因而都有一個“文件名”。 應(yīng)用程序通??梢酝ㄟ^系統(tǒng)調(diào)用open()打開設(shè)備文件,建立起與目標(biāo)設(shè)備的連接。 打開了代表著目標(biāo)設(shè)備的文件,即建立起與設(shè)備的連接后,可以通過read()、write()、ioctl()等常規(guī)的文件操作對目標(biāo)設(shè)備進(jìn)行操作。設(shè)備文件的屬性由三部分信息組成:第一部分是文件的類型,第

5、二部分是一個主設(shè)備號,第三部分是一個次設(shè)備號。其中類型和主設(shè)備號結(jié)合在一起惟一地確定了設(shè)備文件驅(qū)動程序及其界面,而次設(shè)備號則說明目標(biāo)設(shè)備是同類設(shè)備中的第幾個。21設(shè)備文件不能用普通的辦法建立。要通過mknod命令。mknod命令的語法:mknod 路徑 模式 主設(shè)備號 次設(shè)備號模式有兩種:c為字符設(shè)備 b為塊設(shè)備例如:mknod /dev/test c 254 0設(shè)備文件可以象普通文件一樣直接使用,例如:/dev/lp0為一個打印機(jī),使用cat doc.txt/dev/lp0就可以將文檔交給打印機(jī)去進(jìn)行打印/dev/ttyS0為主機(jī)上的串口COM1,使用讀寫文件的方法,也可以實現(xiàn)對串口的讀寫操

6、作22一、設(shè)備驅(qū)動中的關(guān)鍵數(shù)據(jù)結(jié)構(gòu)二、驅(qū)動程序框架三、實現(xiàn)各種功能的基本函數(shù)四、實例23要編寫設(shè)備驅(qū)動程序,就要實現(xiàn)它跟高層文件系統(tǒng)和底層硬件之間的操作接口。這些接口一般要遵循DDI/DKI(Device-Driver Interface / Device-Kernel Interface)接口規(guī)范,所以要使用一些標(biāo)準(zhǔn)的數(shù)據(jù)結(jié)構(gòu)來進(jìn)行操作。底層硬件的操作主要由不同硬件的特性來決定。跟文件系統(tǒng)的接口主要使用三個數(shù)據(jù)結(jié)構(gòu):inode文件索引節(jié)點(diǎn)結(jié)構(gòu)struct file文件結(jié)構(gòu)文件操作結(jié)構(gòu),設(shè)備驅(qū)動程序要實現(xiàn)這個結(jié)構(gòu)里的主要操作24struct inode稱做索引節(jié)點(diǎn)數(shù)據(jù)結(jié)構(gòu),定義如下:struc

7、t inode struct list_head i_hash;struct list_head i_list;struct list_head i_dentry;struct list_head i_dirty_buffers;struct list_head i_dirty_data_buffers;unsigned longi_ino;atomic_ti_count;kdev_ti_dev;umode_ti_mode;nlink_ti_nlink;uid_ti_uid;gid_ti_gid;kdev_ti_rdev;loff_ti_size;time_ti_atime;time_ti_m

8、time;time_ti_ctime;unsigned inti_blkbits;unsigned longi_blksize;unsigned longi_blocks;unsigned longi_version;struct semaphorei_sem;struct semaphorei_zombie;struct inode_operations*i_op;struct *i_fop;/文件操作指針文件操作指針struct super_block*i_sb;wait_queue_head_ti_wait;struct *i_flock;struct address_space*i_m

9、apping;struct address_spacei_data;struct dquot*i_dquotMAXQUOTAS;struct list_head i_devices;struct pipe_inode_info*i_pipe;struct block_device*i_bdev;/塊設(shè)備塊設(shè)備struct char_device*i_cdev;/字符設(shè)備字符設(shè)備unsigned longi_dnotify_mask; struct dnotify_struct*i_dnotify; unsigned longi_state;unsigned inti_flags;unsigne

10、d chari_sock;atomic_ti_writecount;unsigned inti_attr_flags;_u32i_generation;union struct minix_inode_infominix_i; struct ext2_inode_infoext2_i; struct ext3_inode_infoext3_i; struct hpfs_inode_infohpfs_i; struct ntfs_inode_infontfs_i; struct msdos_inode_infomsdos_i; struct umsdos_inode_infoumsdos_i;

11、struct iso_inode_infoisofs_i; struct nfs_inode_infonfs_i; struct sysv_inode_infosysv_i; struct affs_inode_infoaffs_i; struct ufs_inode_infoufs_i; struct efs_inode_infoefs_i; struct romfs_inode_inforomfs_i; struct shmem_inode_infoshmem_i; struct coda_inode_infocoda_i; struct smb_inode_infosmbfs_i; st

12、ruct hfs_inode_infohfs_i; struct adfs_inode_infoadfs_i; struct qnx4_inode_infoqnx4_i; struct reiserfs_inode_inforeiserfs_i; struct bfs_inode_infobfs_i; struct udf_inode_infoudf_i; struct ncp_inode_infoncpfs_i; struct proc_inode_infoproc_i; struct socketsocket_i; struct usbdev_inode_info usbdev_i; st

13、ruct jffs2_inode_infojffs2_i; void*generic_ip; u; 25struct file主要用于與文件系統(tǒng)相關(guān)的設(shè)備驅(qū)動程序,可提供關(guān)于被打開的文件的信息,定義如下:struct file struct list_headf_list;struct dentry*f_dentry;struct vfsmount *f_vfsmnt;struct *f_op;atomic_tf_count;unsigned int f_flags;mode_tf_mode;loff_tf_pos;unsigned long f_reada, f_ramax, f_raend

14、, f_ralen, f_rawin;struct fown_structf_owner;unsigned intf_uid, f_gid;intf_error;unsigned longf_version;/* needed for tty driver, and maybe others */void*private_data;/* preallocated helper kiobuf to speedup O_DIRECT */struct kiobuf*f_iobuf;longf_iobuf_lock;26struct struct module *owner;loff_t (*lls

15、eek) (struct file *, loff_t, int);ssize_t (*read) (struct file *, char *, size_t, loff_t *);ssize_t (*write) (struct file *, const char *, size_t, loff_t *);int (*readdir) (struct file *, void *, filldir_t);unsigned int (*poll) (struct file *, struct poll_table_struct *);int (*ioctl) (struct inode *

16、, struct file *, unsigned int, unsigned long);int (*mmap) (struct file *, struct vm_area_struct *);int (*open) (struct inode *, struct file *);int (*flush) (struct file *);int (*release) (struct inode *, struct file *);int (*fsync) (struct file *, struct dentry *, int datasync);int (*fasync) (int, s

17、truct file *, int);int (*lock) (struct file *, int, struct *);ssize_t (*readv) (struct file *, const struct iovec *, unsigned long, loff_t *);ssize_t (*writev) (struct file *, const struct iovec *, unsigned long, loff_t *);ssize_t (*sendpage) (struct file *, struct page *, int, size_t, loff_t *, int

18、);unsigned long (*get_unmapped_area)(struct file *,unsigned long, unsigned long, unsigned long, unsigned long);在用戶自己的驅(qū)動程序中,首先要根據(jù)驅(qū)動程序的功能,完成結(jié)構(gòu)中函數(shù)的實現(xiàn)。不需要的函數(shù)接口可以直接在結(jié)構(gòu)中初始化為NULL。中的變量會在驅(qū)動程序初始化時,注冊到系統(tǒng)內(nèi)部。每個進(jìn)程對設(shè)備的操作,都會根據(jù)主次設(shè)備號,轉(zhuǎn)換成對結(jié)構(gòu)的訪問。在設(shè)備驅(qū)動中,如果有需要的操作而本結(jié)構(gòu)中沒有提供的,統(tǒng)統(tǒng)交給ioctl函數(shù)實現(xiàn) 27Linux的設(shè)備驅(qū)動程序與外部的接口可以分為三部分:驅(qū)動程序與內(nèi)

19、核的接口:通過來完成驅(qū)動程序與系統(tǒng)引導(dǎo)的接口:利用驅(qū)動程序?qū)υO(shè)備初始化驅(qū)動程序與設(shè)備的接口:描述了驅(qū)動程序如何與設(shè)備進(jìn)行交互,這部分與具體設(shè)備密切相關(guān)驅(qū)動程序的代碼可以分成以下幾個部分:驅(qū)動程序的注冊和注銷;設(shè)備的打開和釋放;設(shè)備的讀寫;設(shè)備的控制;設(shè)備的中斷和查詢。281. 驅(qū)動程序的注冊和注銷:驅(qū)動程序一般通過注冊的方式將自己的函數(shù)操作集與具體的設(shè)備關(guān)聯(lián)起來。所以,在設(shè)備初始化時,應(yīng)向系統(tǒng)進(jìn)行登記register。卸載設(shè)備的時候用unregister注銷。字符設(shè)備和塊設(shè)備的注冊和注銷并不相同。字符設(shè)備的注冊函數(shù)是:int register_chrdev(unsigned int major

20、,const char *name,struct *fops)卸載函數(shù)是:int unregister_chrdev(unsigned int major,const char *name)29Linux對字符設(shè)備的管理是通過一個字符設(shè)備表chrdevs 來實現(xiàn)的。表里的每一項是一個device_struct結(jié)構(gòu)。struct device_structconst char *name;struct *fops;chrdevs 的數(shù)組下標(biāo)就是字符設(shè)備的主設(shè)備號major。要查看系統(tǒng)中這個表格的當(dāng)前內(nèi)容,看/proc/devices即可。30字符設(shè)備的注冊:向chrdevs 中增加一個新項。in

21、t register_chrdev(int major,char *name,struct *fops)major為申請的主設(shè)備號,為0時,自動尋找一個空閑號分配。name為設(shè)備的名字。fops為驅(qū)動程序中結(jié)構(gòu)的指針。注冊成功時,返回申請到的主設(shè)備號。出錯時返回一個負(fù)值。字符設(shè)備的注銷:void unregister_chrdev(int major,char *name)312. 設(shè)備讀寫:設(shè)備讀寫是實現(xiàn)用戶空間和內(nèi)核空間的數(shù)據(jù)交換,因此涉及內(nèi)存操作。設(shè)備驅(qū)動程序在申請和釋放內(nèi)存時,因為使用的是內(nèi)核空間,不能調(diào)用用戶空間的函數(shù)malloc和free,而代之以調(diào)用kmalloc和kfree,它

22、們在linux/kernel.h中被定義為:void *kmalloc(unsigned int len, int priority);void kfree(void * obj);參數(shù)len為希望申請的字節(jié)數(shù),obj為要釋放的內(nèi)存指針。priority為分配內(nèi)存操作的優(yōu)先級,即在沒有足夠空閑內(nèi)存時如何操作,一般由取值GFP_KERNEL解決即可。322. 設(shè)備讀寫:設(shè)備讀寫是實現(xiàn)用戶空間和內(nèi)核空間的數(shù)據(jù)交換,因此涉及內(nèi)存操作。內(nèi)存間數(shù)據(jù)的傳送:unsigned long copy_to_user(void *to,void *from,long count);unsigned long co

23、py_from_user(void *to,void *from,long count);以上兩個函數(shù)的原型在333. 設(shè)備控制:對設(shè)備的控制是通過對I/O端口的讀寫來實現(xiàn)的。inline unsigned int inb(unsigned short port);inline unsigned int inb_p(unsigned short port);/讀端口inline void outb(char value,unsigned short port);inline void outb_p(char value,unsigned short port); /寫端口int _check_

24、region(struct resource *parent, unsigned long start, unsigned long n);/檢查一個區(qū)域的端口struct resource *_request_region(struct resource *parent, unsigned long start, unsigned long n, const char *name);/申請一個區(qū)域的端口void _release_region(struct resource *parent, unsigned long start, unsigned long n);/釋放一個區(qū)域的端口34

25、3. 設(shè)備控制:對設(shè)備的控制接口通過ioctl函數(shù)來實現(xiàn)。它就象個大雜物箱,把跟設(shè)備有關(guān)的各種操作都裝在這里。例如:一個LCD的驅(qū)動,要實現(xiàn)清屏LCD_Clear、顯示矩形Disp_Rect、畫線Draw_Line等功能。void LCD_Clear() void Disp_Rect() void Draw_Line static int *_ioctl(struct inode *inode, struct file *file, int cmd, long arg)switch(cmd)case:CLEARLCD_Clear();case:RECTDisp_Rect();case:LINE

26、Draw_Line();35編寫一個test.c,雖然它基本上什么也不干,但是它體現(xiàn)了一個字符設(shè)備驅(qū)動程序的基本框架:#define _NO_VERSION_#include #include #include #include #include #include #include #include #include #include unsigned int test_major = 0;/用一個靜態(tài)變量存儲設(shè)備號36read和write的實現(xiàn):static sszie_t read_test(struct file * *buf,size_t count,loff_t *fops)copy_to_user(*buf,*);static sszie_t write_test(struct file * *buf,size_t count,loff_t *

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論