CSE 4105 System Programming · Lab 15

Character, block and USB drivers

A character device, a RAM disk and a USB keyboard driver, in a virtual machine.

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

  1. cd lab15_1; make builds sysbuf_starter.ko and the static test program sbtest
  2. TODO 1 init: alloc_chrdev_region, cdev_init/cdev_add, class_create, device_create (with the goto ladder)
  3. TODO 2 read: EOF, min, copy_to_user, *pos += n
  4. TODO 3 write: −ENOSPC, copy_from_user, update used
  5. TODO 4 ioctl: CLEAR, GETSIZE with put_user, default −ENOTTY
  6. ../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

  1. cd lab15_2; make builds sbd_starter.ko
  2. TODO 2 tag set and disk: blk_mq_alloc_sq_tag_set, sbd_alloc_disk, fill major, minors, fops, name
  3. TODO 3 set_capacity in sectors, add_disk; jump to the right undo label on error
  4. TODO 1 queue_rq: rq_for_each_segment, bvec_kmap_local, memcpy in the right direction
  5. test: mke2fs -q /dev/sbd0; mount /dev/sbd0 /mnt, write a file, umount, mount again, read it
  6. 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

  1. cd lab15_3; make builds sysprog_kbd_starter.ko and mylsusb
  2. USB=1 ../guest/run_guest.sh . adds a UHCI controller, a USB keyboard and a mouse; run mylsusb
  3. TODO 1 id_table; TODO 2 find the interrupt IN endpoint
  4. TODO 3 usb_fill_int_urb, usb_set_intfdata, usb_submit_urb
  5. TODO 4 decode the report and resubmit with GFP_ATOMIC
  6. 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.

    ← Lab 14All lectures