Homework 5

In this homework you will get to know more advanced features in Linux kernel modules.

Overview

Documentation (Human Language)

A non-technical assignment is to write documentation and answer questions. You can use either English oder German while working on technical assignments. The suggestion is to use English for practicing purposes and to avoid awkward mixins of English technical terms with German ;-)

hw5/QnA.md Question Boxes

Throughout the document you will find several question boxes. These questions are meant to help you think through what you did and how you can solve the current part of the assignment. Please keep a protocol for answering these questions in your project repository at $REPO_DIR/hw5/QnA.md. The file must contain the questions with brief answers written in your own words.

hw5/README.md (optional)

You can use this document to make the following notes:

  • difficulties throughout the homework
  • design decisions that are necessary to explain or you think are important to emphasize

Preparation

  • Complete Homework 4
  • Have SSH/X2Go access to your group's syslab container

    The labshell-Name for this assignment is sysoHW5.

    [info] In a terminal on your container you can open this environment with the command

    $ labshell sysoHW5
    

    More information on this can be found on the generic HTWG SYSLAB information site.

Skills You Will Acquire

During this assignment you'll gain experiences in the following activities:

  • Use more Linux Kernel features in your modules

Pre-Requisites

Before you proceed, please research the following topics. There is no need get into great detail at this point, but simply get an overview of what they are and how they are related.

Assignments

This homework is a continuation of homework 4.

Busybox

Configure Busybox to contain the applets for dealing with processes:

  • kill
  • ps

Linux Kernel Modules Driver Development

At this point you should be familiar with the process outlined above, and you are ready to develop and test even more complex modules.

General Instructions for all modules
  • Use the new device number system to register your device drivers. See lecture slides 54 and 55
  • Use the MODULE_ macros to insert author and description into your modules. You can check this information for each module in the running virtual machine with the modinfo command.
  • You can safely skip any instructions you might encounter for registering udev/mdev as a hotplug manager, since your system uses the kernel managed devtmpfs.
    • You can also skip any instructions of using mknod, as the node creation is handled by the devtmpfs
  • Create a subdirectory $REPO/hw5/modules/$MODULE with the C code and the Makefile for each of the following modules.

[warning]

  • All implemented methods should printk debug messages about what has been called, enriched with information about the specific function call
  • Every module must clean up the allocated resources on unload (if possible, else exit non-zero). This is not explicitly mentioned in the module description!
Test Instructions for all modules

Because each module is different, you will write a functional test for each module. Effectively the functional tests will be transferred to the virtual machine in form of an an executable.

To your liking, you can use either a shell script or write a program in a language that needs to be compiled to a binary.

For this to work the same for all possible test implementations, add a Makefile target called test to each module which produces the test executable.

  • For a shell script, this can be a NOOP if the script is named test.
  • For compiled programs ensure to use the cross compiler

Each test executable must be copied to the artifacts/$MODULENAME.ko.test.

hello_counted

  • Learn how to manage memory dynamically in kernel modules
Implementation

Load

  • Allocate a character device Region for 1 device
  • (Let the system) Create a character device at /dev/hello_counted

Open

  • Allocate memory for a counter which is specific for this open call

Close

  • Free the memory for the counter

[success] Questions

  • Which functions are available in the kernel for allocating/freeing memory?
  • Which functions did you choose and why?

Read

  • Returns a string that displays how many bytes have been read from the device so far:

    "Hello, from grp$NR. You have read $BYTES bytes so far."

  • Increases the counter by the number of bytes that were read
Test
  • The expected string is read from the device and the byte counter is working

mytasklet

  • Learn the basics of kernel Tasklets
Implementation

Load

  • Create and activate a tasklet that issues a printk() with the message Tasklet grp$NR

Unload

  • Deactivate the tasklet
Test
  • The kernel log must contain the expected string

mytimer

  • Learn the basics of in-kernel timer handling
Implementation

Load

  • Create and start a timer that triggers every 2 seconds. When the timer is triggered, it should print information about the exact time between the trigger events. Specifically these are the

    • current,
    • minimum,
    • and maximum,

      measured inter-trigger durations.

      Print the timing information in three different units:

    • Jiffies
    • CPU Cycles
    • Nanoseconds

      [success]

      • Which is the more accurate time source: jiffies or CPU cycles?

Unload

  • Gracefully stop the timer
Test
  • The kernel log prints the measured information periodically

mykthread

  • Learn the basics about kernel threads
Implementation

Load

  • Start a kernel thread that runs a loop over printing a message to the kernel log and then sleeping for 2 seconds.

Unload

  • Gracefully stop the kernel thread

[success] Questions

  • How can you identify the kernel thread's PID using the ps utility?
  • Can your kernel thread receive and handle signals that were sent from userspace using kill?
Test
  • Verify that the module creates a kernel thread that prints to the kernel log

myworkqueue

  • Learn the basics of kernel workqueues
Implementation

Replicate the functionality of the mytimer module using workqueues.

[success] Questions

  • What is the name of the workqueue in the process list?
  • How do the time measurements of the workqueue compare to the one from the timer?
  • What problems can occur on module unload?
Test
  • Verify timer functionality
  • Verify thread creation
  • Module load/unload/reload works without problems

mysemaphore

  • Learn the difference between the usage of spinlocks and semaphores
Implementation

Load

  • Allocate a character device Region for 1 device
  • (Let the system) Create a character device at /dev/mysemaphore

Open

  • This function must contain a code section that is guarded by a semaphore to ensure mutual exclusion
  • Within this critical section, the calling instance sleeps for three seconds
  • If the critical section is busy, this gets printed to the kernel log. Then, a loop is started that retries to enter the critical section every 200ms

[success] Questions

  • How would the design of mutual exclusion look like using a spinclock?
  • Which implementation would you prefer, and why?

[warning]

  • Can close and unload unconditionally clean up the resources?
Test
  • Verify the critical section can only be entered by the semaphore's initial counter number of threads
  • Verify the suspend/retry loop
  • Module load/unload/reload works without problems

mybuffer_sync

Tis module combines the above techniques to build a version of the mybuffer module that provides a buffered character device which is safe to access from multiple parallel threads.

Implementation

Based on the implementation of the mybuffer module, this implementation has to resolve all race conditions without losing functionality.

Test
  • Based on the tests from mybuffer
  • Demonstrate how simultaneous access from multiple readers and writers does not lead to inconsistent data

Result To Be Submitted (tracked by Git)

This section gives you information which files are part of the submission for this homework. Results for bonus assignments are not covered within this section.

Test-Suite and Continous Integration

Merge and Run the Continous-Integration test suite.

Documentation files

(not shown in the above tree) Please include the documentation files that are explained in the beginning.

Build Instructions (hw5/hw5.sh)

A shell script that reproduces the final result of your homework. This shell script will be used to verify your results, and does not need to include commands that run the interactive menuconfig. However, you may implement such functionality for working conveniently within your homework repository.

Arguments and Script behavior

Arguments Function
(called without any arguments) Build all artifacts starting with just the files that are checked in to git
qemu Run qemu-system-aarch64, booting your system with the initrd and network
ssh_cmd Connect to the VM via SSH session as the root user and pass remainder arguments as the SSH command
modules_build Build all modules and their tests (if build is needed) and copy *.ko and *.ko.test files to the artifacts/ directory
modules_copy Copy all kernel modules, test executables (and shared libraries if necessary) via SSH and load them; should use ssh_cmd
modules_load Load all copied kernel modules
modules_test Run the test for each module
modules_unload Unload all kernel modules (should not error if none are loaded)
modules Run modules_{build,copy,load,test,unload} in the given order
clean Remove all files not tracked by git
ssh_cmd [cmd [args...]] Establish a connection to the VM's SSH server via authorized_key authentication. It runs the specified command with all arguments inside the VM. An example would be ssh_cmd "echo Hello, World", as found in the CI scripts.

Build Artifacts (Binary Files)

The following files must be present in at hw5/artifacts/ after the build is complete but not tracked by git!

File Target Architecture Purpose
Image.gz aarch64 (arm64) Kernel binary used for qemu
One *.ko file per module aarch64 (arm64) Kernel Objects
One *.ko.test file per module aarch64 (arm64) Executable to test the given Kernel Object
sysinfo aarch64 Statically (dynamically, if you completed HW3/Bonus1) linked binary of your little C program
dropbearmulti aarch64 Statically (dynamically, if you completed HW3/Bonus1) linked multicall binary for Dropbear
initrd.cpio aarch64 Initial RamDisk file in the form of a cpio archive

Other Files and Git

[warning] Please do not add binary files to your git repository. Only add files that represent configuration, source code and build commands.

Bonus Assignments

These optional assignments allow you to dig in a little deeper! They don't depend on each other so you can cherry-pick the ones you are interested in.

Kernel Memory Leak Detection

Enable and use the Linux kernel memory leak detection and demonstrate it's usage. Demonstrate the memory leak detection with a module that knowingly leaks memory.

Driver that is configurable via /sysfs

Design and implement a module that registers itself with the sysfs and exposes configuration options.

For example, this could be a modification of the mysemaphore module that allows to read the number of waiting threads, alter the number of simultaneous threads, etc.!

results matching ""

    No results matching ""