Skip to content

Commit

Permalink
feat: add Nano Pi R4S support
Browse files Browse the repository at this point in the history
This commit adds initial support for the Nano Pi
R4S from Friendlyelec. This device is a networking focused
rk3399 based SBC with two 1G ethernet interfaces,
making it perfect for edge or SOHO deployments.

Signed-off-by: Marvin Drees <[email protected]>
Signed-off-by: Noel Georgi <[email protected]>
  • Loading branch information
MDr164 authored and frezbo committed Sep 2, 2022
1 parent 36c1f1d commit cdb6bb2
Show file tree
Hide file tree
Showing 8 changed files with 159 additions and 5 deletions.
1 change: 1 addition & 0 deletions .drone.jsonnet
Original file line number Diff line number Diff line change
Expand Up @@ -584,6 +584,7 @@ local release = {
'_out/metal-bananapi_m64-arm64.img.xz',
'_out/metal-libretech_all_h3_cc_h5-arm64.img.xz',
'_out/metal-jetson_nano-arm64.img.xz',
'_out/metal-nanopi_r4s-arm64.img.xz',
'_out/nocloud-amd64.raw.xz',
'_out/nocloud-arm64.raw.xz',
'_out/openstack-amd64.tar.gz',
Expand Down
4 changes: 2 additions & 2 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -247,14 +247,14 @@ images-essential: image-aws image-gcp image-metal ## Builds only essential image

images: image-aws image-azure image-digital-ocean image-gcp image-hcloud image-metal image-nocloud image-openstack image-oracle image-scaleway image-upcloud image-vmware image-vultr ## Builds all known images (AWS, Azure, DigitalOcean, GCP, HCloud, Metal, NoCloud, Openstack, Oracle, Scaleway, UpCloud, Vultr and VMware).

sbc-%: ## Builds the specified SBC image. Valid options are rpi_4, rock64, bananapi_m64, libretech_all_h3_cc_h5, rockpi_4, rockpi_4c, pine64 and jetson_nano (e.g. sbc-rpi_4)
sbc-%: ## Builds the specified SBC image. Valid options are rpi_4, rock64, bananapi_m64, libretech_all_h3_cc_h5, rockpi_4, rockpi_4c, pine64, jetson_nano and nanopi_r4s (e.g. sbc-rpi_4)
@docker pull $(REGISTRY_AND_USERNAME)/imager:$(IMAGE_TAG)
@ . ./hack/imager.sh && \
tmpdir=$$(prepare_extension_images linux/arm64 $(IMAGER_SYSTEM_EXTENSIONS)) && \
docker run --rm -v /dev:/dev -v "$${tmpdir}:/system/extensions" --privileged $(REGISTRY_AND_USERNAME)/imager:$(IMAGE_TAG) image --platform metal --arch arm64 --board $* --tar-to-stdout $(IMAGER_ARGS) | tar xz -C $(ARTIFACTS) ; \
rm -rf "$${tmpdir}"

sbcs: sbc-rpi_4 sbc-rock64 sbc-bananapi_m64 sbc-libretech_all_h3_cc_h5 sbc-rockpi_4 sbc-rockpi_4c sbc-pine64 sbc-jetson_nano ## Builds all known SBC images (Raspberry Pi 4 Model B, Rock64, Banana Pi M64, Radxa ROCK Pi 4, Radxa ROCK Pi 4c, pine64, Libre Computer Board ALL-H3-CC and Jetson Nano).
sbcs: sbc-rpi_4 sbc-rock64 sbc-bananapi_m64 sbc-libretech_all_h3_cc_h5 sbc-rockpi_4 sbc-rockpi_4c sbc-pine64 sbc-jetson_nano sbc-nanopi_r4s ## Builds all known SBC images (Raspberry Pi 4 Model B, Rock64, Banana Pi M64, Radxa ROCK Pi 4, Radxa ROCK Pi 4c, Pine64, Libre Computer Board ALL-H3-CC, Jetson Nano and Nano Pi R4S).

.PHONY: iso
iso: ## Builds the ISO and outputs it to the artifact directory.
Expand Down
4 changes: 2 additions & 2 deletions go.work.sum
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ github.com/asaskevich/govalidator v0.0.0-20190424111038-f61b66f89f4a h1:idn718Q4
github.com/aws/aws-sdk-go v1.44.19/go.mod h1:y4AeaBuwd2Lk+GepC1E9v0qOiTws0MIWAX4oIKwKHZo=
github.com/aws/aws-sdk-go v1.44.56 h1:bT+lExwagH7djxb6InKUVkEKGPAj5aAPnV85/m1fKro=
github.com/aws/aws-sdk-go v1.44.56/go.mod h1:y4AeaBuwd2Lk+GepC1E9v0qOiTws0MIWAX4oIKwKHZo=
github.com/benbjohnson/clock v1.1.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA=
github.com/bgentry/speakeasy v0.1.0 h1:ByYyxL9InA1OWqxJqqp2A5pYHUrCiAL6K3J+LKSsQkY=
github.com/bitly/go-simplejson v0.5.0 h1:6IH+V8/tVMab511d5bn4M7EwGXZf9Hj6i2xSwkNEM+Y=
github.com/bits-and-blooms/bitset v1.2.0 h1:Kn4yilvwNtMACtf1eYDlG8H77R07mZSPbMjLyS07ChA=
Expand Down Expand Up @@ -72,8 +73,6 @@ github.com/coreos/etcd v3.3.13+incompatible h1:8F3hqu9fGYLBifCmRCJsicFqDx/D68Rt3
github.com/coreos/go-oidc v2.1.0+incompatible h1:sdJrfw8akMnCuUlaZU3tE/uYXFgfqom8DBE9so9EBsM=
github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e h1:Wf6HqHfScWJN9/ZjdUKyjop4mf3Qdd+1TvvltAvM3m8=
github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f h1:lBNOc5arjvs8E5mO2tbpBpLoyyu8B6e44T7hJy6potg=
github.com/cosi-project/runtime v0.2.0-alpha.0 h1:IuwfSYXvfvit7GNaITqjr4i4FRG5cG5wXA2x8EpmcNc=
github.com/cosi-project/runtime v0.2.0-alpha.0/go.mod h1:cJeaTRT6lL6TUNLZoKiF7ftSv92ANacY6g/R6potnMA=
github.com/cpuguy83/go-md2man v1.0.10 h1:BSKMNlYxDvnunlTymqtgONjNnaRV1sTpcovwwjF22jk=
github.com/cpuguy83/go-md2man/v2 v2.0.1/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=
github.com/cyphar/filepath-securejoin v0.2.3 h1:YX6ebbZCZP7VkM3scTTokDgBL2TY741X51MTk3ycuNI=
Expand Down Expand Up @@ -261,6 +260,7 @@ go.opentelemetry.io/otel/sdk v1.3.0 h1:3278edCoH89MEJ0Ky8WQXVmDQv3FX4ZJ3Pp+9fJre
go.opentelemetry.io/otel/sdk/export/metric v0.20.0 h1:c5VRjxCXdQlx1HjzwGdQHzZaVI82b5EbBgOu2ljD92g=
go.opentelemetry.io/otel/sdk/metric v0.20.0 h1:7ao1wpzHRVKf0OQ7GIxiQJA6X7DLX9o14gmVon7mMK8=
go.opentelemetry.io/proto/otlp v0.11.0 h1:cLDgIBTf4lLOlztkhzAEdQsJ4Lj+i5Wc9k6Nn0K1VyU=
go.uber.org/goleak v1.1.11/go.mod h1:cwTWslyiVhfpKIDGSZEM2HlOvcqm+tG4zioyIeLoqMQ=
go.uber.org/goleak v1.1.12/go.mod h1:cwTWslyiVhfpKIDGSZEM2HlOvcqm+tG4zioyIeLoqMQ=
go.uber.org/multierr v1.7.0/go.mod h1:7EAYxJLBy9rStEaz58O2t4Uvip6FSURkq8/ppBp95ak=
golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6 h1:QE6XYQK6naiK1EPAe1g/ILLxN5RBoH5xkJk3CqlMI/Y=
Expand Down
3 changes: 3 additions & 0 deletions internal/app/machined/pkg/runtime/v1alpha1/board/board.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import (
bananapim64 "github.com/talos-systems/talos/internal/app/machined/pkg/runtime/v1alpha1/board/bananapi_m64"
jetsonnano "github.com/talos-systems/talos/internal/app/machined/pkg/runtime/v1alpha1/board/jetson_nano"
libretechallh3cch5 "github.com/talos-systems/talos/internal/app/machined/pkg/runtime/v1alpha1/board/libretech_all_h3_cc_h5"
nanopir4s "github.com/talos-systems/talos/internal/app/machined/pkg/runtime/v1alpha1/board/nanopi_r4s"
"github.com/talos-systems/talos/internal/app/machined/pkg/runtime/v1alpha1/board/pine64"
"github.com/talos-systems/talos/internal/app/machined/pkg/runtime/v1alpha1/board/rock64"
rockpi4 "github.com/talos-systems/talos/internal/app/machined/pkg/runtime/v1alpha1/board/rockpi4"
Expand Down Expand Up @@ -65,6 +66,8 @@ func newBoard(board string) (b runtime.Board, err error) {
b = &rockpi4c.Rockpi4c{}
case constants.BoardJetsonNano:
b = &jetsonnano.JetsonNano{}
case constants.BoardNanoPiR4S:
b = &nanopir4s.NanoPiR4S{}
default:
return nil, fmt.Errorf("unsupported board: %q", board)
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.

package nanopir4s

import (
"fmt"
"log"
"os"
"path/filepath"

"github.com/talos-systems/go-procfs/procfs"
"golang.org/x/sys/unix"

"github.com/talos-systems/talos/internal/app/machined/pkg/runtime"
"github.com/talos-systems/talos/pkg/copy"
"github.com/talos-systems/talos/pkg/machinery/constants"
)

var (
bin = fmt.Sprintf("/usr/install/arm64/u-boot/%s/u-boot-rockchip.bin", constants.BoardNanoPiR4S)
off int64 = 512 * 64
dtb = "/dtb/rockchip/rk3399-nanopi-r4s.dtb"
)

// NanoPiR4S represents the Friendlyelec Nano Pi R4S board.
//
// Reference: https://wiki.friendlyelec.com/wiki/index.php/NanoPi_R4S
type NanoPiR4S struct{}

// Name implements the runtime.Board.
func (n *NanoPiR4S) Name() string {
return constants.BoardNanoPiR4S
}

// Install implements the runtime.Board.
func (n *NanoPiR4S) Install(disk string) (err error) {
file, err := os.OpenFile(disk, os.O_RDWR|unix.O_CLOEXEC, 0o666)
if err != nil {
return err
}

defer file.Close() //nolint:errcheck

uboot, err := os.ReadFile(bin)
if err != nil {
return err
}

log.Printf("writing %s at offset %d", bin, off)

amount, err := file.WriteAt(uboot, off)
if err != nil {
return err
}

log.Printf("wrote %d bytes", amount)

// NB: In the case that the block device is a loopback device, we sync here
// to esure that the file is written before the loopback device is
// unmounted.
if err := file.Sync(); err != nil {
return err
}

src := "/usr/install/arm64" + dtb
dst := "/boot/EFI" + dtb

if err := os.MkdirAll(filepath.Dir(dst), 0o600); err != nil {
return err
}

return copy.File(src, dst)
}

// KernelArgs implements the runtime.Board.
func (n *NanoPiR4S) KernelArgs() procfs.Parameters {
return []*procfs.Parameter{
procfs.NewParameter("console").Append("tty0").Append("ttyS2,1500000n8"),
procfs.NewParameter("sysctl.kernel.kexec_load_disabled").Append("1"),
}
}

// PartitionOptions implements the runtime.Board.
func (n *NanoPiR4S) PartitionOptions() *runtime.PartitionOptions {
return &runtime.PartitionOptions{PartitionsOffset: 2048 * 10}
}
3 changes: 3 additions & 0 deletions pkg/machinery/constants/constants.go
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,9 @@ const (
// BoardRockpi4c is the name of the Radxa Rock pi 4 revision C.
BoardRockpi4c = "rockpi_4c"

// BoardNanoPiR4S is the name of the Friendlyelec Nano Pi R4S.
BoardNanoPiR4S = "nanopi_r4s"

// KernelParamHostname is the kernel parameter name for specifying the
// hostname.
KernelParamHostname = "talos.hostname"
Expand Down
2 changes: 1 addition & 1 deletion website/content/v1.3/introduction/support-matrix.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ description: "Table of supported Talos Linux versions and respective platforms."
| - cloud | AWS, GCP, Azure, Digital Ocean, Hetzner, OpenStack, Oracle Cloud, Scaleway, Vultr, Upcloud | AWS, GCP, Azure, Digital Ocean, Hetzner, OpenStack, Oracle Cloud, Scaleway, Vultr, Upcloud |
| - bare metal | x86: BIOS, UEFI; arm64: UEFI; boot: ISO, PXE, disk image | x86: BIOS, UEFI; arm64: UEFI; boot: ISO, PXE, disk image |
| - virtualized | VMware, Hyper-V, KVM, Proxmox, Xen | VMware, Hyper-V, KVM, Proxmox, Xen |
| - SBCs | Banana Pi M64, Jetson Nano, Libre Computer Board ALL-H3-CC, Pine64, Pine64 Rock64, Radxa ROCK Pi 4c, Raspberry Pi 4B | Banana Pi M64, Jetson Nano, Libre Computer Board ALL-H3-CC, Pine64, Pine64 Rock64, Radxa ROCK Pi 4c, Raspberry Pi 4B |
| - SBCs | Banana Pi M64, Jetson Nano, Libre Computer Board ALL-H3-CC, Nano Pi R4S, Pine64, Pine64 Rock64, Radxa ROCK Pi 4c, Raspberry Pi 4B | Banana Pi M64, Jetson Nano, Libre Computer Board ALL-H3-CC, Pine64, Pine64 Rock64, Radxa ROCK Pi 4c, Raspberry Pi 4B |
| - local | Docker, QEMU | Docker, QEMU |
| **Cluster API** | | |
| [CAPI Bootstrap Provider Talos](https://github.com/siderolabs/cluster-api-bootstrap-provider-talos) | >= 0.5.5 | >= 0.5.5 |
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
---
title: "Friendlyelec Nano PI R4S"
description: "Installing Talos on a Nano PI R4S SBC using raw disk image."
aliases:
- ../../../single-board-computers/nanopi_r4s
---

## Prerequisites

You will need

- `talosctl`
- an SD card

Download the latest `talosctl`.

```bash
curl -Lo /usr/local/bin/talosctl https://github.com/siderolabs/talos/releases/download/{{< release >}}/talosctl-$(uname -s | tr "[:upper:]" "[:lower:]")-amd64
chmod +x /usr/local/bin/talosctl
```

## Download the Image

Download the image and decompress it:

```bash
curl -LO https://github.com/siderolabs/talos/releases/download/{{< release >}}/metal-rockpi_4-arm64.img.xz
xz -d metal-nanopi_r4s-arm64.img.xz
```

## Writing the Image

The path to your SD card can be found using `fdisk` on Linux or `diskutil` on macOS.
In this example, we will assume `/dev/mmcblk0`.

Now `dd` the image to your SD card:

```bash
sudo dd if=metal-nanopi_r4s-arm64.img of=/dev/mmcblk0 conv=fsync bs=4M
```

## Bootstrapping the Node

Insert the SD card to your board, turn it on and wait for the console to show you the instructions for bootstrapping the node.
Following the instructions in the console output to connect to the interactive installer:

```bash
talosctl apply-config --insecure --mode=interactive --nodes <node IP or DNS name>
```

Once the interactive installation is applied, the cluster will form and you can then use `kubectl`.

## Retrieve the `kubeconfig`

Retrieve the admin `kubeconfig` by running:

```bash
talosctl kubeconfig
```

0 comments on commit cdb6bb2

Please sign in to comment.