diff --git a/lkmpg.tex b/lkmpg.tex index 3a44f08..1c61cf0 100644 --- a/lkmpg.tex +++ b/lkmpg.tex @@ -153,7 +153,7 @@ Rest assured, after you get over the initial hurdle of doing it for the first ti You should not be working on this stuff in X Window System. Modules can not print to the screen like \cpp|printf()| can, but they can log information and warnings, which ends up being printed on your screen, but only on a console. - If you insmod a module from an xterm, the information and warnings will be logged, but only to your systemd journal. + If you \sh|insmod| a module from an xterm, the information and warnings will be logged, but only to your systemd journal. You will not see it unless you look through your \sh|journalctl|. See \ref{sec:helloworld} for details. To have immediate access to this information, do all your work from the console. @@ -372,8 +372,8 @@ This and a few other macros describing the module are illustrated in the below e \label{modparam} Modules can take command line arguments, but not with the argc/argv you might be used to. -To allow arguments to be passed to your module, declare the variables that will take the values of the command line arguments as global and then use the \cpp|module_param()| macro, (defined in \verb|linux/moduleparam.h|) to set the mechanism up. -At runtime, insmod will fill the variables with any command line arguments that are given, like insmod ./mymodule.ko myvariable=5. +To allow arguments to be passed to your module, declare the variables that will take the values of the command line arguments as global and then use the \cpp|module_param()| macro, (defined in \verb|include/linux/moduleparam.h|) to set the mechanism up. +At runtime, \sh|insmod| will fill the variables with any command line arguments that are given, like \sh|insmod ./mymodule.ko myvariable=5|. The variable declarations and macros should be placed at the beginning of the module for clarity. The example code should clear up my admittedly lousy explanation. @@ -496,7 +496,7 @@ REGPARM 4KSTACKS gcc-3.3' should be '2.6.5-1.358 686 REGPARM 4KSTACKS gcc-3.3' In other words, your kernel refuses to accept your module because version strings (more precisely, version magics) do not match. Incidentally, version magics are stored in the module object in the form of a static string, starting with vermagic:. Version data are inserted in your module when it is linked against the \verb|init/vermagic.o| file. -To inspect version magics and other strings stored in a given module, issue the modinfo module.ko command: +To inspect version magics and other strings stored in a given module, issue the command \sh|modinfo module.ko|: \begin{verbatim} $ modinfo hello-4.ko @@ -701,7 +701,7 @@ The difference is that block devices have a buffer for requests, so they can cho This is important in the case of storage devices, where it is faster to read or write sectors which are close to each other, rather than those which are further apart. Another difference is that block devices can only accept input and return output in blocks (whose size can vary according to the device), whereas character devices are allowed to use as many or as few bytes as they like. Most devices in the world are character, because they don't need this type of buffering, and they don't operate with a fixed block size. -You can tell whether a device file is for a block device or a character device by looking at the first character in the output of ls -l. +You can tell whether a device file is for a block device or a character device by looking at the first character in the output of \sh|ls -l|. If it is `b' then it is a block device, and if it is `c' then it is a character device. The devices you see above are block devices. Here are some character devices (the serial ports): @@ -887,7 +887,7 @@ Normally, when you do not want to allow something, you return an error code (a n With \cpp|cleanup_module| that's impossible because it is a void function. However, there is a counter which keeps track of how many processes are using your module. You can see what its value is by looking at the 3rd field of \verb|/proc/modules|. -If this number isn't zero, rmmod will fail. +If this number isn't zero, \sh|rmmod| will fail. Note that you do not have to check the counter from within \cpp|cleanup_module| because the check will be performed for you by the system call \cpp|sys_delete_module|, defined in \verb|linux/module.c|. You should not use this counter directly, but there are functions defined in \verb|linux/module.h| which let you increase, decrease and display this counter: @@ -952,7 +952,7 @@ A null return value means that the creation has failed. Each time, everytime the file \verb|/proc/helloworld| is read, the function \cpp|procfile_read| is called. Two parameters of this function are very important: the buffer (the second parameter) and the offset (the fourth one). -The content of the buffer will be returned to the application which read it (for example the cat command). +The content of the buffer will be returned to the application which read it (for example the \sh|cat| command). The offset is the current position in the file. If the return value of the function is not null, then this function is called again. So be careful with this function, if it never returns zero, the read function is called endlessly. @@ -1022,7 +1022,7 @@ Consider using this mechanism, in case you want to document something kernel rel \subsection{Manage /proc file with seq\_file} \label{sec:manage_procfs_with_seq_file} As we have seen, writing a /proc file may be quite ``complex''. -So to help people writting /proc file, there is an API named \cpp|seq_file| that helps formating a /proc file for output. +So to help people writting /proc file, there is an API named \cpp|seq_file| that helps formating a \verb|/proc| file for output. It is based on sequence, which is composed of 3 functions: start(), next(), and stop(). The \cpp|seq_file| API starts a sequence when a user read the /proc file. @@ -1135,7 +1135,7 @@ The natural thing to do would be to use the device file to write things to the m However, this leaves open the question of what to do when you need to talk to the serial port itself, for example to send the rate at which data is sent and received. The answer in Unix is to use a special function called \cpp|ioctl| (short for Input Output ConTroL). -Every device can have its own ioctl commands, which can be read ioctl's (to send information from a process to the kernel), write ioctl's (to return information to a process), both or neither. +Every device can have its own \cpp|ioctl| commands, which can be read ioctl's (to send information from a process to the kernel), write ioctl's (to return information to a process), both or neither. Notice here the roles of read and write are reversed again, so in ioctl's read is to send information to the kernel and write is to receive information from the kernel. The ioctl function is called with three parameters: the file descriptor of the appropriate device file, the ioctl number, and a parameter, which is of type long so you can use a cast to use it to pass anything.