Linux Core Concepts: Memory, Processes, IPC, and I/O Multiplexing

Inspecting Process Memory Usage

Using top

PID   – Process ID
USER  – Owner
PR    – Priority (lower = higher)
NI    – Nice value
VIRT  – Virtual memory
RES   – Physical memory
SHR   – Shared memory
S     – State (S=sleep, R=run, Z=zombie, N=negative nice)
%CPU  – CPU usage
%MEM  – Physical memory ratio
TIME+ – Cumulative CPU time
COMMAND – Executable name

Using ps

Common flags:

  • a – All terminals
  • -A/-e – Every process
  • u – User-oriented format
  • x – Include detached processes

Typical pattern:

ps aux | grep <keyword>

Kernel Module Basics

Dynamic Loading vs Static Linking

  • Static: Driver compiled into kernel; large image, slow debug cycle.
  • Dynamic: .ko modules loaded at runtime via insmod/rmmod; smaller kernel, faster iteration.

Boot Flow on Embedded Boards

Bootloader (U-Boot) → Kernel → Mount rootfs → Init → Applications

Minimal rootfs directories:

/etc  configs
/bin  essential user binaries
/sbin essential system binaries
/lib  shared libraries & modules
/dev  device nodes

Writing a Simple Character Driver

Skeleton for an LED driver:

#include <linux/module.h>
#include <linux/fs.h>
#include <linux/uaccess.h>
#include <linux/io.h>

#define DEV_NAME "led_demo"
#define GPIO_BASE 0x56000050
#define GPIO_SIZE 16

static int major;
static void __iomem *gpio_con, *gpio_dat;

static ssize_t led_write(struct file *f, const char __user *buf,
                         size_t len, loff_t *off)
{
    char kbuf;
    if (copy_from_user(&kbuf, buf, 1))
        return -EFAULT;
    if (kbuf == '1')
        iowrite32(ioread32(gpio_dat) & ~((1<<4)|(1<<5)|(1<<6)), gpio_dat);
    else
        iowrite32(ioread32(gpio_dat) |  ((1<<4)|(1<<5)|(1<<6)), gpio_dat);
    return len;
}

static int led_open(struct inode *i, struct file *f)
{
    u32 val = ioread32(gpio_con);
    val &= ~((0x3<<(4*2)) | (0x3<<(5*2)) | (0x3<<(6*2)));
    val |=  ((0x1<<(4*2)) | (0x1<<(5*2)) | (0x1<<(6*2)));
    iowrite32(val, gpio_con);
    return 0;
}

static const struct file_operations led_fops = {
    .owner = THIS_MODULE,
    .open  = led_open,
    .write = led_write,
};

static int __init led_init(void)
{
    major = register_chrdev(0, DEV_NAME, &led_fops);
    gpio_con = ioremap(GPIO_BASE, GPIO_SIZE);
    gpio_dat = gpio_con + 1;
    return 0;
}

static void __exit led_exit(void)
{
    unregister_chrdev(major, DEV_NAME);
    iounmap(gpio_con);
}

module_init(led_init);
module_exit(led_exit);
MODULE_LICENSE("GPL");

Process, Thread, Coroutine

Aspect Process Thread Coroutine
Resource owner Seperate VM Shares VM Shares thread
Switch cost High (kernel) Medium (kernel) Low (user)
Typical use CPU-bound jobs I/O-bound jobs Massive concurrency

Copy-on-write after fork() defers page duplication until write occurs.


Inter-Process Communication

Mechanism Traits
Anonymous pipe Half-duplex, parenet–child only, 4 kB buffer, byte stream
Named pipe (FIFO) Path-based, any processes, same semantics as pipe
Message queue Structured records, kernel linked-list, size limits
Shared memory Fastest, needs external sync (e.g., semaphores)
Unix domain socket Local full-duplex, socket API
Signal Async notification, limited payload

Virtual Memory Essentials

  • Physical RAM: Actual DRAM.
  • Virtual address space: Per-process contiguous range, mapped via page tables.
  • Swap: Disk area for evicted pages.
  • Shared memory: Same physical frames mapped into multiple processes.

Address translation (simplified):

  1. Split VA into page number + offset.
  2. Walk page table (page number → frame number).
  3. Combine frame number + offset → physical address.
  4. On miss, raise page fault → load from disk.

I/O Multiplexing

Stages of a read():

  1. Wait for data ready.
  2. Copy data from kernel to user buffer.

Comparison

Call Max FDs Complexity Data Structure Edge Trigger
select 1024 O(n) fd_set No
poll none O(n) pollfd array No
epoll none O(1) RB tree + list Yes (ET/LT)

epoll workflow:

  1. epoll_create() → obtain epfd.
  2. epoll_ctl(epfd, ADD, fd, &event) → insert into RB tree.
  3. epoll_wait(epfd, events, maxevents, timeout) → sleep until ready list non-empty.

File Descriptors and VFS

  • FD: Small integer index into per-process open-file table.
  • VFS layer provides uniform open/read/write/ioctl for any filesystem or device.

Byte Order Detection

int is_little_endian(void) {
    uint16_t x = 0x1;
    return *(uint8_t *)&x;
}

Static vs Global Variables

  • static int g; – visible only in current translation unit.
  • int g; – external linkage, visible to other units via extern.

Tags: Linux kernel memory process IPC

Posted on Sun, 12 Jul 2026 17:21:43 +0000 by Warboss Alex