Hallo zusammen,
ich stosse momentan auf ein komisches Problem.
Bei Aufrufen von Funktionen veraendert der Kernel den Stack nicht.
Also mal ein wenig genauer:
Eine meiner Funktionen ruft eine andere auf und setzt den Stack richtig (Parameteruebergabe korrekt).
Nachdem die Funktion durchgelaufen ist, kehrt der Code zurueck und zeigt mir im GDB die Parameter der aufrufenden Funktion an.
Dabei faellt mir auf, dass der erste Parameter (der oberste auf dem Stack) der Ruecksprungadresse der aufgerufenen Funktion entspricht.
Woran liegt das?
Ich habe keine plausible Erklaerung dafuer, da der Code auch im Assembler nicht schlecht aussieht (call, ret).
Kann es sein, dass da QEmu was falsch macht und vergisst das Register zu veraendern?
Das kann ich aber fast nicht glauben, da ich auch schon ein Linux in QEmu gestartet habe und das funktioniert.
Gruss,
rizor
Edit:
Der erste Aufruf der Funktion geht aber gut und der Code laeuft ordentlich durch.
Hier mal der betroffene C-Code:
/*
* this function sets the flags of one entry correctly
*/
static inline void __boot mmu_set_flags(vmm_space_p entry, char rw, char big) {
entry->present = 0x1;
entry->no_tlb_flush = 0x1;
if (rw)
entry->writable = 0x1;
if (big)
entry->big_page = 0x1;
}
/*
* this function maps physical memory, while paging is inactive
*/
void __boot mmu_map_offline(vmm_space_p space, void* vmem,
void* pmem, size_t size, char rw) {
vmm_space_p l1_tbl;
uint32_t mapped;
size_t alloc;
void* frame;
int l2, l1;
while (size) {
l2 = MMU_L2_INDEX(vmem);
if (!space[l2].present &&
size >= MMU_PAGE_SIZE_BIG && pse_feature) {
space[l2].frame = (uint32_t)pmem;
mmu_set_flags(&space[l2], rw, 1);
mapped = MMU_PAGE_SIZE_BIG;
}
else {
l1 = MMU_L1_INDEX(vmem);
//generate a l1 table
if (!space[l2].present) {
alloc = 0x1000;
frame = boot_malloc(&alloc);
if (!alloc) {
//TODO call panic
while (1);
}
boot_memset(frame, 0x0, 0x1000);
space[l2].frame = (uint32_t)frame;
mmu_set_flags(&space[l2], 1, 0);
}
l1_tbl = (vmm_space_p)((uint32_t)space[l2].frame);
l1_tbl[l1].frame = (uint32_t)pmem;
mmu_set_flags(&l1_tbl[l1], rw, 0);
mapped = MMU_PAGE_SIZE_NORM;
}
vmem += mapped;
pmem += mapped;
size -= mapped;
}
}
Die bearbeiteten Strukturen wurden wie folgt definiert:
struct l2_entry {
uint32_t present : 1;
uint32_t writable : 1;
uint32_t userspace : 1;
uint32_t write_through : 1;
uint32_t no_cache : 1;
uint32_t dirty : 1;
uint32_t dirty_page : 1;
uint32_t big_page : 1;
uint32_t no_tlb_flush : 1;
uint32_t free : 3;
uint32_t frame: 20;
} packed;
struct l1_entry {
uint32_t present : 1;
uint32_t writable : 1;
uint32_t userspace : 1;
uint32_t write_through : 1;
uint32_t no_cache : 1;
uint32_t dirty : 1;
uint32_t dirty_page : 1;
uint32_t zero : 1;
uint32_t no_tlb_flush : 1;
uint32_t free : 3;
uint32_t frame: 20;
} packed;