In this project you will learn hands-on how system calls work and how the kernel interacts with hardware via memory-mapped I/O: You will add new system calls to the kernel that control the on-board LED of the Pi. Note that the Pi already has drivers for this purpose that could easily be used. It is not the point of the project to control the LED with existing drivers as you would normally do if they are available, but rather to build them from scratch.
First, follow first the instructions to set up the Pi and turn off the LED as described there.
This project cannot be done in one day. The building process itself takes a significant amount of time. You need to plan in enough time for it.
To understand how we can access devices via memory-mapped I/O, read this article. It describes how the GPIO pins of the Pi are controlled, but the same is true for the LED, which in fact is wired into the GPIO controller and works the same as the GPIO pins. Its pin number is 29. You can find here an adapted version of the source code, which is ready to be used with the Pi. On the Pi download the source file with
wget https://larsrohwedder.com/teaching/dm510-26/projects/leds.c
Make sure the LED is turned off as described above. Compile and execute the program:
gcc -o leds leds.c
sudo ./leds
You should see the led blinking. Stop the process using Ctrl+C. For many reasons it is not a good idea to directly write to raw physical memory in user programs. We will implement a similar control in the kernel.
Follow the instructions here to download, build and run your own custom version of the Linux kernel. Then follow the instructions here to understand how to add new system calls. Design a system call interface for controlling the LED (turning it on or off) and add the corresponding function stubs to the kernel, first without the implementation.
On a high level, you will control the LED in a similar way to the user mode hack: by writing to the physical memory addresses. When kernel code executes, it does not run in the raw physical memory space. That means for example that dereferencing pointer 10 will not read/write to the physical address 10, but to some other address that you have no control over. In the user mode hack the workaround was to map /dev/mem to some memory section via mmap.
This is not the safe way to do it and in particular is not feasible to do from kernel code.
Instead, use the functions ioremap(), iowrite32(), and iounmap() as described in the hardware chapter of the Linux driver manual, specifically the section Using I/O Memory.
Write a user program that rigorously tests the functionality of your system calls, including for example invalid inputs (if appropriate).
Submit via itslearning the following:
SYSCALL_DEFINE... in it. You do not need to include header files, etc.uname -r on your terminal and then how you execute your user program(s). Move the camera between screen and Pi to demonstrate how the LED changes.Questionaire:
If your answer is no to some of these questions, you may include explanation on which problems you ran into. It is intentional that there is no excessive report on the project. All design decisions that you made should be documented in the source code itself.
Assessment:
The project will be graded based on the following: