In the linux source there are two different head.S files located at:
arch/arm/boot/compressed/head.S
What is the puprpose of each one and what is the order of there execution ?
Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems. It only takes a minute to sign up.
Sign up to join this communityIn the linux source there are two different head.S files located at:
arch/arm/boot/compressed/head.S
What is the puprpose of each one and what is the order of there execution ?
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() |
+------+ +--------------------+ +------------------+ +------------------------+
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.
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