{"id":539,"date":"2019-09-23T14:15:12","date_gmt":"2019-09-23T06:15:12","guid":{"rendered":"http:\/\/iqotom.com\/?p=539"},"modified":"2019-10-17T14:26:12","modified_gmt":"2019-10-17T06:26:12","slug":"linux%e9%a9%b1%e5%8a%a8-%e5%ae%9e%e7%8e%b0%e4%b8%80%e4%b8%aa%e5%ad%97%e7%ac%a6%e8%ae%be%e5%a4%87%e9%a9%b1%e5%8a%a8","status":"publish","type":"post","link":"http:\/\/iqotom.com\/?p=539","title":{"rendered":"Linux\u9a71\u52a8 \u5b9e\u73b0\u4e00\u4e2a\u5b57\u7b26\u8bbe\u5907\u9a71\u52a8"},"content":{"rendered":"\n<p>================================================================<br>\u300a<a href=\"http:\/\/iqotom.com\/?p=526\">Linux\u9a71\u52a8 \u7f16\u8bd1\u4e00\u4e2ahello\u6a21\u5757<\/a>\u300b<br>\u300a<a href=\"http:\/\/iqotom.com\/?p=539\">Linux\u9a71\u52a8 \u5b9e\u73b0\u4e00\u4e2a\u5b57\u7b26\u8bbe\u5907\u9a71\u52a8<\/a>\u300b<br>\u300a<a href=\"http:\/\/iqotom.com\/?p=552\">Liunx\u9a71\u52a8 \u5b9e\u73b0\u4e00\u4e2amisc\u8bbe\u5907\u9a71\u52a8<\/a>\u300b <br> ================================================================ <\/p>\n\n\n\n<h3 class=\"wp-block-heading\">\u5b57\u7b26\u8bbe\u5907\u57fa\u7840\u77e5\u8bc6<\/h3>\n\n\n\n<p> \u5199\u4e00\u4e2a\u7b80\u5355\u7684linux\u5b57\u7b26\u8bbe\u5907\u9a71\u52a8\u7a0b\u5e8f\uff0c\u9700\u8981\u5185\u6838\u91cc\u7684\u4ee5\u4e0b\u51e0\u4e2a\u5934\u6587\u4ef6\uff0c\u56e0\u4e3a\u9700\u8981\u8c03\u7528\u4e00\u4e9b\u57fa\u672c\u7684\u5b8f\u548c\u4e00\u4e9b\u57fa\u672c\u7684\u51fd\u6570\u6765\u4f7f\u7528<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>#include &lt;linux\/cdev.h>\n#include &lt;linux\/kdev_t.h>\n#include &lt;linux\/fs.h><\/code><\/pre>\n\n\n\n<p> \u8fdb\u5165Linux\u5185\u6838\u6e90\u7801\uff0c\u8fdb\u5165<code>include\/linux\/<\/code>\uff0c\u6253\u5f00cdev.h <\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>struct cdev {\n\tstruct kobject kobj;\/\/\u8bbe\u5907\u6a21\u578b\u76f8\u5173\u7684\n\tstruct module *owner;\/\/\u6240\u5c5e\u4e8e\u54ea\u4e2a\u6a21\u5757--->THIS MODULE\n\t\/\/\u5229\u7528file_operations\u8ddf\u7528\u6237\u6001\u8fdb\u884c\u64cd\u4f5c--->\u6709open , read , write \u7b49\u65b9\u6cd5\n\tconst struct file_operations *ops;\n\tstruct list_head list;\/\/\u94fe\u8868,\u5c06\u8bbe\u5907\u63d2\u5165\u5230\u4e00\u6761\u94fe\u8868\u91cc\u53bb\n\tdev_t dev;\/\u901a\u8fc7\u8bbe\u5907\u53f7\u5339\u914d\u5bf9\u5e94\u7684\u9a71\u52a8\n\tunsigned int count;\/\/\u8981\u6ce8\u518c\u5b57\u7b26\u8bbe\u5907\u7684\u4e2a\u6570\n} __randomize_layout;<\/code><\/pre>\n\n\n\n<p> \u91cc\u9762\u8fd8\u6709\u90e8\u5206\u51fd\u6570\uff0c\u6211\u4eec\u6682\u65f6\u53ea\u9700\u8981<code>cdev_init,cdev_add,cdev_del<\/code><br> \u6253\u5f00kdev_t.h <\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>#define MINORBITS\t20\n#define MINORMASK\t((1U &lt;&lt; MINORBITS) - 1)\n\/\/\u4ece\u8bbe\u5907\u53f7\u4e2d\u53d6\u51fa\u4e3b\u8bbe\u5907\u53f7\n#define MAJOR(dev)\t((unsigned int) ((dev) >> MINORBITS))\n\/\/\u4ece\u8bbe\u5907\u53f7\u4e2d\u53d6\u51fa\u6b21\u8bbe\u5907\u53f7\n#define MINOR(dev)\t((unsigned int) ((dev) &amp; MINORMASK))\n\/\/\u521b\u5efa\u4e00\u4e2a\u8bbe\u5907\u53f7\n#define MKDEV(ma,mi)\t(((ma) &lt;&lt; MINORBITS) | (mi))<\/code><\/pre>\n\n\n\n<p> \u521b\u5efa\u8bbe\u5907\u53f7\u5c31\u9700\u8981kdev_t\u8fd9\u4e2a\u5b8f\uff0c\u521b\u5efa\u8bbe\u5907\u53f7\u540e\u8fd8\u8981\u5bf9\u8bbe\u5907\u8fdb\u884c\u6ce8\u518c\uff0c\u8fd9\u65f6\u5019\u9700\u8981fs.h\u8fd9\u4e2a\u5934\u6587\u4ef6\u91cc\u7684\u51fd\u6570\uff0c\u6ce8\u518c\u548c\u91ca\u653e<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>extern int register_chrdev_region(dev_t, unsigned, const char *);\n\/\/\u52a8\u6001\u5206\u914d\u8bbe\u5907\u53f7\uff0c\u7531\u5185\u6838\u7ed9\u6211\u4eec\u5206\u914d\u4e00\u4e2a\u8bbe\u5907\u53f7\uff0c\u8fd9\u4e2a\u8bbe\u5907\u53f7\u662f\u5185\u6838\u81ea\u52a8\u5206\u914d\u7684\uff0c\u5c31\u4e0d\u9700\u8981\u6211\u4eec\u53bb\u4f7f\u7528MKDEV\u8fd9\u4e2a\u5b8f\u6765\u8fdb\u884c\u624b\u52a8\nextern int alloc_chrdev_region(dev_t *, unsigned, unsigned, const char *);\nextern void unregister_chrdev_region(dev_t, unsigned);<\/code><\/pre>\n\n\n\n<p> \u7f16\u5199\u7b80\u5355\u7684\u5b57\u7b26\u8bbe\u5907\u9700\u8981\u4ee5\u4e0b\u6b65\u9aa4\uff1a <\/p>\n\n\n\n<ol><li> \u521b\u5efa\u8bbe\u5907\u53f7 <\/li><li> \u6ce8\u518c\u8bbe\u5907\u53f7 <\/li><li> \u9000\u51fa\u9a71\u52a8\u65f6\uff0c\u6ce8\u9500\u8bbe\u5907 <\/li><\/ol>\n\n\n\n<p> \u521b\u5efa\u8bbe\u5907\u6587\u4ef6\uff0c\u5229\u7528cat \/proc\/devices\u53ef\u4ee5\u67e5\u770b\u7533\u8bf7\u5230\u7684\u8bbe\u5907\u540d\u3001\u8bbe\u5907\u53f7\uff0c\u8fd9\u91cc\u8d34\u51fa\u90e8\u5206\u4ee3\u7801\uff1a <\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>\/\/\u521b\u5efa\u4e00\u4e2a\u5b57\u7b26\u8bbe\u5907\nstruct char_dev\n{\n    struct cdev c_dev;\n    dev_t dev_no;\n    char buf[1024];\n};\nstruct char_dev *my_dev;\nstatic int __init cdev_test_init(void)\n{  \n    int ret;\n    \/\/\u521b\u5efa\u8bbe\u5907\u53f7->\u4e3b\u8bbe\u5907\u53f7\uff0c\u6b21\u8bbe\u5907\u53f7\n    \/\/dev_no = MKDEV(222,2);\n    \/\/\u6ce8\u518c\u8bbe\u5907\u53f7\n    \/\/ret = register_chrdev_region(dev_no,1,\"my_dev\");\n    \/\/1.\u7ed9\u5b57\u7b26\u8bbe\u5907\u5206\u914d\u5185\u5b58\u7a7a\u95f4\n    my_dev = kmalloc(sizeof(*my_dev),GFP_KERNEL);\n    \/\/2.\u81ea\u52a8\u7533\u8bf7\u8bbe\u5907\u53f7\u5e76\u6ce8\u518c\u5b57\u7b26\u8bbe\u5907\n    ret = alloc_chrdev_region(&amp;my_dev->dev_no,1,1,\"my_dev\");\n    \/\/3.\u521d\u59cb\u5316\u5b57\u7b26\u8bbe\u5907\n    cdev_init(&amp;my_dev->c_dev, &amp;my_ops);\n    \/\/4.\u6dfb\u52a0\u4e00\u4e2a\u5b57\u7b26\u8bbe\u5907\n    ret = cdev_add(&amp;my_dev->c_dev, my_dev->dev_no, 1);\n    return 0;\n}<\/code><\/pre>\n\n\n\n<h3 class=\"wp-block-heading\">\u81ea\u52a8\u521b\u5efa\u8bbe\u5907\u8282\u70b9<\/h3>\n\n\n\n<p> \u5229\u7528<strong>udev\uff08mdev\uff09<\/strong>\u6765\u5b9e\u73b0\u8bbe\u5907\u6587\u4ef6\u7684\u81ea\u52a8\u521b\u5efa\uff0c\u9996\u5148\u5e94\u4fdd\u8bc1\u652f\u6301udev\uff08mdev\uff09\uff0c\u7531busybox\u914d\u7f6e<br> \u5728\u9a71\u52a8\u7528\u52a0\u5165\u5bf9udev \u7684\u652f\u6301\u4e3b\u8981\u505a\u7684\u5c31\u662f\uff1a\u5728\u9a71\u52a8\u521d\u59cb\u5316\u7684\u4ee3\u7801\u91cc\u8c03\u7528class_create(&#8230;)\u4e3a\u8be5\u8bbe\u5907\u521b\u5efa\u4e00\u4e2aclass\uff0c\u518d\u4e3a\u6bcf\u4e2a\u8bbe\u5907\u8c03\u7528device_create(&#8230;)\u521b\u5efa\u5bf9\u5e94\u7684\u8bbe\u5907<br> \u5185\u6838\u4e2d\u5b9a\u4e49\u7684struct class\u7ed3\u6784\u4f53\uff0c\u987e\u540d\u601d\u4e49\uff0c\u4e00\u4e2astruct class\u7ed3\u6784\u4f53\u7c7b\u578b\u53d8\u91cf\u5bf9\u5e94\u4e00\u4e2a\u7c7b\uff0c\u5185\u6838\u540c\u65f6\u63d0\u4f9b\u4e86class_create(\u2026)\u51fd\u6570\uff0c\u53ef\u4ee5\u7528\u5b83\u6765\u521b\u5efa\u4e00\u4e2a\u7c7b\uff0c\u8fd9\u4e2a\u7c7b\u5b58\u653e\u4e8esysfs\u4e0b\u9762\uff0c\u4e00\u65e6\u521b\u5efa\u597d\u4e86\u8fd9\u4e2a\u7c7b\uff0c\u518d\u8c03\u7528 device_create(\u2026)\u51fd\u6570\u6765\u5728\/dev\u76ee\u5f55\u4e0b\u521b\u5efa\u76f8\u5e94\u7684\u8bbe\u5907\u8282\u70b9<br> \u8fd9\u6837\uff0c\u52a0\u8f7d\u6a21\u5757\u7684\u65f6\u5019\uff0c\u7528\u6237\u7a7a\u95f4\u4e2d\u7684udev\u4f1a\u81ea\u52a8\u54cd\u5e94 device_create()\u51fd\u6570\uff0c\u53bb\/sysfs\u4e0b\u5bfb\u627e\u5bf9\u5e94\u7684\u7c7b\u4ece\u800c\u521b\u5efa\u8bbe\u5907\u8282\u70b9<\/p>\n\n\n\n<p> \u8fd9\u91cc\u8d34\u51fa\u90e8\u5206\u5b9e\u73b0\u4ee3\u7801\uff1a <\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>struct device *my_device;\n    \n    ......\n    \/\/5.\u4e3a\u8be5\u8bbe\u5907\u521b\u5efa\u4e00\u4e2aclass\n    \/\/\u8fd9\u4e2a\u7c7b\u5b58\u653e\u4e8esysfs\u4e0b\u9762\uff0c\u8c03\u7528device_create\u51fd\u6570\u65f6\u4f1a\u5728\/dev\u76ee\u5f55\u521b\u5efa\u76f8\u5e94\u7684\u8bbe\u5907\u8282\u70b9\n    cls = class_create(THIS_MODULE, \"myclass\");\/\/sys\/devices\/virtual\/myclass\/my_dev\n    if(IS_ERR(cls))\n    {\n        unregister_chrdev_region(my_dev->dev_no,1);\n        return -EBUSY;\n    }\n    \/\/6.\u521b\u5efa\u5bf9\u5e94\u7684\u8bbe\u5907\u8282\u70b9\n    \/\/\u52a0\u8f7d\u6a21\u5757\u65f6\uff0c\u7528\u6237\u7a7a\u95f4\u7684udev\u4f1a\u81ea\u52a8\u54cd\u5e94\u8be5\u51fd\u6570\uff0c\u53bb\/sysfs\u4e0b\u5bfb\u627e\u5bf9\u5e94\u7684\u7c7b\u521b\u5efa\u8bbe\u5907\u8282\u70b9\n    my_device = device_create(cls,NULL,my_dev->dev_no,NULL,\"my_dev\");\/\/mknod \/dev\/my_dev\n    if(IS_ERR(my_device))\n    {\n        class_destroy(cls);\n        unregister_chrdev_region(my_dev->dev_no,1);\n        return -EBUSY;\n    }<\/code><\/pre>\n\n\n\n<p> \u5b9e\u73b0\u6548\u679c\u5982\u4e0b\u56fe\uff1a <\/p>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter\"><img loading=\"lazy\" decoding=\"async\" width=\"681\" height=\"146\" src=\"http:\/\/iqotom.com\/wp-content\/uploads\/2019\/09\/linux-cdev-drive-01.png\" alt=\"\" class=\"wp-image-541\" srcset=\"http:\/\/iqotom.com\/wp-content\/uploads\/2019\/09\/linux-cdev-drive-01.png 681w, http:\/\/iqotom.com\/wp-content\/uploads\/2019\/09\/linux-cdev-drive-01-300x64.png 300w\" sizes=\"(max-width: 681px) 100vw, 681px\" \/><\/figure><\/div>\n\n\n\n<h3 class=\"wp-block-heading\">\u4e3a\u9a71\u52a8\u6dfb\u52a0open()\u3001read()\u3001write()\u3001ioctl()\u51fd\u6570<\/h3>\n\n\n\n<p> \u5f53\u4e00\u4e2a\u5b57\u7b26\u8bbe\u5907\u88ab\u6ce8\u518c\u540e\uff0c\u6211\u4eec\u968f\u5373\u5c31\u8981\u6765\u64cd\u4f5c\u8fd9\u4e2a\u5b57\u7b26\u8bbe\u5907\uff0copen  , read , write , close\u7b49\u64cd\u4f5c\uff0c\u9700\u8981file_operations\u8fd9\u4e2a\u7ed3\u6784\u4f53\uff1a <\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>static const struct file_operations __fops = {\t\t\t\t\\\n\t.owner\t = THIS_MODULE,\t\t\t\t\t\t\\\n\t.open\t = __fops ## _open,\t\t\t\t\t\\\n\t.release = simple_attr_release,\t\t\t\t\t\\\n\t.read\t = simple_attr_read,\t\t\t\t\t\\\n\t.write\t = simple_attr_write,\t\t\t\t\t\\\n\t.llseek\t = generic_file_llseek,\t\t\t\t\t\\\n}\n\nstruct file_operations {\n\tstruct module *owner;\n\tloff_t (*llseek) (struct file *, loff_t, int);\n\tssize_t (*read) (struct file *, char __user *, size_t, loff_t *);\n\tssize_t (*write) (struct file *, const char __user *, size_t, loff_t *);\n\tssize_t (*read_iter) (struct kiocb *, struct iov_iter *);\n\tssize_t (*write_iter) (struct kiocb *, struct iov_iter *);\n\tint (*iterate) (struct file *, struct dir_context *);\n\tint (*iterate_shared) (struct file *, struct dir_context *);\n\t__poll_t (*poll) (struct file *, struct poll_table_struct *);\n\tlong (*unlocked_ioctl) (struct file *, unsigned int, unsigned long);\n\tlong (*compat_ioctl) (struct file *, unsigned int, unsigned long);\n\tint (*mmap) (struct file *, struct vm_area_struct *);\n\t......<\/code><\/pre>\n\n\n\n<p> \u90a3\u4e48\u5185\u6838\u662f\u5982\u4f55\u53bb\u8bc6\u522b\u76f8\u5e94\u7684\u51fd\u6570\u5462\uff1f <br> \u662f\u901a\u8fc7\u7cfb\u7edf\u8c03\u7528 , \u5728\u4e0a\u5c42\u5e94\u7528\u7a0b\u5e8f\uff0c\u6253\u4e2a\u6bd4\u65b9 .<br> \u901a\u8fc7open()\u6253\u5370\u76f8\u5e94\u7684\u8bbe\u5907\uff0c\u90a3\u4e48syscall\u51fd\u6570\u5c31\u4f1a\u901a\u8fc7\u7cfb\u7edf\u8c03\u7528\u53f7\u8bc6\u522b\u5230\u5185\u6838\u6001\u91cc\u7684\u51fd\u6570\uff0c\u8fdb\u800c\u8c03\u7528\u5230\u6211\u4eec\u8fd9\u91cc\u5b9e\u73b0\u7684my_open,\u8fd9\u5c31\u662f\u5185\u6838\u6001\u548c\u7528\u6237\u6001\u76f8\u4e92\u6c9f\u901a\u7684\u65b9\u5f0f <\/p>\n\n\n\n<p> \u90e8\u5206\u4ee3\u7801\uff1a <\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>\/\/\u521b\u5efa\u51fd\u6570\uff0c\u8fd9\u91cc\u5c31\u4e0d\u5199\u51fa\u5177\u4f53\u5b9e\u73b0\u4e86\nint my_open(struct inode *inode, struct file *file){...}\nint my_close(struct inode *inode, struct file *file){...}\nssize_t my_read(struct file *file,char __user *buf,size_t len,loff_t *pos){...}\nssize_t my_write(struct file *file,const char __user *buf,size_t len,loff_t *pos){...}\nlong my_ioctl(struct file *file,unsigned int cmd,unsigned long arg){...}\nstruct file_operations my_ops = {\n    .open = my_open,\n    .read = my_read,\n    .write = my_write,\n    .unlocked_ioctl = my_ioctl,\n    .release = my_close,\n};\n\/\/\u521d\u59cb\u5316ops\ncdev_init(&amp;my_dev->c_dev, &amp;my_ops);<\/code><\/pre>\n\n\n\n<p> \u6700\u7ec8\u6548\u679c\u56fe :<\/p>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter\"><img loading=\"lazy\" decoding=\"async\" width=\"729\" height=\"363\" src=\"http:\/\/iqotom.com\/wp-content\/uploads\/2019\/09\/linux-cdev-drive-02.png\" alt=\"\" class=\"wp-image-542\" srcset=\"http:\/\/iqotom.com\/wp-content\/uploads\/2019\/09\/linux-cdev-drive-02.png 729w, http:\/\/iqotom.com\/wp-content\/uploads\/2019\/09\/linux-cdev-drive-02-300x149.png 300w\" sizes=\"(max-width: 729px) 100vw, 729px\" \/><\/figure><\/div>\n\n\n\n<p>Linux\u5b57\u7b26\u8bbe\u5907\u9a71\u52a8\u5b8c\u6210\uff01 <\/p>\n\n\n\n<p>\u9879\u76ee\u6e90\u7801\u5730\u5740\uff1a<a href=\"https:\/\/github.com\/huchanghui123\/my_cdev\">https:\/\/github.com\/huchanghui123\/my_cdev<\/a><\/p>\n\n\n\n<p> \u53c2\u8003\u94fe\u63a5\uff1a <br> <a href=\"https:\/\/blog.csdn.net\/zqixiao_09\/article\/details\/50839042\">https:\/\/blog.csdn.net\/zqixiao_09\/article\/details\/50839042<\/a> <br> <a href=\"https:\/\/blog.csdn.net\/morixinguan\/article\/details\/55002774\">https:\/\/blog.csdn.net\/morixinguan\/article\/details\/55002774<\/a> <\/p>\n","protected":false},"excerpt":{"rendered":"<p>Linux\u9a71\u52a8 \u5b9e\u73b0\u4e00\u4e2a\u5b57\u7b26\u8bbe\u5907\u9a71\u52a8\uff0c\u5f00\u53d1\u73af\u5883Ubuntu18.04 LTS\uff0c\u9644\u5b8c\u6574\u4ee3\u7801\u3002<\/p>\n","protected":false},"author":1,"featured_media":550,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[48,5,49],"tags":[51,50],"_links":{"self":[{"href":"http:\/\/iqotom.com\/index.php?rest_route=\/wp\/v2\/posts\/539"}],"collection":[{"href":"http:\/\/iqotom.com\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"http:\/\/iqotom.com\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"http:\/\/iqotom.com\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"http:\/\/iqotom.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=539"}],"version-history":[{"count":5,"href":"http:\/\/iqotom.com\/index.php?rest_route=\/wp\/v2\/posts\/539\/revisions"}],"predecessor-version":[{"id":902,"href":"http:\/\/iqotom.com\/index.php?rest_route=\/wp\/v2\/posts\/539\/revisions\/902"}],"wp:featuredmedia":[{"embeddable":true,"href":"http:\/\/iqotom.com\/index.php?rest_route=\/wp\/v2\/media\/550"}],"wp:attachment":[{"href":"http:\/\/iqotom.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=539"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"http:\/\/iqotom.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=539"},{"taxonomy":"post_tag","embeddable":true,"href":"http:\/\/iqotom.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=539"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}