Beiträge anzeigen

Diese Sektion erlaubt es dir alle Beiträge dieses Mitglieds zu sehen. Beachte, dass du nur solche Beiträge sehen kannst, zu denen du auch Zugriffsrechte hast.


Nachrichten - klaus55

Seiten: [1]
1
Vielen Dank für eure Hilfe! Es funktioniert jetzt.
Das Problem war, dass ich nur

menuentry "My Kernel" {
multiboot kernel-0.1
}

angegeben habe. Richtig ist aber
menuentry "My Kernel" {
multiboot /boot/kernel-0.1
}

Also ich hab das Verzeichnis nicht richtig angegeben. Wenn ich

menuentry "My Kernel" {
insmod multiboot kernel-0.1
}

mache kommt keine Fehlermeldung, aber er läd den Kernel auch nicht.

Naja, ich bin froh, dass es jetzt funktioniert  :-)

Danke nochmal an alle! Ist echt super, dass immer so schnell Leute antworten, auch wenn es so aussieht, als wär hier nicht viel los.

Edit: Und ich hab jetzt auch endlich verstanden wofür das multiboot gut ist.  :-)
2
Hm..wie meinst du das? Kannst du mir vielleicht ein Beispiel zeigen?
3
Okay, wenn ich jetzt den Kernel beim Starten auswähle, verschwindet das Menü kurz (vielleicht 5 ms oder so) und erscheint dann wieder.
Wenn ich meinen Kernel mit qemu ausführe schreibt er aber ein paar Sachen auf den Bildschirm, so wie es eigentlich sein sollte.
4
Okay, kannst du mir sagen wie das geht oder hast du nen passenden Link dazu?

Hab noch nicht groß Erfahrung mit GRUB.
5
Ja, das hab ich versucht, aber es klappt nicht so ganz wie ich es mache.

Also ich hab das Tutorial durchgemacht und benutze entsprechend das makefile von dort:

SRCS = $(shell find -name '*.[cS]')
OBJS = $(addsuffix .o,$(basename $(SRCS)))

CC = gcc
LD = ld

ASFLAGS = -m32
CFLAGS = -m32 -Wall -g -fno-stack-protector -nostdinc
LDFLAGS = -melf_i386 -Tkernel.ld

INC=-I/usr/include

kernel-0.1: $(OBJS)
  $(LD) $(LDFLAGS) -o $@ $^
 
%.o: %.c
  $(CC) $(INC) $(CFLAGS) -c -o $@ $^

%.o: %.S
  $(CC) $(ASFLAGS) -c -o $@ $^
 
clean:
  rm $(OBJS)
 
.PHONY: clean

In der grub.cfg hab ich den Eintrag hinzugefügt:

Zitat
menuentry "MyKernel" {
   multiboot kernel-0.1
}


Die Datei kernel-0.1 befindet sich im übergeordneten Ordner /boot.

Den Kernel kann ich beim Start auswählen, aber dann erscheint ein Fehler: error: couldn't open file
oder so ähnlich
6
Ich hätte jetzt nochmal eine Frage.
Also ich hab sozusagen den ersten Prototypen meines Kernels fertig. Bis jetzt habe ich ihn immer mit qemu getestet (qemu-system-x86_64 -kernel kernel).
Wie muss ich den Kernel jetzt installieren/kompilieren, damit ich ihn beim Start des Computers aus dem Boot-Menü auswählen und starten kann?
Ich verwende Linux und Grub.
7
Ich habe nochmal eine Frage zu dem ljmp.
Wenn ich mir irgendwelche instruction sets anschaue z.B. von Intel, dann finde ich immer nur ein jmp, aber kein ljmp.
Übersetzt der compiler das einfach in ein jump x:y? Wenn ja, wo finde ich eine Tabelle wo all diese Instruktionen aufgelistet sind?

8
So, habe nochmal eine Frage.

Auf dieser Seite http://www.lowlevel.eu/wiki/Global_Descriptor_Table wird diese Funktion beschrieben:

static void set_entry(int i, unsigned int base, unsigned int limit, int flags)
{
    gdt[i] = limit & 0xffffLL; // <-----
    gdt[i] |= (base & 0xffffffLL) << 16;
    gdt[i] |= (flags & 0xffLL) << 40;
    gdt[i] |= ((limit >> 16) & 0xfLL) << 48; // <-----
    gdt[i] |= ((flags >> 8 )& 0xffLL) << 52;
    gdt[i] |= ((base >> 24) & 0xffLL) << 56;
}

In dem angegebenen Beispiel wollen wir das Limit auf 0xfffff setzen. Jetzt frage ich mich aber wie das geht, denn
die Funktion bekommt ja nur einen unsigned int = 16 Bit übergeben. Das limit Feld ist aber so aufgeteilt, dass es 20 Bit umfasst.
Wenn man jetzt doch einen Rechtsshift macht, dann wird doch bei unsigned int mit 0en aufgefüllt, oder? dann wären die oberen vier Bit des
Limits aber 0 anstatt 1.

Verstehe ich das richtig oder was verstehe ich da falsch?

9
Super, danke für die schnelle und ausführliche Antwort zu dieser Zeit noch!  :-)
10
Hallo,

nachdem die GDT erstellt wurde und der GDT Pointer über lgdt gesetzt wurde, müssen ja noch die Segmentregister zurückgesetzt werden.

Das geht ja mit folgendem Code:

asm volatile(
           "mov $0x10, %ax;"
           "mov %ax, %ds;"
           "mov %ax, %es;"
           "mov %ax, %ss;"
           "ljmp $0x8, $.1;"
           ".1:"
       );

Nur verstehe ich noch nicht ganz was da gemacht wird.
Also 0x10 ist ja der Offset zu dem Kernel-Datensegment.
Nachdem dieser gesetzt wurde, mache ich dann einen long jump in mein Kernel-Codesegment (wieso genau? wo läuft mein Programm weiter?)

Hier verstehe ich nicht so ganz, was die vorletzte und die letzte Zeile bzw. $.1 und .1: bedeuten.

Vielleicht kann mir ja jemand weiterhelfen.

Gruß
Klaus55

Seiten: [1]

Einloggen