ARM64 OS Handbook
🔍

Chapter 44: Coding Standards

What You Will Learn in This Chapter
  • Why consistent coding standards matter for a team project
  • Naming conventions for functions, variables, types, and macros
  • Indentation, spacing, and brace style
  • Comment guidelines and documentation expectations
  • File organization and header file structure
  • How to enforce standards with clang-format and checkpatch

44.1 Why Standards Matter

In a team of five developers building a kernel, code will be read far more often than it is written. Consistent formatting and naming conventions reduce cognitive overhead, prevent bugs, and make code reviews productive. These standards apply to all C and assembly code in the kernel tree.

44.2 Naming Conventions

ElementConventionExample
Functionssnake_casealloc_page(), uart_send()
Global variablessnake_case with descriptive nameskernel_page_table, system_timer
Local variablessnake_case, short but cleari, count, page_addr
Types (typedef)snake_case with _t suffixuint32_t (standard), page_t, process_t
Struct/enum tagssnake_casestruct pcb, enum vm_flags
MacrosUPPER_SNAKE_CASEPAGE_SIZE, MAX_PROCESSES
Inline functionssnake_case (same as regular functions)static inline round_up()
File namessnake_case.c / snake_case.huart.c, page_alloc.c

44.3 Formatting

Indentation and Braces

/* Indent: 4 spaces. No tabs. */
/* Braces: K&R style (opening brace on same line). */
void example_function(void) {
    if (condition) {
        do_something();
    } else {
        do_other();
    }

    for (int i = 0; i < count; i++) {
        process_item(items[i]);
    }
}

/* Always use braces for loops and conditionals, even single lines. */
if (error)
    return -1;  /* WRONG: no braces */
if (error) {
    return -1;  /* CORRECT */
}

/* One space after if/for/while, before opening paren. */
if (x)     /* CORRECT */
if(x)      /* WRONG */

Spacing

/* One space around binary operators. */
int sum = a + b * c;

/* No space between function name and opening paren. */
void *kmalloc(size_t size);
kmalloc(256);  /* CORRECT */
kmalloc (256); /* WRONG */

/* Pointer: * goes next to the variable name. Not next to the type. */
int *ptr;       /* CORRECT */
int* ptr;       /* WRONG */
int * ptr;      /* WRONG */

/* One space after commas in function arguments. */
function(a, b, c);   /* CORRECT */
function(a,b,c);     /* WRONG */

Switch Statements

switch (value) {
case OPTION_A:
    handle_a();
    break;
case OPTION_B:
    handle_b();
    /* fallthrough */
case OPTION_C:
    handle_c();
    break;
default:
    handle_default();
    break;
}

44.4 Comments

/*
 * Block comments for file headers and function
 * descriptions. Use /* for multi-line.
 */
int documented_function(void);

/* Single-line comments for implementation details. */

// C++ style comments are also acceptable for short notes. //

Every public function in header files must have a doc comment explaining what it does, its parameters, and return value:

/**
 * alloc_page - Allocate a single physical page.
 *
 * Returns a pointer to the page's physical address (identity-mapped),
 * or NULL if no free pages are available.
 * The allocated page is zeroed.
 */
void *alloc_page(void);

44.5 Header File Structure

/* kernel/include/timer.h */
#ifndef __TIMER_H__
#define __TIMER_H__

#include <stdint.h>

/* Public API */
void     timer_init(void);
uint64_t timer_get_ticks(void);
void     timer_sleep(uint64_t ms);

/* Internal (only for timer.c) */
#ifdef __TIMER_INTERNAL__
extern volatile uint64_t system_ticks;
void timer_irq_handler(void);
#endif

#endif /* __TIMER_H__ */

Rules for header files:

  • Every header must have a #ifndef include guard
  • Include only what is needed (no transitive includes)
  • Do not define variables in header files
  • Keep the public API separate from internal implementation details using #ifdef

44.6 File Organization

/*
 * kernel/mm/page_alloc.c - Physical page allocator
 *
 * Implements a buddy allocator for physical memory management.
 */

#include "kernel.h"
#include "mm.h"

/* Private defines */
#define MAX_ORDER  10

/* Private structs */
struct free_list {
    struct free_list *next;
};

/* Private globals */
static struct free_list page_buckets[MAX_ORDER + 1];

/* Forward declarations */
static void split_page(int order);

/* Public functions */
void *alloc_page(void) { ... }
void free_page(void *page) { ... }

/* Private functions */
static void split_page(int order) { ... }

Structure within a C file:

  1. File header comment
  2. Includes
  3. Defines and macros
  4. Type definitions and structs
  5. Global variables
  6. Forward declarations of static functions
  7. Public functions
  8. Private functions

44.7 What Not to Do

/* NEVER: */
goto label;                    /* No gotos except for cleanup */
extern int global;             /* No extern globals in headers */
#define max(a,b) a>b?a:b       /* No function-like macros when inline works */
int *p = malloc(100);          /* No malloc in kernel; use kmalloc */
void fn() {                    /* No empty parens in K&R style; use (void) */
    ;                          /* No empty statements */
}

44.8 Enforcing Standards

Use clang-format to automatically format code. Our .clang-format file defines the project style:

# .clang-format
BasedOnStyle: LLVM
IndentWidth: 4
UseTab: Never
BreakBeforeBraces: Attach
AllowShortIfStatementsOnASingleLine: false
ColumnLimit: 100
# Format all C source files
clang-format -i kernel/**/*.c kernel/**/*.h

# Run the Linux kernel checkpatch script for additional checks
./scripts/checkpatch.pl -f kernel/mm/page_alloc.c

All code submitted for review must pass clang-format without changes.

44.9 Our Implementation

Our kernel follows these standards throughout. Key conventions to remember:

  • Language: C17 with GNU extensions, no C++
  • Compiler: aarch64-none-elf-gcc with -Wall -Wextra -Werror
  • Formatting: clang-format with the project .clang-format file
  • Header guards: #ifndef __FILENAME_H__
  • Error returns: negative errno values (e.g., -ENOMEM)
  • Success returns: 0 for success, positive values for results (like file descriptors)

44.10 Exercises

Exercise 1: Review and Fix

Take a kernel source file and run clang-format on it. Review the diff and understand every change clang-format made.

Exercise 2: Write a checkpatch Rule

Add a custom checkpatch.pl rule that flags any use of // comments (optionally, or flag any goto label).

44.11 Summary

Consistent coding standards make the kernel codebase readable, maintainable, and reviewable. Snake_case naming, K&R braces, 4-space indentation, and avoid tabs are the foundation. Header files use include guards and separate public from private API. Automatic enforcement with clang-format ensures code meets the standard without manual effort.