Real mode BIOS routine and Protected Mode

后端 未结 9 618
萌比男神i
萌比男神i 2021-02-06 02:03

I am doing some OS experiment. Until now, all my code utilized the real mode BIOS interrupt to manipulate hard disk and floppy. But once my code enabled the Protect Mode of the

9条回答
  •  爱一瞬间的悲伤
    2021-02-06 02:15

    V86: yes the way to go, but if setting up an OS:

    try this(designed for long mode but should work.I havent tested this YET, I see no reason it wont work yet.Issue is not nasm, its ld.)

    LD H8s 16-bit ELF/aout references.This is standard to load from GRUB.

    I kow the 32-bit CS is off, I need to double check its location. Otherwise it looks ok.

    This is hard to find code.

    -- ;modify for 32bit??

    ;this code is placed somewhere after 10000h
    ;-----we're in LONG MODE-----
      mov          dword [.stckptr], esp   ;first of all save stack
      sgdt         [.gdtv32]               ;save your gdt pointer
      lgdt         [.gdtv16]               ;load a new one
      sidt         [.idt32]                ;save your idt pointer
      lidt         [.idt16]                ;load real mode idt
      ;far jump in long mode is not possible, do a trick
      push         DESC_REAL
      push         @f-10000h               ;this is CS*10h, modify if needed!
      retfd
    .stckptr:
      dd           0
      align        16
    .gdtv32:
      dw           0
      dd           0
      align        16
    .gdtv16:
      dw           .gdtend-.gdt-1
      dd           .gdt,0
      align        16
    .gdt:
      dd           0,0                      ;null descriptor
    DESC_DATA=8                                 ;descriptor in YOUR GDT (modify)
    DESC_LONG=$-.gdt
      dd           00000000h,00209800h      ;32 bit  mode cs -MOD ME
    DESC_REAL=$-.gdt
      dd           0000FFFFh,00009801h      ;16 bit real mode cs (modify base if needed!)
    .gdtend:
      align        16
    .idt32:
      dw           0
      dd           0
      align        16
    .idt16:
      dw           3FFh
      dd           0
      USE16
    
    ;-----we're in COMPATIBLITY MODE-----
      ;disable paging and protmode at once
    @@:   mov          eax, cr0
      and          eax, 7FFFFFFEh   
      mov          cr0, eax
    
      ;set up real mode segment registers and stack
      mov          esp, realmode_stack_top          ;modify it to your needs!
      xor          ax, ax
      mov          ds, ax
      mov          es, ax
      mov          fs, ax
      mov          gs, ax
      mov          ss, ax
      ;convert long mode rip to real mode cs:ip
      ;jmp CS:(pmode address)-CS*10h
    
      jmp          1000h:@f-10000h                  ;modify if needed!
    ;-----we're in REAL MODE-----
    @@:   ;***********call some BIOS interrupt here**********
      mov          ax, 3
      int          10h
    
    
      ;switch back to long mode
      mov          eax, cr0
      or           eax, 80000001h
      mov          cr0, eax                         ;enable protmode and paging
    
      ;jmp         DESC_LONG:@f
      db           66h
      db           0EAh
      dd           @f
      dw           DESC_LONG
      USE32
    ;-----we're in protected MODE-----
    @@:   lgdt         [cs:.gdtv32]                    ;restore gdt
      mov          ax, DESC_DATA                   ;read YOUR DATA descriptor to selectors
      mov          ds, ax
      mov          es, ax
      mov          fs, ax
      mov          gs, ax
      mov          ss, ax
      lidt         [.idt32]                        ;restore idt
      mov          rsp, qword [.stckptr]           ;restore stack
      ;must be a non rip-relative jump
      mov          eax, @f
      jmp          eax
    @@:
    
      ;AS WE WERE!
    

提交回复
热议问题