2014-10-19 39 views
6

Bir işletim sistemi projesinde, bootloader olarak isolinux (syslinux 4.5) kullanarak, çekirdeğimi 0x200000'de organize edilen çoklu önyükleme başlığına yüklüyorum.BIOS Korunmuş modda kesmeler

Çekirdeğin zaten 32 bit korumalı modda olduğunu biliyorum. Sorum şu: BIOS kesintilerine erişmek için daha kolay bir yolu var mı? (Temelde 0x10: D'yi istiyorum:

Yüklemeden sonra, çekirdeğim kendi GDT ve IDT girişlerini ayarlar ve IRQ'ları daha fazla giderir. Bu nedenle, çekirdek yüklendikten ve VGA/SVGA modlarını (VBE 2.0 modu) kurduktan hemen sonra gerçek moda geçmek mümkündür. Sonra çekirdeğime devam edip ekrana yazmak için VBE 2.0 fiziksel arabellek adresini kullandığım korumalı moda geçelim. Evet ise nasıl? Ben çok denedim ama başarı :(

Yan not

alamadım. Ben internette bir sürü aradı ve o syslinux.cfg 1.x + ben bu konuda% 100 emin değilim, _intcall api sağlar bulundu bakın "syslinux 4.5 \ COM32 \ lib \ sys \ initcall.c"

cevap

2

kısa cevap hiçbir. BIOS çağrıları gerçek modunda çalışacak şekilde tasarlanmıştır ve korumalı mod tarafından belirlenen kısıtlamaları saygı yok, sen öylesine Onları kullanmak için izin verilmez ve CPU çalışırsanız üçlü hata olur.

Ancak, x86 işlemcileri bir x86 processo öykünmesi için kullanılabilecek Virtual 8086 mode sağlar r 16 bit gerçek modda çalışıyor. OSDev wiki ve forumları bu konu hakkında çok sayıda bilgi sağlar. Bu rotaya giderseniz, VM86 koduna müdahale etmekten kaçınmak için çekirdeği yüksek yarıya (Linux 0xC0000000 kullanır) aktarmak genellikle iyi bir fikirdir.

2

BIOS, 16 bit makineler için tasarlanmıştır. Ancak, hala korumalı modda BIOS kesmeleri aramak için üç seçeneğiniz vardır.

  1. Yeniden gerçek moda geçin ve korumalı moda yeniden girin (En kolay yaklaşım).
  2. V86 modunu kullanın (64 bit uzun modda kullanılamaz).
  3. Kendi 16 bit x86 işlemci emülatörünüzü yazın (En zor yaklaşım).

VBE için işletim sistemimde ve BIOS aracılığıyla disk erişimi için ilk yaklaşımı kullandım.
Bu amaç için kullanılan kod benim işletim sistemim:

;______________________________________________________________________________________________________ 
;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