Lowlevel
Lowlevel => Lowlevel-Coding => Thema gestartet von: Nicolas am 12. July 2007, 22:50
-
Hallo,
Ich habe einen Bootloader (Aus dem LowLevel Wiki) und den C-Kernel von TeeJay.
Ich habe das ganze erfolgreich unter Linux/Gentoo kompiliert, gelinkt und assembliert. Sowie auch zusammen gefügt und auf die Diskette geschrieben.
Wenn ich die Diskette von auf meinem HauptPC booten will, seh ich nur einen blinkenden Cursor. Liegt warscheinlich an falschen BIOS Einstellungen.
Wenn ich die Diskette in meine alten P3 einlege, funktioniert es.
Allerdings wird hier sofort nachdem der Bootloader gestartet ist, rebootet. (Zum Kernel laden kommt es nicht mal.)
Eins sei gesagt, Assembler ist nicht so mein Ding, aber C und C++ verstehe ich.
Meine benutzen Befehle:
nasm -f bin -o kernel16.bin kernel16.asm
nasm -f aout -o kernel32.obj kernel32.asm
gcc -ffreestanding -c -Os -o ckernel.obj kernel.c
ld -T link.ld -o c32kernel.bin
cat boot.bin kernel16.bin c32kernel.bin > operatingsystem.img
dd if=operatingsystem.img of=/dev/fd0
Super, alles funktioniert ohne Probleme. Nichts... Nur der PC rebootet sobald der Bootloader gestartet wird.
Codes sind exact die gleichen wie vom Tutorial.
Hier noch ein Linker File:
OUTPUT_FORMAT("binary")
INPUT(kernel32.obj ckernel.obj)
ENTRY(start)
SECTIONS
{
.text 0x10200 : {
code = .; _code = .; __code = .;
*(.text)
. = ALIGN(1);
}
.data : {
data = .; _data = .; __data = .;
*(.data)
. = ALIGN(1);
}
.bss :
{
bss = .; _bss = .; __bss = .;
*(.bss)
. = ALIGN(1);
}
end = .; _end = .; __end = .;
}
Bitte, sagt mir nicht ich solle suchen. Ich suche schon seit Vormittag nach einer Lösung hier im Forum sowie bei Google und Co..
Nur, ich finde kein Thema welches mit meinem übereinstimmt.
Tut - 1: http://www.jay-code.de/scripts/htmlgenerator.php?page=ckernel&directory=tutorials
Tut - 2:
http://lowlevel.brainsware.org/wiki/index.php/Ausgabe_1
Ich hoffe ihr könnt mir helfen.
Gruß
-
Hi Nicolas, erstmal willkommen im Forum. :)
Eins sei gesagt, Assembler ist nicht so mein Ding, aber C und C++ verstehe ich.
Dann würde ich dir ans Herz legen, GRUB zu verwenden. Das machen die meisten hier, weil man sich damit viel unnötigen Ärger erspart und einige zusätzliche Features bekommt, die man mit einem eigenen Bootloader wohl sowieso nicht umsetzen würde.
TeeJays Code kenne ich auch aus diesem Grund nicht gut genug, um direkt irgendwas dazu sagen zu können. Ich weiß nur, daß damit immer wieder Probleme gemeldet werden. Wenn ich Zeit habe und dich die Lösung mit dem eigenen Bootloader trotz der besseren Alternative GRUB interessiert, schaue ich mir das heute abend vielleicht mal genauer an.
-
Ok, GRUB habe ich eh mit Gentoo mitinstalliert, werde ich mal probieren.
Trotzdem würde mich, wenn es möglich ist, die Lösung mit dem einen Bootloader auch interessieren. Aber ich probier jetzt mal GRUB.
Vielen Dank für deine Antwort!
// EDIT START
Habe jetz mit GRUB getestet. Aufgabe: GRUB soll <kernel.bin> von der Diskette booten.
So, habe nun den C-Kernel erneut durchgemacht. Draufgespielt, Error 17 (bedeutung kommt gleich).
Dann habe ich gelesen den GRUB Bootsektor stage1.
Habe das ganze in das .bin file gespielt (dd if=/boot/grub/stage1 of=kernel.bin).
Danach das ganze auf die Diskette (dd if=kernel.bin of=/dev/fd0).
Noch ein Gedanke: Ich verwende bei der Festplatte (hd0,0) also hab ichs mal mit (fd0,0) versucht. Nein, funktioniert nicht, Error 11 (bedeutung kommt gleich).
---
Error 11: Unrecognized device string
Error 17: Cannot mount selected partition
Boot-Log:
Booting 'Operating System'
root (fd0)
Filesystem unknown, using whole disk.
kernel /kernel.bin
Mein GRUB-Eintrag:
title=Operating System
root (fd0)
kernel /kernel.bin
//EDIT END
Gruß
-
fd0,0? Würde man damit nicht die Diskette in Partitionen einteilen?
bitmaster
-
Hmm, ich denke schon, also zumindest ist es so bei den Festplatten.
Nur, das hilft mir jetzt auch nicht weiter.
Gruß
-
Wenn dann muss es fd0 heißen bei grub. Welches Dateisystem hat den die Festplatte? Wenn NTFS, dann vergiss es, das geht nicht mit grub ;)
-
Hehe, Ich nutze Gentoo Linux ;)
Hab 3 Partitionen => hda1 => /boot, hda2 => Swap, hda3 => Linux System.
Und ich benutze GRUB.
fd0 ist mir schon klar, dann kommt aber wie oben beschrieben "Error 17"
-
Habe das ganze in das .bin file gespielt (dd if=/boot/grub/stage1 of=kernel.bin).
Danach das ganze auf die Diskette (dd if=kernel.bin of=/dev/fd0).
Faktisch hast du also stage1 auf die Diskette kopiert und vorher evtl. noch deinen Kernel überschrieben, wenn es die kernel.bin schon gab. Wolltest du das wirklich so machen? ;)
GRUB kann die Diskette deswegen nicht mounten, weil du kein Dateisystem draufgemacht hast. Wie man es richtig macht, habe ich vor einiger Zeit mal ins Wiki gestellt (http://lowlevel.brainsware.org/wiki/index.php/GRUB-Image_erstellen). Statt lost.krn nimmst du deinen eigenen Kernel, wichtig ist nur, daß er im ELF-Format ist und einen Multibootheader hat (kannst du mit mbchk prüfen).
-
ELF, heißt das ich soll den Assembler Kernel statt bin-file in ein elf-file assemblieren?
gruß
-
Ja, wäre zu empfehlen. GRUB kann zwar mit einem erweiterten Multiboot-Header auch mit anderen Formaten umgehen, aber ELF ist am problemlosesten. Damit brauchst du dann nur die Multiboot-Magic, die Flags und die Checksumme und das war's.
-
Wo finde ich den eine multiboot.h?
Gruß
-
ftp://alpha.gnu.org/gnu/grub/grub-0.97.tar.gz im Verzeichnis grub-0.97/doc/multiboot.h oder auch in der Multiboot Specification (http://www.gnu.org/software/grub/manual/multiboot/multiboot.html#multiboot_002eh).
-
Also, Ich habe nun den Kernel noch mal kompiliert - mit multiboot.h -. Ich habe noch eine andere Header datei genannt "std.h" in der ist auch das include für die multiboot.h drinnen.
Mein C-File included dann die std.h.
Ok, Kernel ist gebaut... nun mach ich einmal "mbchk kernel.bin"
Ausgabe: kernel.bin: No Multiboot Header.
Es ist die multiboot.h aus dem GRUB.tar.gz
Gruß
-
Achtung, Lizenz! Was GRUB ausliefert, steht unter der GPL und darf somit nur verwendet werden, wenn du deinen Kernel entweder auch unter der GPL freigibst oder ihn für immer für dich behältst und an gar niemanden weitergibst.
Schreib dir die paar structs, die du brauchst, lieber selbst aus der Spezifikation zusammen, dann hast du keine derartigen Probleme. Aber um erstmal überhaupt was bootbares zu bekommen, brauchst du gar keine multiboot.h.
Dazu mußt du nur den Multiboot-Header irgendwo innerhalb der ersten 8k unterbringen. Beispielsweise so (nasm-Syntax):
_start:
...
jmp $
multiboot_header:
align 4
MULTIBOOT_MAGIC equ 0x1BADB002
MULTIBOOT_FLAGS equ 0x03
MULTIBOOT_CHECKSUM equ -MULTIBOOT_MAGIC-MULTIBOOT_FLAGS
dd MULTIBOOT_MAGIC
dd MULTIBOOT_FLAGS
dd MULTIBOOT_CHECKSUM
-
Ja, mein Kernel steht unter GPL (hat auch die Kommentare der GPL drinnen).
Hab das nun eingebaut in meine kernel32.asm. Kompiliert, mbchk => All tests passed.
Nun hab ich wie im Wiki das GRUB Image erstellt. Nur statt /tmp/testimg hab ich /dev/fd0 genommen. (Floppy)
Er erkennt zwar die Diskette und will auch von der booten nur kommt Error 13 "Invald or unsupportef executable format".
Gruß
-
Bist du sicher, daß du den Multiboot-Header drin hast und ELF benutzt?
-
Meine kernel32.asm sieht so aus:
[Bits 32]
extern main
global start
start:
call main
stop:
jmp stop
multiboot_header:
align 4
MULTIBOOT_MAGIC equ 0x1BADB002
MULTIBOOT_FLAGS equ 0x03
MULTIBOOT_CHECKSUM equ -MULTIBOOT_MAGIC-MULTIBOOT_FLAGS
dd MULTIBOOT_MAGIC
dd MULTIBOOT_FLAGS
dd MULTIBOOT_CHECKSUM
wie lautet der befehl für ELF bei nasm?
Ich denke man kann nur die kernel16.asm in ELF, weil die kernel32 ja eine .obj ist... Naja, ich weiß nicht so viel davon.
Gruß
-
Für den Anfang sollten es diese paar Befehle tun:
nasm -felf kernel32.asm
gcc -c *.c
ld -Ttext=0x100000 -o kernel.elf *.o
Den 16-Bit-Kernel brauchst du mit GRUB nicht, du kannst sofort im Protected Mode loslegen.
-
Vielen Dank, es funktioniert!
Naja, noch nicht ganz.
Der Text also "Welcome to Protected Mode" wird zwar ausgeben darunter kommt aber eine Boot-Message.
Welcome to Protected Mode
root (fd0)
Filesystem type is fat, using whole disk
kernel /kernel.elf
[Multiboot-elf, <0x100000:0x81:0x0>, <0x101084:0x0:0x0>, shtab=0x102168, entry=0x100000]
Kann man die wegbringen?
Gruß
-
Jo, einfach erstmal überall Leerzeichen drüberschreiben. ;)
-
Wie meinst du das jetzt?
Ich hab jetzt in der kernel32.asm und kernel.c am anfang ein Leerzeichen hingeschrieben, doch funktionieren tut es nicht.
In einem Tutorial von osdever.net wurde eine clear_screen funktion deklariert.
Liegt es daran, soll ich diese Verwenden?
Gruß
-
Diese Nachricht kommt von GRUB und nicht von deinem Kernel. Du kannst einfach alle Zeichen auf dem Bildschrim mit Leerzeichen überschreiben oder die Farb-Attribute so setzten, dass man den Text nicht sieht.
-
Super danke,
Hab nun aus einem OSDever Tutorial das Ding eingefärbt.
Der Text ist zwar nun sehr unten, aber egal, werde das schon irgendwie hinkriegen.
Vielen Dank für deine Zeit und Hilfe taljeth!
Gruß
-
Sobald du verstanden hast, wie deine Textausgabefunktion funktioniert, kriegst du das Problem gelöst, daß der Text ganz unten ist. Dort wird sicher irgendwo eine Cursorposition gespeichert, die du dann eben entsprechend setzen mußt.
Aber mach dir nichts draus, ich habe auch mit zusammenkopierten Kerneln angefangen, ohne gleich alles zu verstehen. ;)
-
So weit ich weiß schreibt GRUB im RM etwas auf den Schirm (allso mittels int 10h oder so). Und der BIOS Interrupt speichert die Cursorposition in der BDA ab. Diese kannst du dann auslesen, X auf Null setzen und Y plus eins. Dann halt über die Ports den Cursor an die Position setzten. Wie genau das geht => live.de, google.de etc.
Oder wie schon erwähnt halt:
mov edi,0B8000h ;wenn ES-Basis = Null
mov ax,0020h
mov ecx,80*25 ;80*25 Zeichen pro Schirm
rep stosd
Dann ist der Schirm leer und du kannst deine Willkommensmeldung schreiben.
bitmaster