Next, Module hello will be used to create a proc file named hello, which will send us 'Hello World' from Kernel space
- Finish workspace setup
- Understand workflow
- Download the folder
helloto local workspace
- Navigate to Project directory
cd hello
- compile Module
sudo make
- Look for
helloin loaded Modules
sudo lsmod | grep hello
You will get no results
- Look for file
helloin porc fs
cat /proc/hello
you will see :
cat: proc/hello: No such file or directory
- Insert Module
sudo insmod hello.ko
- Again check for simple in module list
sudo lsmod | grep hello
- Check the proc file again
cat /proc/hello
Now we can see
Hello World!
- Remove the Module and verify it's gone
sudo rmmod hello
sudo lsmod | grep hello
No output means module is removed
- Check for proc file again
cat /proc/hello
- Necessary Headers
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/proc_fs.h>
#include <asm/uaccess.h>
- Define macros
#define BUFFER_SIZE 128
#define PROC_NAME "hello"
- Declare function to be called upon proc file read
static ssize_t proc_read(struct file *file, char __user *usr_buf,size_t count, loff_t *pos);
proc_readwill be called whenver we read the created proc file
- Set options for creating new proc file
static const struct proc_ops hello_ops= {
.proc_read = proc_read
};
proc_opsis struct which has options to be used while creating a proc file entry, here we only need to read proc file, hence, we only set theproc_readmember, which is a function pointer.
- This function is called when module is loaded
static int proc_init(void)
{
/* creates the /proc/hello entry */
proc_create(PROC_NAME, 0666, NULL, &hello_ops);
return 0;
}
proc_createfunction creates a new proc file entry with name asPROC_NAME. It returns a type calledproc_dir_entrywhich is a struct representing a proc file.
Permissions of read and write are given by passing0666. Permissions : Numeric Notation
parent is set toNULLhence our file be directly inside /proc
lastly&hello_opsrefers to options we defined above to be used while creating the proc file.
- This function is called when module is removed
{
static void proc_exit(void)
{
/* removes the /proc/hello entry */
remove_proc_entry(PROC_NAME, NULL);
}
}
We remove the prof file using it's name
PROC_NAMEand passing parent as NULL, since it was created at top level.
- This function is called each time
/proc/hellois read
static ssize_t proc_read(struct file *file, char __user *usr_buf,size_t count, loff_t *pos)
{
int rv = 0;
char buffer[BUFFER_SIZE];
static int completed = 0;
if (completed) {
completed = 0;
return 0;
}
completed = 1;
rv = sprintf(buffer,"%s\n" ,"Hello World");
/* copies kernel space buffer to user space usr buf */
copy_to_user(usr_buf, buffer, rv);
return rv;
}
This function will be called each time we read a proc file. So function will be called from user space and function lives in kernel space
fileis a file pointer, which refers toproc file, we are reading.
usr_bufis the buffer in user space which will be written into.
countrefers to the max bytes of data that can written tousr_buf.
posrefers to positional offset while writting tousr_buf.
Note : in our case when we write cat /proc/hello, so the cat command calls the proc_read function with file pointer to our hello proc file, usr_buf as our terminal, and a significant count and generally zero pos.
But how would the proc_read function caller, here cat command know that no more data is to be received?
proc_readreturns the number of bytes, which is equal to number of chars written, soproc_readis called repeteadly until it returns a0value, which means no more data is to be written, whereas a return value of-1indicates failure!
So we initialize
bufferandrvin Kernel space, referring to Kernel buffer and read-value which is returned byproc_read.
initiallycompletedis made 0, to specify that data is still left to be written.
finally we countrvusing sprintf, and copy the Kernel buffer :bufferto user buffer :usr_buf, and return rv.
In next call toproc_read, completed is 1 and hence function returns!
- Macros for registering module entry and exit points
module_init(proc_init);
module_exit(proc_exit);
- Defining additional module info
MODULE_LICENSE("GPL");
MODULE_DESCRIPTION("Hello Module");
MODULE_AUTHOR("SGG");
Note : We declare custom functions and variable as static, this is to limit their scope to current module,otherwise they would be accessible in whole of Kernel and pollute global namespace!
Next up : jiffies Module


