Linux Kernel series-12. B. Operating System Development-jump from Loader to protection mode, 12. bloader
Now, the kernel has been loaded into the memory. It is time to jump into the protection mode.
The first is GDT and the corresponding selector. We only define three descriptors, which are 0 ~ 4 GB executable segment, a 0 ~ A 4 GB read/write segment and a segment pointing to the memory start address:
; GDT; Segment Base Address segment boundary, attribute LABEL_GDT: Descriptor 0, 0, 0; empty Descriptor LABEL_DESC_FLAT_C: Descriptor 0, 0 fffffh, DA_CR | DA_32 | da_limit_4 K; Limit, 0 fffffh, DA_DRW | DA_32 | DA_LIMIT_4K; latency: Descriptor latency, 0 ffffh, DA_DRW | latency; the first video address GdtLenequ $-latency-1; Segment Boundary Limit + LABEL_GDT; base address; GDT Select Sub-SelectorFlatCequLABEL_DESC_FLAT_C-Example-LABEL_GDTSelectorVideoequLABEL_DESC_VIDEO-LABEL_GDT + SA_RPL3
In the previous protection mode, the base address of most descriptors is calculated during runtime and filled in with the corresponding location, because at that time our program was loaded by BIOS or DOS, we do not know the segment address, so we do not know the position in the memory when the program is running.
Currently, the Loader is loaded by ourselves, and the segment address has been identified as BaseOfLoader. Therefore, the physical address of the number (variable) in the Loader can be expressed using the following formula:
Physical address of the number (variable) = BaseOfLoader * 10 h + offset of the number (variable)
We put it and the corresponding declaration in load. inc.
BaseOfLoader equ 09000 h; LOADER. location where the BIN is loaded ---- segment address OffsetOfLoader equ 0100 h; LOADER. location where the BIN is loaded ---- offset address BaseOfLoaderPhyAddr equBaseOfLoader * 10 h; LOADER. location where the BIN is loaded ---- physical address BaseOfKernelFile equ 08000 h; KERNEL. BIN loaded to location ---- segment address OffsetOfKernelFile equ 0 h; KERNEL. location of BIN loaded ---- offset address
We have defined a macro BaseOfLoaderPhyAddr to replace BaseOfLoader * 10 h, which is used once in loader. asm to calculate the base address of GDT.
The running result is as follows:
【Source code]