github.com/f-secure-foundry/tamago@v0.0.0-20220307101044-d73fcdd7f11b/board/raspberrypi/README.md (about) 1 TamaGo - bare metal Go for ARM SoCs - Raspberry Pi Support 2 ========================================================== 3 4 tamago | https://github.com/f-secure-foundry/tamago 5 6 Copyright (c) the pi/pi2/pizero package authors 7 8 ![TamaGo gopher](https://github.com/f-secure-foundry/tamago/wiki/images/tamago.svg?sanitize=true) 9 10 Contributors 11 ============ 12 13 [Kenneth Bell](https://github.com/kenbell) 14 15 Introduction 16 ============ 17 18 TamaGo is a framework that enables compilation and execution of unencumbered Go 19 applications on bare metal ARM System-on-Chip (SoC) components. 20 21 The [pi](https://github.com/f-secure-foundry/tamago/tree/master/board/raspberrypi) 22 package provides support for the [Raspberry Pi](https://www.raspberrypi.org/) 23 series of Single Board Computer. 24 25 Documentation 26 ============= 27 28 For more information about TamaGo see its 29 [repository](https://github.com/f-secure-foundry/tamago) and 30 [project wiki](https://github.com/f-secure-foundry/tamago/wiki). 31 32 For the underlying driver support for this board see package 33 [bcm2835](https://github.com/f-secure-foundry/tamago/tree/master/bcm2835). 34 35 The package API documentation can be found on 36 [pkg.go.dev](https://pkg.go.dev/github.com/f-secure-foundry/tamago). 37 38 Supported hardware 39 ================== 40 41 | SoC | Board | SoC package | Board package | 42 |---------|----------------------|-------------------------------------------------------------------------------|----------------------------------------------------------------------------------------------| 43 | BCM2835 | Pi Zero | [bcm2835](https://github.com/f-secure-foundry/tamago/tree/master/soc/bcm2835) | [pi/pizero](https://github.com/f-secure-foundry/tamago/tree/master/board/raspberrypi/pizero) | 44 | BCM2835 | Pi 1 Model A+ (v1.2) | [bcm2835](https://github.com/f-secure-foundry/tamago/tree/master/soc/bcm2835) | [pi/pi1](https://github.com/f-secure-foundry/tamago/tree/master/board/raspberrypi/pi1) | 45 | BCM2835 | Pi 1 Model B+ (v1.2) | [bcm2835](https://github.com/f-secure-foundry/tamago/tree/master/soc/bcm2835) | [pi/pi1](https://github.com/f-secure-foundry/tamago/tree/master/board/raspberrypi/pi1) | 46 | BCM2836 | Pi 2 Model B (v1.1) | [bcm2835](https://github.com/f-secure-foundry/tamago/tree/master/soc/bcm2835) | [pi/pi2](https://github.com/f-secure-foundry/tamago/tree/master/board/raspberrypi/pi2) | 47 48 Compiling 49 ========= 50 51 Go applications are simply required to import, the relevant board package to 52 ensure that hardware initialization and runtime support takes place: 53 54 ```golang 55 import ( 56 _ "github.com/f-secure-foundry/tamago/board/raspberrypi/pi2" 57 ) 58 ``` 59 60 OR 61 62 ```golang 63 import ( 64 _ "github.com/f-secure-foundry/tamago/board/raspberrypi/pi1" 65 ) 66 ``` 67 68 OR 69 70 ```golang 71 import ( 72 _ "github.com/f-secure-foundry/tamago/board/raspberrypi/pizero" 73 ) 74 ``` 75 76 Build the [TamaGo compiler](https://github.com/f-secure-foundry/tamago-go) 77 (or use the [latest binary release](https://github.com/f-secure-foundry/tamago-go/releases/latest)): 78 79 ```sh 80 wget https://github.com/f-secure-foundry/tamago-go/archive/refs/tags/latest.zip 81 unzip latest.zip 82 cd tamago-go-latest/src && ./all.bash 83 cd ../bin && export TAMAGO=`pwd`/go 84 ``` 85 86 Go applications can be compiled as usual, using the compiler built in the 87 previous step, but with the addition of the following flags/variables and 88 ensuring that the required SoC and board packages are available in `GOPATH`: 89 90 ```sh 91 GO_EXTLINK_ENABLED=0 CGO_ENABLED=0 GOOS=tamago GOARM=5 GOARCH=arm \ 92 ${TAMAGO} build -ldflags "-T 0x00010000 -E _rt0_arm_tamago -R 0x1000" 93 ``` 94 95 GOARM & Examples 96 ---------------- 97 98 The GOARM environment variable must be set according to the Raspberry Pi model: 99 100 | Model | GOARM | Example | 101 |-------|-------|-------------------------------------------------------------| 102 | Zero | 5 | <https://github.com/f-secure-foundry/tamago-example-pizero> | 103 | 1A+ | 5 | <https://github.com/prusnak/tamago-example-pi1> | 104 | 1B+ | 5 | <https://github.com/prusnak/tamago-example-pi1> | 105 | 2B | 7 | <https://github.com/kenbell/tamago-example-pi2> | 106 107 NOTE: The Pi Zero and Pi 1 are ARMv6, but do not have support for all floating point instructions the Go compiler 108 generates with `GOARM=6`. Using `GOARM=5` causes Go to include a software floating point implementation. 109 110 Executing 111 ========= 112 113 There are two options for executing compiled binaries. The direct approach is to convert Go binaries 114 to emulate the Linux boot protocol and have the Pi firmware load and execute the binary as a Linux kernel. 115 The U-boot method enables ELF binaries to be loaded and executed directly. 116 117 In both cases a minimal set of Raspberry Pi firmware must be present on the SD card that initializes the 118 Raspberry Pi using the VideoCore GPU. The following minimum files are required: 119 120 * bootcode.bin 121 * fixup.dat 122 * start.elf 123 124 These files are available [here](https://github.com/raspberrypi/firmware/tree/master/boot). 125 126 Direct 127 ------ 128 129 Linux kernels are expected to have executable code as the first bytes of the binary. The Go compiler 130 does not natively support creating such binaries, so a stub is generated and pre-pended that will jump 131 to the Go entrypoint. In this way, the Linux boot protocol is satisfied. 132 133 The example projects (linked above) use the direct approach. The GNU cross-compiler toolchain is 134 required. This method is in some ways more complex, but the Makefile code from the examples can be 135 used as an example implementation. 136 137 1. Build the Go ELF binary as normal 138 2. Use `objcopy` from the GNU cross-compiler toolchain to convert the binary to 'bin' format 139 3. Extract the entrypoint from the ELF format file 140 4. Compile a stub that will jump to the real entrypoint 141 5. Prepend the stub with sufficient padding for alignment 142 6. Configure the Pi to treat the binary as the Linux kernel to load 143 144 In the examples, this code performs steps 1-5: 145 146 ```sh 147 $(CROSS_COMPILE)objcopy -j .text -j .rodata -j .shstrtab -j .typelink \ 148 -j .itablink -j .gopclntab -j .go.buildinfo -j .noptrdata -j .data \ 149 -j .bss --set-section-flags .bss=alloc,load,contents \ 150 -j .noptrbss --set-section-flags .noptrbss=alloc,load,contents\ 151 $(APP) -O binary $(APP).o 152 ${CROSS_COMPILE}gcc -D ENTRY_POINT=`${CROSS_COMPILE}readelf -e $(APP) | grep Entry | sed 's/.*\(0x[a-zA-Z0-9]*\).*/\1/'` -c boot.S -o boot.o 153 ${CROSS_COMPILE}objcopy boot.o -O binary stub.o 154 # Truncate pads the stub out to correctly align the binary 155 # 32768 = 0x10000 (TEXT_START) - 0x8000 (Default kernel load address) 156 truncate -s 32768 stub.o 157 cat stub.o $(APP).o > $(APP).bin 158 ``` 159 160 The bootstrap code is something equivalent to this: 161 162 ```S 163 .global _boot 164 165 .text 166 _boot: 167 LDR r1, addr 168 BX r1 169 170 addr: 171 .word ENTRY_POINT 172 ``` 173 174 Direct: Configuring the firmware 175 -------------------------------- 176 177 An example config.txt is: 178 179 ```txt 180 enable_uart=1 181 uart_2ndstage=1 182 dtparam=uart0=on 183 kernel=example.bin 184 kernel_address=0x8000 185 disable_commandline_tags=1 186 core_freq=250 187 ``` 188 189 See <http://rpf.io/configtxt> for more configuration options. 190 191 NOTE: Do not be tempted to set the kernel address to 0x0: 192 193 1. TamaGo places critical data-structures at RAMSTART 194 2. The Pi firmware parks all but 1 CPU core in wait-loops, controlled by bytes starting at 0x000000CC 195 (see <https://github.com/raspberrypi/tools/blob/master/armstubs/armstub7.S>) 196 197 Direct: Executing 198 ----------------- 199 200 Copy the binary and config.txt to an SD card alongside the Pi firmware binaries and power-up the Pi. 201 202 U-Boot 203 ------ 204 205 For the U-Boot method, configure, compile and copy [U-Boot](https://www.denx.de/wiki/U-Boot) onto an 206 existing Raspberry Pi bootable SD card (see above for minimum context of the card). 207 208 ```sh 209 cd u-boot 210 211 # Config: 212 # - use rpi_0_w_defconfig for Pi Zero 213 # - use rpi_defconfig for Pi 1 214 # - use rpi_2_defconfig for Pi 2 215 make rpi_0_w_defconfig 216 217 # Build 218 make 219 220 # Copy 221 cp u-boot.bin <path_to_sdcard> 222 ``` 223 224 U-Boot: Configuring the firmware 225 -------------------------------- 226 227 The Raspberry Pi firmware must be configured to use U-Boot. Enabling the 228 [UART](https://www.raspberrypi.org/documentation/configuration/uart.md) is 229 recommended to diagnose boot issues. 230 231 These settings work well in `config.txt`: 232 233 ```text 234 enable_uart=1 235 uart_2ndstage=1 236 dtparam=uart0=on 237 kernel=u-boot.bin 238 core_freq=250 239 ``` 240 241 U-Boot: Executing 242 ----------------- 243 244 Copy the built ELF binary on an existing bootable Raspberry Pi SD card, then 245 launch it from the U-Boot console as follows: 246 247 ```sh 248 ext2load mmc 0:1 0x8000000 example 249 bootelf 0x8000000 250 ``` 251 252 For non-interactive execution modify the U-Boot configuration accordingly. 253 254 Debugging: Standard output 255 ========================== 256 257 The standard output can be accessed through the UART pins on the Raspberry Pi. 258 A 3.3v USB-to-serial cable, such as the [Adafruit USB to TTL Serial Cable](https://www.adafruit.com/product/954) 259 can be used. Any suitable terminal emulator can be used to access standard output. 260 261 The UART clock is based on the VPU clock in some Pi models, if the UART output 262 appears corrupted, ensure the VPU clock frequency is fixed using `core_freq=250` 263 in `config.txt`. 264 265 NOTE: Go outputs 'LF' for newline, for best results use a terminal app capable 266 of mapping 'LF' to 'CRLF' as-needed. 267 268 License 269 ======= 270 271 tamago | https://github.com/f-secure-foundry/tamago 272 Copyright (c) F-Secure Corporation 273 274 raspberrypi | https://github.com/f-secure-foundry/tamago/tree/master/board/raspberrypi 275 Copyright (c) the pi package authors 276 277 These source files are distributed under the BSD-style license found in the 278 [LICENSE](https://github.com/f-secure-foundry/tamago/blob/master/board/raspberrypi/LICENSE) file. 279 280 The TamaGo logo is adapted from the Go gopher designed by Renee French and 281 licensed under the Creative Commons 3.0 Attributions license. Go Gopher vector 282 illustration by Hugo Arganda.