Why disable mmu
And, is the value the last field, right? This is highly likely to explode; you can't just "turn off" the MMU in the middle of operation as all of your physical to virtual translations and the caches will disappear. Why not just map the memory page containing the registers into the virtual memory view the correct solution. I don't want to explode my board I want to put them in the sources of my kernel or my bootloader.
But i am not sure i understand your second sentence, you mean using mmap to write these registers? Because it's what i have done and it didn't worked for registers which are not writeable. The mmap call is a user-space call which relies on the underlying kernel-space device node which is handling the mmap i. Lets say for example you have some code that polls the uart status register waiting for a character in the rx buffer. If that first read shows there is no character, that status goes in the cache, you will remain in the loop forever since you will never get to talk to the status register again you will simply get the cached copy of the register.
When the mmu is on, you use the mmu to mark the address space used by that peripheral as non- data -cacheable, and you dont have this problem. With the mmu off you need the data cache off for arm systems. Leaving the I-cache on is okay because instruction fetches only read instructions Well for a bare metal application that is okay, it helps for example if you are using a flash that has a potential for read disturb spi or i2c flashes.
The problem is this application is a bootloader, so you must take some extra care. For example your bootloader has some code at address 0x that it runs through at least once, then you choose to use it as a bootloader, the bootloader might be at say address 0x allowing you to load a new program at 0x, this load uses data accesses so it does not go through the instruction cache.
So there is a potential that the instruction cache has some or all of the code from the last time you were in the 0x area, and when you branch to the bootloaded code at 0x you will get either the old program from cache or a nasty mixture of old program and new program for the parts that are cached and not cached. So if your bootloader allows for the i-cache to be on, you need to invalidate the cache before branching to bootloaded code. Lastly, if you or anyone using this bootloader wants to use jtag, then you have that same problem but worse, data cycles that do not go through the i-cache are used to write the new program to ram, when you tell the jtag debugger to then run the new program you will get 1 only the new program, 2 a mixture of the new program and old program fragments from cache 3 the old program from cache.
So d-cache is bad without an mmu because of things that are not in ram, peripherals, etc. The i-cache is a use at your own risk kind of thing which you can mitigate except for the times that jtag is used for debugging. If you have concerns or have confirmed read-disturb in your external flash, then I recommend turn on the i-cache, use a tight loop to copy your application to ram, branch to the ram copy and run there, turn off the i-cache or use at your own risk and dont touch the flash again, certainly not heavy read accesses to small areas.
A tight uart polling loop like you might have for a command line parser, is a really good place to get hit with read-disturb. Some BIOS implementations go into protected mode before entering the bootloader.
Most don't. It is possible that BIOS switches to protected mode for a short period and switches back before going to the bootloader, which would allow it to use some of the benefits of protected mode such as 32 bit being the default address size. The reason that the bootloader should be in real mode is that most BIOS functions only work in real mode, so you need to be in real mode to use them.
Any variables in foo and bar , are stored here, on the stack or in available registers. The fp keeps track of the variables from function to function. It is a frame or picture window on the stack for that function. The ABI defines a layout of this frame. Typically the lr and other registers are saved here behind the scenes by the compiler as well as the previous value of fp. This makes a linked list of stack frames and if you want you can trace it all the way back to main.
The root is fp , which points to one stack frame like a struct with one variable in the struct being the previous fp. You can go along the list until the final fp which is normally NULL. So the sp is where the stack is and the fp is where the stack was, a lot like the pc and lr. Each old lr link register is stored in the old fp frame pointer.
The sp and fp are a data aspect of functions. Your point B is the active pc and sp. Point A is actually the fp and lr ; unless you call yet another function and then the compiler might get ready to setup the fp to point to the data in B. Following is some ARM assembler that might demonstrate how this all works. This will be different depending on how the compiler optimizes, but it should give an idea,.
These concepts are generic to all CPUs and compiled languages, although the details can vary. The use of the link register , frame pointer are part of the function prologue and epilogue, and if you understood everything, you know how a stack overflow works on an ARM.
See also: ARM calling convention. An ABI may use other values, but the above are typical for most setups. The indexes above are for 32 bit values as all ARM registers are 32 bits. If you are byte-centric, multiply by four. The frame is also aligned to at least four bytes. Addendum: This is not an error in the assembler; it is normal. An explanation is in the ARM generated prologs question. The MMU has settings to determine which memory regions are cacheable or not.
If you do not have the mmu on but you have the data cache on if possible then you cannot safely talk to peripherals. Lets say for example you have some code that polls the uart status register waiting for a character in the rx buffer.
0コメント