github.com/usbarmory/tamago@v0.0.0-20240508072735-8612bbe1e454/board/raspberrypi/README.md (about) 1 TamaGo - bare metal Go for ARM SoCs - Raspberry Pi Support 2 ========================================================== 3 4 tamago | https://github.com/usbarmory/tamago 5 6 Copyright (c) the pi/pi2/pizero package authors 7 8 ![TamaGo gopher](https://github.com/usbarmory/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/RISC-V System-on-Chip (SoC) components. 20 21 The [pi](https://github.com/usbarmory/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/usbarmory/tamago) and 30 [project wiki](https://github.com/usbarmory/tamago/wiki). 31 32 For the underlying driver support for this board see package 33 [bcm2835](https://github.com/usbarmory/tamago/tree/master/bcm2835). 34 35 The package API documentation can be found on 36 [pkg.go.dev](https://pkg.go.dev/github.com/usbarmory/tamago). 37 38 Supported hardware 39 ================== 40 41 | SoC | Board | SoC package | Board package | 42 |------------------|----------------------|------------------------------------------------------------------------|---------------------------------------------------------------------------------------| 43 | Broadcom BCM2835 | Pi Zero | [bcm2835](https://github.com/usbarmory/tamago/tree/master/soc/bcm2835) | [pi/pizero](https://github.com/usbarmory/tamago/tree/master/board/raspberrypi/pizero) | 44 | Broadcom BCM2835 | Pi 1 Model A+ (v1.2) | [bcm2835](https://github.com/usbarmory/tamago/tree/master/soc/bcm2835) | [pi/pi1](https://github.com/usbarmory/tamago/tree/master/board/raspberrypi/pi1) | 45 | Broadcom BCM2835 | Pi 1 Model B+ (v1.2) | [bcm2835](https://github.com/usbarmory/tamago/tree/master/soc/bcm2835) | [pi/pi1](https://github.com/usbarmory/tamago/tree/master/board/raspberrypi/pi1) | 46 | Broadcom BCM2836 | Pi 2 Model B (v1.1) | [bcm2835](https://github.com/usbarmory/tamago/tree/master/soc/bcm2835) | [pi/pi2](https://github.com/usbarmory/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/usbarmory/tamago/board/raspberrypi/pi2" 57 ) 58 ``` 59 60 OR 61 62 ```golang 63 import ( 64 _ "github.com/usbarmory/tamago/board/raspberrypi/pi1" 65 ) 66 ``` 67 68 OR 69 70 ```golang 71 import ( 72 _ "github.com/usbarmory/tamago/board/raspberrypi/pizero" 73 ) 74 ``` 75 76 Build the [TamaGo compiler](https://github.com/usbarmory/tamago-go) 77 (or use the [latest binary release](https://github.com/usbarmory/tamago-go/releases/latest)): 78 79 ```sh 80 wget https://github.com/usbarmory/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/usbarmory/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 Compiled binaries can be executed by converting Go binaries to emulate the 114 Linux boot protocol and have the Pi firmware load and execute the binary as a 115 Linux kernel. 116 117 A minimal set of Raspberry Pi firmware must be present on the SD card to 118 initialize the Raspberry Pi using the VideoCore GPU. The following minimum 119 files are required: 120 121 * bootcode.bin 122 * fixup.dat 123 * start.elf 124 125 These files are available [here](https://github.com/raspberrypi/firmware/tree/master/boot). 126 127 Direct 128 ------ 129 130 Linux kernels are expected to have executable code as the first bytes of the binary. The Go compiler 131 does not natively support creating such binaries, so a stub is generated and pre-pended that will jump 132 to the Go entrypoint. In this way, the Linux boot protocol is satisfied. 133 134 The example projects (linked above) use the direct approach. The GNU cross-compiler toolchain is 135 required. This method is in some ways more complex, but the Makefile code from the examples can be 136 used as an example implementation. 137 138 1. Build the Go ELF binary as normal 139 2. Use `objcopy` from the GNU cross-compiler toolchain to convert the binary to 'bin' format 140 3. Extract the entrypoint from the ELF format file 141 4. Compile a stub that will jump to the real entrypoint 142 5. Prepend the stub with sufficient padding for alignment 143 6. Configure the Pi to treat the binary as the Linux kernel to load 144 145 In the examples, this code performs steps 1-5: 146 147 ```sh 148 $(CROSS_COMPILE)objcopy -j .text -j .rodata -j .shstrtab -j .typelink \ 149 -j .itablink -j .gopclntab -j .go.buildinfo -j .noptrdata -j .data \ 150 -j .bss --set-section-flags .bss=alloc,load,contents \ 151 -j .noptrbss --set-section-flags .noptrbss=alloc,load,contents\ 152 $(APP) -O binary $(APP).o 153 ${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 154 ${CROSS_COMPILE}objcopy boot.o -O binary stub.o 155 # Truncate pads the stub out to correctly align the binary 156 # 32768 = 0x10000 (TEXT_START) - 0x8000 (Default kernel load address) 157 truncate -s 32768 stub.o 158 cat stub.o $(APP).o > $(APP).bin 159 ``` 160 161 The bootstrap code is something equivalent to this: 162 163 ```S 164 .global _boot 165 166 .text 167 _boot: 168 LDR r1, addr 169 BX r1 170 171 addr: 172 .word ENTRY_POINT 173 ``` 174 175 Direct: Configuring the firmware 176 -------------------------------- 177 178 An example config.txt is: 179 180 ```txt 181 enable_uart=1 182 uart_2ndstage=1 183 dtparam=uart0=on 184 kernel=example.bin 185 kernel_address=0x8000 186 disable_commandline_tags=1 187 core_freq=250 188 ``` 189 190 See <http://rpf.io/configtxt> for more configuration options. 191 192 NOTE: Do not be tempted to set the kernel address to 0x0: 193 194 1. TamaGo places critical data-structures at RAMSTART 195 2. The Pi firmware parks all but 1 CPU core in wait-loops, controlled by bytes starting at 0x000000CC 196 (see <https://github.com/raspberrypi/tools/blob/master/armstubs/armstub7.S>) 197 198 Direct: Executing 199 ----------------- 200 201 Copy the binary and config.txt to an SD card alongside the Pi firmware binaries and power-up the Pi. 202 203 Debugging: Standard output 204 ========================== 205 206 The standard output can be accessed through the UART pins on the Raspberry Pi. 207 A 3.3v USB-to-serial cable, such as the [Adafruit USB to TTL Serial Cable](https://www.adafruit.com/product/954) 208 can be used. Any suitable terminal emulator can be used to access standard output. 209 210 The UART clock is based on the VPU clock in some Pi models, if the UART output 211 appears corrupted, ensure the VPU clock frequency is fixed using `core_freq=250` 212 in `config.txt`. 213 214 NOTE: Go outputs 'LF' for newline, for best results use a terminal app capable 215 of mapping 'LF' to 'CRLF' as-needed. 216 217 License 218 ======= 219 220 tamago | https://github.com/usbarmory/tamago 221 Copyright (c) WithSecure Corporation 222 223 raspberrypi | https://github.com/usbarmory/tamago/tree/master/board/raspberrypi 224 Copyright (c) the pi package authors 225 226 These source files are distributed under the BSD-style license found in the 227 [LICENSE](https://github.com/usbarmory/tamago/blob/master/board/raspberrypi/LICENSE) file. 228 229 The TamaGo logo is adapted from the Go gopher designed by Renee French and 230 licensed under the Creative Commons 3.0 Attributions license. Go Gopher vector 231 illustration by Hugo Arganda.