Experiment 6: memory paging

Experiment 5: memory paging

Corresponding book P199 page 5.2

1. Summary of relevant basic knowledge

Page directory page directory item page table page table item physical page virtual address physical address

Concept Brief
Page directory entries and page table entries

The lower 3 bytes are attributes. The upper 20 bits are physical addresses.

This experiment
Virtual address: 32 bits = 4GB
Physical address: 32MB (but the real address accessible under the paging mechanism is only 1MB lower). 32MB is the test result of the memory capacity of the last experiment.
Physical page size: 4kB
One page table size: 4kB
One page table item size: 4B
A page table has 1024 page table entries
Therefore, a page table can represent 1024*4kB=4MB of virtual memory

One page directory size: 4kB
One page directory entry size: 4B
A page directory has 1024 page directory entries
Therefore, the page directory can represent 4MB*1024=4GB virtual memory

According to the physical page size, the number of 4B page table items is 2 ^ 10
Number of page directory entries 2 ^ 10,
Virtual addresses can be divided into

10 digits10 digits12 digits
Page directory entry indexPage entry indexIntra block offset

From the above table, the formula for converting virtual address into physical address is very clear.
The upper 10 bits represent that the virtual address will access the page directory entries of the page directory, so as to obtain the first 20 bits of the page directory entry, that is, the first address of the corresponding page table.
The middle 10 bits represent that the virtual address will access the page table entries of the page table, so as to obtain the first 20 bits of the page table entry, that is, the first address of the corresponding physical page.
The last 12 bits represent the offset of the physical page
The obtained physical header address plus the last 12 bit offset is the physical address corresponding to the virtual address.

2. Experimental records

2.1 experimental purpose

1. Construct page directory and page table, complete the mapping from virtual address 3GB~3GB+1MB to real address 0 ~1MB, and the mapping from virtual address 0 ~1MB to physical address 0 ~1MB.

[note] you are not mistaken, which means that the virtual address 3GB and virtual address 0 will be transformed into the same physical address 0 in this experiment

2. Turn on the protection mode and the paging mechanism of the protection mode
3. Modify the segment base address in the GDTR and the segment base address in the segment descriptor of the video memory to ensure the code

mov byte [gs:160],'V' 

[gs:160] in [gs:160] will spell out the virtual address 0xc00b800+160 under the segmentation mechanism and paging mechanism of protection mode. Obviously, this address is between 3GB~3GB+1MB virtual addresses.

4. Execute the above sentence code, which is equivalent to writing the ASCLL code of character 'V' to the virtual address 0xc00b800+160,
In the third step, we set up the paging mechanism of protection mode, and the cpu will automatically convert the virtual address provided into physical address and then access the memory.
Therefore, this experiment can detect whether the virtual address can be automatically converted into 0xb800 in 1MB of the real address (i.e. the first address in video memory text mode) according to the page table and page directory defined by ourselves under the paging mechanism of protected mode

If bochs simulation is used, the character V can be printed on the display screen, indicating that the virtual address is successfully transformed into physical address, and the test is successful.

2.2 precautions for this experiment

In this experiment, 1024 page directory items can be constructed
1024 page table entries can also be constructed for each page table
But it should be noted that
1... When constructing the page directory, our code only constructs the 0th page directory item and the 768th ~ 1023rd page directory item. The 0 and 768th directory items are the first address of the 0 page table. The 1023rd page directory item contains the first address of the page directory. The table of contents items on pages 769 to 1022 contain the first address of the table of pages 1 to 254.

2. When constructing the page table, we only constructed the first 256 page table items in the 0-th page table. Because a physical page is 4KB, the real address that can be accessed under the paging mechanism is only 1MB lower, 256*4KB=1MB.

According to the above two points, we can also get a message that needs attention
One page directory entry represents 4MB of virtual memory,
The 0 and 768th directory items are the first address of the 0 page table,
The directory entry on page 768 represents 4MB768=4MB256*3=3GB
Therefore, this experiment only completed the virtual address 3GB~3GB+1MB
The mapping of real address 0~1MB and the mapping of virtual address 0~1MB to real address 0~1MB.

3. The first address of the page directory of this experiment is 0x100000, i.e. 1MB.
The first address of the table on page 0 is 0x101000, i.e. 1MB+4KB
Reason for this setting: low 1MB is used to install MBR s,loader.s and kernel.

4. In this experiment, 3GB~3GB+1MB virtual addresses are mapped to lower 1MB physical addresses in turn, that is, in 3GB~3GB+1MB virtual addresses, the physical address corresponding to the small virtual address must be small.

2.3 experimental code

boot.inc increase

;-------------   Page table configuration   ----------------
PAGE_DIR_TABLE_POS equ 0x100000
;----------------   Page table related properties    --------------
PG_P  equ   1b
PG_RW_R	 equ  00b 
PG_RW_W	 equ  10b 
PG_US_S	 equ  000b 
PG_US_U	 equ  100b 

loader.s

   %include "boot.inc"
   section loader vstart=LOADER_BASE_ADDR
   LOADER_STACK_TOP equ LOADER_BASE_ADDR
;structure gdt And its internal descriptor
   GDT_BASE:   dd    0x00000000 
	       dd    0x00000000

   CODE_DESC:  dd    0x0000FFFF 
	       dd    DESC_CODE_HIGH4

   DATA_STACK_DESC:  dd    0x0000FFFF
		     dd    DESC_DATA_HIGH4

   VIDEO_DESC: dd    0x80000007	       ; limit=(0xbffff-0xb8000)/4k=0x7
	       dd    DESC_VIDEO_HIGH4  ; here dpl Is 0

   GDT_SIZE   equ   $ - GDT_BASE
   GDT_LIMIT   equ   GDT_SIZE -	1 
   times 60 dq 0					 ; 60 descriptor spaces are reserved here(slot)
   SELECTOR_CODE equ (0x0001<<3) + TI_GDT + RPL0         ; amount to(CODE_DESC - 
;GDT_BASE)/8 + TI_GDT + RPL0
   SELECTOR_DATA equ (0x0002<<3) + TI_GDT + RPL0	 ; ditto
   SELECTOR_VIDEO equ (0x0003<<3) + TI_GDT + RPL0	 ; ditto 

   ; total_mem_bytes Used to save memory capacity,In bytes,This position is easy to remember.
   ; Current offset loader.bin File header 0 x200 byte,loader.bin The loading address of is 0 x900,
   ; so total_mem_bytes The address in memory is 0 xb00.We will refer to this address in the kernel in the future
   total_mem_bytes dd 0					 
   ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

   ;The following is the definition gdt The first two bytes are gdt Boundary, the last 4 bytes are gdt Starting address
   gdt_ptr  dw  GDT_LIMIT 
	    dd  GDT_BASE

   ;Manual alignment:total_mem_bytes4 byte+gdt_ptr6 byte+ards_buf244 byte+ards_nr2,256 bytes in total
   ards_buf times 244 db 0
   ards_nr dw 0		      ;For recording ards Number of structures

   loader_start:
   
;-------  int 15h eax = 0000E820h ,edx = 534D4150h ('SMAP') Get memory layout  -------

   xor ebx, ebx		      ;On the first call, ebx The value should be 0
   mov edx, 0x534d4150	      ;edx It is only assigned once and will not change in the loop body
   mov di, ards_buf	      ;ards Structure buffer
.e820_mem_get_loop:	      ;Loop to get each ARDS Memory range description structure
   mov eax, 0x0000e820	      ;implement int 0x15 after,eax The value becomes 0 x534d4150,So every time int
;It should be updated to sub function number before.
   mov ecx, 20		      ;ARDS The size of address range descriptor structure is 20 bytes
   int 0x15
   jc .e820_failed_so_try_e801   ;if cf If the bit is 1, an error occurs. Try 0 xe801 Subfunction
   add di, cx		      ;send di Add 20 bytes to point to the new in the buffer ARDS Structure location
   inc word [ards_nr]	      ;record ARDS quantity
   cmp ebx, 0		      ;if ebx 0 and cf Not 1,This shows ards Return all. It is the last one at present
   jnz .e820_mem_get_loop

;At all ards In the structure, find out(base_add_low + length_low)The maximum value of, that is, the capacity of memory.
   mov cx, [ards_nr]	      ;Traverse each ARDS structural morphology,The number of cycles is ARDS Number of
   mov ebx, ards_buf 
   xor edx, edx		      ;edx Maximum memory capacity,Clear 0 here first
.find_max_mem_area:	      ;No judgment type Is 1,The largest block of memory must be available
   mov eax, [ebx]	      ;base_add_low
   add eax, [ebx+8]	      ;length_low
   add ebx, 20		      ;Points to the next in the buffer ARDS structure
   cmp edx, eax		      ;Bubble sort to find the largest,edx Registers are always the maximum memory capacity
   jge .next_ards
   mov edx, eax		      ;edx Is the total memory size
.next_ards:
   loop .find_max_mem_area
   jmp .mem_get_ok

;------  int 15h ax = E801h Get memory size,Maximum support 4 G  ------
; After return, ax cx Same value,with KB Unit,bx dx Same value,With 64 KB Unit
; stay ax and cx Low 16 in register M,stay bx and dx 16 in register MB To 4 G. 
.e820_failed_so_try_e801:
   mov ax,0xe801
   int 0x15
   jc .e801_failed_so_try88   ;If current e801 Method failed,Just try 0 x88 method

;1 First calculate the low 15 M Memory,ax and cx Zhongshiyi KB Amount of memory in,Convert it to byte Unit
   mov cx,0x400	     ;cx and ax Same value,cx Used as a multiplier
   mul cx 
   shl edx,16
   and eax,0x0000FFFF
   or edx,eax
   add edx, 0x100000 ;ax Just 15 MB,So add 1 MB
   mov esi,edx	     ;Lower it by 15 first MB Memory storage esi Register backup

;2 Add 16 more MB The above memory is converted to byte Unit,register bx and dx The middle is 64 KB Amount of memory in
   xor eax,eax
   mov ax,bx		
   mov ecx, 0x10000	;0x10000 64 decimal KB
   mul ecx		;32 Bit multiplication,The default multiplier is eax,The product is 64 bits,High 32-bit storage edx,Low 32-bit storage eax.
   add esi,eax		;Because this method can only measure 4 G Memory within,So 32 bits eax that's enough,edx Must be 0,Only add
;eax Then
   mov edx,esi		;edx Is the total memory size
   jmp .mem_get_ok

;-----------------  int 15h ah = 0x88 Get memory size,Only 64 can be obtained M within  ----------
.e801_failed_so_try88: 
   ;int 15 After, ax Deposited in kb Memory capacity in
   mov  ah, 0x88
   int  0x15
   jc .error_hlt
   and eax,0x0000FFFF
      
   ;16 Multiplicative, multiplicative ax,The product is 32 bits.The upper 16 bits of the product are dx In, the lower 16 bits of the product are ax in
   mov cx, 0x400     ;0x400 Equal to 1024,take ax Replace the memory capacity in with byte Unit
   mul cx
   shl edx, 16	     ;hold dx Move to high 16 bits
   or edx, eax	     ;Combine the lower 16 bits of the product into edx,Is the product of 32 bits
   add edx,0x100000  ;0x88 The subfunction will only return 1 MB More memory,Therefore, the actual memory size should be added with 1 MB

.mem_get_ok:
   mov [total_mem_bytes], edx	 ;Replace memory with byte Deposit after unit total_mem_bytes Office.


;-----------------   Ready to enter protection mode   -------------------
;1 open A20
;2 load gdt
;3 take cr0 of pe Position 1

   ;-----------------  open A20  ----------------
   in al,0x92
   or al,0000_0010B
   out 0x92,al

   ;-----------------  load GDT  ----------------
   lgdt [gdt_ptr]

   ;-----------------  cr0 Position 0 1  ----------------
   mov eax, cr0
   or eax, 0x00000001
   mov cr0, eax

   jmp dword SELECTOR_CODE:p_mode_start	     ; Refresh the pipeline to avoid the impact of branch prediction,this
;species cpu Optimization strategy, most afraid jmp Jump,
					     ; This will lead to the failure of the previous prediction, which plays the role of refreshing.
.error_hlt:		      ;Suspend on error
   hlt

[bits 32]
p_mode_start:
   mov ax, SELECTOR_DATA
   mov ds, ax
   mov es, ax
   mov ss, ax
   mov esp,LOADER_STACK_TOP
   mov ax, SELECTOR_VIDEO
   mov gs, ax;
   
 ; Create page directory and page table and initialize page memory bitmap
   call setup_page

   ;To write the descriptor table address and offset to memory gdt_ptr,Reload with new address later
   sgdt [gdt_ptr]	      ; Store to original gdt All locations

   ;take gdt Segment base address in video segment descriptor in descriptor+0xc0000000
   mov ebx, [gdt_ptr + 2]  
   or dword [ebx + 0x18 + 4], 0xc0000000      ;The video segment is the third segment descriptor,Each descriptor is 8 words
;section,So 0 x18. 
					      ;The highest bit of the upper 4 bytes of the segment descriptor is 31 of the segment base address~24 position

   ;take gdt Base address plus 0 xc0000000 Make it the high address of the kernel
   add dword [gdt_ptr + 2], 0xc0000000

   add esp, 0xc0000000        ; The stack pointer is also mapped to the kernel address

   ; Assign the page directory address to cr3
   mov eax, PAGE_DIR_TABLE_POS
   mov cr3, eax

   ; open cr0 of pg position(31st place)
   mov eax, cr0
   or eax, 0x80000000
   mov cr0, eax

   ;After paging is turned on,use gdt Reload new address
   lgdt [gdt_ptr]             ; Reload

   mov  byte [gs:160], 'V';
   jmp $;



;-------------   Create page directory and page table   ---------------
setup_page:
;First clear the space occupied by the page directory by 0 byte
   mov ecx, 4096
   mov esi, 0
.clear_page_dir:
   mov byte [PAGE_DIR_TABLE_POS + esi], 0
   inc esi
   loop .clear_page_dir

;Start creating page directory entries(PDE)
.create_pde:				     ; establish Page Directory Entry
   mov eax, PAGE_DIR_TABLE_POS
   add eax, 0x1000 			     ; here eax Is the location and properties of the first page table
   mov ebx, eax				     ; Here is ebx Assignment, yes.create_pte Prepare, ebx Is the base address.

;   The page directory entries 0 and 0 will be displayed below xc00 Are saved as the address of the first page table,
;   A page table can represent 4 MB Memory,So 0 xc03fffff The following addresses and 0 x003fffff The following addresses point to the same page table,
;   This is in preparation for mapping addresses to kernel addresses
   or eax, PG_US_U | PG_RW_W | PG_P	     ; Properties of page directory entries RW and P Bit 1,US Is 1,Represents user attributes,All privilege levels are accessible.
   mov [PAGE_DIR_TABLE_POS + 0x0], eax       ; 1st directory entry,The first directory entry in the page directory table is written to the location of the first page table(0x101000)And properties(3)
   mov [PAGE_DIR_TABLE_POS + 0xc00], eax     ; A page table item occupies 4 bytes,0xc00 Indicates the directory entry occupied by the 768th page table,0xc00 The above directory entries are for kernel space,
					     ; That is, 0 of the page table xc0000000~0xffffffff Total 1 G Belong to kernel,0x0~0xbfffffff Total 3 G Belongs to user process.
   sub eax, 0x1000
   mov [PAGE_DIR_TABLE_POS + 4092], eax	     ; Make the last directory entry point to the address of the page directory table itself

;Next, create a page table entry(PTE)
   mov ecx, 256				     ; 1M low memory / Page size 4 k = 256
   mov esi, 0
   mov edx, PG_US_U | PG_RW_W | PG_P	     ; The attribute is 7,US=1,RW=1,P=1
.create_pte:				     ; establish Page Table Entry
   mov [ebx+esi*4],edx			     ; At this time ebx It has passed above eax Assign value to 0 x101000,That is, the address of the first page table 
   add edx,4096
   inc esi
   loop .create_pte

;Creating tables for other pages of the kernel PDE
   mov eax, PAGE_DIR_TABLE_POS
   add eax, 0x2000 		     ; here eax Is the location of the second page table
   or eax, PG_US_U | PG_RW_W | PG_P  ; Properties of page directory entries RW and P Bit 1,US Is 0
   mov ebx, PAGE_DIR_TABLE_POS
   mov ecx, 254			     ; The scope is 769~1022 Number of all catalog items
   mov esi, 769
.create_kernel_pde:
   mov [ebx+esi*4], eax
   inc esi
   add eax, 0x1000
   loop .create_kernel_pde
   ret

Code function summary:
setup_page function
Constructed the 0th page directory item and the 768th ~ 1023rd page directory item
Constructed the first 256 page table entries in the page 0 table. Among them, the addresses of page table items are the lower 1MB of real address

First open the protection mode, then call setup_. Page establish the page table and page directory.
Modify the segment base address in GDTR and the segment base address in the segment descriptor of video memory,
Then assign the page directory address to cr3 and open the pg bit (bit 31) of cr0
Final execution
mov byte [gs:160], 'V';
To verify the experimental results.

Analyze the code addressing process of this sentence.
It involves two virtual address conversions.

gs is the selector of the video memory segment
After the following code is modified

sgdt [gdt_ptr]

;;;;;Modified the segment base address of video memory segment descriptor;;;;
mov ebx, [gdt_ptr + 2]  
or dword [ebx + 0x18 + 4], 0xc0000000

;;;;Modified GDT Base address;;;;
add dword [gdt_ptr + 2], 0xc0000000
add esp, 0xc0000000

;;;;Modified GDT Assign starting address to gdtr;;;;;;
lgdt [gdt_ptr] 

The base address of GDT remains unchanged at 1MB lower than the real address and is still 0x900
The base address of the video memory segment descriptor does not change when the real address is lower than 1MB. 0x900+8*3 bytes = 0x918
The descriptor index value in gs has not changed to 3
It becomes the GDT base address in the GDTR and becomes 0xc0000900, that is, 3GB+0x900. This is obviously a virtual address, and the real address is only 32MB
Therefore, the base address of the video memory segment descriptor obtained is also a virtual address
0xc0000900+3 * 8 bytes = 0xc0000918
Since the paging mechanism has been turned on, the virtual address will be converted to the physical address 0x918,
The conversion process is as follows
0xc0000918

10 digits10 digits12 digits
11_0000_000000_0000_00000x918
The decimal system is 76800x918

The 768th page directory item is set by us, and the top 20 bits are the first address of the 0 page table
The middle 10 bits are 0, that is, the 0 page table item of the 0 page table, and the first 20 bits are 0.
Therefore, the physical address corresponding to this virtual address is 0x00000918,
This is the base address of the video memory segment descriptor.
The segment base address recorded in the segment descriptor of video memory is also a virtual address, 0xc00b8000
Similarly, it is converted to a physical address, that is, 0x000b8000
This is the first address of video memory text mode.
160 is the offset, which is legal.
So 'V' will appear on the second line of the display.

2.4 experimental results

1. Compile loader s

nasm -o loader.bin loader.s

2. Compile MBR s

nasm -o mbr.bin mbr.s 

3. Transfer MBR Bin engraved into sector 0

dd if=/home/Seven/bochs2.68/bin/mbr.bin of=/home/Seven/bochs2.68/bin/Seven.img bs=512 count=1 seek=0 conv=notrunc

4. Load the loader Bin is engraved into sector 2 (note that count=3 plus one)

dd if=/home/Seven/bochs2.68/bin/loader.bin of=/home/Seven/bochs2.68/bin/Seven.img bs=512 count=3 seek=2 conv=notrunc

5. Simulate bochs

./bochs -f bochsrc.disk

design sketch

3. Supplement

When building the page directory item, we also set the top 20 bits of the 1023rd page directory item as the first address of the page directory

The process of converting virtual addresses to physical addresses according to paging mechanism
If the upper 20 bits of the virtual address are 0xfffff, the upper 10 bits are all 1. Find the 1023rd page directory item and obtain the page directory header address, and the middle 10 bits are all 1. The page directory is regarded as the page table, the 1023rd page directory item is regarded as the page table item, and the page directory header address is obtained.

Therefore, as long as the upper 20 bits of the virtual address is 0xfffff, you can get the first address of the page directory

We can get it through a specific virtual address
1. Get the physical address of page directory: virtual address 0xffff000
2. Get the physical address of the directory item on the nth page: virtual address: 0xfffffxxx
xxx is the product of page directory index multiplied by 4
For example, if you get the first page directory entry address (the number starts from 0), the virtual address I give should be 0xfffff004 and the first page directory address + 4

If you get the first address of the directory entry on the nth page, you will get the first address of the table on the nth page.
3. Access the page table entry in the page table, that is, get the first address of the nth page table entry in the M-th page table: the first 10 bits of the virtual address I gave are all 1, that is 0x3ff, the middle 10 bits are equal to M, and the last 12 bits are equal to N*4. In this way, the last converted physical address is the first address of the nth page table entry in the M-th page table

Keywords: Operating System

Added by xenophobia on Fri, 04 Mar 2022 09:44:36 +0200