(298 - a)
++
++接着解释下这个 makefile 文件:
++
(298 - b)解释 makefile 的二次编译:
++
(298 - c)开始执行 make ,编译,以及运行:
++
++USB 挂载,跟 NFS 一样,老师教了又一种方式:
++
(299)以下是一些注释:
(230)
(231)
// 头文件#include<linux/fs.h>#include<linux/cdev.h>#defineLED_MAJOR500// 和 mknod 的 500 一致#defineLED_MINOR0// 设备操作集:open/read/write/releasestaticstructfile_operationsled_fops={.owner=THIS_MODULE,.open=led_open,.write=led_write,};staticint__initled_drv_init(void){// 注册字符设备,主号500,名字"led",绑定fopsintret=register_chrdev(LED_MAJOR,"led",&led_fops);if(ret<0){pr_err("register_chrdev fail\n");returnret;}pr_info("led drv register ok, major=%d\n",LED_MAJOR);return0;}staticvoid__exitled_drv_exit(void){unregister_chrdev(LED_MAJOR,"led");}module_init(led_drv_init);module_exit(led_drv_exit);MODULE_LICENSE("GPL");#include<linux/fs.h>#include<linux/cdev.h>#include<linux/device.h>#include<linux/module.h>staticintmajor;staticstructcdevled_cdev;staticstructclass*led_class;staticstructdevice*led_dev;staticstructfile_operationsled_fops={.owner=THIS_MODULE,.open=led_open,.write=led_write,};staticint__initled_drv_init(void){dev_tdevno;// 1. 动态申请主次设备号(不用自己硬写500)intret=alloc_chrdev_region(&devno,0,1,"led_auto");if(ret)returnret;major=MAJOR(devno);// 2. 初始化cdev,绑定操作函数集cdev_init(&led_cdev,&led_fops);led_cdev.owner=THIS_MODULE;cdev_add(&led_cdev,devno,1);// 3. 创建设备类 /sys/class/ledled_class=class_create(THIS_MODULE,"led");if(IS_ERR(led_class)){ret=PTR_ERR(led_class);gotoerr_cdev;}// 4. 自动生成 /dev/led 节点!【重点】led_dev=device_create(led_class,NULL,devno,NULL,"led");if(IS_ERR(led_dev)){ret=PTR_ERR(led_dev);gotoerr_class;}pr_info("auto create /dev/led, major=%d minor=%d\n",major,MINOR(devno));return0;err_class:class_destroy(led_class);err_cdev:cdev_del(&led_cdev);unregister_chrdev_region(devno,1);returnret;}staticvoid__exitled_drv_exit(void){dev_tdevno=MKDEV(major,0);device_destroy(led_class,devno);class_destroy(led_class);cdev_del(&led_cdev);unregister_chrdev_region(devno,1);}module_init(led_drv_init);module_exit(led_drv_exit);MODULE_LICENSE("GPL");
++ 四、用户态测试代码极简示例(配套上面驱动) :
// test_led.c#include<stdio.h>#include<fcntl.h>#include<unistd.h>intmain(void){intfd=open("/dev/led",O_WRONLY);if(fd<0){perror("open /dev/led");return-1;}write(fd,"1",1);// 传给驱动write,点亮LEDclose(fd);return0;}五、实操命令汇总:
# 加载驱动insmod led.ko# 查看字符设备cat/proc/devices# 看/dev/led信息ls-l/dev/led# 卸载rmmod led(232)devtmpfs 在内核态;udev 是用户态守护进程:
(233)
(234)
(235)
谢谢