Makefile hello world
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 |
cat > Makefile << "EOF" CONFIG_MODULE_SIG=n CURRENT = $(shell uname -r) KDIR = /lib/modules/$(CURRENT)/build PWD = $(shell pwd) DEST = /lib/modules/$(CURRENT)/misc TARGET = hello_printk obj-m := $(TARGET).o all: default clean #all: default default: $(MAKE) -C $(KDIR) M=$(PWD) modules install: cp -v $(TARGET).ko $(DEST) # /sbin/depmod -v | grep $(TARGET) /sbin/depmod /sbin/insmod $(TARGET).ko /sbin/lsmod | grep $(TARGET) uninstall: /sbin/rmmod $(TARGET) rm -v $(DEST)/$(TARGET).ko /sbin/depmod clean: @rm -f *.o .*.cmd .*.flags *.mod.c *.order @rm -f .*.*.cmd *.symvers *~ *.*~ @rm -fR .tmp* *.mod @rm -rf .tmp_versions disclean: clean @rm -f *.ko EOF # Исправить восемь пробелов на TAB sed -i 's/ /\t\t/g' Makefile |
hello world c
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 |
cat > hello_printk.c << "EOF" #include <linux/module.h> MODULE_LICENSE("GPL"); MODULE_AUTHOR("LALA <mail@gmail.com>>"); static int __init hello_init(void) { printk("Hello, world!\n"); return 0; } static void __exit hello_exit(void) { printk("Goodbye, world!\n"); } module_init(hello_init); module_exit(hello_exit); EOF make file hello_print.ko modinfo ./hello_print.ko modprobe ./hello_print.ko rmmod hello_print |
simple tty Makefile
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 |
cat > Makefile << "EOF" CONFIG_MODULE_SIG=n CURRENT = $(shell uname -r) KDIR = /lib/modules/$(CURRENT)/build PWD = $(shell pwd) DEST = /lib/modules/$(CURRENT)/misc TARGET = simple_tty obj-m := $(TARGET).o all: default clean default: $(MAKE) -C $(KDIR) M=$(PWD) modules install: cp -v $(TARGET).ko $(DEST) /sbin/depmod /sbin/insmod $(TARGET).ko /sbin/lsmod | grep $(TARGET) uninstall: /sbin/rmmod $(TARGET) rm -v $(DEST)/$(TARGET).ko /sbin/depmod clean: @rm -f *.o .*.cmd .*.flags *.mod.c *.order @rm -f .*.*.cmd *.symvers *~ *.*~ @rm -fR .tmp* *.mod @rm -rf .tmp_versions disclean: clean @rm -f *.ko EOF |
symple tty c
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 |
cat > simple_tty.c << "EOF" #include <linux/module.h> #include <linux/kernel.h> #include <linux/init.h> #include <linux/tty.h> #include <linux/fs.h> #define DRIVER_NAME "simple_tty" #define DEVICE_NAME "ttySIMPLE" MODULE_LICENSE("GPL"); MODULE_AUTHOR("LALA <mail@gmail.com>"); MODULE_DESCRIPTION("Simple TTY Driver"); MODULE_VERSION("1.0"); static struct tty_driver *simple_tty_driver; static struct tty_port *simple_tty_port; // Pointer to tty_port static int simple_tty_open(struct tty_struct *tty, struct file *file) { printk(KERN_INFO "simple_tty: open()\n"); return 0; } static void simple_tty_close(struct tty_struct *tty, struct file *file) { printk(KERN_INFO "simple_tty: close()\n"); } static ssize_t simple_tty_write(struct tty_struct *tty, const unsigned char *buf, size_t count) { size_t i; printk(KERN_INFO "simple_tty: write()\n"); for (i = 0; i < count; i++) { printk(KERN_INFO "simple_tty: %c\n", buf[i]); } return count; } static struct tty_operations simple_tty_ops = { .open = simple_tty_open, .close = simple_tty_close, .write = simple_tty_write, }; static int __init simple_tty_init(void) { int retval; // Allocate memory for the tty_port structure simple_tty_port = kzalloc(sizeof(struct tty_port), GFP_KERNEL); if (!simple_tty_port) { printk(KERN_ERR "simple_tty: failed to allocate tty port\n"); return -ENOMEM; } // Initialize the tty_port structure tty_port_init(simple_tty_port); // Register TTY driver simple_tty_driver = tty_alloc_driver(1, TTY_DRIVER_RESET_TERMIOS); if (!simple_tty_driver) { printk(KERN_ERR "simple_tty: failed to allocate tty driver\n"); kfree(simple_tty_port); // Free allocated tty_port on error return -ENOMEM; } simple_tty_driver->owner = THIS_MODULE; simple_tty_driver->driver_name = DRIVER_NAME; simple_tty_driver->name = DEVICE_NAME; simple_tty_driver->major = 0; // Auto-assign major number simple_tty_driver->type = TTY_DRIVER_TYPE_SERIAL; simple_tty_driver->subtype = SERIAL_TYPE_NORMAL; simple_tty_driver->init_termios = tty_std_termios; simple_tty_driver->flags = TTY_DRIVER_REAL_RAW; // Set the ports field of the driver simple_tty_driver->ports = &simple_tty_port; // Assign the port tty_set_operations(simple_tty_driver, &simple_tty_ops); // Register the driver in the kernel retval = tty_register_driver(simple_tty_driver); if (retval) { printk(KERN_ERR "simple_tty: failed to register tty driver\n"); kfree(simple_tty_port); // Free allocated tty_port on error return retval; } printk(KERN_INFO "simple_tty: driver registered\n"); return 0; } static void __exit simple_tty_exit(void) { tty_unregister_driver(simple_tty_driver); tty_port_destroy(simple_tty_port); // Free the tty_port kfree(simple_tty_port); // Free allocated tty_port memory printk(KERN_INFO "simple_tty: driver unregistered\n"); } module_init(simple_tty_init); module_exit(simple_tty_exit); EOF Описание драйвера: Основные структуры: tty_driver — структура, которая описывает драйвер устройства TTY. tty_operations — набор операций, которые драйвер поддерживает (открытие, запись, закрытие и т.д.). Функции драйвера: simple_tty_open() — вызывается при открытии устройства. simple_tty_close() — вызывается при закрытии устройства. simple_tty_write() — функция записи данных в устройство. Регистрация драйвера: Драйвер регистрируется с помощью tty_register_driver(), после чего его можно использовать как стандартное устройство TTY. Деконструкция драйвера: tty_unregister_driver() — используется при выгрузке модуля для корректной очистки драйвера. make modprobe simple_tty.ko dmesg | grep simple_tty echo "test" > /dev/ttySIMPLE lsmod | grep simple_tty rmmod simple_tty |