欢迎来到三一办公! | 帮助中心 三一办公31ppt.com(应用文档模板下载平台)
三一办公
全部分类
  • 办公文档>
  • PPT模板>
  • 建筑/施工/环境>
  • 毕业设计>
  • 工程图纸>
  • 教育教学>
  • 素材源码>
  • 生活休闲>
  • 临时分类>
  • ImageVerifierCode 换一换
    首页 三一办公 > 资源分类 > PPT文档下载  

    linux教程第08课内存与设备管理.ppt

    • 资源ID:5382326       资源大小:540.01KB        全文页数:44页
    • 资源格式: PPT        下载积分:10金币
    快捷下载 游客一键下载
    会员登录下载
    三方登录下载: 微信开放平台登录 QQ登录  
    下载资源需要10金币
    邮箱/手机:
    温馨提示:
    用户名和密码都是您填写的邮箱或者手机号,方便查询和重复下载(系统自动生成)
    支付方式: 支付宝    微信支付   
    验证码:   换一换

    加入VIP免费专享
     
    账号:
    密码:
    验证码:   换一换
      忘记密码?
        
    友情提示
    2、PDF文件下载后,可能会被浏览器默认打开,此种情况可以点击浏览器菜单,保存网页到桌面,就可以正常下载了。
    3、本站不支持迅雷下载,请使用电脑自带的IE浏览器,或者360浏览器、谷歌浏览器下载即可。
    4、本站资源下载后的文档和图纸-无水印,预览文档经过压缩,下载后原文更清晰。
    5、试题试卷类文档,如果标题没有明确说明有答案则都视为没有答案,请知晓。

    linux教程第08课内存与设备管理.ppt

    5.4 内 存 管 理,操作系统常用的内存管理方式:单一分配方式分区式分配方式页式分配方式段式分配方式Linux系统采用了虚拟内存管理机制,就是交换和请求分页存储管理技术,程序的链接和内存装入,连续分配方式,单一连续分配,这是最简单的一种存储管理方式,但只能用于单用户、单任务的操作系统中。采用这种存储管理方式时,可把内存分为系统区和用户区两部分,系统区仅提供给OS使用,通常是放在内存的低址部分;用户区是指除系统区以外的全部内存空间,提供给用户使用。,固定分区分配,1.划分分区的方法,分区大小相等,即使所有的内存分区大小相等。(2)分区大小不等。,2.内存分配,固定分区使用表,4.2.3 动态分区分配,1.分区分配中的数据结构,空闲分区表。(2)空闲分区链。,空闲链结构,5.4.1 请求分页机制1分页概念逻辑空间分页 内存空间分页页面和内存块的大小是由硬件确定的 逻辑地址表示 内存分配原则页表,2请求分页的基本思想请求分页提供虚拟存储器 在每一个页表项中增加一个状态位表示一个页面是否已装入内存块如果地址转换机构遇到一个具有N状态的页表项时,便产生一个缺页中断,3Linux的多级页表Linux进程的虚存空间 Linux系统采用三级页表的方式,4内存页的分配与释放Linux系统采用两种方法来管理内存页:位图和链表 页组中内存页的数量依次按2的倍数递增,5.4.2 内存交换,内核的交换守护进程kswapd:有自己的进程控制块task_struct结构,它与其他进程一样受内核的调度。但是,它没有自己独立的地址空间,只使用系统空间,所以也把它称为线程。它的任务就是保证系统中有足够的空闲内存页。当系统启动时,交换守护进程由内核的init(初始化)进程启动。被定时唤醒。所做的工作主要分为两部分:将若干不常用的活跃内存页面变为不活跃状态;清理不活跃的“脏”页面,或者回收一些内存页,使之成为空闲的内存页。作为交换空间的交换文件实际就是普通文件,但它们所占的磁盘空间必须是连续的,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);,5.6 设 备 管 理5.6.1 设备管理概述,所有设备都作为特别文件,从而在管理上就具有下列共性:(1)每个设备都对应文件系统中的一个索引节点,都有一个文件名。(2)应用程序通常可以通过系统调用open()打开设备文件,建立起与目标设备的连接。(3)对设备的使用类似于对文件的存取。(4)设备驱动程序是系统内核的一部分,它们必须为系统内核或者它们的子系统提供标准的接口。(5)设备驱动程序利用一些标准的内核服务,如内存分配等。另外,大多数Linux设备驱动程序都可以在需要时装入内核,不需要时卸载下来。,设备驱动的分层结构,5.6.2 设备驱动程序和内核之间的接口,1可安装模块可安装模块是可以在系统运行时动态地安装和拆卸的内核模块,即经过编译但尚未连接的目标文件(后缀为.o)。设备驱动程序或者与设备驱动紧密相关的部分(如文件系统)都是利用可安装模块实现的。在通常情况下,用户利用系统提供的插入模块工具和移走模块工具来装卸可安装模块。,2字符设备用户对字符设备的使用就和存取普通文件一样。在应用程序中使用标准的系统调用来打开、关闭、读写字符设备。,3块设备对块设备的存取与对文件的存取方式一样,其实现机制也与字符设备使用的机制相同。,设备驱动与文件系统的关系,设备驱动是Linux内核的重要组成部分。驱动程序跟一般的用户应用程序不同,它工作在内核态,编程方法和使用的库函数都跟用户级的应用程序有所区别。在Linux内核中,设备驱动跟文件系统联系紧密。每一个设备都是作为一个设备文件,交给文件系统去管理的。设备驱动程序内部是由一组函数组成的。函数由设备驱动的上层文件系统来调用,每一个函数被称做一个入口点。入口点的集合被称为设备驱动程序的上半部分,实现设备驱动与文件系统的接口。常用的入口点有:open、close(或release)、read、write、ioctl等。每一个函数的内部实现被称作驱动程序的下半部分,负责实现具体的设备操作。函数的内部实现通常是靠系统调用提供的函数实现的,不能使用平常我们使用的用户级的C语言库函数。,Linux通过设备号来区分不同的设备。设备号由两部分组成:主设备号MAJOR和次设备号MINOR。主设备号MAJOR指明对应哪些设备驱动。一般一个主设备号对应一个驱动程序。次设备号MINOR用来区分同一个驱动程序控制下的不同的独立的设备。例如:硬盘的主设备名称为hd。在/dev目录下hd即为硬盘。/dev/hda、/dev/hdb等是系统的第一个硬盘和第二个硬盘。而hda0和hda1分别是第一个硬盘上的第一个分区和第二个分区。/proc/devices列出所有现在正在使用的设备号。,设备号,Linux操作系统将所有的设备全部看成文件,并通过文件的操作界面进行操作,用户程序可以像对其他文件一样对此设备文件进行操作。这意味着:由于每一个设备至少由文件系统的一个文件代表,因而都有一个“文件名”。应用程序通常可以通过系统调用open()打开设备文件,建立起与目标设备的连接。打开了代表着目标设备的文件,即建立起与设备的连接后,可以通过read()、write()、ioctl()等常规的文件操作对目标设备进行操作。设备文件的属性由三部分信息组成:第一部分是文件的类型,第二部分是一个主设备号,第三部分是一个次设备号。其中类型和主设备号结合在一起惟一地确定了设备文件驱动程序及其界面,而次设备号则说明目标设备是同类设备中的第几个。,设备文件,设备文件不能用普通的办法建立。要通过mknod命令。mknod命令的语法:mknod 路径 模式 主设备号 次设备号模式有两种:c为字符设备 b为块设备例如:mknod/dev/test c 254 0设备文件可以象普通文件一样直接使用,例如:/dev/lp0为一个打印机,使用cat doc.txt/dev/lp0就可以将文档交给打印机去进行打印/dev/ttyS0为主机上的串口COM1,使用读写文件的方法,也可以实现对串口的读写操作,设备文件,一、设备驱动中的关键数据结构二、驱动程序框架三、实现各种功能的基本函数四、实例,设备驱动基础,要编写设备驱动程序,就要实现它跟高层文件系统和底层硬件之间的操作接口。这些接口一般要遵循DDI/DKI(Device-Driver Interface/Device-Kernel Interface)接口规范,所以要使用一些标准的数据结构来进行操作。底层硬件的操作主要由不同硬件的特性来决定。跟文件系统的接口主要使用三个数据结构:inode文件索引节点结构struct file文件结构file_operations文件操作结构,设备驱动程序要实现这个结构里的主要操作,一、设备驱动中的关键数据结构,struct inode称做索引节点数据结构,定义如下:struct inode struct list_headi_hash;struct list_headi_list;struct 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;unsigned 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_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_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;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;struct 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;struct jffs2_inode_infojffs2_i;void*generic_ip;u;,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_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;,struct file_operations struct module*owner;loff_t(*llseek)(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*,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,struct file*,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*,int);unsigned long(*get_unmapped_area)(struct file*,unsigned long,unsigned long,unsigned long,unsigned long);在用户自己的驱动程序中,首先要根据驱动程序的功能,完成file_operations结构中函数的实现。不需要的函数接口可以直接在file_operations结构中初始化为NULL。file_operations中的变量会在驱动程序初始化时,注册到系统内部。每个进程对设备的操作,都会根据主次设备号,转换成对file_operations结构的访问。在设备驱动中,如果有需要的操作而本结构中没有提供的,统统交给ioctl函数实现,Linux的设备驱动程序与外部的接口可以分为三部分:驱动程序与内核的接口:通过file_operations来完成驱动程序与系统引导的接口:利用驱动程序对设备初始化驱动程序与设备的接口:描述了驱动程序如何与设备进行交互,这部分与具体设备密切相关驱动程序的代码可以分成以下几个部分:驱动程序的注册和注销;设备的打开和释放;设备的读写;设备的控制;设备的中断和查询。,二、设备驱动程序框架,1.驱动程序的注册和注销:驱动程序一般通过注册的方式将自己的函数操作集与具体的设备关联起来。所以,在设备初始化时,应向系统进行登记register。卸载设备的时候用unregister注销。字符设备和块设备的注册和注销并不相同。字符设备的注册函数是:int register_chrdev(unsigned int major,const char*name,struct file_operations*fops)卸载函数是:int unregister_chrdev(unsigned int major,const char*name),三、实现各部分需要的基本函数,Linux对字符设备的管理是通过一个字符设备表chrdevs 来实现的。表里的每一项是一个device_struct结构。struct device_structconst char*name;struct file_operations*fops;chrdevs 的数组下标就是字符设备的主设备号major。要查看系统中这个表格的当前内容,看/proc/devices即可。,字符设备表,字符设备的注册:向chrdevs 中增加一个新项。int register_chrdev(int major,char*name,struct file_operations*fops)major为申请的主设备号,为0时,自动寻找一个空闲号分配。name为设备的名字。fops为驱动程序中file_operations结构的指针。注册成功时,返回申请到的主设备号。出错时返回一个负值。字符设备的注销:void unregister_chrdev(int major,char*name),字符设备表,2.设备读写:设备读写是实现用户空间和内核空间的数据交换,因此涉及内存操作。设备驱动程序在申请和释放内存时,因为使用的是内核空间,不能调用用户空间的函数malloc和free,而代之以调用kmalloc和kfree,它们在linux/kernel.h中被定义为:void*kmalloc(unsigned int len,int priority);void kfree(void*obj);参数len为希望申请的字节数,obj为要释放的内存指针。priority为分配内存操作的优先级,即在没有足够空闲内存时如何操作,一般由取值GFP_KERNEL解决即可。,三、实现各部分需要的基本函数,2.设备读写:设备读写是实现用户空间和内核空间的数据交换,因此涉及内存操作。内存间数据的传送:unsigned long copy_to_user(void*to,void*from,long count);unsigned long copy_from_user(void*to,void*from,long count);以上两个函数的原型在,三、实现各部分需要的基本函数,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 long start,unsigned long n);/检查一个区域的端口struct resource*_request_region(struct resource*parent,unsigned long start,unsigned long n,const char*name);/申请一个区域的端口void _release_region(struct resource*parent,unsigned long start,unsigned long n);/释放一个区域的端口,三、实现各部分需要的基本函数,3.设备控制:对设备的控制接口通过ioctl函数来实现。它就象个大杂物箱,把跟设备有关的各种操作都装在这里。例如:一个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();,三、实现各部分需要的基本函数,编写一个test.c,虽然它基本上什么也不干,但是它体现了一个字符设备驱动程序的基本框架:#define _NO_VERSION_#include#include#include#include#include#include#include#include#include#include unsigned int test_major=0;/用一个静态变量存储设备号,四、一个简单的字符设备驱动程序,read和write的实现:static sszie_t read_test(struct file*file,char*buf,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);,二、一个简单的字符设备驱动程序,open和release的实现:static int open_test(struct inode*inode,struct file*file)MOD_INC_USE_COUNT;return 0;static int release_test(struct inode*inode,struct file*file)MOD_DEC_USE_COUNT;return 0;,二、一个简单的字符设备驱动程序,file_operations的实现:struct const struct file_operations test_fops=.read=read_test,.write=write_test,.open=open_test,.release=release_test;通过这个结构,将本程序的几个函数集成在这个结构里,注册到字符设备表里去。如果有ioctl函数,则驱动程序里就可以写更丰富的函数了。,二、一个简单的字符设备驱动程序,注册和注销:int init_module(void)int result;result=register_chrdev(0,”test”,二、一个简单的字符设备驱动程序,编写完成后的工作:编译用insmod安装,在/proc/devices里可看到安装的设备用mknod创建设备文件,设备号参见上条编写一个测试程序测试设备工作是否正常,二、一个简单的字符设备驱动程序,测试程序:#include#include#include#include main()int testdev,i;char buf10;testdev=open(“/dev/test”,O_RDWR);read(testdev,buf,10);for(i=0;i10;i+)printf(“%dn”,bufi);close(testdev);,二、一个简单的字符设备驱动程序,5.7 中断、异常和系统调用 5.7.1 中断处理,1中断响应一般说来,中断响应顺序执行下述三步动作:(1)中止当前程序的执行;(2)保存原程序的断点信息(主要是程序计数器PC和程序状态寄存器PS的内容);(3)从中断控制器取出中断向量,转到相应的处理程序。,2中断处理核心对中断处理的顺序主要由以下动作完成:保存正在运行进程的各寄存器的内容,把它们放入核 心栈的新帧面中。确定“中断源”或者核查中断发生,识别中断的类型(如时钟中断或者是盘中断)和中断的设备号(如哪个磁盘引起的中断)。系统接到中断后,就从机器那里得到一个中断号,它是检索中断向量表的位移。中断向量因机器而异,但通常都包括相应中断处理程序入口地址和中断处理时处理机的状态字。核心调用中断处理程序,对中断进行处理。中断处理完成并返回。中断处理程序执行完以后,核心便执行与机器相关的特定指令序列,恢复中断时寄存器内容和执行核心栈退栈,进程回到用户态。如果设置了重调度标志,则在本进程返回到用户态时做进程调度。,5.7.2 系统调用,系统调用象普通C函数调用那样出现在C程序中。只发生在用户空间。能把进程的状态从用户态变为核心态,Linux的系统调用是通过中断指令“INT 0 x80”实现的。Linux内核在系统调用时是通过寄存器而不是堆栈传递参数。所有的系统调用都集中在系统调用入口表中统一管理。系统调用入口表是一个函数指针数组(大小为256),以系统调用号为下标在该数组中找到相应的函数指针,进而就能确定用户使用的是哪一个系统调用。当CPU执行到中断指令“INT 0 x80”时,硬件就作出一系列响应,其动作与上述的中断响应相同,

    注意事项

    本文(linux教程第08课内存与设备管理.ppt)为本站会员(sccc)主动上传,三一办公仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。 若此文所含内容侵犯了您的版权或隐私,请立即通知三一办公(点击联系客服),我们立即给予删除!

    温馨提示:如果因为网速或其他原因下载失败请重新下载,重复下载不扣分。




    备案号:宁ICP备20000045号-2

    经营许可证:宁B2-20210002

    宁公网安备 64010402000987号

    三一办公
    收起
    展开