driver-know-hows

device driver related stuff

View on GitHub

C Programming Review

Description

Comprehensive review of C programming concepts essential for kernel development. These are userspace programs that demonstrate concepts you’ll use in kernel code.

Programs

1. pointers_demo.c

Master pointers - the most critical skill for kernel programming.

Topics Covered:

2. structs_demo.c

Understanding structures - heavily used in kernel.

Topics Covered:

Build & Run

# Build all
make

# Run tests
make test

# Or run individually
./pointers_demo
./structs_demo

# Clean
make clean

Expected Output

pointers_demo

╔════════════════════════════════════════════════╗
║   Pointer Fundamentals for Kernel Development ║
╚════════════════════════════════════════════════╝

=== Basic Pointers ===
x = 42
Address of x = 0x7ffc...
ptr points to 0x7ffc...
*ptr = 42
After *ptr = 100, x = 100

=== Pointer Arithmetic ===
...

structs_demo

╔════════════════════════════════════════════════╗
║  Structure Fundamentals for Kernel Development║
╚════════════════════════════════════════════════╝

=== Basic Structures ===
Device: id=1, name=device0, flags=0xff
...

Learning Objectives

After running these programs, you should understand:

Pointers:

Structures:

Why These Matter for Kernel Development

Pointers in Kernel

// Kernel uses pointers EVERYWHERE
struct device *dev;                    // Device pointer
void __iomem *regs;                    // Hardware register pointer
char __user *buffer;                   // Userspace pointer
dma_addr_t dma_handle;                 // DMA address

// container_of to get parent structure
struct my_device *mydev = container_of(dev, struct my_device, dev);

Structures in Kernel

// Kernel structures with function pointers (ops)
struct file_operations {
    int (*open)(struct inode *, struct file *);
    ssize_t (*read)(struct file *, char __user *, size_t, loff_t *);
    ssize_t (*write)(struct file *, const char __user *, size_t, loff_t *);
    // ...
};

// Bit fields for hardware registers
struct control_reg {
    unsigned int enable:1;
    unsigned int mode:2;
    unsigned int reserved:29;
};

Key Differences: Userspace vs Kernel

Concept Userspace Kernel
Allocation malloc() kmalloc()
Free free() kfree()
Strings printf() printk()
NULL check Recommended MANDATORY
Crash result Program dies System crashes

Common Mistakes (Don’t Do This!)

// ❌ BAD: Returning pointer to local variable
int *bad_function(void) {
    int x = 42;
    return &x;  // BUG! x is destroyed after return
}

// ✅ GOOD: Allocate on heap
int *good_function(void) {
    int *p = malloc(sizeof(int));
    if (!p) return NULL;
    *p = 42;
    return p;  // Caller must free
}

// ❌ BAD: Use after free
int *p = malloc(sizeof(int));
free(p);
*p = 42;  // BUG! Memory already freed

// ❌ BAD: Not checking NULL
int *p = malloc(sizeof(int));
*p = 42;  // BUG! Might crash if allocation failed

// ✅ GOOD: Always check
int *p = malloc(sizeof(int));
if (!p) {
    return -ENOMEM;
}
*p = 42;

Self-Test Questions

After running these programs, answer these:

  1. What does p++ do if p is an int *?
    • Adds sizeof(int) bytes to the pointer
  2. What’s the difference between . and ->?
    • . for structure, -> for structure pointer
  3. Why use container_of?
    • To get parent structure from embedded member
  4. What’s a memory leak?
    • Allocated memory that’s never freed
  5. Why are bit fields useful?
    • Directly map to hardware register bits

Next Steps

After mastering these concepts:

  1. ✅ Move to kernel modules: cd ../01-hello/
  2. 📚 Read Chapter 0: ../../00-prerequisites.md
  3. 💻 Try modifying the examples
  4. 🧪 Write your own pointer/structure exercises

Additional Practice

Try these exercises:

  1. Modify pointers_demo.c:
    • Add a doubly-linked list
    • Implement a binary tree
    • Add error injection (simulate malloc failures)
  2. Modify structs_demo.c:
    • Create your own register structure
    • Implement a device with operations
    • Practice container_of with different structures

Resources


Remember: Mastering pointers and structures is ESSENTIAL for kernel development. Take your time with these examples!