You should add terminating "
" at the end of your prints to force their flush into the kernel log buffer. Here is your module with some enhancement suggestions:
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/fs.h>
#include <linux/kdev_t.h>
#include <linux/cdev.h>
#include <linux/uaccess.h>
#include <linux/slab.h>
MODULE_LICENSE("Dual BSD/GPL");
#define DEVICE_NAME "device"
static int device_open(struct inode *, struct file *);
static int device_release(struct inode *, struct file *);
static ssize_t device_read(struct file *, char *, size_t, loff_t *);
static ssize_t device_write(struct file *, const char *, size_t, loff_t *);
static long int device_ioctl(struct file *, unsigned int, unsigned long);
static const struct file_operations fops =
{
.owner= THIS_MODULE,
.read= device_read,
.write=device_write,
.unlocked_ioctl= device_ioctl,
.open= device_open,
.release= device_release
};
struct cdev *device_cdev;
dev_t deviceNumbers;
static int __init init(void) // <------ Add __init keyword for kernel cleanups
{
// This returns the major number chosen dynamically in deviceNumbers
int ret = alloc_chrdev_region(&deviceNumbers, 0, 1, DEVICE_NAME);
if (ret < 0) {
printk(KERN_ALERT "Error registering: %d
", ret);
return -1;
}
device_cdev = cdev_alloc();
cdev_init(device_cdev, &fops);
ret = cdev_add(device_cdev, deviceNumbers, 1);
printk(KERN_INFO "Device initialized (major number is %d)
", MAJOR(deviceNumbers));
return 0;
}
static void __exit cleanup(void) // <------ Add __exit keyword for kernel cleanups
{
unregister_chrdev_region(deviceNumbers, 1);
cdev_del(device_cdev);
printk(KERN_INFO "Device unloaded
");
}
static int device_open(struct inode *inode, struct file *file)
{
printk(KERN_INFO "Device open
");
return 0;
}
static int device_release(struct inode *inode, struct file *file)
{
printk(KERN_INFO "Device released
");
return 0;
}
static ssize_t device_write(struct file *filp, const char *buff, size_t len, loff_t * off)
{
printk(KERN_INFO "Device write
");
return len; // <-------------- To stop the write
}
static ssize_t device_read(struct file *filp, char *buff, size_t len, loff_t * off)
{
printk(KERN_INFO "Device read
");
return len; // <-------------- To stop the read
}
static long int device_ioctl(struct file *file, unsigned int ioctl_num, unsigned long ioctl_param)
{
printk(KERN_INFO "Device IOCTL
");
return 0;
}
module_init(init);
module_exit(cleanup);
Check the current settings for the kernel log level.
$ cat /proc/sys/kernel/printk
4 4 1 7
In the preceding, the first column specifies that only messages with a log level lower than 4 will be printed.
The values accepted by printk() are:
KERN_EMERG 0 System is unusable
KERN_ALERT 1 Action must be taken immediately
KERN_CRIT 2 Critical conditions
KERN_ERR 3 Error conditions
KERN_WARNING 4 Warning conditions
KERN_NOTICE 5 Normal but significant condition
KERN_INFO 6 Informational
KERN_DEBUG 7 Debug-level messages
So, the KERN_INFO level is 6 which is greater than 4!
We modify the configuration:
$ sudo sh -c "echo 7 4 1 7 > /proc/sys/kernel/printk"
$ cat /proc/sys/kernel/printk
7 4 1 7
I built your module with the suggested modifications and tried it on Linux 5.4.0-58:
$ uname -a
Linux xxxx 5.4.0-58-generic #64-Ubuntu SMP Wed Dec 9 08:16:25 UTC 2020 x86_64 x86_64 x86_64 GNU/Linux
$ sudo insmod ./device.ko
$ dmesg
[...]
[ 7244.516706] Device initialized (major number is 235)
$ lsmod
Module Size Used by
device 16384 0
[...]
$ cat /proc/devices
Character devices:
[...]
235 device
$ sudo mknod /dev/device c 235 0
$ ls -l /dev/device
crw-r--r-- 1 root root 235, 0 janv. 3 10:33 /dev/device
$ sudo sh -c "echo foo > /dev/device"
$ dmesg
[...]
[ 7244.516706] Device initialized (major number is 235)
[ 7311.507652] Device open
[ 7311.507672] Device write
[ 7311.507677] Device released
$ sudo rmmod device
$ dmesg
[...]
[ 7244.516706] Device initialized (major number is 235)
[ 7311.507652] Device open
[ 7311.507672] Device write
[ 7311.507677] Device released
[ 7361.523964] Device unloaded
$ sudo rm /dev/device