270 likes | 438 Views
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
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.