Linux Kernel series-32-bit protection mode for Operating System Development

Source: Internet
Author: User

Linux Kernel series-32-bit protection mode for Operating System Development

The source code is as follows:

; ========================================================== =; Pmtest1.asm; Compilation Method: nasm pmtest1.asm-o pmtest1.bin; ========================================================== = % include "pm. inc "; constants, macros, and some descriptions org07c00hjmpLABEL_BEGIN [SECTION. gdt]; GDT; Segment Base Address, segment boundary, attribute LABEL_GDT: Descriptor 0, 0, 0; empty Descriptor LABEL_DESC_CODE32: Descriptor 0, SegCode32Len-1, DA_C + DA_32; inconsistent code snippet LABEL_DESC_VIDEO: Descriptor 0B8000h, 0 ffffh, DA_DRW; first video address; GDT END GdtLenequ $-LABEL_GDT; GDT length GdtPtrdwGdtLen-1; GDT boundary dd0; GDT base address; GDT Select Sub-SelectorCode32equLABEL_DESC_CODE32-limit-LABEL_GDT; END. gdt] [SECTION. s16] [BITS16] LABEL_BEGIN: movax, csmovds, axmoves, axmovss, axmovsp, 0100 h; initialize 32-bit code segment descriptor xoreax, eaxmovax, csshleax, 4 addeax, LABEL_SEG_CODE32movword [LABEL_DESC_CODE32 + 2], axshreax, 16 movbyte [LABEL_DE SC _CODE32 + 4], almovbyte [LABEL_DESC_CODE32 + 7], ah; prepare xoreax, eaxmovax, dsshleax, 4 addeax, LABEL_GDT for loading GDTR; eax <-gdt base address movdword [GdtPtr + 2], eax; [GdtPtr + 2] <-gdt base address; load GDTRlgdt [GdtPtr]; close the cli; open the address line A20inal, 92 horal, 00000010bout92h, al; ready to switch to protection mode moveax, cr0oreax, 1movcr0, eax; truly enter protection mode jmpdword SelectorCode32: 0; execute this statement to load SelectorCode32 into cs ,; and jump to SelectorCode32: 0; END of [SECTI ON. s16] [SECTION. s32]; 32-bit code segment. jump from the real mode. [BITS32] LABEL_SEG_CODE32: movax, SelectorVideomovgs, ax; video segment Selection Sub-(destination) movedi, (80*11 + 79) * 2; screen 11th rows, 79th columns. Movah, 0Ch; 0000: Black Bottom 1100: red letter moval, 'P' mov [gs: edi], ax; stop jmp $ SegCode32Lenequ $-LABEL_SEG_CODE32; END of [SECTION. s32]

The running result is as follows, with a red P on the far right of the screen:

Source code parsing:

1.First, the program jumps to LABEL_BEGIN and jmp LABEL_BEGIN. Initialize all the ds, es, and ss segment registers as the current segment.

2. initialize the 32-bit code segment descriptor

In real mode, the addressing mode of the 16-bit CPU of 8086 is segment x16 + offset. In protection mode, the segment register value is changed to an index, this index points to the segment descriptor, that is, the descriptor corresponding to GDT, which contains the final base address.

Lines 38-41 indicate to move the code segment of the current program four places to the left, that is, x16, plus the LABEL_SEG_CODE32 offset address to form the physical address of LABEL_SEG_CODE32, 42-45 indicates loading the physical address to the base address of the segment descriptor, as shown in

The base address is 0-15 bits, that is, the LABEL_DESC_CODE32 + 2 address, where the 16-bit ax is passed in. The 16 bits are moved to the right of row 43rd, indicating that the 16 bits have been passed in are eliminated, then, the remaining two 8-bit high and low register values are passed into the corresponding segment base address.

Descriptor is a macro defined in pm. inc, as shown in. It represents the format of the segment Descriptor:

3. The structure of the loaded GDTR and GDRT is as follows:

GDTR is the only register pointing to the segment descriptor table. Rows 48-55 load the base address of the segment descriptor table to the GDTR register. Delete the eax value in 48 rows. 49-52 loads the physical address of LABEL_GDT to the two-character location of GdtPtr in 20 rows, that is, the GDT base address. Line 55 loads the content of the GdtPtr address to GDTR. The dual-byte dw corresponds to the 16-bit boundary, and the dual-word dd corresponds to the 32-bit base address.

4. Disconnect and open A20

In protection mode, the interrupt processing mechanism is different from the actual mode. Therefore, disable the interrupt first and set the command to cli. Turn on A20 for historical reasons to prevent rollback when the offset exceeds the maximum value. Lines 8-63

5. Switch to the protection mode

You only need to set the 0th position of the cr0 register to 1. 66-68 rows

6. Enter the protection mode

Jmp dword SelectorCode32: 0. This line is the code that actually enters the protection mode, and SelectorCode32 is a segment Selection Sub, segment Selection Sub-finds the corresponding segment descriptor to find the corresponding segment base address. Shows the format of the sub-segment selection.

Starting from bit 3, it is represented as the index of the segment descriptor table. After the code is executed, the segment base address in the descriptor LABEL_DESC_CODE32, that is, LABEL_SEG_CODE32, is loaded to cs.

Dword is used because the current code is still 16 bits. If there is no dword, The SelectorCode32: 0 offset address will only take 16 bits if it exceeds 16 bits.

 

By now, the 32-bit protection mode has been fully enabled.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.