Adhering to high-quality original content, rejecting content piling, if you like it, please click the star above to bookmark, and you will receive updates immediately, thank you for your attention!
In this section, we will begin the explanation of character device drivers. As an introduction, we will discuss the concept of device drivers, and I will provide what can be considered my exclusive summary of how BSP engineers classify devices, which is very important for the subsequent study of BSP driver development.
1. Concept of Traditional Device Types
Device Driver serves as a bridge between the operating system kernel and hardware, allowing hardware and software developers to focus on their respective parts to achieve collaborative development:
-
It abstracts the kernel and hardware implementation from the user, providing a unified access interface to the upper-level software.
-
It integrates device logic downwards, calling the abstracted controller interfaces provided by the kernel to communicate with the corresponding hardware controllers.
Regarding the classification of device types, the most commonly encountered concepts are to divide device drivers into three categories:
-
Character Device (char device): Accessed sequentially in a byte stream manner, accessed through
<span>/dev/*</span>, such as EEPROMs, temperature and humidity sensors, etc. -
Block Device (block device): Accessed in units of data blocks, allowing random read and write, accessed through
<span>/dev/sdX</span>and<span>/dev/mmcblkX</span>, such as hard drives and SD cards. -
Network Device (network device): Not accessed through
<span>/dev</span>, but registered as network card interfaces (<span>ethX</span>and<span>wlanX</span>), following the network protocol stack, such as Ethernet cards and Wi-Fi modules.
In the design of the Linux kernel device abstraction model, the Linux kernel processes user space interfaces for devices according to <span>char / block / net</span> three categories.
This classification method is based on the user space perspective, categorizing devices through different types of operation interfaces provided by the kernel.
2. BSP Classification of Device Types
I believe the above classification method has certain limitations, as many students may not understand its core principles, leading to confusion regarding the concept of device types, which in turn creates obstacles in the subsequent learning and development of BSP drivers. Therefore, today I want to focus on the classification of device types from the BSP driver perspective.
I have not found authoritative books or materials to back this classification method; I am merely summarizing my years of development experience as a BSP engineer. I believe this classification method will be more helpful in understanding the BSP driver framework.
Combining the previous concept of three types of devices in user space, we can have a more comprehensive and in-depth understanding of device drivers.
To conclude,in BSP drivers, devices are similarly classified into three categories based on hardware: on-chip bus devices, off-chip devices, and CPU internal devices.
The terms on-chip and off-chip refer to the internal and external aspects of SoC chips, while various controllers on the SoC are connected to the CPU core via the AMBA bus. Therefore, we need to understand what the AMBA bus is.
2.1 AMBA Concept
AMBA (Advanced Microcontroller Bus Architecture) is the interconnect architecture between the CPU, memory, and peripherals within an SoC, defining various bus protocols under different performance requirements, including AXI (Advanced eXtensible Interface), AHB (Advanced High-performance Bus), and APB (Advanced Peripheral Bus).
AXI/AHB: Both are high-speed AMBA buses, with AXI being the newer high-speed bus protocol. In mainstream high-performance SoCs, such as the ARM Cortex-A series, AXI is used, connecting high-speed peripherals like <span>USB</span>, <span>UFS</span>, <span>ETH</span>, and <span>DMA</span>. These high-speed devices have relatively complex protocols, so their drivers are also more complex.
APB: A low-speed bus, derived from the <span>AXI/AHB</span> through an <span>APB</span> bridge. Due to the complexity of high-speed bus protocols and their significant hardware resource consumption, some low-speed peripherals like <span>I2C</span>, <span>SPI</span>, and <span>GPIO</span> typically only require simple register read and write operations. Therefore, ARM defined the <span>APB</span> bus to save chip area (reducing gate circuits) and power consumption.
The relationship between the AMBA bus and controllers is shown in the figure below:

2.2 BSP Classification of Device Types
Now that we understand the concept of the AMBA bus, we can comprehend that from the bottom-up BSP perspective, hardware is divided into:
| Driver Classification (Hardware Perspective) | Description | Examples |
| On-chip Bus Devices | Connected internally within the SoC via AMBA, directly operating registers, providing off-chip communication capabilities | I²C, SPI, UART, USB |
| CPU Internal Functional Peripherals | Connected to AMBA but perform functions themselves, not driving external devices | Timer, GPIO, PWM, PL011 UART |
| Off-chip Devices | Connected to the bus, managed by controllers, providing specific functions | EEPROM (I²C), SPI Flash, USB Network Card |
On-chip bus devices: Peripheral controller modules integrated within the SoC, directly mounted on AMBA. They are not final functional devices themselves; they contain physical buses and are managed by drivers for their respective bus protocols, such as <span>I2C</span>, <span>SPI</span>, and <span>USB</span>, used to connect and access actual off-chip functional devices.
CPU internal functional peripherals: Integrated within the CPU core or SoC, also mounted on AMBA, but they are final functional units themselves and do not connect to other devices,<span>GPIO</span>, <span>RTC</span>, <span>UART</span>, and <span>WDT</span> are examples of this type of device.
Off-chip devices: They are not directly connected to the AMBA bus of the SoC and are not internal to the SoC, but are board-level integrated and must be accessed through the corresponding controller drivers. For example, temperature and humidity sensors, <span>EEPROM</span> typically use the <span>I2C</span> bus, <span>Nor Flash</span> uses the <span>SPI</span> bus, and mice and keyboards use the <span>USB</span> bus.
Thus, from the hardware perspective, BSP classifies device types based on whether a controller is internal to the SoC, whether it has a bus, and whether it provides functionality.
Additionally, on-chip bus devices have their own physical buses and protocols, forming their own driver frameworks, which are commonly referred to as subsystems, such as the I2C subsystem, USB subsystem, etc.
2.3 Visual Understanding of BSP Device Classification
We can liken an SoC to a company,<span>CPU</span> is the CEO of the company. If it is a small company, the boss can handle everything personally, just like a simple MCU can independently complete many simple tasks.
However, when the company grows to a certain extent, the CEO no longer has time to handle all tasks, so departments need to be divided and supervisors assigned.<span>I2C</span>, <span>SPI</span>, and <span>USB</span> these on-chip controllers are the supervisors of their respective departments.
Off-chip devices mounted on the buses of various controllers are their subordinates. Subordinates do not report work to the CEO but to their immediate supervisors, who then report to the boss.
3. Is I2C a Character Device?
Returning to device drivers, when a student wants to learn character device drivers, searching for information will likely yield the following answer.

Now that we have learned to distinguish device types from both software and hardware perspectives, it is clear that <span>I2C/SPI</span> are on-chip bus controllers, while LED lights/buttons are off-chip peripherals. Putting them together, whether from a hardware or software concept, is confusing. Therefore, this statement cannot be said to be completely wrong; it holds true in certain contexts but is not rigorous enough.
The I2C driver in Linux is divided into <span>I2C</span> bus drivers + <span>I2C</span> device drivers. When accessed from user space, it is usually through device nodes like <span>/dev/i2c-*</span>, which are character device files. Therefore, from the user space perspective, it is indeed a character device driver.
However, as BSP engineers, we cannot understand it this way,we must not ignore the concepts of bus and controller!!
The <span>I2C</span> in the Linux kernel is not simply a “character device”; it has its own bus driver (bus driver) framework, including:
-
Adapter Driver (
<span>adapter_driver</span>) — Corresponds to the underlying controller (I2C controller hardware) -
Device Driver (
<span>client_driver</span>) — Corresponds to specific<span>I2C</span>slave devices (such as EEPROMs, sensors, etc.) mounted on the bus -
I2C Core (
<span>i2c_core.c</span>) — Manages the registration and matching of devices, buses, and adapters
Therefore, without the concepts of bus and controller, when learning about the <span>I2C</span> subsystem, one will not be able to understand concepts like <span>i2c_adapter</span>, <span>i2c_dev</span>, and <span>i2c_bus</span>.
4. Significance of BSP Device Classification
Finally, I want to explain why I emphasize the concept of device classification. A significant part of it is due to the development of the embedded industry. In the past decade, domestic driver development has leaned towards peripheral driver development, such as network card drivers, camera drivers, etc., which all belong to board-level driver development.
Opportunities for SoC-level driver development are relatively scarce domestically, so the mainstream tutorial books are still based on early classic device driver development books like LDD.
However, this brings about a problem: when a driver engineer places <span>I2C</span> and <span>LCD</span> buttons together and calls it a character device, it indicates that they do not have the concept of a bus. This can lead to confusion when developing BSP drivers, such as when dealing with structures like <span>i2c_i2c_bus</span> and <span>spi_bus</span>, as they will not be able to clarify the relationships involved.
I have also found that this confusion is common when I act as an interviewer, which is why I wanted to create this series on the essential kernel knowledge for BSP engineers.
5. Embedded Driver Engineer vs. BSP Driver Engineer
Now we can answer a frequently asked question from the audience: what is the difference between embedded driver engineers and BSP engineers?
-
Embedded driver engineers are typically board-level driver engineers, focusing on the development of off-chip device drivers, implementing device functionality by calling kernel interfaces. Their superior is the user-level application, and their subordinate is the kernel-provided interface.
-
BSP engineers generally work at the SoC level, focusing on on-chip controllers, developing and debugging controller drivers based on chip manuals and hardware protocols. Their superior is the kernel, and their subordinate is directly facing the SoC.
The former connects users and the kernel, while the latter connects the kernel and hardware.

6. Summary
This section serves as the introduction to character device drivers. Before formally discussing character device driver development, we explained the concept of device types, where character devices, block devices, and network devices are distinguished through interfaces provided by the kernel.
BSP drivers, on the other hand, are classified from the hardware perspective based on whether the hardware is internal or external to the SoC and whether it connects to the AMBA bus.
The benefit of this is to distinguish between software and hardware concepts, laying the foundation for future BSP driver development.
Next, we will formally enter the study of character device driver development, and we will eventually develop a serial port driver program from scratch based on the QEMU environment. The topics we will cover in this chapter include:
-
Character device driver framework and the use of new and old interfaces (register_char_dev/cdev)
-
Automatic registration nodes and manual registration nodes
-
Developing a serial port driver from scratch based on the QEMU environment
-
Underlying principles of the character device framework
If you like it, please give a thumbs up, recommend, and follow; it really means a lot to me!!!
– END –
If you have any questions, feel free to add me on WeChat for discussion. I have created a small group, and I will gradually add some industry leaders I know, all of whom are engineers from top companies at P7 level and above. Any questions regarding the industry, work, or job-hopping can be discussed in the group~~

Self-introduction:Previously worked at AMD, currently a senior BSP engineer in a major chip department.Advocating pragmatism, I believe in learning by doing.Series Introduction:The Essential Kernel Skills for BSP Engineers, aimed at explaining kernel knowledge and underlying principles that will be used by driver and BSP engineers in their work.Previous Recommendations:Ubuntu 24.04 + QEMU + ARMV8 + Linux 6.12 Comprehensive Development Environment Setup TutorialAs we enter the AI era, the irreplaceability of low-level software engineers is becoming increasingly prominent.