diff --git a/work/hello-1/Makefile b/work/hello-1/Makefile index 5288f363e215823d84dae35c7cdc2172ff6f9c7d..b06c2df0f45277c58b081c12be911d4e2507cd05 100644 --- a/work/hello-1/Makefile +++ b/work/hello-1/Makefile @@ -1,6 +1,9 @@ KDIR=../../build/kvm/ -obj-m += hello-1.o +obj-m += hello-1.o +obj-m += hello-2.o +obj-m += hello-3.o +obj-m += hello-5.o PWD := $(CURDIR) all: diff --git a/work/hello-1/hello b/work/hello-1/hello new file mode 100755 index 0000000000000000000000000000000000000000..297a392588eb66dbe792595b2e025125c668e489 Binary files /dev/null and b/work/hello-1/hello differ diff --git a/work/hello-1/hello-1.mod.c b/work/hello-1/hello-1.mod.c new file mode 100644 index 0000000000000000000000000000000000000000..c50ac50780e09188a9caa662cc896b775ac3a7c5 --- /dev/null +++ b/work/hello-1/hello-1.mod.c @@ -0,0 +1,47 @@ +#include <linux/module.h> +#define INCLUDE_VERMAGIC +#include <linux/build-salt.h> +#include <linux/elfnote-lto.h> +#include <linux/export-internal.h> +#include <linux/vermagic.h> +#include <linux/compiler.h> + +#ifdef CONFIG_UNWINDER_ORC +#include <asm/orc_header.h> +ORC_HEADER; +#endif + +BUILD_SALT; +BUILD_LTO_INFO; + +MODULE_INFO(vermagic, VERMAGIC_STRING); +MODULE_INFO(name, KBUILD_MODNAME); + +__visible struct module __this_module +__section(".gnu.linkonce.this_module") = { + .name = KBUILD_MODNAME, + .init = init_module, +#ifdef CONFIG_MODULE_UNLOAD + .exit = cleanup_module, +#endif + .arch = MODULE_ARCH_INIT, +}; + +#ifdef CONFIG_RETPOLINE +MODULE_INFO(retpoline, "Y"); +#endif + + + +static const struct modversion_info ____versions[] +__used __section("__versions") = { + { 0xbdfb6dbb, "__fentry__" }, + { 0x122c3a7e, "_printk" }, + { 0x5b8239ca, "__x86_return_thunk" }, + { 0x76800044, "module_layout" }, +}; + +MODULE_INFO(depends, ""); + + +MODULE_INFO(srcversion, "93D1874613E2633FD08C40F"); diff --git a/work/hello-1/hello-2.c b/work/hello-1/hello-2.c new file mode 100644 index 0000000000000000000000000000000000000000..336c9c3b40aa4af5d606d9d00e7b2a4afc9db85b --- /dev/null +++ b/work/hello-1/hello-2.c @@ -0,0 +1,24 @@ +/* + * hello-1.c - The simplest kernel module. + */ +#include <linux/init.h> /* Needed for the macros */ +#include <linux/module.h> /* Needed by all modules */ +#include <linux/printk.h> /* Needed for pr_info() */ + +static int __init hello_2_init(void) +{ + pr_info("Hello world 2.\n"); + + /* A non 0 return means init_module failed; module can't be loaded. */ + return 0; +} + +static void __exit hello_2_exit(void) +{ + pr_info("Goodbye world 2.\n"); +} + +module_init(hello_2_init); +module_exit(hello_2_exit); + +MODULE_LICENSE("GPL"); diff --git a/work/hello-1/hello-2.mod.c b/work/hello-1/hello-2.mod.c new file mode 100644 index 0000000000000000000000000000000000000000..44d3a1a2a1ea0a3857782c35196cbbe2b7b56af2 --- /dev/null +++ b/work/hello-1/hello-2.mod.c @@ -0,0 +1,47 @@ +#include <linux/module.h> +#define INCLUDE_VERMAGIC +#include <linux/build-salt.h> +#include <linux/elfnote-lto.h> +#include <linux/export-internal.h> +#include <linux/vermagic.h> +#include <linux/compiler.h> + +#ifdef CONFIG_UNWINDER_ORC +#include <asm/orc_header.h> +ORC_HEADER; +#endif + +BUILD_SALT; +BUILD_LTO_INFO; + +MODULE_INFO(vermagic, VERMAGIC_STRING); +MODULE_INFO(name, KBUILD_MODNAME); + +__visible struct module __this_module +__section(".gnu.linkonce.this_module") = { + .name = KBUILD_MODNAME, + .init = init_module, +#ifdef CONFIG_MODULE_UNLOAD + .exit = cleanup_module, +#endif + .arch = MODULE_ARCH_INIT, +}; + +#ifdef CONFIG_RETPOLINE +MODULE_INFO(retpoline, "Y"); +#endif + + + +static const struct modversion_info ____versions[] +__used __section("__versions") = { + { 0x5b8239ca, "__x86_return_thunk" }, + { 0xbdfb6dbb, "__fentry__" }, + { 0x122c3a7e, "_printk" }, + { 0x76800044, "module_layout" }, +}; + +MODULE_INFO(depends, ""); + + +MODULE_INFO(srcversion, "429C9C7906F80F08EC81A8E"); diff --git a/work/hello-1/hello-3.c b/work/hello-1/hello-3.c new file mode 100644 index 0000000000000000000000000000000000000000..28b7f9e7eaab56730724cf068739aea0818b7499 --- /dev/null +++ b/work/hello-1/hello-3.c @@ -0,0 +1,26 @@ +/* + * hello-1.c - The simplest kernel module. + */ +#include <linux/init.h> /* Needed for the macros */ +#include <linux/module.h> /* Needed by all modules */ +#include <linux/printk.h> /* Needed for pr_info() */ + +static int hello3_data __initdata = 3; + +static int __init hello_3_init(void) +{ + pr_info("Hello world %d.\n", hello3_data); + + /* A non 0 return means init_module failed; module can't be loaded. */ + return 0; +} + +static void __exit hello_3_exit(void) +{ + pr_info("Goodbye world 3.\n"); +} + +module_init(hello_3_init); +module_exit(hello_3_exit); + +MODULE_LICENSE("GPL"); diff --git a/work/hello-1/hello-3.mod.c b/work/hello-1/hello-3.mod.c new file mode 100644 index 0000000000000000000000000000000000000000..ab3d9de182bf22cbeeaf7a256e4cff4aacd51d93 --- /dev/null +++ b/work/hello-1/hello-3.mod.c @@ -0,0 +1,47 @@ +#include <linux/module.h> +#define INCLUDE_VERMAGIC +#include <linux/build-salt.h> +#include <linux/elfnote-lto.h> +#include <linux/export-internal.h> +#include <linux/vermagic.h> +#include <linux/compiler.h> + +#ifdef CONFIG_UNWINDER_ORC +#include <asm/orc_header.h> +ORC_HEADER; +#endif + +BUILD_SALT; +BUILD_LTO_INFO; + +MODULE_INFO(vermagic, VERMAGIC_STRING); +MODULE_INFO(name, KBUILD_MODNAME); + +__visible struct module __this_module +__section(".gnu.linkonce.this_module") = { + .name = KBUILD_MODNAME, + .init = init_module, +#ifdef CONFIG_MODULE_UNLOAD + .exit = cleanup_module, +#endif + .arch = MODULE_ARCH_INIT, +}; + +#ifdef CONFIG_RETPOLINE +MODULE_INFO(retpoline, "Y"); +#endif + + + +static const struct modversion_info ____versions[] +__used __section("__versions") = { + { 0x5b8239ca, "__x86_return_thunk" }, + { 0xbdfb6dbb, "__fentry__" }, + { 0x122c3a7e, "_printk" }, + { 0x76800044, "module_layout" }, +}; + +MODULE_INFO(depends, ""); + + +MODULE_INFO(srcversion, "C0F43BFE7A1B717A042758A"); diff --git a/work/hello-1/hello-5.c b/work/hello-1/hello-5.c new file mode 100644 index 0000000000000000000000000000000000000000..01a180b08883b4e66ea94d0831978963595b40f1 --- /dev/null +++ b/work/hello-1/hello-5.c @@ -0,0 +1,68 @@ +/* + * hello-5.c - Demonstrates command line argument passing to a module. + */ +#include <linux/init.h> +#include <linux/kernel.h> /* for ARRAY_SIZE() */ +#include <linux/module.h> +#include <linux/moduleparam.h> +#include <linux/printk.h> +#include <linux/stat.h> + +MODULE_LICENSE("GPL"); + +static short int myshort = 1; +static int myint = 420; +static long int mylong = 9999; +static char *mystring = "blah"; +static int myintarray[2] = { 420, 420 }; +static int arr_argc = 0; + +/* module_param(foo, int, 0000) + * The first param is the parameters name. + * The second param is its data type. + * The final argument is the permissions bits, + * for exposing parameters in sysfs (if non-zero) at a later stage. + */ +module_param(myshort, short, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP); +MODULE_PARM_DESC(myshort, "A short integer"); +module_param(myint, int, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH); +MODULE_PARM_DESC(myint, "An integer"); +module_param(mylong, long, S_IRUSR); +MODULE_PARM_DESC(mylong, "A long integer"); +module_param(mystring, charp, 0000); +MODULE_PARM_DESC(mystring, "A character string"); + +/* module_param_array(name, type, num, perm); + * The first param is the parameter's (in this case the array's) name. + * The second param is the data type of the elements of the array. + * The third argument is a pointer to the variable that will store the number + * of elements of the array initialized by the user at module loading time. + * The fourth argument is the permission bits. + */ +module_param_array(myintarray, int, &arr_argc, 0000); +MODULE_PARM_DESC(myintarray, "An array of integers"); + +static int __init hello_5_init(void) +{ + int i; + + pr_info("Hello, world 5\n=============\n"); + pr_info("myshort is a short integer: %hd\n", myshort); + pr_info("myint is an integer: %d\n", myint); + pr_info("mylong is a long integer: %ld\n", mylong); + pr_info("mystring is a string: %s\n", mystring); + + for (i = 0; i < ARRAY_SIZE(myintarray); i++) + pr_info("myintarray[%d] = %d\n", i, myintarray[i]); + + pr_info("got %d arguments for myintarray.\n", arr_argc); + return 0; +} + +static void __exit hello_5_exit(void) +{ + pr_info("Goodbye, world 5\n"); +} + +module_init(hello_5_init); +module_exit(hello_5_exit); \ No newline at end of file diff --git a/work/hello-1/hello-5.mod.c b/work/hello-1/hello-5.mod.c new file mode 100644 index 0000000000000000000000000000000000000000..beaec194729cd481d28087cd9690204d126416d6 --- /dev/null +++ b/work/hello-1/hello-5.mod.c @@ -0,0 +1,52 @@ +#include <linux/module.h> +#define INCLUDE_VERMAGIC +#include <linux/build-salt.h> +#include <linux/elfnote-lto.h> +#include <linux/export-internal.h> +#include <linux/vermagic.h> +#include <linux/compiler.h> + +#ifdef CONFIG_UNWINDER_ORC +#include <asm/orc_header.h> +ORC_HEADER; +#endif + +BUILD_SALT; +BUILD_LTO_INFO; + +MODULE_INFO(vermagic, VERMAGIC_STRING); +MODULE_INFO(name, KBUILD_MODNAME); + +__visible struct module __this_module +__section(".gnu.linkonce.this_module") = { + .name = KBUILD_MODNAME, + .init = init_module, +#ifdef CONFIG_MODULE_UNLOAD + .exit = cleanup_module, +#endif + .arch = MODULE_ARCH_INIT, +}; + +#ifdef CONFIG_RETPOLINE +MODULE_INFO(retpoline, "Y"); +#endif + + + +static const struct modversion_info ____versions[] +__used __section("__versions") = { + { 0x5b8239ca, "__x86_return_thunk" }, + { 0x18121e8f, "param_array_ops" }, + { 0xd61b6a34, "param_ops_int" }, + { 0x65e16dde, "param_ops_charp" }, + { 0x16db37eb, "param_ops_long" }, + { 0xe284dd72, "param_ops_short" }, + { 0xbdfb6dbb, "__fentry__" }, + { 0x122c3a7e, "_printk" }, + { 0x76800044, "module_layout" }, +}; + +MODULE_INFO(depends, ""); + + +MODULE_INFO(srcversion, "9FCBEE8537BAB4A242DD00B"); diff --git a/work/hello-1/hello.c b/work/hello-1/hello.c new file mode 100644 index 0000000000000000000000000000000000000000..736356e7195b4e76efac768fae462a75f30e0809 --- /dev/null +++ b/work/hello-1/hello.c @@ -0,0 +1,7 @@ +#include <stdio.h> + +int main(void) +{ + printf("hello"); + return 0; +} \ No newline at end of file diff --git a/work/hello-1/modules.order b/work/hello-1/modules.order new file mode 100644 index 0000000000000000000000000000000000000000..07bfd4243bf37eeca62142db31ac55ef9c9cce84 --- /dev/null +++ b/work/hello-1/modules.order @@ -0,0 +1,4 @@ +/root/Desktop/asee/work/hello-1/hello-1.o +/root/Desktop/asee/work/hello-1/hello-2.o +/root/Desktop/asee/work/hello-1/hello-3.o +/root/Desktop/asee/work/hello-1/hello-5.o diff --git a/work/tp1/Makefile b/work/tp1/Makefile new file mode 100644 index 0000000000000000000000000000000000000000..837cdd12da881eadb105df5bc0a804298b4e1d7d --- /dev/null +++ b/work/tp1/Makefile @@ -0,0 +1,9 @@ +KDIR=../../build/kvm/ + +obj-m += chardev.o +PWD := $(CURDIR) + +all: + make -C $(KDIR) M=$(PWD) modules +clean: + make -C $(KDIR) M=$(PWD) clean diff --git a/work/tp1/chardev.c b/work/tp1/chardev.c new file mode 100644 index 0000000000000000000000000000000000000000..e249f14754d7d4d278a298470e20154c732601c0 --- /dev/null +++ b/work/tp1/chardev.c @@ -0,0 +1,184 @@ +/* + * chardev.c: Creates a read-only char device that says how many times + * you have read from the dev file + */ + +#include <linux/atomic.h> +#include <linux/cdev.h> +#include <linux/delay.h> +#include <linux/device.h> +#include <linux/fs.h> +#include <linux/init.h> +#include <linux/kernel.h> /* for sprintf() */ +#include <linux/module.h> +#include <linux/printk.h> +#include <linux/types.h> +#include <linux/uaccess.h> /* for get_user and put_user */ +#include <linux/version.h> + +#include <asm/errno.h> + +/* Prototypes - this would normally go in a .h file */ +static int device_open(struct inode *, struct file *); +static int device_release(struct inode *, struct file *); +static ssize_t device_read(struct file *, char __user *, size_t, loff_t *); +static ssize_t device_write(struct file *, const char __user *, size_t, + loff_t *); + +#define SUCCESS 0 +#define DEVICE_NAME "asee_mod" /* Dev name as it appears in /proc/devices */ +#define BUF_LEN 16 /* Max length of the message from the device */ + +/* Global variables are declared as static, so are global within the file. */ + +static int major; /* major number assigned to our device driver */ + +enum { + CDEV_NOT_USED = 0, + CDEV_EXCLUSIVE_OPEN = 1, +}; + +/* Is device open? Used to prevent multiple access to device */ +static atomic_t already_open = ATOMIC_INIT(CDEV_NOT_USED); + +static char msg[BUF_LEN + 1]; /* The msg the device will give when asked */ + +static struct class *cls; + +static struct file_operations chardev_fops = { + .read = device_read, + .write = device_write, + .open = device_open, + .release = device_release, +}; + +static int __init chardev_init(void) +{ + major = register_chrdev(0, DEVICE_NAME, &chardev_fops); + + if (major < 0) { + pr_alert("Registering char device failed with %d\n", major); + return major; + } + + pr_info("I was assigned major number %d.\n", major); + +#if LINUX_VERSION_CODE >= KERNEL_VERSION(6, 4, 0) + cls = class_create(DEVICE_NAME); +#else + cls = class_create(THIS_MODULE, DEVICE_NAME); +#endif + device_create(cls, NULL, MKDEV(major, 0), NULL, DEVICE_NAME); + + pr_info("Device created on /dev/%s\n", DEVICE_NAME); + + return SUCCESS; +} + +static void __exit chardev_exit(void) +{ + device_destroy(cls, MKDEV(major, 0)); + class_destroy(cls); + + /* Unregister the device */ + unregister_chrdev(major, DEVICE_NAME); +} + +/* Methods */ + +/* Called when a process tries to open the device file, like + * "sudo cat /dev/chardev" + */ +static int device_open(struct inode *inode, struct file *file) +{ + if (atomic_cmpxchg(&already_open, CDEV_NOT_USED, CDEV_EXCLUSIVE_OPEN)) + return -EBUSY; + + + pr_info("%s\n", msg); + try_module_get(THIS_MODULE); + + return SUCCESS; +} + +/* Called when a process closes the device file. */ +static int device_release(struct inode *inode, struct file *file) +{ + /* We're now ready for our next caller */ + atomic_set(&already_open, CDEV_NOT_USED); + + /* Decrement the usage count, or else once you opened the file, you will + * never get rid of the module. + */ + module_put(THIS_MODULE); + + return SUCCESS; +} + +/* Called when a process, which already opened the dev file, attempts to + * read from it. + */ +static int last_writen_bytes; +static int bytes_in_buffer = 0; +static ssize_t device_read(struct file *filp, /* see include/linux/fs.h */ + char __user *buffer, /* buffer to fill with data */ + size_t length, /* length of the buffer */ + loff_t *offset) +{ + /* Number of bytes actually written to the buffer */ + int bytes_read = 0; + char *msg_ptr = msg; + + /* Actually put the data into the buffer */ + while (bytes_in_buffer > 0) { + if (last_writen_bytes >= BUF_LEN) { + last_writen_bytes = 0; + } + /* The buffer is in the user data segment, not the kernel + * segment so "*" assignment won't work. We have to use + * put_user which copies data from the kernel data segment to + * the user data segment. + */ + + put_user(*(msg_ptr + last_writen_bytes), buffer++); + // Try to clear the read + *(msg_ptr + last_writen_bytes) = '\0'; + last_writen_bytes++; + bytes_in_buffer--; + bytes_read++; + } + + *offset = last_writen_bytes; + + /* Most read functions return the number of bytes put into the buffer. */ + return bytes_read; +} + +/* Called when a process writes to dev file: echo "hi" > /dev/hello */ +static ssize_t device_write(struct file *filp, const char __user *buff, + size_t len, loff_t *off) +{ + int bytes_writen = 0; + + int current_bytes = last_writen_bytes; + + for (int cpt = 0; cpt < len; cpt++) { + if (current_bytes >= BUF_LEN) { + current_bytes = 0; + } + get_user(*(msg + current_bytes), buff + cpt); + current_bytes++; + bytes_writen++; + bytes_in_buffer++; + } + + last_writen_bytes = current_bytes; + *off = last_writen_bytes; + + return bytes_writen; +} + +module_init(chardev_init); +module_exit(chardev_exit); + +MODULE_LICENSE("GPL"); \ No newline at end of file diff --git a/work/tp1/chardev.mod.c b/work/tp1/chardev.mod.c new file mode 100644 index 0000000000000000000000000000000000000000..c424c1d8759fc2dc690a3b5054a6272c70013629 --- /dev/null +++ b/work/tp1/chardev.mod.c @@ -0,0 +1,57 @@ +#include <linux/module.h> +#define INCLUDE_VERMAGIC +#include <linux/build-salt.h> +#include <linux/elfnote-lto.h> +#include <linux/export-internal.h> +#include <linux/vermagic.h> +#include <linux/compiler.h> + +#ifdef CONFIG_UNWINDER_ORC +#include <asm/orc_header.h> +ORC_HEADER; +#endif + +BUILD_SALT; +BUILD_LTO_INFO; + +MODULE_INFO(vermagic, VERMAGIC_STRING); +MODULE_INFO(name, KBUILD_MODNAME); + +__visible struct module __this_module +__section(".gnu.linkonce.this_module") = { + .name = KBUILD_MODNAME, + .init = init_module, +#ifdef CONFIG_MODULE_UNLOAD + .exit = cleanup_module, +#endif + .arch = MODULE_ARCH_INIT, +}; + +#ifdef CONFIG_RETPOLINE +MODULE_INFO(retpoline, "Y"); +#endif + + + +static const struct modversion_info ____versions[] +__used __section("__versions") = { + { 0x122c3a7e, "_printk" }, + { 0x47143bb3, "try_module_get" }, + { 0x73895700, "__register_chrdev" }, + { 0xfb890f0b, "class_create" }, + { 0x41b15bc9, "device_create" }, + { 0xf23bcaeb, "device_destroy" }, + { 0xfdfe3852, "class_destroy" }, + { 0x6bc3fbc0, "__unregister_chrdev" }, + { 0xbdfb6dbb, "__fentry__" }, + { 0xc3aaf0a9, "__put_user_1" }, + { 0x5b8239ca, "__x86_return_thunk" }, + { 0x167e7f9d, "__get_user_1" }, + { 0xab632ed, "module_put" }, + { 0x76800044, "module_layout" }, +}; + +MODULE_INFO(depends, ""); + + +MODULE_INFO(srcversion, "9201228D14671D604AADDD7"); diff --git a/work/tp1/modules.order b/work/tp1/modules.order new file mode 100644 index 0000000000000000000000000000000000000000..c25b792bddaa43ba77ecb2e4d91463ba2194cc71 --- /dev/null +++ b/work/tp1/modules.order @@ -0,0 +1 @@ +/root/Desktop/asee/work/tp1/chardev.o