"Write the operating system yourself" read Sense http://blog.csdn.net/zgh1988/article/details/7059936
Comprehensive analysis of the first chapter of "self-writing Operating System" http://blog.csdn.net/zgh1988/article/details/7060032
Comprehensive Analysis of the "self-writing Operating System" Chapter 2 http://blog.csdn.net/zgh1988/article/details/7062065
Comprehensive Analysis of the "hands-on writing Operating System" Chapter 3 1 http://blog.csdn.net/zgh1988/article/details/7098981
Take the final exam. after the Spring Festival in winter vacation, go back to school on the 8th to continue learning. Today, I read a sentence: although we are playing chess, we are slow and weak, but who has seen him step back? Well, keep moving forward step by step to learn programming skills in a down-to-earth manner!
Here, I will continue to share with you my understanding about the protection mode. Taking pmtest2.asm as an example, I will mainly introduce the conversion process of "real mode-protection mode-real mode.
1. The conversion process of "real mode-protection mode-real mode.
2. Use the instance pmtest2.asm to understand the conversion process of "real mode-protection mode-real mode ".
3. Section descriptor attributes
4. macro definition in PM. inc
The above four questions are described in detail below.
1. conversion process of "real mode-protection mode-real mode" 1. Real mode-protection mode
1) In real mode, you must have your own stack segment. Therefore, before entering the protection mode, you must save the SS and SP values to a memory, in this way, the stack is restored from the protection mode to the actual mode.
2) initialize the segment descriptor
3) Prepare for loading GDTR
4) Load GDTR
5) Guanzhong disconnection
6) Open the address line A20
7) set the last bit of the Cr0 register to 1.
8) Jump to the protection mode
2. Protection Mode-real mode
1) precautions:
Before returning to the real-world mode, you need to set each segment register to conform to the standard segment in the real-world mode, where the SS also needs to set the segment limit to 0 ffffh;
You cannot return the actual mode from a 32-bit code segment, but only from a 16-bit code segment, because the attributes in the CS high-speed buffer register meet the requirements of the actual mode when a 32-bit code segment cannot be returned.
The reason for the above two aspects is that starting from 80286, high-speed buffer registers for each segment register are added, and these buffer registers are invisible to programmers, in real mode, the value of these high-speed buffer registers cannot be modified. To change the value of these registers, you must modify the corresponding segment register Selection in protection mode, this is also the reason why ds, es, FS, GS, and SS must be set as the standard segment before the actual mode is returned. However, CS is a special segment and cannot be modified in the conventional way. It can only be changed through inter-segment jump. Once it is jumped to the real mode, it cannot be modified, therefore, it is required that the segment descriptor of the segment in the returned real mode must meet the requirements in the real mode. In real mode, the segment length is 0 ffffh, that is, 1 M. If the segment limit used to return the real mode is not 0 ffffh, it will result in returning the segment length of the high-speed buffer register of the CS segment in the real mode after the real mode or the segment Boundary Value in the protection mode. This is incorrect, therefore, it is required that the segment boundary used to return the real mode must be 0 ffffh.
2) jump from a 32-bit code segment in Protected Mode to a 16-bit code segment
3) Initialize all register segments under a 16-bit code segment
4) set the last position of Cr0 to 0.
5) Implement redirection and return to the real mode
2. Use the instance pmtest2.asm to understand the conversion process of "real mode-protection mode-real mode"
; ========================================================== ===============; Pmtest2.asm; Compilation Method: NASM pmtest2.asm-O pmtest2.com % include "PM. INC "; constants, macros, and some descriptions of org 0100 h jmp label_begin [section. gdt]; gdt; Segment Base segment boundary segment attribute label_gdt: descriptor0,; empty descriptor: descriptor0, 0 ffffh, da_drw; normal descriptor: descriptor0, SegCode32Len-1, da_c + da_32; inconsistent code segment, 32label_desc_code16: descriptor0, 0 ffffh, da_c; inconsistent code segment, 16label_desc_d ATA: descriptor0, DataLen-1, da_drw + da_dpl1; Protocol: descriptor0, topofstack, da_drwa + da_32; stack, 32-bit Protocol: descriptor 0500000 H, 0 ffffh, da_drw; test code segment authorization: descriptor 0b8000h, 0 ffffh, da_drw; memory first address; gdt end gdtlenequ $-label_gdt; gdt length limit-1; gdt boundary dd0; gdt base address; gdt Select Sub-region-memory De16equlabel_desc_code16-Example-label_gdt + example-Example-label_gdtselectorvideoequlabel_desc_video-label_gdt; end of [section. gdt] [section. data1]; Data Segment align 32 [bits 32] label_data: spvalueinrealmodedw0; string pmmessage: DB "in protect mode now. ", 0; after entering protection mode, the string offsetpmmessageequpmmessage-$ strtest is displayed.: DB "abcdefghijklmnopqrstuvwxyz", 0 offsetstrtestequstrtest-$ datalenequ $-label_data; end of [section. data1]; Global stack segment [section. GS] align 32 [bits 32] label_stack: Times 512 db 0 topofstack equ $-label_stack-1; end of [section. GS] [section. s16] [bits 16] label_begin: mov ax, CS mov ds, ax mov es, ax mov SS, ax mov sp, 0100 H mov [label_go_back_to_real + 3], ax mov [spvalueinrealmode], SP; initialize 16-bit code segment descriptor mov Ax, CS movzx eax, ax SHL eax, 4 Add eax, label_seg_code16 mov word [label_desc_code16 + 2], ax SHR eax, 16 mov byte [label_desc_code16 + 4], al mov byte [label_desc_code16 + 7], Ah; initialize 32-bit code segment descriptor XOR eax, eax mov ax, cs shl eax, 4 Add eax, label_seg_code32 mov word [label_desc_code32 + 2], ax SHR eax, 16 mov byte [label_desc_code32 + 4], Al mov byte [label_desc_code32 + 7], Ah; initialize data segment descriptor XOR eax, eax mov ax, DS SHL Eax, 4 Add eax, label_data mov word [label_desc_data + 2], ax SHR eax, 16 mov byte [label_desc_data + 4], Al mov byte [label_desc_data + 7], Ah; initialize the stack segment descriptor XOR eax, eax mov ax, ds shl eax, 4 Add eax, label_stack mov word [label_desc_stack + 2], ax SHR eax, 16 mov byte [label_desc_stack + 4], Al mov byte [label_desc_stack + 7], Ah; prepare XOR eax, eax mov ax, ds shl eax, 4 Add eax, label_gdt; eax <-gdt mov DWORD [Gdtptr + 2], eax; [gdtptr + 2] <-gdt base address; load GDTR lgdt [gdtptr]; close the CLI; open the address line A20 in Al, 92 h or Al, 00000010b out 92 h, Al; clear screen operation (used to specify the color) mov ah, 06 h; functions 06h and 07 h mov CH, 00; Function Description: initialize screen or scrolling mov Cl, 00; entry parameter: Ah = 06 h -- scroll up, 07 h -- scroll down mov DH, 24; Al = scroll row (0 -- clear window) moV DL, 79; bH = default property mov BH, 7 of the blank area; (CH, Cl) = position in the upper left corner of the window (Y coordinate, X coordinate) mov Al, 00; (DH, DL) = the position in the lower right corner of the window (Y coordinate, X coordinate) int 10 h; exit parameter: none; prepare to switch to protection mode mov eax, Cr0 or eax, 1 MoV Cr0, eax; truly enters the protection mode jmp dword selectorcode32: 0; execute this sentence to load selectorcode32 into CS and jump to selectorcode32: 0 ;..................................... .................................;,,,,,, ,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, ,,,,,,,,,,,,,,,,,,,,,,,, label_real_entry:; from the protection mode to the actual mode, mov ax, csmov ds, axmov es, axmov SS, axmov sp, [spvalueinrealmode] in Al, 92 h; close the A20 address line and Al, 11111101 bout 92 h, alsti; disconnect; return to do Smov ax, 4c00hint 21 h; end of [section. s16] [section. s32]; 32-bit code segment, jumped from the real mode to [bits 32] label_seg_code32: mov ax, selectordatamov ds, ax; Data Segment Selection Sub mov ax, selectortestmov es, ax; select Sub-mov ax, selectorvideomov Gs, ax for the test section; Select Sub-mov ax, selectorstackmov SS, ax for the Video Section; Select Sub-mov ESP and topofstack for the stack section; a string mov ah is displayed below, 0ch; 0000: Black Bottom 1100: red letter xor esi, esixor EDI, edimov ESI, offsetpmmessage; source data offset mov EDI, (80*10 + 0) x 2; destination data offset. Screen 10th rows, 0th columns cld.1: lodsbtest Al, aljz. 2mov [GS: EDI], ax; send data from ax to the video storage add EDI, 2jmp. 1.2:; call dispreturncall testreadcall testwritecall testread; stop JMP selectorcode16: 0; deletestread: xor esi, esimov ECx, 8. loop: mov Al, [ES: esi] Call dispalinc esiloop. loopcall dispreturnret; testread end scheme; inclutestwrite: Push esipush edixor ESI, esixor EDI, edimov ESI, offsetstrtest; source data offset. 1: lodsbtest Al, aljz. 2mov [ES: EDI], alinc edijmp. 1.2: Pop edipop esiret; testwrite ends begin; numbers; displays numbers in Al; default:; numbers already exist in Al; EDI always points to the position of the next character to be displayed; changed registers; ax, EDI; Swap dispal: Push ecxpush edxmov ah, 0 chmov DL, alshr Al, 4mov ECx, 2. begin: and Al, 01111 bcmp Al, 9ja. 1add Al, '0' JMP. 2.1: Sub Al, 0 ahadd Al, 'A '. 2: mov [GS: EDI], axadd EDI, 2mov Al, dlloop. beginadd EDI, 2pop edxpop ecxret; dispal end scheme; includispreturn: Push eaxpush ebxmov eax, edimov BL, 160div bland eax, 0 ffhinc sans BL, 160mul blmov EDI, eaxpop ebxpop eaxret; dispreturn ends -------------------------------------------------------------- segcode32lenequ $-label_seg_code32; end of [section. s32]; 16-bit code segment, jumped from 32-bit code segment, jumped out to the actual mode [section. s16code] align 32 [bits 16] label_seg_code16:; return mode: mov ax, selectornormalmov ds, axmov es, axmov FS, axmov Gs, axmov SS, axmov eax, cr0and Al, 11111110 bmov Cr0, eaxlabel_go_back_to_real: JMP 0: label_real_entry; the segment address will be set to the correct value at the beginning of the program code16lenequ $-label_seg_code16; end of [section. s16code]
The following figure shows the jump Process of "real mode-protection mode-real mode ".
Label_begin and label_real_entry run in real mode, and lebel_seg_code32 and label_seg_code16 run in protected mode. Therefore, this program implements the jump of "real mode-protection mode-real mode.
1. Real mode-protection mode
This jump process mainly exists in the label_begin code segment:
70--71: Save the value in SP in real mode
73--111: initialization segment descriptor
113--118: Prepare for loading GDTR
120--121: loading GDTR
123--124: Guanzhong disconnection
126--129: open address line A20
141--144: Switch to protection mode and set the last position of Cr0 to 1.
146--147: Jump to protection mode
2. Protection Mode-real mode
208--209: jump from a 32-bit code segment in Protected Mode to a 16-bit code segment
Skip --322: Prepare for the jump back to the real mode. initialize the segment register to conform to the code segment specifications in the real mode. That is, use selectornormal to initialize the segment register.
324--326: Set the last position of Cr0 to 0.
328--329: Jump to the label_real_entry segment in real mode
158--158: SP in recovery mode
160--162: Disable the A20 address line
164--164: On interrupt
166--168: returns DoS
Iii. segment descriptor attributes
Segment descriptor attributes occupy 5 and 6 bytes. The specific features are as follows:
Here we will mainly introduce 5th bytes of content.
(1) P: Presence (present) bit.
1 indicates that the segment exists in the memory
0 indicates that the segment does not exist in the memory.
(2) DPL: descriptor privilege level, two bits in total.
It specifies the privileged level of the description segment for privileged checks to determine whether the segment can be accessed.
(3) s: Describes the descriptor type.
1. Data Segment and code segment descriptor
0 system segment descriptor and gate Descriptor
(4) type: describes the specific attributes of the bucket described by the bucket descriptor.
Description of data segment type values
----------------------------------
0 read-only
1. Read-only and accessed
2 read/write
3 read/write, accessed
4 read-only and downward Scaling
5 read-only, downward scaling, accessed
6 read/write, downward Scaling
7 read/write, extended down, accessed
Description of the code snippet type value
----------------------------------
8
9 executed and accessed
A execution/read
B: executed/read, accessed
C Only, consistent code segment
D. Only executed, consistent code segment, and accessed
E execution/read, consistent code segment
F execution/read, consistent code segment, accessed
Description of system segment type Encoding
----------------------------------
0 <undefined>
1. 286tss available
2 LDT
3 busy 286tss
4. 286 call Portals
5 tasks
6 286 broken doors
286 trap door
8 undefined
9. Available ipvtss
A <undefined>
B busy javastss
C 386
D <undefined>
E 386 interrupt door
F 386 trap door
Iv. macro definition in PM. inc
In the program, we use Macros in PM. Inc to define the da_drw, da_c, da_32, da_drw, and da_drwa attributes. Let me explain these macro definitions to you.
Da: descriptor attribute
D: Data Segment
C: code segment
S: System segment
R: Read-Only
RW: read/write
A: accessed
----------------------------------------------------------------------------
Da_32 equ 4000 h; 32-bit segment
Da_dpl0 equ 00 h; DPL = 0
Da_dpl1 equ 20 h; DPL = 1
Da_dpl2 equ 40 h; DPL = 2
Da_dpl3 equ 60 h; DPL = 3
----------------------------------------------------------------------------
Description of the type value of the bucket Descriptor
----------------------------------------------------------------------------
Da_dr equ 90 h; Existing read-only data segment type value
Da_drw equ 92 h; read/write data segment attribute values
Da_drwa equ 93 h; type value of the read/write data segment that already exists
Da_c equ 98 h; only the code snippet attribute values exist.
Da_cr equ 9ah; attribute values of executable readable code segments
Da_cco equ 9ch; only consistent code segment attribute values are executed
Da_ccor equ 9eh; the existence of executable readable consistent code segment Attribute Value
----------------------------------------------------------------------------
Description of system segment descriptor type values
----------------------------------------------------------------------------
Da_ldt equ 82 h; Local Descriptor Table segment type value
Da_taskgate equ 85 h; Task gate type value
Da_386tss equ 89 h; available 386 task status segment type value
Da_1_cgate equ 8ch; 386 call door type value
Da_1_igate equ 8eh; 386 interrupt door type value
Da_1_tgate equ 8fh; 386 trap door type value