博文

目前显示的是标签为“vfs”的博文

PC蜂鸣器音乐

有了“使用procfs”、“I/O映射之I/O端口”、“内核读写磁盘文件”这三篇文章的基础后,我们将其结合,实现如下功能的实例: 1.打开传入的音乐谱文件(通过procfs接口); 2.读取音乐谱文件(以“频率”、“延时”、“频率”、“延时”、……这样的格式保存); 3.解析读取的文件; 4.将解析的数据传送去操作8254,让PC蜂鸣器弹奏文件对应的音乐。 好了,基础的内容看开头提及的文章,接下来上代码: #include <linux/init.h> #include <linux/module.h> #include <linux/fs.h> #include <linux/proc_fs.h> #include <asm/uaccess.h> #include <linux/timex.h> #ifndef MAX_PATH #define MAX_PATH 256 #endif #define PACKAGE_SIZE 512 extern void msleep(unsigned int msecs); struct proc_dir_entry * slam_dir = NULL; struct proc_dir_entry * slam_entry = NULL; static char * dir_name = "slam_song"; static char * entry_name = "path"; static void beep(unsigned int freq, unsigned int delay) { unsigned int count; if (freq) count = PIT_TICK_RATE / freq; else count = 20; outb_p(0xB6, 0x43); outb_p(count & 0xff, 0x42); outb((count >> 8) & 0xff, 0x42); ...

内核读写磁盘文件

在用户态,即我们一般编写的C语言程序中,可以使用open、close、read、write等系统调用对磁盘文件进行操作,那么在内核态呢?同样有相应的函数可以使用,而这些函数却是open这些系统调用会使用到的,故而我们还是在内核面向应用的层级进入,实现对磁盘文件的操作。关于如何从open一层层往下找到我们即将要使用的函数过程就不说了,下面直接给出我们用到的函数定义或原型信息,都在include/linux/fs.h文件中有声明,分别在fs/open.c和fs/read_write.c实现下面两类操作函数: 1.打开、关闭文件 struct file *filp_open(const char *filename, int flags, umode_t mode) ; 其中,filename就是文件名(包含完整路径),flags必须包含O_RDONLY、O_WRONLY或O_RDWR其中之一,而mode只有在flags包含O_CREAT时才有作用,表示打开的文件不存在就进行创建时该文件的访问权限,可以是S_IRWXU、S_IRUSR或S_IWUSR等的组合,对于O_和S_开头的这些宏说明可使用man 2 open命令查看,而这些宏则分别在内核include/uapi/asm-generic/fcntl.h和include/uapi/linux/stat.h文件中定义。 int filp_close(struct file *filp, fl_owner_t id) ; 其中,filp指针就是filp_open的返回值,id是POSIX线程的ID,而我们在内核态中操作,暂不需要用到,故一般设置为NULL即可。 2.读写文件 ssize_t vfs_read(struct file *file, char __user *buf, size_t count, loff_t *pos); ssize_t vfs_write(struct file *file, const char __user *buf, size_t count, loff_t *pos) ; 其中,file指针使用filp_open的返回值,buf是用户空间的内存(读写数据存放位置),count是读写多少单位(字节)的数据,pos表示当前文件读写所处于的偏移位置。 相信大家都注意到...