Porting Linux: part 1 (of many)

So I’m working on a book at the moment, to be title “Porting Linux”, which will cover the process of porting the kernel to new architectures (and platforms within those architectures). It happens to coincide with a number of interests of mine. Anyway, I thought I would start making some online notes about porting. This is the first in an ongoing series of mini-dumps of unorganized thoughts on the topics I am researching/working on for the book.

At a high level, a new architecture port[0] needs to cover the following topics:

  • Fundamentals – the bitness and endianness of the system (bitsperlong, byteorder, etc.). Stuff that goes in system.h includes read_barrier_depends handling, and instruction sync and memory barrier definitions.
  • Atomic and bit operations – atomic, bitops, swab, etc. Many of these are used generically by the reference asm-generic code and core kernel to implement higher level primitives.
  • CPU and cacheing – SMP setup, cache management, percpu bits, topology, procfs, etc. The CPU(s) are bootstrapped in head.S and friends, but then they need functions to handle non-MMU items such as IPI, etc.
  • Init – Entry into the kernel, establishing exception vectors, calling into start_kernel. This is head.S and friends.
  • Interrupts and exceptions – IRQ setup, traps, entry, etc. The low-level exceptions might live in head, but they will call into generic C-level code to implement various functionality (specific higher-level functions for e.g. VM live elsewhere)
  • IO operations – IO, PCI root setup, legacy IDE bits, etc. Various miscellaneous stuff, especially generic panic-inducing inb/outb functions on modern arches without separated IO memory).
  • Library functions – Checksum support, asm-optimized stuff not specifically in another subsystem.
  • Locking – Spinlock support
  • Memory management – Init, faults, TLB setup, page management, MMU contexts, memcpy, strings, etc.
  • Modules – Load, unload, and relocation
  • Signals – Signal contexts, signal delivery, compat signal handling
  • Tasks – current macros, thread_info, unistd, process, mmap, ELF and auxiliary vectors
  • Time – timex, time setup
  • Linking – asm-offsets, linkage, symbols exported in assembly, etc.
  • Console drivers – early_printk support and a minimal character driver. The only driver work actually required for a port includes being able to squirt stuff straight out the UART in early_printk, and minimally handle the boot console output.
  • Debugging – backtrace, opcode dissassembly, stack unwind, ftrace, kexec, kgdb, kprobes, ptrace

Those are the areas needed to be covered for a minimally working port.


[0] Based on studying recent ports (tile, microblaze, etc.) from the first patch to the last, and long-time established existing ports (ARM, PowerPC, x86, etc.).

One Response to “Porting Linux: part 1 (of many)”

  1. Noah Watkins says:

    One thing I would love to see in a book like this is a porting walk through for an existing architecture chosen such that a reader could purchase a cheap development board to do the port for real. Even if the arch already exists in the kernel tree, the book walk through could leave out sections of the port and the reader could either figure out how to implement the missing piece, or consult the existing code in the kernel tree.

Leave a Reply