Chapter 0: Prerequisites and Fundamentals
Table of Contents
- Before You Start
- C Programming Essentials
- Linux System Fundamentals
- Computer Architecture Basics
- Build System Basics
- Understanding the Kernel
- Self-Assessment Quiz
Before You Start
What You Need to Know
Required Knowledge:
- β C Programming - Strong understanding (pointers, structures, memory)
- β Linux Command Line - Basic navigation and file operations
- β Text Editor - Comfortable with vim, emacs, or VS Code
- β Basic Compilation - Understanding gcc and make
Recommended But Not Required:
- π Operating System concepts (processes, memory management)
- π Computer architecture (CPU, memory, I/O)
- π Assembly language basics
Hardware:
- π» Linux system (native or VM)
- πΎ At least 2GB RAM
- π½ 20GB free disk space
Time Investment
| Topic | Time Estimate |
|---|---|
| Prerequisites Review | 1-2 weeks |
| Basic Modules | 1-2 weeks |
| Character Drivers | 2-3 weeks |
| Advanced Topics | 4-6 weeks |
| Total | 8-13 weeks |
C Programming Essentials
Pointers (Critical!)
/*
* Pointers are ESSENTIAL for kernel programming
* You must be completely comfortable with them
*/
/* Basic pointer */
int x = 42;
int *ptr = &x; /* ptr points to x */
*ptr = 100; /* Modify through pointer (x is now 100) */
/* Pointer to pointer */
int **pp = &ptr; /* pp points to ptr */
**pp = 200; /* x is now 200 */
/* Array vs pointer */
int arr[10];
int *p = arr; /* Array name is pointer to first element */
p[5] = 42; /* Same as arr[5] = 42 */
*(p + 5) = 42; /* Same as above */
/* Function pointer */
int (*func_ptr)(int, int); /* Pointer to function returning int */
func_ptr = &my_function;
int result = func_ptr(10, 20); /* Call through pointer */
/* Pointer arithmetic */
int *p = arr;
p++; /* Move to next int (adds sizeof(int) bytes) */
p += 5; /* Move 5 ints forward */
/* NULL pointer */
int *p = NULL; /* Always initialize! */
if (p != NULL) { /* Always check before dereferencing */
*p = 42;
}
Structures and Unions
/*
* Structures are heavily used in kernel
*/
/* Basic structure */
struct device {
int id;
char name[32];
unsigned long flags;
};
/* Typedef (less common in kernel) */
typedef struct {
int x, y;
} point_t;
/* Structure pointers */
struct device *dev;
dev->id = 1; /* Access via pointer (->)*/
(*dev).id = 1; /* Same but uglier */
/* Nested structures */
struct driver {
struct device dev; /* Embedded structure */
void (*init)(void); /* Function pointer */
};
/* Bit fields */
struct flags {
unsigned int ready:1; /* 1 bit */
unsigned int error:1; /* 1 bit */
unsigned int mode:2; /* 2 bits */
unsigned int reserved:28; /* Rest */
};
/* Unions (share memory) */
union data {
int i;
float f;
char c[4];
}; /* All members start at same address */
/* Anonymous unions/structs (C11) */
struct packet {
int type;
union {
struct { int x, y; } point;
struct { char name[8]; } text;
}; /* No union name needed */
};
Memory and Casts
/*
* Understanding memory layout is critical
*/
/* Size of types */
sizeof(char) // 1 byte
sizeof(short) // 2 bytes (usually)
sizeof(int) // 4 bytes (usually)
sizeof(long) // 4 or 8 bytes (architecture dependent!)
sizeof(void *) // 4 or 8 bytes (pointer size)
/* Type casting */
int x = 42;
void *generic = (void *)&x; /* Generic pointer */
int *typed = (int *)generic; /* Cast back */
/* Pointer casting (common in kernel) */
unsigned long addr = 0xFFFF8000;
void *ptr = (void *)addr; /* Address to pointer */
unsigned long addr2 = (unsigned long)ptr; /* Pointer to address */
/* Alignment */
struct aligned {
char c; /* 1 byte */
/* 3 bytes padding on 32-bit, 7 on 64-bit */
int i; /* 4 bytes */
} __attribute__((aligned(8))); /* Force 8-byte alignment */
/* Volatile (prevents optimization) */
volatile int *hw_register = (volatile int *)0x80000000;
*hw_register = 1; /* Compiler won't optimize away */
/* Const correctness */
const int *p1; /* Pointer to const int */
int * const p2; /* Const pointer to int */
const int * const p3; /* Const pointer to const int */
Preprocessor
/*
* Heavy preprocessor use in kernel
*/
/* Macros */
#define MAX_SIZE 1024
#define MIN(a, b) ((a) < (b) ? (a) : (b)) /* Always use parentheses! */
/* Multi-line macros */
#define SWAP(a, b) do { \
typeof(a) _tmp = (a); \
(a) = (b); \
(b) = _tmp; \
} while (0) /* do-while trick for safety */
/* Conditional compilation */
#ifdef DEBUG
#define DBG_PRINT(fmt, ...) printk(fmt, ##__VA_ARGS__)
#else
#define DBG_PRINT(fmt, ...)
#endif
/* Stringify */
#define STRINGIFY(x) #x
#define TOSTRING(x) STRINGIFY(x)
TOSTRING(123) /* Becomes "123" */
/* Token pasting */
#define CONCAT(a, b) a##b
CONCAT(hello, _world) /* Becomes hello_world */
/* Common kernel patterns */
#define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0]))
#define container_of(ptr, type, member) /* See kernel headers */
Error Handling
/*
* Kernel uses negative error codes
*/
/* Return value checking */
int ret = some_function();
if (ret < 0) {
/* Error occurred */
return ret; /* Propagate error */
}
/* Common error codes */
-ENOMEM /* Out of memory */
-EINVAL /* Invalid argument */
-EBUSY /* Device busy */
-EFAULT /* Bad address */
-EIO /* I/O error */
/* Error path with goto */
int init_device(void)
{
int ret = 0;
void *buf1 = NULL, *buf2 = NULL;
buf1 = kmalloc(1024, GFP_KERNEL);
if (!buf1) {
ret = -ENOMEM;
goto out;
}
buf2 = kmalloc(2048, GFP_KERNEL);
if (!buf2) {
ret = -ENOMEM;
goto free_buf1;
}
/* Success path */
return 0;
free_buf2:
kfree(buf2);
free_buf1:
kfree(buf1);
out:
return ret;
}
Linux System Fundamentals
Essential Commands
# File operations
ls -la # List files with details
cd /path # Change directory
pwd # Print working directory
cat file # Display file
less file # Page through file
head -n 10 file # First 10 lines
tail -f file # Follow file (useful for logs)
# File editing
vim file # Edit with vim
nano file # Edit with nano
# Permissions
chmod 644 file # rw-r--r--
chmod +x script # Add execute permission
sudo command # Run as root
chown user:group # Change ownership
# Process management
ps aux # List all processes
top # Interactive process viewer
kill PID # Terminate process
killall name # Kill by name
# Kernel/module commands
uname -r # Kernel version
uname -a # All system info
lsmod # List loaded modules
modinfo module # Module information
dmesg # Kernel log
dmesg -w # Watch kernel log
journalctl -k # Systemd kernel log
# System information
lspci # PCI devices
lsusb # USB devices
lscpu # CPU info
free -h # Memory usage
df -h # Disk usage
File System Hierarchy
/
βββ /boot # Kernel and bootloader
β βββ vmlinuz-* # Kernel image
β βββ config-* # Kernel config
βββ /dev # Device files
β βββ sda # Hard disk
β βββ tty* # Terminals
β βββ null # Null device
βββ /etc # Configuration
β βββ udev/ # udev rules
βββ /home # User directories
βββ /lib/modules # Kernel modules
β βββ $(uname -r)/
β βββ kernel/ # Built-in modules
β βββ extra/ # External modules
βββ /proc # Process/kernel info
β βββ cpuinfo # CPU information
β βββ meminfo # Memory info
β βββ [PID]/ # Process info
βββ /sys # Sysfs (device/driver)
β βββ class/ # Device classes
β βββ devices/ # Device hierarchy
β βββ module/ # Module parameters
βββ /tmp # Temporary files
βββ /usr # User programs
β βββ /src # Source code
β βββ /include # Header files
βββ /var # Variable data
βββ /log # Log files
Understanding /proc
# Process information
cat /proc/[PID]/status # Process status
cat /proc/[PID]/cmdline # Command line
cat /proc/[PID]/maps # Memory maps
# System information
cat /proc/cpuinfo # CPU details
cat /proc/meminfo # Memory details
cat /proc/version # Kernel version
cat /proc/modules # Loaded modules (like lsmod)
cat /proc/devices # Character and block devices
cat /proc/interrupts # Interrupt statistics
# Kernel parameters
cat /proc/sys/kernel/ostype
echo value > /proc/sys/kernel/parameter # Modify
Understanding /sys
# Device information
ls /sys/class/ # Device classes
ls /sys/block/ # Block devices
ls /sys/bus/ # Bus types
# Module parameters
ls /sys/module/[module]/parameters/
cat /sys/module/[module]/parameters/[param]
echo value > /sys/module/[module]/parameters/[param]
# Device attributes
ls /sys/class/net/eth0/ # Network device
cat /sys/class/net/eth0/address # MAC address
Computer Architecture Basics
Memory Hierarchy
CPU Registers (fastest, ~1 cycle)
β
L1 Cache (32-64 KB, ~4 cycles)
β
L2 Cache (256-512 KB, ~12 cycles)
β
L3 Cache (2-32 MB, ~30 cycles)
β
RAM (GB, ~100 cycles)
β
SSD/HDD (TB, ~100,000+ cycles)
Memory Layout
High Address (0xFFFFFFFF)
βββββββββββββββββββββββββββ
β Kernel Space β (Ring 0, privileged)
β - Kernel code β
β - Kernel data β
β - Device drivers β
βββββββββββββββββββββββββββ€ β Kernel/User boundary
β Stack (grows down) β
β β β
β β
β β β
β Heap (grows up) β
βββββββββββββββββββββββββββ€
β BSS (uninitialized) β
βββββββββββββββββββββββββββ€
β Data (initialized) β
βββββββββββββββββββββββββββ€
β Text (code) β
βββββββββββββββββββββββββββ
Low Address (0x00000000)
CPU Modes
/*
* x86/x64 Protection Rings
*/
Ring 0: Kernel mode (privileged)
- Full hardware access
- Can execute privileged instructions
- Device drivers run here
Ring 3: User mode (unprivileged)
- Limited access
- Cannot access hardware directly
- Applications run here
// Transition between modes via:
// - System calls (user β kernel)
// - Interrupts (any β kernel)
// - Return from interrupt (kernel β user)
Interrupts and Exceptions
Hardware Interrupt:
Device signals CPU β CPU stops β Saves state β
Executes interrupt handler β Restores state β Continues
Software Interrupt (System Call):
User program invokes syscall β Switch to kernel mode β
Execute kernel function β Return to user mode
Exception:
CPU detects error (div by zero, page fault) β
Switch to kernel β Handle exception
Build System Basics
GCC Compilation Steps
# Complete process
source.c β Preprocessor β preprocessed.i β
Compiler β assembly.s β Assembler β object.o β
Linker β executable
# Step by step
gcc -E source.c -o source.i # Preprocessing only
gcc -S source.c -o source.s # Compilation to assembly
gcc -c source.c -o source.o # Assembly to object
gcc source.o -o program # Linking
# All in one
gcc source.c -o program
# Common flags
gcc -Wall # All warnings
gcc -Werror # Treat warnings as errors
gcc -O2 # Optimization level 2
gcc -g # Include debug symbols
gcc -I/path # Include directory
gcc -L/path # Library directory
gcc -lname # Link library
Makefile Basics
# Simple Makefile
CC = gcc
CFLAGS = -Wall -Werror -g
TARGET = program
OBJS = main.o utils.o
# Default target
all: $(TARGET)
# Link
$(TARGET): $(OBJS)
$(CC) $(CFLAGS) -o $(TARGET) $(OBJS)
# Compile
%.o: %.c
$(CC) $(CFLAGS) -c $< -o $@
# Clean
clean:
rm -f $(TARGET) $(OBJS)
# Phony targets
.PHONY: all clean
Kernel Module Makefile
# Kernel module Makefile structure
obj-m += mymodule.o
# If multiple source files
mymodule-objs := main.o helper.o
# Kernel build directory
KDIR := /lib/modules/$(shell uname -r)/build
# Current directory
PWD := $(shell pwd)
all:
$(MAKE) -C $(KDIR) M=$(PWD) modules
clean:
$(MAKE) -C $(KDIR) M=$(PWD) clean
.PHONY: all clean
Understanding the Kernel
Kernel vs User Space
/*
* Key Differences
*/
// User Space:
printf("Hello\n"); // Standard C library
malloc(size); // User space allocator
pthread_create(); // POSIX threads
sleep(1); // Can block freely
// Can crash without affecting system
// Kernel Space:
printk("Hello\n"); // Kernel logging
kmalloc(size, GFP_KERNEL); // Kernel allocator
kthread_create(); // Kernel threads
msleep(1); // Sleep (careful!)
// Bug = system crash!
System Calls
/*
* User space uses system calls to request kernel services
*/
// User space:
int fd = open("/dev/mydevice", O_RDWR); // System call
write(fd, buffer, size); // System call
close(fd); // System call
// Kernel space (what actually happens):
// open() β sys_open() β kernel file operations
// write() β sys_write() β driver's write function
// close() β sys_close() β driver's release function
Kernel Architecture
βββββββββββββββββββββββββββββββββββββββββββ
β System Call Interface β
βββββββββββββββββββββββββββββββββββββββββββ€
β Process Memory Networkβ
β Scheduler Management Stack β
βββββββββββββββββββββββββββββββββββββββββββ€
β Virtual File System (VFS) β
βββββββββββββββββββββββββββββββββββββββββββ€
β File Systems Block Layer Networkβ
β (ext4, btrfs) (I/O scheduler) (TCP) β
βββββββββββββββββββββββββββββββββββββββββββ€
β Device Drivers β
β (Character, Block, Network) β
βββββββββββββββββββββββββββββββββββββββββββ€
β Hardware Abstraction β
βββββββββββββββββββββββββββββββββββββββββββ
Self-Assessment Quiz
Test your understanding before proceeding:
C Programming
- Whatβs wrong with this code?
int *get_pointer(void) { int x = 42; return &x; // BUG: Returning pointer to local variable! } - What does this print?
int arr[5] = {1, 2, 3, 4, 5}; int *p = arr + 2; printf("%d\n", p[1]); // Answer: 4 (p[1] = *(p+1) = arr[3]) - Fix this macro:
#define MAX(a, b) a > b ? a : b // BUG: Missing parentheses // Correct: #define MAX(a, b) ((a) > (b) ? (a) : (b))
Linux Commands
- How to see last 20 lines of kernel log?
dmesg | tail -20 # or journalctl -k -n 20 - How to check if module is loaded?
lsmod | grep module_name - How to find which kernel version?
uname -r
Concepts
- Whatβs the difference between kernel space and user space?
- Kernel: Ring 0, full hardware access, no protection
- User: Ring 3, limited access, protected from crashes
- Why canβt you use printf in kernel?
- No standard C library in kernel
- Use printk instead
- What happens during a system call?
- Context switch from user to kernel mode
- Kernel function executes
- Return to user mode
Answer Key
If you got:
- 8-9 correct: Ready to start! β
- 5-7 correct: Review weak areas, then proceed
- < 5 correct: Study prerequisites more carefully
Next Steps
β If youβre comfortable with all topics: β Proceed to 01-basics.md
π If you need more review: β Study recommended books:
- βThe C Programming Languageβ by K&R
- βLinux Command Lineβ by William Shotts
- βUnderstanding the Linux Kernelβ by Bovet & Cesati
π» Practice exercises: β Try examples in examples/00-c-review/
Quick Reference Card
Essential C Concepts
// Pointers
int *p = &x; // Address of
int val = *p; // Dereference
// Structures
struct dev *d;
d->member; // Arrow operator
// Casting
(type *)pointer; // Type cast
// Macros
#define FOO(x) ... // With parentheses!
Essential Commands
# Module operations
lsmod # List modules
insmod mod.ko # Load module
rmmod mod # Unload module
modinfo mod.ko # Module info
dmesg # Kernel log
# Building
make # Build
make clean # Clean
Memory Layout
0xFFFFFFFF β Kernel Space (Ring 0)
0xC0000000 β User/Kernel boundary
β Stack (grows down)
β Heap (grows up)
0x08048000 β Text (code)
0x00000000
Ready to write kernel code? Letβs go! β