Hallo liebe Lowlevel-Community!
Bereits vor etwa einem Jahr habe ich mich mit ein bisschen mit OS-Dev beschäftigt und hier auch schon eine Frage gestellt. Ein wenig später hab ich allerdings meine Ubuntu-Installation geschrottet. Neulich habe ich mir dann wieder Ubuntu eingerichtet und wieder begonnen.
Wie auch immer, ich stehe gerade vor einem (wahrscheinlich meiner unendlichen Dummheit zuzuschreibendem) Problem:
Nach Aktivierung der Interrupts mittels "sti" gibts einen Triple Fault -> CPU Reset. Leider lässt sich der Fehler schwer finden, denn gdb braucht offensichtlich Interrupts für Breakpoints.
Als Codebasis habe ich eine Kombination von Lowlevel-Wiki-Tutorials, OS-Dev.org-Wiki-Tutorials und was man noch alles so im Netz findet.
Außerdem noch: kernel.c (mit void main, nichts besonderes) und handler.c (mit Handlern, derzeit ohne wirklichen Inhalt)
Wichtig! Verwendet wird SYSLINUX, nicht GRUB!
Kompiliert mit
Der Linkerscript ist "Standard".
Zum Ausführen nehme ich eine Variante des folgenden Scriptes: wiki.osdev.org/Bare_Bones
Den Reset gibt es nur bei eingeschalteten Interrupts. Ohne wird void main ordnungsgemäß aus geführt.
Hoffe, ich habe mein Problem verständlich erklärt und keine Information vergessen.
Bereits vor etwa einem Jahr habe ich mich mit ein bisschen mit OS-Dev beschäftigt und hier auch schon eine Frage gestellt. Ein wenig später hab ich allerdings meine Ubuntu-Installation geschrottet. Neulich habe ich mir dann wieder Ubuntu eingerichtet und wieder begonnen.

Wie auch immer, ich stehe gerade vor einem (wahrscheinlich meiner unendlichen Dummheit zuzuschreibendem) Problem:
Nach Aktivierung der Interrupts mittels "sti" gibts einen Triple Fault -> CPU Reset. Leider lässt sich der Fehler schwer finden, denn gdb braucht offensichtlich Interrupts für Breakpoints.
Als Codebasis habe ich eine Kombination von Lowlevel-Wiki-Tutorials, OS-Dev.org-Wiki-Tutorials und was man noch alles so im Netz findet.
Code: [Auswählen]
%macro idtentry 1
dw ((%1 - $$) + SECTIONBASE) & 0xFFFF
dw 0x08
db 0x0
db 0b10001110
dw (((%1 - $$) + SECTIONBASE) >> 16) & 0xFFFF
%endmacro
%macro handler 1
extern handler_%1
int_stub_%1:
push dword 0x0
push dword %1
push ebp
push edi
push esi
push edx
push ecx
push edx
push esp
call handler_%1
add esp, 0x4
pop eax
pop ebx
pop ecx
pop edx
pop esi
pop edi
pop ebp
add esp, 0x8
iret
%endmacro
%macro handler_errorcode 1
extern handler_%1
int_stub_%1:
push dword %1
push ebp
push edi
push esi
push edx
push ecx
push edx
push esp
call handler_%1
add esp, 0x4
pop eax
pop ebx
pop ecx
pop edx
pop esi
pop edi
pop ebp
add esp, 0x8
iret
%endmacro
%macro handler_irq_low 1
extern handler_%1
int_stub_%1:
push dword 0x0
push dword %1
push ebp
push edi
push esi
push edx
push ecx
push edx
push esp
call handler_%1
add esp, 0x4
pop eax
pop ebx
pop ecx
pop edx
pop esi
pop edi
pop ebp
add esp, 0x8
mov al, 0x20
out 0x20, al
iret
%endmacro
%macro handler_irq_high 1
extern handler_%1
int_stub_%1:
push dword 0x0
push dword %1
push ebp
push edi
push esi
push edx
push ecx
push edx
push esp
call handler_%1
add esp, 0x4
pop eax
pop ebx
pop ecx
pop edx
pop esi
pop edi
pop ebp
add esp, 0x8
mov al, 0x20
out 0xA0, al
out 0x20, al
iret
%endmacro
global loader
extern main
MODULEALIGN equ 1<<0 ; align loaded modules on page boundaries
MEMINFO equ 1<<1 ; provide memory map
FLAGS equ MODULEALIGN | MEMINFO ; this is the Multiboot 'flag' field
MAGIC equ 0x1BADB002 ; magic number
CHECKSUM equ -(MAGIC + FLAGS) ; checksum
SECTIONBASE equ 0x0100000
section .text
align 4
dd MAGIC
dd FLAGS
dd CHECKSUM
STACKSIZE equ 0x4000 ; 16k
loader:
cli
mov esp, stack + STACKSIZE
lgdt [cs:GDTR]
jmp 0x08:shortjmp
shortjmp:
mov ax, 0x10
mov ds, ax
mov es, ax
mov fs, ax
mov gs, ax
mov ss, ax
lidt [cs:IDTR]
mov al, 0x11
out 0x20, al
call io_wait
mov al, 0x20
out 0x21, al
call io_wait
mov al, 0x04
out 0x21, al
call io_wait
mov al, 0x01
out 0x21, al
call io_wait
mov al, 0x11
out 0xa0, al
call io_wait
mov al, 0x28
out 0xa1, al
call io_wait
mov al, 0x02
out 0xa1, al
call io_wait
mov al, 0x01
out 0xa1, al
call io_wait
xor al, al
out 0x20, al
call io_wait
out 0xa0, al
call io_wait
sti
int 0x30 ; als Testinterrupt mit Textausgabe. Triple Fault gibts aber auch so (PIT)
;push eax ; Multiboot magic number
;push ebx ; Multiboot info structure
call main
hang:
hlt
jmp hang
io_wait:
jmp dly
dly: ret
handler 0
;...
handler 48
GDTR:
dw GDT_END-GDT-1
dd GDT
GDT:
dd 0x0, 0x0
db 0xFF, 0xFF, 0x0, 0x0, 0x0, 0b10011010, 0b11001111, 0x0
db 0xFF, 0xFF, 0x0, 0x0, 0x0, 0b10010010, 0b11001111, 0x0
;db 0xFF, 0xFF, 0x0, 0x0, 0x0, 0b11111010, 0b11001111, 0x0 ; zu Fehlersuchzwecken auskommentiert
;db 0xFF, 0xFF, 0x0, 0x0, 0x0, 0b11110010, 0b11001111, 0x0
GDT_END:
IDTR:
dw 49 * 8 - 1
dd IDT
IDT:
idtentry int_stub_0
;...
idtentry int_stub_48
section .bss
align 4
stack:
resb STACKSIZE
Außerdem noch: kernel.c (mit void main, nichts besonderes) und handler.c (mit Handlern, derzeit ohne wirklichen Inhalt)
Wichtig! Verwendet wird SYSLINUX, nicht GRUB!

Kompiliert mit
Code: [Auswählen]
CC =gcc
CFLAGS =-Wall -Werror -Wextra -Wshadow -Wconversion -Wunreachable-code -Werror-implicit-function-declaration -Wuninitialized -nostdlib -nostartfiles -nodefaultlibs -ffreestanding -fno-builtin -m32 -g3
LDFLAGS =-m elf_i386
AS =nasm
LD =ld
all:kernel.bin
kernel.bin:
$(AS) -f elf -o loader.elf loader.S
$(CC) $(CFLAGS) -o kernel.elf -c kernel.c
$(CC) $(CFLAGS) -o handler.elf -c handler.c
$(LD) $(LDFLAGS) -T linker.ld -o kernel.bin loader.elf kernel.elf handler.elf
objcopy --only-keep-debug kernel.elf kernel.sym
objcopy --strip-debug kernel.elf
[...]
Der Linkerscript ist "Standard".
Zum Ausführen nehme ich eine Variante des folgenden Scriptes: wiki.osdev.org/Bare_Bones
Den Reset gibt es nur bei eingeschalteten Interrupts. Ohne wird void main ordnungsgemäß aus geführt.
Hoffe, ich habe mein Problem verständlich erklärt und keine Information vergessen.


Übersicht
Wiki
Hilfe
Suche
Einloggen
Registrieren
Drucken

Gespeichert
