Linux设备驱动(第三版)笔记

1. hello world(.ko)

// CentOS 7 驱动头文件目录
/lib/modules/3.10.0-327.el7.x86_64/build/include/linux
#include <linux/init.h>
#include <linux/module.h>

static int hello_init(void)
{
    printk(KERN_ALERT "hello world\n");
    return 0;
}

static void hello_exit(void)
{
    printk(KERN_ALERT "goodbye world\n");
}

module_init(hello_init);
module_exit(hello_exit);

2. Makefile(.ko)

obj-m:=hello.o
KDIR:=/lib/modules/$(shell uname -r)/build
PWD:=$(shell pwd)

default:
	$(MAKE) -C $(KDIR) M=$(PWD) modules
	

3. insmod / rmmod

INSMOD(8)                                      insmod                                      INSMOD(8)

NAME
       insmod - Simple program to insert a module into the Linux Kernel

SYNOPSIS
       insmod [filename] [module options...]
       
RMMOD(8)                                        rmmod                                       RMMOD(8)

NAME
       rmmod - Simple program to remove a module from the Linux Kernel

SYNOPSIS
       rmmod [-f] [-s] [-v] [modulename]

4. dmesg

DMESG(1)                                    User Commands                                   DMESG(1)

NAME
       dmesg - print or control the kernel ring buffer

SYNOPSIS
       dmesg [options]

       dmesg --clear
       dmesg --read-clear [options]
       dmesg --console-level level
       dmesg --console-on
       dmesg --console-off

5. 设备的主、次编号

在这里插入图片描述

	if (scull_major) 
	{
	 dev = MKDEV(scull_major, scull_minor);
	 result = register_chrdev_region(dev, scull_nr_devs, "scull");
	} 
	else 
	{
	 result = alloc_chrdev_region(&dev, scull_minor, scull_nr_devs, "scull");
	 scull_major = MAJOR(dev);
	}
	
	if (result < 0) 
	{
	 printk(KERN_WARNING "scull: can't get major %d\n", scull_major);
	 return result;
	} 
	

6. 文件系统相关操作(如何打开、读、写、关闭设备)

在这里插入图片描述

// fs.h
struct file_operations {
	struct module *owner;
	loff_t (*llseek) (struct file *, loff_t, int);
	ssize_t (*read) (struct file *, char __user *, size_t, loff_t *);
	ssize_t (*write) (struct file *, const char __user *, size_t, loff_t *);
	ssize_t (*aio_read) (struct kiocb *, const struct iovec *, unsigned long, loff_t);
	ssize_t (*aio_write) (struct kiocb *, const struct iovec *, unsigned long, loff_t);
	int (*readdir) (struct file *, void *, filldir_t);
	unsigned int (*poll) (struct file *, struct poll_table_struct *);
	long (*unlocked_ioctl) (struct file *, unsigned int, unsigned long);
	long (*compat_ioctl) (struct file *, unsigned int, unsigned long);
	int (*mmap) (struct file *, struct vm_area_struct *);
	int (*open) (struct inode *, struct file *);
	int (*flush) (struct file *, fl_owner_t id);
	int (*release) (struct inode *, struct file *);
	int (*fsync) (struct file *, loff_t, loff_t, int datasync);
	int (*aio_fsync) (struct kiocb *, int datasync);
	int (*fasync) (int, struct file *, int);
	int (*lock) (struct file *, int, struct file_lock *);
	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);
	int (*check_flags)(int);
	int (*flock) (struct file *, int, struct file_lock *);
	ssize_t (*splice_write)(struct pipe_inode_info *, struct file *, loff_t *, size_t, unsigned int);
	ssize_t (*splice_read)(struct file *, loff_t *, struct pipe_inode_info *, size_t, unsigned int);
	RH_KABI_REPLACE(int (*setlease)(struct file *, long, struct file_lock **), int (*setlease)(struct file *, long, struct file_lock **, void **))
	long (*fallocate)(struct file *file, int mode, loff_t offset,
			  loff_t len);
	int (*show_fdinfo)(struct seq_file *m, struct file *f);
};

struct file_operations scull_fops = {
 .owner = THIS_MODULE,
 .llseek = scull_llseek,
 .read = scull_read,
 .write = scull_write,
 .ioctl = scull_ioctl,
 .open = scull_open,
 .release = scull_release,
}; 

7. 注册字符设备

// cdev.h
#ifndef _LINUX_CDEV_H
#define _LINUX_CDEV_H

#include <linux/kobject.h>
#include <linux/kdev_t.h>
#include <linux/list.h>

struct file_operations;
struct inode;
struct module;

struct cdev {
        struct kobject kobj;
        struct module *owner;
        const struct file_operations *ops;
        struct list_head list;
        dev_t dev;
        unsigned int count;
};

void cdev_init(struct cdev *, const struct file_operations *);

struct cdev *cdev_alloc(void);

void cdev_put(struct cdev *p);

int cdev_add(struct cdev *, dev_t, unsigned);

void cdev_del(struct cdev *);

void cd_forget(struct inode *);

extern struct backing_dev_info directly_mappable_cdev_bdi;

8. 未完待续 …

猜你喜欢

转载自blog.csdn.net/qq_38408378/article/details/86168817