Operating Systems 2018F Lecture 12: Difference between revisions
R.samanfar (talk | contribs) |
R.samanfar (talk | contribs) |
||
Line 6: | Line 6: | ||
{{Please leave this line alone and write below (this is the coloured heading)}} | {{Please leave this line alone and write below (this is the coloured heading)}} | ||
Today: Kernel modules | |||
=== First, Anil's ssh setup: === | === First, Anil's ssh setup: === |
Revision as of 20:40, 21 November 2018
Video
Video from the lecture given on October 17, 2018 is now available.
Notes
Template:Please leave this line alone and write below (this is the coloured heading)
Today: Kernel modules
First, Anil's ssh setup:
student@anil-vm:
// openstack
- why is it named anil-vm?
- edit /etc/hosts and /etc/hostname
anilclass@sutherland:
// local machine
- edit /etc/hosts
- add the IP of your VM and give it name
- distributed DNS does this for URLs
- login without password
- ssh key pair, private and public
- files in ~/.ssh/
Public keys?
- sharing won't compromise security
Running X-windows programs on vm:
ssh -X student@anil-vm
// works natively in linux- on macOS, you can run X-server separately
- on Windows, use x2go
Whats a kernel module?
- kernel code, that you load, into the kernel
- same privileges as other kernel code
- dangerous! load kernel module = anything can happen
- only superuser (root) can load
- NOT a system call
Kernel Oops:
- kernel catches the bad memory access
Kernel crash:
- didn't catch it
Build kernel from scratch? Not usually - everything is in modules now
What modules are running?
lsmod
- gets info from
/proc/modules
/proc/modules
is reading a kernel data structurestrace lsmod
:- shows that it starts with
/proc/modules
- but then goes into
/sys/module/
- shows that it starts with
/proc
: human readable/sys
: machine readable- wouldn't find a list of modules here, but rather deep directory structure
Where are kernel modules stored?
/lib/modules/<kernel version>/
- why so many kernel versions?
- ex. 4.15.0-33
- 4.15.0 is version.
- -33 = package release (patches etc)
- ex. 4.15.0-33
Why so many modules? Why not build them in?
- originally, everything was built in - now we basically never do that
- some may conflict
- many are unnecessary
- memory used by kernel is physically used - never virtual
- so we minimize this by only loading necessary kernel modules
.ko
: kernel object
.so
: shared object (ex. C libraries)
Where is kernel itself?
/boot/vmlinuz-4.15.0-33-generic
- naming is traditional. 'z' is for compressed.
- variants may have different suffix, ex. 'rt' for realtime, instead of 'generic'
- kernel is around 8mb
Review tutorial
sudo insmod simple.ko
// load kernel moduledmesg | tail
// shows that kernel is loadedsudo rmmod simple.ko
// removes kernel module
simple.c
- Why
#include <linux/ ...>
? - No headers that are familiar, ex.
stdlib
, etc.- You can't use these in kernel modules. Why?
- You can't use any C library that makes a system call
- What if you wanted to
printf
?printk()
is a reimplementation, becauseprintf
would "bottom out" by making a system call to write()printk
is used to generate logs- how does it do that?
- keeps a buffer until they can be printed somewhere
- bootup messages? produced by
printk
- kernel has its own weird world of standard libraries
- You can't use these in kernel modules. Why?
- Some special syntax around declaring init and exit functions..
- How does kernel actually load a module? (ie. through
module_init()
call in simple.c)- don't worry about it. always something you don't understand...
- and this is one of these things few people need to understand!
- you just needs to know how to use it.
- Why doesn't simple_exit return anything? Nobody cares what it returns!
- vs. if init failed... we would care
Rule of kernel programming: do as little as possible
- nicer to write in userspace
ones.c
- kernel module that implements a device driver for
/dev/ones
- from linux kernels perspective.. same as any other device
- a module might be a device driver, but might not be
- and a driver might be baked into the kernel (not a module)
- but usually, device drivers are implemented as modules
- makes a character device:
register_chrdev()
- every device has a major and a minor number: the above function returns major number
ones_fops { }
: important. struct containing function pointers.- we never call these functions in ones.c
- these implement the file operations on
/dev/ones
- after normal syscall dispatcher stuff, it will want to know HOW to open the device, read, etc
- what if we wanted to do a write?
- well,
/dev/ones
is opened read-only. let'schmod a+w /dev/ones
. echo 5 > /dev/ones
// write error- we only have the operations that we've implemented
- well,
- who calls them?
class_create()
?- can't just create a device from the major number
- need a class first before running
device_create()
- grouping of all devices that use the same driver
- see
/sys/class/comp3000
/sys/devices/virtual/comp3000/ones
- what's this about? metadata.
- thankfully we didn't have to create this ourself -
device_create()
took care of all that
- failed_devreg, etc:
- handling failures is really important in kernel programming.
- if something fails and you don't manually deregister / deallocate memory, it never gets "cleaned up"
- stays in physical memory until you reboot
- How did we come up with this code, generally?
- no manpages
- the linux kernel source is the ultimate reference for how this works
- best way to figure it out is to look at existing device drivers, modify to your purpose, trial & error...
ones_read()
:- similar to
read()
in userspace - in userspace you take a file descriptor; in kernel you take a pointer to a file struct
buf, len
just as inread()
..- offset? point to specific part of the file
- the file is always going to be
/dev/ones
in this case (since it is a device driver) - why
put_user('1', buf++)
instead of*buf++ = 1
?- The 1's are going out into userspace. This is what
put_user()
is for.
- The 1's are going out into userspace. This is what
- similar to
aside: find . -name "ones"
- will find files named "ones" in current directory (.)
Look at newgetpid.c