Guest User

Untitled

a guest
Feb 11th, 2019
100
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. ; Paging
  2. ; Base addresses
  3. %define PAGING_TABLE_SIZE         0x1000
  4. %define PAGING_TABLES_BASE        0x8000
  5.  
  6. ; Entry Flags
  7. %define PT_FLAG_P                 (1 << 0)                        ; Present
  8. %define PT_FLAG_W                 (1 << 1)                        ; Writable
  9. %define PT_FLAGS_P_W              (PT_FLAG_P | PT_FLAG_W)         ; Present & Writable
  10.  
  11. ; Base constants [naming convention: P**T_PML4Tindex_PDPTindex_PDTindex_BASE]
  12. %define PML4T_BASE                (PAGING_TABLES_BASE)
  13. %define PDPT_0_BASE               (PAGING_TABLES_BASE + 1 * PAGING_TABLE_SIZE)
  14. %define PDPT_510_BASE             (PAGING_TABLES_BASE + 2 * PAGING_TABLE_SIZE)
  15. %define PDT_0_0_BASE              (PAGING_TABLES_BASE + 3 * PAGING_TABLE_SIZE)
  16. %define PDT_510_0_BASE            (PAGING_TABLES_BASE + 4 * PAGING_TABLE_SIZE)
  17. %define PT_0_0_0_BASE             (PAGING_TABLES_BASE + 5 * PAGING_TABLE_SIZE)
  18. %define PT_510_0_0_BASE           (PAGING_TABLES_BASE + 6 * PAGING_TABLE_SIZE)
  19.  
  20. ; CR4 bit masks
  21. %define CR4_PAE_MASK              1 << 5
  22.  
  23.  
  24. ; Parameter 1: Base address of the higher level PT
  25. ; Parameter 2: Base address of the lower level PT
  26. ; Parameter 3: Attributes for the higher level PT entry
  27. %macro SetEntryInHighLevelPT 3
  28.     mov edi, %1                 ; address of the higher level table
  29.     mov dword [edi], %2         ; set one level lower table to point to
  30.     or dword [edi], %3          ; set attributes
  31. %endmacro
  32.  
  33. ; Parameter 1: Base address of the PT
  34. ; Parameter 2: Start of the 2MB area we want to map
  35. ; Parameter 3: Attributes for the PT's entries
  36. %macro MapTwoMegsToPT 3
  37.     mov edi, %1     ; PT_BASE
  38.     mov edx, %2     ; MEM_BASE
  39.     mov eax, %3     ; Attributes
  40.  
  41.     mov ecx, 512    ; we want to populate all entries
  42.     %%SetPTEntry:
  43.     mov dword [edi], edx
  44.     or dword [edi], eax
  45.     add edi, 8      ; go to next entry
  46.     add edx, 0x1000 ; go to next memory base
  47.     loop %%SetPTEntry
  48. %endmacro
  49.  
  50. ; we'll set up the page tables at 0x8000
  51. ; we'll identity map the first 2MB of memory
  52. ; and then map the next physical 2MB at virtual address 255TB
  53. SetUpLongModePaging:
  54.     ; We need one PML4T table, two PDPTs, two PDTs and two PTs
  55.     ; Each has TABLE_SIZE (0x1000) bytes, so we need to clear 7 * TABLE_SIZE bytes
  56.     mov edi, PAGING_TABLES_BASE
  57.     xor eax, eax
  58.     mov ecx, 7 * PAGING_TABLE_SIZE
  59.     rep stosb
  60.  
  61.     ; PML4T
  62.     ; we need to map this entire table (well ,without the 511th entry, but why not go for that as well)
  63.     ; this requires 8 (bytes per entry) * 512 entries = 4KB
  64.    
  65.     ; entry 0
  66.     SetEntryInHighLevelPT   PML4T_BASE,                              PDPT_0_BASE,        PT_FLAGS_P_W
  67.  
  68.     ; entry 510
  69.     SetEntryInHighLevelPT   (PML4T_BASE + 510 * 8),                  PDPT_510_BASE,      PT_FLAGS_P_W
  70.     ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  71.  
  72.     ; PDPTs
  73.     ;;;;;;;;;;
  74.     ; PDPT_0
  75.     SetEntryInHighLevelPT   PDPT_0_BASE,                             PDT_0_0_BASE,       PT_FLAGS_P_W
  76.  
  77.     ; PDPT_510
  78.     SetEntryInHighLevelPT   PDPT_510_BASE,                           PDT_510_0_BASE,     PT_FLAGS_P_W
  79.     ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  80.  
  81.     ; PDTs
  82.     ;;;;;;;;;;
  83.     ; PDT_0_0
  84.     SetEntryInHighLevelPT   PDT_0_0_BASE,                            PT_0_0_0_BASE,      PT_FLAGS_P_W
  85.  
  86.     ; PDT_512_0
  87.     SetEntryInHighLevelPT   PDT_510_0_BASE,                          PT_510_0_0_BASE,    PT_FLAGS_P_W
  88.     ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  89.  
  90.  
  91.     ; Now the harder part :), the PTs
  92.     ; PT_0_0_0
  93.     ; Since we are identity mapping the first 2MB, we have to set the first entry to point to address 0,
  94.     ;   the next to 0x1000, the next to 0x2000 etc.
  95.     MapTwoMegsToPT          PT_510_0_0_BASE,        0x200000,   PT_FLAGS_P_W
  96.     MapTwoMegsToPT          PT_0_0_0_BASE,          0,          PT_FLAGS_P_W
  97.  
  98.     ; PT_510_0_0
  99.     ; We're mapping these addresses to the next 2MB of memory (2MB-4MB)
  100.  
  101.     ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  102.  
  103.  
  104.     ; Finally, we'll give the CPU the address to the PML4T
  105.     mov eax, PML4T_BASE
  106.     mov cr3, eax
  107.  
  108.     ; Now, let's enable PAE paging
  109.     mov eax, cr4
  110.     or eax, CR4_PAE_MASK
  111.     mov cr4, eax
  112.  
  113.     ; set LM bit
  114.     mov ecx, 0xC0000080
  115.     rdmsr
  116.     or eax, 1 << 8
  117.     wrmsr
  118.  
  119.     ; enable paging
  120.     mov eax, cr0
  121.     or eax, 1 << 31
  122.     mov cr0, eax
  123.    
  124.     ; go to long mode..
  125.     lgdt [gdt64_pointer]
  126.     call 0x8:main64bit  
  127.  
  128.     ret
RAW Paste Data