Skip to content

Commit 6fddae6

Browse files
Refine documentation for building and profiling Linux kernel modules with Arm Streamline, enhancing clarity in setup instructions, package requirements, and profiling steps.
1 parent 08f97b2 commit 6fddae6

8 files changed

Lines changed: 30 additions & 27 deletions

File tree

content/learning-paths/embedded-and-microcontrollers/streamline-kernel-module/2_build_kernel_image.md

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -6,11 +6,11 @@ weight: 3
66
layout: learningpathall
77
---
88

9-
## Prepare your development environment for Buildroot on Arm
9+
## Prepare to build Linux image with Buildroot
1010

11-
Before you build a Linux image with Buildroot, make sure your development environment includes all 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.
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.
1212

13-
## Install required packages for Buildroot on Arm
13+
## Install required packages for Buildroot
1414

1515
Run the following commands on your aarch64-based Linux system to update your package list and install the necessary dependencies:
1616

@@ -26,9 +26,9 @@ These packages ensure that Buildroot can configure, compile, and assemble all th
2626

2727
## Build a debuggable kernel image
2828

29-
For this Learning Path you'll be using [Buildroot](https://github.com/buildroot/buildroot) to build a Linux image for Raspberry Pi 3B+ with a debuggable Linux kernel. You'll profile Linux kernel modules built out-of-tree and Linux device drivers built in the Linux source code tree.
29+
For this Learning Path you'll build a Linux image for Raspberry Pi 3B+ with a debuggable Linux kernel. You'll profile Linux kernel modules built out-of-tree and Linux device drivers built in the Linux source code tree.
3030

31-
Start by cloning the Buildroot Repository and initialize the build system with the default configurations:
31+
Start by cloning the Buildroot repository and initialize the build system with the default configurations:
3232

3333
```bash
3434
git clone https://github.com/buildroot/buildroot.git
@@ -45,7 +45,7 @@ make menuconfig
4545

4646
![Buildroot menuconfig interface showing configuration options. The screen displays a blue dialog box with white text and a highlighted menu. The main menu lists Build options, System configuration, Kernel, and Target packages. The Build options section is selected, and sub-options include build packages with debugging symbols, gcc debug level set to debug level 3, and build packages with runtime debugging info. The environment is a text-based terminal interface, typical for embedded Linux development. The tone is technical and instructional, guiding users through enabling debugging features in Buildroot. alt-text#center](./images/menuconfig.png)
4747

48-
Change Buildroot configurations to enable debugging symbols and SSH access:
48+
Change the Buildroot configuration to enable debugging symbols and SSH access:
4949

5050
```plaintext
5151
Build options --->
@@ -72,7 +72,7 @@ You might need to update your default `sshd_config` file to match your network r
7272

7373
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.
7474

75-
Open the kernel configuration menu with:
75+
Open the kernel configuration menu using the following:
7676

7777
```bash
7878
make linux-menuconfig
@@ -111,7 +111,7 @@ sdcard.img
111111

112112
If you see `sdcard.img` listed, your image is ready to be flashed to your SD card. You can now flash this image to your SD card and boot your Raspberry Pi with a debuggable Linux kernel.
113113

114-
For details on flashing the SD card image, see [this helpful article](https://www.ev3dev.org/docs/tutorials/writing-sd-card-image-ubuntu-disk-image-writer/).
114+
For details on flashing the SD card image, see the article [Writing an SD Card Image Using Ubuntu Disk Image Writer](https://www.ev3dev.org/docs/tutorials/writing-sd-card-image-ubuntu-disk-image-writer/).
115115

116116
## What you've accomplished and what's next
117117

content/learning-paths/embedded-and-microcontrollers/streamline-kernel-module/3_oot_module.md

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
---
2-
title: Build out-of-tree kernel module
2+
title: Build the out-of-tree kernel module
33
weight: 4
44

55
### FIXED, DO NOT MODIFY
@@ -8,11 +8,11 @@ layout: learningpathall
88

99
## Create an out-of-tree Linux kernel module
1010

11-
You will 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.
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.
1212

1313
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`.
1414

15-
**Makefile**
15+
## Makefile
1616

1717
```makefile
1818
obj-m += mychardrv.o
@@ -29,10 +29,10 @@ clean:
2929
```
3030

3131
{{% notice Note %}}
32-
Change **BUILDROOT_OUT** to the correct buildroot output directory on your host machine.
32+
Change `BUILDROOT_OUT` to the correct buildroot output directory on your host machine.
3333
{{% /notice %}}
3434

35-
**mychardrv.c**
35+
## mychardrv.c
3636

3737
```c
3838
// SPDX-License-Identifier: GPL-2.0

content/learning-paths/embedded-and-microcontrollers/streamline-kernel-module/4_sl_profile_oot.md

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
---
2-
title: Profile out-of-tree kernel module
2+
title: Profile the out-of-tree kernel module
33
weight: 5
44

55
### FIXED, DO NOT MODIFY
@@ -68,7 +68,7 @@ If you are using an AArch32 target, use `arm` instead of `arm64`.
6868
sh -c "echo 10000 > /dev/mychardrv"
6969
```
7070

71-
![Streamline command#center](./images/img04_streamline_cmd.png)
71+
![Streamline command#center alt-text#center](./images/img04_streamline_cmd.png)
7272

7373
8. In the Capture settings dialog, select Add image, add the absolut path of your kernel module file `mychardrv.ko` and click Save.
7474
![Streamline Capture settings dialog showing fields for adding an image and specifying the absolute path to the kernel module file mychardrv.ko. The dialog includes labeled input fields and buttons for saving the configuration. The wider environment is a desktop application window focused on performance profiling setup. Text in the image includes labels such as Add image and fields for entering file paths. The emotional tone is neutral and technical, supporting a step-by-step configuration process for Arm performance analysis. alt-text#center](./images/img05_capture_settings.png)
@@ -85,21 +85,21 @@ Once the capture is stopped, Streamline automatically analyzes the collected dat
8585
<!--
8686
Alt text: Screenshot of the Streamline profiling tool interface showing the process of selecting a data source for counters. The main panel displays a list of available data sources with one highlighted, and a sidebar provides navigation options. The environment is a typical software profiling application window with a neutral, professional tone. Visible text includes Counter selection and labels for different data sources.
8787
-->
88-
![Counter selection#center](./images/img07_select_datasource.png)
88+
![Counter selection alt-text#center](./images/img07_select_datasource.png)
8989

9090
2. In the Functions tab, observe that the function `char_dev_cache_traverse()` has the highest L1 Cache refill rate, which is expected.
9191
Also notice the Image name on the right, which is our module file name `mychardrv.ko`:
9292

93-
![Streamline Functions tab displaying a list of functions with performance metrics such as L1 Cache refill rates. The primary subject is the function char_dev_cache_traverse which is highlighted and shows the highest cache refill value. The right side of the table lists the image name as mychardrv.ko. The wider environment is a desktop profiling application window with columns labeled Function, Image, and various performance counters. Visible text includes function names, image names, and numerical metric values. The emotional tone is neutral and technical, supporting detailed analysis for Arm kernel module profiling.](./images/img08_Functions_Tab.png)
93+
![Streamline Functions tab displaying a list of functions with performance metrics such as L1 Cache refill rates. The primary subject is the function char_dev_cache_traverse which is highlighted and shows the highest cache refill value. The right side of the table lists the image name as mychardrv.ko. The wider environment is a desktop profiling application window with columns labeled Function, Image, and various performance counters. Visible text includes function names, image names, and numerical metric values. The emotional tone is neutral and technical, supporting detailed analysis for Arm kernel module profiling. alt-text#center](./images/img08_Functions_Tab.png)
9494

9595
3. To view the call path of this function, right click on the function name and choose *Select in Call Paths*.
9696

9797
4. You can now see the exact function that called `char_dev_cache_traverse()`. In the Locations column, notice that the function calls started in the userspace (`echo` command) and terminated in the kernel space module `mychardrv.ko`:
98-
![Streamline Call Paths tab displaying a hierarchical call stack with the function char_dev_cache_traverse highlighted. The primary subject is the call path tree, showing the sequence of function calls from userspace echo command through to the kernel module mychardrv.ko. The wider environment is a desktop profiling application window with columns labeled Function, Image, and performance counters. Visible text includes function names, image names, and numerical metric values. The emotional tone is neutral and technical, supporting detailed analysis for Arm kernel module profiling and helping users trace performance issues through the call stack.](./images/img09_callpaths_tab.png)
98+
![Streamline Call Paths tab displaying a hierarchical call stack with the function char_dev_cache_traverse highlighted. The primary subject is the call path tree, showing the sequence of function calls from userspace echo command through to the kernel module mychardrv.ko. The wider environment is a desktop profiling application window with columns labeled Function, Image, and performance counters. Visible text includes function names, image names, and numerical metric values. The emotional tone is neutral and technical, supporting detailed analysis for Arm kernel module profiling and helping users trace performance issues through the call stack. alt-text#center](./images/img09_callpaths_tab.png)
9999
100100
5. Since you compiled the kernel module with debug info, you will be able to see the exact code lines that are causing these cache misses.
101101
To do so, double-click on the function name and the *Code tab* opens. This view shows you how much each code line contributed to the cache misses and in bottom half of the code view, you can also see the disassembly of these lines with the counter values of each assembly instruction:
102-
![Streamline Code tab displaying annotated source code and disassembly for the function char_dev_cache_traverse in the kernel module mychardrv.ko. The primary subject is the code analysis panel, which highlights individual lines of C source code and corresponding assembly instructions, each with associated cache miss metrics. The top half of the window shows the source code with numerical values indicating cache misses per line, while the bottom half presents the disassembly view with counter values for each instruction. The wider environment is a desktop profiling application window with labeled columns such as Function, Image, and performance counters. Visible text includes function names, source code lines, assembly instructions, and numerical metric values. The emotional tone is neutral and technical, supporting detailed analysis for Arm kernel module profiling and helping users identify performance bottlenecks at the code level.](./images/img10_code_tab.png)
102+
![Streamline Code tab displaying annotated source code and disassembly for the function char_dev_cache_traverse in the kernel module mychardrv.ko. The primary subject is the code analysis panel, which highlights individual lines of C source code and corresponding assembly instructions, each with associated cache miss metrics. The top half of the window shows the source code with numerical values indicating cache misses per line, while the bottom half presents the disassembly view with counter values for each instruction. The wider environment is a desktop profiling application window with labeled columns such as Function, Image, and performance counters. Visible text includes function names, source code lines, assembly instructions, and numerical metric values. The emotional tone is neutral and technical, supporting detailed analysis for Arm kernel module profiling and helping users identify performance bottlenecks at the code level. alt-text#center](./images/img10_code_tab.png)
103103
104104
{{% notice Note %}}
105105
You may need to configure path prefix substitution in the Code tab to view the source code correctly. For details on how to set this up and for more information about code analysis, please refer to [Streamline user guide](https://developer.arm.com/documentation/101816/latest/Analyze-your-capture/Analyze-your-code?lang=en)

content/learning-paths/embedded-and-microcontrollers/streamline-kernel-module/5_intree_kernel_driver.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
---
2-
title: Build in-tree kernel driver
2+
title: Build the in-tree kernel driver
33
weight: 6
44

55
### FIXED, DO NOT MODIFY

content/learning-paths/embedded-and-microcontrollers/streamline-kernel-module/6_sl_profile_intree.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
---
2-
title: Profile in-tree kernel driver
2+
title: Profile the in-tree kernel driver
33
weight: 7
44

55
### FIXED, DO NOT MODIFY
@@ -26,4 +26,4 @@ After clicking Save in Capture settings dialog, you can start the capture and an
2626
Since you used `vmlinux` image, you can view the driver functions as well as all other kernel functions that were sampled during the capture.
2727

2828
You can also view the full Call path of any sampled function within the kernel.
29-
![Vmlinux call paths tab#center](./images/img13_vmlinux_callpaths_tab.png)
29+
![Streamline call paths tab displaying hierarchical call stack data for vmlinux. The main section shows a tree view of kernel function calls, with each function indented to indicate its position in the call hierarchy. Columns display metrics such as sample count and percentage of total samples for each function. The selected function is highlighted, and the interface uses a neutral, technical design typical of performance profiling tools. Visible text includes Call Paths, Sample Count, and Percentage. The wider environment features other Streamline tabs and configuration options, supporting a focused, analytical workflow.](./images/img13_vmlinux_callpaths_tab.png)

content/learning-paths/embedded-and-microcontrollers/streamline-kernel-module/7_sl_spe.md

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
---
2-
title: Using Streamline with Statistical Profiling Extension
2+
title: Using Streamline with the Statistical Profiling Extension
33
weight: 8
44

55
### FIXED, DO NOT MODIFY
@@ -25,4 +25,7 @@ To view SPE counter values, Select SPE in the data source drop-down in the Call
2525

2626
As shown in the image, SPE provides much more data about the profiled code than Event-Based Sampling (EBS), which provides us with deep insights into the CPU performance bottlenecks with very low overhead. It's also possible to view or hide columns from the table in Call paths or Functions views by menu-clicking on the table header and choosing from the list of columns.
2727

28-
![SPE function tab#center](./images/img15_spe_function_tab.gif)
28+
![Streamline SPE function tab showing profiling results#center](./images/img15_spe_function_tab.gif)
29+
<!--
30+
Alt text: Streamline application window displaying the Statistical Profiling Extension (SPE) function tab. The main area lists functions with columns for metrics such as sample count, percentage, and address. The user interface highlights the SPE data source in the drop-down menu. The environment is a typical developer desktop with a focus on performance profiling results. The tone is technical and informative.
31+
-->

content/learning-paths/embedded-and-microcontrollers/streamline-kernel-module/8_summary.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,6 @@ layout: learningpathall
77
---
88
## Summary
99

10-
In this learning path, you learned how to build and profile Linux kernel modules step by step. You started with an out-of-tree character driver that had a cache performance issue and then used Arm Streamline to spot where the problem was. Later, you tried the same idea with an in-tree driver and saw how profiling works with the full kernel. Although the example problem was simple, the same methods apply to complex, real-world drivers and scenarios.
10+
In this Learning Path, you learned how to build and profile Linux kernel modules one step at a time. You started with an out-of-tree character driver that had a cache performance issue. Using Arm Streamline, you found where the problem was. Then, you applied the same profiling approach to an in-tree driver and saw how it works with the full kernel. While the example was simple, you can use these methods for more complex, real-world drivers and situations.
1111

12-
The key takeaway is that profiling isn’t just about making code faster—it’s about understanding how your code talks to the hardware. Streamline gives us a clear picture of what’s happening inside the CPU so you can write better, more efficient drivers. By learning to identify bottlenecks, you will be more confident in fixing them and avoiding common mistakes in kernel programming.
12+
The key takeaway is that profiling isn’t just about making code faster.It’s about understanding how your code talks to the hardware. Streamline provides a clear picture of what’s happening inside the CPU so that you can write better, more efficient drivers. By learning to identify bottlenecks, you'll be more confident in fixing them and avoiding common mistakes in kernel programming.

content/learning-paths/embedded-and-microcontrollers/streamline-kernel-module/_index.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ learning_objectives:
1515

1616
prerequisites:
1717
- Basic understanding of Linux kernel development and module programming
18-
- Arm-based Linux target device (such as a Raspberry Pi, BeagleBone, or similar board) with SSH access
18+
- Arm-based Linux target device (such as a Raspberry Pi, BeagleBone, or similar board) with Secure Shell (SSH) access
1919
- A host machine that meets [Buildroot system requirements](https://buildroot.org/downloads/manual/manual.html#requirement)
2020

2121
author: Yahya Abouelseoud

0 commit comments

Comments
 (0)