intro to kernel modules and /proc

47
1 Intro to Kernel Modules and /proc Sarah Diesburg CS 3430 Operating Systems

Upload: others

Post on 08-Jun-2022

6 views

Category:

Documents


0 download

TRANSCRIPT

Page 1: Intro to Kernel Modules and /proc

1

Intro to Kernel Modules and /proc

Sarah Diesburg CS 3430 Operating Systems

Page 2: Intro to Kernel Modules and /proc

Kernel Modules

Or “drivers”, if you prefer…

2

Page 3: Intro to Kernel Modules and /proc

Kernel Module

A kernel module is a portion of kernel functionality that can be dynamically loaded into the operating system at run-time

Example USB drivers File system drivers Disk drivers Cryptographic libraries

3

Page 4: Intro to Kernel Modules and /proc

Why not just compile everything into the kernel? Each machine only needs a certain number

of drivers For example, should not have to load every single

motherboard driver Load only the modules you need Smaller system footprint

Dynamically load modules for new devices Camera, new printer, etc.

4

Page 5: Intro to Kernel Modules and /proc

Creating a Kernel Module

Hello world example

5

Page 6: Intro to Kernel Modules and /proc

Sample Kernel Module: hello.c

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

6

Page 7: Intro to Kernel Modules and /proc

Sample Kernel Module: hello.c

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

7

Module headers

Page 8: Intro to Kernel Modules and /proc

Sample Kernel Module: hello.c

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

8

License declaration

Page 9: Intro to Kernel Modules and /proc

Sample Kernel Module: hello.c

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

9

Initialization function, runs when module

loaded

Tells kernel which function to run on

load

Page 10: Intro to Kernel Modules and /proc

Sample Kernel Module: hello.c

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

10

Exit function, runs when module exits

Tells kernel which function to run on

exit

Page 11: Intro to Kernel Modules and /proc

Sample Kernel Module: Makefile

ifneq ($(KERNELRELEASE),) obj-m := hello.o else KERNELDIR ?= \ /lib/modules/`uname -r`/build/ PWD := `pwd` default: $(MAKE) -C $(KERNELDIR) \ M=$(PWD) modules endif clean: rm -f *.ko *.o Module* *mod*

11

Page 12: Intro to Kernel Modules and /proc

/usr/src/hello$> make

Creates hello.ko – This is the finished kernel

module!

Compile the Kernel Module

12

Page 13: Intro to Kernel Modules and /proc

Inserting and Removing the Module

insmod – insert a module

/usr/src/hello$> sudo insmod hello.ko

rmmod – remove a module

/usr/src/hello$> sudo rmmod hello.ko

13

Page 14: Intro to Kernel Modules and /proc

Listing Modules

lsmod – lists all running modules

/usr/src/hello$>lsmod

14

Page 15: Intro to Kernel Modules and /proc

Where is it printing?

Look inside /var/log/syslog Hint – to watch syslog in realtime, issue the

following command in a second terminal:

$> sudo tail –f /var/log/syslog

Demo…

15

Page 16: Intro to Kernel Modules and /proc

Kernel Module vs User Application

All kernel modules are event-driven Register functions Wait for requests and service them Server/client model

No standard C library Why not?

No floating point support Segmentation fault could freeze/crash your

system Kernel ‘oops’!

16

Page 17: Intro to Kernel Modules and /proc

Kernel Functions

printk() instead of printf() kmalloc() instead of malloc() kfree() instead of free()

Where can I find definitions of these kernel

functions?

17

Page 18: Intro to Kernel Modules and /proc

Kernel manpages

Section 9 of manpages Use manpages on prog1

$> man printk

18

Page 19: Intro to Kernel Modules and /proc

Kernel Headers

#include <linux/init.h> /* module stuff */ #include <linux/module.h> /* module stuff */ #include <asm/semaphore.h> /* locks */ #include <linux/list.h> /* linked lists */ #include <linux/string.h> /* string functions! */

Look inside linux-2.6.39.4/include/ for

more… Google is also your friend

19

Page 20: Intro to Kernel Modules and /proc

Project 2: Kernel Modules

20

Page 21: Intro to Kernel Modules and /proc

procfs Kernel Module

procfs “hello world” example Creates a read-only procfs entry

Steps Create entry in module_init function Register reading function with procfs_read Delete entry in module_cleanup function

Reference Linux Kernel Module Programming Guide: Proc

FS

21

Page 22: Intro to Kernel Modules and /proc

Procfs: Headers and Global Data

#include <linux/module.h>

#include <linux/kernel.h>

#include <linux/proc_fs.h>

MODULE_LICENSE(“GPL”);

#define ENTRY_NAME “helloworld”

#define PERMS 0644

#define PARENT NULL

struct proc_dir_entry *proc_entry;

int procfile_read(char *buf, char **buf_location, off_t offset, int buffer_length, int *eof, void *data);

22

Page 23: Intro to Kernel Modules and /proc

Procfs: Creation

int hello_proc_init(void) { proc_entry = create_proc_entry(ENTRY_NAME, PERMS,PARENT); /* check proc_entry != NULL */ proc_entry->read_proc = procfile_read; proc_entry->write_proc = procfile_write; proc_entry->mode = S_IFREG | S_IRUGO; proc_entry->uid = 0; proc_entry->gid = 0; proc_entry->size = 11; printk(“/proc/%s created\n”, ENTRY_NAME); return 0; }

23

Page 24: Intro to Kernel Modules and /proc

Procfs: Reading

int procfile_read(char *buf, char **buf_location, off_t offset, int buffer_length, int *eof, void *data)

{ int ret; printk(“/proc/%s read called.\n”, ENTRY_NAME); /* Setting eof. We exhaust all data in one shot

*/ *eof = 1; ret = sprintf(buf, “Hello World!\n”); return ret; }

24

Page 25: Intro to Kernel Modules and /proc

Procfs: Writing

int procfile_write( struct file *file, const char __user *buffer, unsigned long count, void *data )

{

char *page; /* don't touch */

if (!page)

return -ENOMEM;

/* Copy the data from the user space. Data is placed in page. */

if (copy_from_user(page, buffer, count)) {

vfree(page);

return -EFAULT;

}

/* Now do something with the data, here we just print it */

printk( "Got [%s]\n", page);

vfree(page);

return count;

}

25

Page 26: Intro to Kernel Modules and /proc

Procfs: Deletion

void hello_proc_exit(void)

{

remove_proc_entry(ENTRY_NAME, NULL);

printk(“Removing /proc/%s.\n”, ENTRY_NAME);

}

26

Page 27: Intro to Kernel Modules and /proc

Procfs: Registration

module_init(hello_proc_init);

module_exit(hello_proc_exit);

27

Page 28: Intro to Kernel Modules and /proc

Testing Procfs

$> sudo insmod hello_proc.ko

$> sudo tail /var/log/syslog

$> cat /proc/helloworld

$> echo 2 > /proc/helloworld

$> sudo rmmod hello_proc

28

Page 29: Intro to Kernel Modules and /proc

Part 2: Backwards

You will write your own proc module called remember that Allows the user to write a string to /proc/remember

(max length 80) Allows the user to read /proc/remember and get

back the string that was just added, only backwards

29

Page 30: Intro to Kernel Modules and /proc

Backwards Example

$> echo “Hello there” > /proc/remember $> cat /proc/backwards ereht olleH $>

30

Page 31: Intro to Kernel Modules and /proc

Part 3: Printer Scheduling

31

Page 32: Intro to Kernel Modules and /proc

Part 3: The Penguin Printer

Implement a /proc kernel module that simulates a busy printer

Your /proc/penguin file must accept writes of different printer job sizes Each dish takes some time to process

Your /proc/penguin file must return status information of the printer when read

32

Page 33: Intro to Kernel Modules and /proc

Why Scheduling?

Classic producer/consumer analogy Similar to disk schedulers File system produces read/write requests Disk consumes requests, optimized for disk head

position, rotational delays, etc.

33

Page 34: Intro to Kernel Modules and /proc

Your Printer

One printer 20 job slots Use a static array of ints?

Four types of print jobs 1-page document (internally represented with a 1) 2-page document (internally represented with a 2) 3-page document (internally represented with a 3) 4-page document (internally represented with a 4)

34

Page 35: Intro to Kernel Modules and /proc

Print jobs

A write of 1-4 to /proc/penguin will fill a job slot with the job corresponding to the number You decide how the job slots get filled (e.g. round

robin or other way) Printer takes 1 second to look in a job slot Regardless if empty or containing a job

35

Page 36: Intro to Kernel Modules and /proc

Print Jobs

The printer can only process one job at a time

Each job takes a different amount of time to process 2 seconds for a 1-page document 3 seconds for a 2-page document 4 seconds for a 3-page document 5 seconds for a 4-page document

36

Page 37: Intro to Kernel Modules and /proc

Print Jobs

Once a job is processed, the printer can mark that job slot as empty and should look at other job slots to find more jobs to process.

37

Page 38: Intro to Kernel Modules and /proc

A wrench in the plans!

In addition, the printer should also accept a “maintenance” job, internally represented with a 5. Maintenance takes a whopping 8 seconds.

38

Page 39: Intro to Kernel Modules and /proc

Additional Printer Commands

In addition to accepting jobs 1-5, the printer should respond to writes of 0 or -1 in the following ways 0 : start the printer -1: stop the printer

39

Page 40: Intro to Kernel Modules and /proc

Starting the Printer

Before the printer is started, it cannot be processing jobs But it can receive jobs on the queue It just isn’t printing yet!

When a printer is stopped, it must finish processing the current job and cease to process any more

40

Page 41: Intro to Kernel Modules and /proc

Starting the Printer

The actual job processing logic will be run in a kthread Introduced in the next project lecture

41

Page 42: Intro to Kernel Modules and /proc

Status Information

Performing a read on /proc/penguin should return some status information printer status: running or not running Current spot being looked at in the queue Current job being processed

If the printer is not running, the last two

pieces of information do not need to be displayed

42

Page 43: Intro to Kernel Modules and /proc

Demo

43

Page 44: Intro to Kernel Modules and /proc

Scheduling Algorithms

A scheduling algorithm considers the state of the consumers and all requests and tries to optimize some metric Throughput: Maximize total requests, minimize

processing total time. Priorities: Requests now have deadlines.

Maximize number of requests meeting deadlines. Burst throughput: Maximize peak requests that

can be handled. Energy: Minimize consumer action

44

Page 45: Intro to Kernel Modules and /proc

Kernel Time Constraints

#include <linux/delay.h>

void ssleep(unsigned int seconds);

A call to ssleep will have the program cease to the task scheduler for seconds number of seconds

45

Page 46: Intro to Kernel Modules and /proc

Additional Design Considerations

How to place jobs in job slots? How to check job slots from the printer? What scheduling algorithm to use?

46

Page 47: Intro to Kernel Modules and /proc

Next Time

Locking Must lock when accessing anything global

printer queue Printer status variables

Kthread How to start/stop the looping logic that looks in the

job queue and “processes” jobs

47