{"id":7710,"date":"2022-02-22T08:58:37","date_gmt":"2022-02-22T08:58:37","guid":{"rendered":"http:\/\/fastbitlab.com\/?p=7710"},"modified":"2023-09-14T12:11:24","modified_gmt":"2023-09-14T06:41:24","slug":"character-driver-file-operation-methods-contd","status":"publish","type":"post","link":"https:\/\/fastbitlab.com\/blog\/character-driver-file-operation-methods-contd\/","title":{"rendered":"Linux Device Driver Programming Lecture 34- Character driver file operation methods contd."},"content":{"rendered":"<div class=\"boldgrid-section\" style=\"background-image: linear-gradient(to left, #eeeeee, #eeeeee);\" data-bg-color-1=\"#EEEEEE\" data-bg-color-2=\"#EEEEEE\" data-bg-direction=\"to left\">\n<div class=\"container\">\n<div class=\"row\" style=\"padding-top: 35px; padding-bottom: 0px; background-image: linear-gradient(to left, #eeeeee, #eeeeee);\" data-bg-color-1=\"#EEEEEE\" data-bg-color-2=\"#EEEEEE\" data-bg-direction=\"to left\">\n<div class=\"col-md-1 col-sm-12 col-xs-12 col-lg-1\">\n<p>&nbsp;<\/p>\n<\/div>\n<div class=\"col-md-10 col-sm-12 col-xs-12 col-lg-10\">\n<h1 class=\"\" style=\"text-align: center; font-size: 30px; border-width: 0px; line-height: 49px;\"><span style=\"font-weight: 400; color: #000080;\"><b>Character driver file operation methods contd.<\/b><\/span><\/h1>\n<div class=\"row bg-editor-hr-wrap\" style=\"border-width: 0px; margin-top: -25px;\">\n<div class=\"col-lg-12 col-md-12 col-xs-12 col-sm-12\">\n<div>\n<p>&nbsp;<\/p>\n<div class=\"bg-hr bg-hr-10 color2-color\" style=\"border-style: solid; border-width: 0px 0px 3px;\"><\/div>\n<p>&nbsp;<\/p>\n<\/div>\n<\/div>\n<\/div>\n<p class=\"\" style=\"border-width: 0px; font-family: 'Roboto Slab'; font-weight: 400; font-size: 17px; line-height: 30px;\" data-font-family=\"Roboto Slab\" data-font-weight=\"400\" data-font-style=\"\"><span style=\"font-weight: 400; color: #000000;\">In the previous article, we came to know about how VFS and it&#8217;s various data structures are involved in a file operation.<\/span><\/p>\n<p class=\"\" style=\"font-size: 20px; line-height: 30px;\" data-font-family=\"Roboto Slab\" data-font-weight=\"400\" data-font-style=\"\"><span style=\"text-decoration: underline; color: #000080;\"><strong>Open Method<\/strong>:<\/span><\/p>\n<p class=\"\" style=\"border-width: 0px; font-family: 'Roboto Slab'; font-weight: 400; font-size: 17px; line-height: 30px;\" data-font-family=\"Roboto Slab\" data-font-weight=\"400\" data-font-style=\"\"><span style=\"font-weight: 400; color: #000000;\"> Whenever the user-level program executes a open system call, the open method( as shown in Figure 1) of your driver will get called, so the VFS passes these two information. <\/span><\/p>\n<p class=\"\" style=\"border-width: 0px; font-family: 'Roboto Slab'; font-weight: 400; font-size: 17px; line-height: 30px;\" data-font-family=\"Roboto Slab\" data-font-weight=\"400\" data-font-style=\"\"><span style=\"font-weight: 400; color: #000000;\">One is pointer of a inode associated with file name or device file, and the second one is pointer of file object. Why the VFS passes pointer to the inode? There is a reason for it.<\/span><\/p>\n<figure id=\"attachment_7713\" aria-describedby=\"caption-attachment-7713\" style=\"width: 765px\" class=\"wp-caption aligncenter\"><img fetchpriority=\"high\" decoding=\"async\" class=\"size-full wp-image-7713\" src=\"http:\/\/fastbitlab.com\/wp-content\/uploads\/2022\/02\/Figure-1-28.png\" alt=\"Figure 1. Open method\" width=\"765\" height=\"339\" srcset=\"https:\/\/fastbitlab.com\/blog\/wp-content\/uploads\/2022\/02\/Figure-1-28.png 765w, https:\/\/fastbitlab.com\/blog\/wp-content\/uploads\/2022\/02\/Figure-1-28-300x133.png 300w, https:\/\/fastbitlab.com\/blog\/wp-content\/uploads\/2022\/02\/Figure-1-28-600x266.png 600w, https:\/\/fastbitlab.com\/blog\/wp-content\/uploads\/2022\/02\/Figure-1-28-120x53.png 120w, https:\/\/fastbitlab.com\/blog\/wp-content\/uploads\/2022\/02\/Figure-1-28-500x222.png 500w, https:\/\/fastbitlab.com\/blog\/wp-content\/uploads\/2022\/02\/Figure-1-28-200x89.png 200w, https:\/\/fastbitlab.com\/blog\/wp-content\/uploads\/2022\/02\/Figure-1-28-400x177.png 400w\" sizes=\"(max-width: 765px) 100vw, 765px\" \/><figcaption id=\"caption-attachment-7713\" class=\"wp-caption-text\"><span style=\"color: #000000;\">Figure 1. Open method<\/span><\/figcaption><\/figure>\n<p data-font-family=\"Roboto Slab\" data-font-weight=\"400\" data-font-style=\"\">&nbsp;<\/p>\n<p class=\"\" style=\"border-width: 0px; font-family: 'Roboto Slab'; font-weight: 400; font-size: 17px; line-height: 30px;\" data-font-family=\"Roboto Slab\" data-font-weight=\"400\" data-font-style=\"\"><span style=\"font-weight: 400; color: #000000;\">But this should be the prototype of your open method in your character driver. We will use the name pcd_open, and this must be the prototype. And this method should return 0 if open is successful. That is, if your device open is successful. And any negative error code if open fails.<\/span><\/p>\n<p class=\"\">&nbsp;<\/p>\n<p class=\"\" style=\"border-width: 0px; font-family: 'Roboto Slab'; font-weight: 400; font-size: 20px; line-height: 30px;\" data-font-family=\"Roboto Slab\" data-font-weight=\"400\" data-font-style=\"\"><span style=\"color: #ff0000;\"><b>What do you do inside the open method?<\/b><span style=\"font-weight: 400;\">&nbsp;<\/span><\/span><\/p>\n<p class=\"\" style=\"border-width: 0px; font-family: 'Roboto Slab'; font-weight: 400; font-size: 17px; line-height: 30px;\" data-font-family=\"Roboto Slab\" data-font-weight=\"400\" data-font-style=\"\"><span style=\"font-weight: 400; color: #000000;\">In your driver&#8217;s open method, you can initialize the device or make the device respond to subsequent system calls such as read-write. Or you can bring the device back to the active mode from the low power mode. Sometimes you need not to do anything in the open method, so you can keep it blank, or you need not to implement the open method at all. If you don&#8217;t implement the open method, then the open call will always be successful. Apart from that, we can detect device initialization errors.<\/span><\/p>\n<p class=\"\" style=\"border-width: 0px; font-family: 'Roboto Slab'; font-weight: 400; font-size: 17px; line-height: 30px;\" data-font-family=\"Roboto Slab\" data-font-weight=\"400\" data-font-style=\"\"><span style=\"font-weight: 400; color: #000000;\">Let&#8217;s say you try to do some device initialization, and if the device doesn&#8217;t respond, then you can return a negative error code saying open failed. You can check open permission. So, user should give some permission to open a device. The device could be read-only(RDONLY), or the device could be write-only(WRONLY), or the device could be read and write(RDWR). If device is read-only, that means there is a device from which you can only read, and if user opens your device file with read\/write permission, then your open method can check the permission, and it can return a negative error code saying a write is not possible.<\/span><\/p>\n<p class=\"\" style=\"border-width: 0px; font-family: 'Roboto Slab'; font-weight: 400; font-size: 17px; line-height: 30px;\" data-font-family=\"Roboto Slab\" data-font-weight=\"400\" data-font-style=\"\"><span style=\"font-weight: 400; color: #000000;\">And you can identify the device being opened using minor number. This may be required when you have more than one minor numbers or more than one device files. Prepare device private data structure if required, and if required, you may also have to update the file position. I will&nbsp; discuss more on this later. As I said, open method is optional actually. If not provided, open will always succeed, and your driver is not notified.<\/span><\/p>\n<p class=\"\">&nbsp;<\/p>\n<p class=\"\" style=\"font-size: 20px; line-height: 30px; font-family: 'Roboto Slab'; font-weight: 400;\" data-font-family=\"Roboto Slab\" data-font-weight=\"400\" data-font-style=\"\"><span style=\"color: #000080;\"><strong><span style=\"text-decoration: underline;\">Close system call<\/span><\/strong><\/span><\/p>\n<p class=\"\" style=\"border-width: 0px; font-family: 'Roboto Slab'; font-weight: 400; font-size: 17px; line-height: 30px;\" data-font-family=\"Roboto Slab\" data-font-weight=\"400\" data-font-style=\"\"><span style=\"color: #000000;\"><span style=\"font-weight: 400;\">Let&#8217;s discuss close system call. Generally, user program uses the close something&nbsp;<\/span><span style=\"font-weight: 400;\">like this. Close using the file descriptor.<\/span><\/span><\/p>\n<figure id=\"attachment_7714\" aria-describedby=\"caption-attachment-7714\" style=\"width: 786px\" class=\"wp-caption aligncenter\"><img decoding=\"async\" class=\"size-full wp-image-7714\" src=\"http:\/\/fastbitlab.com\/wp-content\/uploads\/2022\/02\/Figure-2-29.png\" alt=\"Figure 2. Close system call\" width=\"786\" height=\"388\" srcset=\"https:\/\/fastbitlab.com\/blog\/wp-content\/uploads\/2022\/02\/Figure-2-29.png 786w, https:\/\/fastbitlab.com\/blog\/wp-content\/uploads\/2022\/02\/Figure-2-29-300x148.png 300w, https:\/\/fastbitlab.com\/blog\/wp-content\/uploads\/2022\/02\/Figure-2-29-768x379.png 768w, https:\/\/fastbitlab.com\/blog\/wp-content\/uploads\/2022\/02\/Figure-2-29-600x296.png 600w, https:\/\/fastbitlab.com\/blog\/wp-content\/uploads\/2022\/02\/Figure-2-29-120x59.png 120w, https:\/\/fastbitlab.com\/blog\/wp-content\/uploads\/2022\/02\/Figure-2-29-500x247.png 500w, https:\/\/fastbitlab.com\/blog\/wp-content\/uploads\/2022\/02\/Figure-2-29-200x99.png 200w, https:\/\/fastbitlab.com\/blog\/wp-content\/uploads\/2022\/02\/Figure-2-29-400x197.png 400w\" sizes=\"(max-width: 786px) 100vw, 786px\" \/><figcaption id=\"caption-attachment-7714\" class=\"wp-caption-text\"><span style=\"color: #000000;\">Figure 2. Close system call<\/span><\/figcaption><\/figure>\n<p data-font-family=\"Roboto Slab\" data-font-weight=\"400\" data-font-style=\"\">&nbsp;<\/p>\n<p class=\"\" style=\"border-width: 0px; font-family: 'Roboto Slab'; font-weight: 400; font-size: 17px; line-height: 30px;\" data-font-family=\"Roboto Slab\" data-font-weight=\"400\" data-font-style=\"\"><span style=\"font-weight: 400; color: #000000;\">Basically, what it says is,&nbsp; release the file descriptor. When close is issued, the VFS releases the file object. And the release method is called when the last reference to an open file is closed. That is when the f_count field of the file object becomes 0. Whenever a close is issued on the fd, that may not trigger the release method immediately. The release method is triggered only when all the references to an open file is closed. The VFS tracks this by using f_count field of the file object. So, whenever close is issued, the f_count field of the file object decrements.<\/span><\/p>\n<p class=\"\">&nbsp;<\/p>\n<p class=\"\" style=\"border-width: 0px; font-family: 'Roboto Slab'; font-weight: 400; font-size: 17px; line-height: 30px;\" data-font-family=\"Roboto Slab\" data-font-weight=\"400\" data-font-style=\"\"><span style=\"font-weight: 400; color: #000000;\">When that reaches to 0, then only the release method, as shown in Figure 3 gets called in your driver. That&#8217;s a reason why we call it as a release method, not close method. The VFS calls this driver method when all the references to an open file is closed, and the file object data structure is released from the memory. And the prototype is similar to the open method, it passes 2 arguments here. Pointer of Inode associated with the device file and pointer of file object. And we will be using this name pcd_release&nbsp; in our character driver file.<\/span><\/p>\n<p class=\"\" style=\"font-size: 20px; line-height: 30px; font-family: 'Roboto Slab'; font-weight: 400;\" data-font-family=\"Roboto Slab\" data-font-weight=\"400\" data-font-style=\"\"><span style=\"text-decoration: underline; color: #000080;\"><strong>Release Method<\/strong>:<\/span><\/p>\n<figure id=\"attachment_7715\" aria-describedby=\"caption-attachment-7715\" style=\"width: 702px\" class=\"wp-caption aligncenter\"><img decoding=\"async\" class=\" wp-image-7715\" src=\"http:\/\/fastbitlab.com\/wp-content\/uploads\/2022\/02\/Figure-3-26.png\" alt=\"Figure 3. Release method\" width=\"702\" height=\"211\" srcset=\"https:\/\/fastbitlab.com\/blog\/wp-content\/uploads\/2022\/02\/Figure-3-26.png 812w, https:\/\/fastbitlab.com\/blog\/wp-content\/uploads\/2022\/02\/Figure-3-26-300x90.png 300w, https:\/\/fastbitlab.com\/blog\/wp-content\/uploads\/2022\/02\/Figure-3-26-768x231.png 768w, https:\/\/fastbitlab.com\/blog\/wp-content\/uploads\/2022\/02\/Figure-3-26-600x180.png 600w, https:\/\/fastbitlab.com\/blog\/wp-content\/uploads\/2022\/02\/Figure-3-26-120x36.png 120w, https:\/\/fastbitlab.com\/blog\/wp-content\/uploads\/2022\/02\/Figure-3-26-500x150.png 500w, https:\/\/fastbitlab.com\/blog\/wp-content\/uploads\/2022\/02\/Figure-3-26-200x60.png 200w, https:\/\/fastbitlab.com\/blog\/wp-content\/uploads\/2022\/02\/Figure-3-26-400x120.png 400w, https:\/\/fastbitlab.com\/blog\/wp-content\/uploads\/2022\/02\/Figure-3-26-800x240.png 800w\" sizes=\"(max-width: 702px) 100vw, 702px\" \/><figcaption id=\"caption-attachment-7715\" class=\"wp-caption-text\"><span style=\"color: #000000;\">Figure 3. Release method<\/span><\/figcaption><\/figure>\n<p class=\"\" data-font-family=\"Roboto Slab\" data-font-weight=\"400\" data-font-style=\"\">&nbsp;<\/p>\n<p class=\"\" style=\"border-width: 0px; font-family: 'Roboto Slab'; font-weight: 400; font-size: 17px; line-height: 30px;\" data-font-family=\"Roboto Slab\" data-font-weight=\"400\" data-font-style=\"\"><span style=\"font-weight: 400; color: #000000;\">Let&#8217;s see what we do inside the release method of the driver. In the release method, the driver can do reverse operation of what open had done.<\/span><\/p>\n<p class=\"\" style=\"border-width: 0px; font-family: 'Roboto Slab'; font-weight: 400; font-size: 17px; line-height: 30px;\" data-font-family=\"Roboto Slab\" data-font-weight=\"400\" data-font-style=\"\"><span style=\"font-weight: 400; color: #000000;\">For example, if the open method brings the device out of low power mode, then a release method may send the device back to the low power mode.<\/span><\/p>\n<p class=\"\" style=\"border-width: 0px; font-family: 'Roboto Slab'; font-weight: 400; font-size: 17px; line-height: 30px;\" data-font-family=\"Roboto Slab\" data-font-weight=\"400\" data-font-style=\"\"><span style=\"font-weight: 400; color: #000000;\">Basically, you should leave the device in its default state, the state which was before the open call. You can also free any data structures allocated by the open method. Basically, the release method returns 0 on success or negative error code if there is any errors.<\/span><\/p>\n<p class=\"\" style=\"border-width: 0px; font-family: 'Roboto Slab'; font-weight: 400; font-size: 17px; line-height: 32px;\" data-font-family=\"Roboto Slab\" data-font-weight=\"400\" data-font-style=\"\"><span style=\"font-weight: 400; color: #000000;\">For example, you try to de-initialize the device and the device it doesn&#8217;t respond, then you can return timeout, or IO error, something like that.<\/span><\/p>\n<p class=\"\">&nbsp;<\/p>\n<p class=\"\" style=\"font-size: 20px; line-height: 30px; font-family: 'Roboto Slab'; font-weight: 400;\" data-font-family=\"Roboto Slab\" data-font-weight=\"400\" data-font-style=\"\"><span style=\"text-decoration: underline; color: #000080;\"><strong>Read Method<\/strong>:<\/span><\/p>\n<p class=\"\" style=\"border-width: 0px; font-family: 'Roboto Slab'; font-weight: 400; font-size: 17px; line-height: 30px;\" data-font-family=\"Roboto Slab\" data-font-weight=\"400\" data-font-style=\"\"><span style=\"font-weight: 400; color: #000000;\">Let&#8217;s explore the read system call as shown in Figure 4. This is how read is issued from the user-level program.<\/span><\/p>\n<figure id=\"attachment_7716\" aria-describedby=\"caption-attachment-7716\" style=\"width: 723px\" class=\"wp-caption aligncenter\"><img loading=\"lazy\" decoding=\"async\" class=\" wp-image-7716\" src=\"http:\/\/fastbitlab.com\/wp-content\/uploads\/2022\/02\/Figure-4-22.png\" alt=\"Figure 4. Read system call\" width=\"723\" height=\"354\" srcset=\"https:\/\/fastbitlab.com\/blog\/wp-content\/uploads\/2022\/02\/Figure-4-22.png 850w, https:\/\/fastbitlab.com\/blog\/wp-content\/uploads\/2022\/02\/Figure-4-22-300x147.png 300w, https:\/\/fastbitlab.com\/blog\/wp-content\/uploads\/2022\/02\/Figure-4-22-768x376.png 768w, https:\/\/fastbitlab.com\/blog\/wp-content\/uploads\/2022\/02\/Figure-4-22-600x294.png 600w, https:\/\/fastbitlab.com\/blog\/wp-content\/uploads\/2022\/02\/Figure-4-22-120x59.png 120w, https:\/\/fastbitlab.com\/blog\/wp-content\/uploads\/2022\/02\/Figure-4-22-500x245.png 500w, https:\/\/fastbitlab.com\/blog\/wp-content\/uploads\/2022\/02\/Figure-4-22-200x98.png 200w, https:\/\/fastbitlab.com\/blog\/wp-content\/uploads\/2022\/02\/Figure-4-22-400x196.png 400w, https:\/\/fastbitlab.com\/blog\/wp-content\/uploads\/2022\/02\/Figure-4-22-800x392.png 800w\" sizes=\"(max-width: 723px) 100vw, 723px\" \/><figcaption id=\"caption-attachment-7716\" class=\"wp-caption-text\"><span style=\"color: #000000;\">Figure 4. Read system call<\/span><\/figcaption><\/figure>\n<p class=\"\" data-font-family=\"Roboto Slab\" data-font-weight=\"400\" data-font-style=\"\">&nbsp;<\/p>\n<p class=\"\" style=\"border-width: 0px; font-family: 'Roboto Slab'; font-weight: 400; font-size: 17px; line-height: 30px;\" data-font-family=\"Roboto Slab\" data-font-weight=\"400\" data-font-style=\"\"><span style=\"font-weight: 400; color: #000000;\">It uses three arguments here. The file descriptor, the user buffer, and the number of a bytes to be read. And to handle this read system call, we will be implementing pcd_read in our character driver.&nbsp;<\/span><\/p>\n<p class=\"\">&nbsp;<\/p>\n<p class=\"\" style=\"border-width: 0px; font-family: 'Roboto Slab'; font-weight: 400; font-size: 17px; line-height: 30px;\" data-font-family=\"Roboto Slab\" data-font-weight=\"400\" data-font-style=\"\"><span style=\"font-weight: 400; color: #000000;\">And let&#8217;s look at the prototype of the read method as shown in Figure 5.&nbsp;<\/span><\/p>\n<figure id=\"attachment_7717\" aria-describedby=\"caption-attachment-7717\" style=\"width: 707px\" class=\"wp-caption aligncenter\"><img loading=\"lazy\" decoding=\"async\" class=\" wp-image-7717\" src=\"http:\/\/fastbitlab.com\/wp-content\/uploads\/2022\/02\/Figure-5-21.png\" alt=\"Figure 5. Prototype of read method\" width=\"707\" height=\"301\" srcset=\"https:\/\/fastbitlab.com\/blog\/wp-content\/uploads\/2022\/02\/Figure-5-21.png 824w, https:\/\/fastbitlab.com\/blog\/wp-content\/uploads\/2022\/02\/Figure-5-21-300x127.png 300w, https:\/\/fastbitlab.com\/blog\/wp-content\/uploads\/2022\/02\/Figure-5-21-768x326.png 768w, https:\/\/fastbitlab.com\/blog\/wp-content\/uploads\/2022\/02\/Figure-5-21-600x255.png 600w, https:\/\/fastbitlab.com\/blog\/wp-content\/uploads\/2022\/02\/Figure-5-21-120x51.png 120w, https:\/\/fastbitlab.com\/blog\/wp-content\/uploads\/2022\/02\/Figure-5-21-500x212.png 500w, https:\/\/fastbitlab.com\/blog\/wp-content\/uploads\/2022\/02\/Figure-5-21-200x85.png 200w, https:\/\/fastbitlab.com\/blog\/wp-content\/uploads\/2022\/02\/Figure-5-21-400x170.png 400w, https:\/\/fastbitlab.com\/blog\/wp-content\/uploads\/2022\/02\/Figure-5-21-800x340.png 800w\" sizes=\"(max-width: 707px) 100vw, 707px\" \/><figcaption id=\"caption-attachment-7717\" class=\"wp-caption-text\"><span style=\"color: #000000;\">Figure 5. Prototype of read method<\/span><\/figcaption><\/figure>\n<p data-font-family=\"Roboto Slab\" data-font-weight=\"400\" data-font-style=\"\">&nbsp;<\/p>\n<p class=\"\" style=\"border-width: 0px; font-family: 'Roboto Slab'; font-weight: 400; font-size: 17px; line-height: 30px;\" data-font-family=\"Roboto Slab\" data-font-weight=\"400\" data-font-style=\"\"><span style=\"font-weight: 400; color: #000000;\">The VFS passes all these information to our driver-read method. So, the first one is pointer of file object. And after that is a pointer to the user buffer, and this(size_t count) is a read count given by the user. And after that, loff_t *f_pos This(loff_t *f_pos) is actually pointer of current file position from which the read has to begin.<\/span><\/p>\n<p class=\"\" style=\"border-width: 0px; font-family: 'Roboto Slab'; font-weight: 400; font-size: 17px; line-height: 30px;\" data-font-family=\"Roboto Slab\" data-font-weight=\"400\" data-font-style=\"\"><span style=\"font-weight: 400; color: #000000;\">In read method as shown in Figure 6, what drivers should be doing is it should read a device file and return the data back to the user. That&#8217;s what read is, your driver should return the data back to the user. How many data bytes? So, count the number of data bytes. From which position in the device file, that is decided by this loff_t *f_pos field. Your driver code should read from this position onwards. This(size_t count) much amount of bytes and it should populate all that data bytes into this(char __user *buff) buffer given by the user. That&#8217;s all the driver needs to do.<\/span><\/p>\n<p class=\"\" style=\"border-width: 0px; font-family: 'Roboto Slab'; font-weight: 400; font-size: 17px; line-height: 30px;\" data-font-family=\"Roboto Slab\" data-font-weight=\"400\" data-font-style=\"\"><span style=\"font-weight: 400; color: #000000;\">And after that, there is a macro __user used with pointer of user buffer. What exactly is this macro? This is actually an optional macro which alerts the programmer that this is a user-level pointer. It cannot be trusted for direct dereferencing. That means, in your kernel-level programming, you should not trust this(*buff) pointer.&nbsp;<\/span><\/p>\n<p class=\"\" style=\"border-width: 0px; font-family: 'Roboto Slab'; font-weight: 400; font-size: 17px; line-height: 30px;\" data-font-family=\"Roboto Slab\" data-font-weight=\"400\" data-font-style=\"\"><span style=\"font-weight: 400; color: #000000;\">You should not be doing any direct dereferencing to avoid the kernel faults. __user is a macro used with user-level pointers, which tells the programmer not to trust or assume it as a valid pointer to avoid kernel faults. Never try to dereference user given pointers directly in kernel-level programming. Instead, use dedicated kernel functions such as copy_to_user and copy_from_ user. GCC doesn&#8217;t care whether you use __user macro with user-level pointer or not. So, the GCC won&#8217;t trigger any warnings for this. Doesn&#8217;t matter whether you use it or not.<\/span><\/p>\n<p class=\"\" style=\"border-width: 0px; font-family: 'Roboto Slab'; font-weight: 400; font-size: 17px; line-height: 30px;\" data-font-family=\"Roboto Slab\" data-font-weight=\"400\" data-font-style=\"\"><span style=\"color: #000000;\"><span style=\"font-weight: 400;\">This is actually checked by sparse, a semantic checker tool of linux kernel to find possible coding faults. That&#8217;s why, this is actually optional but it&#8217;s highly recommended to use this macro with user-level pointers. And what you should be doing in read method is, read &#8216;count&#8217; bytes from a device starting at position &#8216;f_pos.&#8217; <\/span><\/span><\/p>\n<p class=\"\" style=\"border-width: 0px; font-family: 'Roboto Slab'; font-weight: 400; font-size: 17px; line-height: 30px;\" data-font-family=\"Roboto Slab\" data-font-weight=\"400\" data-font-style=\"\"><span style=\"color: #000000;\"><span style=\"font-weight: 400;\">Update the position pointer by adding the number of bytes successfully read. Return number of bytes successfully read. Return 0 if there is no bytes to read. That is the situation of end of file. And after that, return appropriate error code&nbsp;<\/span><span style=\"font-weight: 400;\">if there is any error. A return value less than &#8216;count&#8217; does not mean that an error has occurred.<\/span><\/span><\/p>\n<p class=\"\" style=\"border-width: 0px; font-family: 'Roboto Slab'; font-weight: 400; font-size: 17px; line-height: 30px;\" data-font-family=\"Roboto Slab\" data-font-weight=\"400\" data-font-style=\"\"><span style=\"font-weight: 400; color: #000000;\">Basically, you should read the amount requested here( size_t count). But, if that amount is not available, then you can simply return a number of bytes which was successfully read. That&#8217;s why, a return value less than &#8216;count&#8217;&nbsp; does not mean that it&#8217;s an error.<\/span><\/p>\n<p class=\"\" data-font-family=\"Roboto Slab\" data-font-weight=\"400\" data-font-style=\"\">&nbsp;<\/p>\n<p class=\"\" style=\"font-size: 20px; line-height: 30px; font-family: 'Roboto Slab'; font-weight: 400;\" data-font-family=\"Roboto Slab\" data-font-weight=\"400\" data-font-style=\"\"><span style=\"text-decoration: underline; color: #000080;\"><strong>Write Method<\/strong>:<\/span><\/p>\n<p class=\"\" style=\"border-width: 0px; font-family: 'Roboto Slab'; font-weight: 400; font-size: 17px; line-height: 30px;\" data-font-family=\"Roboto Slab\" data-font-weight=\"400\" data-font-style=\"\"><span style=\"font-weight: 400; color: #000000;\">How about write? Again, write is a system call( as shown in Figure 6) used by the user level program to write some data into the device. Write system call gets connected to your driver&#8217;s write method, and let&#8217;s call our write method as pcd_write.<\/span><\/p>\n<figure id=\"attachment_7718\" aria-describedby=\"caption-attachment-7718\" style=\"width: 585px\" class=\"wp-caption aligncenter\"><img loading=\"lazy\" decoding=\"async\" class=\"wp-image-7718 size-full\" src=\"http:\/\/fastbitlab.com\/wp-content\/uploads\/2022\/02\/Figure-6-17.png\" alt=\"Character driver file operation methods contd\" width=\"585\" height=\"308\" srcset=\"https:\/\/fastbitlab.com\/blog\/wp-content\/uploads\/2022\/02\/Figure-6-17.png 585w, https:\/\/fastbitlab.com\/blog\/wp-content\/uploads\/2022\/02\/Figure-6-17-300x158.png 300w, https:\/\/fastbitlab.com\/blog\/wp-content\/uploads\/2022\/02\/Figure-6-17-120x63.png 120w, https:\/\/fastbitlab.com\/blog\/wp-content\/uploads\/2022\/02\/Figure-6-17-500x263.png 500w, https:\/\/fastbitlab.com\/blog\/wp-content\/uploads\/2022\/02\/Figure-6-17-200x105.png 200w, https:\/\/fastbitlab.com\/blog\/wp-content\/uploads\/2022\/02\/Figure-6-17-400x211.png 400w\" sizes=\"(max-width: 585px) 100vw, 585px\" \/><figcaption id=\"caption-attachment-7718\" class=\"wp-caption-text\"><span style=\"color: #000000;\">Figure 6. Write system call<\/span><\/figcaption><\/figure>\n<p class=\"\">&nbsp;<\/p>\n<p class=\"\" style=\"border-width: 0px; font-family: 'Roboto Slab'; font-weight: 400; font-size: 17px; line-height: 30px;\" data-font-family=\"Roboto Slab\" data-font-weight=\"400\" data-font-style=\"\"><span style=\"font-weight: 400; color: #000000;\">Let&#8217;s look at the prototype of pcd_write, as shown in Figure 7.<\/span><\/p>\n<figure id=\"attachment_7719\" aria-describedby=\"caption-attachment-7719\" style=\"width: 777px\" class=\"wp-caption aligncenter\"><img loading=\"lazy\" decoding=\"async\" class=\"wp-image-7719 size-full\" src=\"http:\/\/fastbitlab.com\/wp-content\/uploads\/2022\/02\/Figure-7-14.png\" alt=\"Character driver file operation methods contd\" width=\"777\" height=\"283\" srcset=\"https:\/\/fastbitlab.com\/blog\/wp-content\/uploads\/2022\/02\/Figure-7-14.png 777w, https:\/\/fastbitlab.com\/blog\/wp-content\/uploads\/2022\/02\/Figure-7-14-300x109.png 300w, https:\/\/fastbitlab.com\/blog\/wp-content\/uploads\/2022\/02\/Figure-7-14-768x280.png 768w, https:\/\/fastbitlab.com\/blog\/wp-content\/uploads\/2022\/02\/Figure-7-14-600x219.png 600w, https:\/\/fastbitlab.com\/blog\/wp-content\/uploads\/2022\/02\/Figure-7-14-120x44.png 120w, https:\/\/fastbitlab.com\/blog\/wp-content\/uploads\/2022\/02\/Figure-7-14-500x182.png 500w, https:\/\/fastbitlab.com\/blog\/wp-content\/uploads\/2022\/02\/Figure-7-14-200x73.png 200w, https:\/\/fastbitlab.com\/blog\/wp-content\/uploads\/2022\/02\/Figure-7-14-400x146.png 400w\" sizes=\"(max-width: 777px) 100vw, 777px\" \/><figcaption id=\"caption-attachment-7719\" class=\"wp-caption-text\"><span style=\"color: #000000;\">Figure 7. Write prototype<\/span><\/figcaption><\/figure>\n<p data-font-family=\"Roboto Slab\" data-font-weight=\"400\" data-font-style=\"\">&nbsp;<\/p>\n<p class=\"\" style=\"border-width: 0px; font-family: 'Roboto Slab'; font-weight: 400; font-size: 17px; line-height: 30px;\" data-font-family=\"Roboto Slab\" data-font-weight=\"400\" data-font-style=\"\"><span style=\"font-weight: 400; color: #000000;\">So, the input arguments are exactly same as read method. This(struct file *filp) is a pointer of file object, pointer of user buffer, and write count given by the user, and this is a current file position from which the write has to begin. In write method, you copy the data given by this(*buff) pointer into the device, that&#8217;s what write is.&nbsp; <\/span><\/p>\n<p class=\"\" style=\"border-width: 0px; font-family: 'Roboto Slab'; font-weight: 400; font-size: 17px; line-height: 30px;\" data-font-family=\"Roboto Slab\" data-font-weight=\"400\" data-font-style=\"\"><span style=\"font-weight: 400; color: #000000;\">In write method, what you do is, write &#8216;count&#8217; bytes into the device starting at position &#8216;f_pos&#8217;. And update the kernel file position by adding the number of bytes successfully written. Return number of bytes successfully written. Return appropriate error code if there is any error.<\/span><\/p>\n<p class=\"\">&nbsp;<\/p>\n<p class=\"\" style=\"font-size: 20px; line-height: 30px; font-family: 'Roboto Slab'; font-weight: 400;\" data-font-family=\"Roboto Slab\" data-font-weight=\"400\" data-font-style=\"\"><span style=\"text-decoration: underline; color: #000080;\"><strong>Llseek Method<\/strong>:<\/span><\/p>\n<p class=\"\" style=\"border-width: 0px; font-family: 'Roboto Slab'; font-weight: 400; font-size: 17px; line-height: 30px;\" data-font-family=\"Roboto Slab\" data-font-weight=\"400\" data-font-style=\"\"><span style=\"font-weight: 400; color: #000000;\">And after that, the last system call&nbsp; is llseek (as shown in Figure 8).<\/span><\/p>\n<figure id=\"attachment_7720\" aria-describedby=\"caption-attachment-7720\" style=\"width: 840px\" class=\"wp-caption aligncenter\"><img loading=\"lazy\" decoding=\"async\" class=\"wp-image-7720 size-full\" src=\"http:\/\/fastbitlab.com\/wp-content\/uploads\/2022\/02\/Figure-8-11.png\" alt=\"Character driver file operation methods contd\" width=\"840\" height=\"381\" srcset=\"https:\/\/fastbitlab.com\/blog\/wp-content\/uploads\/2022\/02\/Figure-8-11.png 840w, https:\/\/fastbitlab.com\/blog\/wp-content\/uploads\/2022\/02\/Figure-8-11-300x136.png 300w, https:\/\/fastbitlab.com\/blog\/wp-content\/uploads\/2022\/02\/Figure-8-11-768x348.png 768w, https:\/\/fastbitlab.com\/blog\/wp-content\/uploads\/2022\/02\/Figure-8-11-600x272.png 600w, https:\/\/fastbitlab.com\/blog\/wp-content\/uploads\/2022\/02\/Figure-8-11-120x54.png 120w, https:\/\/fastbitlab.com\/blog\/wp-content\/uploads\/2022\/02\/Figure-8-11-500x227.png 500w, https:\/\/fastbitlab.com\/blog\/wp-content\/uploads\/2022\/02\/Figure-8-11-200x91.png 200w, https:\/\/fastbitlab.com\/blog\/wp-content\/uploads\/2022\/02\/Figure-8-11-400x181.png 400w, https:\/\/fastbitlab.com\/blog\/wp-content\/uploads\/2022\/02\/Figure-8-11-800x363.png 800w\" sizes=\"(max-width: 840px) 100vw, 840px\" \/><figcaption id=\"caption-attachment-7720\" class=\"wp-caption-text\"><span style=\"color: #000000;\">Figure 8. Llseek method<\/span><\/figcaption><\/figure>\n<p>&nbsp;<\/p>\n<p class=\"\" style=\"border-width: 0px; font-family: 'Roboto Slab'; font-weight: 400; font-size: 17px; line-height: 30px;\" data-font-family=\"Roboto Slab\" data-font-weight=\"400\" data-font-style=\"\"><span style=\"font-weight: 400; color: #000000;\">Actually, llseek is used to alter the current file position. This has got nothing to do with a read or write of a device. This system call is used to alter the current file position. So, will come to know more about this a file position and all when we do a code exercise. And this(pcd_lseek) will be our driver method to handle lseek system call, and this is a prototype as shown in Figure 9.<\/span><\/p>\n<figure id=\"attachment_7721\" aria-describedby=\"caption-attachment-7721\" style=\"width: 730px\" class=\"wp-caption aligncenter\"><img loading=\"lazy\" decoding=\"async\" class=\"wp-image-7721 size-full\" src=\"http:\/\/fastbitlab.com\/wp-content\/uploads\/2022\/02\/Figure-9-9.png\" alt=\"Character driver file operation methods contd\" width=\"730\" height=\"351\" srcset=\"https:\/\/fastbitlab.com\/blog\/wp-content\/uploads\/2022\/02\/Figure-9-9.png 730w, https:\/\/fastbitlab.com\/blog\/wp-content\/uploads\/2022\/02\/Figure-9-9-300x144.png 300w, https:\/\/fastbitlab.com\/blog\/wp-content\/uploads\/2022\/02\/Figure-9-9-600x288.png 600w, https:\/\/fastbitlab.com\/blog\/wp-content\/uploads\/2022\/02\/Figure-9-9-120x58.png 120w, https:\/\/fastbitlab.com\/blog\/wp-content\/uploads\/2022\/02\/Figure-9-9-500x240.png 500w, https:\/\/fastbitlab.com\/blog\/wp-content\/uploads\/2022\/02\/Figure-9-9-200x96.png 200w, https:\/\/fastbitlab.com\/blog\/wp-content\/uploads\/2022\/02\/Figure-9-9-400x192.png 400w\" sizes=\"(max-width: 730px) 100vw, 730px\" \/><figcaption id=\"caption-attachment-7721\" class=\"wp-caption-text\"><span style=\"color: #000000;\">Figure 9. llseek prototype<\/span><\/figcaption><\/figure>\n<p data-font-family=\"Roboto Slab\" data-font-weight=\"400\" data-font-style=\"\">&nbsp;<\/p>\n<p class=\"\" style=\"border-width: 0px; font-family: 'Roboto Slab'; font-weight: 400; font-size: 17px; line-height: 30px;\" data-font-family=\"Roboto Slab\" data-font-weight=\"400\" data-font-style=\"\"><span style=\"font-weight: 400; color: #000000;\">The VFS passes three arguments to this method. One is pointer of file object, and the second one is offset value, and the third one is the origin, that is whence information. Whence information can have three possible values.SEEK_SET, SEEK_CUR, SEEK_END.And so this(whence) decides how to use this (off).&nbsp;<\/span><\/p>\n<p class=\"\" style=\"border-width: 0px; font-family: 'Roboto Slab'; font-weight: 400; font-size: 17px; line-height: 30px;\" data-font-family=\"Roboto Slab\" data-font-weight=\"400\" data-font-style=\"\"><span style=\"font-weight: 400; color: #000000;\">Let&#8217;s say if whence field is set to SEEK_SET. If whence is SEEK_SET, then the file offset is set to this value. The current file offset is just equated to this value. If whence is set to SEEK_CUR, then the current file offset is set to its current position plus offset bytes. This(off) is a offset bytes. And if the whence field is set to this value SEEK_END, then the current file offset is set to size of the file plus this offset.&nbsp;<\/span><\/p>\n<p class=\"\" style=\"border-width: 0px; font-family: 'Roboto Slab'; font-weight: 400; font-size: 17px; line-height: 30px;\" data-font-family=\"Roboto Slab\" data-font-weight=\"400\" data-font-style=\"\"><span style=\"font-weight: 400; color: #000000;\">So, we&#8217;ll see more on this lseek method when we a code for this method in our character driver exercise. In the lseek method, you should do a these things. The driver should update the file pointer by using &#8216;offset&#8217; and &#8216;whence&#8217; information. The llseek&nbsp; handler should return, newly updated file position, or the llseek method may also return error. We will see that during implementation .See you in upcoming article.<\/span><\/p>\n<p class=\"\">&nbsp;<\/p>\n<p class=\"\" style=\"font-size: 18px; line-height: 30px; font-family: 'Roboto Slab'; font-weight: 400;\" data-font-family=\"Roboto Slab\" data-font-weight=\"400\" data-font-style=\"\"><strong><span style=\"color: #993366;\">Get the Full Course on Linux Device Driver <span style=\"color: #0000ff;\"><a style=\"color: #0000ff;\" href=\"https:\/\/www.udemy.com\/course\/linux-device-driver-programming-using-beaglebone-black\/\">Here<\/a><\/span><\/span><\/strong><\/p>\n<p class=\"\" style=\"border-width: 0px; font-family: 'Roboto Slab'; font-weight: 400; font-size: 17px; line-height: 30px;\" data-font-family=\"Roboto Slab\" data-font-weight=\"400\" data-font-style=\"\"><span style=\"color: #000080;\"><b>FastBit Embedded Brain Academy Courses<\/b><\/span><\/p>\n<p class=\"\" style=\"border-width: 0px; font-family: 'Roboto Slab'; font-weight: 400; font-size: 17px; line-height: 23px;\" data-font-family=\"Roboto Slab\" data-font-weight=\"400\" data-font-style=\"\"><span style=\"color: #000000;\">C<span style=\"font-weight: 400;\"><span style=\"color: #000000;\">lick here:<\/span>&nbsp;<\/span><\/span><span style=\"color: #3366ff;\"><a style=\"color: #3366ff; text-decoration: underline;\" href=\"http:\/\/fastbitlab.com\/course1\" target=\"_blank\" rel=\"noopener\"><span style=\"font-weight: 400;\">https:\/\/fastbitlab.com\/course1<\/span><\/a><\/span><\/p>\n<p class=\"\">&nbsp;<\/p>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n","protected":false},"excerpt":{"rendered":"<p>&nbsp; Character driver file operation methods contd. &nbsp; &nbsp; In the previous article, we came to know about how VFS and it&#8217;s various data structures are involved in a file operation. Open Method: Whenever the user-level program executes a open system call, the open method( as shown in Figure 1) of your driver will get [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":7713,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"ocean_post_layout":"","ocean_both_sidebars_style":"","ocean_both_sidebars_content_width":0,"ocean_both_sidebars_sidebars_width":0,"ocean_sidebar":"0","ocean_second_sidebar":"0","ocean_disable_margins":"enable","ocean_add_body_class":"","ocean_shortcode_before_top_bar":"","ocean_shortcode_after_top_bar":"","ocean_shortcode_before_header":"","ocean_shortcode_after_header":"","ocean_has_shortcode":"","ocean_shortcode_after_title":"","ocean_shortcode_before_footer_widgets":"","ocean_shortcode_after_footer_widgets":"","ocean_shortcode_before_footer_bottom":"","ocean_shortcode_after_footer_bottom":"","ocean_display_top_bar":"default","ocean_display_header":"default","ocean_header_style":"","ocean_center_header_left_menu":"0","ocean_custom_header_template":"0","ocean_custom_logo":0,"ocean_custom_retina_logo":0,"ocean_custom_logo_max_width":0,"ocean_custom_logo_tablet_max_width":0,"ocean_custom_logo_mobile_max_width":0,"ocean_custom_logo_max_height":0,"ocean_custom_logo_tablet_max_height":0,"ocean_custom_logo_mobile_max_height":0,"ocean_header_custom_menu":"0","ocean_menu_typo_font_family":"0","ocean_menu_typo_font_subset":"","ocean_menu_typo_font_size":0,"ocean_menu_typo_font_size_tablet":0,"ocean_menu_typo_font_size_mobile":0,"ocean_menu_typo_font_size_unit":"px","ocean_menu_typo_font_weight":"","ocean_menu_typo_font_weight_tablet":"","ocean_menu_typo_font_weight_mobile":"","ocean_menu_typo_transform":"","ocean_menu_typo_transform_tablet":"","ocean_menu_typo_transform_mobile":"","ocean_menu_typo_line_height":0,"ocean_menu_typo_line_height_tablet":0,"ocean_menu_typo_line_height_mobile":0,"ocean_menu_typo_line_height_unit":"","ocean_menu_typo_spacing":0,"ocean_menu_typo_spacing_tablet":0,"ocean_menu_typo_spacing_mobile":0,"ocean_menu_typo_spacing_unit":"","ocean_menu_link_color":"","ocean_menu_link_color_hover":"","ocean_menu_link_color_active":"","ocean_menu_link_background":"","ocean_menu_link_hover_background":"","ocean_menu_link_active_background":"","ocean_menu_social_links_bg":"","ocean_menu_social_hover_links_bg":"","ocean_menu_social_links_color":"","ocean_menu_social_hover_links_color":"","ocean_disable_title":"default","ocean_disable_heading":"default","ocean_post_title":"","ocean_post_subheading":"","ocean_post_title_style":"","ocean_post_title_background_color":"","ocean_post_title_background":0,"ocean_post_title_bg_image_position":"","ocean_post_title_bg_image_attachment":"","ocean_post_title_bg_image_repeat":"","ocean_post_title_bg_image_size":"","ocean_post_title_height":0,"ocean_post_title_bg_overlay":0.5,"ocean_post_title_bg_overlay_color":"","ocean_disable_breadcrumbs":"default","ocean_breadcrumbs_color":"","ocean_breadcrumbs_separator_color":"","ocean_breadcrumbs_links_color":"","ocean_breadcrumbs_links_hover_color":"","ocean_display_footer_widgets":"default","ocean_display_footer_bottom":"default","ocean_custom_footer_template":"0","ocean_post_oembed":"","ocean_post_self_hosted_media":"","ocean_post_video_embed":"","ocean_link_format":"","ocean_link_format_target":"self","ocean_quote_format":"","ocean_quote_format_link":"post","ocean_gallery_link_images":"off","ocean_gallery_id":[],"footnotes":""},"categories":[8],"tags":[31],"class_list":["post-7710","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-blog","tag-linux-device-driver-programming-lectures","entry","has-media"],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v27.3 - https:\/\/yoast.com\/product\/yoast-seo-wordpress\/ -->\n<title>Character driver file operation methods | Linux Device Driver<\/title>\n<meta name=\"description\" content=\"Learn about the essential file operation methods in Linux character drivers including open, close, read, write, llseek. Character driver file\" \/>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/fastbitlab.com\/blog\/character-driver-file-operation-methods-contd\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Character driver file operation methods | Linux Device Driver\" \/>\n<meta property=\"og:description\" content=\"Learn about the essential file operation methods in Linux character drivers including open, close, read, write, llseek. Character driver file\" \/>\n<meta property=\"og:url\" content=\"https:\/\/fastbitlab.com\/blog\/character-driver-file-operation-methods-contd\/\" \/>\n<meta property=\"og:site_name\" content=\"FastBit EBA\" \/>\n<meta property=\"article:publisher\" content=\"https:\/\/www.facebook.com\/fastbiteba\/\" \/>\n<meta property=\"article:published_time\" content=\"2022-02-22T08:58:37+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2023-09-14T06:41:24+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/fastbitlab.com\/blog\/wp-content\/uploads\/2022\/02\/Figure-1-28.png\" \/>\n\t<meta property=\"og:image:width\" content=\"765\" \/>\n\t<meta property=\"og:image:height\" content=\"339\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/png\" \/>\n<meta name=\"author\" content=\"FastBitLab\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:creator\" content=\"@fastbiteba\" \/>\n<meta name=\"twitter:site\" content=\"@fastbiteba\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"FastBitLab\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"11 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\\\/\\\/fastbitlab.com\\\/blog\\\/character-driver-file-operation-methods-contd\\\/#article\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/fastbitlab.com\\\/blog\\\/character-driver-file-operation-methods-contd\\\/\"},\"author\":{\"name\":\"FastBitLab\",\"@id\":\"https:\\\/\\\/fastbitlab.com\\\/blog\\\/#\\\/schema\\\/person\\\/e32b38e733a0d76ffa7e6bc998652e5d\"},\"headline\":\"Linux Device Driver Programming Lecture 34- Character driver file operation methods contd.\",\"datePublished\":\"2022-02-22T08:58:37+00:00\",\"dateModified\":\"2023-09-14T06:41:24+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\\\/\\\/fastbitlab.com\\\/blog\\\/character-driver-file-operation-methods-contd\\\/\"},\"wordCount\":2018,\"commentCount\":0,\"publisher\":{\"@id\":\"https:\\\/\\\/fastbitlab.com\\\/blog\\\/#organization\"},\"image\":{\"@id\":\"https:\\\/\\\/fastbitlab.com\\\/blog\\\/character-driver-file-operation-methods-contd\\\/#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/fastbitlab.com\\\/blog\\\/wp-content\\\/uploads\\\/2022\\\/02\\\/Figure-1-28.png\",\"keywords\":[\"Linux Device Driver Programming Lectures\"],\"articleSection\":[\"Blog\"],\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\\\/\\\/fastbitlab.com\\\/blog\\\/character-driver-file-operation-methods-contd\\\/#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/fastbitlab.com\\\/blog\\\/character-driver-file-operation-methods-contd\\\/\",\"url\":\"https:\\\/\\\/fastbitlab.com\\\/blog\\\/character-driver-file-operation-methods-contd\\\/\",\"name\":\"Character driver file operation methods | Linux Device Driver\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/fastbitlab.com\\\/blog\\\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\\\/\\\/fastbitlab.com\\\/blog\\\/character-driver-file-operation-methods-contd\\\/#primaryimage\"},\"image\":{\"@id\":\"https:\\\/\\\/fastbitlab.com\\\/blog\\\/character-driver-file-operation-methods-contd\\\/#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/fastbitlab.com\\\/blog\\\/wp-content\\\/uploads\\\/2022\\\/02\\\/Figure-1-28.png\",\"datePublished\":\"2022-02-22T08:58:37+00:00\",\"dateModified\":\"2023-09-14T06:41:24+00:00\",\"description\":\"Learn about the essential file operation methods in Linux character drivers including open, close, read, write, llseek. Character driver file\",\"breadcrumb\":{\"@id\":\"https:\\\/\\\/fastbitlab.com\\\/blog\\\/character-driver-file-operation-methods-contd\\\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\\\/\\\/fastbitlab.com\\\/blog\\\/character-driver-file-operation-methods-contd\\\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/fastbitlab.com\\\/blog\\\/character-driver-file-operation-methods-contd\\\/#primaryimage\",\"url\":\"https:\\\/\\\/fastbitlab.com\\\/blog\\\/wp-content\\\/uploads\\\/2022\\\/02\\\/Figure-1-28.png\",\"contentUrl\":\"https:\\\/\\\/fastbitlab.com\\\/blog\\\/wp-content\\\/uploads\\\/2022\\\/02\\\/Figure-1-28.png\",\"width\":765,\"height\":339,\"caption\":\"Figure 1. Open method\"},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/fastbitlab.com\\\/blog\\\/character-driver-file-operation-methods-contd\\\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\\\/\\\/fastbitlab.com\\\/blog\\\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Linux Device Driver Programming Lecture 34- Character driver file operation methods contd.\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\\\/\\\/fastbitlab.com\\\/blog\\\/#website\",\"url\":\"https:\\\/\\\/fastbitlab.com\\\/blog\\\/\",\"name\":\"FastBit EBA\",\"description\":\"Your Online Academy of Embedded Systems\",\"publisher\":{\"@id\":\"https:\\\/\\\/fastbitlab.com\\\/blog\\\/#organization\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\\\/\\\/fastbitlab.com\\\/blog\\\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":\"Organization\",\"@id\":\"https:\\\/\\\/fastbitlab.com\\\/blog\\\/#organization\",\"name\":\"FastBit EBA\",\"url\":\"https:\\\/\\\/fastbitlab.com\\\/blog\\\/\",\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/fastbitlab.com\\\/blog\\\/#\\\/schema\\\/logo\\\/image\\\/\",\"url\":\"https:\\\/\\\/fastbitlab.com\\\/blog\\\/wp-content\\\/uploads\\\/2026\\\/04\\\/logo-EzNrEnyr.png\",\"contentUrl\":\"https:\\\/\\\/fastbitlab.com\\\/blog\\\/wp-content\\\/uploads\\\/2026\\\/04\\\/logo-EzNrEnyr.png\",\"width\":640,\"height\":640,\"caption\":\"FastBit EBA\"},\"image\":{\"@id\":\"https:\\\/\\\/fastbitlab.com\\\/blog\\\/#\\\/schema\\\/logo\\\/image\\\/\"},\"sameAs\":[\"https:\\\/\\\/www.facebook.com\\\/fastbiteba\\\/\",\"https:\\\/\\\/x.com\\\/fastbiteba\",\"https:\\\/\\\/www.linkedin.com\\\/in\\\/fastbit-embedded-brain-academy-b3167b124\\\/\",\"https:\\\/\\\/www.youtube.com\\\/channel\\\/UCa1REBV9hyrzGp2mjJCagBg\"]},{\"@type\":\"Person\",\"@id\":\"https:\\\/\\\/fastbitlab.com\\\/blog\\\/#\\\/schema\\\/person\\\/e32b38e733a0d76ffa7e6bc998652e5d\",\"name\":\"FastBitLab\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/9230d0f9bdef28b63a01e7ca274ee7b2e8ed9abe932ee564af8809caaf52a0c8?s=96&d=mm&r=g\",\"url\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/9230d0f9bdef28b63a01e7ca274ee7b2e8ed9abe932ee564af8809caaf52a0c8?s=96&d=mm&r=g\",\"contentUrl\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/9230d0f9bdef28b63a01e7ca274ee7b2e8ed9abe932ee564af8809caaf52a0c8?s=96&d=mm&r=g\",\"caption\":\"FastBitLab\"},\"description\":\"The FastBit Embedded Brain Academy uses the power of internet to bring the online courses related to the field of embedded system programming, Real time operating system, Embedded Linux systems, etc at your finger tip with very low cost. Backed with strong experience of industry, we have produced lots of courses with the customer enrolment over 3000+ across 100+ countries.\"}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"Character driver file operation methods | Linux Device Driver","description":"Learn about the essential file operation methods in Linux character drivers including open, close, read, write, llseek. Character driver file","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/fastbitlab.com\/blog\/character-driver-file-operation-methods-contd\/","og_locale":"en_US","og_type":"article","og_title":"Character driver file operation methods | Linux Device Driver","og_description":"Learn about the essential file operation methods in Linux character drivers including open, close, read, write, llseek. Character driver file","og_url":"https:\/\/fastbitlab.com\/blog\/character-driver-file-operation-methods-contd\/","og_site_name":"FastBit EBA","article_publisher":"https:\/\/www.facebook.com\/fastbiteba\/","article_published_time":"2022-02-22T08:58:37+00:00","article_modified_time":"2023-09-14T06:41:24+00:00","og_image":[{"width":765,"height":339,"url":"https:\/\/fastbitlab.com\/blog\/wp-content\/uploads\/2022\/02\/Figure-1-28.png","type":"image\/png"}],"author":"FastBitLab","twitter_card":"summary_large_image","twitter_creator":"@fastbiteba","twitter_site":"@fastbiteba","twitter_misc":{"Written by":"FastBitLab","Est. reading time":"11 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/fastbitlab.com\/blog\/character-driver-file-operation-methods-contd\/#article","isPartOf":{"@id":"https:\/\/fastbitlab.com\/blog\/character-driver-file-operation-methods-contd\/"},"author":{"name":"FastBitLab","@id":"https:\/\/fastbitlab.com\/blog\/#\/schema\/person\/e32b38e733a0d76ffa7e6bc998652e5d"},"headline":"Linux Device Driver Programming Lecture 34- Character driver file operation methods contd.","datePublished":"2022-02-22T08:58:37+00:00","dateModified":"2023-09-14T06:41:24+00:00","mainEntityOfPage":{"@id":"https:\/\/fastbitlab.com\/blog\/character-driver-file-operation-methods-contd\/"},"wordCount":2018,"commentCount":0,"publisher":{"@id":"https:\/\/fastbitlab.com\/blog\/#organization"},"image":{"@id":"https:\/\/fastbitlab.com\/blog\/character-driver-file-operation-methods-contd\/#primaryimage"},"thumbnailUrl":"https:\/\/fastbitlab.com\/blog\/wp-content\/uploads\/2022\/02\/Figure-1-28.png","keywords":["Linux Device Driver Programming Lectures"],"articleSection":["Blog"],"inLanguage":"en-US","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/fastbitlab.com\/blog\/character-driver-file-operation-methods-contd\/#respond"]}]},{"@type":"WebPage","@id":"https:\/\/fastbitlab.com\/blog\/character-driver-file-operation-methods-contd\/","url":"https:\/\/fastbitlab.com\/blog\/character-driver-file-operation-methods-contd\/","name":"Character driver file operation methods | Linux Device Driver","isPartOf":{"@id":"https:\/\/fastbitlab.com\/blog\/#website"},"primaryImageOfPage":{"@id":"https:\/\/fastbitlab.com\/blog\/character-driver-file-operation-methods-contd\/#primaryimage"},"image":{"@id":"https:\/\/fastbitlab.com\/blog\/character-driver-file-operation-methods-contd\/#primaryimage"},"thumbnailUrl":"https:\/\/fastbitlab.com\/blog\/wp-content\/uploads\/2022\/02\/Figure-1-28.png","datePublished":"2022-02-22T08:58:37+00:00","dateModified":"2023-09-14T06:41:24+00:00","description":"Learn about the essential file operation methods in Linux character drivers including open, close, read, write, llseek. Character driver file","breadcrumb":{"@id":"https:\/\/fastbitlab.com\/blog\/character-driver-file-operation-methods-contd\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/fastbitlab.com\/blog\/character-driver-file-operation-methods-contd\/"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/fastbitlab.com\/blog\/character-driver-file-operation-methods-contd\/#primaryimage","url":"https:\/\/fastbitlab.com\/blog\/wp-content\/uploads\/2022\/02\/Figure-1-28.png","contentUrl":"https:\/\/fastbitlab.com\/blog\/wp-content\/uploads\/2022\/02\/Figure-1-28.png","width":765,"height":339,"caption":"Figure 1. Open method"},{"@type":"BreadcrumbList","@id":"https:\/\/fastbitlab.com\/blog\/character-driver-file-operation-methods-contd\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/fastbitlab.com\/blog\/"},{"@type":"ListItem","position":2,"name":"Linux Device Driver Programming Lecture 34- Character driver file operation methods contd."}]},{"@type":"WebSite","@id":"https:\/\/fastbitlab.com\/blog\/#website","url":"https:\/\/fastbitlab.com\/blog\/","name":"FastBit EBA","description":"Your Online Academy of Embedded Systems","publisher":{"@id":"https:\/\/fastbitlab.com\/blog\/#organization"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/fastbitlab.com\/blog\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":"Organization","@id":"https:\/\/fastbitlab.com\/blog\/#organization","name":"FastBit EBA","url":"https:\/\/fastbitlab.com\/blog\/","logo":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/fastbitlab.com\/blog\/#\/schema\/logo\/image\/","url":"https:\/\/fastbitlab.com\/blog\/wp-content\/uploads\/2026\/04\/logo-EzNrEnyr.png","contentUrl":"https:\/\/fastbitlab.com\/blog\/wp-content\/uploads\/2026\/04\/logo-EzNrEnyr.png","width":640,"height":640,"caption":"FastBit EBA"},"image":{"@id":"https:\/\/fastbitlab.com\/blog\/#\/schema\/logo\/image\/"},"sameAs":["https:\/\/www.facebook.com\/fastbiteba\/","https:\/\/x.com\/fastbiteba","https:\/\/www.linkedin.com\/in\/fastbit-embedded-brain-academy-b3167b124\/","https:\/\/www.youtube.com\/channel\/UCa1REBV9hyrzGp2mjJCagBg"]},{"@type":"Person","@id":"https:\/\/fastbitlab.com\/blog\/#\/schema\/person\/e32b38e733a0d76ffa7e6bc998652e5d","name":"FastBitLab","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/secure.gravatar.com\/avatar\/9230d0f9bdef28b63a01e7ca274ee7b2e8ed9abe932ee564af8809caaf52a0c8?s=96&d=mm&r=g","url":"https:\/\/secure.gravatar.com\/avatar\/9230d0f9bdef28b63a01e7ca274ee7b2e8ed9abe932ee564af8809caaf52a0c8?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/9230d0f9bdef28b63a01e7ca274ee7b2e8ed9abe932ee564af8809caaf52a0c8?s=96&d=mm&r=g","caption":"FastBitLab"},"description":"The FastBit Embedded Brain Academy uses the power of internet to bring the online courses related to the field of embedded system programming, Real time operating system, Embedded Linux systems, etc at your finger tip with very low cost. Backed with strong experience of industry, we have produced lots of courses with the customer enrolment over 3000+ across 100+ countries."}]}},"_links":{"self":[{"href":"https:\/\/fastbitlab.com\/blog\/wp-json\/wp\/v2\/posts\/7710","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/fastbitlab.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/fastbitlab.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/fastbitlab.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/fastbitlab.com\/blog\/wp-json\/wp\/v2\/comments?post=7710"}],"version-history":[{"count":5,"href":"https:\/\/fastbitlab.com\/blog\/wp-json\/wp\/v2\/posts\/7710\/revisions"}],"predecessor-version":[{"id":15929,"href":"https:\/\/fastbitlab.com\/blog\/wp-json\/wp\/v2\/posts\/7710\/revisions\/15929"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/fastbitlab.com\/blog\/wp-json\/wp\/v2\/media\/7713"}],"wp:attachment":[{"href":"https:\/\/fastbitlab.com\/blog\/wp-json\/wp\/v2\/media?parent=7710"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/fastbitlab.com\/blog\/wp-json\/wp\/v2\/categories?post=7710"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/fastbitlab.com\/blog\/wp-json\/wp\/v2\/tags?post=7710"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}