You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Refactor documentation for building Linux kernel images and profiling with Streamline, enhancing clarity in section titles, instructions, and descriptions.
Copy file name to clipboardExpand all lines: content/learning-paths/embedded-and-microcontrollers/streamline-kernel-module/2_build_kernel_image.md
+4-5Lines changed: 4 additions & 5 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -6,13 +6,13 @@ weight: 3
6
6
layout: learningpathall
7
7
---
8
8
9
-
## Prepare to build Linux image with Buildroot
9
+
## Prepare to build a Linux image with Buildroot
10
10
11
11
Before you build a Linux image with [Buildroot](https://github.com/buildroot/buildroot), make sure your development environment includes all the required packages. These tools and libraries are essential for compiling, configuring, and assembling embedded Linux images on Arm platforms. Installing them now helps you avoid build errors and ensures a smooth workflow.
12
12
13
-
## Install required packages for Buildroot
13
+
## Install the required packages for Buildroot
14
14
15
-
Run the following commands on your aarch64-based Linux system to update your package list and install the necessary dependencies:
15
+
Run the following commands on your AArch64-based Linux system to update your package list and install the necessary dependencies:
16
16
17
17
```bash
18
18
sudo apt update
@@ -43,7 +43,7 @@ If you're not using a Raspberry Pi 3B+ for this Learning Path, select the defaul
43
43
make menuconfig
44
44
```
45
45
46
-

46
+

47
47
48
48
Change the Buildroot configuration to enable debugging symbols and SSH access:
49
49
@@ -67,7 +67,6 @@ Target packages --->
67
67
[*] openssh
68
68
[*] server
69
69
[*] key utilities
70
-
```
71
70
You might need to update your default `sshd_config` file to match your network requirements. To do this, set the **Root filesystem overlay directories** option in the **System configuration** menu. Add a directory containing your customized `sshd_config` file. This ensures your SSH server uses the correct settings when the image boots.
72
71
73
72
By default, Linux kernel images are stripped of debugging information. To make the image debuggable for profiling, you need to adjust the kernel build settings.
Copy file name to clipboardExpand all lines: content/learning-paths/embedded-and-microcontrollers/streamline-kernel-module/3_oot_module.md
+30-30Lines changed: 30 additions & 30 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -6,14 +6,16 @@ weight: 4
6
6
layout: learningpathall
7
7
---
8
8
9
-
## Create an out-of-tree Linux kernel module
9
+
## Develop a cache-unfriendly Linux kernel module
10
10
11
11
You'll now create an example Linux kernel module (character device) that demonstrates a cache miss issue caused by traversing a 2D array in column-major order. This access pattern is not cache-friendly, as it skips over most of the neighboring elements in memory during each iteration.
12
12
13
-
To build the Linux kernel module, start by creating a new directory, for example `example_module`. Inside this directory, add two files: `mychardrv.c` and `Makefile`.
13
+
To build the Linux kernel module, start by creating a new directory, for example `example_module`. Inside this directory, add two files: `Makefile` and `mychardrv.c`.
14
14
15
15
## Makefile
16
16
17
+
To build your Linux kernel module for Arm, you need a Makefile that instructs the build system how to compile and link your code against the kernel source. The Makefile below is designed for use with Buildroot and cross-compiles your module for the aarch64 architecture. Update the `BUILDROOT_OUT` variable to match your Buildroot output directory before running the build:
18
+
17
19
```makefile
18
20
obj-m += mychardrv.o
19
21
BUILDROOT_OUT := $(BUILDROOT_HOME)/output # Change this to your buildroot output directory
@@ -28,12 +30,11 @@ clean:
28
30
$(MAKE) -C $(KDIR) M=$(PWD) clean
29
31
```
30
32
31
-
{{% notice Note %}}
32
-
Change `BUILDROOT_OUT` to the correct buildroot output directory on your host machine.
33
-
{{% /notice %}}
34
33
35
34
## mychardrv.c
36
35
36
+
The `mychardrv.c` file contains the source code for your custom Linux kernel module. This module implements a simple character device that demonstrates cache-unfriendly behavior by traversing a two-dimensional array in column-major order. The code below allocates and initializes the array, performs the cache-unfriendly traversal, and exposes a write interface for user input. You’ll use this module to generate measurable performance bottlenecks for analysis with Arm Streamline.
The module above receives the size of a 2D array as a string through the `char_dev_write()` function, converts it to an integer, and passes it to the `char_dev_cache_traverse()` function. This function then creates the 2D array, initializes it with simple data, traverses it in a column-major (cache-unfriendly) order, computes the sum of its elements, and prints the result to the kernel log. The cache-unfriendly aspects allows you to inspect a bottleneck using Streamline in the next section.
205
206
206
-
## Building and Running the Kernel Module
207
+
## Build and run the kernel module
207
208
208
-
1. To compile the kernel module, run make inside the example_module directory. This will generate the output file `mychardrv.ko`.
209
+
To compile the kernel module, run make inside the example_module directory. This generates the output file `mychardrv.ko`.
209
210
210
-
2. Transfer the .ko file to the target using scp command and then insert it using insmod command. After inserting the module, you create a character device node using mknod command. Finally, you can test the module by writing a size value (e.g., 10000) to the device file and measuring the time taken for the operation using the `time` command.
211
+
Transfer the kernel module (`mychardrv.ko`) to your target device using the `scp` command. Then, insert the module with `insmod` and create the character device node with `mknod`. To test the module, write a size value (such as 10000) to the device file and use the `time` command to measure how long the operation takes. This lets you see the performance impact of the cache-unfriendly access pattern in a clear, hands-on way.
211
212
212
-
```bash
213
+
```bash
213
214
scp mychardrv.ko root@<target-ip>:/root/
214
-
```
215
+
```
215
216
216
-
{{% notice Note %}}
217
-
Replace \<target-ip> with your target's IP address
218
-
{{% /notice %}}
217
+
{{% notice Note %}} Replace \<target-ip> with your target's IP address
218
+
{{% /notice %}}
219
219
220
-
3. SSH onto your target device:
220
+
SSH onto your target device:
221
221
222
-
```bash
222
+
```bash
223
223
ssh root@<your-target-ip>
224
-
```
224
+
```
225
225
226
-
4. Execute the following commads on the target to run the module:
227
-
```bash
226
+
Execute the following commads on the target to run the module:
227
+
```bash
228
228
insmod /root/mychardrv.ko
229
229
mknod /dev/mychardrv c 42 0
230
-
```
230
+
```
231
231
232
-
{{% notice Note %}}
232
+
{{% notice Note %}}
233
233
42 and 0 are the major and minor number specified in the module code above
234
-
{{% /notice %}}
234
+
{{% /notice %}}
235
235
236
-
4. To verify that the module is active, run `dmesg` and the output should match the below:
236
+
To verify that the module is active, run `dmesg` and the output should match the below:
237
237
238
-
```bash
238
+
```bash
239
239
dmesg
240
-
```
240
+
```
241
241
242
-
```output
242
+
```output
243
243
[12381.654983] mychardrv is open - Major(42) Minor(0)
244
-
```
244
+
```
245
245
246
-
5. To make sure it's working as expected you can use the following command:
246
+
To make sure it's working as expected you can use the following command:
247
247
248
-
```bash { output_lines = "2-4" }
248
+
```bash { output_lines = "2-4" }
249
249
timeecho'10000'> /dev/mychardrv
250
250
# real 0m 38.04s
251
251
# user 0m 0.00s
252
252
# sys 0m 38.03s
253
-
```
253
+
```
254
254
255
-
The command above passes 10000 to the module, which specifies the size of the 2D array to be created and traversed. The **echo** command takes a long time to complete (around 38 seconds) due to the cache-unfriendly traversal implemented in the `char_dev_cache_traverse()` function.
255
+
The command above passes 10000 to the module, which specifies the size of the 2D array to be created and traversed. The **echo** command takes a long time to complete (around 38 seconds) due to the cache-unfriendly traversal implemented in the `char_dev_cache_traverse()` function.
256
256
257
257
Great job building and running your kernel module! Now that you have a working example, you're ready to take the next step: profiling it with Arm Streamline. In the following section, you'll use Streamline to capture runtime behavior, identify performance bottlenecks, and see firsthand how cache-unfriendly access patterns impact your module. Get ready to gain valuable insights and optimize your code!
0 commit comments