Tasks
The same steps as the lab slide. Do them on a Linux PC with the files from the zip; the tools below help you check your thinking first.
Lab 15.1 · Character Device Drivers
- cd lab15_1; make builds sysbuf_starter.ko and the static test program sbtest
- TODO 1 init: alloc_chrdev_region, cdev_init/cdev_add, class_create, device_create (with the goto ladder)
- TODO 2 read: EOF, min, copy_to_user, *pos += n
- TODO 3 write: −ENOSPC, copy_from_user, update used
- TODO 4 ioctl: CLEAR, GETSIZE with put_user, default −ENOTTY
- ../guest/run_guest.sh . then insmod, echo, cat, dd, ./sbtest
the starter, before TODO 1 (real)
$ insmod sysbuf_starter.ko; echo status $? insmod: can't insert 'sysbuf_starter.ko': No such device status 19 $ dmesg | grep sysbuf sysbuf: not registered yet: TODO 1
the finished lab (real)
$ ./sbtest
write: 22 bytes, size now 22
read at offset 14: 8 bytes "Barishal"
read again: 0 (end of file)
ioctl 0x1234: Inappropriate ioctl for device
SYSBUF_GETSIZE = 0x80045302 (_IOR('S', 2, int))
Lab 15.2 · Block Device Drivers
- cd lab15_2; make builds sbd_starter.ko
- TODO 2 tag set and disk: blk_mq_alloc_sq_tag_set, sbd_alloc_disk, fill major, minors, fops, name
- TODO 3 set_capacity in sectors, add_disk; jump to the right undo label on error
- TODO 1 queue_rq: rq_for_each_segment, bvec_kmap_local, memcpy in the right direction
- test: mke2fs -q /dev/sbd0; mount /dev/sbd0 /mnt, write a file, umount, mount again, read it
- echo 1 > /sys/module/sbd_starter/parameters/trace and watch your requests in dmesg
the starter, before TODO 2–3 (real)
$ insmod sbd_starter.ko; echo status $? insmod: can't insert 'sbd_starter.ko': No such device status 19 $ dmesg | grep sbd | tail -1 sbd: no disk yet: TODO 2 and 3
the finished lab (real)
$ insmod sbd.ko $ mke2fs -q /dev/sbd0 && mount /dev/sbd0 /mnt $ echo hi > /mnt/f && cat /mnt/f && umount /mnt Filesystem label= … 4096 inodes, 16384 blocks 2 block groups hi
Lab 15.3 · USB Device Drivers
- cd lab15_3; make builds sysprog_kbd_starter.ko and mylsusb
- USB=1 ../guest/run_guest.sh . adds a UHCI controller, a USB keyboard and a mouse; run mylsusb
- TODO 1 id_table; TODO 2 find the interrupt IN endpoint
- TODO 3 usb_fill_int_urb, usb_set_intfdata, usb_submit_urb
- TODO 4 decode the report and resubmit with GFP_ATOMIC
- Ctrl-A then C: QEMU monitor. sendkey h, Ctrl-A C back, dmesg | tail
the starter, before TODO 1 (real)
$ insmod sysprog_kbd_starter.ko; echo status $? status 0 $ dmesg | tail -2 # nothing: no probe, the id_table is empty $ ls /sys/bus/usb/drivers hub sysprog_kbd usb usbfs
the finished lab (real)
(qemu) sendkey h (qemu) sendkey shift-b $ dmesg | grep report usb 1-1: report 1: 00 00 0b 00 … key 0x0b 'h' usb 1-1: report 2: 00 00 00 00 … (all keys up) usb 1-1: report 3: 02 00 00 00 … (all keys up) usb 1-1: report 4: 02 00 05 00 … key 0x05 'b' +shift
Try it here
These run in your browser, with no server and no internet. They are built from the same reference programs as the lab, so their output matches what your finished C program should print. They do not replace the real lab: the kernel, gcc and your own code are the point.
Read the files
Every text file from lab15_files.zip. Read here, then download the zip to work on them.