Source: http://www.top-e.org/jiaoshi/class/
This should begin with the generation process of vmliux. Bin.
From the kernel generation process, there are three main links to the kernel:
The first step is to compile the source code of the kernel into a. o file and link it to arch/i386/kernel/head. s to generate vmlinux. Note that all the variable addresses here are virtual addresses protected by 32-bit page addressing. Usually 3G or above.
Step 2: Convert vmlinux objcopy to arch/i386/boot/compressed/vmlinux. Bin, compress the data, and compile the data into piggy. O. At this time, in the compiler's opinion, there is no startup_32 in piggy. O.
Step 3: Set head. o, MISC. O and piggy. the olink is used to generate ARCH/i386/boot/compressed/vmlinux. In this step, the link is arch/i386/boot/compressed/head. s. In this case, startup_32 in arch/i386/kernel/head. S is compressed as a common piece of data, which is ignored by the compiler. Note that the addresses here are all linear addresses in 32-bit addressing mode.
Naturally, in this process, it is impossible to have the startup_32 redefinition problem.
You may say: It's too Bt. Who will compile the program in this way?
Yes. However, is there a better way to efficiently implement self-decompression before the kernel is started?
Therefore, the preceding problems can be solved. After the setup is complete, jump to startup_32 () in vmlinux. bin to be set to startup_32 () in arch/i386/boot/compressed/head. S ()
This is a self-extracting program, which is opposite to the kernel generation process. In this case, the IP address range of the CPU is increased from 1 MB to 4 GB in 32-bit addressing mode. But there is no page table.
We are not interested in the specific decompression process.
The kernel has been decompressed. At 0x100000, that is, 1 MB
Finally, execute a jump command and run the code at 0x100000, that is, startup_32 (). This is the startup_32 () code in arch/i386/kernel/head. S.
Ljmp $ (_ boot_cs), $ __physical_start