On 30/11/2023 20:04, Emile Michel Hobo van Oranje via Gcc-help wrote:
Dear developers:
I'm trying to install a new bootloader on a computer. My angle was to write it to the zero address of the CMOS as follows, but the result is a SEGMENTATION FAULT. How do I write to the zero address using C?
There are two possible reasons for your problem.
The C standard says that trying to dereference a null pointer is
undefined behaviour. Basically, if you are trying to write to "*mem"
when it knows "mem" will be 0, your program is meaningless and the
compiler can use the fact that you apparently don't care what happens if
"mem" is 0 in order to generate more optimal code.
Some compilers (typically for embedded systems) are build to treat
dereferencing 0 as normal pointer access, because it can be useful in
such systems. Compilers for "big" hosted systems treat it as undefined
behaviour, and can do weird things if the result is more efficient code.
If you really want to write to address 0, the solution is to use
"volatile" - define "mem" as "volatile unsigned char * mem;". The
compiler will treat all volatile accesses as literally as it can.
The other possibility - more likely here - is that you are trying to run
the program when the OS has set up the memory page at address 0 as
unwritable (and possibly also unreadable). How you should arrange to
get write access to address 0 is a matter for low-level information on
your OS - it's nothing to do with C, and certainly nothing gcc-specific,
so you'll want to look elsewhere for that kind of information.
Although you have not specified what kind of computer you are talking
about, copying a file to address 0 is almost certainly completely the
wrong way to go about installing a new bootloader. You would want to
read about and study UEFI, grub, uboot, or other related topics
depending on what you mean by "a computer". Good luck - it is /not/ a
small topic!
-- CODE --
#include <stdio.h>
int main (int argc, char* argv[]) {
unsigned char* mem;
FILE* load;
mem = 0;
load = fopen("bootloader", "r");
while (!feof(load)) {
*mem = getc(load);
mem++;
}
fclose(load);
}
-- END OF CODE --
It should just do this, but it doesn't. What stands in my way? C is a low level programming language that's advertised as being suitable for system programming, which would include a bootloader. I did make sure to include the bootloader in the same directory as the executable.
Kind regards,
Emile Michel Hobo van Oranje (recognized by the Supreme Court of the Netherlands)