Real mode BIOS routine and Protected Mode

后端 未结 9 614
萌比男神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:08

    If you're writing an operating system, it really needs to have device drivers for any hardware it needs to use, including the storage devices. If you want to avoid needing drivers at such an early stage, you could consider using an existing bootloader like grub, but eventually you'll need them anyway.

    0 讨论(0)
  • 2021-02-06 02:11

    If you'd like code to read the harddrive (or USB key) from 32-bit mode, you can find some from my OS project PwnOS. It doesn't support DMA or anything, but the basics work. Specifically, trunk/Core/IO/ATA Driver.asm contains the code for reading an ATA device, e.g. harddrive (without magic numbers! :D)

    I decided not to write the code for writing a device, since I didn't want to risk it, but it's very similar. The specs can be found at the first google hit for "cottontail os dev" (you'll want the ATA/ATAPI-6 document), but they're a bit hard to follow.

    If you have any more questions about it, feel free to ask. I've got code to get set up into 64-bit mode as well, as well as an assembly language editor that I specifically designed for OS development (search for Inventor IDE), in that it has built-in assembling and linking of 16-bit, 32-bit, and 64-bit code at defined addresses and file offsets. That way, you can focus on the part you're interested in, instead of the fluff.

    0 讨论(0)
  • 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!
    
    0 讨论(0)
  • 2021-02-06 02:16

    It seems that your question is not how to talk to hardware (the problem device drivers would solve) because the BIOS interfaces are sufficient for you.

    Rather, you need to know how to communicate between protected mode ring 0 (which has unlimited access to BIOS calls and all other privileged instructions) and protected mode ring 3 where application code usually lives. This is a system call. Pretty much all architectures run interrupt handlers in privileged mode so a software interrupt is one way of implementing system calls, x86 also provides a syscall instruction which is optimized for this purpose.

    Of course, you could just run everything in ring 0 with a flat memory model where you can access all memory directly.

    Ring 0/ring 3 is the x86 terminology, but all systems with an MPU support some concept of a privileged mode which allows access to memory by physical address (and for split memory-I/O architectures, access to all of I/O space).

    0 讨论(0)
  • 2021-02-06 02:20

    ATAPI devices use the same ports. You can emulate DPMI in order to get past the 1MB+64k limit, but yeah, learn Protected Mode.

    0 讨论(0)
  • 2021-02-06 02:28

    The project is now an old one, but the OSKit project at Utah — which might still run on modern machines, since other late-1990s operating systems can still find the RAM and disk drives on today's PCs? — was a device-driver stack build separately from any particular operating system so that you could develop your own kernel just by writing C code.

    It was kind of neat; you could compile "Hello, world." in C against OSKit and get an OS you could boot that came up and printed "Hello, world." and then halted. :-)

    Anyway, if you are really doing an "OS experiment", you might want to try it out — or at least use its code as a guideline for how to get up and running with some drivers. Of course, if you're really doing less of an "OS experiment" and more of a "learn obscure facts about x86", then it might do more than you want. :-)

    http://www.cs.utah.edu/flux/oskit/

    0 讨论(0)
提交回复
热议问题