Skip to content

Commit 3c13ca0

Browse files
committed
Remove pico_rand and use boot random instead
Rejig everything to fit into scratch, so full 512k of SRAM is available for the user
1 parent 4b3378b commit 3c13ca0

File tree

4 files changed

+272
-22
lines changed

4 files changed

+272
-22
lines changed

enc_bootloader/CMakeLists.txt

Lines changed: 3 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -35,13 +35,13 @@ if (NOT USE_PRECOMPILED)
3535

3636
target_link_libraries(enc_bootloader
3737
pico_stdlib
38-
pico_rand
3938
)
4039

4140
# use stack guards, as AES variables are written near the stack
4241
target_compile_definitions(enc_bootloader PRIVATE
4342
PICO_USE_STACK_GUARDS=1
4443
PICO_STACK_SIZE=0x200
44+
PICO_NO_PROGRAM_INFO=1
4545
# No heap is used
4646
PICO_HEAP_SIZE=0
4747
# These inits are not required
@@ -51,17 +51,8 @@ if (NOT USE_PRECOMPILED)
5151
pico_minimize_runtime(enc_bootloader)
5252

5353
pico_set_binary_type(enc_bootloader no_flash)
54-
set(USE_USB_DPRAM FALSE)
55-
# create linker script to run from 0x20070000
56-
file(READ ${PICO_LINKER_SCRIPT_PATH}/memmap_no_flash.ld LINKER_SCRIPT)
57-
if (USE_USB_DPRAM)
58-
string(REPLACE "RAM(rwx) : ORIGIN = 0x20000000, LENGTH = 512k" "RAM(rwx) : ORIGIN = 0x2007F000, LENGTH = 4k" LINKER_SCRIPT "${LINKER_SCRIPT}")
59-
target_compile_definitions(enc_bootloader PRIVATE USE_USB_DPRAM=1)
60-
else()
61-
string(REPLACE "RAM(rwx) : ORIGIN = 0x20000000, LENGTH = 512k" "RAM(rwx) : ORIGIN = 0x2007F000, LENGTH = 4k" LINKER_SCRIPT "${LINKER_SCRIPT}")
62-
endif()
63-
file(WRITE ${CMAKE_CURRENT_BINARY_DIR}/memmap_enc_bootloader.ld "${LINKER_SCRIPT}")
64-
pico_set_linker_script(enc_bootloader ${CMAKE_CURRENT_BINARY_DIR}/memmap_enc_bootloader.ld)
54+
set(USE_USB_DPRAM TRUE)
55+
pico_set_linker_script(enc_bootloader ${CMAKE_CURRENT_LIST_DIR}/memmap_enc_bootloader.ld)
6556
pico_add_dis_output(enc_bootloader)
6657
else()
6758
project(enc_bootloader C CXX ASM)

enc_bootloader/enc_bootloader.c

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@
1111
#include "pico/stdlib.h"
1212
#include "boot/picobin.h"
1313
#include "pico/bootrom.h"
14-
#include "pico/rand.h"
1514
#include "hardware/structs/otp.h"
1615
#if USE_USB_DPRAM
1716
#include "hardware/structs/usb_dpram.h"
@@ -34,10 +33,12 @@ extern uint32_t lut_a_map[1];
3433
extern uint32_t lut_b_map[1];
3534
extern uint32_t rstate_sha[4],rstate_lfsr[2];
3635

37-
void __scratch_x("aes") resetrng() {
36+
void resetrng() {
3837
uint32_t f0,f1;
39-
do f0=get_rand_32(); while(f0==0); // make sure we don't initialise the LFSR to zero
40-
f1=get_rand_32();
38+
uint32_t boot_random[4];
39+
rom_get_boot_random(boot_random);
40+
do f0=boot_random[0]; while(f0==0); // make sure we don't initialise the LFSR to zero
41+
f1=boot_random[1];
4142
rstate_sha[0]=f0&0xffffff00; // bottom byte must be zero (or 4) for SHA, representing "out of data"
4243
rstate_sha[1]=f1;
4344
rstate_sha[2]=0x41414141;
@@ -50,15 +51,15 @@ void __scratch_x("aes") resetrng() {
5051
#endif
5152
}
5253

53-
static void __scratch_x("aes") init_lut_map() {
54+
static void init_lut_map() {
5455
int i;
5556
for(i=0;i<256;i++) lut_b[i]=gen_rand_sha()&0xff, lut_a[i]^=lut_b[i];
5657
lut_a_map[0]=0;
5758
lut_b_map[0]=0;
5859
remap();
5960
}
6061

61-
static void __scratch_x("aes") init_aes() {
62+
static void init_aes() {
6263
resetrng();
6364
gen_lut_sbox();
6465
init_lut_map();
@@ -67,8 +68,7 @@ static void __scratch_x("aes") init_aes() {
6768
#if USE_USB_DPRAM
6869
uint8_t* workarea = (uint8_t*)USBCTRL_DPRAM_BASE;
6970
#else
70-
// static __attribute__((aligned(4))) uint8_t workarea[4 * 1024];
71-
uint8_t* workarea = (uint8_t*)SRAM_SCRATCH_Y_BASE;
71+
uint8_t* workarea = (uint8_t*)0x20080200; // AES Code & workspace from 0x20080180 -> 0x20081600
7272
#endif
7373

7474
int main() {
@@ -127,7 +127,7 @@ int main() {
127127

128128
int rc = rom_chain_image(
129129
workarea,
130-
4 * 1024 - PICO_STACK_SIZE, // Don't use stack in workarea
130+
4 * 1024,
131131
data_start_addr,
132132
data_size
133133
);
Lines changed: 259 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,259 @@
1+
/* Based on GCC ARM embedded samples.
2+
Defines the following symbols for use by code:
3+
__exidx_start
4+
__exidx_end
5+
__etext
6+
__data_start__
7+
__preinit_array_start
8+
__preinit_array_end
9+
__init_array_start
10+
__init_array_end
11+
__fini_array_start
12+
__fini_array_end
13+
__data_end__
14+
__bss_start__
15+
__bss_end__
16+
__end__
17+
end
18+
__HeapLimit
19+
__StackLimit
20+
__StackTop
21+
__stack (== StackTop)
22+
*/
23+
24+
MEMORY
25+
{
26+
RAM_START(rwx) : ORIGIN = 0x20080000, LENGTH = 0x180
27+
SCRATCH_X(rwx) : ORIGIN = 0x20080180, LENGTH = 0xE80
28+
SCRATCH_Y(rwx) : ORIGIN = 0x20081000, LENGTH = 0x800
29+
RAM(rwx) : ORIGIN = 0x20081800, LENGTH = 0x800
30+
}
31+
32+
ENTRY(_entry_point)
33+
34+
SECTIONS
35+
{
36+
/* Note unlike RP2040, we start the image with a vector table even for
37+
NO_FLASH builds. On Arm, the bootrom expects a VT at the start of the
38+
image by default; on RISC-V, the default is to enter the image at its
39+
lowest address, so an IMAGEDEF item is required to specify the
40+
nondefault entry point. */
41+
42+
.start_text : {
43+
__logical_binary_start = .;
44+
/* Vectors require 512-byte alignment on v8-M when >48 IRQs are used,
45+
so we would waste RAM if the vector table were not at the
46+
start. */
47+
KEEP (*(.vectors))
48+
KEEP (*(.binary_info_header))
49+
__binary_info_header_end = .;
50+
KEEP (*(.embedded_block))
51+
__embedded_block_end = .;
52+
} > RAM_START
53+
54+
.text : {
55+
__reset_start = .;
56+
KEEP (*(.reset))
57+
__reset_end = .;
58+
*(.time_critical*)
59+
*(.text*)
60+
. = ALIGN(4);
61+
*(.init)
62+
*(.fini)
63+
/* Pull all c'tors into .text */
64+
*crtbegin.o(.ctors)
65+
*crtbegin?.o(.ctors)
66+
*(EXCLUDE_FILE(*crtend?.o *crtend.o) .ctors)
67+
*(SORT(.ctors.*))
68+
*(.ctors)
69+
/* Followed by destructors */
70+
*crtbegin.o(.dtors)
71+
*crtbegin?.o(.dtors)
72+
*(EXCLUDE_FILE(*crtend?.o *crtend.o) .dtors)
73+
*(SORT(.dtors.*))
74+
*(.dtors)
75+
76+
*(.eh_frame*)
77+
} > RAM
78+
79+
.rodata : {
80+
. = ALIGN(4);
81+
*(.rodata*)
82+
*(.srodata*)
83+
. = ALIGN(4);
84+
*(SORT_BY_ALIGNMENT(SORT_BY_NAME(.flashdata*)))
85+
. = ALIGN(4);
86+
} > RAM
87+
88+
.ARM.extab :
89+
{
90+
*(.ARM.extab* .gnu.linkonce.armextab.*)
91+
} > RAM
92+
93+
__exidx_start = .;
94+
.ARM.exidx :
95+
{
96+
*(.ARM.exidx* .gnu.linkonce.armexidx.*)
97+
} > RAM
98+
__exidx_end = .;
99+
100+
/* Machine inspectable binary information */
101+
. = ALIGN(4);
102+
__binary_info_start = .;
103+
.binary_info :
104+
{
105+
KEEP(*(.binary_info.keep.*))
106+
*(.binary_info.*)
107+
} > RAM
108+
__binary_info_end = .;
109+
. = ALIGN(4);
110+
111+
.data : {
112+
__data_start__ = .;
113+
*(vtable)
114+
*(.data*)
115+
*(.sdata*)
116+
117+
. = ALIGN(4);
118+
*(.after_data.*)
119+
. = ALIGN(4);
120+
/* preinit data */
121+
PROVIDE_HIDDEN (__mutex_array_start = .);
122+
KEEP(*(SORT(.mutex_array.*)))
123+
KEEP(*(.mutex_array))
124+
PROVIDE_HIDDEN (__mutex_array_end = .);
125+
126+
. = ALIGN(4);
127+
/* preinit data */
128+
PROVIDE_HIDDEN (__preinit_array_start = .);
129+
KEEP(*(SORT(.preinit_array.*)))
130+
KEEP(*(.preinit_array))
131+
PROVIDE_HIDDEN (__preinit_array_end = .);
132+
133+
. = ALIGN(4);
134+
/* init data */
135+
PROVIDE_HIDDEN (__init_array_start = .);
136+
KEEP(*(SORT(.init_array.*)))
137+
KEEP(*(.init_array))
138+
PROVIDE_HIDDEN (__init_array_end = .);
139+
140+
. = ALIGN(4);
141+
/* finit data */
142+
PROVIDE_HIDDEN (__fini_array_start = .);
143+
*(SORT(.fini_array.*))
144+
*(.fini_array)
145+
PROVIDE_HIDDEN (__fini_array_end = .);
146+
147+
*(.jcr)
148+
. = ALIGN(4);
149+
} > RAM
150+
151+
.tdata : {
152+
. = ALIGN(4);
153+
*(.tdata .tdata.* .gnu.linkonce.td.*)
154+
/* All data end */
155+
__tdata_end = .;
156+
} > RAM
157+
PROVIDE(__data_end__ = .);
158+
159+
.uninitialized_data (NOLOAD): {
160+
. = ALIGN(4);
161+
*(.uninitialized_data*)
162+
} > RAM
163+
/* __etext is (for backwards compatibility) the name of the .data init source pointer (...) */
164+
__etext = LOADADDR(.data);
165+
166+
.tbss (NOLOAD) : {
167+
. = ALIGN(4);
168+
__bss_start__ = .;
169+
__tls_base = .;
170+
*(.tbss .tbss.* .gnu.linkonce.tb.*)
171+
*(.tcommon)
172+
173+
__tls_end = .;
174+
} > RAM
175+
176+
.bss (NOLOAD) : {
177+
. = ALIGN(4);
178+
__tbss_end = .;
179+
180+
*(SORT_BY_ALIGNMENT(SORT_BY_NAME(.bss*)))
181+
*(COMMON)
182+
PROVIDE(__global_pointer$ = . + 2K);
183+
*(.sbss*)
184+
. = ALIGN(4);
185+
__bss_end__ = .;
186+
} > RAM
187+
188+
.heap (NOLOAD):
189+
{
190+
__end__ = .;
191+
end = __end__;
192+
KEEP(*(.heap*))
193+
} > RAM
194+
/* historically on GCC sbrk was growing past __HeapLimit to __StackLimit, however
195+
to be more compatible, we now set __HeapLimit explicitly to where the end of the heap is */
196+
__HeapLimit = ORIGIN(RAM) + LENGTH(RAM);
197+
198+
/* Start and end symbols must be word-aligned */
199+
.scratch_x : {
200+
__scratch_x_start__ = .;
201+
*(.scratch_x.*)
202+
. = ALIGN(4);
203+
__scratch_x_end__ = .;
204+
} > SCRATCH_X
205+
__scratch_x_source__ = LOADADDR(.scratch_x);
206+
207+
.scratch_y : {
208+
__scratch_y_start__ = .;
209+
*(.scratch_y.*)
210+
. = ALIGN(4);
211+
__scratch_y_end__ = .;
212+
} > SCRATCH_Y
213+
__scratch_y_source__ = LOADADDR(.scratch_y);
214+
215+
/* .stack*_dummy section doesn't contains any symbols. It is only
216+
* used for linker to calculate size of stack sections, and assign
217+
* values to stack symbols later
218+
*
219+
* stack1 section may be empty/missing if platform_launch_core1 is not used */
220+
221+
/* by default we put core 0 stack at the end of scratch Y, so that if core 1
222+
* stack is not used then all of SCRATCH_X is free.
223+
*/
224+
.stack1_dummy (NOLOAD):
225+
{
226+
*(.stack1*)
227+
} > SCRATCH_X
228+
.stack_dummy (NOLOAD):
229+
{
230+
KEEP(*(.stack*))
231+
} > SCRATCH_Y
232+
233+
/* stack limit is poorly named, but historically is maximum heap ptr */
234+
__StackLimit = ORIGIN(RAM) + LENGTH(RAM);
235+
__StackOneTop = ORIGIN(SCRATCH_X) + LENGTH(SCRATCH_X);
236+
__StackTop = ORIGIN(SCRATCH_Y) + LENGTH(SCRATCH_Y);
237+
__StackOneBottom = __StackOneTop - SIZEOF(.stack1_dummy);
238+
__StackBottom = __StackTop - SIZEOF(.stack_dummy);
239+
PROVIDE(__stack = __StackTop);
240+
241+
/* picolibc and LLVM */
242+
PROVIDE (__heap_start = __end__);
243+
PROVIDE (__heap_end = __HeapLimit);
244+
PROVIDE( __tls_align = MAX(ALIGNOF(.tdata), ALIGNOF(.tbss)) );
245+
PROVIDE( __tls_size_align = (__tls_size + __tls_align - 1) & ~(__tls_align - 1));
246+
PROVIDE( __arm32_tls_tcb_offset = MAX(8, __tls_align) );
247+
248+
/* llvm-libc */
249+
PROVIDE (_end = __end__);
250+
PROVIDE (__llvm_libc_heap_limit = __HeapLimit);
251+
252+
/* Check if data + heap + stack exceeds RAM limit */
253+
ASSERT(__StackLimit >= __HeapLimit, "region RAM overflowed")
254+
255+
ASSERT( __binary_info_header_end - __logical_binary_start <= 1024, "Binary info must be in first 1024 bytes of the binary")
256+
ASSERT( __embedded_block_end - __logical_binary_start <= 4096, "Embedded block must be in first 4096 bytes of the binary")
257+
258+
/* todo assert on extra code */
259+
}

main.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4938,7 +4938,7 @@ bool encrypt_command::execute(device_map &devices) {
49384938
enc_elf->read_file(tmp);
49394939

49404940
// Bootloader size
4941-
auto bootloader_txt = enc_elf->get_section(".text");
4941+
auto bootloader_txt = enc_elf->get_section(".start_text");
49424942
uint32_t bootloader_size = 0x20082000 - bootloader_txt->virtual_address();
49434943

49444944
// Move bootloader down in physical space to start of SRAM (which will be start of flash once packaged)

0 commit comments

Comments
 (0)