Project 2 Kernel modules Proc FS Project 2

  • Slides: 27
Download presentation
Project 2 Kernel modules, Proc FS

Project 2 Kernel modules, Proc FS

Project 2 • Specification • Part 1 • Part 2 system call simple kernel

Project 2 • Specification • Part 1 • Part 2 system call simple kernel module – Part 1 & Part 2 are Due on 10/02 • Part 3 A little complicated kernel module

Kernel • What is kernel? – The core part of a operating system •

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

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. .

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,

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

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 •

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");

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

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 •

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.

• There is a video showing you the complete procedure. http: //www. youtube. com/watch? v=tb_KX-i. Krj. Y

Where is the words • It is in /var/log/syslog – Inform you when modules

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

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. ht ml#AEN 708

Old way • Create an entry – create_proc_read_entry(PROC_NAME, 0666, 0, proc_read, 0) • Remove

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,

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.

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;

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);

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_operations exam_seq_file_ops = {. owner = THIS_MODULE, . open = exam_seq_open, . read

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

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

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().

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_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

#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

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

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.