2

In the linux source there are two different head.S files located at:

arch/arm/kernel/head.S

arch/arm/boot/compressed/head.S

What is the puprpose of each one and what is the order of there execution ?

3

1 Answer 1

3

I welcome better answers, but my understanding is that it's the kernel startup code (which is architecture-specific) hand-written in assembly (remember, at this point we just have a bare metal CPU and raw access to memory; we can't access complex libraries stored on the file system because we have no file manager yet - it's like asking who created the big bang). Do not confuse this with the boot loader (which loads the boot sector from disk into RAM). I myself had confused them in my earlier answer.

             +- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +     + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +
             ' bootloader                                                                 '     ' kernel                                                                        '
             '                                                                            '     '                                                                               '
+------+     ' +-----------------------------------+     +------------------------------+ '     ' +-----------------------------+     +---------------------------------------+ '
| BIOS | --> ' | arch/x86/boot/header.S::call main | --> | arch/x86/boot/main.c::main() | ' --> ' | init/main.c::start_kernel() | --> | arch/x86/kernel/setup.c::setup_arch() | '
+------+     ' +-----------------------------------+     +------------------------------+ '     ' +-----------------------------+     +---------------------------------------+ '
             '                                                                            '     '                                                                               '
             +- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +     + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +

(EDIT: this is Minix, I wrongly put it in originally)

+------+     +--------------------+     +------------------+     +------------------------+
| BIOS | --> | Bootloader (mbr.S) | --> | startup (head.S) | --> | kernel/main.c::kmain() |
+------+     +--------------------+     +------------------+     +------------------------+

enter image description here

At the end of head.S you'll see the line

    call    _C_LABEL(kmain)

which is the entry point to the kernel:

kernel/main.c

I believe head.S is tacked on to the top of the kernel image at compile time. The BIOS knows to execute this block of code because it's at the very beginning and is the root file system of the ram disk.

As for why there is a compressed and uncompressed part, I think it's because the architecture specific assembly portion of the kernel image, no programmer is skilled enough to do compression. Once we can jump to the kmain routine written in C (but compiled into assembly) we have access to a decompression routine which makes the kernel footprint significantly smaller.

enter image description here

http://duartes.org/gustavo/blog/post/kernel-boot-process/


The entry point using assembly

We like to write everything in C, but we cannot avoid a little bit of assembly. We will write a small file in x86 assembly-language that serves as the starting point for our kernel. All our assembly file will do is invoke an external function which we will write in C, and then halt the program flow.

How do we make sure that this assembly code will serve as the starting point of the kernel?

We will use a linker script that links the object files to produce the final kernel executable. (more explained later) In this linker script, we will explicitly specify that we want our binary to be loaded at the address 0x100000. This address, as I have said earlier, is where the kernel is expected to be. Thus, the bootloader will take care of firing the kernel’s entry point.

http://arjunsreedharan.org/post/82710718100/kernel-101-lets-write-a-kernel

5
  • I just realized .S indicates "aSsembler" Oct 25, 2017 at 19:21
  • 1
    Your answer, while a good one, deals with x86. To the OP : make sure, if interested in ARM boot, you filter out the x86-specific bits. The boot process is different when dealing with ARM.
    – schaiba
    Oct 30, 2017 at 7:03
  • Feel free to edit my post, I'm still trying to learn it myself :) Oct 30, 2017 at 7:04
  • 1
    I'll have to do some in-depth digging myself :) What springs to mind is that, for example, ARM does not have protected mode, not in the sense employed by x86.
    – schaiba
    Oct 30, 2017 at 7:10
  • Ooops, I just realized my answer is for Minix, not Linux. Oct 16, 2019 at 0:11

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .