0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

x86アセンブリをDVDから起動し32bit切り替え迄の手順

0
Posted at

目的

Pentiumの古いパソコンを所有しており、ベアメタルの実験をしたいのですが、あまりに古くHDDと光学ドライブからの起動にしか対応していない為、アセンブリで書いたコードをDVDに書き込み実機で動かすまでの手順を纏めました。
今回動かしたのは起動してから32ビットモードに入るだけの単純なコードです。

検証

ThinkPad X280

a6a90a75a63448

dybabook SS M10 11L/2

7de9352ad2bb9

コンパイルからDVD書き込み

nasm -f bin boot.asm -o boot.bin

mkdir iso
cp boot.bin iso/

xorriso -as mkisofs \
  -o os.iso \
  -b boot.bin \
  -c boot.cat \
  -no-emul-boot \
  -boot-load-size 4 \
  iso
  
qemu-system-x86_64 -cdrom os.iso -m 512 -boot d
  
sudo dvd+rw-format -blank=fast /dev/sr0
sudo growisofs -dvd-compat -Z /dev/sr0=os.iso
boot.asm
[org 0x7C00]
bits 16

start:

    cli
    xor ax, ax
    mov ds, ax
    mov es, ax
    mov ss, ax
    mov sp, 0x7C00
    
    mov ax, 0x0003
    int 0x10 

    ; GDTロード
    lgdt [gdt_descriptor]

    ; 32bitモード有効化
    mov eax, cr0
    or eax, 1
    mov cr0, eax

    ; 32ビットコードへ移行
    jmp 0x08:pm_start

; -----------------------------
gdt_start:
    dq 0x0000000000000000            ; NULL

gdt_code:
    dw 0xFFFF                        ; limit 0-15
    dw 0x0000                        ; base 0-15
    db 0x00                          ; base 16-23
    db 0x9A                          ; code segment
    db 0xCF                          ; flags
    db 0x00                          ; base 24-31

gdt_data:
    dw 0xFFFF
    dw 0x0000
    db 0x00
    db 0x92                          ; data segment
    db 0xCF
    db 0x00
gdt_end:

gdt_descriptor:
    dw gdt_end - gdt_start - 1
    dd gdt_start

; ----------------------
; 32ビット突入
; ----------------------
[bits 32]
pm_start:
    ; データセグメント設定
    mov ax, 0x10
    mov ds, ax
    mov es, ax
    mov fs, ax
    mov gs, ax
    mov ss, ax
    mov esp, 0x9FC00
    
    cli
    

    ;lidt [idt_descriptor]
    
    ; ===== VRAM に文字列描画 =====
    mov edi, 0xB8000        ; VRAM 開始
    mov esi, msg_32bit    
   

.draw_char:
    lodsb                   ; AL = *ESI++
    test al, al
    jz .next
    mov ah, 0xCE   ; 赤背景 + 明るい黄色文字
    stosw                   ; [EDI] = AX
    jmp .draw_char
    
.next:
    


.hlt_loop:
    hlt
    jmp .hlt_loop
    
; set_idt_gate(irq, handler)
; EAX = IRQ番号
; EBX = ハンドラアドレス
set_idt_gate:
    push esi

    mov esi, idt_start
    imul eax, 8
    add esi, eax

    mov word [esi + 0], bx
    shr ebx, 16
    mov word [esi + 6], bx

    mov word [esi + 2], 0x08   ; コードセグメント
    mov byte [esi + 4], 0x00; 
    mov byte [esi + 5], 0x8F   ; Trap Gate(INT1用)

    pop esi
    ret

; ----------------------
; データ領域
; ----------------------
msg_32bit db "32-bit protected mode entered!", 0

; x86 の IDT は最大 256 個
idt_start:
    times 256 * 8 db 0
idt_end:

idt_descriptor:
    dw idt_end - idt_start - 1
    dd idt_start

times 3072-($-$$) db 0
0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?