diff --git a/3.16/LKMPG-3.16.html b/3.16/LKMPG-3.16.html index 9aca1f4..81cdfd6 100644 --- a/3.16/LKMPG-3.16.html +++ b/3.16/LKMPG-3.16.html @@ -1421,7 +1421,7 @@ Kernel modules are different here, too. In the hello world example, you might ha
-One point to keep in mind is the difference between library functions and system calls. Library functions are higher level, run completely in user space and provide a more convenient interface for the programmer to the functions that do the real work—system calls. System calls run in kernel mode on the user's behalf and are provided by the kernel itself. The library function printf() may look like a very general printing function, but all it really does is format the data into strings and write the string data using the low-level system call write(), which then sends the data to standard output. +One point to keep in mind is the difference between library functions and system calls. Library functions are higher level, run completely in user space and provide a more convenient interface for the programmer to the functions that do the real work — system calls. System calls run in kernel mode on the user's behalf and are provided by the kernel itself. The library function printf() may look like a very general printing function, but all it really does is format the data into strings and write the string data using the low-level system call write(), which then sends the data to standard output.
@@ -1483,7 +1483,7 @@ The file /proc/kallsyms holds all the symbols that the kernel knows about
-Memory management is a very complicated subject—the majority of O'Reilly's "Understanding The Linux Kernel" is just on memory management! We're not setting out to be experts on memory managements, but we do need to know a couple of facts to even begin worrying about writing real modules. +Memory management is a very complicated subject — the majority of O'Reilly's "Understanding The Linux Kernel" is just on memory management! We're not setting out to be experts on memory managements, but we do need to know a couple of facts to even begin worrying about writing real modules.
@@ -2953,9 +2953,9 @@ If you want to use ioctls in your own kernel modules, it is best to receive an o /* * Set the message of the device driver */ -#define IOCTL_SET_MSG _IOR(MAJOR_NUM, 0, char *) +#define IOCTL_SET_MSG _IOW(MAJOR_NUM, 0, char *) /* - * _IOR means that we're creating an ioctl command + * _IOW means that we're creating an ioctl command * number for passing information from a user process * to the kernel module. * @@ -3151,7 +3151,7 @@ The init_module function replaces the appropriate location in sys_call
-Now, if B is removed first, everything will be well—it will simply restore the system call to A_open, which calls the original. However, if A is removed and then B is removed, the system will crash. A's removal will restore the system call to the original, sys_open, cutting B out of the loop. Then, when B is removed, it will restore the system call to what it thinks is the original, A_open, which is no longer in memory. At first glance, it appears we could solve this particular problem by checking if the system call is equal to our open function and if so not changing it at all (so that B won't change the system call when it's removed), but that will cause an even worse problem. When A is removed, it sees that the system call was changed to B_open so that it is no longer pointing to A_open, so it won't restore it to sys_open before it is removed from memory. Unfortunately, B_open will still try to call A_open which is no longer there, so that even without removing B the system would crash. +Now, if B is removed first, everything will be well — it will simply restore the system call to A_open, which calls the original. However, if A is removed and then B is removed, the system will crash. A's removal will restore the system call to the original, sys_open, cutting B out of the loop. Then, when B is removed, it will restore the system call to what it thinks is the original, A_open, which is no longer in memory. At first glance, it appears we could solve this particular problem by checking if the system call is equal to our open function and if so not changing it at all (so that B won't change the system call when it's removed), but that will cause an even worse problem. When A is removed, it sees that the system call was changed to B_open so that it is no longer pointing to A_open, so it won't restore it to sys_open before it is removed from memory. Unfortunately, B_open will still try to call A_open which is no longer there, so that even without removing B the system would crash.
diff --git a/3.16/LKMPG-3.16.org b/3.16/LKMPG-3.16.org index e64d984..2160a61 100644 --- a/3.16/LKMPG-3.16.org +++ b/3.16/LKMPG-3.16.org @@ -661,7 +661,7 @@ Programmers use functions they don't define all the time. A prime example of thi Kernel modules are different here, too. In the hello world example, you might have noticed that we used a function, *printk()* but didn't include a standard I/O library. That's because modules are object files whose symbols get resolved upon insmod'ing. The definition for the symbols comes from the kernel itself; the only external functions you can use are the ones provided by the kernel. If you're curious about what symbols have been exported by your kernel, take a look at */proc/kallsyms*. -One point to keep in mind is the difference between library functions and system calls. Library functions are higher level, run completely in user space and provide a more convenient interface for the programmer to the functions that do the real work---system calls. System calls run in kernel mode on the user's behalf and are provided by the kernel itself. The library function printf() may look like a very general printing function, but all it really does is format the data into strings and write the string data using the low-level system call write(), which then sends the data to standard output. +One point to keep in mind is the difference between library functions and system calls. Library functions are higher level, run completely in user space and provide a more convenient interface for the programmer to the functions that do the real work --- system calls. System calls run in kernel mode on the user's behalf and are provided by the kernel itself. The library function printf() may look like a very general printing function, but all it really does is format the data into strings and write the string data using the low-level system call write(), which then sends the data to standard output. Would you like to see what system calls are made by printf()? It's easy! Compile the following program: @@ -695,7 +695,7 @@ The file */proc/kallsyms* holds all the symbols that the kernel knows about and ** Code space -Memory management is a very complicated subject---the majority of O'Reilly's "/Understanding The Linux Kernel/" is just on memory management! We're not setting out to be experts on memory managements, but we do need to know a couple of facts to even begin worrying about writing real modules. +Memory management is a very complicated subject --- the majority of O'Reilly's "/Understanding The Linux Kernel/" is just on memory management! We're not setting out to be experts on memory managements, but we do need to know a couple of facts to even begin worrying about writing real modules. If you haven't thought about what a segfault really means, you may be surprised to hear that pointers don't actually point to memory locations. Not real ones, anyway. When a process is created, the kernel sets aside a portion of real physical memory and hands it to the process to use for its executing code, variables, stack, heap and other things which a computer scientist would know about[5]. This memory begins with 0x00000000 and extends up to whatever it needs to be. Since the memory space for any two processes don't overlap, every process that can access a memory address, say 0xbffff978, would be accessing a different location in real physical memory! The processes would be accessing an index named 0xbffff978 which points to some kind of offset into the region of memory set aside for that particular process. For the most part, a process like our Hello, World program can't access the space of another process, although there are ways which we'll talk about later. @@ -1931,9 +1931,9 @@ void cleanup_module() /* * Set the message of the device driver */ -#define IOCTL_SET_MSG _IOR(MAJOR_NUM, 0, char *) +#define IOCTL_SET_MSG _IOW(MAJOR_NUM, 0, char *) /* - * _IOR means that we're creating an ioctl command + * _IOW means that we're creating an ioctl command * number for passing information from a user process * to the kernel module. * diff --git a/3.8/LKMPG-3.8.org b/3.8/LKMPG-3.8.org index 921fff3..a227e15 100644 --- a/3.8/LKMPG-3.8.org +++ b/3.8/LKMPG-3.8.org @@ -708,7 +708,7 @@ Programmers use functions they don't define all the time. A prime example of thi Kernel modules are different here, too. In the hello world example, you might have noticed that we used a function, printk() but didn't include a standard I/O library. That's because modules are object files whose symbols get resolved upon insmod'ing. The definition for the symbols comes from the kernel itself; the only external functions you can use are the ones provided by the kernel. If you're curious about what symbols have been exported by your kernel, take a look at /proc/kallsyms. -One point to keep in mind is the difference between library functions and system calls. Library functions are higher level, run completely in user space and provide a more convenient interface for the programmer to the functions that do the real work---system calls. System calls run in kernel mode on the user's behalf and are provided by the kernel itself. The library function printf() may look like a very general printing function, but all it really does is format the data into strings and write the string data using the low-level system call write(), which then sends the data to standard output. +One point to keep in mind is the difference between library functions and system calls. Library functions are higher level, run completely in user space and provide a more convenient interface for the programmer to the functions that do the real work --- system calls. System calls run in kernel mode on the user's behalf and are provided by the kernel itself. The library function printf() may look like a very general printing function, but all it really does is format the data into strings and write the string data using the low-level system call write(), which then sends the data to standard output. Would you like to see what system calls are made by printf()? It's easy! Compile the following program: @@ -742,7 +742,7 @@ The file */proc/kallsyms* holds all the symbols that the kernel knows about and ** Code space -Memory management is a very complicated subject---the majority of O'Reilly's `Understanding The Linux Kernel' is just on memory management! We're not setting out to be experts on memory managements, but we do need to know a couple of facts to even begin worrying about writing real modules. +Memory management is a very complicated subject --- the majority of O'Reilly's `Understanding The Linux Kernel' is just on memory management! We're not setting out to be experts on memory managements, but we do need to know a couple of facts to even begin worrying about writing real modules. If you haven't thought about what a segfault really means, you may be surprised to hear that pointers don't actually point to memory locations. Not real ones, anyway. When a process is created, the kernel sets aside a portion of real physical memory and hands it to the process to use for its executing code, variables, stack, heap and other things which a computer scientist would know about[5]. This memory begins with 0x00000000 and extends up to whatever it needs to be. Since the memory space for any two processes don't overlap, every process that can access a memory address, say 0xbffff978, would be accessing a different location in real physical memory! The processes would be accessing an index named 0xbffff978 which points to some kind of offset into the region of memory set aside for that particular process. For the most part, a process like our Hello, World program can't access the space of another process, although there are ways which we'll talk about later. @@ -2045,9 +2045,9 @@ void cleanup_module() /* * Set the message of the device driver */ -#define IOCTL_SET_MSG _IOR(MAJOR_NUM, 0, char *) +#define IOCTL_SET_MSG _IOW(MAJOR_NUM, 0, char *) /* - * _IOR means that we're creating an ioctl command + * _IOW means that we're creating an ioctl command * number for passing information from a user process * to the kernel module. * @@ -2214,7 +2214,7 @@ The source code here is an example of such a kernel module. We want to `spy' on The init_module function replaces the appropriate location in sys_call_table and keeps the original pointer in a variable. The cleanup_module function uses that variable to restore everything back to normal. This approach is dangerous, because of the possibility of two kernel modules changing the same system call. Imagine we have two kernel modules, A and B. A's open system call will be A_open and B's will be B_open. Now, when A is inserted into the kernel, the system call is replaced with A_open, which will call the original sys_open when it's done. Next, B is inserted into the kernel, which replaces the system call with B_open, which will call what it thinks is the original system call, A_open, when it's done. -Now, if B is removed first, everything will be well---it will simply restore the system call to A_open, which calls the original. However, if A is removed and then B is removed, the system will crash. A's removal will restore the system call to the original, sys_open, cutting B out of the loop. Then, when B is removed, it will restore the system call to what it thinks is the original, A_open, which is no longer in memory. At first glance, it appears we could solve this particular problem by checking if the system call is equal to our open function and if so not changing it at all (so that B won't change the system call when it's removed), but that will cause an even worse problem. When A is removed, it sees that the system call was changed to B_open so that it is no longer pointing to A_open, so it won't restore it to sys_open before it is removed from memory. Unfortunately, B_open will still try to call A_open which is no longer there, so that even without removing B the system would crash. +Now, if B is removed first, everything will be well --- it will simply restore the system call to A_open, which calls the original. However, if A is removed and then B is removed, the system will crash. A's removal will restore the system call to the original, sys_open, cutting B out of the loop. Then, when B is removed, it will restore the system call to what it thinks is the original, A_open, which is no longer in memory. At first glance, it appears we could solve this particular problem by checking if the system call is equal to our open function and if so not changing it at all (so that B won't change the system call when it's removed), but that will cause an even worse problem. When A is removed, it sees that the system call was changed to B_open so that it is no longer pointing to A_open, so it won't restore it to sys_open before it is removed from memory. Unfortunately, B_open will still try to call A_open which is no longer there, so that even without removing B the system would crash. Note that all the related problems make syscall stealing unfeasiable for production use. In order to keep people from doing potential harmful things sys_call_table is no longer exported. This means, if you want to do something more than a mere dry run of this example, you will have to patch your current kernel in order to have sys_call_table exported. In the example directory you will find a README and the patch. As you can imagine, such modifications are not to be taken lightly. Do not try this on valueable systems (ie systems that you do not own - or cannot restore easily). You'll need to get the complete sourcecode of this guide as a tarball in order to get the patch and the README. Depending on your kernel version, you might even need to hand apply the patch. Still here? Well, so is this chapter. If Wyle E. Coyote was a kernel hacker, this would be the first thing he'd try. ;) diff --git a/4.7.4/LKMPG-4.7.4.html b/4.7.4/LKMPG-4.7.4.html index 6c990ea..9136298 100644 --- a/4.7.4/LKMPG-4.7.4.html +++ b/4.7.4/LKMPG-4.7.4.html @@ -1241,7 +1241,7 @@ Kernel modules are different here, too. In the hello world example, you might ha
-One point to keep in mind is the difference between library functions and system calls. Library functions are higher level, run completely in user space and provide a more convenient interface for the programmer to the functions that do the real work—system calls. System calls run in kernel mode on the user's behalf and are provided by the kernel itself. The library function printf() may look like a very general printing function, but all it really does is format the data into strings and write the string data using the low-level system call write(), which then sends the data to standard output. +One point to keep in mind is the difference between library functions and system calls. Library functions are higher level, run completely in user space and provide a more convenient interface for the programmer to the functions that do the real work — system calls. System calls run in kernel mode on the user's behalf and are provided by the kernel itself. The library function printf() may look like a very general printing function, but all it really does is format the data into strings and write the string data using the low-level system call write(), which then sends the data to standard output.
@@ -2444,7 +2444,7 @@ If you want to use ioctls in your own kernel modules, it is best to receive an o #include <linux/fs.h> #include <asm/uaccess.h> /* for get_user and put_user */ -#include "chardev2.h" +#include "chardev.h" #define SUCCESS 0 #define DEVICE_NAME "char_dev" #define BUF_LEN 80 @@ -2738,9 +2738,9 @@ If you want to use ioctls in your own kernel modules, it is best to receive an o /* * Set the message of the device driver */ -#define IOCTL_SET_MSG _IOR(MAJOR_NUM, 0, char *) +#define IOCTL_SET_MSG _IOW(MAJOR_NUM, 0, char *) /* - * _IOR means that we're creating an ioctl command + * _IOW means that we're creating an ioctl command * number for passing information from a user process * to the kernel module. * @@ -2796,7 +2796,7 @@ If you want to use ioctls in your own kernel modules, it is best to receive an o * device specifics, such as ioctl numbers and the * major device file. */ -#include "chardev.h" +#include "../chardev.h" #include <stdio.h> #include <stdlib.h> @@ -2934,7 +2934,7 @@ The init_module function replaces the appropriate location in sys_call
-Now, if B is removed first, everything will be well—it will simply restore the system call to A_open, which calls the original. However, if A is removed and then B is removed, the system will crash. A's removal will restore the system call to the original, sys_open, cutting B out of the loop. Then, when B is removed, it will restore the system call to what it thinks is the original, A_open, which is no longer in memory. At first glance, it appears we could solve this particular problem by checking if the system call is equal to our open function and if so not changing it at all (so that B won't change the system call when it's removed), but that will cause an even worse problem. When A is removed, it sees that the system call was changed to B_open so that it is no longer pointing to A_open, so it won't restore it to sys_open before it is removed from memory. Unfortunately, B_open will still try to call A_open which is no longer there, so that even without removing B the system would crash. +Now, if B is removed first, everything will be well — it will simply restore the system call to A_open, which calls the original. However, if A is removed and then B is removed, the system will crash. A's removal will restore the system call to the original, sys_open, cutting B out of the loop. Then, when B is removed, it will restore the system call to what it thinks is the original, A_open, which is no longer in memory. At first glance, it appears we could solve this particular problem by checking if the system call is equal to our open function and if so not changing it at all (so that B won't change the system call when it's removed), but that will cause an even worse problem. When A is removed, it sees that the system call was changed to B_open so that it is no longer pointing to A_open, so it won't restore it to sys_open before it is removed from memory. Unfortunately, B_open will still try to call A_open which is no longer there, so that even without removing B the system would crash.
diff --git a/4.7.4/LKMPG-4.7.4.org b/4.7.4/LKMPG-4.7.4.org
index ce94718..b03d05c 100644
--- a/4.7.4/LKMPG-4.7.4.org
+++ b/4.7.4/LKMPG-4.7.4.org
@@ -612,7 +612,7 @@ Programmers use functions they don't define all the time. A prime example of thi
Kernel modules are different here, too. In the hello world example, you might have noticed that we used a function, *printk()* but didn't include a standard I/O library. That's because modules are object files whose symbols get resolved upon insmod'ing. The definition for the symbols comes from the kernel itself; the only external functions you can use are the ones provided by the kernel. If you're curious about what symbols have been exported by your kernel, take a look at */proc/kallsyms*.
-One point to keep in mind is the difference between library functions and system calls. Library functions are higher level, run completely in user space and provide a more convenient interface for the programmer to the functions that do the real work---system calls. System calls run in kernel mode on the user's behalf and are provided by the kernel itself. The library function printf() may look like a very general printing function, but all it really does is format the data into strings and write the string data using the low-level system call write(), which then sends the data to standard output.
+One point to keep in mind is the difference between library functions and system calls. Library functions are higher level, run completely in user space and provide a more convenient interface for the programmer to the functions that do the real work --- system calls. System calls run in kernel mode on the user's behalf and are provided by the kernel itself. The library function printf() may look like a very general printing function, but all it really does is format the data into strings and write the string data using the low-level system call write(), which then sends the data to standard output.
Would you like to see what system calls are made by printf()? It's easy! Compile the following program:
@@ -1063,7 +1063,7 @@ The reason for copy_from_user or get_user is that Linux memory (on Intel archite
The only memory segment accessible to a process is its own, so when writing regular programs to run as processes, there's no need to worry about segments. When you write a kernel module, normally you want to access the kernel memory segment, which is handled automatically by the system. However, when the content of a memory buffer needs to be passed between the currently running process and the kernel, the kernel function receives a pointer to the memory buffer which is in the process segment. The put_user and get_user macros allow you to access that memory. These functions handle only one caracter, you can handle several caracters with copy_to_user and copy_from_user. As the buffer (in read or write function) is in kernel space, for write function you need to import data because it comes from user space, but not for the read function because data is already in kernel space.
-#+BEGIN_SRC c
+#+BEGIN_SRC c :file procfs2.c
/**
* procfs2.c - create a "file" in /proc
*
@@ -1173,7 +1173,7 @@ Another interesting point here is the module_permission function. This function
It's important to note that the standard roles of read and write are reversed in the kernel. Read functions are used for output, whereas write functions are used for input. The reason for that is that read and write refer to the user's point of view --- if a process reads something from the kernel, then the kernel needs to output it, and if a process writes something to the kernel, then the kernel receives it as input.
-#+BEGIN_SRC c
+#+BEGIN_SRC c :file procfs3.c
/*
procfs3.c
*/
@@ -1298,7 +1298,7 @@ digraph seq_file {
|
Seq_file provides basic functions for file_operations, as seq_read, seq_lseek, and some others. But nothing to write in the /proc file. Of course, you can still use the same way as in the previous example.
-#+BEGIN_SRC c
+#+BEGIN_SRC c :file procfs4.c
/**
* procfs4.c - create a "file" in /proc
* This program uses the seq_file library to manage the /proc file.
@@ -1573,7 +1573,7 @@ If you want to use ioctls in your own kernel modules, it is best to receive an o
#include
-One point to keep in mind is the difference between library functions and system calls. Library functions are higher level, run completely in user space and provide a more convenient interface for the programmer to the functions that do the real work—system calls. System calls run in kernel mode on the user's behalf and are provided by the kernel itself. The library function printf() may look like a very general printing function, but all it really does is format the data into strings and write the string data using the low-level system call write(), which then sends the data to standard output. +One point to keep in mind is the difference between library functions and system calls. Library functions are higher level, run completely in user space and provide a more convenient interface for the programmer to the functions that do the real work — system calls. System calls run in kernel mode on the user's behalf and are provided by the kernel itself. The library function printf() may look like a very general printing function, but all it really does is format the data into strings and write the string data using the low-level system call write(), which then sends the data to standard output.
@@ -1696,7 +1696,7 @@ The next code sample creates a char driver named chardev. You can cat its device */ module_put(THIS_MODULE); - return 0; + return SUCCESS; } /* @@ -2463,7 +2463,7 @@ If you want to use ioctls in your own kernel modules, it is best to receive an o #include <linux/fs.h> #include <asm/uaccess.h> /* for get_user and put_user */ -#include "chardev2.h" +#include "chardev.h" #define SUCCESS 0 #define DEVICE_NAME "char_dev" #define BUF_LEN 80 @@ -2757,9 +2757,9 @@ If you want to use ioctls in your own kernel modules, it is best to receive an o /* * Set the message of the device driver */ -#define IOCTL_SET_MSG _IOR(MAJOR_NUM, 0, char *) +#define IOCTL_SET_MSG _IOW(MAJOR_NUM, 0, char *) /* - * _IOR means that we're creating an ioctl command + * _IOW means that we're creating an ioctl command * number for passing information from a user process * to the kernel module. * @@ -2815,7 +2815,7 @@ If you want to use ioctls in your own kernel modules, it is best to receive an o * device specifics, such as ioctl numbers and the * major device file. */ -#include "chardev.h" +#include "../chardev.h" #include <stdio.h> #include <stdlib.h> @@ -2953,7 +2953,7 @@ The init_module function replaces the appropriate location in sys_call
-Now, if B is removed first, everything will be well—it will simply restore the system call to A_open, which calls the original. However, if A is removed and then B is removed, the system will crash. A's removal will restore the system call to the original, sys_open, cutting B out of the loop. Then, when B is removed, it will restore the system call to what it thinks is the original, A_open, which is no longer in memory. At first glance, it appears we could solve this particular problem by checking if the system call is equal to our open function and if so not changing it at all (so that B won't change the system call when it's removed), but that will cause an even worse problem. When A is removed, it sees that the system call was changed to B_open so that it is no longer pointing to A_open, so it won't restore it to sys_open before it is removed from memory. Unfortunately, B_open will still try to call A_open which is no longer there, so that even without removing B the system would crash. +Now, if B is removed first, everything will be well — it will simply restore the system call to A_open, which calls the original. However, if A is removed and then B is removed, the system will crash. A's removal will restore the system call to the original, sys_open, cutting B out of the loop. Then, when B is removed, it will restore the system call to what it thinks is the original, A_open, which is no longer in memory. At first glance, it appears we could solve this particular problem by checking if the system call is equal to our open function and if so not changing it at all (so that B won't change the system call when it's removed), but that will cause an even worse problem. When A is removed, it sees that the system call was changed to B_open so that it is no longer pointing to A_open, so it won't restore it to sys_open before it is removed from memory. Unfortunately, B_open will still try to call A_open which is no longer there, so that even without removing B the system would crash.
@@ -3561,7 +3561,7 @@ MODULE_AUTHOR("Peter Jay Salzman");
/*
* The tty for the current task, for 2.6.6+ kernels
*/
- my_tty = current->signal->tty;
+ my_tty = get_current_tty();;
#endif
ttyops = my_tty->driver->ops;
diff --git a/4.9.11/LKMPG-4.9.11.org b/4.9.11/LKMPG-4.9.11.org
index 2293714..7ded22a 100644
--- a/4.9.11/LKMPG-4.9.11.org
+++ b/4.9.11/LKMPG-4.9.11.org
@@ -612,7 +612,7 @@ Programmers use functions they don't define all the time. A prime example of thi
Kernel modules are different here, too. In the hello world example, you might have noticed that we used a function, *printk()* but didn't include a standard I/O library. That's because modules are object files whose symbols get resolved upon insmod'ing. The definition for the symbols comes from the kernel itself; the only external functions you can use are the ones provided by the kernel. If you're curious about what symbols have been exported by your kernel, take a look at */proc/kallsyms*.
-One point to keep in mind is the difference between library functions and system calls. Library functions are higher level, run completely in user space and provide a more convenient interface for the programmer to the functions that do the real work---system calls. System calls run in kernel mode on the user's behalf and are provided by the kernel itself. The library function printf() may look like a very general printing function, but all it really does is format the data into strings and write the string data using the low-level system call write(), which then sends the data to standard output.
+One point to keep in mind is the difference between library functions and system calls. Library functions are higher level, run completely in user space and provide a more convenient interface for the programmer to the functions that do the real work --- system calls. System calls run in kernel mode on the user's behalf and are provided by the kernel itself. The library function printf() may look like a very general printing function, but all it really does is format the data into strings and write the string data using the low-level system call write(), which then sends the data to standard output.
Would you like to see what system calls are made by printf()? It's easy! Compile the following program:
@@ -914,7 +914,7 @@ static int device_release(struct inode *inode, struct file *file)
*/
module_put(THIS_MODULE);
- return 0;
+ return SUCCESS;
}
/*
@@ -964,8 +964,10 @@ static ssize_t device_read(struct file *filp, /* see include/linux/fs.h */
/*
* Called when a process writes to dev file: echo "hi" > /dev/hello
*/
-static ssize_t
-device_write(struct file *filp, const char *buff, size_t len, loff_t * off)
+static ssize_t device_write(struct file *filp,
+ const char *buff,
+ size_t len,
+ loff_t * off)
{
printk(KERN_ALERT "Sorry, this operation isn't supported.\n");
return -EINVAL;
@@ -1063,7 +1065,7 @@ The reason for copy_from_user or get_user is that Linux memory (on Intel archite
The only memory segment accessible to a process is its own, so when writing regular programs to run as processes, there's no need to worry about segments. When you write a kernel module, normally you want to access the kernel memory segment, which is handled automatically by the system. However, when the content of a memory buffer needs to be passed between the currently running process and the kernel, the kernel function receives a pointer to the memory buffer which is in the process segment. The put_user and get_user macros allow you to access that memory. These functions handle only one caracter, you can handle several caracters with copy_to_user and copy_from_user. As the buffer (in read or write function) is in kernel space, for write function you need to import data because it comes from user space, but not for the read function because data is already in kernel space.
-#+BEGIN_SRC c
+#+BEGIN_SRC c :file procfs2.c
/**
* procfs2.c - create a "file" in /proc
*
@@ -1173,7 +1175,7 @@ Another interesting point here is the module_permission function. This function
It's important to note that the standard roles of read and write are reversed in the kernel. Read functions are used for output, whereas write functions are used for input. The reason for that is that read and write refer to the user's point of view --- if a process reads something from the kernel, then the kernel needs to output it, and if a process writes something to the kernel, then the kernel receives it as input.
-#+BEGIN_SRC c
+#+BEGIN_SRC c :file procfs3.c
/*
procfs3.c
*/
@@ -1298,7 +1300,7 @@ digraph seq_file {
|
Seq_file provides basic functions for file_operations, as seq_read, seq_lseek, and some others. But nothing to write in the /proc file. Of course, you can still use the same way as in the previous example.
-#+BEGIN_SRC c
+#+BEGIN_SRC c :file procfs4.c
/**
* procfs4.c - create a "file" in /proc
* This program uses the seq_file library to manage the /proc file.
@@ -1573,7 +1575,7 @@ If you want to use ioctls in your own kernel modules, it is best to receive an o
#include