270 likes | 285 Vues
Dive into the core components of an operating system with this guide on kernel modules, system calls, and interacting with hardware using Proc FS. Learn how to create and use modules, write system calls, and access system information.
E N D
Project 2 Kernel modules, Proc FS
Project 2 • Specification • Part1 system call • Part2 simple kernel module • Part1 & Part2 are Due on 10/02 • Part3 A little complicated kernel module
Kernel • What is kernel? • The core part of a operating system • What does kernel do? • Setting up virtual memory • Interacting with hardware • Much more • Linux Kernel • uname -r
Kernel modules • What is a module? • Module is like a plugin or addons • Once a module is "plugged", it works in the kernel space • Why do we need modules • Or compile all the things into the kernel and only use some? • How to use a module • insmod,rmmod
Kernel space • The kernel space has full access to all the hardware...everything! • If there is something wrong in kernel space, your system dead.
User space • Has no access to hardware. • If something wrong in userspace, normally your system is still good to work.
Programming in kernel • The kernel can not use the C libraries written for user space • No malloc(), no free(), no printf() • kmalloc(), kfree(), printk()
System calls • User space program doesn't have the access to the hardware--YES • Then how can we create new files, print to screen?--System calls • System calls are functions provided by the kernel to user-space. It is the only way from usersapce to kernel.
Write a module • #include <linux/init.h> • #include <linux/module.h> • MODULE_LICENSE("Dual BSD/GPL"); • static int hello_init(void) • { printk(KERN_ALERT "Hello, World!\n"); return 0; • } • static void hello_exit(void) • { printk(KERN_ALERT "Goodbye, sleepy world!\n"); • } • module_init(hello_init); • module_exit(hello_exit);
Compile the module • Makefile ifneq ($(KERNELRELEASE),) obj-m := hello.o else KERNELDIR ?= /lib/modules/`uname -r`/build/ PWD := `pwd` default: $(MAKE) -C $(KERNELDIR) M=$(PWD) modules clean: $(MAKE) -C $(KERNELDIR) M=$(PWD) clean endif
Run the module • You can insert the module by: insmod hello.ko • You can remove the module by: rmmod hello • You can list all the modules by: lsmod
There is a video showing you the complete procedure. http://www.youtube.com/watch?v=tb_KX-iKrjY
Where is the words • It is in /var/log/syslog • Inform you when modules are inserted and removed • Contain the output of printk() • tail /var/log/syslog • See last a few messages • dmesg
proc fs • A special file system that present various system information. (cpuinfo diskstats dma) • A way to exchange info between kernel level and user level • http://tldp.org/LDP/lkmpg/2.6/html/lkmpg.html#AEN708
Old way • Create an entry • create_proc_read_entry(PROC_NAME, 0666, 0, proc_read, 0) • Remove an entry • remove_proc_entry(PROC_NAME, NULL);
Old way • int proc_read(char *page, char **start, off_t offset, int count, int *eof, void *data) • return the length of bytes being read • keep track of the length • Almost abandoned! • Use seq_file insterface now.
New way • Use seq_file interface and proc_create(), proc_create_data functions instead. • https://lkml.org/lkml/2013/4/11/215
seq_file • A standard and safe method.(Alexander Viro) struct seq_operations; struct file_operations;
struct seq_operations • struct seq_operations { void * (*start) (struct seq_file *m, loff_t *pos); void (*stop) (struct seq_file *m, void *v); void * (*next) (struct seq_file *m, void *v, loff_t *pos); int (*show) (struct seq_file *m, void *v); };
struct file_operation struct file_operations exam_seq_file_ops = { .owner = THIS_MODULE, .open = exam_seq_open, .read = seq_read, .llseek = seq_lseek, .release = seq_release };
struct seq_operations exam_seq_ops = { .start = exam_seq_start, .stop = exam_seq_stop, .next = exam_seq_next, .show = exam_seq_show }; static int exam_seq_open(struct inode *inode, struct file *file) { return seq_open(file, &exam_seq_ops); };
Create an entry • struct proc_dir_entry *entry; entry = proc_create("exam_seq_file", 0, NULL, &exam_seq_file_ops); if (entry == NULL) return -ENOMEM;
A simply way • Only define show() function. • Use single_open() and single_release().
static int hello_proc_show(struct seq_file *m, void *v) { seq_printf(m, "Hello proc!\n"); return 0; } static int hello_proc_open(struct inode *inode, struct file *file) { return single_open(file, hello_proc_show, NULL); } static const struct file_operations hello_proc_fops = { .owner = THIS_MODULE, .open = hello_proc_open, .read = seq_read, .llseek = seq_lseek, .release = single_release, };
#include <linux/module.h> #include <linux/proc_fs.h> #include <linux/seq_file.h> MODULE_LICENSE("GPL"); static int hello_proc_show(struct seq_file *m, void *v) { seq_printf(m, "Hello proc!\n"); return 0; } static int hello_proc_open(struct inode *inode, struct file *file) { return single_open(file, hello_proc_show, NULL); } static const struct file_operations hello_proc_fops = { .owner = THIS_MODULE, .open = hello_proc_open, .read = seq_read, .release = single_release, }; static int __init hello_proc_init(void) { proc_create("hello_proc", 0, NULL, &hello_proc_fops); return 0; } static void __exit hello_proc_exit(void) { remove_proc_entry("hello_proc", NULL); } module_init(hello_proc_init); module_exit(hello_proc_exit);
Q & A • I got a lot more than 20 system calls? • 20 more system calls than the empty program.(26, 39?)
Q & A • How to handle local time issue? • Hard code the time offset by direct number is not a good way. • Try to use the kernel variable sys_tz.