Regarding how to learn the Embedded Linux kernel, I have some personal insights and understandings that I would like to share. Everyone has their own methods for learning the Linux kernel, and it varies from person to person. Generally, engineers engaged in embedded Linux driver and kernel development can be divided into two types: one focuses on product research and development, while the other engages in open-source communities. As someone who has worked in FAE for many years, I believe that learning the Linux kernel efficiently involves sharing some of my personal learning experiences.
Kernel Learning The Linux kernel’s functionality is becoming increasingly comprehensive. If you do not have ample time, delving deeply into the kernel is not very realistic. Therefore, I recommend starting with a book on the kernel. The first read will be confusing; after reflecting on it, browse through it again. You can imagine how an OS operates, which helps avoid getting lost in the details of the Linux kernel; ultimately, you can delve into the subsystem that interests you or that you need.
Recommended reading: Linux Kernel Development
Even within a subsystem, the content is vast. A labor-saving approach is to search online for related articles to quickly understand the operation of that subsystem; then, combine it with code to form your understanding and summarize it. If you just want to quickly understand the operation of a certain subsystem, you can refer to some early annotated books on code and then look at the latest code implementations when you dive deeper.
Understanding the kernel is a repetitive process; it may not be perfect at first, and you may need to correct yourself repeatedly. Do not get caught up in this correction process; instead, continue to use and learn, and delve deeper when you find something unclear, as the Linux kernel is constantly evolving.
An excellent way to start is from system calls. There is a lot of data available on this topic, and the semantics of system calls are explained, which can indirectly help you understand some concepts of the Linux system. Once you are familiar with system calls, you can get a general idea of how the kernel operates based on the execution process of system calls; however, when tracing system calls, be careful to follow the main line. The current kernel system is very complex, and certain code paths may involve multiple subsystems. You can guess their functionality from their names without needing to delve deeper; otherwise, you may find your energy completely scattered.
Even within a subsystem, the content is vast. A labor-saving approach is to search online for related articles to quickly understand the operation of that subsystem; then, combine it with code to form your understanding and summarize it. If you just want to quickly understand the operation of a certain subsystem, you can refer to some early annotated books on code and then look at the latest code implementations when you dive deeper.
Understanding the kernel is a repetitive process; it may not be perfect at first, and you may need to correct yourself repeatedly. Do not get caught up in this correction process; instead, continue to use and learn, and delve deeper when you find something unclear, as the Linux kernel is constantly evolving.
Another excellent way to start is from system calls. There is a lot of data available on this topic, and the semantics of system calls are explained, which can indirectly help you understand some concepts of the Linux system. Once you are familiar with system calls, you can get a general idea of how the kernel operates based on the execution process of system calls; however, when tracing system calls, be careful to follow the main line. The current kernel system is very complex, and certain code paths may involve multiple subsystems. You can guess their functionality from their names without needing to delve deeper; otherwise, you may find your energy completely scattered.
Learning the Linux kernel requires a significant amount of abstract thinking ability. Here, abstraction simply refers to distinguishing between interfaces and their implementations. Since there are many subsystems in the Linux kernel, many subsystems overlap, making code paths appear very complex. When reading code, to eliminate distractions, it is essential to distinguish what you need to look at from the interfaces of other subsystems. For the interfaces of other subsystems, assume that their functionality is complete and won’t cause problems, allowing you to focus on the key points. For example, an application program’s code can be quite large, like an Apache project, which contains many components. Sometimes, when reading the code, you may see APIs from different components. It is not realistic to delve into the implementations of related components, so distinguishing between primary and secondary aspects can be very helpful for reading code. You cannot, for example, stop to understand the implementation of malloc every time you see it.
Recommended reading: Linux System Programming (2nd Edition) by Robert Love
Linux Programming Interface: Linux and Unix System Programming Manual
Driver Development has always revolved around servers, with a significant focus on network card drivers. Initially, I thought about studying the protocol stack thoroughly from top to bottom, but I found the content overwhelming and progress slow. Later, I referred to some books on driver development, isolating the driver while using the kernel-provided interfaces. It is similar to how, when writing applications, you often only need to understand the system interfaces and library function prototypes without needing to delve deeper. This approach liberates you from the complex implementation details of the kernel, allowing you to focus on the features of the network card; afterward, you can further understand the operational process of the device, such as the position and operation of packet transmission and reception in the protocol stack. Personally, I feel it is best to have exposure to driver development in your work; otherwise, in many cases, some devices are not commonly encountered, like Infiniband cards.
Now, as consumer devices become increasingly widespread, you can choose devices that interest you and are readily available for research, such as wireless network cards, WiFi, etc. You must first focus on one device, familiarize yourself with it from start to finish, then summarize how driver development works, how drivers relate to the system, and how Linux adopts a layered model to provide support for various devices, similar to the abstract layers of VFS.
Recommended reading: Linux Device Drivers (3rd Edition)
How to Study Linux Kernel Subsystems?
The Linux kernel has hundreds of driver subsystems. Have you studied the commonalities and hierarchical design of various kernel driver subsystems? Do you already possess experience in the design of Linux kernel subsystems, such as USB, I2C, HID, etc.?
From my learning perspective, each subsystem is enormous and involves various hardware specifications, making it challenging to understand everything. You can only dive deeper into a specific part when facing issues. Previously, I learned about the SCSI architecture, which has an upper-level abstraction, a middle-layer bridge, and a bottom-level device driver control. If you only do driver work, you can focus on the device features; for the Linux kernel part, you only need to understand the driver interface and basic functionalities like synchronization and memory management.
Design Philosophy of Linux Kernel Drivers
The Linux device driver model views devices from a classification perspective, which is multi-dimensional, hence there are multiple directories under /sys. Additionally, the device driver model provides layout information about devices in the system; for example, based on the bus address, you can locate the corresponding device directory, etc. Linux kernel drivers can follow a layered abstract architecture: the uppermost abstract layer facilitates system software access, the middle layer implements hardware protocol details, while providing interfaces connecting the upper and lower layers. For the lowest layer driver, it must define the interfaces to be implemented and the actual device control.
Due to the support of various driver frameworks in the Linux kernel, drivers can focus more on the characteristics of the devices themselves.
In the process of Linux embedded development, we often encounter many tricky issues, such as memory leaks, kernel stack overflows, and network packet loss. When locating these issues, if there is no effective method, it often consumes a lot of time to pinpoint and troubleshoot.
This time, the Enthusiast Academy invited Ding, a senior network engineer from Hisense (海信), to conduct a live broadcast, helping to deepen the understanding of debugging techniques and solutions for tricky problems in Linux embedded development. Additionally, he will share the current development status of the embedded industry, helping everyone to find their future career development direction.
Live Broadcast Theme: Hardcore Analysis: Debugging Techniques for Embedded Linux Kernel Development
Live Broadcast Time: July 7, 2020, 8 PM (Next Tuesday)
Live Broadcast Outline: (Knowledge Explanation)
1. Linux Memory Leak Debugging Techniques
2. Kernel Stack Overflow Debugging Techniques
3. Network Packet Loss Debugging Techniques
4. Sharing the Current Development Status of the Embedded Industry
What Problems Can the Live Broadcast Help You Solve?
It helps you gain a deeper understanding of debugging techniques for issues like Linux kernel memory leaks, stack overflows, and network packet loss, mastering the inductive debugging thinking of embedded development, and outlining the latest development status of the embedded industry, helping you better locate your career direction.
Course Instructor:
Ding Guangyu, a senior network engineer from Hisense Broadband Multimedia, has led the development of various smart gateways, switches, ONUs, and smart IoT devices, accumulating extensive practical experience in network communication and embedded system development and debugging. He has years of development experience on platforms like Broadcom, MTK, Realtek, etc. He has a deep understanding of the Linux kernel network protocol stack and various network communication protocols.
Scan the QR code below to register immediately!
Friendly Reminder: To provide you with a better live viewing experience, enjoy high-speed, high-definition, and multiple live viewing services such as reservation and playback, it is strongly recommended that you download the “Electronic Enthusiast” APP to watch.
Click “Read the Original” to download the Enthusiast APP immediately↓↓↓