Skip to content

Commit cd7035a

Browse files
committed
Add VEXos "linked files" support to armv7a-vex-v5
Third-party programs running on the VEX V5 platform need a linker script to ensure code and data are always placed in the allowed range `0x3800000-0x8000000` which is read/write/execute. However, users can also configure the operating system to preload a separate file at any location between these two addresses before the program starts (as a sort of basic linking system). Programs have to know about this at compile time - in the linker script - to avoid placing data in a spot that overlaps where the file will be loaded. This is a very popular feature with existing V5 runtimes because it can be used to modify a program's behavior without re-uploading the entire binary to the robot controller. Also, while VEXos's user-exposed file system APIs may only read data from an external SD card, linked files have the advantage of being able to load data directly from the device's onboard storage. This PR adds the `__linked_file_start` symbol to the existing VEX V5 linker script which can be used to shrink the stack and heap so that they do not overlap with the memory region containing a linked file. With these changes, a developer targeting VEX V5 might add a second linker script to their project by specifying `-Clink-arg=-Tcustom.ld` and creating the file `custom.ld` to configure their custom memory layout: ```ld /* Reserve 10MiB for a linked file. */ /* (0x7600000-0x8000000) */ __linked_file_start = __linked_file_end - 10M; /* Optional: specify one or more sections that */ /* represent the developer's custom format. */ SECTIONS { .linked_file_metadata (NOLOAD) : { __linked_file_metadata_start = . . += 1M; __linked_file_metadata_end = . } .linked_file_data (NOLOAD) : { __linked_file_data_start = . . += 9M; __linked_file_data_end = . } } INSERT AFTER .stack; ``` Then, using an external tool like the `vex-v5-serial` crate, they would configure the metadata of their uploaded program to specify the path of their linked file and the address where it should be loaded into memory (in this example, 0x7600000).
1 parent ca77504 commit cd7035a

File tree

1 file changed

+18
-8
lines changed

1 file changed

+18
-8
lines changed

compiler/rustc_target/src/spec/targets/armv7a_vex_v5_linker_script.ld

Lines changed: 18 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -17,15 +17,24 @@ PROVIDE(__vcodesig_type = 0); /* V5_SIG_TYPE_USER */
1717
PROVIDE(__vcodesig_owner = 2); /* V5_SIG_OWNER_PARTNER */
1818
PROVIDE(__vcodesig_options = 0); /* none (0) */
1919

20-
PROVIDE(__user_ram_start = 0x03800000);
21-
PROVIDE(__user_ram_length = 48M);
22-
PROVIDE(__user_ram_end = __user_ram_start + __user_ram_length); /* 0x8000000 */
20+
__user_ram_start = 0x03800000;
21+
__user_ram_end = 0x08000000;
22+
/* (0x48 =) 72 MiB length */
23+
__user_ram_length = __user_ram_start - __user_ram_end;
2324

24-
PROVIDE(__code_signature_length = 0x20);
25+
/*
26+
* VEXos provides a method for pre-loading a "linked file" at a specified
27+
* address in User RAM, conventionally near the end, after the primary
28+
* program binary. We need to be sure not to place any data in that location,
29+
* so we allow the user of this linker script to inform the start address of
30+
* this blob.
31+
*/
32+
PROVIDE(__linked_file_start = __user_ram_end);
33+
PROVIDE(__linked_file_end = __user_ram_end);
2534

2635
PROVIDE(__stack_length = 4M);
27-
PROVIDE(__heap_end = __user_ram_end - __stack_length);
28-
PROVIDE(__user_length = __heap_start - __user_ram_start);
36+
PROVIDE(__stack_top = __linked_file_start);
37+
PROVIDE(__stack_bottom = __linked_file_start - __stack_length);
2938

3039
MEMORY {
3140
USER_RAM (RWX) : ORIGIN = __user_ram_start, LENGTH = __user_ram_length
@@ -44,7 +53,7 @@ SECTIONS {
4453
LONG(__vcodesig_options)
4554

4655
FILL(0)
47-
. = __user_ram_start + __code_signature_length;
56+
. = __user_ram_start + 0x20;
4857
} > USER_RAM
4958

5059
/*
@@ -125,7 +134,8 @@ SECTIONS {
125134
*/
126135
.heap (NOLOAD) : {
127136
__heap_start = .;
128-
. = __heap_end;
137+
. = __stack_bottom;
138+
__heap_end = .;
129139
} > USER_RAM
130140

131141
.stack (NOLOAD) : ALIGN(8) {

0 commit comments

Comments
 (0)