CPU Execution States on ARM

1. Overview Process Context The kernel executes code on behalf of a user-space process (e.g., handling a system call like read() or write()). Key Properties: Associated with a struct task_struct (process descriptor). Can sleep (use blocking functions like mutex_lock()). Can access user-space memory (via copy_from_user()). Interrupt Context “Atomic context” or “Interrupt context”, The kernel executes code to handle a hardware interrupt or softirq (e.g., a network packet arriving) Key Properties: No associated process (current macro points to an idle task). Cannot sleep (blocking functions like kmalloc(GFP_KERNEL) are forbidden). Runs with interrupts disabled (on the current CPU). 2. CPU Execution States in ARM ARM architectures (e.g., ARMv8-A) define exception levels (ELs) that correspond to CPU execution states: ...

May 4, 2025 · 3 min

System Call (Software Interrupt)

1. System Call Basics System calls (syscalls) are the interface for user-space programs to request services from the kernel. Examples include: File I/O: read(), write(), open(), close(). Device Control: ioctl(). Signal Handling: kill(), signal(). 2. System Call Table and Registration Syscall Table: A table (sys_call_table) maps syscall numbers to handler functions. Architecture-Specific: x86: Defined in arch/x86/entry/syscalls/syscall_64.tbl. ARM: Defined in arch/arm/tools/syscall.tbl. Registration: Syscalls are registered at compile time using macros like SYSCALL_DEFINE (e.g., SYSCALL_DEFINE3(write, ...) for write()). For custom syscalls (rare and discouraged), you would: Add an entry to the syscall table. Define the handler using SYSCALL_DEFINE. Recompile the kernel (or use modules for dynamic insertion). 3. Flow of System Calls 1. User-Space Invocation The libc wrapper (e.g., read(), ioctl()) triggers a software interrupt (int 0x80 on x86) or uses the syscall instruction (modern x86/ARM). // User-space code fd = open("/dev/mydevice", O_RDWR); // Syscall 1: open() read(fd, buf, 100); // Syscall 2: read() ioctl(fd, MY_CMD, arg); // Syscall 3: ioctl() close(fd); // Syscall 4: close() 2. Transition to Kernel Mode Switches to kernel mode (ring 0 on x86, EL1 on ARM). Saves user-space registers (e.g., RIP, RSP, EFLAGS). Jumps to the kernel’s syscall entry point (e.g., entry_SYSCALL_64 on x86) 3. Syscall Dispatching Syscall Number: The syscall number is stored in a register (e.g., RAX on x86, R7 on ARM). Example: __NR_read (syscall number for read()). Syscall Table: The kernel uses sys_call_table (array of function pointers) to find the handler. Example: sys_call_table[__NR_read] points to sys_read(). 4. Handler Execution in Process Context Generic Steps for All Syscalls: Argument Validation: Check pointers (e.g., buf in read()) using access_ok() Copy arguments from user space with copy_from_user() or get_user() Kernel Function Execution: Perform the requested operation (e.g., read from a file, send an ioctl command) File Operations (read/write): File Descriptor Resolution: Convert fd to a struct file using fdget(). Check file permissions (FMODE_READ/FMODE_WRITE). Driver Interaction: Call the read/write method from the file’s file_operations struct. Example: For /dev/mydevice, this invokes the driver’s .read function. I/O Control (ioctl): The ioctl syscall (sys_ioctl()) calls the driver’s .unlocked_ioctl method. !../3-Resource/Platform/IOCTL in Kernel Device Drivers#3. Integrate into file_operations 5. Return to User Space: Result is stored in eax/r0, and the kernel restores user registers Execute iret (x86) or exception return (ARM) to resume user-mode execution. 4. Device File Operations Character devices (e.g., /dev/char_dev) expose operations via file_operations: ...

May 4, 2025 · 4 min

Interrupt

Overview An interrupt is a signal that breaks the normal execution flow to handle an event. When an interrupt occurs, the CPU pauses its current task, jumps to an interrupt service routine (ISR), and after the ISR completes it resumes the original task. In other words, interrupts let hardware or software requests “call” the CPU’s attention immediately, then let the program continue “as if nothing happened” after handling it. Why are interrupts needed? Avoid Polling: More efficient than continuously checking device status (polling), reducing CPU overhead and increasing system throughput Real-Time Responsiveness: Essential for systems requiring quick reactions to events Automotive airbag systems detecting collisions Network Interface Cards (NICs) processing incoming packets Interrupt Types Hardware Interrupts: Triggered by devices (e.g., keyboard, NIC). Managed by the Programmable Interrupt Controller (PIC) or APIC. Software Interrupts: Generated by software (e.g., int 0x80 for syscalls). Exceptions: CPU-generated (e.g., divide-by-zero, page faults). How the Kernel Registers Interrupts Interrupt Descriptor Table (IDT) Initialization: At boot, the kernel populates the IDT with default handlers (e.g., for exceptions). Hardware interrupts are mapped to a generic entry (e.g., common_interrupt on x86). Device Drivers: Drivers request a specific IRQ (Interrupt Request Line) using request_irq(). Example: int request_irq(unsigned int irq, irq_handler_t handler, unsigned long flags, const char *name, void *dev); irq: The interrupt number (e.g., IRQ 1 for keyboard). handler: The ISR function. flags: Options like IRQF_SHARED for shared interrupts. dev: A cookie passed to the ISR (used for shared IRQs). What happens when an interrupt is occurred? See Interrupt Handling Flow ...

May 3, 2025 · 2 min

External Toolchain in Buildroot

Using External Toolchain Option 1: Give tarball URL Specify URL for the tarball in BR_TOOLCHAIN_EXTERNAL_URL Example: BR_TOOLCHAIN_EXTERNAL_URL=http://192.168.101.52:8082/artifactory/toolchain.tar.xz In this case you will have to deselect BR2_PRIMARY_SITE_ONLY option Option 2: Give tarball relative dl path If BR2_PRIMARY_SITE_ONLY option is selected then you have to keep the toolchain inside dl/toolchain-external-custom/ directory and pass the name of tarball to BR_TOOLCHAIN_EXTERNAL_URL Example: BR2_PRIMARY_SITE="http://192.168.101.52:8082/artifactory/dl" BR2_PRIMARY_SITE_ONLY=y BR_TOOLCHAIN_EXTERNAL_URL=nvrx-rk3588-toolcahin.tar.xz This will extract the toolchain to buildroot’s build directory output/host/opt/ext-toolchain ...

April 4, 2025 · 1 min

Generic GPIO Management in Linux

Introduction GPIO (General Purpose Input/Output) is a fundamental interface in embedded systems and Linux-based platforms. Linux provides multiple methods to control GPIOs, including the deprecated /sys/class/gpio/ interface and the modern libgpiod (GPIO character device) API. This document provides a comprehensive guide to managing GPIOs in Linux. GPIO Interfaces in Linux Linux provides three primary ways to manage GPIOs: Legacy Sysfs Interface (/sys/class/gpio/) - Deprecated but still present on some systems. GPIO Character Device (/dev/gpiochipX) - The recommended approach using libgpiod. Direct Kernel Access - Through kernel drivers or device tree configurations. 1. Sysfs GPIO Interface (Deprecated) The sysfs-based interface was historically used to control GPIOs but has been marked as deprecated in favor of gpiod. If still available, it can be accessed via /sys/class/gpio/. ...

February 19, 2025 · 2 min

SPI

SPI (Serial Peripheral Interface) Overview Synchronous, full-duplex serial bus. Master-slave architecture (1 master, multiple slaves). Uses 4 wires: SCLK (clock), MOSI (Master Out Slave In), MISO (Master In Slave Out), SS/CS (Slave Select). Physical Layer Push-pull outputs (faster than open-drain). Each slave requires a dedicated SS line. Data Frame Structure No start/stop bits – continuous stream synchronized to SCLK. Data sampled on clock edges defined by CPOL (clock polarity) and CPHA (clock phase): Mode 0: CPOL=0 (idle low), CPHA=0 (sample on rising edge). Mode 3: CPOL=1 (idle high), CPHA=1 (sample on falling edge). S C L K | M O S I ( D a t a f r o m M a s t e r ) | M I S O ( D a t a f r o m S l a v e ) | C S ( A c t i v e L o w ) Key Features Full-duplex communication (simultaneous MOSI/MISO). No addressing – slaves selected via SS lines. Speeds: Up to 100+ Mbps (depends on hardware). Pros & Cons Pros Cons High-speed communication High pin count (n+3 for n slaves) Simple protocol, flexible modes No built-in error detection Full-duplex support No multi-master support Use Cases High-speed sensors (e.g., IMUs). Display controllers (OLED, TFT). SD cards, NOR flash memory. Comparison Table Feature UART I2C SPI Clock None (async) Shared (SCL) Shared (SCLK) Duplex Full-duplex Half-duplex Full-duplex Topology Point-to-point Multi-device Master-slave Speed Low (≤115kbps) Moderate (≤3.4Mbps) High (≥10Mbps) Addressing None 7/10-bit Hardware (SS lines) Pins 2 (TX/RX) 2 (SCL/SDA) 4 + n (SS per slave) Error Handling Parity bit ACK/NACK None

February 5, 2025 · 2 min

UART

UART (Universal Asynchronous Receiver-Transmitter) UART is a simple, asynchronous serial communication protocol used for full-duplex communication between two devices. Key Features: Asynchronous: No clock signal – relies on pre-agreed baud rate (e.g., 9600, 115200 bps). Uses two main lines: TX (Transmit) and RX (Receive). Configurable baud rate (e.g., 9600, 115200 bps). Error detection: Parity bit (optional). Flow control: Hardware (RTS/CTS) or software (XON/XOFF). No addressing – only two devices per bus. Data Frame Structure Start bit (1 bit, logic low). Data bits (5–9 bits, LSB-first). Parity bit (optional, even/odd/none). Stop bit(s) (1 or 2 bits, logic high). S t a r t B i t | D a t a B i t s ( 5 - 9 ) | P a r i t y B i t ( O p t i o n a l ) | S t o p B i t ( 1 - 2 ) Points to Remember If the baud rate is set as 115200, then the recever will expect stop bit that is high state for 1 baud period(generally). Usage in Linux Kernel: #include <linux/serial_core.h> struct uart_port *port; uart_write(port, "Hello", 5); Use Cases Debugging consoles (e.g., Linux kernel printk via UART). GPS modules, Bluetooth/Wi-Fi modules.

February 5, 2025 · 1 min

Kernel Synchronization in Linux

1. Introduction In a multitasking environment, multiple processes and threads may need to access shared resources concurrently. Without proper synchronization, race conditions, deadlocks, and data corruption can occur. The Linux kernel provides various synchronization primitives to ensure safe concurrent access while maintaining performance. 2. Spinlocks Spinlocks are busy-waiting locks used in scenarios where critical sections are short and must be protected from concurrent access. Key Features: Suitable for short, critical sections. Does not sleep, making it ideal for use in interrupt handlers. If contention occurs, the CPU spins in a loop until the lock is available. Usage: spinlock_t my_lock; spin_lock_init(&my_lock); spin_lock(&my_lock); /* Critical section */ spin_unlock(&my_lock); Types of Spinlocks: ...

February 4, 2025 · 4 min

Monolithic vs Microkernel

Monolithic Kernel All core OS services (memory management, process scheduling, file systems, drivers) reside in kernel space. Example: Linux Kernel. Pros: Fast performance, directaccess to hardware. Cons: Large codebase, difficult debugging, crashes can affect the whole system. Microkernel Minimal core kernel, with most services running in user space. Example: QNX, Minix. Pros: Stability, modularity, better security. Cons: Performance overhead due to inter-process communication (IPC).

February 4, 2025 · 1 min

Kernel Space vs User Space

Overview Kernel Space: This is where the Linux kernel executes and provides low-level access to hardware, system memory management, process scheduling, and device drivers. Kernel space has privileged access to system resources and is protected from direct user interference. For example, when a user requests data from a hardware sensor, the kernel driver handles communication with the hardware, processes the request, and returns the data to user space through system calls. User Space: This is where applications and system utilities run. User-space processes operate with restricted privileges and interact with the kernel via system calls, libraries, and IPC mechanisms. For example, a user-space daemon may monitor the watchdog status by writing to /dev/watchdog, or a mobile app may read light intensity from /sys/bus/i2c/devices/1-0039/lux. Communication Methods between Kernel and User Space There are several ways to facilitate communication between user space and kernel space in an embedded Linux environment: ...

February 4, 2025 · 3 min