Autor Thema: Longmode Fragen  (Gelesen 8355 mal)

Scan

  • Beiträge: 14
    • Profil anzeigen
Gespeichert
« am: 31. January 2008, 14:05 »
Da ich ja jetzt endlich 'ne 64 Bit Maschine habe, wollte ich (natürlich) auch ein wenig beim Programmieren aufrüsten. Im Moment lese ich das AMD Manual zum AMD64 format, aber da die Community mir immer mehr sagen konnte als die entwickler, wollte ich hier mal ein paar fragen stellen:

1. Wie komme ich in den 64 bit Modus? (Konnte ich nirgens finden)
2. Was verändert sich beim programmieren im 64 bit Modus (GDT, IDT, Tasks)
3. Was ändert sich beim Kompilieren (Linkerdatei, spezielle gcc-flags usw)

Danke im Voraus für die antworten  :-D
« Letzte Änderung: 31. January 2008, 14:07 von Scan »

bitmaster

  • Troll
  • Beiträge: 1 138
    • Profil anzeigen
    • OS-64 = 64 Bit Operating System
Gespeichert
« Antwort #1 am: 31. January 2008, 15:30 »
1) Steht im AMD64 Manual Volume 2 unter "14.8 Long-Mode Initialization Example" S. 430 (im Acrobat Reader 470).

2) Also:

- es steht kein Hardwaremultitasking mehr zur verfügung
- die meisten Register sind jetzt 64 Bit groß
usw. :-)

3) kA, ich progge in ASM

bitmaster
In the Future everyone will need OS-64!!!

Scan

  • Beiträge: 14
    • Profil anzeigen
Gespeichert
« Antwort #2 am: 31. January 2008, 16:35 »
1) Ah danke für den Hinweis =D

2) Also gibt es kein TSS register mehr?

3) Na ja so was will ich nicht versuchen

Danke für die schnelle Antwort =D

nooooooooos

  • Beiträge: 734
    • Profil anzeigen
Gespeichert
« Antwort #3 am: 31. January 2008, 16:38 »
2) Ja, hauptsächlich...Etwas äquivalentes gibt es allerdings für das Umschalten zwischen den Ringen...
3) Ist nicht soo viel schlimmer als C...


Gruss
Nooooooooooos

Scan

  • Beiträge: 14
    • Profil anzeigen
Gespeichert
« Antwort #4 am: 31. January 2008, 17:15 »
2) Also alles mit software-threading... hmm

3) Aber einen JIT-Compiler in ASM? Na ja...

Scan

  • Beiträge: 14
    • Profil anzeigen
Gespeichert
« Antwort #5 am: 31. January 2008, 17:17 »
4) Und ein eintrag in die 64 bit GDT/IDT, wie sehen die aus?

bluecode

  • Beiträge: 1 391
    • Profil anzeigen
    • lightOS
Gespeichert
« Antwort #6 am: 31. January 2008, 18:34 »
Zitat
3. Was ändert sich beim Kompilieren (Linkerdatei, spezielle gcc-flags usw)
Meine g++ flags unter x86-64: -fuse-cxa-atexit -nostdlib -fno-builtin -fno-rtti -fno-exceptions -Wall -fno-omit-frame-pointer -m64 -mno-red-zone -mno-sse -mcmodel=kernel
Am besten baust du dir einen Crosscompiler. Im osdev.org wiki steht wie man das für x86-64 macht.
Am Linkerscript hat sich bei mir nur das OUTPUT_FORMAT und die Adresse des Kernelbeginns geändert.

Generell ist zu sagen, dass sich der Aufbau der GDT (Kapitel 4.2.1 & 4.4.1 -> brauchst nur Codesegmentdeskriptoren, alles andere kann 0 sein) /IDT (Kapitel 4.8.3.1), des TSS (jo, das gibt es schon noch), der Register geändert hat. Zu beachten ist auch noch, dass eigentlich nur weniger Instruktionen als immediate Wert einen 64bit Integer haben können (darunter natürlich mov). Außerdem iretq explizit verwenden in den Interrupthandlern (sonst will die Saubacke von Assembler immer das normale 32bit iret nehmen).
edit: Paging geht über 4Level, damit man sinnvoll zu einer 48bit Adresse kommt.Standardspeicherseitengröße ist trotzdem weiterhin 4kb. Syscall/Sysret für syscalls nutzen anstatt Interrupt (auch mal die neue Instruktion swapgs dazu anschauen, Intel Manuals 2B). Es verspricht schneller zu sein.
Mir fällts grad auf: Meine Kapitelnummern beziehen sich auf die Manuals von Intel (nicht AMD).
« Letzte Änderung: 31. January 2008, 18:39 von bluecode »
lightOS
"Überlegen sie mal 'nen Augenblick, dann lösen sich die ganzen Widersprüche auf. Die Wut wird noch größer, aber die intellektuelle Verwirrung lässt nach.", Georg Schramm

Scan

  • Beiträge: 14
    • Profil anzeigen
Gespeichert
« Antwort #7 am: 31. January 2008, 21:13 »
Nur ne kleine Frage, dann les ich nochmal AMD und Intel genau durch: Was wäre denn ein guter Wert für den Kernel, um gemappt zu werden

OUTPUT_FORMAT("elf64-x86-64")
ENTRY(start)
phys = 0x0000000000100000; /* 1 megabytes */
virt = 0x0000800000000000; /* 128 gigabytes */
diff = virt - phys;
SECTIONS
{
. = virt;

__kernel_phys_start__ = . - diff;

.text : AT(ADDR(.text) - diff)
{
*(.text)
*(.rodata*)
. = ALIGN(0x1000);
}
.data ALIGN(0x1000) : AT(ADDR(.data) - diff)
{
*(.data)
}
        .bss ALIGN(0x4) :  AT(ADDR(.bss) - diff)
        {
*(.bss)
*(COMMON)
}

. = ALIGN(0x1000);

__kernel_phys_end__ = . - diff;
}

das ist jetzt meine linkerdatei, und irgendwie beschwert sich ld, dass text, data und bss am falschen platz sind
« Letzte Änderung: 31. January 2008, 21:27 von Scan »

bluecode

  • Beiträge: 1 391
    • Profil anzeigen
    • lightOS
Gespeichert
« Antwort #8 am: 31. January 2008, 22:06 »
Nunja, das hat mit den Intel/AMD Manuals (leider) nicht viel zu tun. Das Problem liegt da eher bei gcc. Es gibt im Longmode mehrere Möglichkeiten zur Codegeneration. Damit ist gemeint wie groß die benutzten Adressen wirklich sein dürfen (Zeiger auf Daten sind immer 64bit):
 * small code model: Code in den unteren 2GiB, Relocations müssen in den unteren 2GiB liegen (also alle shared-libraries)
 * kernel code model: Code in den oberen 2GiB (Wird erreicht über signextension)
 * medium code model: Code in den unteren 2GiB, Relocations auch über 2GiB möglich
 * large code model: Code/Relocations auch über 2GiB möglich
Das Problem mit gcc ist nun, dass das large code model erst mit gcc 4.3, welcher noch nicht freigegeben wurde, unterstützt. D.h. man "muss" (was ja prinzipiell kein Problem ist) das kernel code model nehmen und damit den kernel in den obersten 2GiB des Adressraums haben.
Man wählt im übrigen das Codemodel über die Option -mcmode, siehe auch gcc homepage.
lightOS
"Überlegen sie mal 'nen Augenblick, dann lösen sich die ganzen Widersprüche auf. Die Wut wird noch größer, aber die intellektuelle Verwirrung lässt nach.", Georg Schramm

Scan

  • Beiträge: 14
    • Profil anzeigen
Gespeichert
« Antwort #9 am: 31. January 2008, 22:29 »
soll also heißen, gcc macht es nicht mit, wenn ich versuche, über 4 GB oder unter 2 GB den kernel zu mappen?

edit: Außerdem: Wieso ist mein Kernel, ohne eigentlichen Inhalt, schon 2 MB groß? Wie soll ich denn testen ohne Floppy?
« Letzte Änderung: 31. January 2008, 22:31 von Scan »

bluecode

  • Beiträge: 1 391
    • Profil anzeigen
    • lightOS
Gespeichert
« Antwort #10 am: 31. January 2008, 22:58 »
soll also heißen, gcc macht es nicht mit, wenn ich versuche, über 4 GB oder unter 2 GB den kernel zu mappen?
Theoretisch mit dem entsprechenden -mcmodel schon. Also -mcmodel=small für die unteren 2GB und -mcmodel=large wenn es egal sein soll. Wobei ersteres ungeschickt ist, da man möglichst viel virtuellen Raum für Anwendungen haben will und letzteres geht ja nicht, da es noch nicht implementiert/freigegeben ist. Deswegen wurde eben -mcmodel=kernel implementiert.

Zitat
Wieso ist mein Kernel, ohne eigentlichen Inhalt, schon 2 MB groß?
Schau dir mal mein Linkerscript an, ich glaube dass SIZEOF_HEADERS der entscheidende Punkt war, aber sicher bin ich mir auch nichtmehr.
lightOS
"Überlegen sie mal 'nen Augenblick, dann lösen sich die ganzen Widersprüche auf. Die Wut wird noch größer, aber die intellektuelle Verwirrung lässt nach.", Georg Schramm

Scan

  • Beiträge: 14
    • Profil anzeigen
Gespeichert
« Antwort #11 am: 01. February 2008, 13:00 »
Okay, mal abgesehen davon, dass sich der LD beschwert, wenn ich über 4 GB versuche zu mappen, scheint es zu funktionieren. Danke

bluecode

  • Beiträge: 1 391
    • Profil anzeigen
    • lightOS
Gespeichert
« Antwort #12 am: 01. February 2008, 13:21 »
Was für eine Fehlermeldung bringt LD denn (orginal Wortlaut wäre nicht schlecht)? Ich kann mir jetzt grad nicht vorstellen wo da das Problem sein soll. Es sei denn du nutzt nicht -mcmodel=kernel zum compilieren.
lightOS
"Überlegen sie mal 'nen Augenblick, dann lösen sich die ganzen Widersprüche auf. Die Wut wird noch größer, aber die intellektuelle Verwirrung lässt nach.", Georg Schramm

Scan

  • Beiträge: 14
    • Profil anzeigen
Gespeichert
« Antwort #13 am: 01. February 2008, 22:46 »
start.o: In function `start':
src/start.asm:(.text+0x37): relocation truncated to fit: R_X86_64_32 against `.text'
start.o: In function `start_long':
src/start.asm:(.text+0x4b): relocation truncated to fit: R_X86_64_32 against `.data'
src/start.asm:(.text+0x53): relocation truncated to fit: R_X86_64_32 against `.data'

Wäre die Fehlermeldung...

Aber irgnedwie ist mir das alles zu umständlich, vielleicht bleibe ich erstmal bei 32 bit ^^ Danke für eure Mühen  :-)

bluecode

  • Beiträge: 1 391
    • Profil anzeigen
    • lightOS
Gespeichert
« Antwort #14 am: 03. February 2008, 14:33 »
Könntest du mir evtl. mal deine Buildumgebung (Makefiles, Sourcecode, etc...) schicken? Dann könnte ich es mir anschauen. Dann wäre auch anderen mit dem gleichen Fehler geholfen. :-)

Zitat
Aber irgnedwie ist mir das alles zu umständlich
Jo, bei mir hat es auch etwas gedauert bis ich das raushatte.

Zitat
vielleicht bleibe ich erstmal bei 32 bit
Wenn du dir ein bisschen Gedanken über Portabilität beim Designen machst, dann kannst du auch long- & protected-mode unterstützen.
lightOS
"Überlegen sie mal 'nen Augenblick, dann lösen sich die ganzen Widersprüche auf. Die Wut wird noch größer, aber die intellektuelle Verwirrung lässt nach.", Georg Schramm

 

Einloggen