Eigenen Kernel mit qemu testen.
-
Hoi,
habe mal zum Spaß dieses Tutorial verfolgt: http://www.lowlevel.eu/wiki/C%2B%2B-Kernel_mit_GRUB .
Kernel kompiliert und dann wollte ich ihn mit qemu mal laufen lassen.qemu-system-i386 kernel.bin
Jedenfalls beschwert sich qemu dass der Datenträger kein bootbares Medium ist. Ich kann mich aber erinnern dass das bei früheren Versuchen genau so geklappt hat.
Was mache ich falsch?
Danke und GRüße,
Ethon
-
Probier es mal so:
qemu-system-i386 -kernel kernel.bin
-
Danke, aber jetzt gibt's nen Crash, der auch bleibt, wenn der der einzig ausgeführte Code eine Endlosschleife ist.
[ferler@notebook-fedora17 OS]$ qemu-system-i386 -kernel kernel.bin qemu: fatal: Trying to execute code outside RAM or ROM at 0x00000000000a0000 EAX=00000000 EBX=00000000 ECX=00000000 EDX=00000000 ESI=00000000 EDI=00000000 EBP=00000000 ESP=00009fe0 EIP=0000fdfa EFL=00000002 [-------] CPL=0 II=0 A20=1 SMM=0 HLT=0 ES =9000 00090000 ffffffff 00cf9300 CS =9020 00090200 0000ffff 00009b00 SS =9000 00090000 0000ffff 00009300 DS =9000 00090000 0000ffff 00009300 FS =9000 00090000 0000ffff 00009300 GS =9000 00090000 0000ffff 00009300 LDT=0000 00000000 0000ffff 00008200 TR =0000 00000000 0000ffff 00008b00 GDT= 000ca264 00000017 IDT= 00000000 000003ff CR0=00000010 CR2=00000000 CR3=00000000 CR4=00000000 DR0=0000000000000000 DR1=0000000000000000 DR2=0000000000000000 DR3=0000000000000000 DR6=00000000ffff0ff0 DR7=0000000000000400 CCS=00000000 CCD=00000000 CCO=ADDB EFER=0000000000000000 FCW=037f FSW=0000 [ST=0] FTW=00 MXCSR=00001f80 FPR0=0000000000000000 0000 FPR1=0000000000000000 0000 FPR2=0000000000000000 0000 FPR3=0000000000000000 0000 FPR4=0000000000000000 0000 FPR5=0000000000000000 0000 FPR6=0000000000000000 0000 FPR7=0000000000000000 0000 XMM00=00000000000000000000000000000000 XMM01=00000000000000000000000000000000 XMM02=00000000000000000000000000000000 XMM03=00000000000000000000000000000000 XMM04=00000000000000000000000000000000 XMM05=00000000000000000000000000000000 XMM06=00000000000000000000000000000000 XMM07=00000000000000000000000000000000 Aborted (core dumped)
Kann das den überhaupt funktionieren? Qemu ist ja nicht grub, trotzdem wird auf der Website immer so getan als könnte man den Kernel, der Grub erwartet, einfach so mit qemu ausführen.
Meiner laienhaften Einschätzung liegt das Problem daran, dass das Linkerscript den Code auf 0x100000 positioniert, qemu aber den Real- und nicht den Protectedmode simuliert, dh. bei 0xa0000 ist Schluss ... liege ich hierbei richtig?
Falls ja, wo könnte ich nachlesen, wie ich den Kernel aus dem Link auf Qemu zum Laufen bekomme bzws welche Schritte fehlen?
Danke nochmal!
-
Frag die Jungs doch einfach im IRC channel de.euirc.net bei #lost.
Ansonsten schau Dir PrettyOS an.
-
Das Qemu BIOS bietet einfach die Funktion direkt einen Multiboot kompatiblen Kernel zu laden. Dazu gehört auch das Schalten in den Protected Mode etc., also klappt das schon. Ich habe es auch damals benutzt.
Deinen Fehler kann ich allerdings nicht so richtig deuten. Nur das der Fehler noch im Qemu BIOS auftritt. Das einzige was ich dazu gefunden habe ist, dass booten von Multiboot Kerneln erst ab Qemu 0.11 geht. Ich weiß nicht welche Version du da hast.
-
Wieder mal danke.
Bin noch nicht wirklich schlauer geworden, war mal in genanntem IRC, wo man zumindestens auf eine Merkwürdigkeit gestoßen ist ... ld platziert 1 MB "Nichts" vor den Multiboot-Header, aber der muss ja an einer tieferen Addresse liegen?[ferler@notebook-fedora17 OS]$ readelf -a kernel.bin ELF Header: Magic: 7f 45 4c 46 01 01 01 00 00 00 00 00 00 00 00 00 Class: ELF32 Data: 2's complement, little endian Version: 1 (current) OS/ABI: UNIX - System V ABI Version: 0 Type: EXEC (Executable file) Machine: Intel 80386 Version: 0x1 Entry point address: 0x10000c Start of program headers: 52 (bytes into file) Start of section headers: 1048632 (bytes into file) Flags: 0x0 Size of this header: 52 (bytes) Size of program headers: 32 (bytes) Number of program headers: 1 Size of section headers: 40 (bytes) Number of section headers: 5 Section header string table index: 2 Section Headers: [Nr] Name Type Addr Off Size ES Flg Lk Inf Al [ 0] NULL 00000000 000000 000000 00 0 0 0 [ 1] .text PROGBITS 00100000 100000 000015 00 AX 0 0 16 [ 2] .shstrtab STRTAB 00000000 100015 000021 00 0 0 1 [ 3] .symtab SYMTAB 00000000 100100 0000b0 10 4 8 4 [ 4] .strtab STRTAB 00000000 1001b0 000056 00 0 0 1 Key to Flags: W (write), A (alloc), X (execute), M (merge), S (strings) I (info), L (link order), G (group), T (TLS), E (exclude), x (unknown) O (extra OS processing required) o (OS specific), p (processor specific) There are no section groups in this file. Program Headers: Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align LOAD 0x000000 0x00000000 0x00000000 0x100015 0x100015 R E 0x200000 Section to Segment mapping: Segment Sections... 00 .text There is no dynamic section in this file. There are no relocations in this file. The decoding of unwind sections for machine type Intel 80386 is not currently supported. Symbol table '.symtab' contains 11 entries: Num: Value Size Type Bind Vis Ndx Name 0: 00000000 0 NOTYPE LOCAL DEFAULT UND 1: 00100000 0 SECTION LOCAL DEFAULT 1 2: 00000000 0 FILE LOCAL DEFAULT ABS asmKernel.asm 3: 00000000 0 NOTYPE LOCAL DEFAULT ABS FLAGS 4: 1badb002 0 NOTYPE LOCAL DEFAULT ABS MAGIC 5: e4524ffe 0 NOTYPE LOCAL DEFAULT ABS CHECKSUM 6: 00100000 0 NOTYPE LOCAL DEFAULT 1 MultiBootHeader 7: 00100013 0 NOTYPE LOCAL DEFAULT 1 stop 8: 00100015 0 NOTYPE GLOBAL DEFAULT 1 start_ctors 9: 00100015 0 NOTYPE GLOBAL DEFAULT 1 end_ctors 10: 0010000c 0 NOTYPE GLOBAL DEFAULT 1 loader No version information found in this file.
Wie kann ich das Problem behaben? Hier nochmal das Linkerscript, die Zeile ". = 0x100000" auszukommentieren hilft nichts ...
ENTRY(loader) OUTPUT_FORMAT(elf32-i386) OUTPUT_ARCH(i386:i386) SECTIONS { . = 0x0100000; .text : { *(.text*) *(.rodata) } .data : { start_ctors = .; *(.ctors) end_ctors = .; *(.data) } .bss : { *(.bss) } /DISCARD/ : { *(.dtors) *(.comment) } }
Und hier mal der "Kernel" selbst:
global loader ; Unser Einsprungspunkt ;extern kernelMain ; kernelMain() aus Kernel.cpp ;extern initialiseConstructors ; aus Startup.cpp FLAGS equ 0 MAGIC equ 0x1BADB002 ; Magicnumber - Erkennungsmerkmal für GRUB CHECKSUM equ -(MAGIC + FLAGS) ; Checksum section .text align 4 MultiBootHeader: dd MAGIC ; Magic number dd FLAGS ; Flags dd CHECKSUM ; Checksum loader: mov esp,0x200000 ; Stack an die 2MB-Grenze platzieren push eax ; Multiboot-Magicnumber auf den Stack legen push ebx ; Adresse der Multiboot-Structure auf den Stack legen ;call initialiseConstructors ; Konstruktoren aufrufen ;call kernelMain ; kernelMain aufrufen stop: jmp stop ; Endlosschleife nach Beendigung unseres Kernels
Ich komm einfach nicht drauf.
Grüße,
Ethon
-
Ich habe den kernel mal mit dem Einsprungpunkt von PrettyOS verglichen. Wirklich relevante Unterschiede konnte ich nicht feststellen (.text wird bei uns nicht angegeben und als Flag nutzen wir 10b statt 0).
Hast du mal versucht, den Kernel mit Grub zu booten?