TamaGo - bare metal Go for ARM SoCs

Related tags

DevOps Tools tamago
Overview

TamaGo - bare metal Go for ARM SoCs

tamago | https://github.com/f-secure-foundry/tamago

Copyright (c) F-Secure Corporation
https://foundry.f-secure.com

TamaGo gopher

Authors

Andrea Barisani
[email protected] | [email protected]

Andrej Rosano
[email protected] | [email protected]

Introduction

TamaGo is a framework that enables compilation and execution of unencumbered Go applications on bare metal ARM System-on-Chip (SoC) components.

The projects spawns from the desire of reducing the attack surface of embedded systems firmware by removing any runtime dependency on C code and Operating Systems.

The TamaGo framework consists of the following components:

  • A modified Go distribution which extends GOOS support to the tamago target, allowing bare metal execution.

  • Go packages for SoC driver support.

  • Go packages for board support.

The modifications are meant to be minimal for both the Go distribution (< ~4000 LOC changed) and the target application (one import required), with a clean separation from other architectures.

Strong emphasis is placed on code re-use from existing architectures already included within the standard Go runtime, see Internals.

Both aspects are motivated by the desire of providing a framework that allows secure Go firmware development on embedded systems.

Current release level

GitHub release Build Status

The current release for the TamaGo modified Go distribution is tamago1.16.3, which adds GOOS=tamago support to go1.16.3.

Binary releases for amd64 and armv7l Linux hosts are available.

Documentation

The main documentation can be found on the project wiki.

The package API documentation can be found on pkg.go.dev.

Supported hardware

The following table summarizes currently supported SoCs and boards.

SoC Board SoC package Board package
NXP i.MX6ULZ USB armory Mk II imx6 usbarmory/mark-two
NXP i.MX6ULL MCIMX6ULL-EVK imx6 mx6ullevk
BCM2835 Raspberry Pi Zero bcm2835 pi/pizero
BCM2835 Raspberry Pi 1 Model A+ bcm2835 pi/pi1
BCM2835 Raspberry Pi 1 Model B+ bcm2835 pi/pi1
BCM2836 Raspberry Pi 2 Model B bcm2835 pi/pi2

Compiling

Go applications are simply required to import, the relevant board package to ensure that hardware initialization and runtime support takes place:

import (
	// Example for USB armory Mk II
	_ "github.com/f-secure-foundry/tamago/board/f-secure/usbarmory/mark-two"
)

Build the TamaGo compiler (or use the latest binary release):

wget https://github.com/f-secure-foundry/tamago-go/archive/refs/tags/latest.zip
cd tamago-go-latest/src && ./all.bash
cd ../bin && export TAMAGO=`pwd`/go

Go applications can be compiled with the compiler built in the previous step, with the addition of a few flags/variables:

# Example for USB armory Mk II
GO_EXTLINK_ENABLED=0 CGO_ENABLED=0 GOOS=tamago GOARM=7 GOARCH=arm \
  ${TAMAGO} build -ldflags "-T 0x80010000  -E _rt0_arm_tamago -R 0x1000"

See the respective board package README file for compilation information for each specific target.

Executing and debugging

See the respective board package README file for execution and debugging information for each specific target (real or emulated).

The example application provides sample driver usage and instructions for native as well as emulated execution.

License

tamago | https://github.com/f-secure-foundry/tamago
Copyright (c) F-Secure Corporation

These source files are distributed under the BSD-style license found in the LICENSE file.

The TamaGo logo is adapted from the Go gopher designed by Renee French and licensed under the Creative Commons 3.0 Attributions license. Go Gopher vector illustration by Hugo Arganda.

Comments
  • Unable to get example working for RPi Zero

    Unable to get example working for RPi Zero

    Hi folks,

    I've had an issue open on the RPi Zero example repo for a month, but realised that may not be the right place to post this problem!

    Building the example RPi Zero project (with some tweaks, to fix the go.mod file) creates a kernel file which builds successfully, but fails to run on any of my RPi Zeros.

    These are the files I've had on my SD card, but I get no flashing LED, no printed output and no clues I know how to follow as to further debugging (I also tried including bcm2708-rpi-zero-w.dtb as it's called out as missing in the UART log, with no luck).

    How should I proceed in trying to fix this?

    UART Output
    Raspberry Pi Bootcode
    
    Read File: config.txt, 279
    
    Read File: start.elf, 2955648 (bytes)
    
    Read File: fixup.dat, 7311 (bytes)
    
    MESS:00:00:01.002000:0: brfs: File read: /mfs/sd/config.txt
    MESS:00:00:01.006316:0: brfs: File read: 279 bytes
    MESS:00:00:01.062589:0: HDMI0:EDID error reading EDID block 0 attempt 0
    MESS:00:00:01.068754:0: HDMI0:EDID error reading EDID block 0 attempt 1
    MESS:00:00:01.075090:0: HDMI0:EDID error reading EDID block 0 attempt 2
    MESS:00:00:01.081427:0: HDMI0:EDID error reading EDID block 0 attempt 3
    MESS:00:00:01.087764:0: HDMI0:EDID error reading EDID block 0 attempt 4
    MESS:00:00:01.094100:0: HDMI0:EDID error reading EDID block 0 attempt 5
    MESS:00:00:01.100437:0: HDMI0:EDID error reading EDID block 0 attempt 6
    MESS:00:00:01.106774:0: HDMI0:EDID error reading EDID block 0 attempt 7
    MESS:00:00:01.113111:0: HDMI0:EDID error reading EDID block 0 attempt 8
    MESS:00:00:01.119448:0: HDMI0:EDID error reading EDID block 0 attempt 9
    MESS:00:00:01.125543:0: HDMI0:EDID giving up on reading EDID block 0
    MESS:00:00:01.131252:0: brfs: File read: /mfs/sd/config.txt
    MESS:00:00:01.136292:0: gpioman: gpioman_get_pin_num: pin LEDS_PWR_OK not defined
    MESS:00:00:01.163018:0: brfs: File read: 279 bytes
    MESS:00:00:01.343494:0: gpioman: gpioman_get_pin_num: pin LEDS_PWR_OK not defined
    MESS:00:00:01.349317:0: *** Restart logging
    MESS:00:00:01.353713:0: hdmi: HDMI0:EDID error reading EDID block 0 attempt 0
    MESS:00:00:01.361298:0: hdmi: HDMI0:EDID error reading EDID block 0 attempt 1
    MESS:00:00:01.368156:0: hdmi: HDMI0:EDID error reading EDID block 0 attempt 2
    MESS:00:00:01.375014:0: hdmi: HDMI0:EDID error reading EDID block 0 attempt 3
    MESS:00:00:01.381870:0: hdmi: HDMI0:EDID error reading EDID block 0 attempt 4
    MESS:00:00:01.388729:0: hdmi: HDMI0:EDID error reading EDID block 0 attempt 5
    MESS:00:00:01.395586:0: hdmi: HDMI0:EDID error reading EDID block 0 attempt 6
    MESS:00:00:01.402443:0: hdmi: HDMI0:EDID error reading EDID block 0 attempt 7
    MESS:00:00:01.409302:0: hdmi: HDMI0:EDID error reading EDID block 0 attempt 8
    MESS:00:00:01.416158:0: hdmi: HDMI0:EDID error reading EDID block 0 attempt 9
    MESS:00:00:01.422775:0: hdmi: HDMI0:EDID giving up on reading EDID block 0
    MESS:00:00:01.428679:0: hdmi: HDMI0:EDID error reading EDID block 0 attempt 0
    MESS:00:00:01.436472:0: hdmi: HDMI0:EDID error reading EDID block 0 attempt 1
    MESS:00:00:01.443329:0: hdmi: HDMI0:EDID error reading EDID block 0 attempt 2
    MESS:00:00:01.450187:0: hdmi: HDMI0:EDID error reading EDID block 0 attempt 3
    MESS:00:00:01.457044:0: hdmi: HDMI0:EDID error reading EDID block 0 attempt 4
    MESS:00:00:01.463902:0: hdmi: HDMI0:EDID error reading EDID block 0 attempt 5
    MESS:00:00:01.470760:0: hdmi: HDMI0:EDID error reading EDID block 0 attempt 6
    MESS:00:00:01.477617:0: hdmi: HDMI0:EDID error reading EDID block 0 attempt 7
    MESS:00:00:01.484475:0: hdmi: HDMI0:EDID error reading EDID block 0 attempt 8
    MESS:00:00:01.491333:0: hdmi: HDMI0:EDID error reading EDID block 0 attempt 9
    MESS:00:00:01.497949:0: hdmi: HDMI0:EDID giving up on reading EDID block 0
    MESS:00:00:01.503563:0: hdmi: HDMI:hdmi_get_state is deprecated, use hdmi_get_display_state instead
    MESS:00:00:01.512308:0: HDMI0: hdmi_pixel_encoding: 162000000
    MESS:00:00:01.518005:0: vec: vec_middleware_power_on: vec_base: 0x7e806000 rev-id 0x00002708 @ vec: 0x7e806100 @ 0x00000420 enc: 0x7e806060 @ 0x00000220 cgmsae: 0x7e80605c @ 0x00000000
    MESS:00:00:01.539405:0: dtb_file 'bcm2708-rpi-zero-w.dtb'
    MESS:00:00:01.543299:0: dtb_file 'bcm2708-rpi-0-w.dtb'
    MESS:00:00:01.548141:0: Failed to load Device Tree file 'bcm2708-rpi-0-w.dtb'
    MESS:00:00:01.555008:0: Failed to open command line file 'cmdline.txt'
    MESS:00:00:01.719713:0: brfs: File read: /mfs/sd/example-pi-zero.bin
    MESS:00:00:01.724374:0: Loading 'example-pi-zero.bin' to 0x8000 size 0x161050
    MESS:00:00:01.731301:0: gpioman: gpioman_get_pin_num: pin EMMC_ENABLE not defined
    MESS:00:00:01.739720:0: uart: Set PL011 baud rate to 103448.300000 Hz
    MESS:00:00:01.746151:0: uart: Baud rate change done...
    MESS:00:00:01.749584:0: uart: Baud ratel1pageTableStart 0x4000
    l1pageTableSize  0x4000
    
    opened by jphastings 16
  • Initial Pi 2 + Pi Zero support

    Initial Pi 2 + Pi Zero support

    Adds basic support for Pi 2 and Pi Zero.

    Pi Zero also requires: https://github.com/f-secure-foundry/tamago-go/pull/2 (Pi Zero does not support the lsb, isb, dmb instructions, so instead does equivalents using MCR-style instructions.

    opened by kenbell 10
  • add Raspberry Pi 1 support

    add Raspberry Pi 1 support

    This PR adds Raspberry Pi 1 (B+) support to Tamago.

    It's an amalgamation of Pi Zero and Pi 2 code.

    Tested on Raspberry Pi 1 B+ v1.2 via https://github.com/prusnak/tamago-example-pi1, which is a slightly modified version of https://github.com/kenbell//tamago-example-pi2 (the only diff is the latest commit)

    opened by prusnak 9
  • relocation target runtime.nanotime not defined

    relocation target runtime.nanotime not defined

    I try to build armory-ums on FreeBSD 11.4 using tamago compiled there (with one test failing at https://github.com/f-secure-foundry/tamago/issues/18):

    [email protected]:~/src/armory-ums % gmake TAMAGO=$HOME/src/tamago-go/bin/go SHELL=/usr/local/bin/bash
    GO_EXTLINK_ENABLED=0 CGO_ENABLED=0 GOOS=tamago GOARM=7 GOARCH=arm /home/saper/src/tamago-go/bin/go build -tags linkramsize -ldflags "-s -w -T 0x80010000  -E _rt0_arm_tamago -R 0x1000 -X '[email protected] on 2020-11-08 19:07:20' -X 'main.Revision=39e2ed4'" -o armory-ums
    # github.com/f-secure-foundry/armory-ums
    runtime.chansend: relocation target runtime.nanotime not defined
    runtime.send: relocation target runtime.nanotime not defined
    runtime.closechan: relocation target runtime.nanotime not defined
    runtime.chanrecv: relocation target runtime.nanotime not defined
    runtime.recv: relocation target runtime.nanotime not defined
    runtime.notetsleepg: relocation target runtime.nanotime not defined
    runtime.checkTimeouts: relocation target runtime.nanotime not defined
    runtime.(*gcControllerState).endCycle: relocation target runtime.nanotime not defined
    runtime.(*gcControllerState).findRunnableGCWorker: relocation target runtime.nanotime not defined
    runtime.pollFractionalWorkerExit: relocation target runtime.nanotime not defined
    runtime.gcStart: relocation target runtime.nanotime not defined
    runtime.gcMarkDone: relocation target runtime.nanotime not defined
    runtime.gcMarkTermination: relocation target runtime.nanotime not defined
    runtime.gcBgMarkWorker: relocation target runtime.nanotime not defined
    runtime.gcAssistAlloc1: relocation target runtime.nanotime not defined
    runtime.gcPaceScavenger: relocation target runtime.nanotime not defined
    runtime.scavengeSleep: relocation target runtime.nanotime not defined
    runtime.usleep: relocation target runtime.nanotime not defined
    runtime.main: relocation target runtime.nanotime not defined
    runtime.forcegchelper: relocation target runtime.nanotime not defined
    runtime.schedinit: relocation target runtime.nanotime not defined
    /home/saper/src/tamago-go/pkg/tool/freebsd_amd64/link: too many errors
    gmake: *** [Makefile:68: armory-ums] Error 2
    [email protected]:~/src/armory-ums % git log -1
    commit 39e2ed4306c66341feefe39ed925be7c10506a6c (HEAD -> master, tag: v20201102, origin/master, origin/HEAD)
    Author: Andrea Barisani <[email protected]>
    Date:   Mon Nov 2 12:27:46 2020 +0100
    
        fix REPORT LUNS response format
    

    tamago-go version:

    Merge: b36fc0cbcb 000ba39230
    Author: Andrej Rosano <[email protected]>
    Date:   Mon Nov 4 10:50:22 2019 +0100
    
        Merge branch 'tamago1.13.4'
    
    opened by saper 5
  • More flexible USB setup flow

    More flexible USB setup flow

    This PR adds a way for users to handle custom USB descriptor requests by adding a new Device struct field called DescriptorSetup, just like the Setup field.

    A new field called Conditional has been added to the Device type.

    This field let the user decide whether a SetupData request should be handled by usb.doSetup() or by other logic defined in Conditiona function logic.

    Both functions are optional, and their presence doesn't impact the logic currently implemented in Tamago's USB stack.

    opened by gsora 5
  • Feature: USB support in Pi drivers

    Feature: USB support in Pi drivers

    Hi, I am looking into writing a HomeKit serial controller for my HVAC system. This would mean I'd use a microcontroller-like device (such as the Pi zero) to talk serial to the HVAC, and present itself as a HomeKit device over ethernet.

    However I read that tamago does not support threads. Would this mean any project using concurrency is automatically Out of Scope? (e.g. using go func)

    https://github.com/brutella/hc

    opened by hazcod 5
  • Raspberry Pi use and the need for U-boot

    Raspberry Pi use and the need for U-boot

    Section Executing and debugging of https://github.com/f-secure-foundry/tamago/blob/master/board/raspberrypi/README.md mentioned U-Boot, but it seems that both examples (Pi Zero and Pi 2) got rid of the U-boot recently.

    Can you please clarify the situation and if the U-Boot is really no longer needed update the README.md to not mention it?

    opened by prusnak 5
  • Improve Raspberry Pi support.

    Improve Raspberry Pi support.

    This PR improves raspberry pi support by:

    • making the code more consistent with the rest of the codebase
    • making the pi specific packages more consistent among themselves
    • removing unused functions or duplicate constants
    • adding missing documentation
    • fixing broken linkx
    • adding required copyright and licensing notes
    opened by abarisani 4
  • imx6: Fix IOMUXC_END value

    imx6: Fix IOMUXC_END value

    The IOMUXC range ends at 0x020e3fff. Fix this from 0x0203ffff and change the range check in NewPad to use && instead of || to detect invalid addresses.

    opened by connojd 3
  • error typechecking package os/signal: /home/saper/src/tamago-go/src/os/signal/signal.go:32:9: undeclared name: numSig (tamago-arm)

    error typechecking package os/signal: /home/saper/src/tamago-go/src/os/signal/signal.go:32:9: undeclared name: numSig (tamago-arm)

    Tried building tamago-go (c117e5d62adf00b99dc5cb9e7e0d3105d87fb09d - current latest) on FreeBSD 11.4 and got this test failure in the end:

    ##### API check
    Error running API checker: exit status 1
    Go version is "go1.13.4", ignoring -next /home/saper/src/tamago-go/api/next.txt
    2020/11/08 18:32:44 error typechecking package os/signal: /home/saper/src/tamago-go/src/os/signal/signal.go:32:9: undeclared name: numSig (tamago-arm)
    exit status 1
    2020/11/08 18:36:14 Failed: exit status 1
    2020/11/08 18:36:14 FAILED
    

    go-1.15.2,1 from FreeBSD standard packages has been used to bootstrap it.

    Full build log: https://gist.github.com/be54c7dfd7a45b7c611a9999f240c528

    opened by saper 3
  • TamaGo fails to initialize on Raspberry Pi 2 (v1.1)

    TamaGo fails to initialize on Raspberry Pi 2 (v1.1)

    I've raised a PR to drop out of HYP mode (default on modern Pi firmware) against tamago-go: https://github.com/f-secure-foundry/tamago-go/pull/1

    With this, and some basic board support for Pi2 I'm able to get a hello world / blinky lights app working.

    opened by kenbell 3
  • Device invariably

    Device invariably "dies" after some time

    Dear Tamago authors,

    I cannot get the device to live further than a minute on tamago. The issue has been reproduced with tamago-go#1.18.1 and tamaga-go#1.18.3 and the latest tamago. The bootloader is loaded using SDP. Since I lack the debugging hardware, it's rather hard to figure the root cause. No panic is emitted. The issue is observed with and without the sd card being inserted.

    Repro

    Code

    func init() {
    	model := imx6.Model()
    	if !imx6.Native {
    		banner += fmt.Sprintf(" - %s %d MHz (emulated)", model, imx6.ARMFreq()/1000000)
    		return
    	}
    	if err := imx6.SetARMFreq(900); err != nil {
    		log.Printf("WARNING: error setting ARM frequency: %v", err)
    	}
    }
    
    func main() {
    	select {}
    }
    
    

    Steps

    1. Plug the device
    2. Flash through SDP
    3. Blue led goes from soft to hard
    4. Wait ~34s
    5. Blue led goes from hard to soft -- device is unresponsive

    Video

    https://drive.google.com/file/d/1_ianaqZ977cbfOYE3gYm8hQSo8weLGW5/view

    Please let me know if I can help with that investigation.

    Thank you!

    opened by marctrem 1
Owner
F-Secure Foundry
F-Secure Hardware Security Team
F-Secure Foundry
The bare metal Go smart card

Authors Andrea Barisani [email protected] | [email protected] Introduction The GoKey application implements a USB smartcard in pure Go

F-Secure Foundry 143 Nov 28, 2022
A Go unikernel running on x86 bare metal

EggOS A Go unikernel running on x86 bare metal Run a single Go applications on x86 bare metal, written entirely in Go (only a small amount of C and so

fanbingxin 2k Dec 4, 2022
A suite of microservices for software-defined networking (SDN) and bare-metal provisioning

M3L is a suite of microservices for software-defined networking (SDN) and bare-metal provisioning, which store their data as Custom Resources in Kubernetes.

Nicklas Frahm 0 Jan 19, 2022
e2d is a command-line tool for deploying and managing etcd clusters, both in the cloud or on bare-metal

e2d is a command-line tool for deploying and managing etcd clusters, both in the cloud or on bare-metal. It also includes e2db, an ORM-like abstraction for working with etcd.

Chris Marshall 2 Aug 23, 2022
A Stable & Secure Tunnel based on KCP with N:M multiplexing and FEC. Available for ARM, MIPS, 386 and AMD64。KCPプロトコルに基づく安全なトンネル。KCP 프로토콜을 기반으로 하는 보안 터널입니다。

Disclaimer: kcptun maintains a single website — github.com/xtaci/kcptun. Any websites other than github.com/xtaci/kcptun are not endorsed by xtaci. Re

xtaci 13.1k Nov 30, 2022
ARM project repository for back-/frontend dev

Ahlam Rahma Mohamed (ARM) Project This repository will include the code base for the ARM project user interface and other helping components. Author M

null 0 Dec 17, 2021
Vippy - A Virtual IP/BGP/IPVS Load-Balancer for Equinix Metal

Vippy - A Virtual IP/BGP/IPVS Load-Balancer for Equinix Metal If I figure out how to make it work.. How it works! The Vippy LB PoC uses BGP/IPVS and E

Daniel Finneran 5 Mar 10, 2022
Terraform-equinix-migration-tool - Tool to migrate code from Equinix Metal terraform provider to Equinix terraform provider

Equinix Terraform Provider Migration Tool This tool targets a terraform working

Equinix 1 Feb 15, 2022
[TOOL, CLI] - Filter and examine Go type structures, interfaces and their transitive dependencies and relationships. Export structural types as TypeScript value object or bare type representations.

typex Examine Go types and their transitive dependencies. Export results as TypeScript value objects (or types) declaration. Installation go get -u gi

Daniel T. Gorski 154 Nov 2, 2022
Fastglue is an opinionated, bare bones wrapper that glues together fasthttp and fasthttprouter to act as a micro HTTP framework.

fastglue Overview fastglue is an opinionated, bare bones wrapper that glues together fasthttp and fasthttprouter to act as a micro HTTP framework. It

Zerodha Technology 71 Jun 14, 2022
Bare Bones Encrypted File Uploading Service

eggnog Basic file uploading service in Go. Files are XOR encrypted server side, and are only accessible with the key. It's not perfect encryption, but

Daniel 1 Nov 15, 2021
Tinyini - Bare-bones Go library for reading INI-like configuration files

tinyini tinyini is a minimalistic library for parsing INI-like configuration files. example configuration file globalkey = globalvalue [section] key

null 0 Jan 10, 2022
Atomic Arbitrage - A base example of a bare implementation of an arbitrage bot

Atomic Arbitrage Atomic Arbitrage is a base example of a bare implementation of

null 133 Nov 23, 2022