Skip to content

Commit f03fb5b

Browse files
committed
Add Linux loader
This privdes just enough firmware to load Linux. The loader is linked to run from the aliased BRAM address. It can load a raw kernel (vmlinux.bin) or a wrapper that embeds the device tree (dtbImage.microwatt). The printf comes from https://github.com/mpredfearn/simple-printf 1. Build Linux for microwatt objcopy -O binary microwatt/vmlinux vmlinux.bin 2. Build a dtb 3. Set MW_DEBUG to point to a copy of mw_debug and type `make load` to load the loader into BRAM. 4. Press 'RESET' 5. Follow the instructions: Microwatt Loader (Jun 2 2020 21:31:16) Load binaries into SDRAM and select option to start: vmlinux.bin and dtb: mw_debug -b jtag stop load vmlinux.bin load microwatt.dtb 1000000 start press 'l' to start' dtbImage.microwatt: mw_debug -b jtag stop load dtbImage.microwatt 500000 start press 'w' to start' If you want to test other software, such as MicroPython, you can also load it to the start of SDRAM and the loader will jump to it with 'l'. Signed-off-by: Joel Stanley <joel@jms.id.au>
1 parent 84ab28b commit f03fb5b

File tree

7 files changed

+678
-0
lines changed

7 files changed

+678
-0
lines changed

.gitignore

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,17 @@
33
*.cf
44
*.s
55
*_tb
6+
*.swp
67
main_ram.bin
78
tests/*/*.bin
89
tests/*/*.hex
910
tests/*/*.elf
1011
TAGS
12+
tags
13+
scripts/mw_debug/mw_debug
14+
loader/loader.bin
15+
loader/loader.hex
16+
loader/loader.elf
17+
loader/powerpc.lds
18+
*.swn
19+
*.swo

loader/Makefile

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
ARCH = $(shell uname -m)
2+
ifneq ("$(ARCH)", "ppc64")
3+
ifneq ("$(ARCH)", "ppc64le")
4+
CROSS_COMPILE ?= powerpc64le-linux-gnu-
5+
endif
6+
endif
7+
8+
PYTHON3 ?= python3
9+
MW_DEBUG ?= mw_debug
10+
BRAM_ADDRESS ?= 0x80000000
11+
12+
CC = $(CROSS_COMPILE)gcc
13+
LD = $(CROSS_COMPILE)ld
14+
OBJCOPY = $(CROSS_COMPILE)objcopy
15+
16+
CFLAGS = -Os -g -Wall -std=c99 -msoft-float -mno-string -mno-multiple \
17+
-mno-vsx -mno-altivec -mlittle-endian -fno-stack-protector \
18+
-mstrict-align -ffreestanding -fdata-sections -ffunction-sections \
19+
-I../include
20+
ASFLAGS = $(CFLAGS)
21+
LDFLAGS = -T powerpc.lds --gc-sections
22+
23+
all: loader.hex
24+
25+
load: loader.bin
26+
$(MW_DEBUG) -b jtag load $^ $(BRAM_ADDRESS)
27+
28+
%.lds : %.lds.S
29+
$(CC) -I../include -P -E $< -o $@
30+
31+
loader.elf: loader.o head.o ../lib/console.o load.o printf.o | powerpc.lds
32+
$(LD) $(LDFLAGS) -o $@ $^
33+
34+
loader.bin: loader.elf
35+
$(OBJCOPY) -O binary $^ $@
36+
37+
loader.hex: loader.bin
38+
$(PYTHON3) ../scripts/bin2hex.py $^ > $@
39+
40+
clean:
41+
@rm -f *.o loader.elf loader.bin loader.hex powerpc.lds

loader/head.S

Lines changed: 109 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,109 @@
1+
/* Copyright 2013-2014 IBM Corp.
2+
*
3+
* Licensed under the Apache License, Version 2.0 (the "License");
4+
* you may not use this file except in compliance with the License.
5+
* You may obtain a copy of the License at
6+
*
7+
* http://www.apache.org/licenses/LICENSE-2.0
8+
*
9+
* Unless required by applicable law or agreed to in writing, software
10+
* distributed under the License is distributed on an "AS IS" BASIS,
11+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
12+
* implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
#include <microwatt_soc.h>
18+
19+
#define STACK_TOP (BRAM_BASE + 0x2000)
20+
21+
#define FIXUP_ENDIAN \
22+
tdi 0,0,0x48; /* Reverse endian of b . + 8 */ \
23+
b 191f; /* Skip trampoline if endian is good */ \
24+
.long 0xa600607d; /* mfmsr r11 */ \
25+
.long 0x01006b69; /* xori r11,r11,1 */ \
26+
.long 0x05009f42; /* bcl 20,31,$+4 */ \
27+
.long 0xa602487d; /* mflr r10 */ \
28+
.long 0x14004a39; /* addi r10,r10,20 */ \
29+
.long 0xa64b5a7d; /* mthsrr0 r10 */ \
30+
.long 0xa64b7b7d; /* mthsrr1 r11 */ \
31+
.long 0x2402004c; /* hrfid */ \
32+
191:
33+
34+
35+
/* Load an immediate 64-bit value into a register */
36+
#define LOAD_IMM64(r, e) \
37+
lis r,(e)@highest; \
38+
ori r,r,(e)@higher; \
39+
rldicr r,r, 32, 31; \
40+
oris r,r, (e)@h; \
41+
ori r,r, (e)@l;
42+
43+
.section ".head","ax"
44+
45+
/*
46+
* Microwatt currently enters in LE mode at 0x0, so we don't need to
47+
* do any endian fix ups>
48+
*/
49+
. = 0
50+
.global _start
51+
_start:
52+
b boot_entry
53+
54+
/* QEMU enters at 0x10 */
55+
. = 0x10
56+
FIXUP_ENDIAN
57+
b boot_entry
58+
59+
. = 0x100
60+
FIXUP_ENDIAN
61+
b boot_entry
62+
63+
.global boot_entry
64+
boot_entry:
65+
/* setup stack */
66+
LOAD_IMM64(%r1, STACK_TOP - 0x100)
67+
LOAD_IMM64(%r12, main)
68+
mtctr %r12,
69+
bctrl
70+
b .
71+
72+
#define EXCEPTION(nr) \
73+
.= nr ;\
74+
b .
75+
76+
/* More exception stubs */
77+
EXCEPTION(0x300)
78+
EXCEPTION(0x380)
79+
EXCEPTION(0x400)
80+
EXCEPTION(0x480)
81+
EXCEPTION(0x500)
82+
EXCEPTION(0x600)
83+
EXCEPTION(0x700)
84+
EXCEPTION(0x800)
85+
EXCEPTION(0x900)
86+
EXCEPTION(0x980)
87+
EXCEPTION(0xa00)
88+
EXCEPTION(0xb00)
89+
EXCEPTION(0xc00)
90+
EXCEPTION(0xd00)
91+
EXCEPTION(0xe00)
92+
EXCEPTION(0xe20)
93+
EXCEPTION(0xe40)
94+
EXCEPTION(0xe60)
95+
EXCEPTION(0xe80)
96+
EXCEPTION(0xf00)
97+
EXCEPTION(0xf20)
98+
EXCEPTION(0xf40)
99+
EXCEPTION(0xf60)
100+
EXCEPTION(0xf80)
101+
#if 0
102+
EXCEPTION(0x1000)
103+
EXCEPTION(0x1100)
104+
EXCEPTION(0x1200)
105+
EXCEPTION(0x1300)
106+
EXCEPTION(0x1400)
107+
EXCEPTION(0x1500)
108+
EXCEPTION(0x1600)
109+
#endif

loader/load.S

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
/*
2+
* Set up system for jumping to Linux.
3+
*
4+
* load_linux(kernel, dtb)
5+
*/
6+
.global load_linux
7+
load_linux:
8+
/* ABI:
9+
* r5: zero (no openfirmware)
10+
* r3: device tree
11+
*/
12+
addi %r5,0,0
13+
addi %r12,%r3,0
14+
addi %r3,%r4,0
15+
mtctr %r12
16+
bctrl
17+
b .
18+
19+
/*
20+
* Invalidate the icache.
21+
*/
22+
.global invalidate_icache
23+
invalidate_icache:
24+
icbi 0,0
25+
isync
26+
blr

loader/loader.c

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
#include <stdint.h>
2+
#include <stdbool.h>
3+
#include <io.h>
4+
#include <microwatt_soc.h>
5+
6+
#include "console.h"
7+
8+
extern void load_linux(unsigned long kernel, unsigned long dtb);
9+
extern void invalidate_icache(void);
10+
11+
extern int simple_printf(char *fmt, ...);
12+
#define printf(...) simple_printf(__VA_ARGS__)
13+
14+
#define DTB_ADDR 0x01000000L
15+
16+
#define DTBIMAGE_ADDR 0x500000L
17+
18+
int main(void)
19+
{
20+
int i;
21+
potato_uart_init();
22+
unsigned long kernel, dtb;
23+
24+
printf("\r\nMicrowatt Loader (%s %s)\r\n\r\n", __DATE__, __TIME__);
25+
26+
writeq(SYS_REG_CTRL_DRAM_AT_0, SYSCON_BASE + SYS_REG_CTRL);
27+
invalidate_icache();
28+
29+
printf("Load binaries into SDRAM and select option to start:\r\n\r\n");
30+
printf("vmlinux.bin and dtb:\r\n");
31+
printf(" mw_debug -b jtag stop load vmlinux.bin load microwatt.dtb %x start\r\n",
32+
DTB_ADDR);
33+
printf(" press 'l' to start'\r\n\r\n");
34+
35+
printf("dtbImage.microwatt:\r\n");
36+
printf(" mw_debug -b jtag stop load dtbImage.microwatt %x start\r\n",
37+
DTBIMAGE_ADDR);
38+
printf(" press 'w' to start'\r\n\r\n");
39+
40+
while (1) {
41+
switch (getchar()) {
42+
case 'l':
43+
kernel = 0;
44+
dtb = DTB_ADDR;
45+
goto load;
46+
case 'w':
47+
kernel = DTBIMAGE_ADDR;
48+
dtb = -1;
49+
goto load;
50+
default:
51+
continue;
52+
}
53+
}
54+
55+
load:
56+
printf("Loading Linux at %08x...\r\n", 0x0);
57+
for (i = 0; i < 80; i++)
58+
putchar('.');
59+
printf("\r\n");
60+
load_linux(kernel, dtb);
61+
62+
while (1);
63+
}

loader/powerpc.lds.S

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
#include <microwatt_soc.h>
2+
3+
#define BASE_ADDR BRAM_BASE
4+
5+
SECTIONS
6+
{
7+
_start = .;
8+
. = BASE_ADDR;
9+
.head : {
10+
KEEP(*(.head))
11+
}
12+
. = (BASE_ADDR + 0x1000);
13+
.text : { *(.text) }
14+
. = (BASE_ADDR + 0x2000);
15+
.data : { *(.data) }
16+
.bss : { *(.bss) }
17+
}

0 commit comments

Comments
 (0)