In Linux 0.11, we can see there is a main.c with a main()

In my understanding, the object code needs an OS to run it.

I mean, since Linux 0.11 is an OS, who is in front of it to run it? DOS?


The name of main() was simply chosen for familiarity and esthetical reasons; there was no C runtime calling it, as with the main() from a user land program. There's even a comment that tells as much in init/main.c:

void main(void)         /* This really IS void, no error here. */

The main() function is called from boot/head.s:

        pushl $0                # These are the parameters to main :-)
        pushl $0
        pushl $0
        pushl $L6               # return address for main, if it decides to.
        pushl $_main
        jmp setup_paging
        jmp L6                  # main should never return here, but
                                # just in case, we know what happens

Notice how the address of main is pushed on the stack, and setup_paging is called with jmp, not with call, which means that the ret at its end will continue from the start of main().


The Linux kernel, especially in the 0.11 days, was loaded directly by the hardware BIOS.

Basically the BIOS looks at the boot sector (of a floppy) or the Master Boot Record of a hard disk, and loads that sector. With a hard disk the MBR then loads the "primary partition" boot sector.

This loaded boot sector has enough information to know about how to load the kernel into memory, and then run it.

With the old old 0.11 disks it was effectively a floppy boot solution, with the kernel on one disk and root on another disk, so the boot system was very very simple.

When Linux handled hard disks the boot process was still very simple. It was so simple that it became possible to create tools such as "loadlin" which was a simple DOS program that would load the Linux kernel and boot into it, emulating the BIOS loader. In this way a DOS config.sys menu could be created to boot DOS or Linux; an early form of dual booting.

But at it's heart, the Linux kernel is loaded from "bare metal" and takes over the machine.


The main function is a feature of the C language. How exactly it gets converted into a computer instruction for the CPU to "start here" is basically a compiler implementation detail. On bare metal, you can often simply rely on the hardware to start execution at a particular memory address when it first boots. Early versions of Linux depended on a. simple x86 boot loader; today, that role is typically handled by Grub. That behavior, in turn, depends on BIOS firmware conventions, But really, at every level, you have a piece of computer architecture with a convention for how to start a program.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.