Skip to content

Commit dbb8190

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 dbb8190

File tree

1 file changed

+19
-8
lines changed

1 file changed

+19
-8
lines changed

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

Lines changed: 19 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -17,15 +17,25 @@ 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_length = 0);
33+
PROVIDE(__linked_file_end = __user_ram_end);
34+
PROVIDE(__linked_file_start = __linked_file_end - __linked_file_length);
2535

2636
PROVIDE(__stack_length = 4M);
27-
PROVIDE(__heap_end = __user_ram_end - __stack_length);
28-
PROVIDE(__user_length = __heap_start - __user_ram_start);
37+
PROVIDE(__stack_top = __linked_file_start);
38+
PROVIDE(__stack_bottom = __linked_file_start - __stack_length);
2939

3040
MEMORY {
3141
USER_RAM (RWX) : ORIGIN = __user_ram_start, LENGTH = __user_ram_length
@@ -44,7 +54,7 @@ SECTIONS {
4454
LONG(__vcodesig_options)
4555

4656
FILL(0)
47-
. = __user_ram_start + __code_signature_length;
57+
. = __user_ram_start + 0x20;
4858
} > USER_RAM
4959

5060
/*
@@ -125,7 +135,8 @@ SECTIONS {
125135
*/
126136
.heap (NOLOAD) : {
127137
__heap_start = .;
128-
. = __heap_end;
138+
. = __stack_bottom;
139+
__heap_end = .;
129140
} > USER_RAM
130141

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

0 commit comments

Comments
 (0)