You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: _posts/2019-04-27-riscv-from-scratch-2.markdown
+2-2Lines changed: 2 additions & 2 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -248,7 +248,7 @@ Using `qemu` and `dtc`, we've successfully discovered where the RAM lives and ho
248
248
249
249
Well, since the default `crt0` isn't doing what we need it to, we have one obvious choice: writing our own, and then linking it with the object file created from compiling our simple addition program. Our `crt0` will need to know where the top of the stack starts in order to properly initialize it. We could hardcode this value to `0x80000000` directly in our `crt0`, but that isn't a very maintainable solution. What happens when we want to use a different `qemu`-lated CPU, such as the `sifive_e`, that has different memory properties?
250
250
251
-
Fortunately for us, we are far from the first to ask this question, and a good solution exists. GNU's linking program, `ld`, [provides a way for us to define a symbol](https://access.redhat.com/documentation/en-US/Red_Hat_Enterprise_Linux/4/html/Using_ld_the_GNU_Linker/assignments.html) which would be accessible from our `crt0`. We can use this, among other functions provided by `ld`, to create a `__stack_top` symbol definition that is reasonably flexible across multiple different CPUs.
251
+
Fortunately for us, we are far from the first to ask this question, and a good solution exists. GNU's linking program, `ld`, [provides a way for us to define a symbol](https://web.archive.org/web/20190525173911/https://access.redhat.com/documentation/en-US/Red_Hat_Enterprise_Linux/4/html/Using_ld_the_GNU_Linker/assignments.html) which would be accessible from our `crt0`. We can use this, among other functions provided by `ld`, to create a `__stack_top` symbol definition that is reasonably flexible across multiple different CPUs.
252
252
253
253
Rather than writing our own linker file from scratch, it is going to make more sense to take the default linker script that `ld` uses and modify it slightly to expose any additional symbols we want. What is a linker script, you might be wondering? [This snippet summarizes it well:](http://www.scoberlin.de/content/media/http/informatik/gcc_docs/ld_3.html)
254
254
@@ -317,7 +317,7 @@ SECTIONS
317
317
.note.gnu.build-id : { *(.note.gnu.build-id) }
318
318
{% endhighlight %}
319
319
320
-
As you can see, we use the [PROVIDE command](https://access.redhat.com/documentation/en-US/Red_Hat_Enterprise_Linux/4/html/Using_ld_the_GNU_Linker/assignments.html#PROVIDE) to define a symbol called `__stack_top`. `__stack_top` will be accessible from any program linked with this script (assuming the program itself does not also define something named `__stack_top`). We set the value of `__stack_top` to be `ORIGIN(RAM)`, which we know is `0x80000000`, plus `LENGTH(RAM)`, which we know is 128 megabytes (`0x8000000` bytes). This means our `__stack_top` is set to `0x88000000`.
320
+
As you can see, we use the [PROVIDE command](https://web.archive.org/web/20190525173911/https://access.redhat.com/documentation/en-US/Red_Hat_Enterprise_Linux/4/html/Using_ld_the_GNU_Linker/assignments.html#PROVIDE) to define a symbol called `__stack_top`. `__stack_top` will be accessible from any program linked with this script (assuming the program itself does not also define something named `__stack_top`). We set the value of `__stack_top` to be `ORIGIN(RAM)`, which we know is `0x80000000`, plus `LENGTH(RAM)`, which we know is 128 megabytes (`0x8000000` bytes). This means our `__stack_top` is set to `0x88000000`.
0 commit comments