mirror of
https://github.com/kernelkit/infix.git
synced 2026-07-23 17:33:01 +02:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
ea315bdb10 | ||
|
|
3f23aa92be | ||
|
|
4984d5ac7f | ||
|
|
d945bb703b | ||
|
|
b047bd2a52 | ||
|
|
efc97f6566 | ||
|
|
39f9c1e166 | ||
|
|
f81de1d3ec | ||
|
|
e7fabfc37d | ||
|
|
956e604dcb | ||
|
|
9d3669b647 | ||
|
|
17a3ca58a0 | ||
|
|
7e2d0cf2f8 | ||
|
|
f5ad6bc9ea | ||
|
|
1698ad6197 | ||
|
|
b3e158fce5 | ||
|
|
5762c75727 | ||
|
|
bb5240e48b | ||
|
|
002c7791ec | ||
|
|
147ffe602f | ||
|
|
d08c3416ec | ||
|
|
c4f24caa94 | ||
|
|
19a0151f68 | ||
|
|
bbbb84fba7 | ||
|
|
ed4fe58fda | ||
|
|
d7812c2ea5 | ||
|
|
ffa23fb9be | ||
|
|
4cf9fd02db | ||
|
|
a5c807abe0 | ||
|
|
b5a292d7dd | ||
|
|
4522d9f217 | ||
|
|
c559b8f2e0 | ||
|
|
4a31df1059 | ||
|
|
965906e2ff | ||
|
|
bcc444f0fe | ||
|
|
949f43853d | ||
|
|
e63275d3a1 | ||
|
|
2abee79c18 | ||
|
|
a844ba7d8c | ||
|
|
e8c9c70e37 | ||
|
|
924567f30b | ||
|
|
0e21dc894b | ||
|
|
f187fee89b | ||
|
|
845e7c13fe | ||
|
|
8c9e36ba5d | ||
|
|
a1a02f2727 | ||
|
|
3ffbef74a8 | ||
|
|
34805dca65 | ||
|
|
8b95c10e39 | ||
|
|
16e72e8741 | ||
|
|
cf591c9813 | ||
|
|
51b0488e66 | ||
|
|
4aa0ab73b3 | ||
|
|
ef7ed89443 | ||
|
|
84860e313f | ||
|
|
0e590e9cbf | ||
|
|
8d647a8e43 | ||
|
|
6fee172c85 | ||
|
|
5c0a4c099e | ||
|
|
3fe7fa5548 | ||
|
|
2120709b68 | ||
|
|
13a50c8b0c | ||
|
|
48718d764b | ||
|
|
ae8a93c4cf | ||
|
|
cbde057bf8 | ||
|
|
f3e058f203 | ||
|
|
c16eeaa9f4 | ||
|
|
681251f899 | ||
|
|
eb1763d49f | ||
|
|
867239c7b8 | ||
|
|
0f1aa30574 | ||
|
|
89146b739a | ||
|
|
7bcbd3c51b | ||
|
|
91374a1155 | ||
|
|
3966f8ed0e | ||
|
|
f708f9b1ed | ||
|
|
055c8dd1ae | ||
|
|
fd4cda35b5 | ||
|
|
a7a630e0d9 | ||
|
|
0c8ce332d1 | ||
|
|
3d088f3e2b | ||
|
|
b691868a83 | ||
|
|
d1659dbbc1 | ||
|
|
8973dc488b | ||
|
|
f71bb73375 | ||
|
|
0c11cea07b | ||
|
|
65b674855a | ||
|
|
71ec4fa220 |
@@ -0,0 +1,41 @@
|
||||
name: 'Restore Build Caches'
|
||||
description: 'Restore dl/ and .ccache/ caches for Buildroot builds'
|
||||
inputs:
|
||||
target:
|
||||
description: 'Build target for cache key differentiation'
|
||||
required: true
|
||||
dl-prefix:
|
||||
description: 'Prefix for dl/ cache key (e.g., "dl", "dl-boot")'
|
||||
required: false
|
||||
default: 'dl'
|
||||
ccache-prefix:
|
||||
description: 'Prefix for .ccache/ cache key (e.g., "ccache", "ccache-boot")'
|
||||
required: false
|
||||
default: 'ccache'
|
||||
enabled:
|
||||
description: 'Set to false to skip cache restoration'
|
||||
required: false
|
||||
default: 'true'
|
||||
runs:
|
||||
using: 'composite'
|
||||
steps:
|
||||
- name: Restore Cache of dl/
|
||||
if: ${{ inputs.enabled == 'true' }}
|
||||
uses: actions/cache@v4
|
||||
with:
|
||||
path: dl/
|
||||
key: ${{ inputs.dl-prefix }}-${{ hashFiles('.git/modules/buildroot/HEAD', 'configs/*', 'package/*/*.hash') }}
|
||||
restore-keys: |
|
||||
${{ inputs.dl-prefix }}-
|
||||
dl-
|
||||
|
||||
- name: Restore Cache of .ccache/
|
||||
if: ${{ inputs.enabled == 'true' }}
|
||||
uses: actions/cache@v4
|
||||
with:
|
||||
path: .ccache/
|
||||
key: ${{ inputs.ccache-prefix }}-${{ inputs.target }}-${{ hashFiles('.git/modules/buildroot/HEAD', 'package/*/*.hash') }}
|
||||
restore-keys: |
|
||||
${{ inputs.ccache-prefix }}-${{ inputs.target }}-
|
||||
${{ inputs.ccache-prefix }}-
|
||||
ccache-
|
||||
@@ -0,0 +1,15 @@
|
||||
name: 'Podman Cleanup'
|
||||
description: 'Clean up stale podman state from previous runs'
|
||||
runs:
|
||||
using: 'composite'
|
||||
steps:
|
||||
- name: Cleanup podman state
|
||||
shell: bash
|
||||
run: |
|
||||
set -x
|
||||
podman ps -a || true
|
||||
podman stop -a || true
|
||||
podman rm -a -f || true
|
||||
podman volume prune -f || true
|
||||
podman system prune -a -f || true
|
||||
podman system migrate || true
|
||||
@@ -22,7 +22,10 @@ jobs:
|
||||
- cn9130_crb_boot
|
||||
- fireant_boot
|
||||
- nanopi_r2s_boot
|
||||
- rpi2_boot
|
||||
- rpi64_boot
|
||||
- sama7g54_ek_emmc_boot
|
||||
- sama7g54_ek_sd_boot
|
||||
env:
|
||||
MAKEFLAGS: -j5
|
||||
steps:
|
||||
@@ -63,24 +66,11 @@ jobs:
|
||||
|
||||
echo "Building ${defconfig}_defconfig, version ${version}-${rev}, artifact ${archive} ..."
|
||||
|
||||
- name: Restore Cache of dl/
|
||||
uses: actions/cache@v4
|
||||
- uses: ./.github/actions/cache-restore
|
||||
with:
|
||||
path: dl/
|
||||
key: dl-boot-${{ hashFiles('.git/modules/buildroot/HEAD', 'configs/*', 'package/*/*.hash') }}
|
||||
restore-keys: |
|
||||
dl-boot-
|
||||
dl-
|
||||
|
||||
- name: Restore Cache of .ccache/
|
||||
uses: actions/cache@v4
|
||||
with:
|
||||
path: .ccache/
|
||||
key: ccache-boot-${{ matrix.defconfig }}-${{ hashFiles('.git/modules/buildroot/HEAD', 'package/*/*.hash') }}
|
||||
restore-keys: |
|
||||
ccache-boot-${{ matrix.defconfig }}-
|
||||
ccache-boot-
|
||||
ccache-
|
||||
target: ${{ matrix.defconfig }}
|
||||
dl-prefix: dl-boot
|
||||
ccache-prefix: ccache-boot
|
||||
|
||||
- name: Configure ${{ matrix.defconfig }}_defconfig
|
||||
run: |
|
||||
|
||||
@@ -8,9 +8,11 @@ on:
|
||||
type: choice
|
||||
required: true
|
||||
options:
|
||||
- raspberrypi-rpi2
|
||||
- raspberrypi-rpi64
|
||||
- bananapi-bpi-r3
|
||||
- friendlyarm-nanopi-r2s
|
||||
- microchip-sama7g54-ek
|
||||
default: 'raspberrypi-rpi64'
|
||||
|
||||
jobs:
|
||||
@@ -49,6 +51,11 @@ jobs:
|
||||
- name: Set bootloader and target based on board
|
||||
run: |
|
||||
case "${{ inputs.board }}" in
|
||||
raspberrypi-rpi2)
|
||||
echo "BOOTLOADER=rpi2-boot" >> $GITHUB_ENV
|
||||
echo "ARCH=arm" >> $GITHUB_ENV
|
||||
echo "BUILD_EMMC=false" >> $GITHUB_ENV
|
||||
;;
|
||||
raspberrypi-rpi64)
|
||||
echo "BOOTLOADER=rpi64-boot" >> $GITHUB_ENV
|
||||
echo "ARCH=aarch64" >> $GITHUB_ENV
|
||||
@@ -65,6 +72,12 @@ jobs:
|
||||
echo "ARCH=aarch64" >> $GITHUB_ENV
|
||||
echo "BUILD_EMMC=false" >> $GITHUB_ENV
|
||||
;;
|
||||
microchip-sama7g54-ek)
|
||||
echo "BOOTLOADER_SD=sama7g54-ek-sd-boot" >> $GITHUB_ENV
|
||||
echo "BOOTLOADER_EMMC=sama7g54-ek-emmc-boot" >> $GITHUB_ENV
|
||||
echo "ARCH=arm" >> $GITHUB_ENV
|
||||
echo "BUILD_EMMC=true" >> $GITHUB_ENV
|
||||
;;
|
||||
*)
|
||||
echo "Error: Unknown board ${{ inputs.board }}"
|
||||
exit 1
|
||||
|
||||
@@ -20,24 +20,16 @@ jobs:
|
||||
runs-on: [self-hosted, release]
|
||||
strategy:
|
||||
matrix:
|
||||
target: [aarch64, x86_64]
|
||||
target: [aarch64, arm, x86_64]
|
||||
fail-fast: false
|
||||
steps:
|
||||
- name: Cleanup podman state
|
||||
run: |
|
||||
set -x
|
||||
podman ps -a || true
|
||||
podman stop -a || true
|
||||
podman rm -a -f || true
|
||||
podman volume prune -f || true
|
||||
podman system prune -a -f || true
|
||||
podman system migrate || true
|
||||
|
||||
- uses: actions/checkout@v4
|
||||
with:
|
||||
clean: true
|
||||
submodules: recursive
|
||||
|
||||
- uses: ./.github/actions/podman-cleanup
|
||||
|
||||
- name: Set Release Variables
|
||||
id: vars
|
||||
run: |
|
||||
@@ -48,24 +40,10 @@ jobs:
|
||||
echo "dir=infix-$target" >> $GITHUB_OUTPUT
|
||||
echo "tgz=infix-$target.tar.gz" >> $GITHUB_OUTPUT
|
||||
|
||||
- name: Restore Cache of dl/
|
||||
if: ${{ inputs.use_cache }}
|
||||
uses: actions/cache@v4
|
||||
- uses: ./.github/actions/cache-restore
|
||||
with:
|
||||
path: dl/
|
||||
key: dl-${{ hashFiles('.git/modules/buildroot/HEAD', 'configs/*', 'package/*/*.hash') }}
|
||||
restore-keys: |
|
||||
dl-
|
||||
|
||||
- name: Restore Cache of .ccache/
|
||||
if: ${{ inputs.use_cache }}
|
||||
uses: actions/cache@v4
|
||||
with:
|
||||
path: .ccache/
|
||||
key: ccache-${{ matrix.target }}-${{ hashFiles('.git/modules/buildroot/HEAD', 'package/*/*.hash') }}
|
||||
restore-keys: |
|
||||
ccache-${{ matrix.target }}-
|
||||
ccache-
|
||||
target: ${{ matrix.target }}
|
||||
enabled: ${{ inputs.use_cache }}
|
||||
|
||||
- name: Configure & Build
|
||||
env:
|
||||
|
||||
@@ -78,15 +78,6 @@ jobs:
|
||||
rm -rf ./* || true
|
||||
rm -rf ./.??* || true
|
||||
ls -la ./
|
||||
- name: Cleanup podman state
|
||||
run: |
|
||||
set -x
|
||||
podman ps -a || true
|
||||
podman stop -a || true
|
||||
podman rm -a -f || true
|
||||
podman volume prune -f || true
|
||||
podman system prune -a -f || true
|
||||
podman system migrate || true
|
||||
|
||||
- name: Checkout infix repo
|
||||
uses: actions/checkout@v4
|
||||
@@ -98,6 +89,8 @@ jobs:
|
||||
submodules: recursive
|
||||
token: ${{ secrets.CHECKOUT_TOKEN || github.token }}
|
||||
|
||||
- uses: ./.github/actions/podman-cleanup
|
||||
|
||||
- name: Run pre-build script
|
||||
if: ${{ inputs.pre_build_script != '' }}
|
||||
run: |
|
||||
@@ -127,22 +120,9 @@ jobs:
|
||||
echo "tgz=${name}-${target}.tar.gz" >> $GITHUB_OUTPUT
|
||||
echo "Building target ${target}_defconfig"
|
||||
|
||||
- name: Restore Cache of dl/
|
||||
uses: actions/cache@v4
|
||||
- uses: ./.github/actions/cache-restore
|
||||
with:
|
||||
path: dl/
|
||||
key: dl-${{ hashFiles('.git/modules/buildroot/HEAD', 'configs/*', 'package/*/*.hash') }}
|
||||
restore-keys: |
|
||||
dl-
|
||||
|
||||
- name: Restore Cache of .ccache/
|
||||
uses: actions/cache@v4
|
||||
with:
|
||||
path: .ccache/
|
||||
key: ccache-${{ env.TARGET }}-${{ hashFiles('.git/modules/buildroot/HEAD', 'package/*/*.hash') }}
|
||||
restore-keys: |
|
||||
ccache-${{ env.TARGET }}-
|
||||
ccache-
|
||||
target: ${{ env.TARGET }}
|
||||
|
||||
- name: Configure ${{ env.TARGET }}
|
||||
run: |
|
||||
@@ -153,10 +133,6 @@ jobs:
|
||||
podman rm -af || true
|
||||
pkill -9 -f rootlessport || true
|
||||
|
||||
- name: Unit Test ${{ env.TARGET }}
|
||||
run: |
|
||||
make test-unit
|
||||
|
||||
- name: Prepare parallel build
|
||||
id: parallel
|
||||
run: |
|
||||
|
||||
@@ -45,22 +45,10 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- name: Restore Cache of dl/
|
||||
uses: actions/cache@v4
|
||||
- uses: ./.github/actions/cache-restore
|
||||
with:
|
||||
path: dl/
|
||||
key: dl-netconf-${{ hashFiles('.git/modules/buildroot/HEAD', 'configs/*', 'package/*/*.hash') }}
|
||||
restore-keys: |
|
||||
dl-netconf-
|
||||
dl-
|
||||
- name: Restore Cache of .ccache/
|
||||
uses: actions/cache@v4
|
||||
with:
|
||||
path: .ccache/
|
||||
key: ccache-x86_64-${{ hashFiles('.git/modules/buildroot/HEAD', 'package/*/*.hash') }}
|
||||
restore-keys: |
|
||||
ccache-x86_64-
|
||||
ccache-
|
||||
target: x86_64
|
||||
dl-prefix: dl-netconf
|
||||
- name: Disk inventory (2/2) ...
|
||||
run: |
|
||||
echo "df -h ========================================================================="
|
||||
|
||||
@@ -48,20 +48,12 @@ jobs:
|
||||
contents: write
|
||||
discussions: write
|
||||
steps:
|
||||
- name: Cleanup podman state
|
||||
run: |
|
||||
set -x
|
||||
podman ps -a || true
|
||||
podman stop -a || true
|
||||
podman rm -a -f || true
|
||||
podman volume prune -f || true
|
||||
podman system prune -a -f || true
|
||||
podman system migrate || true
|
||||
|
||||
- uses: actions/checkout@v4
|
||||
with:
|
||||
submodules: 'true'
|
||||
|
||||
- uses: ./.github/actions/podman-cleanup
|
||||
|
||||
- name: Set Release Variables
|
||||
id: rel
|
||||
run: |
|
||||
|
||||
@@ -60,16 +60,6 @@ jobs:
|
||||
name: Regression Test ${{ github.event_name == 'workflow_dispatch' && github.event.inputs.name || inputs.name }} ${{ github.event_name == 'workflow_dispatch' && github.event.inputs.target || inputs.target }}
|
||||
runs-on: [self-hosted, regression]
|
||||
steps:
|
||||
- name: Cleanup podman state
|
||||
run: |
|
||||
set -x
|
||||
podman ps -a || true
|
||||
podman stop -a || true
|
||||
podman rm -a -f || true
|
||||
podman volume prune -f || true
|
||||
podman system prune -a -f || true
|
||||
podman system migrate || true
|
||||
|
||||
- name: Checkout infix repo
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
@@ -80,6 +70,8 @@ jobs:
|
||||
submodules: recursive
|
||||
token: ${{ secrets.CHECKOUT_TOKEN || github.token }}
|
||||
|
||||
- uses: ./.github/actions/podman-cleanup
|
||||
|
||||
- name: Run pre-test script
|
||||
if: ${{ inputs.pre_test_script != '' }}
|
||||
run: |
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
name: Kernelkit Trigger
|
||||
name: CI
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
@@ -28,6 +28,7 @@ jobs:
|
||||
outputs:
|
||||
x86_64_target: ${{ steps.set-targets.outputs.x86_64_target }}
|
||||
aarch64_target: ${{ steps.set-targets.outputs.aarch64_target }}
|
||||
arm_target: ${{ steps.set-targets.outputs.arm_target }}
|
||||
steps:
|
||||
- run: |
|
||||
echo "Triggering build, logging meta data ..."
|
||||
@@ -43,25 +44,40 @@ jobs:
|
||||
| grep -q "ci:main"; then
|
||||
echo "x86_64_target=x86_64_minimal" >> $GITHUB_OUTPUT
|
||||
echo "aarch64_target=aarch64_minimal" >> $GITHUB_OUTPUT
|
||||
echo "arm_target=arm_minimal" >> $GITHUB_OUTPUT
|
||||
else
|
||||
echo "x86_64_target=x86_64" >> $GITHUB_OUTPUT
|
||||
echo "aarch64_target=aarch64" >> $GITHUB_OUTPUT
|
||||
echo "arm_target=arm" >> $GITHUB_OUTPUT
|
||||
fi
|
||||
unit-test:
|
||||
needs: check-trigger
|
||||
uses: ./.github/workflows/unit-test.yml
|
||||
with:
|
||||
name: "infix"
|
||||
target: ${{ needs.check-trigger.outputs.x86_64_target }}
|
||||
|
||||
build-x86_64:
|
||||
needs: check-trigger
|
||||
needs: [check-trigger, unit-test]
|
||||
uses: ./.github/workflows/build.yml
|
||||
with:
|
||||
name: "infix"
|
||||
target: ${{ needs.check-trigger.outputs.x86_64_target }}
|
||||
|
||||
build-aarch64:
|
||||
needs: check-trigger
|
||||
needs: [check-trigger, unit-test]
|
||||
uses: ./.github/workflows/build.yml
|
||||
with:
|
||||
name: "infix"
|
||||
target: ${{ needs.check-trigger.outputs.aarch64_target }}
|
||||
|
||||
build-arm:
|
||||
needs: [check-trigger, unit-test]
|
||||
uses: ./.github/workflows/build.yml
|
||||
with:
|
||||
name: "infix"
|
||||
target: ${{ needs.check-trigger.outputs.arm_target }}
|
||||
|
||||
test-run-x86_64:
|
||||
needs: [check-trigger, build-x86_64]
|
||||
uses: ./.github/workflows/test.yml
|
||||
|
||||
@@ -0,0 +1,116 @@
|
||||
name: unit-test
|
||||
|
||||
on:
|
||||
workflow_dispatch:
|
||||
inputs:
|
||||
target:
|
||||
description: "Build target (e.g. aarch64 or aarch64_minimal)"
|
||||
default: "x86_64"
|
||||
type: string
|
||||
parallel:
|
||||
description: 'Massive parallel build of each image'
|
||||
default: true
|
||||
type: boolean
|
||||
name:
|
||||
description: "Name (for spin overrides)"
|
||||
default: "infix"
|
||||
type: string
|
||||
infix_repo:
|
||||
description: 'Repo to checkout (for spin overrides)'
|
||||
default: kernelkit/infix
|
||||
type: string
|
||||
infix_branch:
|
||||
description: 'Branch/tag/commit to checkout (for spin overrides)'
|
||||
default: ''
|
||||
type: string
|
||||
|
||||
workflow_call:
|
||||
inputs:
|
||||
target:
|
||||
required: true
|
||||
type: string
|
||||
name:
|
||||
required: true
|
||||
type: string
|
||||
infix_repo:
|
||||
required: false
|
||||
type: string
|
||||
default: kernelkit/infix
|
||||
infix_branch:
|
||||
required: false
|
||||
type: string
|
||||
default: ''
|
||||
description: 'Branch/tag/commit to checkout (for spin overrides). Defaults to github.ref if not specified'
|
||||
parallel:
|
||||
required: false
|
||||
type: boolean
|
||||
default: true
|
||||
pre_build_script:
|
||||
required: false
|
||||
type: string
|
||||
default: ''
|
||||
description: 'Optional script to run after checkout (for spin customization)'
|
||||
secrets:
|
||||
CHECKOUT_TOKEN:
|
||||
required: false
|
||||
description: 'Token for cross-repository access'
|
||||
|
||||
env:
|
||||
NAME: ${{ github.event_name == 'workflow_dispatch' && github.event.inputs.name || inputs.name }}
|
||||
TARGET: ${{ github.event_name == 'workflow_dispatch' && github.event.inputs.target || inputs.target }}
|
||||
INFIX_REPO: ${{ github.event_name == 'workflow_dispatch' && github.event.inputs.infix_repo || inputs.infix_repo }}
|
||||
INFIX_BRANCH: ${{ github.event_name == 'workflow_dispatch' && github.event.inputs.infix_branch || inputs.infix_branch }}
|
||||
|
||||
jobs:
|
||||
unit-tests:
|
||||
name: Build ${{ github.event_name == 'workflow_dispatch' && github.event.inputs.name || inputs.name }} ${{ github.event_name == 'workflow_dispatch' && github.event.inputs.target || inputs.target }}
|
||||
runs-on: [ self-hosted, latest ]
|
||||
env:
|
||||
PARALLEL: ${{ github.event_name == 'workflow_dispatch' && github.event.inputs.parallel == 'true' || github.event_name != 'workflow_dispatch' && inputs.parallel == true }}
|
||||
strategy:
|
||||
fail-fast: false
|
||||
steps:
|
||||
- name: Cleanup Build Folder
|
||||
run: |
|
||||
ls -la ./
|
||||
rm -rf ./* || true
|
||||
rm -rf ./.??* || true
|
||||
ls -la ./
|
||||
|
||||
- name: Checkout infix repo
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
repository: ${{ env.INFIX_REPO }}
|
||||
ref: ${{ env.INFIX_BRANCH != '' && env.INFIX_BRANCH || github.ref }}
|
||||
clean: true
|
||||
fetch-depth: 0
|
||||
submodules: recursive
|
||||
token: ${{ secrets.CHECKOUT_TOKEN || github.token }}
|
||||
|
||||
- uses: ./.github/actions/podman-cleanup
|
||||
|
||||
- name: Run pre-build script
|
||||
if: ${{ inputs.pre_build_script != '' }}
|
||||
run: |
|
||||
cat > ./pre-build.sh << 'EOF'
|
||||
${{ inputs.pre_build_script }}
|
||||
EOF
|
||||
chmod +x ./pre-build.sh
|
||||
bash ./pre-build.sh
|
||||
|
||||
- uses: ./.github/actions/cache-restore
|
||||
with:
|
||||
target: ${{ env.TARGET }}
|
||||
|
||||
- name: Configure ${{ env.TARGET }}
|
||||
run: |
|
||||
make ${{ env.TARGET }}_defconfig
|
||||
|
||||
- name: Cleanup stale containers and ports
|
||||
run: |
|
||||
podman rm -af || true
|
||||
pkill -9 -f rootlessport || true
|
||||
|
||||
- name: Unit Test ${{ env.TARGET }}
|
||||
run: |
|
||||
make test-unit
|
||||
+1
-1
@@ -2,6 +2,7 @@
|
||||
.claude
|
||||
.gdb_history
|
||||
.claude
|
||||
AGENTS.md
|
||||
/.backup
|
||||
/.ccache
|
||||
/dl
|
||||
@@ -11,4 +12,3 @@
|
||||
/test/.log
|
||||
/local.mk
|
||||
/test/spec/Readme.adoc
|
||||
|
||||
|
||||
@@ -5,6 +5,7 @@ config BR2_PACKAGE_BANANAPI_BPI_R3
|
||||
select BR2_PACKAGE_LINUX_FIRMWARE
|
||||
select BR2_PACKAGE_LINUX_FIRMWARE_MEDIATEK
|
||||
select BR2_PACKAGE_LINUX_FIRMWARE_MEDIATEK_MT7986
|
||||
select BR2_PACKAGE_LINUX_FIRMWARE_AIROHA_EN8811H
|
||||
select SDCARD_AUX
|
||||
help
|
||||
Build Banana PI R3 support
|
||||
|
||||
@@ -1,20 +1,29 @@
|
||||
# Banana Pi BPI-R3
|
||||
# Banana Pi BPI-R3 / BPI-R3 Mini
|
||||
|
||||
<img src="bananapi-bpi-r3.webp" alt="The board" width=800 padding=10>
|
||||
|
||||
## Overview
|
||||
|
||||
The Banana Pi R3 is a high-performance networking board with full Infix
|
||||
support for all enabled features including switched Ethernet ports, WiFi,
|
||||
and SFP interfaces.
|
||||
The Banana Pi BPI-R3 and BPI-R3 Mini are high-performance networking
|
||||
boards with full Infix support for all enabled features including
|
||||
Ethernet, WiFi, and SFP interfaces.
|
||||
|
||||
Both boards share the same SoC and most peripherals. The key
|
||||
differences are:
|
||||
|
||||
| Feature | BPI-R3 | BPI-R3 Mini |
|
||||
|-----------------|--------------------|-------------------------|
|
||||
| Ethernet switch | Yes (4x LAN + WAN) | No (WAN/LAN ports only) |
|
||||
| SD card slot | Yes | No |
|
||||
|
||||
### Hardware Features
|
||||
|
||||
- MediaTek MT7986 ARM Cortex-A53 quad-core processor @ 2.0 GHz
|
||||
- 2 GB DDR4 RAM
|
||||
- 8 GB eMMC storage + microSD card slot
|
||||
- 5x Gigabit Ethernet ports (4x LAN, 1x WAN)
|
||||
- 2x SFP cages for fiber connectivity (1G/2.5G)
|
||||
- 8 GB eMMC storage
|
||||
- microSD card slot (BPI-R3 only)
|
||||
- 5x Gigabit Ethernet ports with switch core (BPI-R3 only)
|
||||
- 2x SFP cages for fiber connectivity (1G/2.5G) (BPI-R3 only)
|
||||
- Dual-band WiFi (2.4 GHz + 5 GHz)
|
||||
- USB 3.0 port
|
||||
- Mini PCIe slot
|
||||
@@ -23,16 +32,16 @@ and SFP interfaces.
|
||||
|
||||
Infix comes preconfigured with:
|
||||
|
||||
- **LAN ports** (lan1-lan4): Bridged for internal networking
|
||||
- **LAN ports** (lan1-lan4): Bridged for internal networking (BPI-R3 only)
|
||||
- **WAN port**: DHCP client enabled for internet connectivity
|
||||
- **SFP ports** (sfp1, sfp2): Available for configuration
|
||||
- **SFP ports** (sfp1, sfp2): Available for configuration (BPI-R3 only)
|
||||
- **WiFi interfaces** (wifi0, wifi1): Available for configuration
|
||||
|
||||
## Getting Started
|
||||
|
||||
### Quick Start with SD Card
|
||||
### BPI-R3: Quick Start with SD Card
|
||||
|
||||
The easiest way to get started is using an SD card:
|
||||
The easiest way to get started with the BPI-R3 is using an SD card:
|
||||
|
||||
> [!NOTE]
|
||||
> SD card boot works but we have observed stability issues. For production
|
||||
@@ -49,6 +58,12 @@ The easiest way to get started is using an SD card:
|
||||
- Connect to LAN port or console (115200 8N1)
|
||||
- Default login: `admin` / `admin`
|
||||
|
||||
### BPI-R3 Mini: Getting Started
|
||||
|
||||
The BPI-R3 Mini does not have an SD card slot, so you must install
|
||||
directly to eMMC. See [Installing to eMMC — BPI-R3
|
||||
Mini](#bpi-r3-mini) below.
|
||||
|
||||
### Boot Switch Reference
|
||||
|
||||
The BPI-R3 has a 4-position DIP switch that controls boot media:
|
||||
@@ -62,60 +77,44 @@ The BPI-R3 has a 4-position DIP switch that controls boot media:
|
||||
| 1010 | SPI NAND | Boot from SPI NAND (advanced users) |
|
||||
|
||||
> [!NOTE]
|
||||
> Switch position is read from left to right: "0" = OFF, "1" = ON.
|
||||
> Switch position is read from left to right: "0" = OFF, "1" = ON.
|
||||
> When the DIP switch is in the "UP" position it is OFF(0).
|
||||
|
||||
## Advanced: Installing to eMMC
|
||||
## Installing to eMMC
|
||||
|
||||
For production deployments or better performance, you can install Infix
|
||||
to the internal eMMC storage. This is more complex but provides faster
|
||||
boot times and eliminates the external SD card.
|
||||
to the internal eMMC storage.
|
||||
|
||||
> [!IMPORTANT]
|
||||
> While Infix boots on both SD card and eMMC, we have observed stability
|
||||
> issues with SD cards on this platform. **eMMC is recommended** for
|
||||
> reliable operation.
|
||||
|
||||
### Why Use eMMC?
|
||||
|
||||
**Advantages:**
|
||||
|
||||
- More reliable than SD card (stability issues observed with SD cards)
|
||||
- Faster boot and better performance
|
||||
- No external SD card to manage
|
||||
- More robust for industrial/embedded deployments
|
||||
|
||||
**Disadvantages:**
|
||||
|
||||
- More complex installation process
|
||||
- Requires intermediate NAND boot step
|
||||
- Harder to recover from errors
|
||||
> While Infix boots on both SD card and eMMC on the BPI-R3, we have
|
||||
> observed stability issues with SD cards on this platform. **eMMC is
|
||||
> recommended** for reliable operation.
|
||||
|
||||
### Prerequisites
|
||||
|
||||
- FTDI USB-to-serial cable (3.3V) for console access
|
||||
- microSD card with Infix (for initial boot)
|
||||
- USB flash drive (FAT32 formatted)
|
||||
- microSD card with Infix, for initial boot (BPI-R3 only)
|
||||
- Downloaded files (see below)
|
||||
|
||||
### Required Files
|
||||
|
||||
Download and place these files on a FAT32-formatted USB drive:
|
||||
|
||||
1. **Intermediate NAND bootloader** (from Frank-W's U-Boot):
|
||||
- [bpi-r3_spim-nand_bl2.img][5] (BL2 loader)
|
||||
- [bpi-r3_spim-nand_fip.bin][6] (FIP image)
|
||||
2. **Infix eMMC image:**
|
||||
1. **Infix eMMC image:**
|
||||
- [infix-bpi-r3-emmc.img][3] (Complete system image)
|
||||
3. **eMMC bootloader** (extracted from):
|
||||
2. **eMMC bootloader** (extracted from):
|
||||
- [bpi-r3-emmc-boot-2025.01-latest.tar.gz][4]
|
||||
- Extract `bl2.img` from the tarball to your USB drive
|
||||
3. **Intermediate NAND bootloader** (BPI-R3 only, from Frank-W's U-Boot):
|
||||
- [bpi-r3_spim-nand_bl2.img][5] (BL2 loader)
|
||||
- [bpi-r3_spim-nand_fip.bin][6] (FIP image)
|
||||
|
||||
> [!WARNING]
|
||||
> The following process involves multiple boot mode changes. Take your
|
||||
> time verify each step carefully.
|
||||
> time and verify each step carefully.
|
||||
|
||||
### Installation Steps
|
||||
### BPI-R3
|
||||
|
||||
#### Step 1: Boot from SD card
|
||||
|
||||
@@ -177,13 +176,48 @@ mmc partconf 0 1 1 0
|
||||
|
||||
Your BPI-R3 should now boot Infix from internal eMMC storage!
|
||||
|
||||
### BPI-R3 Mini
|
||||
|
||||
The BPI-R3 Mini does not have an SD card slot, so you have to go
|
||||
through the factory-installed Linux (OpenWRT) to flash the Infix
|
||||
bootloader and OS to eMMC.
|
||||
|
||||
#### Step 1: Boot from NAND (factory default)
|
||||
|
||||
<img src="r3mini_nandboot2.png" alt="BPI-R3 Mini NAND boot switch position" width=400>
|
||||
|
||||
1. Ensure boot switches are set to NAND mode (factory default)
|
||||
2. Place `infix-bpi-r3-emmc.img` and `bl2.img` on a USB drive
|
||||
3. Power on and boot into Linux
|
||||
4. Mount the USB drive to `/mnt`
|
||||
|
||||
#### Step 2: Flash Infix to eMMC
|
||||
|
||||
From the Linux shell:
|
||||
|
||||
```
|
||||
echo 0 > /proc/sys/kernel/printk
|
||||
dd if=/mnt/infix-bpi-r3-emmc.img of=/dev/mmcblk0
|
||||
echo 0 > /sys/block/mmcblk0boot0/force_ro
|
||||
dd if=/mnt/bl2.img of=/dev/mmcblk0boot0
|
||||
sync
|
||||
```
|
||||
|
||||
#### Step 3: Boot from eMMC
|
||||
|
||||
<img src="r3mini_emmcboot.png" alt="BPI-R3 Mini eMMC boot switch position" width=400>
|
||||
|
||||
1. Power off the board
|
||||
2. Set boot switches to eMMC mode (see image above)
|
||||
3. Power on
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
### Board won't boot
|
||||
|
||||
- Verify boot switch positions (check twice!)
|
||||
- Ensure power supply provides adequate current (12V/2A recommended)
|
||||
- Try booting from SD card with switches at **0000**
|
||||
- Try booting from SD card with switches at **0000** (BPI-R3 only)
|
||||
|
||||
### Can't break into U-Boot
|
||||
|
||||
@@ -195,9 +229,9 @@ Your BPI-R3 should now boot Infix from internal eMMC storage!
|
||||
|
||||
- Boot from NAND (**1010**) and verify eMMC image was written
|
||||
- Check USB drive contents - ensure all files are present
|
||||
- Re-run Step 5 (eMMC boot configuration)
|
||||
- Re-run the eMMC boot configuration step
|
||||
|
||||
### Reverting to SD card
|
||||
### Reverting to SD card (BPI-R3 only)
|
||||
|
||||
Simply set boot switches back to **0000** and boot from SD card. The
|
||||
eMMC installation does not affect SD card functionality.
|
||||
|
||||
@@ -9,6 +9,7 @@ define BANANAPI_BPI_R3_LINUX_CONFIG_FIXUPS
|
||||
$(call KCONFIG_ENABLE_OPT,CONFIG_MEDIATEK_WATCHDOG)
|
||||
$(call KCONFIG_ENABLE_OPT,CONFIG_MEDIATEK_GE_PHY)
|
||||
$(call KCONFIG_ENABLE_OPT,CONFIG_REALTEK_PHY)
|
||||
$(call KCONFIG_SET_OPT,CONFIG_AIR_EN8811H_PHY,m)
|
||||
$(call KCONFIG_ENABLE_OPT,CONFIG_NET_VENDOR_MEDIATEK)
|
||||
$(call KCONFIG_ENABLE_OPT,CONFIG_NET_MEDIATEK_SOC)
|
||||
$(call KCONFIG_SET_OPT,CONFIG_NET_DSA_MT7530,m)
|
||||
|
||||
@@ -1 +1 @@
|
||||
dtb-y += mediatek/mt7986a-bananapi-bpi-r3-sd.dtb mediatek/mt7986a-bananapi-bpi-r3-emmc.dtb
|
||||
dtb-y += mediatek/mt7986a-bananapi-bpi-r3-sd.dtb mediatek/mt7986a-bananapi-bpi-r3-emmc.dtb mediatek/mt7986a-bananapi-bpi-r3-mini.dtb
|
||||
|
||||
@@ -1,2 +1,4 @@
|
||||
#include <arm64/mediatek/mt7986a-bananapi-bpi-r3.dts>
|
||||
|
||||
#include "mt7986a-bananapi-bpi-r3.dtsi"
|
||||
#include "mt7986a-bananapi-bpi-r3-emmc.dtsi"
|
||||
|
||||
@@ -0,0 +1,12 @@
|
||||
#include <arm64/mediatek/mt7986a-bananapi-bpi-r3-mini.dts>
|
||||
|
||||
#include "mt7986a-bananapi-bpi-r3.dtsi"
|
||||
#include "mt7986a-bananapi-bpi-r3-emmc.dtsi"
|
||||
|
||||
&phy0 {
|
||||
compatible = "ethernet-phy-id03a2.a411";
|
||||
};
|
||||
&phy1 {
|
||||
compatible = "ethernet-phy-id03a2.a411";
|
||||
};
|
||||
|
||||
@@ -0,0 +1,2 @@
|
||||
#include "mt7986a-bananapi-bpi-r3.dtsi"
|
||||
#include "mt7986a-bananapi-bpi-r3-emmc.dtsi"
|
||||
@@ -1,2 +1,4 @@
|
||||
#include <arm64/mediatek/mt7986a-bananapi-bpi-r3.dts>
|
||||
|
||||
#include "mt7986a-bananapi-bpi-r3.dtsi"
|
||||
#include "mt7986a-bananapi-bpi-r3-sd.dtsi"
|
||||
|
||||
@@ -1,5 +1,3 @@
|
||||
#include <arm64/mediatek/mt7986a-bananapi-bpi-r3.dts>
|
||||
|
||||
/ {
|
||||
chosen {
|
||||
infix {
|
||||
|
||||
@@ -51,6 +51,11 @@ image #INFIX_ID##VERSION#-bpi-r3-#TARGET#.img {
|
||||
size = 4096s
|
||||
}
|
||||
|
||||
partition en8811h_fw {
|
||||
size = 10M
|
||||
image = "en8811h-fw.bin"
|
||||
}
|
||||
|
||||
partition aux {
|
||||
partition-uuid = D4EF35A0-0652-45A1-B3DE-D63339C82035
|
||||
image = "aux.ext4"
|
||||
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 111 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 110 KiB |
-3
@@ -1,3 +0,0 @@
|
||||
#!/bin/sh
|
||||
udevadm control --reload-rules
|
||||
udevadm trigger --subsystem-match=net --action=add
|
||||
+445
@@ -0,0 +1,445 @@
|
||||
{
|
||||
"ieee802-dot1ab-lldp:lldp": {
|
||||
"infix-lldp:enabled": true
|
||||
},
|
||||
"ietf-hardware:hardware": {
|
||||
"component": [
|
||||
{
|
||||
"name": "USB",
|
||||
"class": "infix-hardware:usb",
|
||||
"state": {
|
||||
"admin-state": "unlocked"
|
||||
}
|
||||
},
|
||||
{
|
||||
"class": "infix-hardware:usb",
|
||||
"name": "USB2",
|
||||
"state": {
|
||||
"admin-state": "unlocked"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "radio0",
|
||||
"class": "infix-hardware:wifi",
|
||||
"infix-hardware:wifi-radio": {
|
||||
"country-code": "DE",
|
||||
"band": "2.4GHz",
|
||||
"channel": "auto"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "radio1",
|
||||
"class": "infix-hardware:wifi",
|
||||
"infix-hardware:wifi-radio": {
|
||||
"country-code": "DE",
|
||||
"band": "5GHz",
|
||||
"channel": "auto"
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
"ietf-interfaces:interfaces": {
|
||||
"interface": [
|
||||
{
|
||||
"name": "br0",
|
||||
"type": "infix-if-type:bridge",
|
||||
"ietf-ip:ipv4": {
|
||||
"address": [
|
||||
{
|
||||
"ip": "192.168.0.1",
|
||||
"prefix-length": 24
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "lan",
|
||||
"type": "infix-if-type:ethernet",
|
||||
"ietf-ip:ipv6": {},
|
||||
"infix-interfaces:bridge-port": {
|
||||
"bridge": "br0"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "lo",
|
||||
"type": "infix-if-type:loopback",
|
||||
"ietf-ip:ipv4": {
|
||||
"address": [
|
||||
{
|
||||
"ip": "127.0.0.1",
|
||||
"prefix-length": 8
|
||||
}
|
||||
]
|
||||
},
|
||||
"ietf-ip:ipv6": {
|
||||
"address": [
|
||||
{
|
||||
"ip": "::1",
|
||||
"prefix-length": 128
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "wan",
|
||||
"type": "infix-if-type:ethernet",
|
||||
"ietf-ip:ipv4": {
|
||||
"infix-dhcp-client:dhcp": {
|
||||
"option": [
|
||||
{
|
||||
"id": "ntp-server"
|
||||
},
|
||||
{
|
||||
"id": "broadcast"
|
||||
},
|
||||
{
|
||||
"id": "domain"
|
||||
},
|
||||
{
|
||||
"id": "hostname"
|
||||
},
|
||||
{
|
||||
"id": "dns-server"
|
||||
},
|
||||
{
|
||||
"id": "router"
|
||||
},
|
||||
{
|
||||
"id": "netmask"
|
||||
},
|
||||
{
|
||||
"id": "vendor-class",
|
||||
"value": "Banana Pi BPI-R3"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"ietf-ip:ipv6": {
|
||||
"infix-dhcpv6-client:dhcp": {
|
||||
"option": [
|
||||
{
|
||||
"id": "ntp-server"
|
||||
},
|
||||
{
|
||||
"id": "client-fqdn"
|
||||
},
|
||||
{
|
||||
"id": "domain-search"
|
||||
},
|
||||
{
|
||||
"id": "dns-server"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "wifi0-ap",
|
||||
"type": "infix-if-type:wifi",
|
||||
"infix-interfaces:wifi": {
|
||||
"radio": "radio0",
|
||||
"access-point": {
|
||||
"ssid": "Infix",
|
||||
"security": {
|
||||
"secret": "wifi"
|
||||
}
|
||||
}
|
||||
},
|
||||
"infix-interfaces:bridge-port": {
|
||||
"bridge": "br0"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "wifi1-ap",
|
||||
"type": "infix-if-type:wifi",
|
||||
"infix-interfaces:wifi": {
|
||||
"radio": "radio1",
|
||||
"access-point": {
|
||||
"ssid": "Infix5Ghz",
|
||||
"security": {
|
||||
"secret": "wifi"
|
||||
}
|
||||
}
|
||||
},
|
||||
"infix-interfaces:bridge-port": {
|
||||
"bridge": "br0"
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
"ietf-keystore:keystore": {
|
||||
"asymmetric-keys": {
|
||||
"asymmetric-key": [
|
||||
{
|
||||
"name": "genkey",
|
||||
"public-key-format": "infix-crypto-types:ssh-public-key-format",
|
||||
"public-key": "",
|
||||
"private-key-format": "infix-crypto-types:rsa-private-key-format",
|
||||
"cleartext-private-key": "",
|
||||
"certificates": {}
|
||||
}
|
||||
]
|
||||
},
|
||||
"symmetric-keys": {
|
||||
"symmetric-key": [
|
||||
{
|
||||
"name": "wifi",
|
||||
"cleartext-symmetric-key": "aW5maXhpbmZpeA==",
|
||||
"key-format": "infix-crypto-types:passphrase-key-format"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"ietf-netconf-acm:nacm": {
|
||||
"enable-nacm": true,
|
||||
"read-default": "permit",
|
||||
"write-default": "permit",
|
||||
"exec-default": "permit",
|
||||
"groups": {
|
||||
"group": [
|
||||
{
|
||||
"name": "admin",
|
||||
"user-name": [
|
||||
"admin"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "operator",
|
||||
"user-name": []
|
||||
},
|
||||
{
|
||||
"name": "guest",
|
||||
"user-name": []
|
||||
}
|
||||
]
|
||||
},
|
||||
"rule-list": [
|
||||
{
|
||||
"name": "admin-acl",
|
||||
"group": [
|
||||
"admin"
|
||||
],
|
||||
"rule": [
|
||||
{
|
||||
"name": "permit-all",
|
||||
"module-name": "*",
|
||||
"access-operations": "*",
|
||||
"action": "permit",
|
||||
"comment": "Allow 'admin' group complete access to all operations and data."
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "operator-acl",
|
||||
"group": [
|
||||
"operator"
|
||||
],
|
||||
"rule": [
|
||||
{
|
||||
"name": "permit-system-rpcs",
|
||||
"module-name": "ietf-system",
|
||||
"rpc-name": "*",
|
||||
"access-operations": "exec",
|
||||
"action": "permit",
|
||||
"comment": "Operators can reboot, shutdown, and set system time."
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "guest-acl",
|
||||
"group": [
|
||||
"guest"
|
||||
],
|
||||
"rule": [
|
||||
{
|
||||
"name": "deny-all-write+exec",
|
||||
"module-name": "*",
|
||||
"access-operations": "create update delete exec",
|
||||
"action": "deny",
|
||||
"comment": "Guests cannot change anything or exec rpcs."
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "default-deny-all",
|
||||
"group": [
|
||||
"*"
|
||||
],
|
||||
"rule": [
|
||||
{
|
||||
"name": "deny-password-access",
|
||||
"path": "/ietf-system:system/authentication/user/password",
|
||||
"access-operations": "*",
|
||||
"action": "deny",
|
||||
"comment": "No user except admins can access password hashes."
|
||||
},
|
||||
{
|
||||
"name": "deny-keystore-access",
|
||||
"module-name": "ietf-keystore",
|
||||
"access-operations": "*",
|
||||
"action": "deny",
|
||||
"comment": "No user except admins can access cryptographic keys."
|
||||
},
|
||||
{
|
||||
"name": "deny-truststore-access",
|
||||
"module-name": "ietf-truststore",
|
||||
"access-operations": "*",
|
||||
"action": "deny",
|
||||
"comment": "No user except admins can access trust store."
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
"ietf-netconf-server:netconf-server": {
|
||||
"listen": {
|
||||
"endpoints": {
|
||||
"endpoint": [
|
||||
{
|
||||
"name": "default-ssh",
|
||||
"ssh": {
|
||||
"tcp-server-parameters": {
|
||||
"local-bind": [
|
||||
{
|
||||
"local-address": "::"
|
||||
}
|
||||
]
|
||||
},
|
||||
"ssh-server-parameters": {
|
||||
"server-identity": {
|
||||
"host-key": [
|
||||
{
|
||||
"name": "default-key",
|
||||
"public-key": {
|
||||
"central-keystore-reference": "genkey"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
"ietf-system:system": {
|
||||
"hostname": "bpi-%m",
|
||||
"ntp": {
|
||||
"server": [
|
||||
{
|
||||
"name": "default",
|
||||
"udp": {
|
||||
"address": "pool.ntp.org"
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
"authentication": {
|
||||
"user": [
|
||||
{
|
||||
"name": "admin",
|
||||
"password": "$factory$",
|
||||
"infix-system:shell": "bash"
|
||||
}
|
||||
]
|
||||
},
|
||||
"infix-system:motd-banner": "Li0tLS0tLS0uCnwgIC4gLiAgfCBJbmZpeCBPUyDigJQgSW1tdXRhYmxlLkZyaWVuZGx5LlNlY3VyZQp8LS4gdiAuLXwgaHR0cHM6Ly9rZXJuZWxraXQub3JnCictJy0tLSctJwo="
|
||||
},
|
||||
"infix-dhcp-server:dhcp-server": {
|
||||
"option": [
|
||||
{
|
||||
"id": "ntp-server",
|
||||
"address": "auto"
|
||||
},
|
||||
{
|
||||
"id": "dns-server",
|
||||
"address": "auto"
|
||||
},
|
||||
{
|
||||
"id": "router",
|
||||
"address": "auto"
|
||||
}
|
||||
],
|
||||
"subnet": [
|
||||
{
|
||||
"subnet": "192.168.0.0/24",
|
||||
"pool": {
|
||||
"start-address": "192.168.0.100",
|
||||
"end-address": "192.168.0.250"
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
"infix-firewall:firewall": {
|
||||
"default": "wan",
|
||||
"zone": [
|
||||
{
|
||||
"name": "lan",
|
||||
"action": "accept",
|
||||
"interface": [
|
||||
"br0"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "wan",
|
||||
"action": "drop",
|
||||
"interface": [
|
||||
"wan"
|
||||
],
|
||||
"service": [
|
||||
"dhcpv6-client"
|
||||
]
|
||||
}
|
||||
],
|
||||
"policy": [
|
||||
{
|
||||
"name": "lan-to-wan",
|
||||
"action": "accept",
|
||||
"ingress": [
|
||||
"lan"
|
||||
],
|
||||
"egress": [
|
||||
"wan"
|
||||
],
|
||||
"masquerade": true
|
||||
}
|
||||
]
|
||||
},
|
||||
"infix-meta:meta": {
|
||||
"version": "1.7"
|
||||
},
|
||||
"infix-services:mdns": {
|
||||
"enabled": true
|
||||
},
|
||||
"infix-services:ssh": {
|
||||
"enabled": true,
|
||||
"hostkey": [
|
||||
"genkey"
|
||||
],
|
||||
"listen": [
|
||||
{
|
||||
"name": "ipv4",
|
||||
"address": "0.0.0.0",
|
||||
"port": 22
|
||||
},
|
||||
{
|
||||
"name": "ipv6",
|
||||
"address": "::",
|
||||
"port": 22
|
||||
}
|
||||
]
|
||||
},
|
||||
"infix-services:web": {
|
||||
"enabled": true,
|
||||
"console": {
|
||||
"enabled": true
|
||||
},
|
||||
"netbrowse": {
|
||||
"enabled": true
|
||||
},
|
||||
"restconf": {
|
||||
"enabled": true
|
||||
}
|
||||
}
|
||||
}
|
||||
+2
@@ -0,0 +1,2 @@
|
||||
ACTION=="add", SUBSYSTEM=="net", DEVPATH=="/devices/platform/soc/15100000.ethernet/net/eth0", NAME="lan"
|
||||
ACTION=="add", SUBSYSTEM=="net", DEVPATH=="/devices/platform/soc/15100000.ethernet/net/eth1", NAME="wan"
|
||||
@@ -3,6 +3,9 @@ CONFIG_BOOTDELAY=2
|
||||
# CONFIG_MMC_PCI is not set
|
||||
CONFIG_ENV_IS_NOWHERE=y
|
||||
# CONFIG_ENV_IS_IN_MMC is not set
|
||||
CONFIG_MULTI_DTB_FIT=y
|
||||
CONFIG_OF_LIST="mt7986a-bpi-r3-sd mt7986a-bpi-r3-emmc mt7986a-bpi-r3-mini"
|
||||
|
||||
CONFIG_USB=y
|
||||
CONFIG_USB_XHCI_HCD=y
|
||||
CONFIG_USB_XHCI_MTK=y
|
||||
@@ -26,8 +29,17 @@ CONFIG_MTD_SPI_NAND=y
|
||||
CONFIG_MTK_SPIM=y
|
||||
CONFIG_MTK_SNOR=y
|
||||
|
||||
CONFIG_DM_MDIO=y
|
||||
CONFIG_DM_ETH_PHY=y
|
||||
CONFIG_PHY_ETHERNET_ID=y
|
||||
|
||||
CONFIG_PHY_AIROHA=y
|
||||
CONFIG_PHY_AIROHA_EN8811H=y
|
||||
CONFIG_PHY_AIROHA_FW_IN_MMC=y
|
||||
|
||||
CONFIG_CMD_SF=y
|
||||
CONFIG_CMD_USB=y
|
||||
CONFIG_CMD_MTD=y
|
||||
CONFIG_CMD_MDIO=y
|
||||
CONFIG_CMD_MTDPARTS=y
|
||||
CONFIG_CMD_DM=y
|
||||
|
||||
@@ -15,6 +15,10 @@
|
||||
scriptaddr = "0x48000000";
|
||||
ramdisk_addr_r = "0x4A000000";
|
||||
|
||||
en8811h_fw_part = "0#en8811h_fw";
|
||||
en8811h_fw_dm_dir = "EthMD32.dm.bin";
|
||||
en8811h_fw_dsp_dir = "EthMD32.DSP.bin";
|
||||
|
||||
/* This is a development platform, keep
|
||||
* developer mode statically enabled.
|
||||
*/
|
||||
|
||||
-3
@@ -1,3 +0,0 @@
|
||||
#!/bin/sh
|
||||
udevadm control --reload-rules
|
||||
udevadm trigger --subsystem-match=net --action=add
|
||||
-4
@@ -1,4 +0,0 @@
|
||||
#!/bin/sh
|
||||
# Workaround for: https://github.com/kernelkit/infix/issues/1357
|
||||
udevadm control --reload-rules
|
||||
udevadm trigger --subsystem-match=net --action=add
|
||||
-4
@@ -1,4 +0,0 @@
|
||||
#!/bin/sh
|
||||
# Workaround for: https://github.com/kernelkit/infix/issues/1357
|
||||
udevadm control --reload-rules
|
||||
udevadm trigger --subsystem-match=net --action=add
|
||||
@@ -1,5 +1,6 @@
|
||||
if BR2_arm
|
||||
|
||||
source "$BR2_EXTERNAL_INFIX_PATH/board/arm/microchip-sama7g54-ek/Config.in"
|
||||
source "$BR2_EXTERNAL_INFIX_PATH/board/arm/raspberrypi-rpi2/Config.in"
|
||||
|
||||
endif
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
config BR2_PACKAGE_MICROCHIP_SAMA7G54_EK
|
||||
bool "Microchip SAMA7G54-EK Evaluation Kit"
|
||||
depends on BR2_arm
|
||||
select SDCARD_AUX
|
||||
help
|
||||
Support for the Microchip SAMA7G54 Evaluation Kit featuring
|
||||
a Cortex-A7 processor with MACB Gigabit Ethernet and MMC storage.
|
||||
@@ -0,0 +1,13 @@
|
||||
Copyright (c) 2026 The KernelKit Authors
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
copyright notice and this permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
@@ -0,0 +1,116 @@
|
||||
Microchip SAMA7G54-EK
|
||||
=====================
|
||||
|
||||
The [SAMA7G54-EK][1] is an evaluation kit for the Microchip SAMA7G5 series,
|
||||
featuring an ARM Cortex-A7 processor @ 800 MHz with 512 MB DDR3L RAM.
|
||||
|
||||
The board features:
|
||||
|
||||
- 2x MACB Gigabit Ethernet ports
|
||||
- 8 GB eMMC (SDMMC0) + microSD card slot (SDMMC1)
|
||||
- QSPI NOR flash
|
||||
- USB 2.0 host ports
|
||||
- CAN bus interfaces
|
||||
- Flexcom serial ports (UART, SPI, I2C)
|
||||
|
||||
How to Build
|
||||
------------
|
||||
|
||||
Since there are no pre-built images for ARM 32-bit, you need to build
|
||||
both Infix and the bootloader from source.
|
||||
|
||||
### SD Card
|
||||
|
||||
1. Build the bootloader
|
||||
|
||||
make O=x-boot-sama7g54 sama7g54_ek_sd_boot_defconfig
|
||||
make O=x-boot-sama7g54
|
||||
|
||||
2. Build Infix
|
||||
|
||||
make O=x-arm arm_defconfig
|
||||
make O=x-arm
|
||||
|
||||
3. Create the SD card image
|
||||
|
||||
./utils/mkimage.sh -b x-boot-sama7g54 -r x-arm microchip-sama7g54-ek
|
||||
|
||||
### eMMC
|
||||
|
||||
1. Build the bootloader
|
||||
|
||||
make O=x-boot-sama7g54-emmc sama7g54_ek_emmc_boot_defconfig
|
||||
make O=x-boot-sama7g54-emmc
|
||||
|
||||
2. Build Infix (same as above, skip if already built)
|
||||
|
||||
make O=x-arm arm_defconfig
|
||||
make O=x-arm
|
||||
|
||||
3. Create the eMMC image
|
||||
|
||||
./utils/mkimage.sh -b x-boot-sama7g54-emmc -r x-arm -t emmc microchip-sama7g54-ek
|
||||
|
||||
Flashing to SD Card
|
||||
-------------------
|
||||
|
||||
[Flash the image][0] to a microSD card (at least 2 GB):
|
||||
|
||||
```bash
|
||||
sudo dd if=x-boot-sama7g54/images/infix-arm-sdcard.img of=/dev/sdX \
|
||||
bs=1M status=progress oflag=direct
|
||||
```
|
||||
|
||||
You can also use `bmaptool` for faster writes:
|
||||
|
||||
```bash
|
||||
sudo bmaptool copy x-boot-sama7g54/images/infix-arm-sdcard.img /dev/sdX
|
||||
```
|
||||
|
||||
> [!WARNING]
|
||||
> Ensure `/dev/sdX` is the correct device for your SD card and not used
|
||||
> by the host system! Use `lsblk` to verify.
|
||||
|
||||
Flashing to eMMC
|
||||
-----------------
|
||||
|
||||
The SAMA7G5EK has an on-board 8 GB eMMC (SDMMC0/mmc0). Jumper J22
|
||||
controls if booting from onboard storage is allowed or not; open means
|
||||
allowed. When open, the SW4 button can also prevent booting from eMMC
|
||||
if held at power on.
|
||||
|
||||
The easiest method is to flash from a running SD card system:
|
||||
|
||||
1. Boot the board from SD card
|
||||
2. Transfer the eMMC image to the board (USB drive, network, etc.)
|
||||
3. Flash the eMMC:
|
||||
|
||||
sudo bmaptool copy emmc.img /dev/mmcblk0
|
||||
|
||||
4. Power off, remove SD card, and boot from eMMC
|
||||
|
||||
Booting the Board
|
||||
-----------------
|
||||
|
||||
1. Insert the flashed SD card (or ensure eMMC is flashed)
|
||||
2. Connect an Ethernet cable
|
||||
3. Power up the board
|
||||
4. Find the assigned IP and SSH in, default login: `admin` / `admin`
|
||||
|
||||
Console Port
|
||||
------------
|
||||
|
||||
The debug console is on Flexcom3 (active by default):
|
||||
|
||||
- Baud rate: 115200
|
||||
- Data bits: 8
|
||||
- Parity: None
|
||||
- Stop bits: 1
|
||||
|
||||
Connect a USB-to-serial adapter to the board's debug UART header.
|
||||
|
||||
> [!WARNING]
|
||||
> Use only 3.3V serial adapters.
|
||||
|
||||
[0]: https://kernelkit.org/posts/flashing-sdcard/
|
||||
[1]: https://www.microchip.com/en-us/development-tool/EV21H18A
|
||||
@@ -0,0 +1 @@
|
||||
dtb-y += microchip/at91-sama7g5ek.dtb
|
||||
@@ -0,0 +1,18 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
/*
|
||||
* Infix OS device tree for Microchip SAMA7G5 Evaluation Kit
|
||||
*/
|
||||
|
||||
#include <arm/microchip/at91-sama7g5ek.dts>
|
||||
#include "infix.dtsi"
|
||||
|
||||
/ {
|
||||
chosen {
|
||||
stdout-path = "serial0:115200n8";
|
||||
};
|
||||
};
|
||||
|
||||
/* Thermal sensor disabled until OTP is calibrated */
|
||||
&thermal_sensor {
|
||||
status = "disabled";
|
||||
};
|
||||
@@ -0,0 +1,13 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
/*
|
||||
* Common Infix OS defaults
|
||||
*/
|
||||
|
||||
/ {
|
||||
chosen {
|
||||
infix {
|
||||
/* Default admin user password: 'admin' */
|
||||
factory-password-hash = "$5$mI/zpOAqZYKLC2WU$i7iPzZiIjOjrBF3NyftS9CCq8dfYwHwrmUK097Jca9A";
|
||||
};
|
||||
};
|
||||
};
|
||||
@@ -0,0 +1,85 @@
|
||||
# Disk image for Microchip SAMA7G5EK (sama7g5 evaluation kit)
|
||||
|
||||
image boot.vfat {
|
||||
vfat {
|
||||
files = {
|
||||
"boot.bin",
|
||||
"u-boot.bin"
|
||||
}
|
||||
}
|
||||
|
||||
size = 16M
|
||||
}
|
||||
|
||||
image cfg.ext4 {
|
||||
empty = true
|
||||
temporary = true
|
||||
size = 16M
|
||||
|
||||
ext4 {
|
||||
label = "cfg"
|
||||
use-mke2fs = true
|
||||
features = "uninit_bg"
|
||||
extraargs = "-m 0 -i 4096"
|
||||
}
|
||||
}
|
||||
|
||||
# The /var partition will be expanded automatically at first boot
|
||||
# to use the full size of the SD-card or eMMC media.
|
||||
image var.ext4 {
|
||||
empty = true
|
||||
temporary = true
|
||||
size = 128M
|
||||
|
||||
ext4 {
|
||||
label = "var"
|
||||
use-mke2fs = true
|
||||
features = "uninit_bg"
|
||||
extraargs = "-m 0 -i 4096"
|
||||
}
|
||||
}
|
||||
|
||||
image #INFIX_ID##VERSION#-sama7g54-ek-#TARGET#.img {
|
||||
hdimage {
|
||||
partition-table-type = "hybrid"
|
||||
}
|
||||
|
||||
partition boot {
|
||||
partition-type = 0xC
|
||||
bootable = "true"
|
||||
image = "boot.vfat"
|
||||
offset = 1M
|
||||
}
|
||||
|
||||
partition aux {
|
||||
partition-uuid = D4EF35A0-0652-45A1-B3DE-D63339C82035
|
||||
image = "aux.ext4"
|
||||
}
|
||||
|
||||
partition primary {
|
||||
partition-type-uuid = 0FC63DAF-8483-4772-8E79-3D69D8477DE4
|
||||
bootable = true
|
||||
size = 250M
|
||||
image = "rootfs.squashfs"
|
||||
}
|
||||
|
||||
partition secondary {
|
||||
partition-type-uuid = 0FC63DAF-8483-4772-8E79-3D69D8477DE4
|
||||
bootable = true
|
||||
size = 250M
|
||||
image = "rootfs.squashfs"
|
||||
}
|
||||
|
||||
partition cfg {
|
||||
partition-uuid = 7aa497f0-73b5-47e5-b2ab-8752d8a48105
|
||||
image = "cfg.ext4"
|
||||
}
|
||||
|
||||
partition var {
|
||||
partition-uuid = 8046A06A-E45A-4A14-A6AD-6684704A393F
|
||||
image = "var.ext4"
|
||||
}
|
||||
}
|
||||
|
||||
# Silence genimage warnings
|
||||
config {}
|
||||
@@ -0,0 +1,69 @@
|
||||
# Microchip SAMA7G54-EK kernel configuration fixups
|
||||
define MICROCHIP_SAMA7G54_EK_LINUX_CONFIG_FIXUPS
|
||||
# AT91/Microchip SoC
|
||||
$(call KCONFIG_ENABLE_OPT,CONFIG_ARCH_AT91)
|
||||
$(call KCONFIG_ENABLE_OPT,CONFIG_SOC_SAMA7G5)
|
||||
$(call KCONFIG_ENABLE_OPT,CONFIG_ATMEL_CLOCKSOURCE_TCB)
|
||||
|
||||
# Serial console (FLEXCOM)
|
||||
# Use ttyAT naming to avoid major/minor conflict with the
|
||||
# 8250 driver (needed by Raspberry Pi 2 in the shared ARM config)
|
||||
$(call KCONFIG_ENABLE_OPT,CONFIG_SERIAL_ATMEL)
|
||||
$(call KCONFIG_ENABLE_OPT,CONFIG_SERIAL_ATMEL_CONSOLE)
|
||||
$(call KCONFIG_ENABLE_OPT,CONFIG_SERIAL_ATMEL_TTYAT)
|
||||
$(call KCONFIG_ENABLE_OPT,CONFIG_MFD_ATMEL_FLEXCOM)
|
||||
|
||||
# Network: MACB Ethernet
|
||||
$(call KCONFIG_ENABLE_OPT,CONFIG_NET_VENDOR_MICROCHIP)
|
||||
$(call KCONFIG_ENABLE_OPT,CONFIG_MACB)
|
||||
$(call KCONFIG_ENABLE_OPT,CONFIG_MICREL_PHY)
|
||||
|
||||
# MMC/SD
|
||||
$(call KCONFIG_ENABLE_OPT,CONFIG_MMC_SDHCI)
|
||||
$(call KCONFIG_ENABLE_OPT,CONFIG_MMC_SDHCI_PLTFM)
|
||||
$(call KCONFIG_ENABLE_OPT,CONFIG_MMC_SDHCI_OF_AT91)
|
||||
|
||||
# Pin control and GPIO
|
||||
$(call KCONFIG_ENABLE_OPT,CONFIG_PINCTRL_AT91)
|
||||
$(call KCONFIG_ENABLE_OPT,CONFIG_PINCTRL_AT91PIO4)
|
||||
$(call KCONFIG_ENABLE_OPT,CONFIG_GPIO_SYSFS)
|
||||
|
||||
# I2C and SPI
|
||||
$(call KCONFIG_ENABLE_OPT,CONFIG_I2C_AT91)
|
||||
$(call KCONFIG_ENABLE_OPT,CONFIG_SPI_ATMEL)
|
||||
$(call KCONFIG_ENABLE_OPT,CONFIG_SPI_ATMEL_QUADSPI)
|
||||
|
||||
# Power management and reset
|
||||
$(call KCONFIG_ENABLE_OPT,CONFIG_POWER_RESET)
|
||||
$(call KCONFIG_ENABLE_OPT,CONFIG_POWER_RESET_AT91_RESET)
|
||||
$(call KCONFIG_ENABLE_OPT,CONFIG_POWER_RESET_AT91_SAMA5D2_SHDWC)
|
||||
|
||||
# Watchdog
|
||||
$(call KCONFIG_ENABLE_OPT,CONFIG_WATCHDOG)
|
||||
$(call KCONFIG_ENABLE_OPT,CONFIG_SAMA5D4_WATCHDOG)
|
||||
|
||||
# DMA and RTC
|
||||
$(call KCONFIG_ENABLE_OPT,CONFIG_AT_XDMAC)
|
||||
$(call KCONFIG_ENABLE_OPT,CONFIG_RTC_CLASS)
|
||||
$(call KCONFIG_ENABLE_OPT,CONFIG_RTC_DRV_AT91SAM9)
|
||||
|
||||
# Crypto hardware acceleration
|
||||
$(call KCONFIG_ENABLE_OPT,CONFIG_CRYPTO_DEV_ATMEL_AES)
|
||||
$(call KCONFIG_ENABLE_OPT,CONFIG_CRYPTO_DEV_ATMEL_TDES)
|
||||
$(call KCONFIG_ENABLE_OPT,CONFIG_CRYPTO_DEV_ATMEL_SHA)
|
||||
|
||||
# USB Host
|
||||
$(call KCONFIG_ENABLE_OPT,CONFIG_USB_EHCI_HCD)
|
||||
$(call KCONFIG_ENABLE_OPT,CONFIG_USB_OHCI_HCD)
|
||||
|
||||
# Regulators
|
||||
$(call KCONFIG_ENABLE_OPT,CONFIG_REGULATOR)
|
||||
$(call KCONFIG_ENABLE_OPT,CONFIG_REGULATOR_FIXED_VOLTAGE)
|
||||
$(call KCONFIG_ENABLE_OPT,CONFIG_REGULATOR_MCP16502)
|
||||
|
||||
# NVMEM for OTP
|
||||
$(call KCONFIG_ENABLE_OPT,CONFIG_NVMEM_MICROCHIP_OTPC)
|
||||
endef
|
||||
|
||||
$(eval $(ix-board))
|
||||
$(eval $(generic-package))
|
||||
@@ -0,0 +1,12 @@
|
||||
[system]
|
||||
compatible=infix-sama7g54-ek
|
||||
bootloader=uboot
|
||||
statusfile=/mnt/aux/rauc.status
|
||||
|
||||
[slot.rootfs.0]
|
||||
device=/dev/disk/by-partlabel/primary
|
||||
bootname=primary
|
||||
|
||||
[slot.rootfs.1]
|
||||
device=/dev/disk/by-partlabel/secondary
|
||||
bootname=secondary
|
||||
+5
@@ -0,0 +1,5 @@
|
||||
{
|
||||
"@ethtool:driver=macb": {
|
||||
"broken-flow-control": true
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
CONFIG_DEVICE_TREE_INCLUDES="infix-env.dtsi infix-key.dtsi sama7g54-ek-env-emmc.dtsi"
|
||||
@@ -0,0 +1,13 @@
|
||||
# Common U-Boot extras for SAMA7G54-EK
|
||||
CONFIG_EFI_PARTITION=y
|
||||
CONFIG_ENV_IMPORT_FDT=y
|
||||
CONFIG_FIT=y
|
||||
CONFIG_FIT_SIGNATURE=y
|
||||
CONFIG_RSA=y
|
||||
CONFIG_RSA_VERIFY=y
|
||||
CONFIG_BLKMAP=y
|
||||
CONFIG_LZ4=y
|
||||
CONFIG_LZMA=y
|
||||
CONFIG_CMD_UNLZ4=y
|
||||
CONFIG_CMD_UNZIP=y
|
||||
CONFIG_CMD_IMI=y
|
||||
@@ -0,0 +1,19 @@
|
||||
/ {
|
||||
config {
|
||||
environment {
|
||||
vendor = "Microchip";
|
||||
bootcmd = "run ixboot";
|
||||
boot_targets = "mmc0";
|
||||
fdtfile = "microchip/at91-sama7g5ek.dtb";
|
||||
fdt_addr_r = "0x62000000";
|
||||
kernel_addr_r = "0x63000000";
|
||||
scriptaddr = "0x68000000";
|
||||
ramdisk_addr_r = "0x69000000";
|
||||
ixbootdelay = "0.5";
|
||||
bootdelay = "-2";
|
||||
bootmenu_delay = "10";
|
||||
ixbtn-devmode = "setenv dev_mode yes; echo Enabled";
|
||||
ixbtn-factory = "echo \"No button, use bootmenu\"";
|
||||
};
|
||||
};
|
||||
};
|
||||
@@ -0,0 +1,19 @@
|
||||
/ {
|
||||
config {
|
||||
environment {
|
||||
vendor = "Microchip";
|
||||
bootcmd = "run ixboot";
|
||||
boot_targets = "mmc1";
|
||||
fdtfile = "microchip/at91-sama7g5ek.dtb";
|
||||
fdt_addr_r = "0x62000000";
|
||||
kernel_addr_r = "0x63000000";
|
||||
scriptaddr = "0x68000000";
|
||||
ramdisk_addr_r = "0x69000000";
|
||||
ixbootdelay = "0.5";
|
||||
bootdelay = "-2";
|
||||
bootmenu_delay = "10";
|
||||
ixbtn-devmode = "setenv dev_mode yes; echo Enabled";
|
||||
ixbtn-factory = "echo \"No button, use bootmenu\"";
|
||||
};
|
||||
};
|
||||
};
|
||||
@@ -0,0 +1 @@
|
||||
CONFIG_DEVICE_TREE_INCLUDES="infix-env.dtsi infix-key.dtsi sama7g54-ek-env-sd.dtsi"
|
||||
@@ -0,0 +1,4 @@
|
||||
label Infix (arm)
|
||||
kernel /boot/zImage
|
||||
fdtdir /boot
|
||||
append ${bootargs_root} ${bootargs_log} usbcore.authorized_default=2 -- ${bootargs_user}
|
||||
@@ -1,11 +1,21 @@
|
||||
|
||||
menu "Images"
|
||||
|
||||
comment "DDI Based"
|
||||
source "$BR2_EXTERNAL_INFIX_PATH/board/common/image/image-ddi/Config.in"
|
||||
source "$BR2_EXTERNAL_INFIX_PATH/board/common/image/image-ddi-disk/Config.in"
|
||||
|
||||
comment "ITB Based"
|
||||
source "$BR2_EXTERNAL_INFIX_PATH/board/common/image/image-itb-rootfs/Config.in"
|
||||
source "$BR2_EXTERNAL_INFIX_PATH/board/common/image/image-itb-aux/Config.in"
|
||||
source "$BR2_EXTERNAL_INFIX_PATH/board/common/image/image-itb-qcow/Config.in"
|
||||
source "$BR2_EXTERNAL_INFIX_PATH/board/common/image/image-itb-gns3a/Config.in"
|
||||
source "$BR2_EXTERNAL_INFIX_PATH/board/common/image/image-itb-rauc/Config.in"
|
||||
source "$BR2_EXTERNAL_INFIX_PATH/board/common/image/image-itb-dl-release/Config.in"
|
||||
|
||||
comment "General"
|
||||
source "$BR2_EXTERNAL_INFIX_PATH/board/common/image/image-barebox-esp/Config.in"
|
||||
source "$BR2_EXTERNAL_INFIX_PATH/board/common/image/image-lvm-stub/Config.in"
|
||||
source "$BR2_EXTERNAL_INFIX_PATH/board/common/image/image-readme/Config.in"
|
||||
|
||||
endmenu
|
||||
|
||||
@@ -0,0 +1,102 @@
|
||||
#Simple dracut config for a system without systemd
|
||||
|
||||
#Dracut configuration
|
||||
|
||||
show_modules=yes
|
||||
i18n_install_all=no
|
||||
lvmconf=no
|
||||
mdadmconf=no
|
||||
early_microcode=no
|
||||
hostonly=no
|
||||
hostonly_cmdline=no
|
||||
use_fstab=no
|
||||
kernel_cmdline="rd.break=initqueue"
|
||||
do_strip=no
|
||||
|
||||
# Dracut modules needed
|
||||
add_dracutmodules+=" \
|
||||
busybox \
|
||||
"
|
||||
|
||||
# Modules to ignore
|
||||
omit_dracutmodules+=" \
|
||||
base \
|
||||
bash \
|
||||
biosdevname \
|
||||
btrfs \
|
||||
bluetooth \
|
||||
caps \
|
||||
cifs \
|
||||
connman \
|
||||
crypt \
|
||||
crypt-gpg \
|
||||
dash \
|
||||
dbus-broker \
|
||||
dbus-daemon \
|
||||
dm \
|
||||
dmraid \
|
||||
dmsquash-live-ntfs \
|
||||
dracut-systemd \
|
||||
fcoe \
|
||||
fcoe-uefi \
|
||||
fs-lib \
|
||||
iscsi \
|
||||
i18n \
|
||||
kernel-modules \
|
||||
kernel-modules-extra \
|
||||
lvmmerge \
|
||||
lvm \
|
||||
lunmask \
|
||||
mdraid \
|
||||
memstrack \
|
||||
mksh \
|
||||
modsign \
|
||||
mount-root \
|
||||
multipath \
|
||||
nbd \
|
||||
network-legacy \
|
||||
network-wicked \
|
||||
nfs \
|
||||
nvdimm \
|
||||
nvmf \
|
||||
parse-lunmask \
|
||||
pcsc \
|
||||
qemu \
|
||||
qemu-net \
|
||||
resume \
|
||||
rootfs-block \
|
||||
rngd \
|
||||
shutdown \
|
||||
systemd \
|
||||
systemd-udevd \
|
||||
systemd-coredump \
|
||||
systemd-ask-password \
|
||||
systemd-timedated \
|
||||
systemd-rfkill \
|
||||
systemd-resolved \
|
||||
systemd-hostnamed \
|
||||
systemd-initrd \
|
||||
systemd-integritysetup \
|
||||
systemd-journald \
|
||||
systemd-ldconfig \
|
||||
systemd-networkd \
|
||||
systemd-timesyncd \
|
||||
systemd-veritysetup \
|
||||
systemd-modules-load \
|
||||
systemd-pcrphase \
|
||||
systemd-portabled \
|
||||
systemd-pstore \
|
||||
systemd-sysctl \
|
||||
systemd-repart \
|
||||
systemd-sysext \
|
||||
systemd-sysusers \
|
||||
systemd-tmpfiles \
|
||||
squash \
|
||||
ssh-client \
|
||||
stratis \
|
||||
tpm2-tss \
|
||||
udev-rules \
|
||||
url-lib \
|
||||
usrmount \
|
||||
virtiofs \
|
||||
"
|
||||
@@ -0,0 +1,6 @@
|
||||
config IMAGE_BAREBOX_ESP
|
||||
bool "Barebox EFI System Partition"
|
||||
depends on BR2_TARGET_BAREBOX
|
||||
default y if IMAGE_DDI
|
||||
help
|
||||
An EFI System Partition (ESP) with Barebox installed.
|
||||
+38
@@ -0,0 +1,38 @@
|
||||
#!/bin/sh
|
||||
|
||||
set -e
|
||||
|
||||
case "$BR2_ARCH" in
|
||||
x86_64)
|
||||
BOOT_EFI=BOOTX64.EFI
|
||||
;;
|
||||
*)
|
||||
echo "Unknown EFI boot path for $BR2_ARCH" >&2
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
|
||||
mkdir -p "${WORKDIR}"/root
|
||||
rm -rf "${WORKDIR}"/tmp
|
||||
mkdir -p "${WORKDIR}"/tmp
|
||||
|
||||
cat <<EOF >"${WORKDIR}"/genimage.cfg
|
||||
image barebox-esp.vfat {
|
||||
size = "16M"
|
||||
vfat {
|
||||
file EFI/BOOT/$BOOT_EFI {
|
||||
image = $BINARIES_DIR/barebox.efi
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
# Silence genimage warnings
|
||||
config {}
|
||||
EOF
|
||||
|
||||
genimage \
|
||||
--tmppath "${WORKDIR}"/tmp \
|
||||
--rootpath "${WORKDIR}"/root \
|
||||
--inputpath "${WORKDIR}" \
|
||||
--outputpath "${BINARIES_DIR}" \
|
||||
--config "${WORKDIR}"/genimage.cfg
|
||||
@@ -0,0 +1,7 @@
|
||||
################################################################################
|
||||
#
|
||||
# image-barebox-esp
|
||||
#
|
||||
################################################################################
|
||||
|
||||
$(eval $(ix-image))
|
||||
@@ -0,0 +1,8 @@
|
||||
menuconfig IMAGE_DDI_DISK
|
||||
bool "LVM2 based provisioning disk (DDI)"
|
||||
depends on IMAGE_BAREBOX_ESP
|
||||
depends on IMAGE_DDI
|
||||
help
|
||||
Compose a full disk image consisting of an EFI System
|
||||
Partition (ESP) containing Barebox, and an LVM PV in which
|
||||
Infix is installed as an LV.
|
||||
+46
@@ -0,0 +1,46 @@
|
||||
#!/bin/sh
|
||||
|
||||
set -e
|
||||
|
||||
|
||||
mkdir -p "${WORKDIR}"/root
|
||||
rm -rf "${WORKDIR}"/tmp
|
||||
mkdir -p "${WORKDIR}"/tmp
|
||||
|
||||
"${BR2_EXTERNAL_INFIX_PATH}"/utils/lvm-mkinternal \
|
||||
"${BINARIES_DIR}"/"${ARTIFACT}".raw >"${WORKDIR}"/internal.lvm
|
||||
|
||||
cat <<EOF >"${WORKDIR}"/genimage.cfg
|
||||
|
||||
image ${ARTIFACT}.disk {
|
||||
hdimage {
|
||||
partition-table-type = "gpt"
|
||||
}
|
||||
|
||||
partition esp {
|
||||
partition-type-uuid = "esp"
|
||||
image = "$BINARIES_DIR/barebox-esp.vfat"
|
||||
}
|
||||
|
||||
partition esp-backup {
|
||||
partition-type-uuid = "esp"
|
||||
image = "$BINARIES_DIR/barebox-esp.vfat"
|
||||
}
|
||||
|
||||
partition internal {
|
||||
growfs = "true"
|
||||
partition-type-uuid = "lvm"
|
||||
image = "internal.lvm"
|
||||
}
|
||||
}
|
||||
|
||||
# Silence genimage warnings
|
||||
config {}
|
||||
EOF
|
||||
|
||||
genimage \
|
||||
--tmppath "${WORKDIR}"/tmp \
|
||||
--rootpath "${WORKDIR}"/root \
|
||||
--inputpath "${WORKDIR}" \
|
||||
--outputpath "${BINARIES_DIR}" \
|
||||
--config "${WORKDIR}"/genimage.cfg
|
||||
@@ -0,0 +1,9 @@
|
||||
################################################################################
|
||||
#
|
||||
# image-ddi-disk
|
||||
#
|
||||
################################################################################
|
||||
|
||||
IMAGE_DDI_DISK_DEPENDENCIES := image-barebox-esp image-ddi
|
||||
|
||||
$(eval $(ix-image))
|
||||
@@ -0,0 +1,33 @@
|
||||
menuconfig IMAGE_DDI
|
||||
bool "Discoverable Disk Image (DDI)"
|
||||
select BR2_TARGET_ROOTFS_SQUASHFS
|
||||
select BR2_PACKAGE_HOST_GENIMAGE
|
||||
help
|
||||
Create a Discoverable Disk Image containing:
|
||||
- SquashFS of the root filesystem
|
||||
- dm-verity hash tree of the root filesystem
|
||||
- DDI compliant JSON signature object of the hash tree
|
||||
|
||||
https://uapi-group.org/specifications/specs/discoverable_disk_image/
|
||||
|
||||
config IMAGE_DDI_KEY
|
||||
string "signing key"
|
||||
depends on IMAGE_DDI
|
||||
default "${BR2_EXTERNAL_INFIX_PATH}/board/common/signing-keys/development/infix.key"
|
||||
help
|
||||
Path to the private RSA key, in PKCS#8 format, used to sign
|
||||
the dm-verity hash tree.
|
||||
|
||||
config IMAGE_DDI_CERT
|
||||
string "signing cert"
|
||||
depends on IMAGE_DDI
|
||||
default "${BR2_EXTERNAL_INFIX_PATH}/board/common/signing-keys/development/infix.crt"
|
||||
help
|
||||
Path to the X509 certificate whose associated public key can
|
||||
validate the authenticity of the generated signature.
|
||||
|
||||
The SHA256 fingerprint of this certificate is recorded
|
||||
alongside the standard PKCS#7 signature in the JSON object,
|
||||
which can be useful to locate corresponding key on systems
|
||||
that lack full X509 parsing capabilities.
|
||||
|
||||
Executable
+81
@@ -0,0 +1,81 @@
|
||||
#!/bin/sh
|
||||
|
||||
# Generate the DDI in two phases. First we create the verity hash tree
|
||||
# and signature, then we collect them together with the rootfs in the
|
||||
# ddi. The reason for this is that genimage (at least up to v19) can
|
||||
# not infer the size of a partition if the image to be placed in it is
|
||||
# created by the same genimage instance. With the two-phase approach,
|
||||
# we work around that problem and can create a DDI without any wasted
|
||||
# space.
|
||||
|
||||
set -e
|
||||
|
||||
rm -rf "${WORKDIR}"/tmp
|
||||
mkdir -p "${WORKDIR}"/tmp "${WORKDIR}"/verity
|
||||
|
||||
cat <<EOF >"${WORKDIR}"/genimage-verity.cfg
|
||||
image rootfs.verity {
|
||||
verity {
|
||||
image = "rootfs.squashfs"
|
||||
}
|
||||
}
|
||||
|
||||
image rootfs.verity-sig {
|
||||
verity-sig {
|
||||
image = "rootfs.verity"
|
||||
cert = "${CERT}"
|
||||
key = "${KEY}"
|
||||
}
|
||||
}
|
||||
|
||||
config {}
|
||||
EOF
|
||||
|
||||
genimage \
|
||||
--loglevel 1 \
|
||||
--tmppath "${WORKDIR}"/tmp \
|
||||
--rootpath "${WORKDIR}" \
|
||||
--inputpath "${BINARIES_DIR}" \
|
||||
--outputpath "${WORKDIR}"/verity \
|
||||
--config "${WORKDIR}"/genimage-verity.cfg
|
||||
|
||||
case "${BR2_ARCH}" in
|
||||
"x86_64")
|
||||
arch=x86-64
|
||||
;;
|
||||
*)
|
||||
echo "ERROR: missing mapping from ${BR2_ARCH} to genimage arch" >&2
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
|
||||
cat <<EOF >"${WORKDIR}"/genimage-ddi.cfg
|
||||
image ${ARTIFACT}.raw {
|
||||
hdimage {
|
||||
partition-table-type = "gpt"
|
||||
}
|
||||
|
||||
partition root {
|
||||
partition-type-uuid = "root-${arch}"
|
||||
image = "rootfs.squashfs"
|
||||
}
|
||||
partition root-verity {
|
||||
partition-type-uuid = "root-${arch}-verity"
|
||||
image = "${WORKDIR}/verity/rootfs.verity"
|
||||
}
|
||||
partition root-verity-sig {
|
||||
partition-type-uuid = "root-${arch}-verity-sig"
|
||||
image = "${WORKDIR}/verity/rootfs.verity-sig"
|
||||
}
|
||||
}
|
||||
|
||||
config {}
|
||||
EOF
|
||||
|
||||
genimage \
|
||||
--loglevel 1 \
|
||||
--tmppath "${WORKDIR}"/tmp \
|
||||
--rootpath "${WORKDIR}" \
|
||||
--inputpath "${BINARIES_DIR}" \
|
||||
--outputpath "${BINARIES_DIR}" \
|
||||
--config "${WORKDIR}"/genimage-ddi.cfg
|
||||
@@ -0,0 +1,32 @@
|
||||
image rootfs.verity {
|
||||
verity {
|
||||
image = "rootfs.squashfs"
|
||||
}
|
||||
}
|
||||
|
||||
image rootfs.verity-sig {
|
||||
verity-sig {
|
||||
image = "rootfs.verity"
|
||||
cert = "@CERT@"
|
||||
key = "@KEY@"
|
||||
}
|
||||
}
|
||||
|
||||
image @ARTIFACT@.raw {
|
||||
hdimage {
|
||||
partition-table-type = "gpt"
|
||||
}
|
||||
|
||||
partition root {
|
||||
partition-type-uuid = "root-@ARCH@"
|
||||
image = "rootfs.squashfs"
|
||||
}
|
||||
partition root-verity {
|
||||
partition-type-uuid = "root-@ARCH@-verity"
|
||||
image = "rootfs.verity"
|
||||
}
|
||||
partition root-verity-sig {
|
||||
partition-type-uuid = "root-@ARCH@-verity-sig"
|
||||
image = "rootfs.verity-sig"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
################################################################################
|
||||
#
|
||||
# image-ddi
|
||||
#
|
||||
################################################################################
|
||||
|
||||
IMAGE_DDI_DEPENDENCIES := host-genimage rootfs-squashfs
|
||||
IMAGE_DDI_CONFIG_VARS := KEY CERT
|
||||
|
||||
$(eval $(ix-image))
|
||||
@@ -0,0 +1,15 @@
|
||||
tmpfs /tmp tmpfs mode=0755,nosuid,nodev 0 0
|
||||
tmpfs /run tmpfs mode=0755,nosuid,nodev 0 0
|
||||
tmpfs /media tmpfs mode=1755,nosuid,nodev 0 0
|
||||
tmpfs /mnt/tmp tmpfs defaults 0 0
|
||||
|
||||
# Locate and mount /cfg, /home, /root and /var from the internal
|
||||
# volume, wherever that is located - or, as a last resort, setup tmpfs
|
||||
# mounts at these points. Setup an ephemeral writable overlay on /etc.
|
||||
/usr/libexec/infix/mnt# /mnt/rw helper none 0 0
|
||||
|
||||
# Optional, nice-to-have mounts
|
||||
debugfs /sys/kernel/debug debugfs nofail 0 0
|
||||
tracefs /sys/kernel/tracing tracefs nofail 0 0
|
||||
cfgfs /config configfs nofail,noauto 0 0
|
||||
host /mnt/host 9p nofail,noauto,cache=none,msize=16384 0 0
|
||||
+211
@@ -0,0 +1,211 @@
|
||||
#!/bin/sh
|
||||
# Called from /etc/fstab to ensure we have something writable mounted
|
||||
# at /cfg, /home, /root, and /var.
|
||||
#
|
||||
# In the normal case, the "rw" LV from the "internal" LVM VG is used
|
||||
# to back all persistant storage. In the event that "internal" is
|
||||
# present, but the "rw" LV is missing, one will be provisioned, along
|
||||
# with the required BTRFS subvolumes.
|
||||
#
|
||||
# In all other scenarios where the subvolumes are not available, the
|
||||
# system will fall back to temporary storage for all mount points.
|
||||
#
|
||||
# For /etc, a writable, tmpfs backed, layer is always overlayed on top
|
||||
# of the read-only contents from the OS image.
|
||||
|
||||
set -e
|
||||
|
||||
nm=$(basename "$0")
|
||||
need_restore=
|
||||
code=0
|
||||
|
||||
logmsg()
|
||||
{
|
||||
logger -k -t "$nm" -p user.crit "$@"
|
||||
}
|
||||
|
||||
status()
|
||||
{
|
||||
GREEN="$(printf '\033[1;32m')"
|
||||
RED="$(printf '\033[1;31m')"
|
||||
YELLOW="$(printf '\033[1;33m')"
|
||||
BOLD="$(printf '\033[1m')"
|
||||
RESET="$(printf '\033[0m')"
|
||||
|
||||
case $1 in
|
||||
0) color=$GREEN; text=' OK ' ;;
|
||||
1) color=$RED; text='FAIL' ;;
|
||||
2) color=$YELLOW;text='WARN' ;;
|
||||
*) color=$YELLOW;text=' ⋯ ' ;;
|
||||
esac
|
||||
|
||||
printf '%s[%s%s%s%s]%s ' "$BOLD" "$color" "$text" "$RESET" "$BOLD" "$RESET"
|
||||
}
|
||||
|
||||
print_start()
|
||||
{
|
||||
printf '\r\033[K%s%s' "$(status 3)" "$*" > /dev/console
|
||||
need_restore=YES
|
||||
}
|
||||
|
||||
print_end()
|
||||
{
|
||||
rc=$1; shift
|
||||
if [ $# -gt 0 ]; then
|
||||
printf '\r\033[K%s%s\n' "$(status "$rc")" "$*" > /dev/console
|
||||
else
|
||||
printf '\r%s\n' "$(status "$rc")" > /dev/console
|
||||
fi
|
||||
}
|
||||
|
||||
# Restore Finit's original progress message so its [ OK ] appears correctly
|
||||
print_restore()
|
||||
{
|
||||
[ "$need_restore" ] || return 0
|
||||
print_start "Mounting filesystems from /etc/fstab"
|
||||
}
|
||||
|
||||
# # External button or bootloader changed kernel command line
|
||||
# check_factory()
|
||||
# {
|
||||
# if [ -f /mnt/cfg/infix/.reset ]; then
|
||||
# return 0;
|
||||
# fi
|
||||
|
||||
# if grep -q 'finit.cond=factory-reset' /proc/cmdline; then
|
||||
# return 0;
|
||||
# fi
|
||||
|
||||
# # Add to your br2-external to extend factory-reset check
|
||||
# if [ ! -x /usr/libexec/infix/check-factory ]; then
|
||||
# return 1;
|
||||
# fi
|
||||
|
||||
# /usr/libexec/infix/check-factory
|
||||
# }
|
||||
|
||||
# factory_reset()
|
||||
# {
|
||||
# find /sys/class/leds/ -type l -exec sh -c 'echo 100 > $0/brightness' {} \;
|
||||
# print_start "Resetting to factory defaults."
|
||||
# logger $opt -p user.notice -t "$nm" "Resetting to factory defaults."
|
||||
|
||||
# rm -rf /mnt/cfg/* /mnt/var/*
|
||||
# sync
|
||||
|
||||
# logger $opt -p user.notice -t "$nm" "Factory reset complete."
|
||||
# print_end 0 "Factory reset complete."
|
||||
# print_restore
|
||||
# }
|
||||
|
||||
subvols="cfg var root home"
|
||||
|
||||
internal_rw_provision()
|
||||
{
|
||||
print_start "Provisioning persistent storage on internal volume"
|
||||
|
||||
lvm lvcreate --name rw --extents 50%FREE internal || {
|
||||
logmsg "No rw LV available, nor could it be created"
|
||||
print_end 1
|
||||
return 1
|
||||
}
|
||||
|
||||
mkfs.btrfs -L rw /dev/internal/rw || {
|
||||
logmsg "Could not create BTRFS on rw LV"
|
||||
print_end 1
|
||||
return 1
|
||||
}
|
||||
|
||||
mount -t btrfs /dev/internal/rw /mnt/rw || {
|
||||
logmsg "Failed to mount rw"
|
||||
print_end 1
|
||||
return 1
|
||||
}
|
||||
|
||||
for subvol in $subvols; do
|
||||
btrfs subvolume create /mnt/rw/@"$subvol" || {
|
||||
logmsg "Failed to create @$subvol on rw"
|
||||
print_end 1
|
||||
return 1
|
||||
}
|
||||
done
|
||||
|
||||
umount /mnt/rw || {
|
||||
logmsg "Failed to unmount rw"
|
||||
print_end 1
|
||||
return 1
|
||||
}
|
||||
|
||||
print_end 0
|
||||
}
|
||||
|
||||
internal_rw_activate()
|
||||
{
|
||||
lvm vgs internal || {
|
||||
logmsg "No internal volume available"
|
||||
return 1
|
||||
}
|
||||
|
||||
lvm vgchange -ay internal || {
|
||||
logmsg "Unable to bring internal volume online"
|
||||
return 1
|
||||
}
|
||||
|
||||
# The only condition under which we do BTRFS provisioning is when
|
||||
# the LV is absent. In all other failure scenarios: fall back to
|
||||
# tmpfs and let the user sort it out. This way we do not risk any
|
||||
# loss of data.
|
||||
[ -b /dev/internal/rw ] && return 0
|
||||
|
||||
internal_rw_provision
|
||||
}
|
||||
|
||||
internal_rw_mount()
|
||||
{
|
||||
internal_rw_activate || return 1
|
||||
|
||||
for subvol in $subvols; do
|
||||
mount -t btrfs /dev/internal/rw /"$subvol" -o subvol=@"$subvol" || {
|
||||
logmsg "Failed to mount /$subvol"
|
||||
return 1
|
||||
}
|
||||
done
|
||||
}
|
||||
|
||||
tmpfs_rw_mount()
|
||||
{
|
||||
for subvol in $subvols; do
|
||||
mkdir -p -m 0755 /mnt/tmp/"$subvol"
|
||||
mount /mnt/tmp/"$subvol" /"$subvol" -o bind || {
|
||||
logmsg "Failed to mount temporary /$subvol"
|
||||
return 1
|
||||
}
|
||||
done
|
||||
}
|
||||
|
||||
tmpfs_etc_mount()
|
||||
{
|
||||
mkdir -p -m 0755 /mnt/tmp/etc/
|
||||
tar c -C /etc . | tar x -C /mnt/tmp/etc
|
||||
mount /mnt/tmp/etc /etc -o bind
|
||||
}
|
||||
|
||||
exec >/mnt/tmp/mnt.log 2>&1
|
||||
|
||||
tmpfs_etc_mount || {
|
||||
code=1
|
||||
logmsg "Failed to make /etc writable"
|
||||
}
|
||||
|
||||
if ! internal_rw_mount; then
|
||||
code=1
|
||||
print_end 1 "Mounting persistent storage from internal volume"
|
||||
logmsg "Internal volume not found, falling back to tmpfs"
|
||||
|
||||
print_start "Falling back to ephemeral tmpfs storage!"
|
||||
tmpfs_rw_mount
|
||||
print_end $?
|
||||
fi
|
||||
|
||||
print_restore
|
||||
exit $code
|
||||
@@ -0,0 +1,8 @@
|
||||
config IMAGE_LVM_STUB
|
||||
bool "LVM2 stub image"
|
||||
default y if IMAGE_DDI
|
||||
help
|
||||
An empty LVM2 physical volume attached to the internal
|
||||
volume group. This is useful as a base image for persistent
|
||||
storage in QEMU emulation scenarios where the OS is supplied
|
||||
in a separate image.
|
||||
+34
@@ -0,0 +1,34 @@
|
||||
#!/bin/sh
|
||||
|
||||
set -e
|
||||
|
||||
|
||||
mkdir -p "${WORKDIR}"/root
|
||||
rm -rf "${WORKDIR}"/tmp
|
||||
mkdir -p "${WORKDIR}"/tmp
|
||||
|
||||
"${BR2_EXTERNAL_INFIX_PATH}"/utils/lvm-mkinternal >"${WORKDIR}"/stub.lvm
|
||||
|
||||
cat <<EOF >"${WORKDIR}"/genimage.cfg
|
||||
image lvm-stub.disk {
|
||||
hdimage {
|
||||
partition-table-type = "gpt"
|
||||
}
|
||||
|
||||
partition internal {
|
||||
growfs = "true"
|
||||
image = "stub.lvm"
|
||||
partition-type-uuid = "lvm"
|
||||
}
|
||||
}
|
||||
|
||||
# Silence genimage warnings
|
||||
config {}
|
||||
EOF
|
||||
|
||||
genimage \
|
||||
--tmppath "${WORKDIR}"/tmp \
|
||||
--rootpath "${WORKDIR}"/root \
|
||||
--inputpath "${WORKDIR}" \
|
||||
--outputpath "${BINARIES_DIR}" \
|
||||
--config "${WORKDIR}"/genimage.cfg
|
||||
@@ -0,0 +1,7 @@
|
||||
################################################################################
|
||||
#
|
||||
# image-lvm-stub
|
||||
#
|
||||
################################################################################
|
||||
|
||||
$(eval $(ix-image))
|
||||
@@ -10,6 +10,7 @@ $(1): $$($(2)_DEPENDENCIES)
|
||||
PKGDIR=$$($(2)_DIR) \
|
||||
WORKDIR=$$(BUILD_DIR)/$(1) \
|
||||
BINARIES_DIR=$$(BINARIES_DIR) \
|
||||
BR2_ARCH=$$(BR2_ARCH) \
|
||||
BR2_EXTERNAL_INFIX_PATH=$$(BR2_EXTERNAL_INFIX_PATH) \
|
||||
ARTIFACT=$$(INFIX_ARTIFACT) \
|
||||
COMPATIBLE=$$(INFIX_COMPATIBLE) \
|
||||
@@ -19,6 +20,7 @@ $(1): $$($(2)_DEPENDENCIES)
|
||||
|
||||
ifeq ($$($(2)),y)
|
||||
TARGETS_ROOTFS += $(1)
|
||||
BR2_ROOTFS_OVERLAY := "$$(realpath $$(pkgdir)/rootfs) $$(call qstrip,$$(BR2_ROOTFS_OVERLAY))"
|
||||
endif
|
||||
|
||||
endef
|
||||
|
||||
+15
@@ -0,0 +1,15 @@
|
||||
#!/bin/bash
|
||||
|
||||
check() {
|
||||
return 0
|
||||
}
|
||||
|
||||
depends() {
|
||||
return 0
|
||||
}
|
||||
|
||||
install() {
|
||||
# Not sure if this should be handled by buildroot's merged-usr
|
||||
# module. Fix it here for now.
|
||||
ln -s "lib" "${initdir?}/lib64"
|
||||
}
|
||||
Executable
+279
@@ -0,0 +1,279 @@
|
||||
#!/bin/sh
|
||||
|
||||
echo -ne "\e[31m●\e[0m \e[33m●\e[0m \e[32m●\e[0m Infix Initramfs — " >/dev/console
|
||||
source /etc/os-release >/dev/console
|
||||
echo "$VERSION"
|
||||
|
||||
set -e
|
||||
|
||||
getkopt()
|
||||
{
|
||||
grep -q -E "(^| )$1( |$)" /proc/cmdline
|
||||
}
|
||||
|
||||
getkparam()
|
||||
{
|
||||
sed -n "s/.*\<$1=\([^ ]*\).*/\1/p" /proc/cmdline
|
||||
}
|
||||
|
||||
debug_shell()
|
||||
{
|
||||
[ "$(getkparam rd.shell)" = "$1" ] || return 0
|
||||
|
||||
exec </dev/console &>/dev/console
|
||||
echo "Starting debug shell at $1"
|
||||
exec sh -i
|
||||
}
|
||||
|
||||
die()
|
||||
{
|
||||
step="${*:-$step}"
|
||||
|
||||
echo -e "\r\e[0K[\e[31mFAIL\e[0m] $step" >/dev/console
|
||||
echo "<0>ix-initramfs: ERROR: $step" >/dev/kmsg
|
||||
debug_shell error
|
||||
exit 1
|
||||
}
|
||||
|
||||
warn()
|
||||
{
|
||||
step="${*:-$step}"
|
||||
|
||||
echo -e "\r\e[0K[\e[33mWARN\e[0m] $step" >/dev/console
|
||||
echo "<5>ix-initramfs: WARNING: $step" >/dev/kmsg
|
||||
debug_shell warning
|
||||
}
|
||||
|
||||
ok()
|
||||
{
|
||||
step="${*:-$step}"
|
||||
|
||||
echo -e "\r\e[0K[\e[32m OK \e[0m] $step" >/dev/console
|
||||
echo "<5>ix-initramfs: $step" >/dev/kmsg
|
||||
}
|
||||
|
||||
begin()
|
||||
{
|
||||
step="$*"
|
||||
echo -ne "[\e[33m ⋯ \e[0m] $step" >/dev/console
|
||||
}
|
||||
|
||||
debug()
|
||||
{
|
||||
echo "<7>ix-initramfs: $*" >/dev/kmsg
|
||||
}
|
||||
|
||||
mountcore()
|
||||
{
|
||||
mount -t proc proc /proc
|
||||
mount -t sysfs sys /sys
|
||||
mount -t devtmpfs dev /dev
|
||||
}
|
||||
|
||||
mountroot()
|
||||
{
|
||||
mkdir /newroot
|
||||
mount "$1" /newroot || \
|
||||
die "Unable to mount rootfs on $1"
|
||||
|
||||
ok "Mounting root filesystem on $(basename $1)"
|
||||
}
|
||||
|
||||
switchroot()
|
||||
{
|
||||
local innerinit=$(getkparam init)
|
||||
|
||||
ok "Switching to root filesystem"
|
||||
exec switch_root /newroot ${innerinit:-/sbin/init}
|
||||
}
|
||||
|
||||
internal_get_part()
|
||||
{
|
||||
local _i _pv
|
||||
|
||||
for _i in $(seq 50); do
|
||||
_pv=$(lvm pvs --reportformat json \
|
||||
| jq -r '.report[].pv[] | select(.vg_name == "internal") | .pv_name')
|
||||
if [ "$_pv" ]; then
|
||||
[ $_i -gt 5 ] && ok
|
||||
echo "$_pv"
|
||||
return 0
|
||||
fi
|
||||
|
||||
[ $_i -eq 5 ] && begin "Waiting for the internal volume to come online"
|
||||
sleep .2
|
||||
done
|
||||
|
||||
warn "Proceeding without the internal volume"
|
||||
return 0
|
||||
}
|
||||
|
||||
internal_inflate()
|
||||
{
|
||||
local _dev _growfs _index _part
|
||||
|
||||
getkopt rd.nointernal && return 0
|
||||
|
||||
GPT_PART_GROWFS_BIT=59
|
||||
|
||||
_part=$(internal_get_part)
|
||||
[ "$_part" ] || return 0
|
||||
|
||||
_index=$(cat /sys/class/block/$(basename "$_part")/partition)
|
||||
[ "$_index" ] || return 1
|
||||
|
||||
_dev=/dev/$(basename $(realpath /sys/class/block/$(basename "$_part")/../))
|
||||
[ -b "$_dev" ] || return 1
|
||||
|
||||
sgdisk "$_dev" -A "$_index":get:$GPT_PART_GROWFS_BIT \
|
||||
| grep -q "$_index:$GPT_PART_GROWFS_BIT:1" \
|
||||
|| return 0
|
||||
|
||||
begin "Inflating internal VG in $_part"
|
||||
|
||||
# First, expand the GPT to cover the entire disk and expand the
|
||||
# LVM partition as much as possible.
|
||||
if ! sgdisk "$_dev" \
|
||||
--disk-guid=random \
|
||||
--set-alignment=1 \
|
||||
--move-second-header \
|
||||
--delete="$_index" \
|
||||
--largest-new="$_index" --typecode="$_index":8e00 \
|
||||
>/tmp/internal-inflate.log 2>&1; then
|
||||
warn "Failed to inflate GPT on $_dev"
|
||||
return 0
|
||||
fi
|
||||
|
||||
if ! lvm pvresize "$_part" >>/tmp/internal-inflate.log 2>&1; then
|
||||
warn "Failed to resize PV $_part"
|
||||
return 0
|
||||
fi
|
||||
|
||||
ok "Inflated internal VG in $_part"
|
||||
}
|
||||
|
||||
addparts()
|
||||
{
|
||||
local _disk="$1"
|
||||
local _partscan="/sys/class/block/"$(basename "$_disk")/partscan
|
||||
|
||||
[ -f "$_partscan" ] && [ $(cat "$_partscan") -eq 1 ] && return
|
||||
|
||||
kpartx -a "$_disk" 2>/dev/null || die "addparts: Unable to add partitions from $_disk"
|
||||
}
|
||||
|
||||
gptuuid_probe()
|
||||
{
|
||||
local _uuid=$(echo "$1" | sed -e 's/^GPTUUID=//' | tr ABCDEF abcdef)
|
||||
local _cand _disk _initrd
|
||||
|
||||
[ -f /initrd.image ] && _initrd=/initrd.image
|
||||
|
||||
for _disk in $_initrd $(find /dev/ -type b); do
|
||||
_cand=$(ddi "$_disk" inspect uuid | tr ABCDEF abcdef)
|
||||
[ $? -eq 0 ] || continue
|
||||
|
||||
if [ "$_cand" = "$_uuid" ]; then
|
||||
ok "Located $_uuid in $_disk"
|
||||
echo "$_disk"
|
||||
return
|
||||
fi
|
||||
done
|
||||
|
||||
die "gptuuid_probe: Unable to find disk $_uuid"
|
||||
}
|
||||
|
||||
ddi_probe()
|
||||
{
|
||||
local _disk="$1"
|
||||
local _dm="$(basename $_disk).root"
|
||||
local _hash=$(getkparam rd.ddi.roothash)
|
||||
local _v _trust
|
||||
|
||||
if [ -n "$_hash" ]; then
|
||||
ok "Trusting pre-authenticated root hash"
|
||||
_v="-V $_hash"
|
||||
else
|
||||
_v="-v"
|
||||
fi
|
||||
|
||||
_trust=$(ddi "$_disk" part root open $_v "$_dm" 2>&1 \
|
||||
|| die "ddi_probe: veritysetup of $_disk failed")
|
||||
|
||||
ok "$_trust"
|
||||
ok "Opened verity protected root from $(basename $_disk)"
|
||||
echo /dev/mapper/"$_dm"
|
||||
}
|
||||
|
||||
lvm_probe()
|
||||
{
|
||||
local _vg=$(dirname "$1") _lv=$(basename "$1")
|
||||
|
||||
lvm vgchange -ay "$_vg" &>/dev/null || \
|
||||
die "lvm_probe: Failed to activate the $_vg VG"
|
||||
|
||||
[ -b /dev/"$1" ] || die "lvm_probe: Unable to locate the $_lv LV in $_vg"
|
||||
|
||||
echo /dev/"$1"
|
||||
}
|
||||
|
||||
lo_probe()
|
||||
{
|
||||
local _lo=$(losetup -f || die "probe_lo: found no free loop device for $1")
|
||||
losetup -P "$_lo" "$1" || die "probe_lo: losetup of $1 to $_lo failed"
|
||||
|
||||
debug "lo_probe: setup $_lo backed by $1"
|
||||
echo "$_lo"
|
||||
}
|
||||
|
||||
probe()
|
||||
{
|
||||
local _real _kind
|
||||
|
||||
case "$1" in
|
||||
/*)
|
||||
_real=$(realpath "$1")
|
||||
_kind=$(stat -c %F "$_real" 2>/dev/null || true)
|
||||
case "$_kind" in
|
||||
"block special file")
|
||||
addparts "$_real"
|
||||
echo "$_real"
|
||||
;;
|
||||
"regular file")
|
||||
lo_probe "$_real"
|
||||
;;
|
||||
"")
|
||||
die "Unknown root \"$1\""
|
||||
;;
|
||||
*)
|
||||
die "Unsupported root \"$1\": $_kind"
|
||||
;;
|
||||
esac
|
||||
;;
|
||||
lvm)
|
||||
shift
|
||||
probe $(lvm_probe "$@")
|
||||
;;
|
||||
ddi)
|
||||
shift
|
||||
ddi_probe $(probe "$@")
|
||||
;;
|
||||
GPTUUID=*)
|
||||
gptuuid_probe "$@"
|
||||
;;
|
||||
esac
|
||||
}
|
||||
|
||||
mountcore
|
||||
|
||||
debug_shell internal
|
||||
internal_inflate
|
||||
|
||||
debug_shell probe
|
||||
rootdev=$(probe $(getkparam root | sed -e 's/:/ /g'))
|
||||
|
||||
debug_shell mount
|
||||
mountroot "$rootdev"
|
||||
|
||||
debug_shell switchroot
|
||||
switchroot
|
||||
+21
@@ -0,0 +1,21 @@
|
||||
#!/bin/bash
|
||||
|
||||
progs="blkid ddi dmsetup kpartx jq lvm openssl sgdisk veritysetup"
|
||||
|
||||
check() {
|
||||
require_binaries $progs || return 1
|
||||
|
||||
return 0
|
||||
}
|
||||
|
||||
depends() {
|
||||
return 0
|
||||
}
|
||||
|
||||
install() {
|
||||
inst_multiple $progs
|
||||
inst '/etc/os-release'
|
||||
inst '/etc/rauc/keys/*'
|
||||
|
||||
cp "$moddir/init" "${initdir?}/init"
|
||||
}
|
||||
@@ -0,0 +1,279 @@
|
||||
mainmenu "QEMU @ARCH@ Virtualization"
|
||||
|
||||
config QEMU_@ARCH@
|
||||
bool
|
||||
default y
|
||||
|
||||
config QEMU_ARCH
|
||||
string
|
||||
default "@ARCH@"
|
||||
|
||||
config QEMU_VIRTIO_BUS
|
||||
string
|
||||
default "device" if QEMU_arm
|
||||
default "pci"
|
||||
|
||||
config QEMU_BIN_DDI
|
||||
string
|
||||
default "@IMAGE@"
|
||||
|
||||
config QEMU_BIN_DISK
|
||||
string
|
||||
default "@DISK@"
|
||||
|
||||
config QEMU_BIN_ESP
|
||||
string
|
||||
default "@ESP@"
|
||||
|
||||
config QEMU_BIN_KERNEL
|
||||
string
|
||||
depends on QEMU_LOADER_QEMU
|
||||
default "../zImage" if QEMU_arm
|
||||
default "../Image" if QEMU_aarch64
|
||||
default "../bzImage" if QEMU_x86_64
|
||||
|
||||
config QEMU_BIN_LVM_STUB
|
||||
string
|
||||
default "../lvm-stub.disk"
|
||||
|
||||
|
||||
choice
|
||||
prompt "Loader"
|
||||
default QEMU_LOADER_QEMU
|
||||
|
||||
config QEMU_LOADER_QEMU
|
||||
bool "QEMU"
|
||||
|
||||
config QEMU_LOADER_OVMF
|
||||
bool "OVMF (UEFI)"
|
||||
|
||||
endchoice
|
||||
|
||||
config QEMU_BIN_BIOS
|
||||
string
|
||||
depends on !QEMU_LOADER_KERNEL
|
||||
default "OVMF.fd" if QEMU_LOADER_OVMF
|
||||
|
||||
menu "Machine"
|
||||
|
||||
config QEMU_MACHINE
|
||||
string "Machine"
|
||||
default "pc" if QEMU_x86_64
|
||||
default "virt"
|
||||
|
||||
config QEMU_CPU
|
||||
string "CPU"
|
||||
default "host" if QEMU_x86_64
|
||||
default "cortex-a53" if QEMU_aarch64
|
||||
default "max"
|
||||
|
||||
config QEMU_RAM
|
||||
string "RAM size (k/M/G)"
|
||||
default "384M"
|
||||
|
||||
choice
|
||||
prompt "Console"
|
||||
default QEMU_CONSOLE_VIRTIO
|
||||
|
||||
config QEMU_CONSOLE_VIRTIO
|
||||
bool "Virtio (hvc0)"
|
||||
|
||||
config QEMU_CONSOLE_SERIAL
|
||||
bool "Serial (ttyS0/ttyAMA0)"
|
||||
|
||||
endchoice
|
||||
|
||||
config QEMU_CONSOLE
|
||||
string
|
||||
default "hvc0" if QEMU_CONSOLE_VIRTIO
|
||||
default "ttyAMA0" if QEMU_arm
|
||||
default "ttyAMA0" if QEMU_aarch64
|
||||
default "ttyS0"
|
||||
|
||||
endmenu
|
||||
|
||||
menu "Disks & Filesystems"
|
||||
|
||||
config QEMU_DISK_INITRD
|
||||
bool "Use the DDI as initrd"
|
||||
depends on QEMU_LOADER_QEMU
|
||||
help
|
||||
Pass, and boot from, the DDI as the initial RAM disk.
|
||||
|
||||
This is useful to test netbooting scenarios, e.g., in
|
||||
combination with an empty system disk to simulate an initial
|
||||
deployment.
|
||||
|
||||
comment "System disk"
|
||||
|
||||
choice
|
||||
prompt "Interface"
|
||||
default QEMU_DISK_SYS_IF_VIRTIO
|
||||
|
||||
config QEMU_DISK_SYS_IF_VIRTIO
|
||||
bool "virtio"
|
||||
help
|
||||
Attach system disks using virtio block devices.
|
||||
|
||||
endchoice
|
||||
|
||||
choice
|
||||
prompt "Contents"
|
||||
default QEMU_DISK_SYS_SPLIT
|
||||
|
||||
config QEMU_DISK_SYS_EMPTY
|
||||
bool "Empty disk"
|
||||
help
|
||||
Attach an empty disk.
|
||||
|
||||
This is useful for testing things like installing Infix from a
|
||||
USB mass storage device (see "USB Mass Storage" below).
|
||||
|
||||
config QEMU_DISK_SYS_FULL
|
||||
bool "Full system disk"
|
||||
help
|
||||
Use the full system disk containing:
|
||||
- EFI partition (and backup) with Barebox
|
||||
- LVM PV with Infix installed
|
||||
|
||||
This is useful when testing system upgrades, fallback
|
||||
mechanisms related to corrupt disks etc.
|
||||
|
||||
WARNING: Usage of this option is fraught with peril as
|
||||
incremental builds of Infix are likely to cause corruption in
|
||||
the QCoW2 layer. If you do not understand the meaning of this
|
||||
you most likely to NOT want to make use of this feature.
|
||||
|
||||
config QEMU_DISK_SYS_NONE
|
||||
bool "None"
|
||||
help
|
||||
Do not attach any system disk.
|
||||
|
||||
This is useful for testing how Infix behaves when no persistent
|
||||
storage is available - a common scenario during bringup of a
|
||||
new board.
|
||||
|
||||
config QEMU_DISK_SYS_SPLIT
|
||||
bool "Split ESP/DDI/LVM"
|
||||
help
|
||||
Attach the EFI System partition, containing Barebox; the raw
|
||||
DDI image; and an (initially empty) LVM stub for persistent
|
||||
storage - each as a separate disk.
|
||||
|
||||
This is the simplest way of testing out incremental builds of
|
||||
Infix. Since the DDI is attached as a raw read-only disk, there
|
||||
is no risk of CoW corruption like with a full system disk.
|
||||
|
||||
NOTE: In this setup, the size below refers to the size of the
|
||||
LVM stub.
|
||||
|
||||
endchoice
|
||||
|
||||
config QEMU_DISK_SYS_SIZE
|
||||
string "Size (k/M/G)"
|
||||
default "8G"
|
||||
|
||||
comment "USB mass storage"
|
||||
|
||||
choice
|
||||
prompt "Contents"
|
||||
default QEMU_DISK_USB_NONE
|
||||
|
||||
config QEMU_DISK_USB_DISK
|
||||
bool "Full system disk"
|
||||
help
|
||||
Attach the full system disk containing:
|
||||
- EFI partition (and backup) with Barebox
|
||||
- LVM PV with Infix installed
|
||||
|
||||
config QEMU_DISK_USB_NONE
|
||||
bool "None"
|
||||
help
|
||||
Do not attach any disk over USB.
|
||||
|
||||
endchoice
|
||||
|
||||
config QEMU_DISK_USB_SIZE
|
||||
string "Size (k/M/G)"
|
||||
depends on !QEMU_DISK_USB_NONE
|
||||
default "4G"
|
||||
|
||||
comment "Host filesystem passthrough (9P)"
|
||||
|
||||
config QEMU_DISK_HOST
|
||||
string "Path"
|
||||
default "/tmp"
|
||||
|
||||
endmenu
|
||||
|
||||
menu "Networking"
|
||||
|
||||
choice
|
||||
prompt "Mode"
|
||||
default QEMU_NET_USER
|
||||
|
||||
config QEMU_NET_BRIDGE
|
||||
bool "Bridged"
|
||||
|
||||
config QEMU_NET_NONE
|
||||
bool "None"
|
||||
|
||||
config QEMU_NET_ROCKER
|
||||
bool "Rocker"
|
||||
|
||||
config QEMU_NET_TAP
|
||||
bool "TAP"
|
||||
|
||||
config QEMU_NET_USER
|
||||
bool "User"
|
||||
|
||||
endchoice
|
||||
|
||||
config QEMU_NET_MODE
|
||||
string
|
||||
default "bridge" if QEMU_NET_BRIDGE
|
||||
default "none" if QEMU_NET_NONE
|
||||
default "rocker" if QEMU_NET_ROCKER
|
||||
default "tap" if QEMU_NET_TAP
|
||||
default "user" if QEMU_NET_USER
|
||||
|
||||
config QEMU_NET_MODEL
|
||||
string "Interface model"
|
||||
default "virtio-net-device" if QEMU_arm
|
||||
default "virtio-net-pci"
|
||||
help
|
||||
The default virtio NIC works for most use-cases, but if you
|
||||
want to play with low-level stuff like ethtool, you might
|
||||
want to test the Intel 82545EM driver, e1000.
|
||||
|
||||
Note: ARM 32-bit uses virtio-net-device (MMIO) by default.
|
||||
|
||||
config QEMU_NET_BRIDGE_DEV
|
||||
string "Bridge device"
|
||||
depends on QEMU_NET_BRIDGE
|
||||
default "virbr0"
|
||||
|
||||
config QEMU_NET_USER_OPTS
|
||||
string "User mode options"
|
||||
depends on QEMU_NET_USER
|
||||
help
|
||||
Extra -nic user,<OPTIONS>
|
||||
|
||||
config QEMU_NET_TAP_N
|
||||
int "Number of TAPs"
|
||||
depends on QEMU_NET_TAP
|
||||
default 1
|
||||
|
||||
config QEMU_NET_PORTS
|
||||
int "Number of Rocker switch ports"
|
||||
depends on QEMU_NET_ROCKER
|
||||
default 10
|
||||
|
||||
endmenu
|
||||
|
||||
config QEMU_EXTRA
|
||||
string "Extra QEMU options"
|
||||
|
||||
config QEMU_APPEND
|
||||
string "Extra kernel options"
|
||||
depends on QEMU_LOADER_QEMU
|
||||
Executable
+480
@@ -0,0 +1,480 @@
|
||||
#!/bin/sh
|
||||
# This script can be used to start an Infix OS image in Qemu. It reads
|
||||
# either a .config, generated from Config.in, or qemu.cfg from a release
|
||||
# tarball, for the required configuration data.
|
||||
#
|
||||
# Debian/Ubuntu users can change the configuration post-release, install
|
||||
# the kconfig-frontends package:
|
||||
#
|
||||
# sudo apt install kconfig-frontends
|
||||
#
|
||||
# and then call this script with:
|
||||
#
|
||||
# ./run.sh -c
|
||||
#
|
||||
# To bring up a menuconfig dialog. Select `Exit` and save the changes.
|
||||
# For more help, see:_
|
||||
#
|
||||
# ./run.sh -h
|
||||
#
|
||||
# shellcheck disable=SC3037
|
||||
|
||||
# Add /sbin to PATH for mkfs.ext4 and such (not default in debian)
|
||||
export PATH="/sbin:/usr/sbin:$PATH"
|
||||
|
||||
qdir=$(dirname "$(readlink -f "$0")")
|
||||
imgdir=$(readlink -f "${qdir}/..")
|
||||
prognm=$(basename "$0")
|
||||
|
||||
usage()
|
||||
{
|
||||
cat <<EOF
|
||||
usage: $prognm [OPTIONS] [-- KERNEL-ARGS]
|
||||
|
||||
Start Infix in a VM.
|
||||
|
||||
Any arguments after -- are passed to the kernel, provided that QEMU's
|
||||
native loader is being used (i.e., not UEFI, for example). This
|
||||
includes a second --, which the kernel uses to delimit between kernel
|
||||
arguments and those passed to the init process.
|
||||
|
||||
Options:
|
||||
-0
|
||||
Clear any copy-on-write layers, resetting all disks to their
|
||||
initial states, and exit.
|
||||
|
||||
-c
|
||||
Run menuconfig to change Qemu settings. This requires the
|
||||
'kconfig-frontends' package (Debian/Ubuntu).
|
||||
|
||||
-G
|
||||
Skip config generation. This is useful if you are testing out new
|
||||
QEMU features by manually modifying qemu.cfg.
|
||||
|
||||
-h
|
||||
Show this help message
|
||||
|
||||
Example:
|
||||
|
||||
$prognm -- loglevel=4 -- finit.debug
|
||||
|
||||
Will set the kernel's loglevel to 4, and pass finit.debug as an
|
||||
argument to PID 1.
|
||||
|
||||
EOF
|
||||
}
|
||||
|
||||
die()
|
||||
{
|
||||
echo "$prognm: $*" >&2
|
||||
exit 1
|
||||
}
|
||||
|
||||
binpath()
|
||||
{
|
||||
case "$1" in
|
||||
./*|../*)
|
||||
# Relative paths are relative to the location of .config
|
||||
printf "$qdir/$1"
|
||||
;;
|
||||
*)
|
||||
printf "$1"
|
||||
;;
|
||||
esac
|
||||
}
|
||||
|
||||
q()
|
||||
{
|
||||
local _cmd="$1"
|
||||
shift
|
||||
|
||||
case "$_cmd" in
|
||||
sect)
|
||||
printf ' \\\n\t' >>"$qdir"/qemu.sh
|
||||
|
||||
case $# in
|
||||
1)
|
||||
printf -- "-$1" >>"$qdir"/qemu.sh
|
||||
_delim=" "
|
||||
;;
|
||||
2)
|
||||
printf -- "-$1 $2" >>"$qdir"/qemu.sh
|
||||
_delim=","
|
||||
;;
|
||||
*)
|
||||
die "q sect: Invalid arguments"
|
||||
;;
|
||||
esac
|
||||
;;
|
||||
param)
|
||||
[ $# -eq 2 ] || die "q param: Takes exactly two arguments"
|
||||
printf -- "$_delim$1=$2" >>"$qdir"/qemu.sh
|
||||
_delim=","
|
||||
;;
|
||||
option)
|
||||
[ $# -eq 1 ] || die "q option: Takes exactly one argument"
|
||||
printf -- "$_delim$1" >>"$qdir"/qemu.sh
|
||||
_delim=","
|
||||
;;
|
||||
*)
|
||||
die "q: Unknown command: $_cmd"
|
||||
;;
|
||||
esac
|
||||
}
|
||||
|
||||
q_sect_device_virtio()
|
||||
{
|
||||
q sect device virtio-$1-$QEMU_VIRTIO_BUS
|
||||
}
|
||||
|
||||
q_add_disk()
|
||||
{
|
||||
if [ "$QEMU_DISK_SYS_IF_VIRTIO" ]; then
|
||||
q_sect_device_virtio blk
|
||||
q param drive "$1"
|
||||
else
|
||||
die "Unknown system disk interface"
|
||||
fi
|
||||
}
|
||||
|
||||
q_sect_device_usb()
|
||||
{
|
||||
if [ -z "$usb_bus_added" ]; then
|
||||
q sect usb
|
||||
q sect device usb-ehci
|
||||
q param id ehci
|
||||
usb_bus_added=YES
|
||||
fi
|
||||
|
||||
q sect device "$1"
|
||||
q param bus ehci.0
|
||||
}
|
||||
|
||||
qcowed()
|
||||
{
|
||||
local _qcow="$qdir"/"$1".qcow2
|
||||
local _base _size
|
||||
|
||||
if [ -f "$_qcow" ] && qemu-img check -q "$_qcow"; then
|
||||
echo "$_qcow"
|
||||
return
|
||||
fi
|
||||
|
||||
rm -f "$_qcow"
|
||||
|
||||
case $# in
|
||||
2)
|
||||
_size="$2"
|
||||
|
||||
qemu-img create -q -f qcow2 "$_qcow" "$_size" \
|
||||
|| die "Unable to create $1"
|
||||
;;
|
||||
3)
|
||||
|
||||
_base="$2"
|
||||
_size="$3"
|
||||
|
||||
[ "$_size" = "auto" ] && _size=
|
||||
|
||||
qemu-img create -q -f qcow2 -F raw \
|
||||
-o backing_file="$_base" "$_qcow" $_size \
|
||||
|| die "Unable to create CoW layer for $_base"
|
||||
;;
|
||||
*)
|
||||
die "qcowed: usage: qcowed <name> [<backing-file>] <size>"
|
||||
;;
|
||||
esac
|
||||
|
||||
echo "$_qcow"
|
||||
}
|
||||
|
||||
append()
|
||||
{
|
||||
echo -n " $*" >>"$qdir"/append
|
||||
}
|
||||
|
||||
gen_machine()
|
||||
{
|
||||
q sect machine
|
||||
q param type "$QEMU_MACHINE"
|
||||
q param accel kvm:tcg
|
||||
|
||||
q sect cpu "$QEMU_CPU"
|
||||
|
||||
q sect m
|
||||
q param size "$QEMU_RAM"
|
||||
}
|
||||
|
||||
gen_loader()
|
||||
{
|
||||
if [ "$QEMU_LOADER_QEMU" ]; then
|
||||
q sect kernel $(binpath "$QEMU_BIN_KERNEL")
|
||||
elif [ "$QEMU_LOADER_OVMF" ]; then
|
||||
q sect bios $(binpath "$QEMU_BIN_BIOS")
|
||||
fi
|
||||
}
|
||||
|
||||
gen_serial()
|
||||
{
|
||||
q sect display none
|
||||
|
||||
q_sect_device_virtio serial
|
||||
|
||||
q sect chardev stdio
|
||||
q param id console0
|
||||
q param mux on
|
||||
|
||||
q sect mon
|
||||
q param chardev console0
|
||||
|
||||
case "$QEMU_CONSOLE" in
|
||||
hvc0)
|
||||
q sect device virtconsole
|
||||
q param nr 0
|
||||
q param name console
|
||||
q param chardev console0
|
||||
;;
|
||||
ttyS0|ttyAMA0)
|
||||
q sect serial chardev:console0
|
||||
;;
|
||||
*)
|
||||
die "Unsupported console: $QEMU_CONSOLE"
|
||||
;;
|
||||
esac
|
||||
|
||||
append console="$QEMU_CONSOLE"
|
||||
|
||||
[ "$V" ] && append debug || append loglevel=4
|
||||
}
|
||||
|
||||
gpt_uuid()
|
||||
{
|
||||
sgdisk "$1" -p | awk '
|
||||
BEGIN { err = 1; } END { exit(err); }
|
||||
/^Creating new GPT/ { exit; }
|
||||
|
||||
/^Disk identifier \(GUID\): / {
|
||||
print($4); err = 0; exit;
|
||||
}' || die "Unable to determine GPT UUID of $1"
|
||||
}
|
||||
|
||||
gen_disk_sys_empty()
|
||||
{
|
||||
q sect drive
|
||||
q param id disk-sys
|
||||
q param format qcow2
|
||||
q param if none
|
||||
q param file $(qcowed disk-sys "$QEMU_DISK_SYS_SIZE")
|
||||
|
||||
q_add_disk disk-sys
|
||||
}
|
||||
|
||||
gen_disk_sys_full()
|
||||
{
|
||||
q sect drive
|
||||
q param id disk-sys
|
||||
q param format qcow2
|
||||
q param if none
|
||||
q param file $(qcowed disk-sys $(binpath "$QEMU_BIN_DISK") \
|
||||
"$QEMU_DISK_SYS_SIZE")
|
||||
|
||||
q_add_disk disk-sys
|
||||
|
||||
append root=ddi:lvm:internal/$(basename "$QEMU_BIN_DDI")
|
||||
}
|
||||
|
||||
gen_disk_sys_split()
|
||||
{
|
||||
# EFI System Partition
|
||||
q sect drive
|
||||
q param id disk-esp
|
||||
q param format qcow2
|
||||
q param if none
|
||||
q param file $(qcowed disk-esp $(binpath "$QEMU_BIN_ESP") auto)
|
||||
|
||||
q_add_disk disk-esp
|
||||
|
||||
# LVM stub
|
||||
q sect drive
|
||||
q param id disk-sys
|
||||
q param format qcow2
|
||||
q param if none
|
||||
q param file $(qcowed disk-sys $(binpath "$QEMU_BIN_LVM_STUB") \
|
||||
"$QEMU_DISK_SYS_SIZE")
|
||||
|
||||
q_add_disk disk-sys
|
||||
|
||||
# DDI (ro)
|
||||
q sect drive
|
||||
q param id disk-ddi
|
||||
q param format raw
|
||||
q param file $(binpath "$QEMU_BIN_DDI")
|
||||
q param if none
|
||||
q param read-only on
|
||||
|
||||
q_add_disk disk-ddi
|
||||
|
||||
append root=ddi:GPTUUID=$(gpt_uuid $(binpath "$QEMU_BIN_DDI"))
|
||||
}
|
||||
|
||||
gen_disk_sys()
|
||||
{
|
||||
[ "$QEMU_DISK_SYS_NONE" ] && return
|
||||
|
||||
if [ "$QEMU_DISK_SYS_EMPTY" ]; then
|
||||
gen_disk_sys_empty
|
||||
elif [ "$QEMU_DISK_SYS_FULL" ]; then
|
||||
gen_disk_sys_full
|
||||
elif [ "$QEMU_DISK_SYS_SPLIT" ]; then
|
||||
gen_disk_sys_split
|
||||
else
|
||||
die "Unknown system disk mode"
|
||||
fi
|
||||
}
|
||||
|
||||
gen_disk_usb()
|
||||
{
|
||||
[ "$QEMU_DISK_USB_NONE" ] && return
|
||||
|
||||
if [ "$QEMU_DISK_USB_DISK" ]; then
|
||||
q sect drive
|
||||
q param id disk-usb
|
||||
q param format qcow2
|
||||
q param file $(qcowed disk-usb \
|
||||
$(binpath "$QEMU_BIN_DISK") \
|
||||
"$QEMU_DISK_USB_SIZE")
|
||||
q param if none
|
||||
|
||||
q_sect_device_usb usb-storage
|
||||
q param drive disk-usb
|
||||
else
|
||||
die "Unknown USB attachment"
|
||||
fi
|
||||
}
|
||||
|
||||
gen_disk_initrd()
|
||||
{
|
||||
[ "$QEMU_DISK_INITRD" ] || return
|
||||
|
||||
q sect initrd $(binpath "$QEMU_BIN_DDI")
|
||||
append root=ddi:/initrd.image
|
||||
}
|
||||
|
||||
internal_is_available()
|
||||
{
|
||||
[ "$QEMU_DISK_SYS_FULL" ] || [ "$QEMU_DISK_SYS_SPLIT" ] \
|
||||
|| [ "$QEMU_DISK_USB_DISK" ]
|
||||
}
|
||||
|
||||
gen_disks()
|
||||
{
|
||||
gen_disk_sys
|
||||
gen_disk_usb
|
||||
|
||||
gen_disk_initrd
|
||||
|
||||
internal_is_available || append rd.nointernal
|
||||
}
|
||||
|
||||
gen_gdb()
|
||||
{
|
||||
# Create a UNIX socket on the host that is connected to a virtio
|
||||
# console in the guest, which gdbserver can attach to for
|
||||
# userspace debugging.
|
||||
q sect chardev socket
|
||||
q param id gdbserver
|
||||
q param path "$qdir"/gdbserver.sock
|
||||
q param server on
|
||||
q param wait off
|
||||
|
||||
q sect device virtconsole
|
||||
q param nr 1
|
||||
q param name gdbserver
|
||||
q param chardev gdbserver
|
||||
|
||||
# Create a UNIX socket on the host that is connected to QEMU's GDB
|
||||
# stub, for bootloader/kernel debugging.
|
||||
q sect chardev socket
|
||||
q param id gdbqemu
|
||||
q param path "$qdir"/gdbqemu.sock
|
||||
q param server on
|
||||
q param wait off
|
||||
|
||||
q sect gdb chardev:gdbqemu
|
||||
}
|
||||
|
||||
gen_all()
|
||||
{
|
||||
local _append
|
||||
|
||||
: >"$qdir"/append
|
||||
cat <<EOF >"$qdir"/qemu.sh
|
||||
#!/bin/sh
|
||||
|
||||
echo "Starting Qemu :: Ctrl-a x -- exit | Ctrl-a c -- toggle console/monitor"
|
||||
|
||||
line=\$(stty -g)
|
||||
stty raw
|
||||
trap 'stty "\$line"' EXIT INT TERM
|
||||
|
||||
qemu-system-$QEMU_ARCH -nodefaults \\
|
||||
EOF
|
||||
chmod +x "$qdir"/qemu.sh
|
||||
|
||||
gen_machine
|
||||
gen_loader
|
||||
gen_serial
|
||||
gen_disks
|
||||
gen_gdb
|
||||
|
||||
if [ "$QEMU_LOADER_QEMU" ]; then
|
||||
_append=$(cat "$qdir"/append)
|
||||
q sect append "\"$_append $QEMU_APPEND $*\""
|
||||
fi
|
||||
|
||||
echo >>"$qdir"/qemu.sh
|
||||
}
|
||||
|
||||
menuconfig()
|
||||
{
|
||||
command -v kconfig-mconf >/dev/null \
|
||||
|| die "cannot find kconfig-mconf for menuconfig"
|
||||
|
||||
CONFIG_= KCONFIG_CONFIG="$qdir"/.config \
|
||||
kconfig-mconf "$qdir"/Config.in
|
||||
}
|
||||
|
||||
_generate=YES
|
||||
|
||||
while getopts "0cGh-" opt; do
|
||||
case ${opt} in
|
||||
0)
|
||||
echo "Clearing all copy-on-write layers" >&2
|
||||
rm -f "$qdir"/*.qcow2
|
||||
exit 0
|
||||
;;
|
||||
c)
|
||||
menuconfig
|
||||
;;
|
||||
G)
|
||||
_generate=
|
||||
;;
|
||||
h)
|
||||
usage && exit 0
|
||||
;;
|
||||
-)
|
||||
break
|
||||
;;
|
||||
*)
|
||||
usage && exit 1
|
||||
;;
|
||||
esac
|
||||
done
|
||||
shift $((OPTIND - 1))
|
||||
|
||||
# shellcheck disable=SC1090
|
||||
. "$qdir"/.config
|
||||
|
||||
[ "$_generate" ] && gen_all "$*"
|
||||
|
||||
exec "$qdir"/qemu.sh
|
||||
@@ -149,7 +149,7 @@ config QEMU_HOST
|
||||
|
||||
config QEMU_APPEND
|
||||
string "Extra kernel options"
|
||||
depends on !QEMU_ROOTFS_MMC
|
||||
depends on QEMU_LOADER_KERNEL
|
||||
|
||||
config QEMU_EXTRA
|
||||
string "Extra QEMU options"
|
||||
@@ -4,9 +4,15 @@
|
||||
#
|
||||
################################################################################
|
||||
|
||||
QEMU_SCRIPTS_DIR := $(pkgdir)
|
||||
qemu-scripts-dir := $(pkgdir)/$(if $(IMAGE_DDI),ddi,itb)
|
||||
qemu-image := ../$(INFIX_ARTIFACT).$(if $(IMAGE_DDI),raw,qcow2)
|
||||
qemu-disk := $(if $(IMAGE_DDI_DISK),../$(INFIX_ARTIFACT).disk)
|
||||
qemu-esp := $(if $(IMAGE_BAREBOX_ESP),../barebox-esp.vfat)
|
||||
|
||||
qemu-kconfig-prefix := $(if $(IMAGE_DDI),,CONFIG_)
|
||||
|
||||
qemu-kconfig = \
|
||||
CONFIG_="CONFIG_" \
|
||||
CONFIG_="$(qemu-kconfig-prefix)" \
|
||||
BR2_CONFIG="$(BINARIES_DIR)/qemu/.config" \
|
||||
$(BUILD_DIR)/buildroot-config/$(1) $(2) "$(BINARIES_DIR)/qemu/Config.in"
|
||||
|
||||
@@ -25,17 +31,19 @@ qemu-scripts: \
|
||||
$(BINARIES_DIR)/qemu/Config.in \
|
||||
$(BINARIES_DIR)/qemu/.config
|
||||
|
||||
$(BINARIES_DIR)/qemu/run.sh: $(QEMU_SCRIPTS_DIR)/run.sh
|
||||
$(BINARIES_DIR)/qemu/run.sh: $(qemu-scripts-dir)/run.sh
|
||||
@$(call IXMSG,"Installing QEMU scripts")
|
||||
@mkdir -p $(dir $@)
|
||||
@cp $< $@
|
||||
|
||||
$(BINARIES_DIR)/qemu/Config.in: $(QEMU_SCRIPTS_DIR)/Config.in.in
|
||||
$(BINARIES_DIR)/qemu/Config.in: $(qemu-scripts-dir)/Config.in.in
|
||||
@mkdir -p $(dir $@)
|
||||
@sed \
|
||||
-e "s:@ARCH@:QEMU_$(BR2_ARCH):" \
|
||||
-e "s:@DISK_IMG@:../$(INFIX_ARTIFACT).qcow2:" \
|
||||
< $< >$@
|
||||
-e "s:@ARCH@:$(BR2_ARCH):g" \
|
||||
-e "s:@IMAGE@:$(qemu-image):g" \
|
||||
-e "s:@DISK@:$(qemu-disk):g" \
|
||||
-e "s:@ESP@:$(qemu-esp):g" \
|
||||
<$< >$@
|
||||
|
||||
$(BINARIES_DIR)/qemu/.config: $(BINARIES_DIR)/qemu/Config.in
|
||||
@$(call qemu-kconfig,conf,--olddefconfig)
|
||||
|
||||
@@ -0,0 +1,2 @@
|
||||
#set DEBUG=1
|
||||
service [2345] <pid/confd,pid/staticd> name:netd netd -- Network route daemon
|
||||
@@ -0,0 +1 @@
|
||||
../available/netd.conf
|
||||
@@ -0,0 +1,28 @@
|
||||
# Default FRR daemons file for Infix - confd overwrites on routing changes.
|
||||
# watchfrr, zebra, mgmtd, and staticd are always started by frrinit.sh.
|
||||
ospfd=no
|
||||
ripd=no
|
||||
bfdd=no
|
||||
bgpd=no
|
||||
ospf6d=no
|
||||
ripngd=no
|
||||
isisd=no
|
||||
pimd=no
|
||||
pim6d=no
|
||||
ldpd=no
|
||||
eigrpd=no
|
||||
babeld=no
|
||||
vrrpd=no
|
||||
pathd=no
|
||||
|
||||
vtysh_enable=yes
|
||||
watchfrr_options="-l 4"
|
||||
zebra_options=" -A 127.0.0.1 -s 90000000"
|
||||
mgmtd_options=" -A 127.0.0.1"
|
||||
ospfd_options=" -A 127.0.0.1"
|
||||
ripd_options=" -A 127.0.0.1"
|
||||
staticd_options="-A 127.0.0.1"
|
||||
bfdd_options=" -A 127.0.0.1"
|
||||
|
||||
frr_profile="traditional"
|
||||
|
||||
@@ -0,0 +1,2 @@
|
||||
# Replaces default frr.conf file
|
||||
log syslog warnings
|
||||
@@ -1,9 +0,0 @@
|
||||
! Default settings for staticd, used for both
|
||||
! confd generated routes, udhcpc and zeroconf
|
||||
frr defaults traditional
|
||||
hostname Router
|
||||
password zebra
|
||||
enable password zebra
|
||||
no log unique-id
|
||||
log syslog informational
|
||||
log facility local2
|
||||
Executable
+343
@@ -0,0 +1,343 @@
|
||||
#!/bin/sh
|
||||
|
||||
set -e
|
||||
|
||||
capath=/etc/rauc/keys
|
||||
|
||||
usage()
|
||||
{
|
||||
local _ddi="$(basename $0)"
|
||||
|
||||
cat <<EOF
|
||||
usage: $_ddi [<options>] <image> <command> [<args>]
|
||||
|
||||
Discoverable Disk Image manipulation
|
||||
|
||||
Options:
|
||||
|
||||
-A <arch>
|
||||
Override the system architecture.
|
||||
|
||||
-C <path>
|
||||
Source trusted signing keys from the supplied directory.
|
||||
Default: $capath
|
||||
|
||||
-h
|
||||
Show this message and exit.
|
||||
|
||||
Commands:
|
||||
|
||||
inspect <property>
|
||||
|
||||
uuid
|
||||
Print GPT disk identifier
|
||||
|
||||
part <partition> <command> [<args]
|
||||
Where <partition> is one of:
|
||||
root The first root partition
|
||||
|
||||
open [<options>] <name>
|
||||
|
||||
Create a device mapping for the specified partition, called
|
||||
<name>.
|
||||
|
||||
Options:
|
||||
|
||||
-v
|
||||
Use the associated dm-verity hash tree, whose root hash is
|
||||
available in the associated signature partition.
|
||||
|
||||
-V <root-hash>
|
||||
Use the associated dm-verity hash tree, along with an
|
||||
externally validated root hash.
|
||||
|
||||
verify [<options>]
|
||||
|
||||
Verify that the specified partition exists and, optionally,
|
||||
is accompanied by a trusted dm-verity hash tree.
|
||||
|
||||
Options:
|
||||
|
||||
-v
|
||||
Require the presence of an associated dm-verity hash tree,
|
||||
whose root hash is available in the associated signature
|
||||
partition.
|
||||
|
||||
-V <root-hash>
|
||||
Require the presence of an associated dm-verity hash tree
|
||||
whose root hash matches the provided one.
|
||||
|
||||
Examples:
|
||||
|
||||
Map and mount the verity protected SquashFS root partition from an
|
||||
image:
|
||||
$_ddi infix-x86_64.raw part root open -v infix
|
||||
mount -t squashfs /dev/mapper/infix /opt
|
||||
|
||||
EOF
|
||||
}
|
||||
|
||||
X86_64_CODE_ROOT=0x8304
|
||||
X86_64_CODE_ROOT_VERITY=0x830c
|
||||
X86_64_CODE_ROOT_VERITY_SIG=0x8370
|
||||
|
||||
die()
|
||||
{
|
||||
echo "ERROR: $*" >&2
|
||||
exit 1
|
||||
}
|
||||
|
||||
ok()
|
||||
{
|
||||
echo "$*" >&2
|
||||
}
|
||||
|
||||
setup_arch()
|
||||
{
|
||||
case "$1" in
|
||||
x86_64)
|
||||
CODE_ROOT=$X86_64_CODE_ROOT
|
||||
CODE_ROOT_VERITY=$X86_64_CODE_ROOT_VERITY
|
||||
CODE_ROOT_VERITY_SIG=$X86_64_CODE_ROOT_VERITY_SIG
|
||||
;;
|
||||
*)
|
||||
die "Unsupported architecture"
|
||||
esac
|
||||
}
|
||||
|
||||
setup_work()
|
||||
{
|
||||
local _umask
|
||||
|
||||
_umask=$(umask)
|
||||
umask 077
|
||||
workdir=$(mktemp -d)
|
||||
umask $_umask
|
||||
|
||||
trap 'rm -rf "$workdir"' EXIT INT TERM
|
||||
}
|
||||
|
||||
ddi_to_block()
|
||||
{
|
||||
local _kind _lo
|
||||
|
||||
_kind=$(stat -Lc %F "$1")
|
||||
case "$_kind" in
|
||||
"block special file")
|
||||
echo "$1"
|
||||
return
|
||||
;;
|
||||
"regular file")
|
||||
_lo=$(losetup -f || die "Found no free loop device for $1")
|
||||
losetup -P "$_lo" "$1" || die "Failed to setup loop device of $1"
|
||||
echo "$_lo"
|
||||
return
|
||||
;;
|
||||
esac
|
||||
|
||||
die "$1 is a $_kind, only regular and block devices are supported"
|
||||
}
|
||||
|
||||
ddi_get_part_info()
|
||||
{
|
||||
local _code _item
|
||||
|
||||
case "$2" in
|
||||
root) _code="$CODE_ROOT";;
|
||||
root-verity) _code="$CODE_ROOT_VERITY";;
|
||||
root-verity-sig) _code="$CODE_ROOT_VERITY_SIG";;
|
||||
*) die "Unknown partition type \"$1\"" ;;
|
||||
esac
|
||||
_code=$(printf "%04X" "$_code")
|
||||
_item=${3:-exists}
|
||||
|
||||
sgdisk "$1" -p | awk -v code="$_code" -v item="$_item" '
|
||||
/^[ ]*[0-9]+/ {
|
||||
if ($6 != code)
|
||||
next;
|
||||
|
||||
if (item == "exists") exit(0);
|
||||
if (item == "index") { print($1); exit(0); }
|
||||
|
||||
exit(1);
|
||||
}
|
||||
'
|
||||
}
|
||||
|
||||
ddi_get_part_dev()
|
||||
{
|
||||
local _dev _index _lvuuid _subsys
|
||||
|
||||
_index=$(ddi_get_part_info "$1" "$2" index \
|
||||
|| die "No $2 partition found on $1")
|
||||
|
||||
_subsys=$(dmsetup info -c --noheadings -o subsystem "$1" 2>/dev/null || true)
|
||||
if [ "$_subsys" = "LVM" ]; then
|
||||
_lvuuid=$(dmsetup info -c --noheadings -o uuid "$1")
|
||||
_dev=/dev/mapper/$(dmsetup info -c --noheadings -o name -u "part${_index}-$_lvuuid")
|
||||
else
|
||||
_dev=$(basename "$1")
|
||||
_dev=$(find /sys/block/"$_dev"/ -mindepth 1 -maxdepth 1 -type d \
|
||||
-name "${_dev}$_index" -o -name "${_dev}p$_index")
|
||||
_dev=/dev/$(basename "$_dev")
|
||||
fi
|
||||
|
||||
[ -b "$_dev" ] || die "Failed to locate $2 partition in $1"
|
||||
|
||||
echo "$_dev"
|
||||
}
|
||||
|
||||
ddi_get_root_hash()
|
||||
{
|
||||
local _subj
|
||||
|
||||
command -v openssl >/dev/null || die "Missing dependency: openssl"
|
||||
command -v jq >/dev/null || die "Missing dependency: jq"
|
||||
|
||||
jq -r .rootHash "$1" | tr -d '\n' >"$workdir"/hash \
|
||||
|| die "Invalid signature: rootHash is missing"
|
||||
|
||||
jq -r .signature "$1" | base64 -d >"$workdir"/sig \
|
||||
|| die "Invalid signature: signature data is missing"
|
||||
|
||||
openssl cms -verify -verify_retcode -CApath "$capath" \
|
||||
-content "$workdir"/hash \
|
||||
-in "$workdir"/sig -inform DER \
|
||||
-certsout "$workdir"/certs >/dev/null 2>&1 \
|
||||
|| die "Signature verification failed"
|
||||
|
||||
_subj=$(openssl x509 -noout -subject <"$workdir"/certs | sed -e 's/^subject=//')
|
||||
ok "Trusting root hash signature from $_subj"
|
||||
|
||||
cat "$workdir"/hash
|
||||
}
|
||||
|
||||
ddipart_get_verity()
|
||||
{
|
||||
local _hash
|
||||
|
||||
while getopts "vV:" opt; do
|
||||
case "$opt" in
|
||||
V)
|
||||
vkind="${kind}-verity"
|
||||
vhash="$OPTARG"
|
||||
;;
|
||||
v)
|
||||
vkind="${kind}-verity"
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
[ "$vkind" ] || return
|
||||
|
||||
vpart=$(ddi_get_part_dev "$img" "$vkind")
|
||||
|
||||
[ "$vhash" ] && return
|
||||
|
||||
vskind="${vkind}-sig"
|
||||
vspart=$(ddi_get_part_dev "$img" "$vskind")
|
||||
vhash=$(ddi_get_root_hash "$vspart")
|
||||
}
|
||||
|
||||
ddipart_open()
|
||||
{
|
||||
[ "$vpart" ] || die "$kind partition is already accessible at $part"
|
||||
|
||||
shift $((OPTIND - 1))
|
||||
|
||||
veritysetup open "$part" "$1" "$vpart" "$vhash"
|
||||
}
|
||||
|
||||
ddipart_verify()
|
||||
{
|
||||
[ "$vpart" ] || return
|
||||
|
||||
veritysetup verify "$part" "$vpart" "$vhash"
|
||||
ok "Image in $img has $kind partition with valid dm-verity hash tree"
|
||||
}
|
||||
|
||||
ddipart()
|
||||
{
|
||||
local _cmd
|
||||
|
||||
kind="$1"
|
||||
shift
|
||||
|
||||
ddi_get_part_info "$img" "$kind" \
|
||||
|| die "No $kind partition found on $img"
|
||||
|
||||
_cmd="$1"
|
||||
shift
|
||||
|
||||
case "$_cmd" in
|
||||
open|verify)
|
||||
img=$(ddi_to_block $img)
|
||||
part=$(ddi_get_part_dev "$img" "$kind")
|
||||
ddipart_get_verity "$@"
|
||||
|
||||
ddipart_$_cmd "$@"
|
||||
;;
|
||||
*)
|
||||
die "Unknown partition command \"$_cmd\""
|
||||
;;
|
||||
esac
|
||||
}
|
||||
|
||||
ddiinspect()
|
||||
{
|
||||
case "$1" in
|
||||
uuid)
|
||||
sgdisk "$img" -p | awk '
|
||||
BEGIN { err = 1; } END { exit(err); }
|
||||
/^Creating new GPT/ { exit; }
|
||||
|
||||
/^Disk identifier \(GUID\): / {
|
||||
print($4); err = 0; exit;
|
||||
}'
|
||||
;;
|
||||
*)
|
||||
die "Unknown property: $1"
|
||||
;;
|
||||
esac
|
||||
}
|
||||
|
||||
_arch=$(uname -m)
|
||||
|
||||
while getopts "A:C:h" opt; do
|
||||
case ${opt} in
|
||||
A)
|
||||
_arch="$OPTARG"
|
||||
;;
|
||||
C)
|
||||
capath="$OPTARG"
|
||||
;;
|
||||
h)
|
||||
usage && exit 0
|
||||
;;
|
||||
esac
|
||||
done
|
||||
shift $((OPTIND - 1))
|
||||
|
||||
if [ $# -lt 2 ]; then
|
||||
usage && exit 1
|
||||
fi
|
||||
|
||||
img="$1"
|
||||
cmd="$2"
|
||||
shift 2
|
||||
|
||||
setup_arch "$_arch"
|
||||
setup_work
|
||||
|
||||
case "$cmd" in
|
||||
inspect)
|
||||
ddiinspect "$@"
|
||||
;;
|
||||
part)
|
||||
ddipart "$@"
|
||||
;;
|
||||
*)
|
||||
echo "Unknown command \"$cmd\"" >2
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
@@ -0,0 +1,18 @@
|
||||
# Copy product-specific files (udev rules, factory config, etc.) to /
|
||||
# based on DT compatible strings, before udevd processes any events.
|
||||
#
|
||||
# <hook/mount/all> fires after all filesystems are mounted but before
|
||||
# finit enters runlevel S and starts any service, so the run task is
|
||||
# guaranteed to start ahead of udevd. The <run/preudev/success>
|
||||
# condition below then blocks udevd until pre-udev has finished.
|
||||
#
|
||||
# Systems without a matching product directory exit immediately.
|
||||
run name:preudev cgroup.init [S] <hook/mount/all> log \
|
||||
/usr/libexec/infix/pre-udev -- Probing platform
|
||||
|
||||
# Hold udevd back until pre-udev has had a chance to install any
|
||||
# product-specific udev rules so that they are applied on first pass.
|
||||
service nowarn cgroup.system name:udevd notify:none env:-/etc/default/udevd pid:udevd log \
|
||||
[S12345789] <run/preudev/success> /lib/systemd/systemd-udevd $UDEVD_ARGS -- Device event daemon (udev)
|
||||
service nowarn cgroup.system name:udevd notify:none env:-/etc/default/udevd pid:udevd log \
|
||||
[S12345789] <run/preudev/success> udevd $UDEVD_ARGS -- Device event daemon (udev)
|
||||
@@ -5,5 +5,5 @@ run nowarn if:udevd cgroup.init <service/udevd/ready> log \
|
||||
|
||||
# Now that everything should be probed, do a final pass over the
|
||||
# uevent queue before starting syslogd and everything else
|
||||
run nowarn if:udevd cgroup.init :post <service/udevd/ready> log \
|
||||
run nowarn if:udevd cgroup.init :post <run/preudev/success,service/udevd/ready> log \
|
||||
[S] udevadm settle -t 30 --
|
||||
|
||||
@@ -1,40 +1,22 @@
|
||||
#!/bin/sh
|
||||
# Find, install, and run product specific files and script in /etc
|
||||
# before resuming bootstrap.
|
||||
# Run product specific init scripts and set bootstrap conditions.
|
||||
#
|
||||
# Product-specific files (udev rules, factory config, etc.) are already
|
||||
# copied to / by the pre-udev run task before udevd starts. This
|
||||
# script handles the remaining product init: running custom scripts
|
||||
# from /etc/product/init.d/ and setting finit conditions.
|
||||
#
|
||||
# Use /etc/product/init.d/S01-myscript for scripts, may be a symlink, it
|
||||
# will be called with `start` as its only argument.
|
||||
#
|
||||
# The compatible array is listed in the same order as the device tree,
|
||||
# most significant to least. Hence the reverse.[], to ensure overrides
|
||||
# are applied in order of significance.
|
||||
ident=$(basename "$0")
|
||||
|
||||
PRODUCT_INIT=/etc/product/init.d
|
||||
PREFIXD=/usr/share/product
|
||||
COMPATIBLES=$(jq -r '.compatible | reverse.[] | ascii_downcase' /run/system.json)
|
||||
|
||||
note()
|
||||
{
|
||||
logger -I $$ -k -p user.notice -t "$ident" "$1"
|
||||
}
|
||||
|
||||
found=false
|
||||
for PRODUCT in $COMPATIBLES; do
|
||||
DIR="$PREFIXD/$PRODUCT"
|
||||
if [ -d "$DIR" ]; then
|
||||
note "Using vendor/product-specific defaults for $PRODUCT."
|
||||
for dir in "$DIR"/*; do
|
||||
[ -d "$dir" ] && cp -a "$dir" /
|
||||
done
|
||||
found=true
|
||||
fi
|
||||
done
|
||||
|
||||
if [ "$found" = false ]; then
|
||||
note "No vendor/product-specific directory found, using built-in defaults."
|
||||
fi
|
||||
|
||||
# Conditions for bootstrap services, this enables product specific
|
||||
# init scripts to prevent select services from starting.
|
||||
initctl -nbq cond set led
|
||||
|
||||
@@ -290,6 +290,14 @@ def parse_interface_info(ifname):
|
||||
if power_match:
|
||||
result['txpower'] = float(power_match.group(1))
|
||||
|
||||
# wiphy index -> phy/radio name
|
||||
elif stripped.startswith('wiphy '):
|
||||
try:
|
||||
wiphy_idx = int(stripped.split()[1])
|
||||
result['phy'] = normalize_phy_name(f'phy{wiphy_idx}')
|
||||
except (ValueError, IndexError):
|
||||
pass
|
||||
|
||||
return result
|
||||
|
||||
|
||||
|
||||
+48
@@ -0,0 +1,48 @@
|
||||
#!/bin/sh
|
||||
# Copy product-specific files to / based on DT compatible strings.
|
||||
# Designed to run before udevd, so that udev rules are in place when
|
||||
# the kernel starts enumerating devices. No Python, no jq, no syslogd.
|
||||
#
|
||||
# Mirrors the platform detection from 00-probe and the copy logic from
|
||||
# 05-product, but reads the DT directly instead of /run/system.json.
|
||||
|
||||
PREFIXD=/usr/share/product
|
||||
COMPAT=/sys/firmware/devicetree/base/compatible
|
||||
IDENT=$(basename "$0")
|
||||
|
||||
note()
|
||||
{
|
||||
logger -I $$ -k -p user.notice -t "$IDENT" "$*"
|
||||
}
|
||||
|
||||
# Only DT-based systems have product-specific data keyed by compatible.
|
||||
# QEMU and x86/DMI systems have no product dirs to copy.
|
||||
[ -f "$COMPAT" ] || exit 0
|
||||
|
||||
# The DT compatible property is a null-separated list of strings,
|
||||
# ordered most-specific first (e.g. "bananapi,bpi-r3\0mediatek,mt7986a").
|
||||
# Reverse the list so least-specific is applied first and more-specific
|
||||
# overrides it, matching the behaviour of 05-product.
|
||||
reversed=""
|
||||
while IFS= read -r c; do
|
||||
[ -n "$c" ] || continue
|
||||
reversed="$c${reversed:+ $reversed}"
|
||||
done <<EOF
|
||||
$(tr '\0' '\n' < "$COMPAT" | tr '[:upper:]' '[:lower:]')
|
||||
EOF
|
||||
|
||||
found=false
|
||||
for compat in $reversed; do
|
||||
dir="$PREFIXD/$compat"
|
||||
[ -d "$dir" ] || continue
|
||||
|
||||
note "Using product-specific defaults for $compat."
|
||||
for subdir in "$dir"/*; do
|
||||
[ -d "$subdir" ] && cp -a "$subdir" /
|
||||
done
|
||||
found=true
|
||||
done
|
||||
|
||||
$found || note "No product-specific directory found, using built-in defaults."
|
||||
|
||||
exit 0
|
||||
@@ -1,15 +0,0 @@
|
||||
#!/bin/sh
|
||||
# Sort and collate all /etc/frr/static.d/*.conf files managed by confd,
|
||||
# udhcpc, and avahi-autoipd before starting staticd.
|
||||
|
||||
DIRD=/etc/frr/static.d
|
||||
NAME=/etc/frr/staticd.conf
|
||||
NEXT=${NAME}+
|
||||
|
||||
rm -f "$NEXT"
|
||||
find "$DIRD" -type f -name '*.conf' ! -name '*~' | sort | while read -r file; do
|
||||
cat "$file" >> "$NEXT"
|
||||
done
|
||||
|
||||
cmp -s "$NAME" "$NEXT" && exit 0
|
||||
mv "$NEXT" "$NAME"
|
||||
@@ -7,7 +7,7 @@ ACTION="$1"
|
||||
IP_CACHE="/var/lib/misc/${interface}.cache"
|
||||
RESOLV_CONF="/run/resolvconf/interfaces/${interface}.conf"
|
||||
NTPFILE="/run/chrony/dhcp-sources.d/${interface}.sources"
|
||||
NAME="/etc/frr/static.d/${interface}-dhcp.conf"
|
||||
NAME="/etc/netd/conf.d/${interface}-dhcp.conf"
|
||||
NEXT="${NAME}+"
|
||||
|
||||
[ -n "$broadcast" ] && BROADCAST="broadcast $broadcast"
|
||||
@@ -75,14 +75,23 @@ was_option_requested()
|
||||
# client MUST ignore the Router option.
|
||||
set_dhcp_routes()
|
||||
{
|
||||
echo "! Generated by udhcpc" > "$NEXT"
|
||||
echo "# Generated by udhcpc" > "$NEXT"
|
||||
echo "" >> "$NEXT"
|
||||
if [ -n "$staticroutes" ]; then
|
||||
if was_option_requested 121; then
|
||||
# format: dest1/mask gw1 ... destn/mask gwn
|
||||
set -- $staticroutes
|
||||
while [ -n "$1" -a -n "$2" ]; do
|
||||
dbg "adding route $1 via $2 metric $metric tag 100"
|
||||
echo "ip route $1 $2 $metric tag 100" >> "$NEXT"
|
||||
cat >> "$NEXT" <<-EOF
|
||||
route {
|
||||
prefix = "$1"
|
||||
nexthop = "$2"
|
||||
distance = $metric
|
||||
tag = 100
|
||||
}
|
||||
|
||||
EOF
|
||||
shift 2
|
||||
done
|
||||
else
|
||||
@@ -91,7 +100,15 @@ set_dhcp_routes()
|
||||
elif [ -n "$router" ] ; then
|
||||
if was_option_requested 3; then
|
||||
for i in $router ; do
|
||||
echo "ip route 0.0.0.0/0 $i $metric tag 100" >> "$NEXT"
|
||||
cat >> "$NEXT" <<-EOF
|
||||
route {
|
||||
prefix = "0.0.0.0/0"
|
||||
nexthop = "$i"
|
||||
distance = $metric
|
||||
tag = 100
|
||||
}
|
||||
|
||||
EOF
|
||||
done
|
||||
else
|
||||
log "ignoring unrequested router (option 3)"
|
||||
@@ -102,7 +119,7 @@ set_dhcp_routes()
|
||||
cmp -s "$NAME" "$NEXT" && return
|
||||
mv "$NEXT" "$NAME"
|
||||
|
||||
initctl -nbq restart staticd
|
||||
initctl reload netd
|
||||
}
|
||||
|
||||
clr_dhcp_routes()
|
||||
@@ -111,7 +128,7 @@ clr_dhcp_routes()
|
||||
[ -f "$NAME" ] || return
|
||||
rm "$NAME"
|
||||
|
||||
initctl -nbq restart staticd
|
||||
initctl reload netd
|
||||
}
|
||||
|
||||
clr_dhcp_addresses()
|
||||
|
||||
@@ -0,0 +1,3 @@
|
||||
CODE_ROOT=0x8304
|
||||
CODE_ROOT_VERITY=0x830c
|
||||
CODE_ROOT_VERITY_SIG=0x8370
|
||||
+1
-1
Submodule buildroot updated: c3390cbf09...cde6f777f9
@@ -27,7 +27,7 @@ BR2_ROOTFS_OVERLAY="${BR2_EXTERNAL_INFIX_PATH}/board/common/rootfs ${BR2_EXTERNA
|
||||
BR2_ROOTFS_POST_BUILD_SCRIPT="${BR2_EXTERNAL_INFIX_PATH}/board/common/post-build.sh"
|
||||
BR2_LINUX_KERNEL=y
|
||||
BR2_LINUX_KERNEL_CUSTOM_VERSION=y
|
||||
BR2_LINUX_KERNEL_CUSTOM_VERSION_VALUE="6.18.8"
|
||||
BR2_LINUX_KERNEL_CUSTOM_VERSION_VALUE="6.18.14"
|
||||
BR2_LINUX_KERNEL_USE_CUSTOM_CONFIG=y
|
||||
BR2_LINUX_KERNEL_CUSTOM_CONFIG_FILE="${BR2_EXTERNAL_INFIX_PATH}/board/aarch64/linux_defconfig"
|
||||
BR2_LINUX_KERNEL_INSTALL_TARGET=y
|
||||
@@ -39,9 +39,11 @@ BR2_PACKAGE_E2FSPROGS=y
|
||||
BR2_PACKAGE_E2FSPROGS_RESIZE2FS=y
|
||||
BR2_PACKAGE_DBUS_CXX=y
|
||||
BR2_PACKAGE_DBUS_GLIB=y
|
||||
BR2_PACKAGE_DBUS_TRIGGERD=y
|
||||
BR2_PACKAGE_EUDEV_RULES_GEN=y
|
||||
# BR2_PACKAGE_EUDEV_ENABLE_HWDB is not set
|
||||
BR2_PACKAGE_GPSD_DEVICES="/dev/gps0"
|
||||
BR2_PACKAGE_GPSD_MAX_CLIENT_VALUE=2
|
||||
BR2_PACKAGE_GPSD_MAX_DEV_VALUE=1
|
||||
BR2_PACKAGE_GPTFDISK=y
|
||||
BR2_PACKAGE_GPTFDISK_SGDISK=y
|
||||
BR2_PACKAGE_MDIO_TOOLS=y
|
||||
@@ -146,9 +148,11 @@ INFIX_DESC="Infix is an immutable, friendly, and secure operating system that tu
|
||||
INFIX_HOME="https://github.com/kernelkit/infix/"
|
||||
INFIX_DOC="https://kernelkit.org/infix/"
|
||||
INFIX_SUPPORT="mailto:kernelkit@googlegroups.com"
|
||||
BR2_PACKAGE_FEATURE_GPS=y
|
||||
BR2_PACKAGE_FEATURE_WIFI_MEDIATEK=y
|
||||
BR2_PACKAGE_FEATURE_WIFI_REALTEK=y
|
||||
BR2_PACKAGE_CONFD=y
|
||||
BR2_PACKAGE_NETD=y
|
||||
BR2_PACKAGE_CONFD_TEST_MODE=y
|
||||
BR2_PACKAGE_CURIOS_HTTPD=y
|
||||
BR2_PACKAGE_CURIOS_NFTABLES=y
|
||||
|
||||
@@ -27,7 +27,7 @@ BR2_ROOTFS_OVERLAY="${BR2_EXTERNAL_INFIX_PATH}/board/common/rootfs ${BR2_EXTERNA
|
||||
BR2_ROOTFS_POST_BUILD_SCRIPT="${BR2_EXTERNAL_INFIX_PATH}/board/common/post-build.sh"
|
||||
BR2_LINUX_KERNEL=y
|
||||
BR2_LINUX_KERNEL_CUSTOM_VERSION=y
|
||||
BR2_LINUX_KERNEL_CUSTOM_VERSION_VALUE="6.18.8"
|
||||
BR2_LINUX_KERNEL_CUSTOM_VERSION_VALUE="6.18.14"
|
||||
BR2_LINUX_KERNEL_USE_CUSTOM_CONFIG=y
|
||||
BR2_LINUX_KERNEL_CUSTOM_CONFIG_FILE="${BR2_EXTERNAL_INFIX_PATH}/board/aarch64/linux_defconfig"
|
||||
BR2_LINUX_KERNEL_INSTALL_TARGET=y
|
||||
@@ -39,9 +39,11 @@ BR2_PACKAGE_E2FSPROGS=y
|
||||
BR2_PACKAGE_E2FSPROGS_RESIZE2FS=y
|
||||
BR2_PACKAGE_DBUS_CXX=y
|
||||
BR2_PACKAGE_DBUS_GLIB=y
|
||||
BR2_PACKAGE_DBUS_TRIGGERD=y
|
||||
BR2_PACKAGE_EUDEV_RULES_GEN=y
|
||||
# BR2_PACKAGE_EUDEV_ENABLE_HWDB is not set
|
||||
BR2_PACKAGE_GPSD_DEVICES="/dev/gps0"
|
||||
BR2_PACKAGE_GPSD_MAX_CLIENT_VALUE=2
|
||||
BR2_PACKAGE_GPSD_MAX_DEV_VALUE=1
|
||||
BR2_PACKAGE_GPTFDISK=y
|
||||
BR2_PACKAGE_GPTFDISK_SGDISK=y
|
||||
BR2_PACKAGE_MDIO_TOOLS=y
|
||||
@@ -124,7 +126,9 @@ INFIX_DESC="Infix is an immutable, friendly, and secure operating system that tu
|
||||
INFIX_HOME="https://github.com/kernelkit/infix/"
|
||||
INFIX_DOC="https://kernelkit.org/infix/"
|
||||
INFIX_SUPPORT="mailto:kernelkit@googlegroups.com"
|
||||
BR2_PACKAGE_FEATURE_GPS=y
|
||||
BR2_PACKAGE_CONFD=y
|
||||
BR2_PACKAGE_NETD=y
|
||||
BR2_PACKAGE_CONFD_TEST_MODE=y
|
||||
BR2_PACKAGE_GENCERT=y
|
||||
BR2_PACKAGE_STATD=y
|
||||
|
||||
@@ -24,5 +24,6 @@ BR2_TARGET_UBOOT_FORMAT_DTB=y
|
||||
BR2_PACKAGE_HOST_UBOOT_TOOLS=y
|
||||
BR2_PACKAGE_HOST_UBOOT_TOOLS_FIT_SUPPORT=y
|
||||
BR2_PACKAGE_HOST_UBOOT_TOOLS_FIT_SIGNATURE_SUPPORT=y
|
||||
BR2_PACKAGE_HOST_UBOOT_TOOLS_FDT_ADD_PUBKEY=y
|
||||
TRUSTED_KEYS=y
|
||||
TRUSTED_KEYS_DEVELOPMENT=y
|
||||
|
||||
@@ -28,7 +28,7 @@ BR2_ROOTFS_OVERLAY="${BR2_EXTERNAL_INFIX_PATH}/board/common/rootfs ${BR2_EXTERNA
|
||||
BR2_ROOTFS_POST_BUILD_SCRIPT="${BR2_EXTERNAL_INFIX_PATH}/board/common/post-build.sh"
|
||||
BR2_LINUX_KERNEL=y
|
||||
BR2_LINUX_KERNEL_CUSTOM_VERSION=y
|
||||
BR2_LINUX_KERNEL_CUSTOM_VERSION_VALUE="6.18.8"
|
||||
BR2_LINUX_KERNEL_CUSTOM_VERSION_VALUE="6.18.14"
|
||||
BR2_LINUX_KERNEL_USE_CUSTOM_CONFIG=y
|
||||
BR2_LINUX_KERNEL_CUSTOM_CONFIG_FILE="${BR2_EXTERNAL_INFIX_PATH}/board/arm/linux_defconfig"
|
||||
BR2_LINUX_KERNEL_INSTALL_TARGET=y
|
||||
@@ -41,9 +41,11 @@ BR2_PACKAGE_E2FSPROGS=y
|
||||
BR2_PACKAGE_E2FSPROGS_RESIZE2FS=y
|
||||
BR2_PACKAGE_DBUS_CXX=y
|
||||
BR2_PACKAGE_DBUS_GLIB=y
|
||||
BR2_PACKAGE_DBUS_TRIGGERD=y
|
||||
BR2_PACKAGE_EUDEV_RULES_GEN=y
|
||||
# BR2_PACKAGE_EUDEV_ENABLE_HWDB is not set
|
||||
BR2_PACKAGE_GPSD_DEVICES="/dev/gps0"
|
||||
BR2_PACKAGE_GPSD_MAX_CLIENT_VALUE=2
|
||||
BR2_PACKAGE_GPSD_MAX_DEV_VALUE=1
|
||||
BR2_PACKAGE_GPTFDISK=y
|
||||
BR2_PACKAGE_GPTFDISK_SGDISK=y
|
||||
BR2_PACKAGE_MDIO_TOOLS=y
|
||||
@@ -135,15 +137,18 @@ BR2_PACKAGE_HOST_MTOOLS=y
|
||||
BR2_PACKAGE_HOST_UBOOT_TOOLS_FIT_SUPPORT=y
|
||||
BR2_PACKAGE_HOST_UBOOT_TOOLS_FIT_SIGNATURE_SUPPORT=y
|
||||
BR2_PACKAGE_HOST_UBOOT_TOOLS_FDT_ADD_PUBKEY=y
|
||||
BR2_PACKAGE_MICROCHIP_SAMA7G54_EK=y
|
||||
BR2_PACKAGE_RASPBERRYPI_RPI2=y
|
||||
INFIX_VENDOR_HOME="https://kernelkit.org"
|
||||
INFIX_DESC="Infix is an immutable, friendly, and secure operating system that turns any ARM or x86 device into a powerful, manageable network appliance. Deploy on anything from $35 Raspberry Pi boards to enterprise switches as routers, IoT gateways, or edge devices. Infix models Linux networking features using YANG so you can manage your devices using NETCONF/RESTCONF APIs and focus on your business logic running in isolated containers."
|
||||
INFIX_HOME="https://github.com/kernelkit/infix/"
|
||||
INFIX_DOC="https://kernelkit.org/infix/"
|
||||
INFIX_SUPPORT="mailto:kernelkit@googlegroups.com"
|
||||
BR2_PACKAGE_FEATURE_GPS=y
|
||||
BR2_PACKAGE_FEATURE_WIFI_MEDIATEK=y
|
||||
BR2_PACKAGE_FEATURE_WIFI_REALTEK=y
|
||||
BR2_PACKAGE_CONFD=y
|
||||
BR2_PACKAGE_NETD=y
|
||||
BR2_PACKAGE_CONFD_TEST_MODE=y
|
||||
BR2_PACKAGE_GENCERT=y
|
||||
BR2_PACKAGE_STATD=y
|
||||
|
||||
@@ -28,7 +28,7 @@ BR2_ROOTFS_OVERLAY="${BR2_EXTERNAL_INFIX_PATH}/board/common/rootfs ${BR2_EXTERNA
|
||||
BR2_ROOTFS_POST_BUILD_SCRIPT="${BR2_EXTERNAL_INFIX_PATH}/board/common/post-build.sh"
|
||||
BR2_LINUX_KERNEL=y
|
||||
BR2_LINUX_KERNEL_CUSTOM_VERSION=y
|
||||
BR2_LINUX_KERNEL_CUSTOM_VERSION_VALUE="6.18.8"
|
||||
BR2_LINUX_KERNEL_CUSTOM_VERSION_VALUE="6.18.14"
|
||||
BR2_LINUX_KERNEL_USE_CUSTOM_CONFIG=y
|
||||
BR2_LINUX_KERNEL_CUSTOM_CONFIG_FILE="${BR2_EXTERNAL_INFIX_PATH}/board/arm/linux_defconfig"
|
||||
BR2_LINUX_KERNEL_INSTALL_TARGET=y
|
||||
@@ -41,9 +41,11 @@ BR2_PACKAGE_E2FSPROGS=y
|
||||
BR2_PACKAGE_E2FSPROGS_RESIZE2FS=y
|
||||
BR2_PACKAGE_DBUS_CXX=y
|
||||
BR2_PACKAGE_DBUS_GLIB=y
|
||||
BR2_PACKAGE_DBUS_TRIGGERD=y
|
||||
BR2_PACKAGE_EUDEV_RULES_GEN=y
|
||||
# BR2_PACKAGE_EUDEV_ENABLE_HWDB is not set
|
||||
BR2_PACKAGE_GPSD_DEVICES="/dev/gps0"
|
||||
BR2_PACKAGE_GPSD_MAX_CLIENT_VALUE=2
|
||||
BR2_PACKAGE_GPSD_MAX_DEV_VALUE=1
|
||||
BR2_PACKAGE_GPTFDISK=y
|
||||
BR2_PACKAGE_GPTFDISK_SGDISK=y
|
||||
BR2_PACKAGE_MDIO_TOOLS=y
|
||||
@@ -117,13 +119,16 @@ BR2_PACKAGE_HOST_MTOOLS=y
|
||||
BR2_PACKAGE_HOST_UBOOT_TOOLS_FIT_SUPPORT=y
|
||||
BR2_PACKAGE_HOST_UBOOT_TOOLS_FIT_SIGNATURE_SUPPORT=y
|
||||
BR2_PACKAGE_HOST_UBOOT_TOOLS_FDT_ADD_PUBKEY=y
|
||||
BR2_PACKAGE_MICROCHIP_SAMA7G54_EK=y
|
||||
BR2_PACKAGE_RASPBERRYPI_RPI2=y
|
||||
INFIX_VENDOR_HOME="https://kernelkit.org"
|
||||
INFIX_DESC="Infix is an immutable, friendly, and secure operating system that turns any ARM or x86 device into a powerful, manageable network appliance. Deploy on anything from $35 Raspberry Pi boards to enterprise switches as routers, IoT gateways, or edge devices. Infix models Linux networking features using YANG so you can manage your devices using NETCONF/RESTCONF APIs and focus on your business logic running in isolated containers."
|
||||
INFIX_HOME="https://github.com/kernelkit/infix/"
|
||||
INFIX_DOC="https://kernelkit.org/infix/"
|
||||
INFIX_SUPPORT="mailto:kernelkit@googlegroups.com"
|
||||
BR2_PACKAGE_FEATURE_GPS=y
|
||||
BR2_PACKAGE_CONFD=y
|
||||
BR2_PACKAGE_NETD=y
|
||||
BR2_PACKAGE_CONFD_TEST_MODE=y
|
||||
BR2_PACKAGE_GENCERT=y
|
||||
BR2_PACKAGE_STATD=y
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user