已阅读5页,还剩1页未读, 继续免费阅读
版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
Linux核心定制在嵌入式系统中应用的探讨随着硬件的发展,只靠汇编语言已经无法满足嵌入式系统的开发要求了;同时种类繁多的开发平台无论是硬件的还是软件的平台都让人难以挑选;但是可以看到的是一些专用的软件平台必将被历史淘汰;硬件上ARM在嵌入式系统一家独大的局面也必将被打破。INTER也即将发布手机用CPU,AMD已经推出移动和嵌入式设备用的三个系列CPU;所以源代码开放对各种硬件支持良好的LINUX是嵌入式系统开发的必选软件平台;但是由于LINUX是针对台式机笔记本的,所以在各式驱动和内存等的支持上的过多导致相对嵌入式系统来说过分庞大;所以在嵌入式系统的开发中,我们可以对LINUX内核的驱动模块和内存管理上进行删减和定制;(Android系统、虚拟操作系统VMware的最新版本等都是对LINUX内核的驱动和内存管理进行深层次定制修改的LINUX变种)本文主要讨论在LINUX内核中定制开发嵌入式系统的驱动;对linux的devfs类型的驱动程序的编写可以从以下几大内容理解和入手:通过分析驱动程序源代码可以发现驱动程序一般可分三部分:核心数据结构;核心数据和资源的初始化,注册以及注消,释放;底层设备操作函数;A.核心数据结构struct file_operations fops 设备驱动程序接口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);block_device_operations 块设备驱动程序接口int (*open) (struct inode *, struct file *);int (*release) (struct inode *, struct file *);int (*ioctl) (struct inode *, struct file *, unsigned, unsigned long);int (*check_media_change) (kdev_t);int (*revalidate) (kdev_t);struct module *owner;块设备的READ().WRITE()不在这里注册,而是在设备的读写请求队列里注册,内核在这里将调用通用的blk_read(),blk_write().向读写队列发出读写请求. Linux 利用这些数据结构向内核注册open(),release(),ioctl(),check_media_change(),rvalidate()等函数的入口句柄.我们将要编写的open(),release(),ioctl(),check_media_change(),revalidate()等函数,将在驱动初始化的时候,通过一个此结构类型的变量向内核提供函数的 入口. struct request_queue_t 设备请求队列的数据结构struct request_list unsigned int count;unsigned int pending2;struct list_head free;struct request struct list_head queue;int elevator_sequence;kdev_t rq_dev;int cmd;/* READ or WRITE */int errors;unsigned long start_time;unsigned long sector;unsigned long nr_sectors;unsigned long hard_sector, hard_nr_sectors;unsigned int nr_segments;unsigned int nr_hw_segments;unsigned long current_nr_sectors, hard_cur_sectors;void * special;char * buffer;struct completion * waiting;struct buffer_head * bh;struct buffer_head * bhtail;request_queue_t *q;struct request_queue/* * the queue request freelist, one for reads and one for writes */struct request_listrq;/* * The total number of requests on each queue */int nr_requests;/* * Batching threshold for sleep/wakeup decisions */int batch_requests;/* * The total number of 512byte blocks on each queue */atomic_t nr_sectors;/* * Batching threshold for sleep/wakeup decisions */int batch_sectors;/* * The max number of 512byte blocks on each queue */int max_queue_sectors;/* * Together with queue_head for cacheline sharing */struct list_headqueue_head;elevator_televator;request_fn_proc* request_fn;merge_request_fn* back_merge_fn;merge_request_fn* front_merge_fn;merge_requests_fn* merge_requests_fn;make_request_fn* make_request_fn;plug_device_fn* plug_device_fn;/* * The queue owner gets to use this for whatever they like. * ll_rw_blk doesnt touch it. */void* queuedata;/* * This is used to remove the plug when tq_disk runs. */struct tq_structplug_tq;/* * Boolean that indicates whether this queue is plugged or not. */intplugged:1;/* * Boolean that indicates whether current_request is active or * not. */inthead_active:1;/* * Boolean that indicates you will use blk_started_sectors * and blk_finished_sectors in addition to blk_started_io * and blk_finished_io. It enables the throttling code to * help keep the sectors in flight to a reasonable value */intcan_throttle:1;unsigned longbounce_pfn;/* * Is meant to protect the queue in the future instead of * io_request_lock */spinlock_tqueue_lock;/* * Tasks wait here for free read and write requests */wait_queue_head_twait_for_requests;struct request*last_request;缓冲区和对缓冲区相应的I/O操作在此任务队列中相关联,等待内核的调度.如果是字符设备就不需要此数据结构.而块设备的read(),write()函数则在buffer_queue的initize和设备请求队列进行处理请求时候传递给request_fn().struct request_queue_t设备请求队列的变量类型,驱动程序在初始化的时候需要填写request_fn().其他的数据结构还有 I/O port,Irq,DMA 资源分配,符合POSIX标准的ioctl的cmd的构造和定义,以及描述设备自身的相关数据结构定义-如设备的控制寄存器的相关数据结构定义,BIOS里的参数定义,设备类型定义等. B.初始化和注册和注消,模块方式驱动程序的加载和卸载. 设备驱动程序在定义了数据结构后 ,首先开始初始化:如I/O 端口的检查和登记,内核对 I/O PORT的检查和登记提供了两个 函数check_region(int io_port, int off_set)和request_region(int io_port, int off_set,char *devname).I/O Port登记后,就可以用inb()和outb()进行操作了 .还有DMA和Irq的初始化检查和 登记, int request_irq(unsigned int irq ,void(*handle)(int,void *,struct pt_regs *),unsigned int long flags,const char *device);irq: 是要申请的中断。handle:中断处理函数指针。flags:SA_INTERRUPT 请求一个快速中断,0 正常中断。device:设备名。如果登记成功,返回0,这时在/proc/interrupts文件中可以看你请求的中断。DMA主要是在内存中分配交换内存空间.还有缓冲区,设备请求队列的初始化.还有设备控制寄存器的检查和初始化,还有对设备自身相关的数据结构的初始化,填写一些设备特定的数据等.然后,开始注册devfs_register()向VFS注册统一的设备操作函数.static struct file_operations XXX_fops = owner: THIS_MODULE, XXX_fops所属的设备模块 read: XXX_read, 读设备操作 write: XXX_write, 写设备操作 ioctl: XXX_ioctl, 控制设备操作 mmap: XXX_mmap, 内存重映射操作 open: XXX_open, 打开设备操作 release: XXX_release 释放设备操作 /* . */;blk_init_queue()队列初始化函数.request_irq()中断注册函数相应的注消函数:devfs_unregister (devfs_handle_t de);free_irq()释放中断,I/O资源,释放缓冲区,释放设备,请求队列,VFS节点等.模块方式驱动程序的加载和卸载.static int _init _init_module (void) /* . */static void _exit _cleanup_module (void) /* 加载驱动程序模块入口 */module_init(_init_module);/* 卸载驱动程序模块入口 */module_exit(_cleanup_module);_intrrupt()设备发生中断时的处理程序.1.对共享中断的处理;2.对spinlock以及其他的事务的处理;C. 底层设备操作函数的编写read().write(),open(),release(),check_media_change(),revalidate()等.open()和release()打开设备是通过调用file_operations结构中的函数open( )来完成的,它是驱动程序用来为今后的操作完成初始化准备工作的。在大部分驱动程序中,open( )通常需要完成下列工作: 1. 检查设备相关错误,如设备尚未准备好等。 2. 如果是第一次打开,则初始化硬件设备。 3. 识别次设备号,如果有必要则更新读写操作的当前位置指针f_ops。 4. 分配和填写要放在file-private_data里的数据结构。 5. 使用计数增1。释放设备是通过调用file_operations结构中的函数release( )来完成的,这个设备方法有时也被称为cl
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 公司耐火材料烧成工现场作业技术规程
- 2025年证券投资顾问之证券投资顾问业务真题练习试卷A卷附答案
- 2025年农产品电商市场竞争报告考核试卷及答案
- 中国寿命试验仪项目投资可行性研究报告
- 机动车内胎行业深度研究报告
- 氨基酸添加剂行业深度研究报告
- 石材切割行业深度研究报告
- 无味红霉素行业深度研究报告
- 电机铸铝转子压铸机行业深度研究报告
- 自动高速退火镀锡机行业深度研究报告
- 2025江苏南通市通州区石港镇招聘便民服务中心人员2人考试笔试模拟试题及答案解析
- 2025年全国共青团“新团员入团”应知应会知识考试能力检测试卷及一套完整答案详解
- 2025年公务员面试《行政管理与领导力测试》备考题库及答案解析
- 精神科常见疾病及护理
- 2025年仓储物流仓储员职业技能考试模拟题
- 氧化剂和还原剂课件高一上学期化学人教版
- DB65∕T 4777.2-2024 社区视频信息结构化处理系统 第2部分:接口协议要求
- 2025年证监会公务员考试行测金融知识模拟试卷(含答案)
- 纸箱厂安全生产责任制
- 2025华润电力招聘模拟试卷及参考答案详解一套
- 贮藏与加工课件
评论
0/150
提交评论