[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [Lost] [Patch] kernel2: pmm_init muss Module reservieren
> Am Montag, 9. Juni 2008 22.32:16 schrieb kevin@xxxxxxxxxx:
>> ! kernel2: Initialisierung des physischen Speichers gefixt (Fuer den
>> letzten freien Bereich bis 0xffffffff wurde 0 als Ende zurueckgegeben
>> und
>> die folgenden Reservierungen daher nicht beruecksichtigt)
>
> Ack.
Das ganze war doch nochmal ein Stueck kaputter. Neuer Anlauf:
! kernel2: Initialisierung des physischen Speichers gefixt (Fuer den
letzten freien Bereich bis 0xffffffff wurde 0 als Ende zurueckgegeben und
die folgenden Reservierungen daher nicht beruecksichtigt)
! kernel2: In der Memory Map nicht aufgefuehrte Bereiche sind reserviert,
nicht frei
Index: trunk/src/kernel2/src/mm/phys.c
===================================================================
--- trunk.orig/src/kernel2/src/mm/phys.c
+++ trunk/src/kernel2/src/mm/phys.c
@@ -342,22 +342,21 @@ void pmm_free(paddr_t start, size_t coun
}
-struct reserved_block {
+struct mem_block {
paddr_t start;
paddr_t end;
};
/**
- * @return Beschreibung des reservierten Blocks. Wenn i größer als die
- * Anzahl der reservierten Blocks ist, wird ein Block mit start > end
+ * @return Beschreibung des freien Speicherblocks. Wenn i größer als die
+ * Anzahl der freien Blocks ist, wird ein Block mit start > end
* zurückgegeben.
*/
-static struct reserved_block get_reserved_block
+static struct mem_block get_free_block
(struct multiboot_info* multiboot_info, size_t i)
-{
- struct reserved_block result;
-
-
+{
+ struct mem_block result;
+
// Überprüfung der BIOS-Memory-Map
struct multiboot_mmap* mmap;
uintptr_t mmap_addr = multiboot_info->mi_mmap_addr;
@@ -368,17 +367,41 @@ static struct reserved_block get_reserve
mmap++)
{
// Typ 1 steht für freien Speicher
- if (mmap->mm_type != 1) {
+ if (mmap->mm_type == 1) {
if (i-- == 0) {
result.start = (paddr_t)((uintptr_t) mmap->mm_base_addr);
- result.end = (paddr_t)((uintptr_t) mmap->mm_base_addr
- + (dword) mmap->mm_length);
+ result.end = (paddr_t)((uintptr_t) mmap->mm_base_addr
+ + (dword) mmap->mm_length - 1);
return result;
}
}
}
- // Der Kernel ist auch besetzt
+ result.start = (paddr_t) 0xFFFFFFFF;
+ result.end = (paddr_t) 0;
+
+ return result;
+}
+
+/**
+ * @return Beschreibung des reservierten Blocks. Wenn i größer als die
+ * Anzahl der reservierten Blocks ist, wird ein Block mit start > end
+ * zurückgegeben.
+ */
+static struct mem_block get_reserved_block
+ (struct multiboot_info* multiboot_info, size_t i)
+{
+ struct mem_block result;
+
+ // Die Bitmap ist bereits zugewiesen, wenn diese Funktion aufgerufen wird
+ if (i-- == 0) {
+ result.start = pmm_bitmap;
+ result.end = pmm_bitmap +
+ ((pmm_bitmap_length / 8) * PMM_BITS_PER_ELEMENT);
+ return result;
+ }
+
+ // Der Kernel ist besetzt
if (i-- == 0) {
result.start = kernel_phys_start;
result.end = kernel_phys_end;
@@ -407,7 +430,7 @@ static struct reserved_block get_reserve
result.end = (paddr_t) (uintptr_t) multiboot_module->end;
return result;
}
-
+
// Die Kommandozeile des Moduls
if (multiboot_module->cmdline) {
if (i-- == 0) {
@@ -437,22 +460,43 @@ static paddr_t find_bitmap_mem
(struct multiboot_info* multiboot_info, size_t size)
{
if (multiboot_info->mi_flags & MULTIBOOT_INFO_HAS_MMAP) {
- size_t i = 0;
- struct reserved_block block;
+ size_t i, j;
+ struct mem_block free, reserved;
paddr_t bitmap = 0x0;
- do
+ i = 0;
+ do
{
- block = get_reserved_block(multiboot_info, i++);
- if (block.start > block.end) {
+ // Freien Speicherblock suchen und Bitmap an den Anfang legen
+ free = get_free_block(multiboot_info, i++);
+ if (free.start > free.end) {
panic("Keinen Platz fuer die Speicherbitmap gefunden");
- } else if (block.start > bitmap + size) {
+ }
+ bitmap = free.start;
+
+ // Probieren, ob der Speicherblock nicht doch besetzt ist und
+ // in diesem Fall ein Stueck weitergehen und nochmal von vorne
+ // durchprobieren
+ j = 0;
+ do
+ {
+ reserved = get_reserved_block(multiboot_info, j++);
+ if (!((reserved.start > bitmap + size)
+ || (reserved.end < bitmap)))
+ {
+ j = 0;
+ bitmap = reserved.end;
+ }
+ }
+ while ((bitmap <= free.end) && (reserved.start < reserved.end));
+
+ // Wenn die Bitmap nach Beruecksichtigung aller besetzten Bereiche
+ // immer noch im freien Bereich liegt, dann nehmen wir die Adresse
+ if (bitmap <= free.end) {
return bitmap;
- } else {
- bitmap = block.end;
}
- }
- while (TRUE);
+ }
+ while(TRUE);
} else {
return (paddr_t) 0x1000;
}
@@ -506,26 +550,41 @@ void pmm_init(struct multiboot_info* mul
size_t bitmap_size = required_bitmap_size(multiboot_info);
pmm_bitmap = find_bitmap_mem(multiboot_info, bitmap_size);
pmm_bitmap_length = 8 * bitmap_size / PMM_BITS_PER_ELEMENT;
-
- // Am Anfang ist alles frei
- memset(pmm_bitmap, ~0x0, bitmap_size);
-
- // Zunächst die Bitmap selbst als besetzt markieren...
- phys_mark_page_range_as_used(pmm_bitmap, NUM_PAGES(bitmap_size));
+
+ // Am Anfang ist alles besetzt
+ memset(pmm_bitmap, 0x0, bitmap_size);
// ...anschließend die BIOS-Memory-Map abarbeiten
size_t i = 0;
do
{
- struct reserved_block block = get_reserved_block(multiboot_info, i++);
-
+ struct mem_block block = get_free_block(multiboot_info, i++);
+
+ // Wenn der Start nach dem Ende liegt, ist der Block ungültig
+ // und wir sind fertig
+ if (block.start > block.end) {
+ break;
+ }
+
+ // Reservierten Block als frei markieren
+ phys_mark_page_range_as_free
+ (block.start, NUM_PAGES(block.end - block.start));
+ }
+ while(TRUE);
+
+
+ // ...und dann Kernel usw. wieder reservieren
+ i = 0;
+ do
+ {
+ struct mem_block block = get_reserved_block(multiboot_info, i++);
+
// Wenn der Start nach dem Ende liegt, ist der Block ungültig
// und wir sind fertig
if (block.start > block.end) {
break;
}
-
-
+
// Reservierten Block als besetzt markieren
phys_mark_page_range_as_used
(block.start, NUM_PAGES(block.end - block.start));