1
0

refactor: modify until exercice 4

This commit is contained in:
2026-04-02 18:28:29 +02:00
parent aa7342123d
commit 6b0246b2a5
10 changed files with 113 additions and 94 deletions

View File

@@ -52,7 +52,19 @@
#pagebreak()
= #i18n("appendix-title", lang: option.lang) <sec:appendix>
== Exercices Lab 01
#include "lab01-module/ex01.typ"
#pagebreak()
#include "lab01-module/ex02.typ"
#include "lab01-module/ex03.typ"
#pagebreak()
#include "lab01-module/ex04.typ"
#pagebreak()
#include "lab01-module/ex05.typ"
#include "lab01-module/ex06.typ"
#pagebreak()
#include "lab01-module/ex07.typ"
#include "lab01-module/ex08.typ"
//-------------------------------------
// Glossary

View File

@@ -1,11 +1,9 @@
#import "/doc/metadata.typ": *
#task(
[Adapt the kernel module to receive parameters],
[
Adapt the kernel module of the previous exercise to receive two or three parameters of your choice. These parameters will be displayed in the console when the module is loaded.
],
)
=== Adapt the kernel module to receive parameters <lab01:ex02>
#colorbox(title: "Exercise", color: hei-blue)[
Adapt the kernel module of the previous exercise to receive two or three parameters of your choice. These parameters will be displayed in the console when the module is loaded.
]
```bash
|> modprobe mymodule

View File

@@ -1,9 +1,6 @@
#import "/doc/metadata.typ": *
#task(
[What does it mean the 4 values in ```/proc/sys/kernel/printk``` ?],
[]
)
=== What does it mean the 4 values in ```/proc/sys/kernel/printk``` ? <lab01:ex03>
We can show what there is in:

View File

@@ -1,16 +1,12 @@
#import "/doc/metadata.typ": *
#task(
[
Create module with dynamic allocation and a chained list
],
[
Create dynamically elements in the kernel. Adapt a kernel module to specify at the installation the number of element to create a initial text.
Each element will contain a unique number. The elements are create at the installation of the module adn chained in a list.
These elements will be destruct during the uninstallation of the module.
Some information messages are emits to allow debugging.
]
)
=== Create module with dynamic allocation and a chained list <lab01:ex04>
#colorbox(title: "Exercise", color: hei-blue)[
Create dynamically elements in the kernel. Adapt a kernel module to specify at the installation the number of element to create a initial text.
Each element will contain a unique number. The elements are create at the installation of the module adn chained in a list.
These elements will be destruct during the uninstallation of the module.
Some information messages are emits to allow debugging.
]
To allocate memory in the kernel, we can use the `kcalloc` function. It allows to allocate directly the memory for all element. It's also possible to use `kzalloc` in a loop to allocate memory for each element. We prefer allocate all the memory at once to avoid fragmentation and to be sure all the memory can be allocated.
@@ -18,12 +14,12 @@ To allocate memory in the kernel, we can use the `kcalloc` function. It allows t
struct element* element_ptr = kcalloc(elements, sizeof(struct element), GFP_KERNEL);
for (int i = 0; i < elements; i++) {
struct element* e = element_ptr + i;
if (e != 0) {
strncpy(e->text, text, TEXT_LENGTH_MAX - 1);
e->unique_number = i;
list_add_tail(&e->node, &list_unique_elements);
pr_info ("add element %d: %s\n", e->unique_number, e->text);
}
}
struct element* e = element_ptr + i;
if (e != 0) {
strncpy(e->text, text, TEXT_LENGTH_MAX - 1);
e->unique_number = i;
list_add_tail(&e->node, &list_unique_elements);
pr_info ("add element %d: %s\n", e->unique_number, e->text);
}
}
```

View File

@@ -1,24 +1,20 @@
#import "/doc/metadata.typ": *
#task(
[
Display the processor chip ID, CPU temperature and the MAC adress of the Ethernet controller
],
[
- Chip ID registers: _0x01c1'4200_ to _0x01c1'420c_
- 32 bits register of the temperature sensor: _0x01c2'5080_
- two 32 bits registers of the Ethernet controller MAC address: _0x01c3'0050_ and _0x01c3'0054_
=== Display the processor chip ID, CPU temperature and the MAC adress of the Ethernet controller <lab01:ex05>
#colorbox(title: "Exercise", color: hei-blue)[
- Chip ID registers: _0x01c1'4200_ to _0x01c1'420c_
- 32 bits register of the temperature sensor: _0x01c2'5080_
- two 32 bits registers of the Ethernet controller MAC address: _0x01c3'0050_ and _0x01c3'0054_
To calculate the temperature value, there is this formul:
$
"temperature" = -1991 dot "register value" / 10 + 223000
$
To calculate the temperature value, there is this formul:
$
"temperature" = -1991 dot "register value" / 10 + 223000
$
The chip ID can be verified in ```/proc/iomem```.
The register value of the temperature can be verified in the file: ```/sys/class/thermal/thermal_zone0/temp```.
The MAC address can be verified with ``` ifconfig```.
]
)
The chip ID can be verified in ```/proc/iomem```.
The register value of the temperature can be verified in the file: ```/sys/class/thermal/thermal_zone0/temp```.
The MAC address can be verified with ``` ifconfig```.
]
The resources are savec in a struct:
```c

View File

@@ -1,13 +1,8 @@
#import "/doc/metadata.typ": *
#task(
[
Kernel thread
],
[
Develop a module which allows to instanciate a thread in the kernel. This thread will display a message every 5 seconds. Use the function ```ssleep(5)``` to sleep the thread from ``` linux/delay.h```.
]
)
=== Kernel thread <lab01:ex06>
#colorbox(title: "Exercise", color: hei-blue)[
Develop a module which allows to instanciate a thread in the kernel. This thread will display a message every 5 seconds. Use the function ```ssleep(5)``` to sleep the thread from ``` linux/delay.h```.
]
Easy exercice, a thread in the kernet is a `struct task_struct*` that can be created with `kthread_run`

View File

@@ -1,13 +1,9 @@
#import "/doc/metadata.typ": *
#task(
[
Sleeping
],
[
Develop a module which instanciate 2 threads in the kernel. The first one will wait a wake up notification from the second thread and will sleep. The second will send the notification every 5 seconds. Then it will sleep. We will use the waitqueue for the sleeping function. To allow debugging, each thread will send a message when it wakes up.
]
)
=== Sleeping <lab01:ex07>
#colorbox(title: "Exercise", color: hei-blue)[
Develop a module which instanciate 2 threads in the kernel. The first one will wait a wake up notification from the second thread and will sleep. The second will send the notification every 5 seconds. Then it will sleep. We will use the waitqueue for the sleeping function. To allow debugging, each thread will send a message when it wakes up.
]
This exercice make 2 threads in concurrency with wait queue. Here the queue ware declare
statically with the macro `DECLARE_WAIT_QUEUE_HEAD`. Then for this exercice we use an atomic

View File

@@ -1,20 +1,16 @@
#import "/doc/metadata.typ": *
#task(
[
Interrupts
],
[
Develop a module which allows to detect every push on the button of the nanopi with interrupt. Every interrupts will send a message for debugging.
=== Interrupts <lab01:ex08>
#colorbox(title: "Exercise", color: hei-blue)[
Develop a module which allows to detect every push on the button of the nanopi with interrupt. Every interrupts will send a message for debugging.
- Use the service ``` gpio_request(<io_nr>, <label>)```
- Get the interrupt vector with ``` gpio_to_irq(<io_nr>)```
- Extension card information:
- k1 - gpio: A, pin_nr=0, io_nr=0
- k2 - gpio: A, pin_nr=2, io_nr=2
- k3 - gpio: A, pin_nr=3, io_nr=3
]
)
- Use the service ``` gpio_request(<io_nr>, <label>)```
- Get the interrupt vector with ``` gpio_to_irq(<io_nr>)```
- Extension card information:
- k1 - gpio: A, pin_nr=0, io_nr=0
- k2 - gpio: A, pin_nr=2, io_nr=2
- k3 - gpio: A, pin_nr=3, io_nr=3
]
We made a custom structur for the gpio device that contain all useful information like the name and the id.
```c

View File

@@ -1,7 +1,50 @@
#import "/doc/metadata.typ": *
#let ln(num) = {
let str_num = if int(num) < 10 { "0" + str(num) } else { str(num) }
let lbl = label("lab01:ex" + str_num)
link(lbl)[Ex 1.#num]
}
= Linux Kernel Programming
In this lab, we learn how to develop a tiny kernel module. We initially create a tiny skeleton that just print a message when the module is loaded and unloaded in #ref(<lab01:ex01>, supplement: "Ex").
In this lab, we learn how to develop a tiny kernel module. We initially create a tiny skeleton that just print a message when the module is loaded and unloaded in #ln(1). Then in #ln(2), we see how to use parameters with insmod and with modprobe. To make things easier for us, weve added a line to the makefile that copy the modules configuration file (that contain the parameters for the modules) to the correct directory on the target. The `install` command is used as combination of `mkdir`, `cp` and `chmod`.
```makefile
install:
$(MAKE) -C $(KDIR) M=$(PWD) INSTALL_MOD_PATH=$(MODPATH) modules_install
install -D -m 0644 $(SOURCE).conf $(MODPATH)/etc/modprobe.d/$(SOURCE).conf
```
The exercice 3 ask us what does it mean the 4 values in ```/proc/sys/kernel/printk``` ?
We can show what there is in:
```bash
|> cat /proc/sys/kernel/printk
7 4 1 7
```
The number specified the level of output in a console.
This file specifies the log level for: \
current (7), default (4), minimum (1) and boot-time default (7).
This number matches with this table (#link("https://www.kernel.org/doc/html/latest/core-api/printk-basics.html", [printk documentation])):
#table(
columns: (2fr, 1fr, 3fr),
[*Name*], [*String*], [*Alias function*],
[KERN_EMERG], ["0"], [pr_emerg()],
[KERN_ALERT], ["1"], [pr_alert()],
[KERN_CRIT], ["2"], [pr_crit()],
[KERN_ERR], ["3"], [pr_err()],
[KERN_WARNING], ["4"], [pr_warning()],
[KERN_NOTICE], ["5"], [pr_notice()],
[KERN_INFO], ["6"], [pr_info()],
[KERN_DEBUG], ["7"], [pr_debug() and pr_devel() if DEBUG is defined],
[KERN_DEFAULT], [""], [],
[KERN_CONT], ["c"], [pr_cont()],
)
In #ln(4), we see how to dynamically create elements in the kernel.
== Cheatsheet commands
- `modinfo <module.ko>`: display information about a kernel module
@@ -14,19 +57,3 @@ In this lab, we learn how to develop a tiny kernel module. We initially create a
- `modprobe -r <module>`: uninstall a kernel module and its dependencies
- `make`: build the kernel module
- `make install`: install the kernel module in the root filesystem
// == Exercises
// #include "ex01.typ"
// #pagebreak()
// #include "ex01.typ"
// #include "ex03.typ"
// #pagebreak()
// #include "ex04.typ"
// #pagebreak()
// #include "ex05.typ"
// #include "ex06.typ"
// #pagebreak()
// #include "ex07.typ"
// #include "ex08.typ"

View File

@@ -1,4 +1,10 @@
#import "/doc/metadata.typ": *
#let ln(num) = {
let str_num = if int(num) < 10 { "0" + str(num) } else { str(num) }
let lbl = label("lab01:ex" + str_num)
link(lbl)[Ex 1.#num]
}
= Linux Kernel Programming
== Exercises