Skip to content

Commit 1e833c3

Browse files
committed
Initial commit
0 parents  commit 1e833c3

16 files changed

+672
-0
lines changed

.gitignore

+8
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
*.o
2+
*.bin
3+
*.elf
4+
mmio_load
5+
mmio_view
6+
mmio_rate
7+
mmio_enable_hook
8+
mmio_disable_hook

Makefile

+32
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
all: launch_core1.bin core1.bin blink_core1.bin mmio_enable_hook mmio_load mmio_view
2+
3+
clean:
4+
rm *.o *.elf *.bin mmio_enable_hook mmio_disable_hook mmio_load mmio_view
5+
6+
%.o: %.s
7+
arm-none-eabi-as $< -o $@
8+
9+
launch_core1.elf: launch_core1.o
10+
arm-none-eabi-ld launch_core1.o -T memmap -o $@
11+
12+
core1.elf: count_core1.o
13+
arm-none-eabi-ld count_core1.o -T memmap_core1 -o $@
14+
15+
blink_core1.elf: blink_core1.o
16+
arm-none-eabi-ld blink_core1.o -T memmap_core1 -o $@
17+
18+
%.bin: %.elf
19+
arm-none-eabi-objcopy $< -O binary $@
20+
21+
mmio_enable_hook: mmio_enable_hook.c
22+
gcc $< -o $@
23+
24+
mmio_disable_hook: mmio_disable_hook.c
25+
gcc $< -o $@
26+
27+
mmio_view: mmio_view.c
28+
gcc $< -o $@
29+
30+
mmio_load: mmio_load.c
31+
gcc $< -o $@
32+

README.md

+35
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
# RP1 launch second core
2+
3+
This hack hooks a frequently called function in the RP1 firmware, and
4+
uses it to launch the second core at a known address.
5+
6+
Beware: this hardcodes the address of the function to hook, so if you
7+
aren't running the same firmware version as me it might need modification.
8+
9+
My version is
10+
11+
$ vcgencmd bootloader_version
12+
2024/01/05 15:57:40
13+
version 30cc5f37d65b279e820adb1d9840ad3c1cc98229 (release)
14+
15+
The current code blinks an LED connected to GPIO 17.
16+
17+
## Building and running
18+
19+
You'll need to install the arm-none-eabi toolchain to build RP1 binaries:
20+
21+
sudo apt install binutils-arm-none-eabi
22+
23+
Then build everything:
24+
25+
make
26+
27+
Load the hook code for core0 and the blinky code for core1:
28+
29+
sudo ./mmio_load
30+
31+
Enable the hook:
32+
33+
sudo ./mmio_enable_hook
34+
35+
If everything's working GPIO 17 should now be blinking, driven by the RP1 core1.

blink_core1.s

+42
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
.cpu cortex-m3
2+
.thumb
3+
.syntax unified
4+
5+
.section .text
6+
.align 2
7+
.thumb_func
8+
.globl _entry
9+
_entry:
10+
/* Func SYS_RIO, output enable */
11+
ldr r0, =0x400d008c
12+
mov r1, #0x85
13+
str r1, [r0]
14+
15+
/* pad control */
16+
ldr r0, =0x400f0048
17+
mov r1, #0x56
18+
str r1, [r0]
19+
20+
/* output enable */
21+
ldr r0, =0x400e2000
22+
mov r1, #0x20000
23+
str r1, [r0, #4]
24+
25+
/* output high */
26+
str r1, [r0]
27+
28+
sub r0, 0x1000
29+
mov r5, #0x500000
30+
adr r6, count
31+
mov r7, #0
32+
1:
33+
add r7, #1
34+
str r7, [r6]
35+
cmp r7, r5
36+
bls 1b
37+
str r1, [r0]
38+
mov r7, #0
39+
b 1b
40+
41+
.align 4
42+
count: .word 0

count_core1.s

+17
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
.cpu cortex-m3
2+
.thumb
3+
.syntax unified
4+
5+
.section .text
6+
.align 2
7+
.thumb_func
8+
.globl _entry
9+
_entry:
10+
adr r6, count
11+
ldr r7, [r6]
12+
add r7, #1
13+
str r7, [r6]
14+
b _entry
15+
16+
.align 4
17+
count: .word 0

counter.s

+30
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
.cpu cortex-m3
2+
.thumb
3+
.syntax unified
4+
5+
.section .text
6+
.align 2
7+
.thumb_func
8+
.globl _entry
9+
_entry:
10+
push {r6,r7}
11+
adr r6, count
12+
ldr r7, [r6]
13+
add r7, #1
14+
str r7, [r6]
15+
pop {r6,r7}
16+
17+
/* Clear interrupt implementation */
18+
cmp r0, #0x1f
19+
mov r3, #1
20+
mov.w r2, #0xe000e000
21+
bls 1f
22+
subs r0, #0x20
23+
add r3, #4
24+
1: lsls r3, r0
25+
str.w r3,[r2,#0x180]
26+
bx lr
27+
28+
29+
.align 4
30+
count: .word 0

jmp.s

+10
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
.cpu cortex-m3
2+
.thumb
3+
.syntax unified
4+
5+
.section .text
6+
.align 2
7+
.thumb_func
8+
.globl _entry
9+
_entry:
10+
b 0x20007000

launch_core1.s

+41
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
.cpu cortex-m3
2+
.thumb
3+
.syntax unified
4+
5+
.section .text
6+
.align 2
7+
.thumb_func
8+
.globl _entry
9+
_entry:
10+
push {r6,r7}
11+
adr r6, count
12+
ldr r7, [r6]
13+
cmp r7, #0
14+
bne 1f
15+
push {r0,r1}
16+
ldr r0, =0x40154014
17+
ldr r1, =(0x4FF83F2D ^ 0x20008001)
18+
str r1, [r0]
19+
ldr r1, =0x100030d0
20+
str r1, [r0,#8]
21+
sev
22+
pop {r0,r1}
23+
1:
24+
add r7, #1
25+
str r7, [r6]
26+
pop {r6,r7}
27+
28+
/* Clear interrupt implementation */
29+
cmp r0, #0x1f
30+
mov r3, #1
31+
mov.w r2, #0xe000e000
32+
bls 1f
33+
subs r0, #0x20
34+
add r3, #4
35+
1: lsls r3, r0
36+
str.w r3,[r2,#0x180]
37+
bx lr
38+
39+
40+
.align 4
41+
count: .word 0

memmap

+9
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
MEMORY
2+
{
3+
ram(rwx) : ORIGIN = 0x20007000, LENGTH = 0x1000
4+
}
5+
SECTIONS
6+
{
7+
.text : { *(.text*) } > ram
8+
.data : { *(.data*) *(.rodata*) } > ram
9+
}

memmap-jmp

+9
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
MEMORY
2+
{
3+
ram(rwx) : ORIGIN = 0x200007c8, LENGTH = 0x8
4+
}
5+
SECTIONS
6+
{
7+
.text : { *(.text*) } > ram
8+
.data : { *(.data*) *(.rodata*) } > ram
9+
}

memmap_core1

+9
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
MEMORY
2+
{
3+
ram(rwx) : ORIGIN = 0x20008000, LENGTH = 0x8000
4+
}
5+
SECTIONS
6+
{
7+
.text : { *(.text*) } > ram
8+
.data : { *(.data*) *(.rodata*) } > ram
9+
}

mmio_disable_hook.c

+93
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
#include <stdio.h>
2+
#include <stdlib.h>
3+
#include <unistd.h>
4+
#include <sys/time.h>
5+
#include <stdint.h>
6+
#include <endian.h>
7+
#include <errno.h>
8+
#include <fcntl.h>
9+
#include <stddef.h>
10+
#include <stdint.h>
11+
#include <stdio.h>
12+
#include <stdlib.h>
13+
#include <sys/mman.h>
14+
#include <sys/stat.h>
15+
#include <sys/types.h>
16+
#include <unistd.h>
17+
18+
19+
20+
//#define MMIOADDR 0x601100000
21+
//#define MMIOADDR 0x1f000f0000
22+
#define MMIOADDR 0x1f00400000
23+
#define MMIOLEN 0x10000
24+
#define BASE 0x700
25+
#define LEN 0x100
26+
27+
volatile unsigned int *mmio;
28+
#define REG32(m,x) ((volatile uint64_t *)((uint64_t)(m)+(uint64_t)(x)))
29+
30+
static void setup_io() {
31+
int fd = open("/dev/mem", O_RDWR | O_SYNC);
32+
if (fd < 0) {
33+
printf("Unable to open /dev/mem. Run as root using sudo?\n");
34+
exit(-1);
35+
}
36+
37+
void *gpio_map =
38+
mmap(NULL, // Any adddress in our space will do
39+
MMIOLEN, // Map length
40+
PROT_READ | PROT_WRITE, // Enable reading & writting to mapped memory
41+
MAP_SHARED, // Shared with other processes
42+
fd, // File to map
43+
MMIOADDR // Offset to GPIO peripheral
44+
);
45+
46+
close(fd);
47+
48+
if (gpio_map == MAP_FAILED) {
49+
perror("mmap failed, errno");
50+
exit(-1);
51+
}
52+
53+
mmio = ((volatile unsigned *)gpio_map) + BASE/4;
54+
}
55+
56+
57+
58+
volatile unsigned int test;
59+
int main(void) {
60+
61+
62+
setup_io();
63+
64+
printf("Read mmio address: %10lx \n", MMIOADDR + BASE);
65+
66+
unsigned int a=0;
67+
volatile unsigned int b=0;
68+
unsigned int i = 0;
69+
70+
for(a=0; a<LEN/4; a++) {
71+
if (!(a & 0x7)) printf("\n%04x: ", a*4);
72+
b= *(mmio + a);
73+
//*(mmio + a) = 0;
74+
printf("%08x ", b);
75+
}
76+
printf("\n");
77+
78+
// Jump from 0x200007c8 to 0x20007000
79+
*(mmio + 0xc8/4) = 0xf04f281f;
80+
//*(mmio + 0xc8/4) = 0xbc1af006;
81+
82+
#if 0
83+
a = 0;
84+
//FILE* f = fopen("counter.bin", "rb");
85+
FILE* f = fopen("core1.bin", "rb");
86+
while (!feof(f)) {
87+
unsigned int val;
88+
fread(&val, sizeof(val), 1, f);
89+
*(mmio + a++) = val;
90+
}
91+
#endif
92+
}
93+

0 commit comments

Comments
 (0)