Basic Linux Kernel

David Nguyen, Duy-Ky Nguyen, PhD

Linux is the kernel of an operating system. It is really nothing more than a resource manager. Whether the resource being managed is a process, memory, or hardware device; the kernel manages and arbitrates access to the resource between multiple competing users (both in the kernel and in user space).

Right after power-on, the system is in real mode until MMU (Memory Mangagement Unit) is initialzed for protected mode. The protected mode has 2 modes : kernel and user. Kernel mode has direct access to  low-level hardware resource, while the user mode must make a system call for such access.

The bootloader loads kernel from ROM into RAM, not copy, as RAM address is virtual address. The virtual address space has an excellent featute where its size is 4 GB regardless physical memory size. The virtual space is divided into 2 areas :
(1) 0 ~ 3 GB : User space
(2) 3 ~ 4 GB : Kernel space starts @ 0xC0000000, ie 3 GB
        (a) 0 ~ 896MB        : Low memory
        (b) 896MB ~ 1 GB : High memory, 128 MB for kernel data structure, aka kernel header, Kernel compilation creates a file "system.map" starting at 0xC0000000.

Power-On Sequence


Right after power on, the bootloader runs out of ROM  in real mode to init RAM for loading  kernel from ROM to RAM then run out of RAM. The mode becomes protected after MMU initialized.

Below is the first kernel message

Linux version 2.6.23 (duyky@Cos4_H.Samba) (gcc version 4.1.2) #51 Fri Oct 24 19:18:08 PST 2008 All HW resources are initilalized, such as USB, PCI, Ethernet, ...
Filesystem is mounted before the very first process init is started as it executes /etc/inittab and some init scripts afterward.

Kernel memory is freed up before control is transferred to init process with the last kernel message below

Freeing unused kernel memory: 140k init

1) Boot loader: either BIOS for x86 or u-boot for non-x86 (ARM, PowerPC, ...)
    Alsways starts from known address in flash to initialize RAM chip select to copy kernel from flash to RAM

2) Boot kernel
    Kernek runs out of RAM with the very first instruction in arch/my_arch/kernel/head.S where my_arch is i386 or powerpc

3) arch/powerpc/kernel/head_32.S

_start:
    . . .
start_here:
    . . .
    bl    machine_init    /* arch/powerpc/kernel/setup_32.c : udbg_early_init() to init printk */
    . . .
turn_on_mmu:              /* real mode before mmu turned on */
    . . .
    start_kernel          /* init/main.c after mmu turned on, so protected mode */

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

start_kernel() /* init/main.c */
{
    . . .

    printk(linux_banner);
    . . .
    rest_init(); /* 0 */
}
//////////////////////////////////////////////
rest_init() /* 0 */
{
    . . .
    kernel_thread(kernel_init, NULL, CLONE_FS | CLONE_SIGHAND); /* 0.1 */
    . . .
}
//////////////////////////////////////////////
kernel_init() /* 0.1 */
{
    . . .
    do_basic_setup();     // drivers : PCI, USB, net, ...
    . . .
    prepare_namespace();    // mount filesystem
    . . .

    init_post(); /* 0.1.1 */
    return 0;
}
//////////////////////////////////////////////
init_post() /* 0.1.1 */
{
    . . .
         /* one-way function, ie return only on error when no init found */
    run_init_process("/sbin/init");
    run_init_process(" /etc/init");    /* After filesystem mounted */
    run_init_process("/bin/init");
    run_init_process("/bin/sh");

    panic("No init found. Try passing init= option to kernel.");
}
//////////////////////////////////////////////////////////////////////