refactor: modify until exercice 4
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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:
|
||||
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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`
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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, we’ve added a line to the makefile that copy the module’s 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"
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user