"It starts at 0 and executes instructions" is a funny, but mostly true way to express this. Some people are shocked that no magic happens before the instructions start.
Sort of. It's actually fairly common on larger cores (and particular, larger SoCs) for there to exist magic that happens before architectural reset vectors.
> By pre-boot code, I’m not talking about the little ROM blob that gets run after reset to set up your peripherals so you can pull your bootloader from SD card or SSD. That part was a no-brainer to share. I’m talking about the code that gets run before the architecturally guaranteed “reset vector”. A number of software developers (and alarmingly, some security experts) believe that the life of a CPU begins at the reset vector. In fact, there’s often a significant body of code that gets executed on a CPU to set things up to meet the architectural guarantees of a hard reset – bringing all the registers to their reset state, tuning clock generators, gating peripherals, and so forth. Critically, chip makers heavily rely upon this pre-boot code to also patch all kinds of embarrassing silicon bugs, and to enforce binning rules.
Something fun mentioned in a comment on that article, this the majority of this "pre-boot" code is actually FOSS in POWER9. There are a set of "auxiliary processors" called "PPE"s, among which there is one, the "SBE", or "self boot engine", which is a very small and simple PowerPC core that IPLs the big POWER9 cores [0]. These big processors with tons of cache and interconnects need a lot of help to get to executing PC 0x00.
I suspect that almost all the big "application processors" from Intel and AMD, and the exotic ARM/SPARC server chips, have equivalent embedded ICs to jump-start the "big cores".
In many modern CPUs, it's an auxiliary processor that "starts at 0" (within its dedicated ROM) and then eventually turns on the main CPUs. In a modern Intel core, I think that CPU is actually the one in the secure enclave, which also happens to do things like DRAM training...
In a microcontroller, the clock generators and the peripherals are often set up by the main core just after boot, and are under user control - the chip's reset network (literally just a wire) handles bringing things into a known state before boot.
Yeah, I was actually thinking the basic behavior that OP mentioned could be quite rare these days. Last project I worked on there was a whole startup procedure. You could even use a special bootloader that they kept in ROM, if you wanted... It did a number of other things that were generally not visible to the developer, but probably required some CPU interaction.
This is pretty old. There's quite a lot that happens before instructions start on modern CPUs.
Just one small example: CPUs have many small SRAM arrays for micro-architecture features like branch predictors. Some of these need to be initialized after reset by a state machine that takes many cycles.
I have even heard of a large chip that pushes initialization vectors through the scan chains so that all flops begin in an initial state, without requiring a reset network.
It's easy to overlook for those who program mostly on higher level systems. There was a recent HN thread that I think pointed to this article on what happens before main() in C programs:
On microcontrollers, there are often some preliminaries that are programmed into nonvolatile settings of the hardware, such as the type of clock oscillator. On a microprocessor like the Z80, your circuit was supposed to ensure that things like the clock oscillator and power supplies were stable before releasing the RESET pin.
If older CPUs have no magic, what is the 6502 doing here (https://youtu.be/yl8vPW5hydQ?t=706) that causes it to put eb60 → ffff → eb60 → 01f7 → 01f6 → 01f5 on the address bus, before it actually reads from memory?
https://www.pagetable.com/?p=410 may go some way toward explaining this. The behavior is slightly different than in the video. I believe this is because the video is using a 65C02 instead of the original NMOS 6502 and the implementation is slightly different.
Brilliant; makes perfect sense of the "magic." It'd be interesting to see a compare-and-contrast of the "dump" of a decode ROM of a 65C02 vs the 6502's decode PLA, to see exactly what the 65C02 is doing with those few added cycles in what is presumably its generic BRK implementation.
https://www.bunniestudios.com/blog/?p=5127
> By pre-boot code, I’m not talking about the little ROM blob that gets run after reset to set up your peripherals so you can pull your bootloader from SD card or SSD. That part was a no-brainer to share. I’m talking about the code that gets run before the architecturally guaranteed “reset vector”. A number of software developers (and alarmingly, some security experts) believe that the life of a CPU begins at the reset vector. In fact, there’s often a significant body of code that gets executed on a CPU to set things up to meet the architectural guarantees of a hard reset – bringing all the registers to their reset state, tuning clock generators, gating peripherals, and so forth. Critically, chip makers heavily rely upon this pre-boot code to also patch all kinds of embarrassing silicon bugs, and to enforce binning rules.