81
Lowlevel-Coding / Re: Verständnisfragen
« am: 04. September 2009, 11:39 »Das würde also heißen, das ein "ALIGN 16" auch ausreichen sollte und man dieses, wenn man die performance nicht betrachtet, auch weglassen könnte.Und zwar habe ich im Assemblerstub für GRUB folgenden Abschnitt:Ein gewisses Alignment für den Stack (und für alle Daten im allgemeinen) ist für die Performance von Vorteil. Man hätte das auch mit anderen Mitteln erreichen können, z.B. die Stackvariable nachträglich anpassen können.Code: [Auswählen][SECTION .bss]
Dieser Abschnitt reserviert Daten für den Stack (16 KiB). Die Sektion BSS deswegen, weil es sich ja um uninitialisierte Daten handelt. Nun verstehe ich allerdings nicht, warum darüber ein "ALIGN 32" steht.
ALIGN 32
stack:
resb OS_STACK_SIZE
Und ich glaube zur Zeit gibt es keine Register in aktuellen CPUs, die größer als 16 Bytes sind bzw. von mehr als 16 Byte Alignment profitieren. Also ist die 32 vielleicht etwas übertrieben. (Ich glaube der GCC sorgt in der 64 Bit Version auch nur für 16 Byte Alignment.)
Nun gut, dann ist verständlich, warum die Daten Page-aligned sind. Nun ist es in dem Linkerscript von mir so, dass nur die Daten Page-aligned sind. Sollten da nicht alle Sektionen ein "ALIGN(0x1000)" bekommen?Die einzelnen Sektionen sind mir soweit klar. Nur frage ich mich, warum die Sektionen nach .text (.data und .bss) bei mir und in vielen Tutorials ein ALIGN(0x1000) haben.Page-alignment ist immer dann von Vorteil, wenn Paging im Spiel ist. Falls du deinen Kernel in einen anderen Speicherbereich mappen willst, und nicht mit "halben Seiten" hantieren willst, kann das eventuell deinen Algorithmus vereinfachen.
Laut Manual heißt dass, das diese Sektionen dann an Page-Aligned werden. Das heißt also, dass .bss an 0x00101000 liegt (laut objdump). Aber was bringt das für Vorteile?Code: [Auswählen].data ALIGN(0x1000) : { /*...*/ }
Wenn du allerdings Programme laden willst, dann ist es von noch größerem Vorteil, dass deren Sektionen page-aligned sind, weil du dann deinen eigenen Lade-Algorithmus ein gutes Stück einfacher gestalten kannst.
Außerdem ist so eine Trennung der Sektionen auf Seitengrenzen Voraussetzung, dass du das No-Execute-Bit effektiv benutzen kannst. (Ich glaube die ersten beiden Gründe sind wichtiger als dieser. Sowas macht eh keiner^^)
Ich habe mir mal die Arbeit gemacht, ein eigenes Linkerscript zu schreiben. Folgendes ist dabei zustande gekommen:
Code: [Auswählen]
ENTRY(_start)
OUTPUT_FORMAT(elf32-i386)
/* some variables */
KERNEL_VMA = 0x00100000; /* VMA = virtual memory address */
KERNEL_LMA = 0x00100000; /* LMA = load memory address */
KERNEL_VMA_TO_LMA = KERNEL_VMA - KERNEL_LMA; /* address offset for e.g. higher half */
SECTIONS
{
/* Load kernel at virtual memory address */
. = KERNEL_VMA;
/* define variable for kernels start address */
kernel_start_address = .;
/* code section and read only data (e.g. strings within c-part)*/
.text : AT(ADDR(.text) - KERNEL_VMA_TO_LMA)
{
*(.text)
*(.rodata)
}
/* Initialised data - should be page aligned */
.data ALIGN(0x1000) : AT(ADDR(.data) - KERNEL_VMA_TO_LMA)
{
*(.data)
}
/* Uninitialised data */
.bss : AT(ADDR(.bss) - KERNEL_VMA_TO_LMA)
{
_sbss = .;
*(.bss)
*(COMMON)
_ebss = .;
}
/* define variable for kernels end address */
kernel_end_address = .;
}
Gibt es da noch etwaige Unstimmigkeiten oder Fehler? Irgendwelche Dinge, die ich nicht berücksichtigt habe?Eines habe ich jetzt aber noch...
In manchen Tutorials ist rodata als extra Sektion angegeben. Dient dies einfach nur der Übersicht? Im OSDev-Wiki steht dann, dass rodata nach .text kommt... Was ist da jetzt richtig, bzw. besser, da ja beides richtig zu sein scheint?
Gruß Christian