Lowlevel
Lowlevel => Lowlevel-Coding => Thema gestartet von: errorXVI am 23. September 2009, 12:55
-
Hi,
ich bin dabei, ein 64bit-System zu programmieren und befinde mich selbst ebenfalls auf einer 64bit-Plattform (Kubuntu 64bit). Da ich GRUB verwende, muss ich jedoch einen 32bit-Loader schreiben, der den tatsächlichen Kernel lädt. Da ich für diese eine Datei kein ganzes Linkerscript schreiben will, suche ich nach einer Möglichkeit, mit einem Kommandozeilenparameter die Output-Architektur und das Output-Format zu setzen, also die Entsprechung zu OUTPUT_ARCH(i386:i386) und OUTPUT_FORMAT(elf32-i386). Ich hoffe mal, es gibt da eine Möglichkeit?
Grüße
errorXVI
-
ich bin mir nicht ganz sicher was OUTPUT_ARCH(…) macht aber vielleicht reicht dir das ja:
-melf_i386 --oformat elf32-i386
LD-Options (http://sourceware.org/binutils/docs/ld/Options.html)
-
Danke, genau das habe ich gesucht!
Ich habe nun ein weiteres Problem, wenn ich versuche, meinen Kernel (bzw. momentan nur den Startup-Code, den Rest muss ich erst noch portieren) zu kompilieren. Wenn ich das Ganze linke, bekomme ich folgende Fehlermeldung ausgespuckt:
-- Linking kernel executable
./boot/boot.o: In function `_start':
boot.asm:(.text+0x0): multiple definition of `start'
boot/boot.o:boot.asm:(.text+0x0): first defined here
./boot/boot.o: In function `_start':
boot.asm:(.text+0x0): multiple definition of `_start'
boot/boot.o:boot.asm:(.text+0x0): first defined here
./boot/boot.o: In function `start32':
boot.asm:(.text+0x2c): multiple definition of `start32'
boot/boot.o:boot.asm:(.text+0x2c): first defined here
./boot/boot.o: In function `multiboot_header':
boot.asm:(.text+0x18): relocation truncated to fit: R_X86_64_32 against `.text'
boot.asm:(.text+0x1c): relocation truncated to fit: R_X86_64_32 against `.text'
boot.asm:(.text+0x28): relocation truncated to fit: R_X86_64_32 against `.text'
./boot/boot.o: In function `start32':
boot.asm:(.text+0x38): relocation truncated to fit: R_X86_64_32 against `.text'
boot.asm:(.text+0x53): relocation truncated to fit: R_X86_64_32 against `.text'
./boot/boot.o: In function `code64Jump':
boot.asm:(.text+0x6e): relocation truncated to fit: R_X86_64_PC32 against symbol `start64' defined in .text section in ./boot/loader.o
./krnl/main.o:(.eh_frame+0x20): relocation truncated to fit: R_X86_64_32 against `.text'
make: *** [kernel] Error 1
Ich gehe stark davon aus, dass zumindest das erste Problem am Linkerscript liegt, aber da ich mich mit den ld-Skripten leider nicht sehr gut auskenne, weiß ich nicht, was daran falsch ist:
/*
* kernel.ld
*/
/* define kernel link locations */
kernel_VMA = 0xffff800000000000;
kernel_LMA = 0x100000;
ENTRY(_start)
/* define different sections */
SECTIONS
{
/* link from LMA */
. = kernel_LMA;
_boot = .;
_kernelLMA = .;
/* boot.asm is ran in linear addresses */
.text_boot :
{
boot/boot.o (.text)
}
_eboot = .;
/* link from VMA */
. = . + kernel_VMA;
_text = .;
_kernel = .;
_kernelVMA = kernel_VMA;
/* the rest of the code links to higher memory */
.text : AT(ADDR(.text) - kernel_VMA + kernel_LMA)
{
_code = .;
*(.text)
*(.text*)
*(EXCLUDE_FILE(*boot/boot.o) .text)
/* read only data */
*(.rodata*)
*(.rdata*)
. = ALIGN(4096);
}
/* _etext defined */
_etext = .; PROVIDE(etext = .);
_data = .;
/* data section */
.data : AT(ADDR(.data) - kernel_VMA + kernel_LMA)
{
data = .;
*(.data)
. = ALIGN(4096);
}
/* _edata defined */
_edata = .; PROVIDE(edata = .);
bss = .;
/* static code */
.bss : AT(ADDR(.bss) - kernel_VMA + kernel_LMA)
{
*(.bss)
. = ALIGN(4096);
}
_ebss = .;
.ehframe : AT(ADDR(.ehframe) - kernel_VMA + kernel_LMA)
{
ehframe = .;
*(.ehframe)
. = ALIGN(4096);
}
_end = .; PROVIDE (end = .);
_ekernel = .;
}
start, _start und start32 sind allesamt in der boot.asm definiert, die ich ja noch extra einbinde, aber eigentlich für den späteren Verlauf exclude.
Woran das "relocation truncated to fit R_X86_64_32 liegen könnte, weiß ich leider nicht.
-
*(.text) «--
[…]
*(EXCLUDE_FILE(*boot/boot.o) .text)
das sieht stark nach einem Fehler aus.
Woran das "relocation truncated to fit R_X86_64_32 liegen könnte, weiß ich leider nicht.
Da werden In- und Output-Format nicht übereinstimmen, oder du hast den falsche Parameter für -m… gewählt.
[edit]
Du versuchst deinen 32-Bit bootloader mit dem 64bit Kernel in einer ELF64 zu vereinen?
GRUB kann kein elf64 laden(zumindest nicht ohne Patch).
-
Aber mit patch kann es und das kann ich nur empfehlen. Den Patch habe ich in meinem Repository (http://repo.or.cz/w/lightOS.git?a=blob;f=toolchain/grub_x86_64.patch;h=480e38fceb7bd66a18f4ab9adde57b119fa0e985;hb=HEAD).Falls du grub nicht selbst bauen willst, kann ich dir auch ein Diskettenimage zur Verfügung stellen.
-
Du versuchst deinen 32-Bit bootloader mit dem 64bit Kernel in einer ELF64 zu vereinen?
GRUB kann kein elf64 laden(zumindest nicht ohne Patch).
Das habe ich auch gehört, aber dann habe ich in einem Tutorial gelesen, das würde keinen Unterschied machen und GRUB würde auch 64bit-Code laden können, deswegen wollte ich es erst einmal ausprobieren, bevor ich mich an das aufwändige Patchen/GRUB2 installieren mache.
Falls du grub nicht selbst bauen willst, kann ich dir auch ein Diskettenimage zur Verfügung stellen.
Das wäre nett! GRUB auf meinem 64bit-Rechner zu kompilieren bereitet leider trotz pure64-Patch größere Schwierigkeiten.
Grüße
errorXVI
-
Die amd64-Variante von tyndur linkt das alles irgendwie zu einer 32-Bit-Binary zusammen, mit der ein ungepatchter GRUB zurechtkommt. Näher angeschaut habe ich mir das noch nicht - könnte gut sein, dass das nicht so empfehlenswert ist, aber es geht anscheinend. ;)
Falls du einen Blick riskieren willst: amd64-Verzeichnis im git (http://git.tyndur.org/?p=tyndur.git;a=tree;f=src/kernel2/src/arch/amd64;h=ff2e58fc9e91334363943445e57d28e5baec7712;hb=HEAD). Makefile.all ist das Skript, das die Sachen zusammenbastelt.
-
Theoretisch wäre doch auch eine "2 Kern"-Lösung möglich.
Man lässt von GRUB einen 32Bit Kernel laden. Als Module bekommt dieser dann z.B. den 64Bit Kernel und den ganzen Rest an Modulen, der noch gebraucht wird. Der 32Bit Part aktiviert dann, falls möglich, den Long Mode und führt den 64Bit Kernel aus.
Das ist nur so eine Idee, die mir eben gekommen ist... Wäre natürlich umständlicher, als die Benutzung von GRUB2 oder einem gepatchten GRUB, aber es ist machbar... :roll:
-
Ja, das geht auch. Machen manche auch, glaube ich. Ist aber nicht so handlich wie eine einzelne Datei. ;)
-
ChristianF: hatte ich vorher gemacht, ist aber bescheiden (zumindest wenn man das ganze in Assembler macht), da es bei mir ca. 800 Codezeilen waren und ist anfangs häufig kaputt war (ungefähr das eigener-Bootloader-Erlebnis).
errorXVI: Gib mir mal über PM deine E-Mail-Adresse.
-
Wieso schreibst du sowas auch in Assembler? :|
-
Theoretisch wäre doch auch eine "2 Kern"-Lösung möglich.
Man lässt von GRUB einen 32Bit Kernel laden. Als Module bekommt dieser dann z.B. den 64Bit Kernel und den ganzen Rest an Modulen, der noch gebraucht wird. Der 32Bit Part aktiviert dann, falls möglich, den Long Mode und führt den 64Bit Kernel aus.
Das hatte ich mir auch überlegt, aber dann müsste ich erst noch die ELF Header parsen etc.
errorXVI: Gib mir mal über PM deine E-Mail-Adresse.
Abgesendet.
Grüße
errorXVI
-
Ich hab die E-Mail abgesendet. Wenn du in meinem vorherigen Beitrag schaust, ist dort der Link zu dem Patch in meinem Repository. Irgendwo in der mittendrin steht auch eine Erklärung was genau grub für dich macht.
-
Danke. Was der Patch macht hab ich mir schon angeschaut, scheint sich ja dann recht einfach booten zu lassen.
Grüße
errorXVI