Linux

21 Posts

Why GPIO, pinctrl, clock, regulator, and reset Are Driver Lifecycle Resources

7 minute

Many embedded Linux device bugs look like register-access bugs: probe runs, register mapping succeeds, but reads return invalid values; interrupts never arrive; an I2C device randomly NACKs; the first access after resume fails.

The problem is not always in register access.

Whether hardware works often depends on more basic resources first: pins must be muxed correctly, clocks must be enabled, power must be stable, reset must be released, and GPIO polarity must be correct.

Read More

Why Linux DMA mapping API Cannot Use Raw Pointers

7 minute

A common DMA driver bug looks like this: the CPU prepared a buffer, but the device reads old data; the device finished DMA, but the CPU still sees old values; the driver works on one SoC but fails after enabling IOMMU.

The usual root cause is treating a CPU pointer as an address the device can use.

In Linux, user virtual addresses, kernel virtual addresses, physical addresses, and DMA addresses are different layers. A device should receive a DMA address, not an ordinary C pointer.

Read More

How Interrupts, Wait Queues, and poll Connect in Linux Drivers

7 minute

An application waits on a device fd with poll() or epoll_wait(). The hardware has already raised an interrupt, but the application never wakes. Or the application wakes repeatedly, but read() returns no data.

This kind of bug usually does not live in one function. It comes from interrupts, buffers, wait queues, and poll semantics not agreeing with each other.

A hardware interrupt does not deliver data directly to an application. It only tells the CPU that a device event happened. The driver must turn that event into kernel-visible state and wake the processes waiting for it.

Read More

What char devices and file_operations Expose to User Space

8 minute

In Linux driver debugging, user space often sees a /dev/xxx node.

An application can open() it, read() from it, write() to it, or control it with ioctl(). It looks as if the device is a file.

But a char device is not “hardware handed directly to the application.” /dev/xxx is only a user-space entry. What actually decides what each call means is the char device object registered by the driver and its file_operations.

Read More

Why platform driver probe Happens

8 minute

platform_driver is common in embedded Linux. SoC internal peripherals such as UART, I2C controllers, SPI controllers, PWM, watchdogs, GPIO controllers, clock controllers, and interrupt controllers often use platform drivers.

When debugging this kind of driver, the most common problem is not a wrong register write. It is that probe never happens.

The Device Tree node exists, and the driver is built in, but why does probe not run?
The compatible string looks right, but why does it not match?
probe runs, but why are resources missing?
What does EPROBE_DEFER in the log mean?

Read More

Why the Linux Driver Model Separates device, driver, and bus

8 minute

A common Linux driver problem looks like this: the driver is built into the kernel, the Device Tree node exists, but probe never runs. Or probe runs but cannot obtain resources. Or the module loads successfully, but no device node appears.

If you only stare at the driver C file, this kind of problem is easy to misread.

A Linux driver is not “a hardware library function called by an application.” It first has to enter the kernel device model. The kernel needs to know which devices exist, which drivers exist, and what rules match them. Only after a match succeeds does the driver get a chance to initialize the hardware.

Read More

Why Device Tree and Board Description Affect Driver Probe

8 minute

A common Linux device-debugging problem looks like this: the driver code did not change, the kernel boots, but the device never probes. The log may only say probe failed, or the driver may never be entered at all.

The problem is not always in C code.

On many embedded Linux platforms, whether a driver can find a device and obtain register ranges, interrupts, clocks, power supplies, GPIOs, and DMA channels first depends on whether the board description is correct. On ARM, RISC-V, and many embedded platforms, that description is usually Device Tree.

Read More

Why a System Call Is Not a Normal Function Call

7 minute

Application code calls read(), write(), open(), or mmap() in a way that looks very similar to an ordinary function call. Pass a few arguments, receive a return value, check errno on failure.

But a system call is not a normal function call.

A normal function call stays inside the same process, privilege level, and address space. A system call moves the CPU from user space into kernel space and hands control to the kernel. The kernel does not receive “trusted arguments.” It receives a request from user space: whether the file descriptor is valid, whether the pointer is accessible, whether the length is safe, whether the process has permission, and whether the call should block all have to be checked.

Read More

What Embedded Linux Does From Bootloader to User Space

7 minute

When an embedded Linux device boots slowly, an application does not start, a driver does not load, or a network service fails, people often jump straight to application logs.

But the application is only the last part of the boot chain. After power-on, the CPU does not directly jump to business logic. It starts from a fixed entry, initializes the minimal hardware environment, enters the bootloader, loads the Linux kernel, Device Tree, and rootfs-related information, waits for the kernel to reach user space, and only then reaches the application.

Read More

What Happens From Power-On to Application Start?

5 minute

When a device boots slowly, an application does not start, a driver does not load, or a network service fails, people often jump straight to application logs.

But the application is only the last part of the boot chain. After power-on, the CPU does not directly jump to business logic. It starts from a fixed entry, initializes the minimal hardware environment, finds the next-stage image, loads an OS or RTOS, initializes memory, devices, and scheduling, and only then reaches the application.

Read More