Прерывания BIOS в защищенном режиме

Я работаю над проектом операционной системы, используя isolinux (syslinux 4.5) в качестве загрузчика, загружая мое ядро с многозадачным заголовком, организованным в 0x200000.

Как я знаю, ядро уже находится в 32-битном защищенном режиме. Мой вопрос: есть ли более простой способ получить доступ к прерываниям BIOS? (В основном я хочу 0x10: D)

после загрузки мое ядро устанавливает свои собственные записи GDT и IDT и далее переназначает IRQ. Итак, можно ли перейти в реальный режим сразу после ядро загружается и настраивает режимы VGA/SVGA (режим VBE 2.0). Затем после того, как я продолжу свое ядро и перейду в защищенный режим, где я использую физический адрес буфера VBE 2.0 для записи на экран? Если да, то как? Я много пробовал, но не добился успеха : (

Примечание: Я много искал в интернете и нашел, что syslinux 1.x + предоставляет _intcall api, я не на 100% уверен в этом. См. раздел "syslinux 4.5com32libsysinitcall.c"

2 ответов


короткий ответ:нет. Вызовы BIOS предназначены для работы в реальном режиме и не уважают ограничения, установленные защищенным режимом, поэтому вам не разрешено их использовать, и CPU будет тройной ошибкой, если вы попытаетесь.

однако процессоры x86 предоставляют виртуальный режим 8086, который может использоваться для эмуляции процессора x86, работающего в 16-битном реальном режиме. Вики и форумы OSDev предоставляют богатую информацию по этой теме. Если вы идете по этому маршруту, это, как правило, хорошая идея сопоставить ядро с более высокой половиной (Linux использует 0xC0000000), чтобы избежать вмешательства в код VM86.


BIOS был разработан для 16-битных машин. Тем не менее, у вас есть три варианта вызова прерываний BIOS в защищенном режиме.

  1. переключитесь обратно в реальный режим и снова войдите в защищенный режим (самый простой подход).
  2. используйте режим v86 (недоступно в 64-разрядном длинном режиме).
  3. напишите свой собственный 16-битный эмулятор процессора x86 (самый сложный подход).

я использовал первый подход в своей операционной системе для доступа к VBE и диску через BIOS.
Код используемые для этой цели в моей операционной системе:

;______________________________________________________________________________________________________
;Switch to 16-bit real Mode
;IN/OUT:  nothing

go16:
    [BITS 32]

    cli         ;Clear interrupts
    pop edx         ;save return location in edx

    jmp 0x20:PM16       ;Load CS with selector 0x20

;For go to 16-bit real mode, first we have to go to 16-bit protected mode
    [BITS 16]
PM16:
    mov ax, 0x28        ;0x28 is 16-bit protected mode selector.
    mov ss, ax  
    mov ds, ax
    mov es, ax
    mov gs, ax
    mov fs, ax
    mov sp, 0x7c00+0x200    ;Stack hase base at 0x7c00+0x200    


    mov eax, cr0
    and eax, 0xfffffffe ;Clear protected enable bit in cr0

    mov cr0, eax    

    jmp 0x50:realMode   ;Load CS and IP


realMode:
;Load segment registers with 16-bit Values.
    mov ax, 0x50
    mov ds, ax
    mov fs, ax
    mov gs, ax
    mov ax, 0
    mov ss, ax
    mov ax, 0
    mov es, ax
    mov sp, 0x7c00+0x200    

    cli
    lidt[.idtR]     ;Load real mode interrupt vector table
    sti

    push 0x50       ;New CS
    push dx         ;New IP (saved in edx)
    retf            ;Load CS, IP and Start real mode

;Real mode interrupt vector table
.idtR:  dw 0xffff       ;Limit
    dd 0            ;Base