Questions in 2. stage bootloader code
Questions in 2. stage bootloader code
Hello guys,
I want to understand the whole startup process. Therefore I checked the bootloader_init function. There I have 2 questions, maybe someone can help me.
1. In function cpu_init_memctl there is the function WSR(MEMCTL, memctl);
Can someone explain this in more detail?
2. In function cpu_configure_region_protection there will be protected some regions.
Can someone explain this in more detail? Why these pages has to be protected?
Thank you.
I want to understand the whole startup process. Therefore I checked the bootloader_init function. There I have 2 questions, maybe someone can help me.
1. In function cpu_init_memctl there is the function WSR(MEMCTL, memctl);
Can someone explain this in more detail?
2. In function cpu_configure_region_protection there will be protected some regions.
Can someone explain this in more detail? Why these pages has to be protected?
Thank you.
Re: Questions in 2. stage bootloader code
Hi Alex,
Thanks for the very clear questions.
https://github.com/espressif/esp-idf/co ... c91289aa17
The zero-cost loop feature is a special set of instructions allowing loops to be implemented very efficiently. Unfortunately gcc doesn't generate them automatically at the moment, so the only places these are used are some custom optimized libc functions and the esp-dsp library.
Thanks for the very clear questions.
We set this register to disable the "zero cost loop buffe" and work around an CPU erratum in the zero-cost loop implementation, it can sometimes trigger an IllegalInstructionException otherwise. The commit that added this workaround is here and has a short description:
https://github.com/espressif/esp-idf/co ... c91289aa17
The zero-cost loop feature is a special set of instructions allowing loops to be implemented very efficiently. Unfortunately gcc doesn't generate them automatically at the moment, so the only places these are used are some custom optimized libc functions and the esp-dsp library.
This is done to ensure the CPU throws an illegal access exception if you try to do something like dereference a null pointer (i.e. read/write an address close to 0x00000000). The resolution of the CPU access protection feature is 512MB pages, so on startup we mark any 512MB page of address space with nothing mapped in it as illegal to access.
Re: Questions in 2. stage bootloader code
Thank you.
Regarding 1. question:
How can I raise this issue on purpose? So there is an error in gcc, am I right?
2. question:
Are there any detailed information why these addresses will be protected / cached?
Greetings
Regarding 1. question:
How can I raise this issue on purpose? So there is an error in gcc, am I right?
2. question:
Are there any detailed information why these addresses will be protected / cached?
Greetings
-
- Posts: 9764
- Joined: Thu Nov 26, 2015 4:08 am
Re: Questions in 2. stage bootloader code
The error is not in GCC - it's a design error in the Xtensa core hardware.
What detailed info do you need? If this address is not set to non-accessible, something like2. question:
Are there any detailed information why these addresses will be protected / cached?
Code: Select all
int *p=NULL;
printf("Value is %d\n", *p);
Re: Questions in 2. stage bootloader code
Thank you. That helped me a lot.
I set the itlb / dtlb to "0x0" after that I am allowed to write / read in this pages...
The question about the "detailed information" was: Why exactly these pages: 0x00000000, 0x80000000, ...
I think there should some information in xtensa datasheet and I will search for this, but maybe you can explain this better?
Kind Regards
I set the itlb / dtlb to "0x0" after that I am allowed to write / read in this pages...
The question about the "detailed information" was: Why exactly these pages: 0x00000000, 0x80000000, ...
I think there should some information in xtensa datasheet and I will search for this, but maybe you can explain this better?
Kind Regards
Re: Questions in 2. stage bootloader code
Hi Alex,
(Note the ESP32 has nothing like the MMU in a full scale processor like an x86, so there's no way to change the virtual address mapping of resources or RAM at runtime.)
Something has to tell the CPU "accessing these address ranges is an error", or it will happily try and read to write them. If you don't flag these regions as an error then writes will most likely be discarded (they may actually stall the CPU), and reads will most likely return junk values. As Sprite says, usually this is not something a programmer wants - you want the CPU to fault if it accesses some obviously rubbish address.
In a lot of microcontrollers the firmware doesn't need to set these faulting addresses because they're set by the mask ROM or hard-wired into the CPU, but in the case of ESP32 it's firmware configured so we set it on boot.
Because there's nothing there. If you look in the "System and Memory" chapter of the ESP32 Technical Reference Manual then you can see all of the addresses where the CPU can access resources inside the chip. There are no resources mapped in those regions.
(Note the ESP32 has nothing like the MMU in a full scale processor like an x86, so there's no way to change the virtual address mapping of resources or RAM at runtime.)
Something has to tell the CPU "accessing these address ranges is an error", or it will happily try and read to write them. If you don't flag these regions as an error then writes will most likely be discarded (they may actually stall the CPU), and reads will most likely return junk values. As Sprite says, usually this is not something a programmer wants - you want the CPU to fault if it accesses some obviously rubbish address.
In a lot of microcontrollers the firmware doesn't need to set these faulting addresses because they're set by the mask ROM or hard-wired into the CPU, but in the case of ESP32 it's firmware configured so we set it on boot.
Re: Questions in 2. stage bootloader code
Thank you very much.
So 0x10000000, 0x60000000, 0x70000000, 0x90000000, 0xb0000000, 0xd0000000, 0xf0000000 will be used for internal things (wifi, ...) Am I right?
At this matter I try to understand the external memory and read the documentation (chapter 2.3.3 External memory, page 30, https://www.espressif.com/sites/default ... ual_en.pdf)
In table 6 I can see there are 2 bus types (data, instruction):
Why the Instruction addressing has the size of 11512kB. In my mind the whole flash will be used for instructions. The actual code of app_main will be stored in this part --> to access the code of app_main I need the addresses 0x400C_2000 ... 0x40BF_FFFF. Am I right?
When do I need the data part: external SRAM / external Flash? Do you have any valued example therefore?
Thanks in advance.
Greetings
So 0x10000000, 0x60000000, 0x70000000, 0x90000000, 0xb0000000, 0xd0000000, 0xf0000000 will be used for internal things (wifi, ...) Am I right?
At this matter I try to understand the external memory and read the documentation (chapter 2.3.3 External memory, page 30, https://www.espressif.com/sites/default ... ual_en.pdf)
In table 6 I can see there are 2 bus types (data, instruction):
Why the Instruction addressing has the size of 11512kB. In my mind the whole flash will be used for instructions. The actual code of app_main will be stored in this part --> to access the code of app_main I need the addresses 0x400C_2000 ... 0x40BF_FFFF. Am I right?
When do I need the data part: external SRAM / external Flash? Do you have any valued example therefore?
Thanks in advance.
Greetings
Re: Questions in 2. stage bootloader code
Page size is 512MB which is 0x20000000 so the region at 0x60000000-0x7FFFFFFF is the only unprotected range in that list.
There are some registers in the range 0x60000000 that are not documented in the TRM, if you dig around there is a bit of unofficial information online about them (nothing that interesting, some registers are mapped to both this bus and the main peripheral register bus in ESP32 so we document and recommend using the latter bus).
In ESP-IDF, rodata (strings, other constant data) is mapped from flash to the data memory space by default. As instruction memory space has limitations on aligned access. Some more info is here.AlexESP32 wrote: ↑Wed Jan 20, 2021 6:51 pmAt this matter I try to understand the external memory and read the documentation (chapter 2.3.3 External memory, page 30, https://www.espressif.com/sites/default ... ual_en.pdf)
In table 6 I can see there are 2 bus types (data, instruction):
Why the Instruction addressing has the size of 11512kB. In my mind the whole flash will be used for instructions. The actual code of app_main will be stored in this part --> to access the code of app_main I need the addresses 0x400C_2000 ... 0x40BF_FFFF. Am I right?
When do I need the data part: external SRAM / external Flash? Do you have any valued example therefore?
The external SRAM feature lets you add up to 4MB of RAM to the ESP32. More info here.
Re: Questions in 2. stage bootloader code
Thank you. One more last question to really understand this topic:
"Instruction addressing has the size of 11512kB" means:
If I have an ESP32 with 16MB external flash I only can use maximum 11,512MB of them? The rest I can use for other things, for example for RAM.
Am I right?
Greetings
"Instruction addressing has the size of 11512kB" means:
If I have an ESP32 with 16MB external flash I only can use maximum 11,512MB of them? The rest I can use for other things, for example for RAM.
Am I right?
Greetings
Re: Questions in 2. stage bootloader code
Not exactly, see the entries in Table 6 of the TRM memory chapter. The 11,512kB is for flash mappings only (not RAM), and instruction space only (meaning you can't access this as data, it's only intended for use mapping read-only executable code from flash.)
Who is online
Users browsing this forum: No registered users and 132 guests