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.