memory - ARM bare-metal with MMU: successive reads yield different values -


context (probably not needed):

as learning exercise, i'm trying implement mini "os" raspberry pi.

i'm implementing dumb memory management system. have mmu enabled, , i'm in process of getting usable kmalloc.

it can allocate chunks of memory pre-existing little kernel heap, mapped after code , data segments. i'm trying grow needed mapping more pages. must able produce physically contiguous chunks.

the code hosted @ github, there's branch dedicated question debug code. note it's not example of well-organized, well-commented nor clever code. :)

actual question:

while trying debug data abort, found strange.

this piece of code kmalloc:

next->prev_size = chunk->size; next->size = -1;  term_printf(term, "a chunk->next_free = 0x%x\n", chunk->next_free); term_printf(term, "b chunk->next_free = 0x%x\n", chunk->next_free);  *prev_list = next; next->next_free = chunk->next_free;  term_printf(term, "next_free = 0x%x, chunk 0x%x\n", next->next_free, chunk->next_free); term_printf(term, "next_free = 0x%x, chunk 0x%x\n", next->next_free, chunk->next_free); 

i run 3 times. here results:

# 1st chunk->next_free = 0x0 b chunk->next_free = 0x0 next_free = 0x0, chunk 0x0 next_free = 0x0, chunk 0x0  # 2nd chunk->next_free = 0xffffffff b chunk->next_free = 0x0 next_free = 0x0, chunk 0xffffffff next_free = 0x0, chunk 0x0  # 3rd chunk->next_free = 0xffffffff b chunk->next_free = 0xffffffff next_free = 0xffffffff, chunk 0xffffffff next_free = 0xffffffff, chunk 0xffffffff 

the first , third iterations normal (though next_free supposed have value 0, data abort occurs because it's got 0xffffffff). code doing during second? o_o kind of black sorcery can make printf output 2 different values chunk->next_free when read 4 times in row? o_o

the data aligned, pages cacheable , non-bufferable (making them non-cacheable doesn't help), , same result whether compiler optimizations turned on or off. tried throwing data memory barrier in there indeed nothing. checked assembly produced, looks ok.

i thought caused corrupted tlbs. i'm issuing "invalidate unified single entry" (mcr p15, 0, %[addr], c8, c7, 1) after each new page mapping. enough?

i tried debugging qemu gets data abort earlier when setting bitmap of used physical pages, though part works fine on pi.

i'm looking clues can cause behavior. if need more context please ask, though code moment rapidly changing , messy lots of printf.


eta: disassembly -o0 first 2 printf:

c00025e4:       e51b3018        ldr     r3, [fp, #-24] c00025e8:       e5933008        ldr     r3, [r3, #8] c00025ec:       e59b0004        ldr     r0, [fp, #4] c00025f0:       e59f10a0        ldr     r1, [pc, #160]  ; c0002698 <kmalloc_wilderness+0x2c0> c00025f4:       e1a02003        mov     r2, r3 c00025f8:       eb000238        bl      c0002ee0 <term_printf> c00025fc:       e51b3018        ldr     r3, [fp, #-24] c0002600:       e5933008        ldr     r3, [r3, #8] c0002604:       e59b0004        ldr     r0, [fp, #4] c0002608:       e59f1088        ldr     r1, [pc, #140]  ; c000269c <kmalloc_wilderness+0x2c4> c000260c:       e1a02003        mov     r2, r3 c0002610:       eb000232        bl      c0002ee0 <term_printf> 

so puts address of chunk r3, perform ldr next_free. again before second prinf. there's 1 core, dma not running, there's nothing changing value in memory between calls.

with -o2:

c0001c38:       e1a00006        mov     r0, r6 c0001c3c:       e59f10d8        ldr     r1, [pc, #216]  ; c0001d1c <kmalloc_wilderness+0x1b8> c0001c40:       e5942008        ldr     r2, [r4, #8] c0001c44:       eb000278        bl      c000262c <term_printf> c0001c48:       e1a00006        mov     r0, r6 c0001c4c:       e59f10cc        ldr     r1, [pc, #204]  ; c0001d20 <kmalloc_wilderness+0x1bc> c0001c50:       e5942008        ldr     r2, [r4, #8] c0001c54:       eb000274        bl      c000262c <term_printf> 

so still fetches value ldr. that's why same thing both optimization levels.


new edit: added more printfs, , seems singularity happens @ point:

next->size = -1; 

after line, chunk->next_free turns heisenberg's cat. before, reads 0.

the structure defined such:

struct kheap_chunk {     size_t prev_size;     size_t size; // -1 wilderness chunk, bit 0 high if free     struct kheap_chunk *next_free; }; 

chunk , next don't overlap.

if move "singularity line" below next->next_free = chunk->next_free, stops alternating between 2 values, it's still weird: chunk->next_free 0 before *prev_list = next, 0xffffffff after that. next->next_free still set 0.


Comments

Popular posts from this blog

basic authentication with http post params android -

vb.net - Virtual Keyboard commands -

css - Firefox for ubuntu renders wrong colors -