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

下載本文檔

版權說明:本文檔由用戶提供并上傳,收益歸屬內容提供方,若內容存在侵權,請進行舉報或認領

文檔簡介

1、5.4 內 存 管 理操作系統常用的內存管理方式:單一分配方式分區(qū)式分配方式頁式分配方式段式分配方式Linux系統采用了虛擬內存管理機制,就是交換和請求分頁存儲管理技術第1頁,共44頁。程序的鏈接和內存裝入第2頁,共44頁。連續(xù)分配方式單一連續(xù)分配 這是最簡單的一種存儲管理方式,但只能用于單用戶、單任務的操作系統中。采用這種存儲管理方式時,可把內存分為系統區(qū)和用戶區(qū)兩部分,系統區(qū)僅提供給OS使用,通常是放在內存的低址部分;用戶區(qū)是指除系統區(qū)以外的全部內存空間, 提供給用戶使用。 第3頁,共44頁。固定分區(qū)分配 1. 劃分分區(qū)的方法 分區(qū)大小相等, 即使所有的內存分區(qū)大小相等。 (2) 分區(qū)大小

2、不等。 第4頁,共44頁。2. 內存分配 固定分區(qū)使用表 第5頁,共44頁。4.2.3 動態(tài)分區(qū)分配 1. 分區(qū)分配中的數據結構 空閑分區(qū)表。 (2) 空閑分區(qū)鏈。 空閑鏈結構 第6頁,共44頁。5.4.1 請求分頁機制1分頁概念邏輯空間分頁 內存空間分頁頁面和內存塊的大小是由硬件確定的 邏輯地址表示 內存分配原則頁表 第7頁,共44頁。2請求分頁的基本思想請求分頁提供虛擬存儲器 在每一個頁表項中增加一個狀態(tài)位表示一個頁面是否已裝入內存塊如果地址轉換機構遇到一個具有N狀態(tài)的頁表項時,便產生一個缺頁中斷 第8頁,共44頁。3Linux的多級頁表Linux進程的虛存空間 Linux系統采用三級頁表

3、的方式 第9頁,共44頁。4內存頁的分配與釋放Linux系統采用兩種方法來管理內存頁:位圖和鏈表 頁組中內存頁的數量依次按2的倍數遞增 第10頁,共44頁。5.4.2 內存交換內核的交換守護進程kswapd :有自己的進程控制塊task_struct結構,它與其他進程一樣受內核的調度。但是,它沒有自己獨立的地址空間,只使用系統空間,所以也把它稱為線程。它的任務就是保證系統中有足夠的空閑內存頁。當系統啟動時,交換守護進程由內核的init(初始化)進程啟動。被定時喚醒 。所做的工作主要分為兩部分:將若干不常用的活躍內存頁面變?yōu)椴换钴S狀態(tài);清理不活躍的“臟”頁面,或者回收一些內存頁,使之成為空閑的內

4、存頁。作為交換空間的交換文件實際就是普通文件,但它們所占的磁盤空間必須是連續(xù)的 第11頁,共44頁。7.5 內 存 管 理 #include void *malloc(size_t size); #include void *calloc(size_t nmemb, size_t size); #include void *realloc(void *ptr, size_t size); #include void free(void *ptr);第12頁,共44頁。5.6 設 備 管 理5.6.1 設備管理概述所有設備都作為特別文件,從而在管理上就具有下列共性:(1)每個設備都對應文件系統中

5、的一個索引節(jié)點,都有一個文件名。(2)應用程序通??梢酝ㄟ^系統調用open( )打開設備文件,建立起與目標設備的連接。(3)對設備的使用類似于對文件的存取。(4)設備驅動程序是系統內核的一部分,它們必須為系統內核或者它們的子系統提供標準的接口。(5)設備驅動程序利用一些標準的內核服務,如內存分配等。另外,大多數Linux設備驅動程序都可以在需要時裝入內核,不需要時卸載下來。 第13頁,共44頁。 設備驅動的分層結構 第14頁,共44頁。5.6.2 設備驅動程序和內核之間的接口1可安裝模塊可安裝模塊是可以在系統運行時動態(tài)地安裝和拆卸的內核模塊,即經過編譯但尚未連接的目標文件(后綴為.o)。設備驅

6、動程序或者與設備驅動緊密相關的部分(如文件系統)都是利用可安裝模塊實現的。 在通常情況下,用戶利用系統提供的插入模塊工具和移走模塊工具來裝卸可安裝模塊。 第15頁,共44頁。2字符設備用戶對字符設備的使用就和存取普通文件一樣。在應用程序中使用標準的系統調用來打開、關閉、讀寫字符設備。 第16頁,共44頁。3塊設備對塊設備的存取與對文件的存取方式一樣,其實現機制也與字符設備使用的機制相同。 第17頁,共44頁。設備驅動與文件系統的關系 設備驅動是Linux內核的重要組成部分。驅動程序跟一般的用戶應用程序不同,它工作在內核態(tài),編程方法和使用的庫函數都跟用戶級的應用程序有所區(qū)別。在Linux內核中,

7、設備驅動跟文件系統聯系緊密。每一個設備都是作為一個設備文件,交給文件系統去管理的。 設備驅動程序內部是由一組函數組成的。函數由設備驅動的上層文件系統來調用,每一個函數被稱做一個入口點。入口點的集合被稱為設備驅動程序的上半部分,實現設備驅動與文件系統的接口。常用的入口點有:open、close(或release)、read、write、ioctl等。 每一個函數的內部實現被稱作驅動程序的下半部分,負責實現具體的設備操作。函數的內部實現通常是靠系統調用提供的函數實現的,不能使用平常我們使用的用戶級的C語言庫函數。第18頁,共44頁。Linux通過設備號來區(qū)分不同的設備。設備號由兩部分組成:主設備號

8、MAJOR和次設備號MINOR。主設備號MAJOR指明對應哪些設備驅動。一般一個主設備號對應一個驅動程序。次設備號MINOR用來區(qū)分同一個驅動程序控制下的不同的獨立的設備。例如:硬盤的主設備名稱為hd。在/dev目錄下hd即為硬盤。/dev/hda、/dev/hdb等是系統的第一個硬盤和第二個硬盤。而hda0和hda1分別是第一個硬盤上的第一個分區(qū)和第二個分區(qū)。/proc/devices列出所有現在正在使用的設備號。設備號第19頁,共44頁。Linux操作系統將所有的設備全部看成文件,并通過文件的操作界面進行操作,用戶程序可以像對其他文件一樣對此設備文件進行操作。這意味著: 由于每一個設備至少

9、由文件系統的一個文件代表,因而都有一個“文件名”。 應用程序通??梢酝ㄟ^系統調用open()打開設備文件,建立起與目標設備的連接。 打開了代表著目標設備的文件,即建立起與設備的連接后,可以通過read()、write()、ioctl()等常規(guī)的文件操作對目標設備進行操作。設備文件的屬性由三部分信息組成:第一部分是文件的類型,第二部分是一個主設備號,第三部分是一個次設備號。其中類型和主設備號結合在一起惟一地確定了設備文件驅動程序及其界面,而次設備號則說明目標設備是同類設備中的第幾個。設備文件第20頁,共44頁。設備文件不能用普通的辦法建立。要通過mknod命令。mknod命令的語法:mknod

10、路徑 模式 主設備號 次設備號模式有兩種:c為字符設備 b為塊設備例如:mknod /dev/test c 254 0設備文件可以象普通文件一樣直接使用,例如:/dev/lp0為一個打印機,使用cat doc.txt/dev/lp0就可以將文檔交給打印機去進行打印/dev/ttyS0為主機上的串口COM1,使用讀寫文件的方法,也可以實現對串口的讀寫操作設備文件第21頁,共44頁。一、設備驅動中的關鍵數據結構二、驅動程序框架三、實現各種功能的基本函數四、實例設備驅動基礎第22頁,共44頁。要編寫設備驅動程序,就要實現它跟高層文件系統和底層硬件之間的操作接口。這些接口一般要遵循DDI/DKI(De

11、vice-Driver Interface / Device-Kernel Interface)接口規(guī)范,所以要使用一些標準的數據結構來進行操作。底層硬件的操作主要由不同硬件的特性來決定。跟文件系統的接口主要使用三個數據結構:inode文件索引節(jié)點結構struct file文件結構file_operations文件操作結構,設備驅動程序要實現這個結構里的主要操作一、設備驅動中的關鍵數據結構第23頁,共44頁。struct inode稱做索引節(jié)點數據結構,定義如下:struct inode struct list_headi_hash;struct list_headi_list;struct

12、list_headi_dentry;struct list_headi_dirty_buffers;struct list_headi_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_mtime;time_ti_ctime;unsigned inti_blkbits;unsigned longi_blksize;un

13、signed longi_blocks;unsigned longi_version;struct semaphorei_sem;struct semaphorei_zombie;struct inode_operations*i_op;struct file_operations*i_fop;/文件操作指針struct super_block*i_sb;wait_queue_head_ti_wait;struct file_lock*i_flock;struct address_space*i_mapping;struct address_spacei_data;struct dquot*i

14、_dquotMAXQUOTAS;struct list_headi_devices;struct pipe_inode_info*i_pipe;struct block_device*i_bdev;/塊設備struct char_device*i_cdev;/字符設備unsigned longi_dnotify_mask; struct dnotify_struct*i_dnotify; unsigned longi_state;unsigned inti_flags;unsigned chari_sock;atomic_ti_writecount;unsigned inti_attr_fla

15、gs;_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; struct iso_inode_infoisofs_i; struct nfs_inode_infonfs_i

16、; 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; struct hfs_inode_infohfs_i; struct adfs_inode_infoadfs_i;

17、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; struct jffs2_inode_infojffs2_i; void*generic_ip; u; 第24頁,共

18、44頁。struct file主要用于與文件系統相關的設備驅動程序,可提供關于被打開的文件的信息,定義如下:struct file struct list_headf_list;struct dentry*f_dentry;struct vfsmount *f_vfsmnt;struct file_operations*f_op;atomic_tf_count;unsigned int f_flags;mode_tf_mode;loff_tf_pos;unsigned long f_reada, f_ramax, f_raend, f_ralen, f_rawin;struct fown_st

19、ructf_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;第25頁,共44頁。struct file_operations struct module *owner;loff_t (*llseek) (str

20、uct 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 *, struct

21、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, struct fil

22、e *, int);int (*lock) (struct file *, int, struct file_lock *);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 *, in

23、t);unsigned long (*get_unmapped_area)(struct file *,unsigned long, unsigned long, unsigned long, unsigned long);在用戶自己的驅動程序中,首先要根據驅動程序的功能,完成file_operations結構中函數的實現。不需要的函數接口可以直接在file_operations結構中初始化為NULL。file_operations中的變量會在驅動程序初始化時,注冊到系統內部。每個進程對設備的操作,都會根據主次設備號,轉換成對file_operations結構的訪問。在設備驅動中,如果有需要的

24、操作而本結構中沒有提供的,統統交給ioctl函數實現 第26頁,共44頁。Linux的設備驅動程序與外部的接口可以分為三部分:驅動程序與內核的接口:通過file_operations來完成驅動程序與系統引導的接口:利用驅動程序對設備初始化驅動程序與設備的接口:描述了驅動程序如何與設備進行交互,這部分與具體設備密切相關驅動程序的代碼可以分成以下幾個部分:驅動程序的注冊和注銷;設備的打開和釋放;設備的讀寫;設備的控制;設備的中斷和查詢。二、設備驅動程序框架第27頁,共44頁。1. 驅動程序的注冊和注銷:驅動程序一般通過注冊的方式將自己的函數操作集與具體的設備關聯起來。所以,在設備初始化時,應向系統

25、進行登記register。卸載設備的時候用unregister注銷。字符設備和塊設備的注冊和注銷并不相同。字符設備的注冊函數是:int register_chrdev(unsigned int major,const char *name,struct file_operations *fops)卸載函數是:int unregister_chrdev(unsigned int major,const char *name)三、實現各部分需要的基本函數第28頁,共44頁。Linux對字符設備的管理是通過一個字符設備表chrdevs 來實現的。表里的每一項是一個device_struct結構。st

26、ruct device_structconst char *name;struct file_operations *fops;chrdevs 的數組下標就是字符設備的主設備號major。要查看系統中這個表格的當前內容,看/proc/devices即可。字符設備表第29頁,共44頁。字符設備的注冊:向chrdevs 中增加一個新項。int register_chrdev(int major,char *name,struct file_operations *fops)major為申請的主設備號,為0時,自動尋找一個空閑號分配。name為設備的名字。fops為驅動程序中file_operati

27、ons結構的指針。注冊成功時,返回申請到的主設備號。出錯時返回一個負值。字符設備的注銷:void unregister_chrdev(int major,char *name)字符設備表第30頁,共44頁。2. 設備讀寫:設備讀寫是實現用戶空間和內核空間的數據交換,因此涉及內存操作。設備驅動程序在申請和釋放內存時,因為使用的是內核空間,不能調用用戶空間的函數malloc和free,而代之以調用kmalloc和kfree,它們在linux/kernel.h中被定義為:void *kmalloc(unsigned int len, int priority);void kfree(void * o

28、bj);參數len為希望申請的字節(jié)數,obj為要釋放的內存指針。priority為分配內存操作的優(yōu)先級,即在沒有足夠空閑內存時如何操作,一般由取值GFP_KERNEL解決即可。三、實現各部分需要的基本函數第31頁,共44頁。2. 設備讀寫:設備讀寫是實現用戶空間和內核空間的數據交換,因此涉及內存操作。內存間數據的傳送:unsigned long copy_to_user(void *to,void *from,long count);unsigned long copy_from_user(void *to,void *from,long count);以上兩個函數的原型在三、實現各部分需要的

29、基本函數第32頁,共44頁。3. 設備控制:對設備的控制是通過對I/O端口的讀寫來實現的。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_region(struct resource *parent, unsigned lon

30、g 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ū)域的端口三、實現各部分需要的基本函數第33頁,共44頁。3. 設備控制:對設備的控制接口通過ioct

31、l函數來實現。它就象個大雜物箱,把跟設備有關的各種操作都裝在這里。例如:一個LCD的驅動,要實現清屏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:LINEDraw_Line();三、實現各部分需要的

32、基本函數第34頁,共44頁。編寫一個test.c,雖然它基本上什么也不干,但是它體現了一個字符設備驅動程序的基本框架:#define _NO_VERSION_#include #include #include #include #include #include #include #include #include #include unsigned int test_major = 0;/用一個靜態(tài)變量存儲設備號四、一個簡單的字符設備驅動程序第35頁,共44頁。read和write的實現:static sszie_t read_test(struct file *file,char *bu

33、f,size_t count,loff_t *fops)copy_to_user(*buf,*file,count);static sszie_t write_test(struct file *file,char *buf,size_t count,loff_t *fops)copy_from_user(*file,*buf,count);二、一個簡單的字符設備驅動程序第36頁,共44頁。open和release的實現:static int open_test(struct inode *inode,struct file *file)MOD_INC_USE_COUNT;return 0;s

34、tatic int release_test(struct inode *inode,struct file *file)MOD_DEC_USE_COUNT;return 0;二、一個簡單的字符設備驅動程序第37頁,共44頁。file_operations的實現:struct const struct file_operations test_fops=.read = read_test,.write = write_test,.open = open_test,.release = release_test;通過這個結構,將本程序的幾個函數集成在這個結構里,注冊到字符設備表里去。如果有ioctl函數,則驅動程序里就可以寫更豐富的函數了。二、一個簡單的字符設備驅動程序第38頁,共44頁。注冊和注銷:int init_module(void)int result;result = register_chrdev(0,”test”,&test_fops);if(test_major =

溫馨提示

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

評論

0/150

提交評論