Compare commits

..
Author SHA1 Message Date
Tobias Waldekranz 257f1df1d5 test: case: user_scripts: Add test
Verify that:
- Scripts are executed when the service is enabled
- Scripts are not enabled when the service is disabled
2024-05-21 22:02:28 +02:00
Tobias Waldekranz 8664c27096 confd: Add support for running user scripts
Add a new service that, when enabled, will execute run-parts on
`/cfg/user-scripts.d`.

This strikes a balance between two conflicting objectives:

1. There should be no implicit way to schedule arbitrary code
   execution on the device, i.e. no default run-parts directory.

2. It is very useful to have a way of scheduling arbitrary code
   execution on the device, e.g. being able to install a debug script
   on a production image.

With this feature, we still meet (1), since the feature has to be
explicitly enabled in the startup-config; but we also fulfill (2),
since we can easily enable it when needed.
2024-05-21 22:02:28 +02:00
410 changed files with 4809 additions and 15755 deletions
+13 -69
View File
@@ -1,7 +1,6 @@
name: Bob the Builder
on:
pull_request:
push:
branches:
- main
@@ -16,13 +15,6 @@ jobs:
target: [aarch64, x86_64]
fail-fast: false
steps:
- name: Cleanup Build Folder
run: |
ls -la ./
rm -rf ./* || true
rm -rf ./.??* || true
ls -la ./
- uses: actions/checkout@v4
with:
clean: true
@@ -52,77 +44,35 @@ jobs:
ccache-${{ matrix.target }}-
ccache-
- name: Configure ${{ matrix.target }}
- name: Configure & Build
run: |
make ${{ matrix.target }}_defconfig
- name: Unit Test ${{ matrix.target }}
run: |
make test-unit
- name: Build ${{ matrix.target }}
run: |
echo "Building ${{ matrix.target }}_defconfig ..."
target=${{ matrix.target }}_defconfig
echo "Building $target ..."
make $target
make
- name: Check SBOM from Build
run: |
make legal-info
- name: Prepare ${{ matrix.target }} Artifact
- name: Prepare Artifact
run: |
cd output/
mv images ${{ steps.vars.outputs.dir }}
ln -s ${{ steps.vars.outputs.dir }} images
tar chfz ${{ steps.vars.outputs.tgz }} ${{ steps.vars.outputs.dir }}
- name: Test
if: matrix.target == 'x86_64'
run: |
make test
- uses: actions/upload-artifact@v4
with:
path: output/${{ steps.vars.outputs.tgz }}
name: artifact-${{ matrix.target }}
test:
name: Regression Test of Infix x86_64
needs: build
runs-on: [ self-hosted, regression ]
steps:
- uses: actions/checkout@v4
with:
clean: true
submodules: recursive
- name: Configure x86_64
run: |
make x86_64_defconfig
- uses: actions/download-artifact@v4
with:
pattern: "artifact-*"
merge-multiple: true
- name: Restore x86-64 output/
run: |
ls -l
mkdir -p output
mv infix-x86_64.tar.gz output/
cd output/
tar xf infix-x86_64.tar.gz
ln -s infix-x86_64 images
- name: Regression Test
run: |
make test
- name: Publish Test Result
# Ensure this runs even if Regression Test fails
if: always()
run: cat test/.log/last/result-gh.md >> $GITHUB_STEP_SUMMARY
release:
if: ${{github.repository_owner == 'kernelkit' && github.ref_name == 'main'}}
name: Upload Latest Build
needs: test
runs-on: ubuntu-latest
needs: build
runs-on: [ self-hosted, latest ]
permissions:
contents: write
steps:
@@ -131,12 +81,6 @@ jobs:
pattern: "artifact-*"
merge-multiple: true
- name: Create checksums ...
run: |
for file in *.tar.gz; do
sha256sum $file > $file.sha256
done
- uses: ncipollo/release-action@v1
with:
allowUpdates: true
@@ -146,7 +90,7 @@ jobs:
prerelease: true
tag: "latest"
token: ${{ secrets.GITHUB_TOKEN }}
artifacts: "*.tar.gz*"
artifacts: "*.tar.gz"
- name: Summary
run: |
+2 -2
View File
@@ -2,7 +2,7 @@ name: Coverity Scan
on:
schedule:
- cron: '5 0 * * 6'
- cron: '5 0 * * *'
workflow_dispatch:
env:
@@ -54,7 +54,7 @@ jobs:
run: |
sudo apt-get -y update
sudo apt-get -y install pkg-config libjansson-dev libev-dev \
libcrypt-dev libglib2.0-dev libpcre2-dev \
libaugeas-dev libglib2.0-dev libpcre2-dev \
libuev-dev libite-dev
- name: Build dependencies
+94
View File
@@ -0,0 +1,94 @@
name: Reggie Regression
on:
push:
branches:
- '*'
pull_request:
branches:
- '*'
workflow_dispatch:
concurrency:
group: ${{ github.workflow }}-${{ github.head_ref || github.ref }}
cancel-in-progress: true
jobs:
build:
name: Regression Testing ${{ matrix.target }}
runs-on: [ self-hosted, regression ]
if: github.event_name != 'pull_request' || github.event.pull_request.head.repo.full_name != github.event.pull_request.base.repo.full_name
strategy:
matrix:
target: [aarch64, x86_64]
fail-fast: false
steps:
- uses: actions/checkout@v4
with:
clean: true
submodules: recursive
- name: Clean up cruft ...
run: |
./test/env -c
- name: Set Build Variables
id: vars
run: |
target=${{ matrix.target }}
echo "dir=infix-$target" >> $GITHUB_OUTPUT
echo "tgz=infix-$target.tar.gz" >> $GITHUB_OUTPUT
- name: Restore Cache of dl/
uses: actions/cache@v4
with:
path: dl/
key: dl-netconf-${{ 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-x86_64-${{ hashFiles('.git/modules/buildroot/HEAD', 'package/*/*.hash') }}
restore-keys: |
ccache-${{ matrix.target }}-
ccache-
- name: Configure ${{ matrix.target }}
run: |
target=${{ matrix.target }}_defconfig
echo "Building $target ..."
make $target
- name: Unit Test
run: |
make test-unit
- name: Build
run: |
make
- name: Prepare Artifact
run: |
cd output/
mv images ${{ steps.vars.outputs.dir }}
ln -s ${{ steps.vars.outputs.dir }} images
tar cfz ${{ steps.vars.outputs.tgz }} ${{ steps.vars.outputs.dir }}
- name: Upload Artifact
uses: actions/upload-artifact@v4
with:
path: output/${{ steps.vars.outputs.tgz }}
name: artifact-${{ matrix.target }}
- name: Regression Test
if: matrix.target == 'x86_64'
run: |
make test
- name: Publish Test Result
# Ensure this runs even if Regression Test fails
if: always()
run: cat test/.log/last/result-gh.md >> $GITHUB_STEP_SUMMARY
+5 -1
View File
@@ -112,6 +112,10 @@ config INFIX_ARCH
default "riscv64" if BR2_riscv
default "x86_64" if BR2_x86_64
menu "Packages"
source "$BR2_EXTERNAL_INFIX_PATH/package/Config.in"
source "$BR2_EXTERNAL_INFIX_PATH/package/Config.in.host"
endmenu
source "$BR2_EXTERNAL_INFIX_PATH/board/common/Config.in"
+2 -7
View File
@@ -1,13 +1,8 @@
export BR2_EXTERNAL ?= $(CURDIR)
export BR2_EXTERNAL := $(CURDIR)
export PATH := $(CURDIR)/bin:$(PATH)
ARCH ?= $(shell uname -m)
O ?= output
# If a relative output path is specified, we have to translate it to
# an absolute one before handing over control to Buildroot, which will
# otherwise treat it as relative to ./buildroot.
override O := $(if $(filter /%,$O),$O,$(CURDIR)/$O)
O ?= $(CURDIR)/output
config := $(O)/.config
bmake = $(MAKE) -C buildroot O=$(O) $1
+6 -8
View File
@@ -5,8 +5,8 @@
Infix is a free, Linux based, immutable Network Operating System (NOS)
built on [Buildroot][1], and [sysrepo][2]. A powerful mix that ease
porting to different platforms, simplify long-term maintenance, and
provide made-easy management using NETCONF, RESTCONF[^2], or the
built-in command line interface (CLI) from a console or SSH login.
provide made-easy management using NETCONF[^1] or the built-in command
line interface (CLI) from a console or SSH login.
> Click the **▶ Example CLI Session** foldout below for an example, or
> head on over to the [Infix Documentation](doc/README.md) for more
@@ -22,7 +22,7 @@ may be appealing for other use-cases as well:
- Atomic upgrades to secondary partition
- Highly security focused
An immutable[^1] operating system enhances security and inherently makes
An immutable[^2] operating system enhances security and inherently makes
it maintenance-free. Configuration and data, e.g, containers, is stored
on separate partitions to ensure complete separation from system files
and allow for seamless backup, restore, and provisioning.
@@ -93,7 +93,6 @@ The [following boards](board/aarch64/README.md) are fully supported:
- Marvell CN9130 CRB
- Marvell EspressoBIN
- Microchip SparX-5i PCB135 (eMMC)
- StarFive VisionFive2
- NanoPi R2S
An x86_64 build is also available, primarily intended for development
@@ -106,15 +105,14 @@ more information, see: [Infix in Virtual Environments](doc/virtual.md).
>
> For *customer specific builds* of Infix, see your product repository.
[^1]: An immutable operating system is one with read-only file systems,
[^1]: NETCONF or RESTCONF, <https://datatracker.ietf.org/doc/html/rfc8040>
[^2]: An immutable operating system is one with read-only file systems,
atomic updates, rollbacks, declarative configuration, and workload
isolation. All to improve reliability, scalability, and security.
For more information, see <https://ceur-ws.org/Vol-3386/paper9.pdf>
and <https://www.zdnet.com/article/what-is-immutable-linux-heres-why-youd-run-an-immutable-linux-distro/>.
[^2]: Partial RESTCONF support, features like HTTP PATCH, OPTIONS, HEAD,
and copying between datastores are still missing.
[1]: https://buildroot.org/
[2]: https://www.sysrepo.org/
[3]: doc/cli/introduction.md
-2
View File
@@ -3,7 +3,5 @@ aarch64
Board Specific Documentation
----------------------------
- [Marvell CN9130-CRB](cn9130-crb/)
- [Microchip SparX-5i PCB135 (eMMC)](sparx5-pcb135/)
- [NanoPi R2S](r2s/)
+2 -2
View File
@@ -118,8 +118,8 @@ the device is reasonably correct, and run the provisioning script:
admin@infix:~$ sudo -i
root@infix:~$ udhcpc -i e28
root@infix:~$ date -us YYYY-MM-DD
root@infix:~$ /usr/libexec/infix/prod/provision tftp://<PC-IP>/infix-aarch64.pkg /dev/mmcblk0
root@infix:~$ date -us YYYY-MM-DD
root@infix:~$ /libexec/infix/prod/provision tftp://<PC-IP>/infix-aarch64.pkg /dev/mmcblk0
After successful completion, the device is fully provisioned. On the
next boot, the device will boot of its own accord from the primary
@@ -16,12 +16,7 @@ run ixboot
";
boot_targets = "mmc1";
ethprime = "eth1";
/* This is a development platform, keep
* developer mode statically enabled.
*/
ixbtn-devmode = "setenv dev_mode yes; echo Enabled";
ixbtn-factory = "echo \"No button available, use bootmenu\"";
bootdelay = "1";
};
};
};
+1 -1
View File
@@ -92,7 +92,7 @@
compatible = "atmel,24c256";
reg = <0x50>;
infix,board = "product";
infix,board = "cpu";
infix,trusted;
nvmem-layout {
-6
View File
@@ -175,14 +175,9 @@ CONFIG_VLAN_8021Q=y
CONFIG_VLAN_8021Q_GVRP=y
CONFIG_VLAN_8021Q_MVRP=y
CONFIG_NET_SCHED=y
CONFIG_NET_SCH_MQPRIO=y
CONFIG_NET_CLS_BASIC=y
CONFIG_NET_CLS_BPF=y
CONFIG_NET_CLS_FLOWER=y
CONFIG_NET_CLS_ACT=y
CONFIG_NET_ACT_GACT=y
CONFIG_NET_ACT_MIRRED=y
CONFIG_NET_ACT_SKBEDIT=y
CONFIG_DCB=y
CONFIG_NETLINK_DIAG=y
CONFIG_MPLS=y
@@ -512,7 +507,6 @@ CONFIG_FUSE_FS=y
CONFIG_VIRTIO_FS=y
CONFIG_OVERLAY_FS=y
CONFIG_VFAT_FS=y
CONFIG_EXFAT_FS=y
CONFIG_TMPFS=y
CONFIG_TMPFS_POSIX_ACL=y
CONFIG_SQUASHFS=y
-165
View File
@@ -1,165 +0,0 @@
FriendlyELC NanoPi R2S
======================
The [NanoPi R2S][1] is a very low-cost 64-bit ARM min router, powered by
the Rockchip RK3328, quad-core Cortex-A53.
The R2S does not have any onboard eMMC, so the only way to boot Infix on
it is using and SD card.
LEDs
----
The front system LEDs work as follows in Infix:
| **Stage** | **SYS** | **LAN** | **WAN** |
|----------------|---------|---------|---------|
| Power-on | dimmed | off | off |
| Factory reset | on | on | on |
| Linux loading | on | off | off |
| System loading | 1 Hz | off | off |
| System up | off | on | off |
| WAN address | off | on | on |
| Locate | 1 Hz | 1 Hz | 1 Hz |
| Fail safe | 5 Hz | off | off |
| Panic | 5 Hz | 5 Hz | 5 Hz |
Powering on the device the SYS LED is turned on faintly (dimmed). It
remains dimmed while U-Boot loads the kernel, and turns bright red when
the kernel starts. It remains steady on until the system has started
the LED daemon, `iitod`, which sets it blinking at 1 Hz while the rest
of the system starts up. When the system has come up successfully, the
SYS LED is turned off and the green LAN LED turns on. The WAN LED will
turn on (green) when the WAN interface is up and has an IP address.
> Compared to the `x86_64` Qemu target, it takes a while to parse all
> YANG models and load `startup-config`, but the whole process should
> not take more than 60 seconds, and usually a lot less.
If a "find my device" function exists, it will blink all LEDs at 1 Hz.
If `startup-config` fails to load Ínfix reverts to `failure-config`,
putting the device in fail safe (or fail secure) mode. Indicated by
the SYS LED blinking at 5 Hz instead of turning off.
If Infix for some reason also fails to load `failure-config`, then all
LEDs will blink at 5 Hz to clearly indicate something is very wrong.
In all error cases the console shows the problem.
Factory Reset
-------------
The reset button on the side can be used not only to safely reboot the
device, but can also be used to trigger a factory reset at power on.
At power-on, keep the reset button pressed for 10 seconds. The system
LEDs (SYS, WAN, LAN) will all blink at 1 Hz, to help you count down the
seconds. When the 10 seconds have passed all LEDs are turned off before
loading Linux.
When Linux boots up it confirms the factory reset by lighting up the
LEDs again, no blinking this time. The LEDs stay on until all files and
directories on read/writable partitions (`/cfg` and `/var`) have been
safely erased.
The system then continues loading, turning off all LEDs except SYS,
which blinks calmly at 1 Hz as usual until the system has completed
loading, this time with a `startup-config` freshly restored from the
device's `factory-config`.
How to Build
------------
```
$ make r2s_defconfig
$ make
```
Once the build has finished you will have `output/images/sdcard.img`
which you can flash to an SD card.
```
$ sudo dd if=output/images/sdcard.img of=/dev/mmcblk0 bs=1M status=progress oflag=direct
```
> **WARNING:** ensure `/dev/mmcblk0` really is the correct device for
> your SD card, and not used by the system!
Booting the Board
-----------------
1. Connect a TTL cable to three UART pins, GND is closest to the edge
2. Insert the flashed SD card
3. Power-up the board using an USB-C cable (ensure good power source!)
Worth noting, unlike many other boards, the Rockchip family of chipsets
runs the UART at 1500000 bps (1.5 Mbps) 8N1.
Secure Boot
-----------
Like other Infix builds, the R2S enjoys secure boot. Please note,
however that the default signing keys are the public!
Also, default builds allow modifying and saving the U-Boot environment
(see below), which you may want to disable to secure the device. The
device also runs in *developer mode*, allowing full U-Boot shell access,
which you may also want to disable in a full production setting.
Caveat
------
Most (all?) of these boards do not have any Vital Product Data (VPD)
EEPROM mounted. This means they do not come with unique MAC addresses
allocated to the two Ethernet ports.
The bootloader (U-Boot) default environment for the board is usually
what provides a default, the same default MAC addresses to Linux:
- 4a:dc:d8:20:0d:84
- 4a:dc:d8:20:0d:85
This is important in case you want to run multiple R2S devices on the
same LAN. Meaning you either have to change the MAC address in the
U-Boot environment (below), or modify your `phys-address` setting in
Infix for the interface(s).
Break into U-Boot using Ctrl-C at power-on, preferably when the text
`Press Ctrl-C NOW to enter boot menu` is displayed. Exit the menu to
get to the prompt:
```
(r2s) printenv
...
eth1addr=4a:dc:d8:20:0d:84
ethact=ethernet@ff540000
ethaddr=4a:dc:d8:20:0d:85
ethprime=eth0
...
```
Here we change both addresses, using the *Locally Administered* bit:
```
(r2s) setenv eth1addr 02:00:c0:ff:ee:01
(r2s) setenv ethaddr 02:00:c0:ff:ee:00
(r2s) saveenv
```
Boot the system, log into Linux, and inspect the MAC addresses:
```
admin@infix-00-00-00:~$ ip -br l
lo UP 00:00:00:00:00:00 <LOOPBACK,UP,LOWER_UP>
eth0 UP 02:00:c0:ff:ee:00 <BROADCAST,MULTICAST,UP,LOWER_UP>
eth1 UP 02:00:c0:ff:ee:01 <BROADCAST,MULTICAST,UP,LOWER_UP>
```
[1]: https://wiki.friendlyelec.com/wiki/index.php/NanoPi_R2S
+4
View File
@@ -0,0 +1,4 @@
label Infix on NanoPi R2S
kernel /boot/Image
devicetree /boot/rk3328-nanopi-r2s.dtb
append root=/dev/mmcblk0p1 rw rootwait bonding.max_bonds=0 dummy.numdummies=0 fb_tunnels=none quiet
+7 -40
View File
@@ -1,70 +1,37 @@
image cfg.ext4 {
empty = true
temporary = true
size = 16M
ext4 {
label = "cfg"
}
}
image var.ext4 {
empty = true
temporary = true
size = 512M
ext4 {
label = "var"
use-mke2fs = true
}
size = 16M
}
image sdcard.img {
hdimage {
partition-table-type = "gpt"
}
partition u-boot-tpl-spl-dtb {
in-partition-table = "no"
offset = 32K
image = "idbloader.img"
offset = 32K
}
partition u-boot-dtb {
in-partition-table = "no"
offset = 8M
image = "u-boot.itb"
offset = 8M
}
partition aux {
partition-uuid = D4EF35A0-0652-45A1-B3DE-D63339C82035
partition rootfs {
partition-type = 0x83
offset = 16M
image = "aux.ext4"
}
partition primary {
partition-type-uuid = 0FC63DAF-8483-4772-8E79-3D69D8477DE4
bootable = true
size = 200M
image = "rootfs.squashfs"
}
partition secondary {
partition-type-uuid = 0FC63DAF-8483-4772-8E79-3D69D8477DE4
bootable = true
size = 200M
image = "rootfs.squashfs"
image = "rootfs.ext4"
}
partition cfg {
partition-uuid = 7aa497f0-73b5-47e5-b2ab-8752d8a48105
partition-type = 0x83
image = "cfg.ext4"
}
partition var {
partition-uuid = 8046A06A-E45A-4A14-A6AD-6684704A393F
image = "var.ext4"
}
}
# Silence genimage warnings
+85 -176
View File
@@ -3,31 +3,22 @@ CONFIG_POSIX_MQUEUE=y
CONFIG_AUDIT=y
CONFIG_NO_HZ_IDLE=y
CONFIG_HIGH_RES_TIMERS=y
CONFIG_BPF_SYSCALL=y
CONFIG_BPF_JIT=y
CONFIG_PREEMPT=y
CONFIG_IRQ_TIME_ACCOUNTING=y
CONFIG_BSD_PROCESS_ACCT=y
CONFIG_BSD_PROCESS_ACCT_V3=y
CONFIG_TASKSTATS=y
CONFIG_TASK_DELAY_ACCT=y
CONFIG_TASK_XACCT=y
CONFIG_PSI=y
CONFIG_IKCONFIG=y
CONFIG_IKCONFIG_PROC=y
CONFIG_LOG_BUF_SHIFT=18
CONFIG_NUMA_BALANCING=y
CONFIG_MEMCG=y
CONFIG_BLK_CGROUP=y
CONFIG_CFS_BANDWIDTH=y
CONFIG_RT_GROUP_SCHED=y
CONFIG_CGROUP_PIDS=y
CONFIG_CGROUP_FREEZER=y
CONFIG_CGROUP_HUGETLB=y
CONFIG_CPUSETS=y
CONFIG_CGROUP_DEVICE=y
CONFIG_CGROUP_CPUACCT=y
CONFIG_CGROUP_PERF=y
CONFIG_CGROUP_BPF=y
CONFIG_NAMESPACES=y
CONFIG_USER_NS=y
CONFIG_SCHED_AUTOGROUP=y
@@ -36,14 +27,19 @@ CONFIG_EXPERT=y
CONFIG_KALLSYMS_ALL=y
CONFIG_PROFILING=y
CONFIG_KEXEC_FILE=y
CONFIG_CRASH_DUMP=y
CONFIG_ARCH_ACTIONS=y
CONFIG_ARCH_ROCKCHIP=y
CONFIG_ARCH_VEXPRESS=y
CONFIG_ARM64_VA_BITS_48=y
CONFIG_SCHED_MC=y
CONFIG_SCHED_SMT=y
CONFIG_NR_CPUS=8
CONFIG_NUMA=y
CONFIG_COMPAT=y
CONFIG_RANDOMIZE_BASE=y
# CONFIG_SUSPEND is not set
CONFIG_HIBERNATION=y
CONFIG_WQ_POWER_EFFICIENT_DEFAULT=y
CONFIG_ENERGY_MODEL=y
CONFIG_ARM_PSCI_CPUIDLE=y
CONFIG_CPU_FREQ=y
CONFIG_CPU_FREQ_STAT=y
@@ -52,8 +48,8 @@ CONFIG_CPU_FREQ_GOV_USERSPACE=y
CONFIG_CPU_FREQ_GOV_ONDEMAND=y
CONFIG_CPU_FREQ_GOV_CONSERVATIVE=m
CONFIG_CPUFREQ_DT=y
CONFIG_ARM_SCMI_CPUFREQ=y
CONFIG_ACPI_CPPC_CPUFREQ=m
CONFIG_ARM_SCMI_CPUFREQ=y
CONFIG_ACPI=y
CONFIG_ACPI_APEI=y
CONFIG_ACPI_APEI_GHES=y
@@ -61,7 +57,6 @@ CONFIG_ACPI_APEI_MEMORY_FAILURE=y
CONFIG_ACPI_APEI_EINJ=y
CONFIG_VIRTUALIZATION=y
CONFIG_KVM=y
CONFIG_KPROBES=y
CONFIG_JUMP_LABEL=y
# CONFIG_GCC_PLUGINS is not set
CONFIG_MODULES=y
@@ -72,11 +67,8 @@ CONFIG_KSM=y
CONFIG_MEMORY_FAILURE=y
CONFIG_TRANSPARENT_HUGEPAGE=y
CONFIG_CMA=y
CONFIG_CMA_AREAS=20
CONFIG_NET=y
CONFIG_PACKET=y
CONFIG_XDP_SOCKETS=y
CONFIG_XDP_SOCKETS_DIAG=y
CONFIG_IP_MULTICAST=y
CONFIG_IP_ADVANCED_ROUTER=y
CONFIG_IP_MULTIPLE_TABLES=y
@@ -84,66 +76,24 @@ CONFIG_IP_ROUTE_MULTIPATH=y
CONFIG_IP_PNP=y
CONFIG_IP_PNP_DHCP=y
CONFIG_IP_PNP_BOOTP=y
CONFIG_NET_IPIP=m
CONFIG_NET_IPGRE_DEMUX=m
CONFIG_NET_IPIP=y
CONFIG_NET_IPGRE_DEMUX=y
CONFIG_NET_IPGRE=m
CONFIG_NET_IPGRE_BROADCAST=y
CONFIG_IP_MROUTE=y
CONFIG_IP_MROUTE_MULTIPLE_TABLES=y
CONFIG_IP_PIMSM_V1=y
CONFIG_IP_PIMSM_V2=y
CONFIG_SYN_COOKIES=y
CONFIG_IPV6_SIT=m
CONFIG_IPV6_GRE=m
CONFIG_IPV6_MULTIPLE_TABLES=y
CONFIG_IPV6_SUBTREES=y
CONFIG_IPV6_MROUTE=y
CONFIG_IPV6_MROUTE_MULTIPLE_TABLES=y
CONFIG_IPV6_PIMSM_V2=y
CONFIG_NETWORK_PHY_TIMESTAMPING=y
CONFIG_IPV6=m
CONFIG_NETFILTER=y
CONFIG_BRIDGE_NETFILTER=y
CONFIG_NETFILTER_NETLINK_QUEUE=y
CONFIG_NETFILTER_NETLINK_LOG=y
CONFIG_NF_CONNTRACK=y
CONFIG_NF_CONNTRACK=m
CONFIG_NF_CONNTRACK_EVENTS=y
CONFIG_NF_CONNTRACK_FTP=y
CONFIG_NF_TABLES=y
CONFIG_NF_TABLES_INET=y
CONFIG_NF_TABLES_NETDEV=y
CONFIG_NFT_CT=m
CONFIG_NFT_CONNLIMIT=m
CONFIG_NFT_LOG=m
CONFIG_NFT_LIMIT=m
CONFIG_NFT_MASQ=m
CONFIG_NFT_REDIR=m
CONFIG_NFT_NAT=m
CONFIG_NFT_TUNNEL=m
CONFIG_NFT_QUEUE=m
CONFIG_NFT_REJECT=m
CONFIG_NFT_COMPAT=m
CONFIG_NFT_HASH=m
CONFIG_NFT_SOCKET=m
CONFIG_NFT_OSF=m
CONFIG_NFT_DUP_NETDEV=m
CONFIG_NFT_FWD_NETDEV=m
CONFIG_NFT_REJECT_NETDEV=m
CONFIG_NETFILTER_XT_TARGET_CHECKSUM=m
CONFIG_NETFILTER_XT_TARGET_LOG=m
CONFIG_NETFILTER_XT_MATCH_ADDRTYPE=m
CONFIG_NETFILTER_XT_MATCH_BPF=m
CONFIG_NETFILTER_XT_MATCH_CGROUP=m
CONFIG_NETFILTER_XT_MATCH_COMMENT=m
CONFIG_NETFILTER_XT_MATCH_CONNLABEL=m
CONFIG_NETFILTER_XT_MATCH_CONNMARK=m
CONFIG_NETFILTER_XT_MATCH_CONNTRACK=m
CONFIG_NETFILTER_XT_MATCH_DSCP=m
CONFIG_NETFILTER_XT_MATCH_HELPER=m
CONFIG_NETFILTER_XT_MATCH_LIMIT=m
CONFIG_NETFILTER_XT_MATCH_MAC=m
CONFIG_NETFILTER_XT_MATCH_MARK=m
CONFIG_NETFILTER_XT_MATCH_MULTIPORT=m
CONFIG_NETFILTER_XT_MATCH_PHYSDEV=m
CONFIG_IP_NF_IPTABLES=m
CONFIG_IP_NF_FILTER=m
CONFIG_IP_NF_TARGET_REJECT=m
@@ -151,46 +101,17 @@ CONFIG_IP_NF_NAT=m
CONFIG_IP_NF_TARGET_MASQUERADE=m
CONFIG_IP_NF_MANGLE=m
CONFIG_IP6_NF_IPTABLES=m
CONFIG_IP6_NF_MATCH_AH=m
CONFIG_IP6_NF_MATCH_EUI64=m
CONFIG_IP6_NF_MATCH_IPV6HEADER=m
CONFIG_IP6_NF_FILTER=m
CONFIG_IP6_NF_TARGET_REJECT=m
CONFIG_IP6_NF_MANGLE=m
CONFIG_IP6_NF_RAW=m
CONFIG_IP6_NF_NAT=m
CONFIG_IP6_NF_TARGET_MASQUERADE=m
CONFIG_IP6_NF_TARGET_NPT=m
CONFIG_NF_TABLES_BRIDGE=m
CONFIG_NFT_BRIDGE_META=m
CONFIG_NFT_BRIDGE_REJECT=m
CONFIG_NF_CONNTRACK_BRIDGE=y
CONFIG_BRIDGE_NF_EBTABLES=m
CONFIG_BRIDGE_EBT_BROUTE=m
CONFIG_BRIDGE_EBT_T_FILTER=m
CONFIG_BRIDGE_EBT_T_NAT=m
CONFIG_BRIDGE_EBT_802_3=m
CONFIG_BRIDGE_EBT_AMONG=m
CONFIG_BRIDGE_EBT_ARP=m
CONFIG_BRIDGE_EBT_IP=m
CONFIG_BRIDGE_EBT_IP6=m
CONFIG_BRIDGE_EBT_LIMIT=m
CONFIG_BRIDGE_EBT_MARK=m
CONFIG_BRIDGE_EBT_PKTTYPE=m
CONFIG_BRIDGE_EBT_STP=m
CONFIG_BRIDGE_EBT_VLAN=m
CONFIG_BRIDGE_EBT_ARPREPLY=m
CONFIG_BRIDGE_EBT_DNAT=m
CONFIG_BRIDGE_EBT_MARK_T=m
CONFIG_BRIDGE_EBT_REDIRECT=m
CONFIG_BRIDGE_EBT_SNAT=m
CONFIG_BRIDGE_EBT_LOG=m
CONFIG_BRIDGE_EBT_NFLOG=m
CONFIG_BRIDGE=y
CONFIG_BRIDGE=m
CONFIG_BRIDGE_VLAN_FILTERING=y
CONFIG_BRIDGE_MRP=y
CONFIG_BRIDGE_CFM=y
CONFIG_VLAN_8021Q=y
CONFIG_NET_DSA=m
CONFIG_NET_DSA_TAG_OCELOT=m
CONFIG_NET_DSA_TAG_OCELOT_8021Q=m
CONFIG_VLAN_8021Q=m
CONFIG_VLAN_8021Q_GVRP=y
CONFIG_VLAN_8021Q_MVRP=y
CONFIG_NET_SCHED=y
@@ -200,22 +121,13 @@ CONFIG_NET_SCH_TAPRIO=m
CONFIG_NET_SCH_MQPRIO=m
CONFIG_NET_SCH_INGRESS=m
CONFIG_NET_CLS_BASIC=m
CONFIG_NET_CLS_BPF=m
CONFIG_NET_CLS_FLOWER=m
CONFIG_NET_CLS_ACT=y
CONFIG_NET_ACT_GACT=y
CONFIG_NET_ACT_MIRRED=y
CONFIG_NET_ACT_NAT=y
CONFIG_NET_ACT_SKBEDIT=y
CONFIG_NET_ACT_VLAN=y
CONFIG_NET_ACT_BPF=y
CONFIG_DCB=y
CONFIG_NETLINK_DIAG=y
CONFIG_MPLS=y
CONFIG_NET_MPLS_GSO=y
CONFIG_MPLS_ROUTING=m
CONFIG_NET_PKTGEN=y
CONFIG_NET_ACT_GACT=m
CONFIG_NET_ACT_MIRRED=m
CONFIG_NET_ACT_GATE=m
CONFIG_BT=m
CONFIG_BT_HIDP=m
# CONFIG_BT_LE is not set
CONFIG_BT_LEDS=y
# CONFIG_BT_DEBUGFS is not set
@@ -230,7 +142,6 @@ CONFIG_MAC80211_LEDS=y
CONFIG_RFKILL=y
CONFIG_NET_9P=y
CONFIG_NET_9P_VIRTIO=y
# CONFIG_ETHTOOL_NETLINK is not set
CONFIG_PCI=y
CONFIG_PCIEPORTBUS=y
CONFIG_PCI_IOV=y
@@ -246,7 +157,6 @@ CONFIG_PCI_EPF_TEST=m
CONFIG_DEVTMPFS=y
CONFIG_DEVTMPFS_MOUNT=y
CONFIG_FW_LOADER_USER_HELPER=y
CONFIG_VEXPRESS_CONFIG=y
CONFIG_ARM_SCMI_PROTOCOL=y
CONFIG_ARM_SCPI_PROTOCOL=y
CONFIG_EFI_CAPSULE_LOADER=y
@@ -261,7 +171,6 @@ CONFIG_MTD_PHYSMAP=y
CONFIG_MTD_PHYSMAP_OF=y
CONFIG_MTD_DATAFLASH=y
CONFIG_MTD_SST25L=y
CONFIG_MTD_BLOCK2MTD=y
CONFIG_MTD_RAW_NAND=y
CONFIG_MTD_NAND_DENALI_DT=y
CONFIG_MTD_SPI_NOR=y
@@ -282,7 +191,6 @@ CONFIG_SCSI_HISI_SAS=y
CONFIG_SCSI_HISI_SAS_PCI=y
CONFIG_MEGARAID_SAS=y
CONFIG_SCSI_MPT3SAS=m
CONFIG_SCSI_VIRTIO=y
CONFIG_ATA=y
CONFIG_SATA_AHCI=y
CONFIG_SATA_AHCI_PLATFORM=y
@@ -290,29 +198,24 @@ CONFIG_AHCI_CEVA=y
CONFIG_SATA_SIL24=y
CONFIG_PATA_OF_PLATFORM=y
CONFIG_MD=y
# CONFIG_MD_BITMAP_FILE is not set
CONFIG_BLK_DEV_DM=y
CONFIG_DM_INIT=y
CONFIG_DM_VERITY=y
CONFIG_DM_VERITY_VERIFY_ROOTHASH_SIG=y
CONFIG_BLK_DEV_MD=m
CONFIG_BLK_DEV_DM=m
CONFIG_DM_MIRROR=m
CONFIG_DM_ZERO=m
CONFIG_NETDEVICES=y
CONFIG_BONDING=m
CONFIG_DUMMY=m
CONFIG_DUMMY=y
CONFIG_WIREGUARD=m
CONFIG_MACVLAN=m
CONFIG_MACVTAP=m
CONFIG_IPVLAN=m
CONFIG_IPVTAP=m
CONFIG_VXLAN=m
CONFIG_VXLAN=y
CONFIG_GENEVE=m
CONFIG_BAREUDP=m
CONFIG_MACSEC=m
CONFIG_TUN=m
CONFIG_TUN=y
CONFIG_VETH=m
CONFIG_VIRTIO_NET=y
CONFIG_NLMON=y
CONFIG_NET_VRF=y
CONFIG_VIRTIO_NET=m
# CONFIG_NET_VENDOR_3COM is not set
# CONFIG_NET_VENDOR_ACTIONS is not set
# CONFIG_NET_VENDOR_ADAPTEC is not set
# CONFIG_NET_VENDOR_AGERE is not set
# CONFIG_NET_VENDOR_ALACRITECH is not set
@@ -380,12 +283,15 @@ CONFIG_STMMAC_ETH=y
# CONFIG_NET_VENDOR_VIA is not set
# CONFIG_NET_VENDOR_WIZNET is not set
# CONFIG_NET_VENDOR_XILINX is not set
CONFIG_LED_TRIGGER_PHY=y
CONFIG_AX88796B_PHY=y
CONFIG_DAVICOM_PHY=m
CONFIG_MICREL_PHY=y
CONFIG_MICROSEMI_PHY=y
CONFIG_AT803X_PHY=m
CONFIG_REALTEK_PHY=y
CONFIG_ROCKCHIP_PHY=y
CONFIG_MDIO_BITBANG=y
CONFIG_MDIO_BCM_UNIMAC=m
CONFIG_MDIO_THUNDER=y
CONFIG_MDIO_BUS_MUX_MULTIPLEXER=y
CONFIG_MDIO_BUS_MUX_MMIOREG=y
CONFIG_USB_RTL8150=m
@@ -393,7 +299,6 @@ CONFIG_USB_RTL8152=m
CONFIG_USB_USBNET=y
CONFIG_USB_NET_AX8817X=m
CONFIG_USB_NET_AX88179_178A=m
CONFIG_USB_NET_CDC_NCM=m
CONFIG_USB_NET_DM9601=m
CONFIG_USB_NET_SMSC75XX=m
CONFIG_USB_NET_SMSC95XX=m
@@ -401,12 +306,13 @@ CONFIG_USB_NET_NET1080=m
CONFIG_USB_NET_PLUSB=m
CONFIG_USB_NET_MCS7830=m
CONFIG_USB_NET_CDC_SUBSET=m
# CONFIG_USB_NET_ZAURUS is not set
CONFIG_USB_NET_ZAURUS=m
CONFIG_ATH10K=m
CONFIG_ATH10K_PCI=m
CONFIG_WCN36XX=m
# CONFIG_WLAN_VENDOR_ATMEL is not set
# CONFIG_WLAN_VENDOR_BROADCOM is not set
# CONFIG_WLAN_VENDOR_CISCO is not set
# CONFIG_WLAN_VENDOR_INTEL is not set
# CONFIG_WLAN_VENDOR_INTERSIL is not set
# CONFIG_WLAN_VENDOR_MARVELL is not set
@@ -449,11 +355,9 @@ CONFIG_RTW89_DEBUGMSG=y
# CONFIG_WLAN_VENDOR_TI is not set
# CONFIG_WLAN_VENDOR_ZYDAS is not set
# CONFIG_WLAN_VENDOR_QUANTENNA is not set
CONFIG_NET_FAILOVER=y
CONFIG_INPUT_FF_MEMLESS=y
CONFIG_INPUT_EVDEV=y
CONFIG_INPUT_EVBUG=y
CONFIG_KEYBOARD_GPIO=y
CONFIG_KEYBOARD_GPIO_POLLED=y
# CONFIG_INPUT_KEYBOARD is not set
# CONFIG_INPUT_MOUSE is not set
CONFIG_INPUT_MISC=y
CONFIG_INPUT_RK805_PWRKEY=y
@@ -500,38 +404,47 @@ CONFIG_PPS=y
CONFIG_DEBUG_PINCTRL=y
CONFIG_PINCTRL_RK805=y
CONFIG_PINCTRL_SINGLE=y
CONFIG_GPIO_SYSFS=y
CONFIG_GPIO_GENERIC_PLATFORM=y
CONFIG_GPIO_ALTERA=m
CONFIG_GPIO_DWAPB=y
CONFIG_GPIO_MB86S7X=y
CONFIG_GPIO_PL061=y
CONFIG_GPIO_XGENE=y
CONFIG_GPIO_MAX732X=y
CONFIG_GPIO_PCA953X=y
CONFIG_GPIO_PCA953X_IRQ=y
CONFIG_POWER_RESET_GPIO_RESTART=y
CONFIG_POWER_RESET_XGENE=y
CONFIG_POWER_RESET_SYSCON=y
CONFIG_SYSCON_REBOOT_MODE=y
CONFIG_CHARGER_RK817=y
CONFIG_BATTERY_SBS=m
CONFIG_BATTERY_BQ27XXX=y
CONFIG_BATTERY_MAX17042=m
CONFIG_CHARGER_BQ25890=m
CONFIG_CHARGER_BQ25980=m
CONFIG_SENSORS_ARM_SCMI=y
CONFIG_SENSORS_ARM_SCPI=y
CONFIG_SENSORS_LM90=m
CONFIG_SENSORS_PWM_FAN=m
CONFIG_THERMAL_GOV_POWER_ALLOCATOR=y
CONFIG_CPU_THERMAL=y
CONFIG_THERMAL_EMULATION=y
CONFIG_ROCKCHIP_THERMAL=m
CONFIG_WATCHDOG=y
CONFIG_WATCHDOG_SYSFS=y
CONFIG_SOFT_WATCHDOG=y
CONFIG_ARM_SP805_WATCHDOG=y
CONFIG_ARM_SBSA_WATCHDOG=y
CONFIG_DW_WATCHDOG=y
CONFIG_ARM_SMC_WATCHDOG=y
CONFIG_MFD_RK8XX_I2C=y
CONFIG_MFD_RK8XX_SPI=y
# CONFIG_MFD_VEXPRESS_SYSREG is not set
CONFIG_REGULATOR=y
CONFIG_MFD_STMFX=y
CONFIG_REGULATOR_DEBUG=y
CONFIG_REGULATOR_FIXED_VOLTAGE=y
CONFIG_REGULATOR_USERSPACE_CONSUMER=y
CONFIG_REGULATOR_NETLINK_EVENTS=y
CONFIG_REGULATOR_GPIO=y
CONFIG_REGULATOR_PWM=y
CONFIG_REGULATOR_RK808=y
CONFIG_REGULATOR_VCTRL=y
# CONFIG_HID_SUPPORT is not set
CONFIG_USB_ULPI_BUS=y
CONFIG_REGULATOR_VEXPRESS=m
# CONFIG_HID_GENERIC is not set
# CONFIG_USB_HID is not set
CONFIG_USB_CONN_GPIO=y
CONFIG_USB=y
CONFIG_USB_ANNOUNCE_NEW_DEVICES=y
@@ -539,7 +452,6 @@ CONFIG_USB_DYNAMIC_MINORS=y
CONFIG_USB_OTG=y
CONFIG_USB_XHCI_HCD=y
CONFIG_USB_EHCI_HCD=y
CONFIG_USB_EHCI_ROOT_HUB_TT=y
CONFIG_USB_EHCI_HCD_PLATFORM=y
CONFIG_USB_OHCI_HCD=y
CONFIG_USB_OHCI_HCD_PLATFORM=y
@@ -548,6 +460,10 @@ CONFIG_USB_STORAGE=y
CONFIG_USB_MUSB_HDRC=y
CONFIG_USB_DWC3=y
CONFIG_USB_DWC2=y
CONFIG_USB_CHIPIDEA=y
CONFIG_USB_CHIPIDEA_UDC=y
CONFIG_USB_CHIPIDEA_HOST=y
CONFIG_USB_ISP1760=y
CONFIG_USB_SERIAL=m
CONFIG_USB_SERIAL_GENERIC=y
CONFIG_USB_SERIAL_SIMPLE=m
@@ -555,6 +471,7 @@ CONFIG_USB_SERIAL_CP210X=m
CONFIG_USB_SERIAL_FTDI_SIO=m
CONFIG_USB_SERIAL_PL2303=m
CONFIG_USB_SERIAL_OPTION=m
CONFIG_USB_HSIC_USB3503=y
CONFIG_NOP_USB_XCEIV=y
CONFIG_USB_ULPI=y
CONFIG_USB_GADGET=y
@@ -571,6 +488,12 @@ CONFIG_USB_CONFIGFS_RNDIS=y
CONFIG_USB_CONFIGFS_EEM=y
CONFIG_USB_CONFIGFS_MASS_STORAGE=y
CONFIG_USB_CONFIGFS_F_FS=y
CONFIG_TYPEC=m
CONFIG_TYPEC_TCPM=m
CONFIG_TYPEC_TCPCI=m
CONFIG_TYPEC_FUSB302=m
CONFIG_TYPEC_TPS6598X=m
CONFIG_TYPEC_HD3SS3220=m
CONFIG_MMC=y
CONFIG_MMC_BLOCK_MINORS=32
CONFIG_MMC_ARMMMCI=y
@@ -582,9 +505,13 @@ CONFIG_MMC_SDHCI_CADENCE=y
CONFIG_MMC_SDHCI_F_SDH30=y
CONFIG_MMC_SPI=y
CONFIG_MMC_DW=y
CONFIG_MMC_DW_EXYNOS=y
CONFIG_MMC_DW_HI3798CV200=y
CONFIG_MMC_DW_K3=y
CONFIG_MMC_DW_ROCKCHIP=y
CONFIG_MMC_MTK=y
CONFIG_MMC_SDHCI_XENON=y
CONFIG_MMC_SDHCI_AM654=y
CONFIG_SCSI_UFSHCD=y
CONFIG_SCSI_UFSHCD_PLATFORM=y
CONFIG_NEW_LEDS=y
@@ -600,7 +527,6 @@ CONFIG_LEDS_TRIGGER_HEARTBEAT=y
CONFIG_LEDS_TRIGGER_CPU=y
CONFIG_LEDS_TRIGGER_DEFAULT_ON=y
CONFIG_LEDS_TRIGGER_PANIC=y
CONFIG_LEDS_TRIGGER_NETDEV=y
CONFIG_RTC_CLASS=y
CONFIG_RTC_DRV_RK808=y
CONFIG_RTC_DRV_EFI=y
@@ -615,6 +541,7 @@ CONFIG_VIRTIO_INPUT=y
CONFIG_VIRTIO_MMIO=y
# CONFIG_VHOST_MENU is not set
CONFIG_STAGING=y
CONFIG_PRISM2_USB=m
CONFIG_RTLLIB=m
CONFIG_RTL8192E=m
CONFIG_RTL8723BS=m
@@ -638,6 +565,7 @@ CONFIG_ROCKCHIP_IODOMAIN=y
CONFIG_ROCKCHIP_DTPM=m
CONFIG_ROCKCHIP_PM_DOMAINS=y
CONFIG_DEVFREQ_GOV_USERSPACE=m
CONFIG_EXTCON_PTN5150=m
CONFIG_EXTCON_USB_GPIO=y
CONFIG_MEMORY=y
CONFIG_IIO=y
@@ -650,7 +578,6 @@ CONFIG_IIO_ST_MAGN_3AXIS=m
CONFIG_MPL3115=m
CONFIG_PWM=y
CONFIG_PWM_ROCKCHIP=y
CONFIG_RESET_GPIO=y
CONFIG_PHY_ROCKCHIP_DPHY_RX0=m
CONFIG_PHY_ROCKCHIP_EMMC=y
CONFIG_PHY_ROCKCHIP_INNO_HDMI=m
@@ -663,6 +590,8 @@ CONFIG_PHY_ROCKCHIP_USB=m
CONFIG_POWERCAP=y
CONFIG_ARM_SCMI_POWERCAP=y
CONFIG_DTPM=y
CONFIG_DTPM_CPU=y
CONFIG_DTPM_DEVFREQ=y
CONFIG_ARM_SMMU_V3_PMU=m
CONFIG_NVMEM_RMEM=m
CONFIG_NVMEM_ROCKCHIP_EFUSE=m
@@ -674,48 +603,30 @@ CONFIG_INTERCONNECT=y
CONFIG_EXT2_FS=y
CONFIG_EXT3_FS=y
CONFIG_EXT4_FS_POSIX_ACL=y
CONFIG_BTRFS_FS=y
CONFIG_BTRFS_FS_POSIX_ACL=y
CONFIG_FANOTIFY=y
CONFIG_FANOTIFY_ACCESS_PERMISSIONS=y
CONFIG_QUOTA=y
CONFIG_AUTOFS_FS=y
CONFIG_FUSE_FS=y
CONFIG_VIRTIO_FS=y
CONFIG_OVERLAY_FS=y
CONFIG_MSDOS_FS=y
CONFIG_OVERLAY_FS=m
CONFIG_VFAT_FS=y
CONFIG_FAT_DEFAULT_UTF8=y
CONFIG_EXFAT_FS=y
CONFIG_PROC_KCORE=y
CONFIG_PROC_CHILDREN=y
CONFIG_TMPFS=y
CONFIG_TMPFS_POSIX_ACL=y
CONFIG_HUGETLBFS=y
CONFIG_EFIVAR_FS=y
CONFIG_JFFS2_FS=y
CONFIG_JFFS2_FS_XATTR=y
CONFIG_SQUASHFS=y
CONFIG_SQUASHFS_LZO=y
CONFIG_SQUASHFS_XZ=y
CONFIG_SQUASHFS_ZSTD=y
CONFIG_NFS_FS=y
CONFIG_NFS_V4=y
CONFIG_NFS_V4_1=y
CONFIG_NFS_V4_2=y
CONFIG_ROOT_NFS=y
CONFIG_9P_FS=y
CONFIG_NLS_DEFAULT="iso8859-15"
CONFIG_NLS_CODEPAGE_437=y
CONFIG_NLS_ISO8859_1=y
CONFIG_NLS_ISO8859_15=y
CONFIG_NLS_UTF8=y
CONFIG_SECURITY=y
CONFIG_CRYPTO_DH=m
CONFIG_CRYPTO_CURVE25519=m
CONFIG_CRYPTO_ECHAINIV=y
CONFIG_CRYPTO_LZO=y
CONFIG_CRYPTO_ZSTD=y
CONFIG_CRYPTO_BLAKE2B=m
CONFIG_CRYPTO_XXHASH=m
CONFIG_CRYPTO_ANSI_CPRNG=y
CONFIG_CRYPTO_USER_API_RNG=m
CONFIG_CRYPTO_GHASH_ARM64_CE=y
@@ -724,22 +635,20 @@ CONFIG_CRYPTO_SHA2_ARM64_CE=y
CONFIG_CRYPTO_SHA512_ARM64_CE=m
CONFIG_CRYPTO_SHA3_ARM64=m
CONFIG_CRYPTO_SM3_ARM64_CE=m
CONFIG_CRYPTO_AES_ARM64_CE_BLK=y
CONFIG_CRYPTO_AES_ARM64_BS=m
CONFIG_CRYPTO_AES_ARM64_CE_CCM=y
CONFIG_CRYPTO_CRCT10DIF_ARM64_CE=m
CONFIG_CRYPTO_DEV_ROCKCHIP=y
CONFIG_CRYPTO_DEV_CCREE=m
CONFIG_PACKING=y
CONFIG_INDIRECT_PIO=y
CONFIG_CRC_CCITT=m
CONFIG_CRC8=y
CONFIG_DMA_CMA=y
CONFIG_CMA_SIZE_MBYTES=32
CONFIG_PRINTK_TIME=y
CONFIG_DEBUG_INFO_DWARF_TOOLCHAIN_DEFAULT=y
CONFIG_MAGIC_SYSRQ=y
CONFIG_DEBUG_FS=y
CONFIG_DETECT_HUNG_TASK=y
# CONFIG_SCHED_DEBUG is not set
CONFIG_FUNCTION_TRACER=y
# CONFIG_FTRACE is not set
CONFIG_MEMTEST=y
@@ -1,189 +0,0 @@
{
"ieee802-dot1ab-lldp:lldp": {
"infix-lldp:enabled": true
},
"ietf-interfaces:interfaces": {
"interface": [
{
"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": "lan",
"type": "infix-if-type:ethernet",
"ietf-ip:ipv4": {
"address": [
{
"ip": "192.168.2.1",
"prefix-length": 24
}
]
},
"ietf-ip:ipv6": {}
},
{
"name": "wan",
"type": "infix-if-type:ethernet"
}
]
},
"ietf-keystore:keystore": {
"asymmetric-keys": {
"asymmetric-key": [
{
"name": "genkey",
"public-key-format": "ietf-crypto-types:ssh-public-key-format",
"public-key": "",
"private-key-format": "ietf-crypto-types:rsa-private-key-format",
"cleartext-private-key": "",
"certificates": {}
}
]
}
},
"ietf-netconf-acm:nacm": {
"groups": {
"group": [
{
"name": "admin",
"user-name": [
"admin"
]
}
]
},
"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."
}
]
}
]
},
"ietf-netconf-server:netconf-server": {
"listen": {
"endpoints": {
"endpoint": [
{
"name": "default-ssh",
"ssh": {
"tcp-server-parameters": {
"local-address": "::"
},
"ssh-server-parameters": {
"server-identity": {
"host-key": [
{
"name": "default-key",
"public-key": {
"central-keystore-reference": "genkey"
}
}
]
}
}
}
}
]
}
}
},
"ietf-system:system": {
"hostname": "r2s",
"ntp": {
"enabled": true,
"server": [
{
"name": "ntp.org",
"udp": {
"address": "pool.ntp.org"
}
}
]
},
"authentication": {
"user": [
{
"name": "admin",
"password": "$factory$",
"infix-system:shell": "bash"
}
]
},
"infix-system:motd-banner": "Li0tLS0tLS0uCnwgIC4gLiAgfCBJbmZpeCAtLSBhIE5ldHdvcmsgT3BlcmF0aW5nIFN5c3RlbQp8LS4gdiAuLXwgaHR0cHM6Ly9rZXJuZWxraXQuZ2l0aHViLmlvCictJy0tLSctJwo="
},
"infix-dhcp-client:dhcp-client": {
"client-if": [
{
"if-name": "wan",
"option": [
{
"name": "broadcast"
},
{
"name": "dns"
},
{
"name": "domain"
},
{
"name": "hostname"
},
{
"name": "ntpsrv"
},
{
"name": "router"
},
{
"name": "subnet"
}
]
}
]
},
"infix-meta:meta": {
"infix-meta:version": "1.0"
},
"infix-services:mdns": {
"enabled": true
},
"infix-services:web": {
"enabled": true,
"console": {
"enabled": true
},
"netbrowse": {
"enabled": true
},
"restconf": {
"enabled": true
}
}
}
@@ -1 +0,0 @@
../available/input-event-daemon.conf
@@ -1 +0,0 @@
service [12345789] log wan-monitor.sh -- WAN Health monitor
-91
View File
@@ -1,91 +0,0 @@
{
"input": {
"path": {
"locate": { "path": "/run/led/locate" },
"status-prime": { "path": "/run/led/status-prime" },
"status-ok": { "path": "/run/led/status-ok" },
"status-err": { "path": "/run/led/status-err" },
"status-crit": { "path": "/run/led/status-crit" },
"fault-prime": { "path": "/run/led/fault-prime" },
"fault-ok": { "path": "/run/led/fault-ok" },
"fault-err": { "path": "/run/led/fault-err" },
"fault-crit": { "path": "/run/led/fault-crit" },
"wan-up": { "path": "/run/led/wan-up" },
"startup": { "path": "/run/finit/cond/run/startup/success" },
"fail-safe": { "path": "/run/finit/cond/run/failure/success" },
"panic": { "path": "/run/finit/cond/run/failure/failure" }
},
"udev": {
"power-a": { "subsystem": "power_supply" },
"power-b": { "subsystem": "power_supply" }
}
},
"output": {
"led-group": {
"port-link-act": {
"match": ["*:green:tp", "*:green:sfp", "*:green:port" ],
"rules": [
{ "if": "true", "then": { "trigger": "netdev", "link": 1, "rx": 1, "tx": 1 } }
]
},
"port-alarm": {
"match": ["*:yellow:tp", "*:yellow:sfp", "*:yellow:port" ],
"rules": [
]
}
},
"led": {
"nanopi-r2s:red:sys": {
"rules": [
{ "if": "locate", "then": "@blink-1hz" },
{ "if": "panic", "then": "@blink-5hz" },
{ "if": "fail-safe", "then": "@blink-5hz" },
{ "if": "startup", "then": "@off" },
{ "if": "true", "then": "@blink-1hz" }
]
},
"nanopi-r2s:green:lan": {
"rules": [
{ "if": "locate", "then": "@blink-1hz" },
{ "if": "panic", "then": "@blink-5hz" },
{ "if": "startup", "then": "@on" }
]
},
"nanopi-r2s:green:wan": {
"rules": [
{ "if": "locate", "then": "@blink-1hz" },
{ "if": "panic", "then": "@blink-5hz" },
{ "if": "wan-up", "then": "@on" }
]
}
}
},
"aliases": {
"on": {
"brightness": true
},
"off": {
"brightness": false
},
"blink-1hz": {
"trigger": "timer",
"delay_on": 500,
"delay_off": 500
},
"blink-5hz": {
"trigger": "timer",
"delay_on": 100,
"delay_off": 100
}
}
}
@@ -1,5 +0,0 @@
[Global]
listen = /dev/input/event1
[Keys]
RESTART = reboot
@@ -1,2 +0,0 @@
ACTION=="add", SUBSYSTEM=="net", DEVPATH=="/devices/platform/ff540000.ethernet/net/eth0", NAME="wan"
ACTION=="add", SUBSYSTEM=="net", DEVPATH=="/devices/platform/ff600000.usb/xhci-hcd.0.auto/usb3/3-1/3-1:1.0/net/*", NAME="lan"
@@ -1,41 +0,0 @@
#!/bin/sh
# Background WAN interface monitor. Lights up WAN LED
# while the interface has a DHCP address.
LED_FILE="/run/led/wan-up"
PID_FILE="/run/$(basename "$0").pid"
check_wan()
{
ip_info=$(ip a show wan)
if echo "$ip_info" | grep -q "inet .* proto dhcp"; then
[ ! -f "$LED_FILE" ] && touch "$LED_FILE"
else
[ -f "$LED_FILE" ] && rm "$LED_FILE"
fi
}
cleanup()
{
rm -f "$LED_FILE"
rm -f "$PID_FILE"
exit 0
}
trap 'cleanup' TERM INT HUP QUIT
echo $$ > "$PID_FILE"
remaining_time=$((1800 - $(awk '{print int($1)}' /proc/uptime)))
[ "$remaining_time" -lt 0 ] && remaining_time=0
while [ "$remaining_time" -gt 0 ]; do
check_wan
sleep 1
remaining_time=$((remaining_time - 1))
done
while :; do
check_wan
sleep 5
done
-16
View File
@@ -1,16 +0,0 @@
CONFIG_BUTTON=y
CONFIG_BUTTON_GPIO=y
CONFIG_LED=y
CONFIG_LED_GPIO=y
# CONFIG_MMC_PCI is not set
CONFIG_DEVICE_TREE_INCLUDES="infix-env.dtsi infix-key.dtsi r2s-env.dtsi"
CONFIG_SYS_PROMPT="(r2s) "
CONFIG_ENV_OVERWRITE=y
# CONFIG_ENV_IS_NOWHERE is not set
CONFIG_ENV_IS_IN_EXT4=y
# CONFIG_ENV_IS_IN_MMC is not set
CONFIG_ENV_EXT4_INTERFACE="mmc"
CONFIG_ENV_EXT4_DEVICE_AND_PART="1:1"
-47
View File
@@ -1,47 +0,0 @@
/ {
config {
environment {
boot_targets = "mmc1";
ethprime = "eth0";
/* This is a development platform, hard code developer mode */
ixbtn-devmode = "setenv dev_mode yes; echo Enabled";
/* Override default definitiion to add LED feedback */
ixbtn-factory = "
if button factory-reset; then
echo \"Keep button pressed for 10 seconds to engage factory reset ...\"
for tick in . . . . . . . . . .; do
led nanopi-r2s:red:sys on
led nanopi-r2s:green:lan on
led nanopi-r2s:green:wan on
sleep 0.5
led nanopi-r2s:red:sys off
led nanopi-r2s:green:lan off
led nanopi-r2s:green:wan off
sleep 0.5
echo -n \"Checking button: \"
button factory-reset || exit
done
echo -n \"Final button check: \"
if button factory-reset; then
setenv factory_reset yes
echo \"FACTORY RESET ENGAGED\"
fi
fi
";
};
};
keys {
compatible = "gpio-keys";
factory-reset {
gpios = <&gpio0 0 GPIO_ACTIVE_LOW>;
linux,code = <KEY_POWER>;
label = "factory-reset";
};
};
};
-18
View File
@@ -107,18 +107,6 @@ config DISK_IMAGE_BOOT_OFFSET
to make sure that the GPT still fits at the start of the
image.
config DISK_IMAGE_TEST_MODE
bool "Enable Test Mode"
depends on DISK_IMAGE
default y
help
Enable the test mode option by default. This setting creates a test-mode flag
in the auxiliary partition of the disk image, initiating the system with the test-config
instead of regular startup-config. The primary purpose of running an image in this mode
is to ensure proper execution of all Infix tests. Additionally, it enables extra RPCs
related to system restart and configuration overrides, allowing tests to be run even on
systems where the factory configuration may potentially create L2 loops.
config DISK_IMAGE_RELEASE_URL
string "Infix URL"
depends on DISK_IMAGE
@@ -172,9 +160,3 @@ config FIT_ARCH
config FIT_KERNEL_LOAD_ADDR
string "Kernel load address"
depends on FIT_IMAGE
config SDCARD_AUX
bool "Create SD-card aux partition"
help
Create and populate aux.ext4 with rootfs.itbh and rauc.status
For use with a static genimage.cfg for, e.g., SD-cards.
-39
View File
@@ -1,39 +0,0 @@
#!/bin/sh
rootdir=$BUILD_DIR/genimage.root
tempdir=$BUILD_DIR/genimage.tmp
cat <<EOF > /tmp/mkaux.cfg
image aux.ext4 {
mountpoint = "/aux"
size = 16M
ext4 {
label = "aux"
use-mke2fs = true
features = "^metadata_csum,^metadata_csum_seed"
}
}
# Silence genimage warnings
config {}
EOF
rm -rf "$rootdir/aux"
mkdir -p "$rootdir/aux"
cp -f "$BINARIES_DIR/rootfs.itbh" "$rootdir/aux/primary.itbh"
cp -f "$BINARIES_DIR/rootfs.itbh" "$rootdir/aux/secondary.itbh"
cp -f "$BINARIES_DIR/rauc.status" "$rootdir/aux/rauc.status"
mkenvimage -s 0x4000 -o "$rootdir/aux/uboot.env" \
"$BR2_EXTERNAL_INFIX_PATH/board/common/uboot/aux-env.txt"
rm -rf "$BINARIES_DIR/aux.ext4"
rm -rf "$tempdir"
genimage \
--rootpath "$rootdir" \
--tmppath "$tempdir" \
--inputpath "$BINARIES_DIR" \
--outputpath "$BINARIES_DIR" \
--config "/tmp/mkaux.cfg"
+1 -10
View File
@@ -128,7 +128,7 @@ diskimg=disk.img
bootimg=
bootpart=
while getopts "a:b:B:n:s:t" opt; do
while getopts "a:b:B:n:s:" opt; do
case ${opt} in
a)
arch=$OPTARG
@@ -145,9 +145,6 @@ while getopts "a:b:B:n:s:t" opt; do
s)
total=$(size2int $OPTARG)
;;
t)
testmode=true
;;
esac
done
shift $((OPTIND - 1))
@@ -193,12 +190,6 @@ cp -f $BINARIES_DIR/rootfs.itbh $root/aux/primary.itbh
cp -f $BINARIES_DIR/rootfs.itbh $root/aux/secondary.itbh
cp -f $BINARIES_DIR/rauc.status $root/aux/rauc.status
if [ "$testmode" = true ]; then
touch "$root/aux/test-mode"
else
rm -f "$root/aux/test-mode"
fi
case "$arch" in
aarch64)
mkenvimage -s 0x4000 -o "$root/aux/uboot.env" \
+12 -12
View File
@@ -2,30 +2,30 @@
set -e
GIT_VERSION=$(git -C "$BR2_EXTERNAL_INFIX_PATH" describe --always --dirty --tags)
GIT_VERSION=$(git -C $BR2_EXTERNAL_INFIX_PATH describe --always --dirty --tags)
name=$1
compat=$2
arch=$2
sign=$3
crt=$(ls $sign/*.crt)
key=$(ls $sign/*.key)
common=$(dirname "$(readlink -f "$0")")
common=$(dirname $(readlink -f "$0"))
work=$BUILD_DIR/mkrauc
mkdir -p "$work"
mkdir -p $work
cp -f "$common/rauc-hooks.sh" "$work/hooks.sh"
cp -f $common/rauc-hooks.sh $work/hooks.sh
# RAUC internally uses the file extension to find a suitable install
# handler, hence the name must be .img
cp -f "$BINARIES_DIR/rootfs.squashfs" "$work/rootfs.img"
cp -f "$BINARIES_DIR/rootfs.itbh" "$work/rootfs.itbh"
cp -f $BINARIES_DIR/rootfs.squashfs $work/rootfs.img
cp -f $BINARIES_DIR/rootfs.itbh $work/rootfs.itbh
cat >"$work/manifest.raucm" <<EOF
cat >$work/manifest.raucm <<EOF
[update]
compatible=${compat}
compatible=infix-${arch}
version=${GIT_VERSION}
[bundle]
@@ -39,7 +39,7 @@ filename=rootfs.img
hooks=post-install
EOF
rm -f "$BINARIES_DIR/$name.pkg"
rm -f $BINARIES_DIR/$name.pkg
rauc --cert="$crt" --key="$key" \
bundle "$work" "$BINARIES_DIR/$name.pkg"
rauc --cert=$crt --key=$key \
bundle $work $BINARIES_DIR/$name.pkg
-49
View File
@@ -4,37 +4,6 @@ common=$(dirname "$(readlink -f "$0")")
. "$BR2_CONFIG" 2>/dev/null
. "$TARGET_DIR/usr/lib/os-release"
# Extract list of loaded YANG modules and their features for yangdoc.html
mkyangdoc()
{
cmd="yangdoc -o $1 -p $TARGET_DIR/usr/share/yang"
# shellcheck disable=SC2155
export SYSREPO_SHM_PREFIX="yangdoc"
while IFS= read -r line; do
if echo "$line" | grep -q '^[a-z]'; then
module=$(echo "$line" | awk '{print $1}')
cmd="$cmd -m $module"
feature=$(echo "$line" | awk -F'|' '{print $8}' | sed 's/^ *//;s/ *$//')
if [ -n "$feature" ]; then
feature_list=$(echo "$feature" | tr ' ' '\n')
for feat in $feature_list; do
cmd="$cmd -e $feat"
done
fi
fi
done <<EOF
$(sysrepoctl -l; rm -f /dev/shm/${SYSREPO_SHM_PREFIX}*)
EOF
# Ignore a few top-level oddballs not used by core Infix
cmd="$cmd -x supported-algorithms"
# Execute the command
echo "Calling: $cmd"
$cmd
}
if [ -n "${ID_LIKE}" ]; then
ID="${ID} ${ID_LIKE}"
fi
@@ -55,16 +24,6 @@ else
VERSION=$GIT_VERSION
fi
if [ -n "$INFIX_IMAGE_ID" ]; then
NAME="$INFIX_IMAGE_ID"
else
NAME="$INFIX_ID"-$(echo "$BR2_ARCH" | tr _ - | sed 's/x86-64/x86_64/')
fi
if [ -f "$TARGET_DIR/etc/rauc/system.conf" ]; then
sed -i "s/compatible=.*/compatible=$NAME/" "$TARGET_DIR/etc/rauc/system.conf"
fi
# This is a symlink to /usr/lib/os-release, so we remove this to keep
# original Buildroot information.
rm -f "$TARGET_DIR/etc/os-release"
@@ -110,9 +69,6 @@ if [ -L "$TARGET_DIR/var/lib/avahi-autoipd" ]; then
mkdir "$TARGET_DIR/var/lib/avahi-autoipd"
fi
# Drop Buildroot default pam_lastlog.so from login chain
sed -i '/^[^#]*pam_lastlog.so/s/^/# /' "$TARGET_DIR/etc/pam.d/login"
# Allow pdmenu (setup) and bash to be login shells, bash is added
# automatically when selected in menuyconfig, but not when BusyBox
# provides a symlink (for ash). The /bin/{true,false} are old UNIX
@@ -129,8 +85,3 @@ grep -qsE '^/bin/false$$' "$TARGET_DIR/etc/shells" \
# Allow clish (symlink to /usr/bin/klish) to be a login shell
grep -qsE '^/bin/clish$$' "$TARGET_DIR/etc/shells" \
|| echo "/bin/clish" >> "$TARGET_DIR/etc/shells"
# Create YANG documentation
if [ "$BR2_PACKAGE_HOST_PYTHON_YANGDOC" = "y" ]; then
mkyangdoc "$BINARIES_DIR/yangdoc.html"
fi
+3 -19
View File
@@ -12,9 +12,6 @@ load_cfg BR2_ARCH
load_cfg BR2_DEFCONFIG
load_cfg BR2_EXTERNAL_INFIX_PATH
load_cfg BR2_TARGET_ROOTFS
# The default IMAGE_ID is infix-$BR2_ARCH but can be overridden
# for imaage names, and compat strings, like infix-r2s
if [ -n "$IMAGE_ID" ]; then
NAME="$IMAGE_ID"
else
@@ -39,7 +36,7 @@ if [ "$SIGN_ENABLED" = "y" ]; then
$common/sign.sh $BR2_ARCH $SIGN_KEY
ixmsg "Creating RAUC Update Bundle"
$common/mkrauc.sh "$NAME$(ver)" $NAME $SIGN_KEY
$common/mkrauc.sh "$NAME$(ver)" $BR2_ARCH $SIGN_KEY
fi
load_cfg DISK_IMAGE
@@ -59,21 +56,8 @@ if [ "$DISK_IMAGE" = "y" ]; then
tar -xa --strip-components=1 -C "$BINARIES_DIR" -f "$archive"
fi
testmode_flag=""
if [ "$DISK_IMAGE_TEST_MODE" = "y" ]; then
testmode_flag="-t"
fi
$common/mkrauc-status.sh "$BINARIES_DIR/${NAME}.pkg" >"$BINARIES_DIR/rauc.status"
$common/mkdisk.sh -a $BR2_ARCH -n $diskimg $testmode_flag -s $DISK_IMAGE_SIZE $bootcfg
fi
load_cfg SDCARD_AUX
if [ "$SDCARD_AUX" = "y" ]; then
ixmsg "Creating initial rauc.status"
$common/mkrauc-status.sh "$BINARIES_DIR/${NAME}.pkg" >"$BINARIES_DIR/rauc.status"
ixmsg "Creating aux.ext4 for sdcard.img"
$common/mkaux.sh
$common/mkdisk.sh -a $BR2_ARCH -n $diskimg -s $DISK_IMAGE_SIZE $bootcfg
fi
load_cfg GNS3_APPLIANCE
@@ -97,7 +81,7 @@ if [ "$BR2_TARGET_ROOTFS_SQUASHFS" = "y" ]; then
fi
# Menuconfig support for modifying Qemu args in release tarballs
cp "$BR2_EXTERNAL_INFIX_PATH/board/common/rootfs/usr/bin/onieprom" "$BINARIES_DIR/"
cp "$BR2_EXTERNAL_INFIX_PATH/board/common/rootfs/bin/onieprom" "$BINARIES_DIR/"
cp "$BR2_EXTERNAL_INFIX_PATH/board/common/qemu/qemu.sh" "$BINARIES_DIR/"
sed -e "s/@ARCH@/QEMU_$BR2_ARCH/" \
-e "s/@DISK_IMG@/$diskimg/" \
+2 -8
View File
@@ -4,10 +4,6 @@ choice
prompt "Target Architecture"
default @ARCH@
config QEMU_riscv64
bool "risv64"
select QEMU_ARCH_IS_64
config QEMU_x86_64
bool "x86_64"
select QEMU_ARCH_IS_64
@@ -112,12 +108,10 @@ config QEMU_RW
default "cfg.ext4"
config QEMU_RW_VAR_OPT
bool "Separate writable /var"
bool "Separate writable /var (256MB)"
if QEMU_RW_VAR_OPT
config QEMU_RW_VAR_SIZE
string "Size of /var"
default "256M"
config QEMU_RW_VAR
string "Writable /var layer"
default "var.ext4"
+2 -18
View File
@@ -146,22 +146,13 @@ usb_args()
USBSTICK="usb.vfat"
if ! [ -f $USBSTICK ]; then
dd if=/dev/zero of=${USBSTICK} bs=8M count=1 >/dev/null 2>&1
if command -v mkfs.vfat >/dev/null; then
mkfs.vfat -n "log" $USBSTICK >/dev/null 2>&1
else
if command -v mkfs.exfat >/dev/null; then
mkfs.exfat -L "log" $USBSTICK >/dev/null 2>&1
fi
fi
mkfs.vfat $USBSTICK >/dev/null 2>&1
fi
echo -n "-drive if=none,id=usbstick,format=raw,file=$USBSTICK "
echo -n "-usb "
echo -n "-device usb-ehci,id=ehci "
echo -n "-device usb-storage,bus=ehci.0,drive=usbstick "
}
rw_args()
{
[ "$CONFIG_QEMU_RW" ] || return
@@ -181,7 +172,7 @@ rw_args()
if [ "$CONFIG_QEMU_RW_VAR_OPT" ]; then
if ! [ -f "$CONFIG_QEMU_RW_VAR" ]; then
dd if=/dev/zero of="$CONFIG_QEMU_RW_VAR" bs=$CONFIG_QEMU_RW_VAR_SIZE count=1 >/dev/null 2>&1
dd if=/dev/zero of="$CONFIG_QEMU_RW_VAR" bs=256M count=1 >/dev/null 2>&1
mkfs.ext4 -L var "$CONFIG_QEMU_RW_VAR" >/dev/null 2>&1
fi
@@ -264,12 +255,6 @@ wdt_args()
echo -n "-device i6300esb -rtc clock=host"
}
gdb_args()
{
echo -n "-chardev socket,id=gdbqemu,path=gdbqemu.sock,server=on,wait=off "
echo -n "-gdb chardev:gdbqemu"
}
run_qemu()
{
if [ "$CONFIG_QEMU_ROOTFS_VSCSI" = "y" ]; then
@@ -287,7 +272,6 @@ run_qemu()
$(net_args) \
$(wdt_args) \
$(vpd_args) \
$(gdb_args) \
$CONFIG_QEMU_EXTRA
EOF
@@ -19,5 +19,5 @@ if [ -z "$OUTPUT" ]; then
fi
umask 0177
echo "$password" | mkpasswd -s > "$OUTPUT"
echo "$password" | mkpasswd > "$OUTPUT"
exit 0
+1
View File
@@ -0,0 +1 @@
/sbin/ip
-28
View File
@@ -1,4 +1,3 @@
# Hey Emacs, this is -*-sh-*-
# System-wide .bashrc file for interactive bash(1) shells.
# If not running interactively, don't do anything
@@ -14,30 +13,3 @@ export PROMPT_COMMAND=prompt_command
# check the window size after each command and, if necessary,
# update the values of LINES and COLUMNS.
shopt -s checkwinsize
log()
{
local fn="/var/log/syslog"
[ -n "$1" ] && fn="/var/log/$1"
less +G "$fn"
}
follow()
{
local fn="/var/log/syslog"
[ -n "$1" ] && fn="/var/log/$1"
tail -F "$fn"
}
_logfile_completions()
{
local cur=${COMP_WORDS[COMP_CWORD]}
local files=$(compgen -f -- "/var/log/$cur")
COMPREPLY=()
for file in $files; do
[ -f "$file" ] && COMPREPLY+=("$(basename "$file")")
done
}
complete -F _logfile_completions log
complete -F _logfile_completions follow
@@ -1,3 +1,3 @@
task name:ixinit log:tag:ixinit [S] <pid/syslogd> \
/usr/libexec/finit/runparts -bp /usr/libexec/infix/init.d \
-- Probing system
run [S] log:console /libexec/infix/probe -- Probing system information
run [S] <pid/syslogd> /libexec/infix/sysctl-sync-ip-conf --
run [S] <pid/syslogd> /libexec/infix/nameif -- Probing network interfaces
@@ -1,4 +1,4 @@
service :%i pid:!/run/k8s-logger-%i.pid <usr/container:%i> \
[2345] k8s-logger -cni %i -f local1 /run/containers/%i.fifo -- Logger for container %i
sysv :%i pid:!/run/container:%i.pid <pid/k8s-logger:%i> log kill:10 \
sysv :%i pid:!/run/container:%i.pid <pid/k8s-logger:%i> kill:10 \
[2345] container -n %i -- container %i
@@ -1 +1 @@
task [S] <service/confd/ready> /usr/libexec/infix/mkcert -- Verifying self-signed https certificate
task [S] <service/confd/ready> /libexec/infix/mkcert -- Verifying self-signed https certificate
@@ -1,3 +0,0 @@
service name:rousette notify:none log <pid/confd> \
[12345] rousette --syslog -t 60 \
-- RESTCONF server
+2 -3
View File
@@ -7,17 +7,16 @@ tmpfs /dev/shm tmpfs mode=0777 0 0
proc /proc proc defaults 0 0
tmpfs /tmp tmpfs mode=1777,nosuid,nodev 0 0
tmpfs /run tmpfs mode=0755,nosuid,nodev 0 0
tmpfs /media tmpfs mode=1755,nosuid,nodev 0 0
sysfs /sys sysfs defaults 0 0
debugfs /sys/kernel/debug debugfs nofail 0 0
cfgfs /config configfs nofail,noauto 0 0
# The chosen backing storage for the overlays placed on /cfg, /etc,
# /home, /root, and /var, are determined dynamically by /usr/libexec/infix/mnt
# /home, /root, and /var, are determined dynamically by /libexec/infix/mnt
# depending on the available devices.
mnttmp /mnt/tmp tmpfs defaults 0 0
LABEL=aux /mnt/aux auto noatime,nodiratime,noauto 0 0
LABEL=var /mnt/var auto noatime,nodiratime,noauto 0 0
LABEL=cfg /mnt/cfg auto noatime,nodiratime,noauto 0 0
hostfs /mnt/host 9p cache=none,msize=16384,noauto 0 0
/usr/libexec/infix/mnt# /cfg helper none 0 0
/libexec/infix/mnt# /cfg helper none 0 0
+1 -1
View File
@@ -1,4 +1,4 @@
.-------.
| . . | Infix -- a Network Operating System
|-. v .-| https://kernelkit.org
|-. v .-| https://kernelkit.github.io
'-'---'-'
@@ -24,6 +24,4 @@ server {
root html;
index index.html index.htm;
}
include /etc/nginx/app/*.conf;
}
@@ -5,6 +5,14 @@ server {
include ssl.conf;
location / {
include /etc/nginx/netbrowse.conf;
proxy_pass http://127.0.0.1:8000;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_redirect off;
}
}
@@ -1,6 +0,0 @@
location /netbrowse/ {
return 301 /netbrowse;
}
location /netbrowse {
include /etc/nginx/netbrowse.conf;
}
@@ -1,9 +0,0 @@
proxy_pass http://127.0.0.1:8000;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_redirect off;
@@ -1,8 +0,0 @@
# /telemetry/optics is for streaming (not used atm)
location ~ ^/(restconf|yang|.well-known)/ {
grpc_pass grpc://[::1]:10080;
grpc_set_header Host $host;
grpc_set_header X-Real-IP $remote_addr;
grpc_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
grpc_set_header X-Forwarded-Proto $scheme;
}
@@ -1,19 +0,0 @@
#%PAM-1.0
auth requisite pam_nologin.so
auth [success=1 default=ignore] pam_unix.so nullok
auth requisite pam_deny.so
auth required pam_permit.so
account requisite pam_nologin.so
account [success=1 default=ignore] pam_unix.so
account requisite pam_deny.so
account required pam_permit.so
password [success=1 default=ignore] pam_unix.so
password requisite pam_deny.so
password required pam_permit.so
session required pam_loginuid.so
session include common-session
session optional pam_keyinit.so force revoke
session optional pam_motd.so
-19
View File
@@ -1,19 +0,0 @@
#%PAM-1.0
auth requisite pam_nologin.so
auth [success=1 default=ignore] pam_unix.so nullok
auth requisite pam_deny.so
auth required pam_permit.so
account requisite pam_nologin.so
account [success=1 default=ignore] pam_unix.so
account requisite pam_deny.so
account required pam_permit.so
password [success=1 default=ignore] pam_unix.so
password requisite pam_deny.so
password required pam_permit.so
session required pam_loginuid.so
session include common-session
session optional pam_keyinit.so force revoke
session optional pam_motd.so
@@ -6,7 +6,6 @@ alias ls='ls --color=auto'
export EDITOR=/usr/bin/edit
export VISUAL=/usr/bin/edit
export LESS="-P %f (press h for help or q to quit)"
export LESSOPEN="|/usr/bin/lesspipe.sh %s"
alias vim='vi'
alias view='vi -R'
alias emacs='mg'
@@ -1,3 +1,2 @@
net.ipv4.ip_forward=1
net.ipv4.ip_forward_update_priority=0
net.ipv6.conf.all.forwarding=1
-84
View File
@@ -1,84 +0,0 @@
# /etc/syslog.conf - Configuration file for syslogd(8)
#
# For information about the format of this file, see syslog.conf(5)
#
#
# First some standard log files. Log by facility.
#
auth,authpriv.* /var/log/auth.log
#*.*;auth,authpriv.none -/var/log/syslog
#cron.* /var/log/cron.log
#daemon.* -/var/log/daemon.log
kern.* -/var/log/kern.log
#lpr.* -/var/log/lpr.log
mail.* -/var/log/mail.log
#user.* -/var/log/user.log
#
# Logging for the mail system. Split it up so that
# it is easy to write scripts to parse these files.
#
#mail.info -/var/log/mail.info
#mail.warn -/var/log/mail.warn
mail.err /var/log/mail.err
#mail.*;mail.!=info -/var/log/mail
#mail,news.=info -/var/log/info
# The tcp wrapper loggs with mail.info, we display all
# the connections on tty12
#
#mail.=info /dev/tty12
#
# Some "catch-all" log files.
#
#*.=debug;\
# auth,authpriv.none;\
# news.none;mail.none -/var/log/debug
*.=info;*.=notice;*.=warn;\
auth,authpriv.none;\
cron,daemon.none;\
mail,news.none -/var/log/messages
#
# Store all critical events, except kernel logs, in critical RFC5424 format.
# Overide global log rotation settings, rotate every 10MiB, keep 5 old logs,
#
#*.=crit;kern.none /var/log/critical ;rotate=10M:5,RFC5424
# Example of sending events to remote syslog server.
# All events from notice and above, except auth, authpriv
# and any kernel message are sent to server finlandia in
# RFC5424 formatted output.
#
#*.notice;auth,authpriv.none;
# kern.none\ @finlandia ;RFC5424
# Emergencies are sent to anyone logged in
#
*.=emerg *
# Priority alert and above are sent to the operator
#
#*.alert root,joey
#
# Secure mode, same as -s, none(0), on(1), full(2). When enabled
# only logging to remote syslog server possible, with full secure
# mode, not even that is possible. We default to prevent syslogd
# from opening UDP/514 and receving messages from other systems.
#
secure_mode 1
#
# Global log rotation, same as -r SIZE:COUNT, command line wins.
#
#rotate_size 1M
#rotate_count 5
#
# Include all config files in /etc/syslog.d/
#
include /etc/syslog.d/*.conf
@@ -1,2 +0,0 @@
rotate_size 1M
rotate_count 10
@@ -1,2 +0,0 @@
# Log critical and above to console, system likely unusable.
*.=crit;*.=alert;*.=emerg /dev/console
+1 -1
View File
@@ -2,7 +2,7 @@ Reserved facilities for logging in various subsystems:
- local0: rauc
- local1: containers
- local2: routing (frr)
- local2:
- local3:
- local5:
- local6: reserved
@@ -1 +0,0 @@
local2.* -/var/log/routing
@@ -1,3 +0,0 @@
# Skip debug level messages in our /var/log/syslog, we have a dedicate
# debug log instead, as well as facility specific logs, e.g., routing
*.info;auth,authpriv.none -/var/log/syslog
@@ -1,5 +0,0 @@
KERNEL=="sd[a-z]", SUBSYSTEMS=="usb", ACTION=="add|change", RUN+="/usr/libexec/infix/media add %k"
KERNEL=="sd[a-z]", SUBSYSTEMS=="usb", ACTION=="remove", RUN+="/usr/libexec/infix/media del %k"
KERNEL=="sd[a-z][0-9]", SUBSYSTEMS=="usb", ACTION=="add|change", RUN+="/usr/libexec/infix/media add %k"
KERNEL=="sd[a-z][0-9]", SUBSYSTEMS=="usb", ACTION=="remove", RUN+="/usr/libexec/infix/media del %k"
@@ -33,26 +33,18 @@ check_factory()
fi
# Add to your br2-external to extend factory-reset check
if [ ! -x /usr/libexec/infix/check-factory ]; then
if [ ! -x /libexec/infix/check-factory ]; then
return 1;
fi
/usr/libexec/infix/check-factory
/libexec/infix/check-factory
}
factory_reset()
{
find /sys/class/leds/ -type l -exec sh -c 'echo 100 > $0/brightness' {} \;
# XXX: flash LEDs to confirm factory-reset in progress
logger $opt -p user.crit -t "$nm" "Resetting to factory defaults."
# Shred all files to prevent restoring contents
find /mnt/cfg -type f -exec shred -zu {} \;
find /mnt/var -type f -exec shred -zu {} \;
# Remove any lingering directories and symlinks as well
rm -rf /mnt/cfg/* /mnt/var/*
logger $opt -p user.crit -t "$nm" "Factory reset complete."
sync
}
@@ -63,7 +63,7 @@ ok
step "Formatting $blk"
[ -b $blk ] || { echo "$blk is not a block device" >&2; err; }
/usr/libexec/infix/prod/fdisk $blk || err
/libexec/infix/prod/fdisk $blk || err
sleep 1
ok
+17
View File
@@ -0,0 +1,17 @@
#!/bin/sh
# When changing default IPv4/6 settings, this does not apply to
# existing interfaces. This syncs the default settings to all known
# interfaces at boot, such that physical interfaces will start from
# the same point as virtual ones.
tmp=$(mktemp)
sysctl net.ipv4.conf.default >$tmp
sysctl net.ipv6.conf.default >>$tmp
for iface in $(ip -j link show | jq -r .[].ifname); do
sed -e "s/.default./.${iface}./g" $tmp | sysctl -p -
done
rm $tmp
-27
View File
@@ -1,27 +0,0 @@
#!/bin/sh
dir()
{
path=$1
if [ -z "$COLUMS" ]; then
TTY=$(resize)
eval "$TTY"
fi
printf "\033[7m%-*s\033[0m\n" "$COLUMNS" "$path directory"
if [ -d "$path" ]; then
ls -p "$path/"
else
echo "Directory $path does not exist."
fi
echo
}
if [ -d "$1" ]; then
dir "$1"
else
dir "$HOME"
dir "/cfg"
dir "/log"
fi
-5
View File
@@ -1,5 +0,0 @@
#!/bin/sh
# Silly wrapper around sudo to prevent it from printing an error for
# unprivileged users: sudo: a password is required
id -nG $LOGNAME | grep -qw wheel && sudo -n $@
-10
View File
@@ -1,10 +0,0 @@
#!/bin/sh
case "$1" in
*.gz)
zcat "$1"
;;
*)
cat "$1"
;;
esac
@@ -1 +0,0 @@
d /var/run/frr 0755 frr frr -
@@ -1,22 +0,0 @@
#!/bin/sh
# Find and install any product specific files in /etc before bootstrap
ident=$(basename "$0")
PREFIXD=/usr/share/product
PRODUCT=$(jq -r '."product-name" | ascii_downcase' /run/system.json)
note()
{
logger -I $$ -k -p user.notice -t "$ident" "$1"
}
DIR="$PREFIXD/$PRODUCT"
if [ -z "$PRODUCT" ] || [ ! -d "$DIR" ]; then
note "No vendor/product specific directory found, using built-in defaults."
exit 0
fi
note "Using vendor/product specific defaults."
for dir in "$DIR"/*; do
[ -d "$dir" ] && cp -a "$dir" /
done
@@ -1,28 +0,0 @@
#!/bin/sh
# When changing default IPv4/6 settings, this does not apply to
# existing interfaces. This syncs the default settings to all known
# interfaces at boot, such that physical interfaces will start from
# the same point as virtual ones.
tmp=$(mktemp)
fil=$(mktemp)
# Ignore unreadable entries, like net.ipv6.conf.default.stable_secret
sysctl net.ipv4.conf.default >"$tmp" 2>/dev/null
sysctl net.ipv6.conf.default >>"$tmp" 2>/dev/null
# Filter out read-only entries like net.ipv4.conf.default.mc_forwarding
# to prevent misleading error messages in syslog
while IFS= read -r line; do
entry=$(echo "$line" | awk '{print $1}')
path="/proc/sys/$(echo "$entry" | tr . /)"
if [ -w "$path" ]; then
echo "$line" >> "$fil"
fi
done < "$tmp"
for iface in $(ip -j link show | jq -r .[].ifname); do
sed -e "s/.default./.${iface}./g" "$fil" | sysctl -q -p -
done
rm "$tmp" "$fil"
@@ -1,52 +0,0 @@
#!/bin/sh
# Opportunistically look for interfaces with multiple transmit queues
# and hardware support for the mqprio queuing discipline. For every
# matching interface, set up mappings from kernel-internal packet
# priorities, via traffic classes, to transmit queues such that as
# many high priorities as possible are scheduled on separate queues.
set -e
map()
{
case "$1" in
2)
echo "map 0 0 0 0 0 0 1 1";;
3)
echo "map 0 0 0 0 1 1 2 2";;
4)
echo "map 0 0 1 1 2 2 3 3";;
5)
echo "map 0 0 1 1 2 2 3 4";;
6)
echo "map 0 0 1 1 2 3 4 5";;
7)
echo "map 0 0 1 2 3 4 5 6";;
8)
echo "map 0 1 2 3 4 5 6 7";;
esac
}
queues()
{
out="queues "
for tc in $(seq 0 $(($1 - 1))); do
out="$out 1@$tc"
done
echo "$out"
}
set $(ip -j -d link show | jq -r '.[] | .ifname, .num_tx_queues')
while [ "$1" ]; do
iface="$1"
txqs="$2"
shift 2
[ $txqs -lt 2 ] && continue
[ $txqs -gt 8 ] && txqs=8
tc qdisc add dev $iface root mqprio hw 1 \
num_tc $txqs $(map $txqs) $(queues $txqs) || true
done
@@ -1,102 +0,0 @@
#!/bin/sh
# Run .cfg migration jq scripts to backup and transform older .cfg files
ident=$(basename "$0")
MIGRATIONS_DIR="/usr/share/confd/migrate"
CONFIG_FILE="/cfg/startup-config.cfg"
BACKUP_DIR="/cfg/backup"
note()
{
logger -I $$ -k -p user.notice -t "$ident" "$1"
}
err()
{
logger -I $$ -k -p user.err -t "$ident" "$1"
}
file_version()
{
jq -r '
if .["infix-meta:meta"] | has("version") then
.["infix-meta:meta"]["version"]
else
"0.0"
end
' "$1"
}
atoi()
{
echo "$1" | awk -F. '{print $1 * 1000 + $2}'
}
if [ ! -f "$CONFIG_FILE" ]; then
# Nothing to migrate
note "No $(basename "$CONFIG_FILE" .cfg) yet, likely factory reset."
exit 0
fi
cfg_version=$(file_version "$CONFIG_FILE")
current_version=$(atoi "$cfg_version")
# Find the latest version by examining the highest numbered directory
sys_version=$(find "$MIGRATIONS_DIR" -mindepth 1 -maxdepth 1 -type d | sort -V | tail -n1 | xargs -n1 basename)
latest_version=$(atoi "$sys_version")
# Check for downgrade
if [ "$current_version" -gt "$latest_version" ]; then
err "Configuration file $CONFIG_FILE version ($cfg_version) is newer than the latest supported version ($sys_version). Exiting."
exit 1
fi
# If the current version is already the latest, exit the script
if [ "$current_version" -eq "$latest_version" ]; then
note "Configuration is already at the latest version ($sys_version). No migration needed."
exit 0
fi
note "Configuration file $CONFIG_FILE is of version $cfg_version, migrating ..."
# Create the backup directory if it doesn't exist
mkdir -p "$BACKUP_DIR"
# Create a backup of the current configuration file
nm=$(basename "$CONFIG_FILE" .cfg)
BACKUP_FILE="$BACKUP_DIR/${nm}-${cfg_version}.cfg"
if cp "$CONFIG_FILE" "$BACKUP_FILE"; then
note "Backup created: $BACKUP_FILE"
else
err "Failed creating backup: $BACKUP_FILE"
exit 1
fi
# Apply the scripts for each version directory in sequence
for version_dir in $(find "$MIGRATIONS_DIR" -mindepth 1 -maxdepth 1 -type d | sort -V); do
dir=$(basename "$version_dir")
version=$(atoi "$dir")
# Step by step upgrade file to latest version
if [ "$current_version" -lt "$version" ]; then
note "Applying migrations for version $dir ..."
# Apply all scripts in the version directory in order
for script in $(find "$version_dir" -type f -name '*.sh' | sort -V); do
note "Calling $script for $CONFIG_FILE ..."
sh "$script" "$CONFIG_FILE"
done
# File now at $version ...
current_version="$version"
fi
done
# Update the JSON file to the latest version
if jq --arg version "$sys_version" '.["infix-meta:meta"]["infix-meta:version"] = $version' "$CONFIG_FILE" \
> "${CONFIG_FILE}.tmp" && mv "${CONFIG_FILE}.tmp" "$CONFIG_FILE"; then
note "Configuration updated to version $sys_version."
else
err "Failed updating configuration to version $sys_version!"
exit 1
fi
@@ -1,2 +0,0 @@
#!/bin/sh
exec initctl -bq cond set ixinit-done
-107
View File
@@ -1,107 +0,0 @@
#!/bin/sh
# Mounts and unmounts external media
ACTION=$1
DEVBASE=$2
DEVICE="/dev/${DEVBASE}"
log()
{
logger -sk -I $$ -p user.notice -t "media" "$1"
}
usage()
{
echo "Usage: $0 {add|start|del|remove|stop} DEV (e.g. sdb1)"
exit 1
}
if [ $# -ne 2 ]; then
usage
fi
# See if this drive is already mounted, and if so where
MOUNT_POINT=$(mount | grep "${DEVICE}" | awk '{ print $3 }')
do_mount()
{
if [ -n "${MOUNT_POINT}" ]; then
log "skipping ${DEVICE}, already mounted at ${MOUNT_POINT}"
exit 1
fi
# Get info for this drive: $ID_FS_LABEL, $ID_FS_UUID, and $ID_FS_TYPE
eval $(udevadm info --query=property --name="${DEVICE}")
# Figure out a mount point to use
LABEL=${ID_FS_LABEL}
if [ -z "${LABEL}" ]; then
LABEL=${DEVBASE}
elif grep -q " /media/${LABEL} " /etc/mtab; then
# Already in use, make a unique one
LABEL="${LABEL}-${DEVBASE}"
fi
MOUNT_POINT="/media/${LABEL}"
umask 007
mkdir -p "${MOUNT_POINT}"
OPTS="rw,relatime,noexec,nodev,uid=0,gid=10"
case ${ID_FS_TYPE} in
vfat)
OPTS="${OPTS},umask=007,shortname=mixed,utf8=1,flush"
;;
exfat)
OPTS="${OPTS},sync"
;;
*)
log "unsupported filesystem ${ID_FS_TYPE}, skipping."
rmdir "${MOUNT_POINT}"
exit 1
;;
esac
log "mount -o ${OPTS} ${DEVICE} ${MOUNT_POINT}"
if ! mount -t "${ID_FS_TYPE}" -o ${OPTS} "${DEVICE}" "${MOUNT_POINT}"; then
log "failed mounting ${DEVICE}"
rmdir "${MOUNT_POINT}"
exit 1
fi
log "mounted ${DEVICE} at ${MOUNT_POINT} for root:wheel with 770 permissions"
}
do_unmount()
{
if [ -z "${MOUNT_POINT}" ]; then
log "cannot unmount ${DEVICE}, is not mounted."
else
umount -l "${DEVICE}"
log "unmounted ${DEVICE}"
fi
# Delete all empty dirs in /media that aren't being used as mount
# points. This is kind of overkill, but if the drive was unmounted
# prior to removal we no longer know its mount point, and we don't
# want to leave it orphaned...
for f in /media/* ; do
if [ -n "$(find "$f" -maxdepth 0 -type d -empty)" ]; then
if ! grep -q " $f " /etc/mtab; then
log "removing mount point $f"
rmdir "$f"
fi
fi
done
}
case "${ACTION}" in
add|start)
do_mount
;;
del|remove|stop)
do_unmount
;;
*)
usage
;;
esac
@@ -1,14 +0,0 @@
#!/bin/sh
# Generate NETCONF SSH host key pair
set -e
BIT=2048
KEY=$1
PUB=$2
mkdir -p "$(dirname "$KEY")" "$(dirname "$PUB")"
openssl genpkey -quiet -algorithm RSA -pkeyopt rsa_keygen_bits:$BIT -outform PEM > "$KEY"
openssl rsa -RSAPublicKey_out < "$KEY" > "$PUB"
exit 0
+1 -6
View File
@@ -58,7 +58,6 @@ unpack_archive()
[ -n "$quiet" ] || log "Extracting OCI archive $file ..."
tar xf "$file" || (log "Error: failed unpacking $file in $(pwd)"; exit 1)
remove=true
fi
dir=$(dirname "$index")
@@ -73,10 +72,6 @@ unpack_archive()
name=$dir
fi
if [ "$remove" = "true" ]; then
rm -rf "$file"
fi
echo "$name"
}
@@ -580,7 +575,7 @@ case $cmd in
stop "$name"
timeout=20
while running "$name"; do
_=$((timeout -= 1))
_=$((timeoute -= 1))
if [ $timeout -le 0 ]; then
log "Timeout waiting for container $1 to stop before restarting it."
exit 1
+1
View File
@@ -0,0 +1 @@
/sbin/ip
@@ -119,7 +119,7 @@ case "$ACTION" in
if [ -n "$hostname" ]; then
log "setting new hostname: $hostname"
hostname "$hostname"
sed -i -E "s/^(127\.0\.1\.1\s+).*/\1$hostname/" /etc/hosts
augtool -s "set /files/etc/hosts/*[ipaddr='127.0.1.1']/canonical $hostname"
fi
# drop info from this interface
+6 -9
View File
@@ -7,19 +7,16 @@
&env {
vendor = "infix";
preboot = "run ixpreboot";
ixbootdelay = "0.5";
bootdelay = "-2";
bootmenu_delay = "10";
bootcmd = "run ixbtn";
boot_targets = "virtio mmc";
bootcmd = "run ixboot";
ixpreboot = /incbin/("scripts/ixpreboot.sh");
ixbtn-devmode = /incbin/("scripts/ixbtn-devmode.sh");
ixbtn-factory = /incbin/("scripts/ixbtn-factory.sh");
ixfactory = /incbin/("scripts/ixfactory.sh");
ixbtn = /incbin/("scripts/ixbtn.sh");
ixdevmode = /incbin/("scripts/ixdevmode.sh");
ixfactory = /incbin/("scripts/ixfactory.sh");
ixbtn = /incbin/("scripts/ixbtn.sh");
ixboot = /incbin/("scripts/ixboot.sh");
ixbootmedia = /incbin/("scripts/ixbootmedia.sh");
ixbootslot = /incbin/("scripts/ixbootslot.sh");
ixprepblk = /incbin/("scripts/ixprepblk.sh");
ixprepdhcp = /incbin/("scripts/ixprepdhcp.sh");
-10
View File
@@ -1,6 +1,5 @@
# CONFIG_OF_OMIT_DTB is not set
CONFIG_DEVICE_TREE_INCLUDES="infix-env.dtsi infix-key.dtsi"
CONFIG_SYS_PROMPT="(ixboot) "
CONFIG_ENV_IMPORT_FDT=y
@@ -17,7 +16,6 @@ CONFIG_DISTRO_DEFAULTS=y
CONFIG_CMD_SETEXPR=y
CONFIG_CMD_SETEXPR_FMT=y
CONFIG_MMC=y
CONFIG_MMC_SDHCI=y
CONFIG_MMC_PCI=y
@@ -26,11 +24,3 @@ CONFIG_CMD_MMC=y
CONFIG_FS_SQUASHFS=y
CONFIG_CMD_SQUASHFS=y
CONFIG_PROT_TCP=y
CONFIG_PROT_TCP_SACK=y
CONFIG_CMD_WGET=y
CONFIG_USE_PREBOOT=y
CONFIG_CMD_BOOTMENU=y
CONFIG_CMD_PAUSE=y
# CONFIG_CMD_BOOTEFI_BOOTMGR is not set
@@ -0,0 +1,32 @@
From 4aef55d1b8cc24187f12f83a2f4d9bfc41ba12ee Mon Sep 17 00:00:00 2001
From: Tobias Waldekranz <tobias@waldekranz.com>
Date: Mon, 30 Jan 2023 15:54:56 +0100
Subject: [PATCH v2 1/9] image: Fix script execution from FIT images with
external data
Update the script loading code to recognize when script data is stored
externally from the FIT metadata (i.e., built with `mkimage -E`).
Signed-off-by: Tobias Waldekranz <tobias@waldekranz.com>
Reviewed-by: Simon Glass <sjg@chromium.org>
---
boot/image-board.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/boot/image-board.c b/boot/image-board.c
index 25b60ec30b..af693c9c08 100644
--- a/boot/image-board.c
+++ b/boot/image-board.c
@@ -1111,7 +1111,8 @@ fallback:
}
/* get script subimage data address and length */
- if (fit_image_get_data(fit_hdr, noffset, &fit_data, &fit_len)) {
+ if (fit_image_get_data_and_size(fit_hdr, noffset,
+ &fit_data, &fit_len)) {
puts("Could not find script subimage data\n");
return 1;
}
--
2.34.1
@@ -0,0 +1,73 @@
From 74f121de98a1614a4068960445b8355cb3e5fa04 Mon Sep 17 00:00:00 2001
From: Tobias Waldekranz <tobias@waldekranz.com>
Date: Tue, 24 Jan 2023 14:00:04 +0100
Subject: [PATCH v2 2/9] cmd: blk: Allow generic read/write operations to work
in sandbox
Ensure that the memory destination/source addresses of block
read/write operations are mapped in before access. Currently, this is
only needed on sandbox builds.
Signed-off-by: Tobias Waldekranz <tobias@waldekranz.com>
Reviewed-by: Simon Glass <sjg@chromium.org>
---
cmd/blk_common.c | 15 +++++++++++----
1 file changed, 11 insertions(+), 4 deletions(-)
diff --git a/cmd/blk_common.c b/cmd/blk_common.c
index 75a072caf5..9f9d4327a9 100644
--- a/cmd/blk_common.c
+++ b/cmd/blk_common.c
@@ -11,6 +11,7 @@
#include <common.h>
#include <blk.h>
#include <command.h>
+#include <mapmem.h>
int blk_common_cmd(int argc, char *const argv[], enum uclass_id uclass_id,
int *cur_devnump)
@@ -63,31 +64,37 @@ int blk_common_cmd(int argc, char *const argv[], enum uclass_id uclass_id,
default: /* at least 4 args */
if (strcmp(argv[1], "read") == 0) {
- ulong addr = hextoul(argv[2], NULL);
+ phys_addr_t paddr = hextoul(argv[2], NULL);
lbaint_t blk = hextoul(argv[3], NULL);
ulong cnt = hextoul(argv[4], NULL);
+ void *vaddr;
ulong n;
printf("\n%s read: device %d block # "LBAFU", count %lu ... ",
if_name, *cur_devnump, blk, cnt);
+ vaddr = map_sysmem(paddr, 512 * cnt);
n = blk_read_devnum(uclass_id, *cur_devnump, blk, cnt,
- (ulong *)addr);
+ vaddr);
+ unmap_sysmem(vaddr);
printf("%ld blocks read: %s\n", n,
n == cnt ? "OK" : "ERROR");
return n == cnt ? 0 : 1;
} else if (strcmp(argv[1], "write") == 0) {
- ulong addr = hextoul(argv[2], NULL);
+ phys_addr_t paddr = hextoul(argv[2], NULL);
lbaint_t blk = hextoul(argv[3], NULL);
ulong cnt = hextoul(argv[4], NULL);
+ void *vaddr;
ulong n;
printf("\n%s write: device %d block # "LBAFU", count %lu ... ",
if_name, *cur_devnump, blk, cnt);
+ vaddr = map_sysmem(paddr, 512 * cnt);
n = blk_write_devnum(uclass_id, *cur_devnump, blk, cnt,
- (ulong *)addr);
+ vaddr);
+ unmap_sysmem(vaddr);
printf("%ld blocks written: %s\n", n,
n == cnt ? "OK" : "ERROR");
--
2.34.1
@@ -0,0 +1,501 @@
From 104a2ab39ac72c402d7463bec05aae4a6d09cfbf Mon Sep 17 00:00:00 2001
From: Tobias Waldekranz <tobias@waldekranz.com>
Date: Thu, 16 Feb 2023 15:06:12 +0100
Subject: [PATCH v2 3/9] blk: blkmap: Add basic infrastructure
blkmaps are loosely modeled on Linux's device mapper subsystem. The
basic idea is that you can create virtual block devices whose blocks
can be backed by a plethora of sources that are user configurable.
This change just adds the basic infrastructure for creating and
removing blkmap devices. Subsequent changes will extend this to add
support for actual mappings.
Signed-off-by: Tobias Waldekranz <tobias@waldekranz.com>
---
MAINTAINERS | 6 +
drivers/block/Kconfig | 18 ++
drivers/block/Makefile | 1 +
drivers/block/blk-uclass.c | 1 +
drivers/block/blkmap.c | 343 +++++++++++++++++++++++++++++++++++++
include/blkmap.h | 35 ++++
include/dm/uclass-id.h | 1 +
7 files changed, 405 insertions(+)
create mode 100644 drivers/block/blkmap.c
create mode 100644 include/blkmap.h
diff --git a/MAINTAINERS b/MAINTAINERS
index 6f53f9c2f6..3e47c9b34c 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -793,6 +793,12 @@ M: Alper Nebi Yasak <alpernebiyasak@gmail.com>
S: Maintained
F: tools/binman/
+BLKMAP
+M: Tobias Waldekranz <tobias@waldekranz.com>
+S: Maintained
+F: drivers/block/blkmap.c
+F: include/blkmap.h
+
BOOTDEVICE
M: Simon Glass <sjg@chromium.org>
S: Maintained
diff --git a/drivers/block/Kconfig b/drivers/block/Kconfig
index e95da48bdc..5a1aeb3d2b 100644
--- a/drivers/block/Kconfig
+++ b/drivers/block/Kconfig
@@ -67,6 +67,24 @@ config BLOCK_CACHE
it will prevent repeated reads from directory structures and other
filesystem data structures.
+config BLKMAP
+ bool "Composable virtual block devices (blkmap)"
+ depends on BLK
+ help
+ Create virtual block devices that are backed by various sources,
+ e.g. RAM, or parts of an existing block device. Though much more
+ rudimentary, it borrows a lot of ideas from Linux's device mapper
+ subsystem.
+
+ Example use-cases:
+ - Treat a region of RAM as a block device, i.e. a RAM disk. This let's
+ you extract files from filesystem images stored in RAM (perhaps as a
+ result of a TFTP transfer).
+ - Create a virtual partition on an existing device. This let's you
+ access filesystems that aren't stored at an exact partition
+ boundary. A common example is a filesystem image embedded in an FIT
+ image.
+
config SPL_BLOCK_CACHE
bool "Use block device cache in SPL"
depends on SPL_BLK
diff --git a/drivers/block/Makefile b/drivers/block/Makefile
index f12447d78d..a161d145fd 100644
--- a/drivers/block/Makefile
+++ b/drivers/block/Makefile
@@ -14,6 +14,7 @@ obj-$(CONFIG_IDE) += ide.o
endif
obj-$(CONFIG_SANDBOX) += sandbox.o host-uclass.o host_dev.o
obj-$(CONFIG_$(SPL_TPL_)BLOCK_CACHE) += blkcache.o
+obj-$(CONFIG_BLKMAP) += blkmap.o
obj-$(CONFIG_EFI_MEDIA) += efi-media-uclass.o
obj-$(CONFIG_EFI_MEDIA_SANDBOX) += sb_efi_media.o
diff --git a/drivers/block/blk-uclass.c b/drivers/block/blk-uclass.c
index c69fc4d518..cb73faaeda 100644
--- a/drivers/block/blk-uclass.c
+++ b/drivers/block/blk-uclass.c
@@ -32,6 +32,7 @@ static struct {
{ UCLASS_EFI_LOADER, "efiloader" },
{ UCLASS_VIRTIO, "virtio" },
{ UCLASS_PVBLOCK, "pvblock" },
+ { UCLASS_BLKMAP, "blkmap" },
};
static enum uclass_id uclass_name_to_iftype(const char *uclass_idname)
diff --git a/drivers/block/blkmap.c b/drivers/block/blkmap.c
new file mode 100644
index 0000000000..acfc002ceb
--- /dev/null
+++ b/drivers/block/blkmap.c
@@ -0,0 +1,343 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (c) 2023 Addiva Elektronik
+ * Author: Tobias Waldekranz <tobias@waldekranz.com>
+ */
+
+#include <common.h>
+#include <blk.h>
+#include <blkmap.h>
+#include <dm.h>
+#include <malloc.h>
+#include <mapmem.h>
+#include <part.h>
+#include <dm/device-internal.h>
+#include <dm/lists.h>
+#include <dm/root.h>
+
+struct blkmap;
+
+/**
+ * struct blkmap_slice - Region mapped to a blkmap
+ *
+ * Common data for a region mapped to a blkmap, specialized by each
+ * map type.
+ *
+ * @node: List node used to associate this slice with a blkmap
+ * @blknr: Start block number of the mapping
+ * @blkcnt: Number of blocks covered by this mapping
+ */
+struct blkmap_slice {
+ struct list_head node;
+
+ lbaint_t blknr;
+ lbaint_t blkcnt;
+
+ /**
+ * @read: - Read from slice
+ *
+ * @read.bm: Blkmap to which this slice belongs
+ * @read.bms: This slice
+ * @read.blknr: Start block number to read from
+ * @read.blkcnt: Number of blocks to read
+ * @read.buffer: Buffer to store read data to
+ */
+ ulong (*read)(struct blkmap *bm, struct blkmap_slice *bms,
+ lbaint_t blknr, lbaint_t blkcnt, void *buffer);
+
+ /**
+ * @write: - Write to slice
+ *
+ * @write.bm: Blkmap to which this slice belongs
+ * @write.bms: This slice
+ * @write.blknr: Start block number to write to
+ * @write.blkcnt: Number of blocks to write
+ * @write.buffer: Data to be written
+ */
+ ulong (*write)(struct blkmap *bm, struct blkmap_slice *bms,
+ lbaint_t blknr, lbaint_t blkcnt, const void *buffer);
+
+ /**
+ * @destroy: - Tear down slice
+ *
+ * @read.bm: Blkmap to which this slice belongs
+ * @read.bms: This slice
+ */
+ void (*destroy)(struct blkmap *bm, struct blkmap_slice *bms);
+};
+
+/**
+ * struct blkmap - Block map
+ *
+ * Data associated with a blkmap.
+ *
+ * @label: Human readable name of this blkmap
+ * @blk: Underlying block device
+ * @slices: List of slices associated with this blkmap
+ */
+struct blkmap {
+ char *label;
+ struct udevice *blk;
+ struct list_head slices;
+};
+
+static bool blkmap_slice_contains(struct blkmap_slice *bms, lbaint_t blknr)
+{
+ return (blknr >= bms->blknr) && (blknr < (bms->blknr + bms->blkcnt));
+}
+
+static bool blkmap_slice_available(struct blkmap *bm, struct blkmap_slice *new)
+{
+ struct blkmap_slice *bms;
+ lbaint_t first, last;
+
+ first = new->blknr;
+ last = new->blknr + new->blkcnt - 1;
+
+ list_for_each_entry(bms, &bm->slices, node) {
+ if (blkmap_slice_contains(bms, first) ||
+ blkmap_slice_contains(bms, last) ||
+ blkmap_slice_contains(new, bms->blknr) ||
+ blkmap_slice_contains(new, bms->blknr + bms->blkcnt - 1))
+ return false;
+ }
+
+ return true;
+}
+
+static int blkmap_slice_add(struct blkmap *bm, struct blkmap_slice *new)
+{
+ struct blk_desc *bd = dev_get_uclass_plat(bm->blk);
+ struct list_head *insert = &bm->slices;
+ struct blkmap_slice *bms;
+
+ if (!blkmap_slice_available(bm, new))
+ return -EBUSY;
+
+ list_for_each_entry(bms, &bm->slices, node) {
+ if (bms->blknr < new->blknr)
+ continue;
+
+ insert = &bms->node;
+ break;
+ }
+
+ list_add_tail(&new->node, insert);
+
+ /* Disk might have grown, update the size */
+ bms = list_last_entry(&bm->slices, struct blkmap_slice, node);
+ bd->lba = bms->blknr + bms->blkcnt;
+ return 0;
+}
+
+static ulong blkmap_blk_read_slice(struct blkmap *bm, struct blkmap_slice *bms,
+ lbaint_t blknr, lbaint_t blkcnt,
+ void *buffer)
+{
+ lbaint_t nr, cnt;
+
+ nr = blknr - bms->blknr;
+ cnt = (blkcnt < bms->blkcnt) ? blkcnt : bms->blkcnt;
+ return bms->read(bm, bms, nr, cnt, buffer);
+}
+
+static ulong blkmap_blk_read(struct udevice *dev, lbaint_t blknr,
+ lbaint_t blkcnt, void *buffer)
+{
+ struct blk_desc *bd = dev_get_uclass_plat(dev);
+ struct blkmap *bm = dev_get_plat(dev->parent);
+ struct blkmap_slice *bms;
+ lbaint_t cnt, total = 0;
+
+ list_for_each_entry(bms, &bm->slices, node) {
+ if (!blkmap_slice_contains(bms, blknr))
+ continue;
+
+ cnt = blkmap_blk_read_slice(bm, bms, blknr, blkcnt, buffer);
+ blknr += cnt;
+ blkcnt -= cnt;
+ buffer += cnt << bd->log2blksz;
+ total += cnt;
+ }
+
+ return total;
+}
+
+static ulong blkmap_blk_write_slice(struct blkmap *bm, struct blkmap_slice *bms,
+ lbaint_t blknr, lbaint_t blkcnt,
+ const void *buffer)
+{
+ lbaint_t nr, cnt;
+
+ nr = blknr - bms->blknr;
+ cnt = (blkcnt < bms->blkcnt) ? blkcnt : bms->blkcnt;
+ return bms->write(bm, bms, nr, cnt, buffer);
+}
+
+static ulong blkmap_blk_write(struct udevice *dev, lbaint_t blknr,
+ lbaint_t blkcnt, const void *buffer)
+{
+ struct blk_desc *bd = dev_get_uclass_plat(dev);
+ struct blkmap *bm = dev_get_plat(dev->parent);
+ struct blkmap_slice *bms;
+ lbaint_t cnt, total = 0;
+
+ list_for_each_entry(bms, &bm->slices, node) {
+ if (!blkmap_slice_contains(bms, blknr))
+ continue;
+
+ cnt = blkmap_blk_write_slice(bm, bms, blknr, blkcnt, buffer);
+ blknr += cnt;
+ blkcnt -= cnt;
+ buffer += cnt << bd->log2blksz;
+ total += cnt;
+ }
+
+ return total;
+}
+
+static const struct blk_ops blkmap_blk_ops = {
+ .read = blkmap_blk_read,
+ .write = blkmap_blk_write,
+};
+
+U_BOOT_DRIVER(blkmap_blk) = {
+ .name = "blkmap_blk",
+ .id = UCLASS_BLK,
+ .ops = &blkmap_blk_ops,
+};
+
+int blkmap_dev_bind(struct udevice *dev)
+{
+ struct blkmap *bm = dev_get_plat(dev);
+ struct blk_desc *bd;
+ int err;
+
+ err = blk_create_devicef(dev, "blkmap_blk", "blk", UCLASS_BLKMAP,
+ dev_seq(dev), 512, 0, &bm->blk);
+ if (err)
+ return log_msg_ret("blk", err);
+
+ INIT_LIST_HEAD(&bm->slices);
+
+ bd = dev_get_uclass_plat(bm->blk);
+ snprintf(bd->vendor, BLK_VEN_SIZE, "U-Boot");
+ snprintf(bd->product, BLK_PRD_SIZE, "blkmap");
+ snprintf(bd->revision, BLK_REV_SIZE, "1.0");
+
+ /* EFI core isn't keen on zero-sized disks, so we lie. This is
+ * updated with the correct size once the user adds a
+ * mapping.
+ */
+ bd->lba = 1;
+
+ return 0;
+}
+
+int blkmap_dev_unbind(struct udevice *dev)
+{
+ struct blkmap *bm = dev_get_plat(dev);
+ struct blkmap_slice *bms, *tmp;
+ int err;
+
+ list_for_each_entry_safe(bms, tmp, &bm->slices, node) {
+ list_del(&bms->node);
+ free(bms);
+ }
+
+ err = device_remove(bm->blk, DM_REMOVE_NORMAL);
+ if (err)
+ return err;
+
+ return device_unbind(bm->blk);
+}
+
+U_BOOT_DRIVER(blkmap_root) = {
+ .name = "blkmap_dev",
+ .id = UCLASS_BLKMAP,
+ .bind = blkmap_dev_bind,
+ .unbind = blkmap_dev_unbind,
+ .plat_auto = sizeof(struct blkmap),
+};
+
+struct udevice *blkmap_from_label(const char *label)
+{
+ struct udevice *dev;
+ struct uclass *uc;
+ struct blkmap *bm;
+
+ uclass_id_foreach_dev(UCLASS_BLKMAP, dev, uc) {
+ bm = dev_get_plat(dev);
+ if (bm->label && !strcmp(label, bm->label))
+ return dev;
+ }
+
+ return NULL;
+}
+
+int blkmap_create(const char *label, struct udevice **devp)
+{
+ char *hname, *hlabel;
+ struct udevice *dev;
+ struct blkmap *bm;
+ size_t namelen;
+ int err;
+
+ dev = blkmap_from_label(label);
+ if (dev) {
+ err = -EBUSY;
+ goto err;
+ }
+
+ hlabel = strdup(label);
+ if (!hlabel) {
+ err = -ENOMEM;
+ goto err;
+ }
+
+ namelen = strlen("blkmap-") + strlen(label) + 1;
+ hname = malloc(namelen);
+ if (!hname) {
+ err = -ENOMEM;
+ goto err_free_hlabel;
+ }
+
+ strlcpy(hname, "blkmap-", namelen);
+ strlcat(hname, label, namelen);
+
+ err = device_bind_driver(dm_root(), "blkmap_dev", hname, &dev);
+ if (err)
+ goto err_free_hname;
+
+ device_set_name_alloced(dev);
+ bm = dev_get_plat(dev);
+ bm->label = hlabel;
+
+ if (devp)
+ *devp = dev;
+
+ return 0;
+
+err_free_hname:
+ free(hname);
+err_free_hlabel:
+ free(hlabel);
+err:
+ return err;
+}
+
+int blkmap_destroy(struct udevice *dev)
+{
+ int err;
+
+ err = device_remove(dev, DM_REMOVE_NORMAL);
+ if (err)
+ return err;
+
+ return device_unbind(dev);
+}
+
+UCLASS_DRIVER(blkmap) = {
+ .id = UCLASS_BLKMAP,
+ .name = "blkmap",
+};
diff --git a/include/blkmap.h b/include/blkmap.h
new file mode 100644
index 0000000000..3c7e36efab
--- /dev/null
+++ b/include/blkmap.h
@@ -0,0 +1,35 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * Copyright (c) 2023 Addiva Elektronik
+ * Author: Tobias Waldekranz <tobias@waldekranz.com>
+ */
+
+#ifndef _BLKMAP_H
+#define _BLKMAP_H
+
+/**
+ * blkmap_from_label() - Find blkmap from label
+ *
+ * @label: Label of the requested blkmap
+ * Returns: A pointer to the blkmap on success, NULL on failure
+ */
+struct udevice *blkmap_from_label(const char *label);
+
+/**
+ * blkmap_create() - Create new blkmap
+ *
+ * @label: Label of the new blkmap
+ * @devp: If not NULL, updated with the address of the resulting device
+ * Returns: 0 on success, negative error code on failure
+ */
+int blkmap_create(const char *label, struct udevice **devp);
+
+/**
+ * blkmap_destroy() - Destroy blkmap
+ *
+ * @dev: The blkmap to be destroyed
+ * Returns: 0 on success, negative error code on failure
+ */
+int blkmap_destroy(struct udevice *dev);
+
+#endif /* _BLKMAP_H */
diff --git a/include/dm/uclass-id.h b/include/dm/uclass-id.h
index 33e43c20db..576237b954 100644
--- a/include/dm/uclass-id.h
+++ b/include/dm/uclass-id.h
@@ -37,6 +37,7 @@ enum uclass_id {
UCLASS_AUDIO_CODEC, /* Audio codec with control and data path */
UCLASS_AXI, /* AXI bus */
UCLASS_BLK, /* Block device */
+ UCLASS_BLKMAP, /* Composable virtual block device */
UCLASS_BOOTCOUNT, /* Bootcount backing store */
UCLASS_BOOTDEV, /* Boot device for locating an OS to boot */
UCLASS_BOOTMETH, /* Bootmethod for booting an OS */
--
2.34.1
@@ -0,0 +1,174 @@
From 77fd2a74a5f7a14f42b5c7acd175a9c1519c4f16 Mon Sep 17 00:00:00 2001
From: Tobias Waldekranz <tobias@waldekranz.com>
Date: Thu, 16 Feb 2023 15:08:00 +0100
Subject: [PATCH v2 4/9] blk: blkmap: Add memory mapping support
Allow a slice of RAM to be mapped to a blkmap. This means that RAM can
now be accessed as if it was a block device, meaning that existing
filesystem drivers can now be used to access ramdisks.
Signed-off-by: Tobias Waldekranz <tobias@waldekranz.com>
---
drivers/block/blkmap.c | 105 +++++++++++++++++++++++++++++++++++++++++
include/blkmap.h | 29 ++++++++++++
2 files changed, 134 insertions(+)
diff --git a/drivers/block/blkmap.c b/drivers/block/blkmap.c
index acfc002ceb..6d6eed889e 100644
--- a/drivers/block/blkmap.c
+++ b/drivers/block/blkmap.c
@@ -130,6 +130,111 @@ static int blkmap_slice_add(struct blkmap *bm, struct blkmap_slice *new)
return 0;
}
+/**
+ * struct blkmap_mem - Memory mapping
+ *
+ * @slice: Common map data
+ * @addr: Target memory region of this mapping
+ * @remapped: True if @addr is backed by a physical to virtual memory
+ * mapping that must be torn down at the end of this mapping's
+ * lifetime.
+ */
+struct blkmap_mem {
+ struct blkmap_slice slice;
+ void *addr;
+ bool remapped;
+};
+
+static ulong blkmap_mem_read(struct blkmap *bm, struct blkmap_slice *bms,
+ lbaint_t blknr, lbaint_t blkcnt, void *buffer)
+{
+ struct blkmap_mem *bmm = container_of(bms, struct blkmap_mem, slice);
+ struct blk_desc *bd = dev_get_uclass_plat(bm->blk);
+ char *src;
+
+ src = bmm->addr + (blknr << bd->log2blksz);
+ memcpy(buffer, src, blkcnt << bd->log2blksz);
+ return blkcnt;
+}
+
+static ulong blkmap_mem_write(struct blkmap *bm, struct blkmap_slice *bms,
+ lbaint_t blknr, lbaint_t blkcnt,
+ const void *buffer)
+{
+ struct blkmap_mem *bmm = container_of(bms, struct blkmap_mem, slice);
+ struct blk_desc *bd = dev_get_uclass_plat(bm->blk);
+ char *dst;
+
+ dst = bmm->addr + (blknr << bd->log2blksz);
+ memcpy(dst, buffer, blkcnt << bd->log2blksz);
+ return blkcnt;
+}
+
+static void blkmap_mem_destroy(struct blkmap *bm, struct blkmap_slice *bms)
+{
+ struct blkmap_mem *bmm = container_of(bms, struct blkmap_mem, slice);
+
+ if (bmm->remapped)
+ unmap_sysmem(bmm->addr);
+}
+
+int __blkmap_map_mem(struct udevice *dev, lbaint_t blknr, lbaint_t blkcnt,
+ void *addr, bool remapped)
+{
+ struct blkmap *bm = dev_get_plat(dev);
+ struct blkmap_mem *bmm;
+ int err;
+
+ bmm = malloc(sizeof(*bmm));
+ if (!bmm)
+ return -ENOMEM;
+
+ *bmm = (struct blkmap_mem) {
+ .slice = {
+ .blknr = blknr,
+ .blkcnt = blkcnt,
+
+ .read = blkmap_mem_read,
+ .write = blkmap_mem_write,
+ .destroy = blkmap_mem_destroy,
+ },
+
+ .addr = addr,
+ .remapped = remapped,
+ };
+
+ err = blkmap_slice_add(bm, &bmm->slice);
+ if (err)
+ free(bmm);
+
+ return err;
+}
+
+int blkmap_map_mem(struct udevice *dev, lbaint_t blknr, lbaint_t blkcnt,
+ void *addr)
+{
+ return __blkmap_map_mem(dev, blknr, blkcnt, addr, false);
+}
+
+int blkmap_map_pmem(struct udevice *dev, lbaint_t blknr, lbaint_t blkcnt,
+ phys_addr_t paddr)
+{
+ struct blkmap *bm = dev_get_plat(dev);
+ struct blk_desc *bd = dev_get_uclass_plat(bm->blk);
+ void *addr;
+ int err;
+
+ addr = map_sysmem(paddr, blkcnt << bd->log2blksz);
+ if (!addr)
+ return -ENOMEM;
+
+ err = __blkmap_map_mem(dev, blknr, blkcnt, addr, true);
+ if (err)
+ unmap_sysmem(addr);
+
+ return err;
+}
+
static ulong blkmap_blk_read_slice(struct blkmap *bm, struct blkmap_slice *bms,
lbaint_t blknr, lbaint_t blkcnt,
void *buffer)
diff --git a/include/blkmap.h b/include/blkmap.h
index 3c7e36efab..74baeb19f8 100644
--- a/include/blkmap.h
+++ b/include/blkmap.h
@@ -7,6 +7,35 @@
#ifndef _BLKMAP_H
#define _BLKMAP_H
+/**
+ * blkmap_map_mem() - Map region of memory
+ *
+ * @dev: Blkmap to create the mapping on
+ * @blknr: Start block number of the mapping
+ * @blkcnt: Number of blocks to map
+ * @addr: The target memory address of the mapping
+ * Returns: 0 on success, negative error code on failure
+ */
+int blkmap_map_mem(struct udevice *dev, lbaint_t blknr, lbaint_t blkcnt,
+ void *addr);
+
+/**
+ * blkmap_map_pmem() - Map region of physical memory
+ *
+ * Ensures that a valid physical to virtual memory mapping for the
+ * requested region is valid for the lifetime of the mapping, on
+ * architectures that require it (sandbox).
+ *
+ * @dev: Blkmap to create the mapping on
+ * @blknr: Start block number of the mapping
+ * @blkcnt: Number of blocks to map
+ * @paddr: The target physical memory address of the mapping
+ * Returns: 0 on success, negative error code on failure
+ */
+int blkmap_map_pmem(struct udevice *dev, lbaint_t blknr, lbaint_t blkcnt,
+ phys_addr_t paddr);
+
+
/**
* blkmap_from_label() - Find blkmap from label
*
--
2.34.1
@@ -0,0 +1,125 @@
From 29ed14e1a427c4e308413bccdc75084c1c1ec75a Mon Sep 17 00:00:00 2001
From: Tobias Waldekranz <tobias@waldekranz.com>
Date: Thu, 16 Feb 2023 15:09:21 +0100
Subject: [PATCH v2 5/9] blk: blkmap: Add linear device mapping support
Allow a slice of an existing block device to be mapped to a
blkmap. This means that filesystems that are not stored at exact
partition boundaries can be accessed by remapping a slice of the
existing device to a blkmap device.
Signed-off-by: Tobias Waldekranz <tobias@waldekranz.com>
---
drivers/block/blkmap.c | 71 ++++++++++++++++++++++++++++++++++++++++++
include/blkmap.h | 13 ++++++++
2 files changed, 84 insertions(+)
diff --git a/drivers/block/blkmap.c b/drivers/block/blkmap.c
index 6d6eed889e..2bb0acc20f 100644
--- a/drivers/block/blkmap.c
+++ b/drivers/block/blkmap.c
@@ -130,6 +130,77 @@ static int blkmap_slice_add(struct blkmap *bm, struct blkmap_slice *new)
return 0;
}
+/**
+ * struct blkmap_linear - Linear mapping to other block device
+ *
+ * @slice: Common map data
+ * @blk: Target block device of this mapping
+ * @blknr: Start block number of the target device
+ */
+struct blkmap_linear {
+ struct blkmap_slice slice;
+
+ struct udevice *blk;
+ lbaint_t blknr;
+};
+
+static ulong blkmap_linear_read(struct blkmap *bm, struct blkmap_slice *bms,
+ lbaint_t blknr, lbaint_t blkcnt, void *buffer)
+{
+ struct blkmap_linear *bml = container_of(bms, struct blkmap_linear, slice);
+
+ return blk_read(bml->blk, bml->blknr + blknr, blkcnt, buffer);
+}
+
+static ulong blkmap_linear_write(struct blkmap *bm, struct blkmap_slice *bms,
+ lbaint_t blknr, lbaint_t blkcnt,
+ const void *buffer)
+{
+ struct blkmap_linear *bml = container_of(bms, struct blkmap_linear, slice);
+
+ return blk_write(bml->blk, bml->blknr + blknr, blkcnt, buffer);
+}
+
+int blkmap_map_linear(struct udevice *dev, lbaint_t blknr, lbaint_t blkcnt,
+ struct udevice *lblk, lbaint_t lblknr)
+{
+ struct blkmap *bm = dev_get_plat(dev);
+ struct blkmap_linear *linear;
+ struct blk_desc *bd, *lbd;
+ int err;
+
+ bd = dev_get_uclass_plat(bm->blk);
+ lbd = dev_get_uclass_plat(lblk);
+ if (lbd->blksz != bd->blksz)
+ /* We could support block size translation, but we
+ * don't yet.
+ */
+ return -EINVAL;
+
+ linear = malloc(sizeof(*linear));
+ if (!linear)
+ return -ENOMEM;
+
+ *linear = (struct blkmap_linear) {
+ .slice = {
+ .blknr = blknr,
+ .blkcnt = blkcnt,
+
+ .read = blkmap_linear_read,
+ .write = blkmap_linear_write,
+ },
+
+ .blk = lblk,
+ .blknr = lblknr,
+ };
+
+ err = blkmap_slice_add(bm, &linear->slice);
+ if (err)
+ free(linear);
+
+ return err;
+}
+
/**
* struct blkmap_mem - Memory mapping
*
diff --git a/include/blkmap.h b/include/blkmap.h
index 74baeb19f8..af54583c7d 100644
--- a/include/blkmap.h
+++ b/include/blkmap.h
@@ -7,6 +7,19 @@
#ifndef _BLKMAP_H
#define _BLKMAP_H
+/**
+ * blkmap_map_linear() - Map region of other block device
+ *
+ * @dev: Blkmap to create the mapping on
+ * @blknr: Start block number of the mapping
+ * @blkcnt: Number of blocks to map
+ * @lblk: The target block device of the mapping
+ * @lblknr: The start block number of the target device
+ * Returns: 0 on success, negative error code on failure
+ */
+int blkmap_map_linear(struct udevice *dev, lbaint_t blknr, lbaint_t blkcnt,
+ struct udevice *lblk, lbaint_t lblknr);
+
/**
* blkmap_map_mem() - Map region of memory
*
--
2.34.1
@@ -0,0 +1,337 @@
From c20dd0f17a128e65c1f376bf0e1cad9cec1d0336 Mon Sep 17 00:00:00 2001
From: Tobias Waldekranz <tobias@waldekranz.com>
Date: Thu, 16 Feb 2023 15:10:49 +0100
Subject: [PATCH v2 6/9] cmd: blkmap: Add blkmap command
Add a frontend for the blkmap subsystem. In addition to the common
block device operations, this allows users to create and destroy
devices, and map in memory and slices of other block devices.
With that we support two primary use-cases:
- Being able to "distro boot" from a RAM disk. I.e., from an image
where the kernel is stored in /boot of some filesystem supported
by U-Boot.
- Accessing filesystems not located on exact partition boundaries,
e.g. when a filesystem image is wrapped in an FIT image and stored
in a disk partition.
Signed-off-by: Tobias Waldekranz <tobias@waldekranz.com>
---
MAINTAINERS | 1 +
cmd/Kconfig | 19 +++++
cmd/Makefile | 1 +
cmd/blkmap.c | 233 +++++++++++++++++++++++++++++++++++++++++++++++++++
disk/part.c | 1 +
5 files changed, 255 insertions(+)
create mode 100644 cmd/blkmap.c
diff --git a/MAINTAINERS b/MAINTAINERS
index 3e47c9b34c..316b85fed7 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -796,6 +796,7 @@ F: tools/binman/
BLKMAP
M: Tobias Waldekranz <tobias@waldekranz.com>
S: Maintained
+F: cmd/blkmap.c
F: drivers/block/blkmap.c
F: include/blkmap.h
diff --git a/cmd/Kconfig b/cmd/Kconfig
index 2caa4af71c..3dd3cdc656 100644
--- a/cmd/Kconfig
+++ b/cmd/Kconfig
@@ -1959,6 +1959,25 @@ config CMD_BLOCK_CACHE
during development, but also allows the cache to be disabled when
it might hurt performance (e.g. when using the ums command).
+config CMD_BLKMAP
+ bool "blkmap - Composable virtual block devices"
+ depends on BLKMAP
+ default y if BLKMAP
+ help
+ Create virtual block devices that are backed by various sources,
+ e.g. RAM, or parts of an existing block device. Though much more
+ rudimentary, it borrows a lot of ideas from Linux's device mapper
+ subsystem.
+
+ Example use-cases:
+ - Treat a region of RAM as a block device, i.e. a RAM disk. This let's
+ you extract files from filesystem images stored in RAM (perhaps as a
+ result of a TFTP transfer).
+ - Create a virtual partition on an existing device. This let's you
+ access filesystems that aren't stored at an exact partition
+ boundary. A common example is a filesystem image embedded in an FIT
+ image.
+
config CMD_BUTTON
bool "button"
depends on BUTTON
diff --git a/cmd/Makefile b/cmd/Makefile
index 36d2daf22a..837eee39b1 100644
--- a/cmd/Makefile
+++ b/cmd/Makefile
@@ -27,6 +27,7 @@ obj-$(CONFIG_CMD_BCB) += bcb.o
obj-$(CONFIG_CMD_BDI) += bdinfo.o
obj-$(CONFIG_CMD_BIND) += bind.o
obj-$(CONFIG_CMD_BINOP) += binop.o
+obj-$(CONFIG_CMD_BLKMAP) += blkmap.o
obj-$(CONFIG_CMD_BLOBLIST) += bloblist.o
obj-$(CONFIG_CMD_BLOCK_CACHE) += blkcache.o
obj-$(CONFIG_CMD_BMP) += bmp.o
diff --git a/cmd/blkmap.c b/cmd/blkmap.c
new file mode 100644
index 0000000000..b34c013072
--- /dev/null
+++ b/cmd/blkmap.c
@@ -0,0 +1,233 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (c) 2023 Addiva Elektronik
+ * Author: Tobias Waldekranz <tobias@waldekranz.com>
+ */
+
+#include <blk.h>
+#include <blkmap.h>
+#include <common.h>
+#include <command.h>
+#include <malloc.h>
+#include <dm/device.h>
+
+static int blkmap_curr_dev;
+
+struct map_ctx {
+ struct udevice *dev;
+ lbaint_t blknr, blkcnt;
+};
+
+typedef int (*map_parser_fn)(struct map_ctx *ctx, int argc, char *const argv[]);
+
+struct map_handler {
+ const char *name;
+ map_parser_fn fn;
+};
+
+int do_blkmap_map_linear(struct map_ctx *ctx, int argc, char *const argv[])
+{
+ struct blk_desc *lbd;
+ int err, ldevnum;
+ lbaint_t lblknr;
+
+ if (argc < 4)
+ return CMD_RET_USAGE;
+
+ ldevnum = dectoul(argv[2], NULL);
+ lblknr = dectoul(argv[3], NULL);
+
+ lbd = blk_get_devnum_by_uclass_idname(argv[1], ldevnum);
+ if (!lbd) {
+ printf("Found no device matching \"%s %d\"\n",
+ argv[1], ldevnum);
+ return CMD_RET_FAILURE;
+ }
+
+ err = blkmap_map_linear(ctx->dev, ctx->blknr, ctx->blkcnt,
+ lbd->bdev, lblknr);
+ if (err) {
+ printf("Unable to map \"%s %d\" at block 0x" LBAF ": %d\n",
+ argv[1], ldevnum, ctx->blknr, err);
+
+ return CMD_RET_FAILURE;
+ }
+
+ printf("Block 0x" LBAF "+0x" LBAF " mapped to block 0x" LBAF " of \"%s %d\"\n",
+ ctx->blknr, ctx->blkcnt, lblknr, argv[1], ldevnum);
+ return CMD_RET_SUCCESS;
+}
+
+int do_blkmap_map_mem(struct map_ctx *ctx, int argc, char *const argv[])
+{
+ phys_addr_t addr;
+ int err;
+
+ if (argc < 2)
+ return CMD_RET_USAGE;
+
+ addr = hextoul(argv[1], NULL);
+
+ err = blkmap_map_pmem(ctx->dev, ctx->blknr, ctx->blkcnt, addr);
+ if (err) {
+ printf("Unable to map %#llx at block 0x" LBAF ": %d\n",
+ (unsigned long long)addr, ctx->blknr, err);
+ return CMD_RET_FAILURE;
+ }
+
+ printf("Block 0x" LBAF "+0x" LBAF " mapped to %#llx\n",
+ ctx->blknr, ctx->blkcnt, (unsigned long long)addr);
+ return CMD_RET_SUCCESS;
+}
+
+struct map_handler map_handlers[] = {
+ { .name = "linear", .fn = do_blkmap_map_linear },
+ { .name = "mem", .fn = do_blkmap_map_mem },
+
+ { .name = NULL }
+};
+
+static int do_blkmap_map(struct cmd_tbl *cmdtp, int flag,
+ int argc, char *const argv[])
+{
+ struct map_handler *handler;
+ struct map_ctx ctx;
+
+ if (argc < 5)
+ return CMD_RET_USAGE;
+
+ ctx.dev = blkmap_from_label(argv[1]);
+ if (!ctx.dev) {
+ printf("\"%s\" is not the name of any known blkmap\n", argv[1]);
+ return CMD_RET_FAILURE;
+ }
+
+ ctx.blknr = hextoul(argv[2], NULL);
+ ctx.blkcnt = hextoul(argv[3], NULL);
+ argc -= 4;
+ argv += 4;
+
+ for (handler = map_handlers; handler->name; handler++) {
+ if (!strcmp(handler->name, argv[0]))
+ return handler->fn(&ctx, argc, argv);
+ }
+
+ printf("Unknown map type \"%s\"\n", argv[0]);
+ return CMD_RET_USAGE;
+}
+
+static int do_blkmap_create(struct cmd_tbl *cmdtp, int flag,
+ int argc, char *const argv[])
+{
+ const char *label;
+ int err;
+
+ if (argc != 2)
+ return CMD_RET_USAGE;
+
+ label = argv[1];
+
+ err = blkmap_create(label, NULL);
+ if (err) {
+ printf("Unable to create \"%s\": %d\n", label, err);
+ return CMD_RET_FAILURE;
+ }
+
+ printf("Created \"%s\"\n", label);
+ return CMD_RET_SUCCESS;
+}
+
+static int do_blkmap_destroy(struct cmd_tbl *cmdtp, int flag,
+ int argc, char *const argv[])
+{
+ struct udevice *dev;
+ const char *label;
+ int err;
+
+ if (argc != 2)
+ return CMD_RET_USAGE;
+
+ label = argv[1];
+
+ dev = blkmap_from_label(label);
+ if (!dev) {
+ printf("\"%s\" is not the name of any known blkmap\n", label);
+ return CMD_RET_FAILURE;
+ }
+
+ err = blkmap_destroy(dev);
+ if (err) {
+ printf("Unable to destroy \"%s\": %d\n", label, err);
+ return CMD_RET_FAILURE;
+ }
+
+ printf("Destroyed \"%s\"\n", label);
+ return CMD_RET_SUCCESS;
+}
+
+static int do_blkmap_get(struct cmd_tbl *cmdtp, int flag,
+ int argc, char *const argv[])
+{
+ struct udevice *dev;
+ const char *label;
+ int err;
+
+ if (argc < 3)
+ return CMD_RET_USAGE;
+
+ label = argv[1];
+
+ dev = blkmap_from_label(label);
+ if (!dev) {
+ printf("\"%s\" is not the name of any known blkmap\n", label);
+ return CMD_RET_FAILURE;
+ }
+
+ if (!strcmp(argv[2], "dev")) {
+ if (argc == 3) {
+ printf("%d\n", dev_seq(dev));
+ } else {
+ err = env_set_hex(argv[3], dev_seq(dev));
+ if (err)
+ return CMD_RET_FAILURE;
+ }
+ } else {
+ return CMD_RET_USAGE;
+ }
+
+ return CMD_RET_SUCCESS;
+}
+
+static int do_blkmap_common(struct cmd_tbl *cmdtp, int flag,
+ int argc, char *const argv[])
+{
+ /* The subcommand parsing pops the original argv[0] ("blkmap")
+ * which blk_common_cmd expects. Push it back again.
+ */
+ argc++;
+ argv--;
+
+ return blk_common_cmd(argc, argv, UCLASS_BLKMAP, &blkmap_curr_dev);
+}
+
+U_BOOT_CMD_WITH_SUBCMDS(
+ blkmap, "Composeable virtual block devices",
+ "info - list configured devices\n"
+ "blkmap part - list available partitions on current blkmap device\n"
+ "blkmap dev [<dev>] - show or set current blkmap device\n"
+ "blkmap read <addr> <blk#> <cnt>\n"
+ "blkmap write <addr> <blk#> <cnt>\n"
+ "blkmap get <label> dev [<var>] - store device number in variable\n"
+ "blkmap create <label> - create device\n"
+ "blkmap destroy <label> - destroy device\n"
+ "blkmap map <label> <blk#> <cnt> linear <interface> <dev> <blk#> - device mapping\n"
+ "blkmap map <label> <blk#> <cnt> mem <addr> - memory mapping\n",
+ U_BOOT_SUBCMD_MKENT(info, 2, 1, do_blkmap_common),
+ U_BOOT_SUBCMD_MKENT(part, 2, 1, do_blkmap_common),
+ U_BOOT_SUBCMD_MKENT(dev, 4, 1, do_blkmap_common),
+ U_BOOT_SUBCMD_MKENT(read, 5, 1, do_blkmap_common),
+ U_BOOT_SUBCMD_MKENT(write, 5, 1, do_blkmap_common),
+ U_BOOT_SUBCMD_MKENT(get, 5, 1, do_blkmap_get),
+ U_BOOT_SUBCMD_MKENT(create, 2, 1, do_blkmap_create),
+ U_BOOT_SUBCMD_MKENT(destroy, 2, 1, do_blkmap_destroy),
+ U_BOOT_SUBCMD_MKENT(map, 32, 1, do_blkmap_map));
diff --git a/disk/part.c b/disk/part.c
index d449635254..35300df590 100644
--- a/disk/part.c
+++ b/disk/part.c
@@ -140,6 +140,7 @@ void dev_print(struct blk_desc *dev_desc)
case UCLASS_NVME:
case UCLASS_PVBLOCK:
case UCLASS_HOST:
+ case UCLASS_BLKMAP:
printf ("Vendor: %s Rev: %s Prod: %s\n",
dev_desc->vendor,
dev_desc->revision,
--
2.34.1
@@ -0,0 +1,266 @@
From e9a394da1d75b2b3bea81e53ec2899d240a98861 Mon Sep 17 00:00:00 2001
From: Tobias Waldekranz <tobias@waldekranz.com>
Date: Thu, 16 Feb 2023 15:13:33 +0100
Subject: [PATCH v2 7/9] test: blkmap: Add test suite
Verify that:
- Block maps can be created and destroyed
- Mappings aren't allowed to overlap
- Multiple mappings can be attached and be read/written from/to
Signed-off-by: Tobias Waldekranz <tobias@waldekranz.com>
---
MAINTAINERS | 1 +
configs/sandbox_defconfig | 1 +
test/dm/Makefile | 1 +
test/dm/blkmap.c | 201 ++++++++++++++++++++++++++++++++++++++
4 files changed, 204 insertions(+)
create mode 100644 test/dm/blkmap.c
diff --git a/MAINTAINERS b/MAINTAINERS
index 316b85fed7..bbcb5117fe 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -799,6 +799,7 @@ S: Maintained
F: cmd/blkmap.c
F: drivers/block/blkmap.c
F: include/blkmap.h
+F: test/dm/blkmap.c
BOOTDEVICE
M: Simon Glass <sjg@chromium.org>
diff --git a/configs/sandbox_defconfig b/configs/sandbox_defconfig
index 34c342b6f5..06021e4902 100644
--- a/configs/sandbox_defconfig
+++ b/configs/sandbox_defconfig
@@ -145,6 +145,7 @@ CONFIG_ADC=y
CONFIG_ADC_SANDBOX=y
CONFIG_AXI=y
CONFIG_AXI_SANDBOX=y
+CONFIG_BLKMAP=y
CONFIG_SYS_IDE_MAXBUS=1
CONFIG_SYS_ATA_BASE_ADDR=0x100
CONFIG_SYS_ATA_STRIDE=4
diff --git a/test/dm/Makefile b/test/dm/Makefile
index 7a79b6e1a2..e15bdbf04b 100644
--- a/test/dm/Makefile
+++ b/test/dm/Makefile
@@ -29,6 +29,7 @@ obj-$(CONFIG_ADC) += adc.o
obj-$(CONFIG_SOUND) += audio.o
obj-$(CONFIG_AXI) += axi.o
obj-$(CONFIG_BLK) += blk.o
+obj-$(CONFIG_BLKMAP) += blkmap.o
obj-$(CONFIG_BUTTON) += button.o
obj-$(CONFIG_DM_BOOTCOUNT) += bootcount.o
obj-$(CONFIG_DM_REBOOT_MODE) += reboot-mode.o
diff --git a/test/dm/blkmap.c b/test/dm/blkmap.c
new file mode 100644
index 0000000000..7a163d6eae
--- /dev/null
+++ b/test/dm/blkmap.c
@@ -0,0 +1,201 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (c) 2023 Addiva Elektronik
+ * Author: Tobias Waldekranz <tobias@waldekranz.com>
+ */
+
+#include <common.h>
+#include <blk.h>
+#include <blkmap.h>
+#include <dm.h>
+#include <asm/test.h>
+#include <dm/test.h>
+#include <test/test.h>
+#include <test/ut.h>
+
+#define BLKSZ 0x200
+
+struct mapping {
+ int src;
+ int cnt;
+ int dst;
+};
+
+const struct mapping unordered_mapping[] = {
+ { 0, 1, 3 },
+ { 1, 3, 0 },
+ { 4, 2, 6 },
+ { 6, 2, 4 },
+
+ { 0, 0, 0 }
+};
+
+const struct mapping identity_mapping[] = {
+ { 0, 8, 0 },
+
+ { 0, 0, 0 }
+};
+
+static char identity[8 * BLKSZ];
+static char unordered[8 * BLKSZ];
+static char buffer[8 * BLKSZ];
+
+static void mkblob(void *base, const struct mapping *m)
+{
+ int nr;
+
+ for (; m->cnt; m++) {
+ for (nr = 0; nr < m->cnt; nr++) {
+ memset(base + (m->dst + nr) * BLKSZ,
+ m->src + nr, BLKSZ);
+ }
+ }
+}
+
+static int dm_test_blkmap_read(struct unit_test_state *uts)
+{
+ struct udevice *dev, *blk;
+ const struct mapping *m;
+
+ ut_assertok(blkmap_create("rdtest", &dev));
+ ut_assertok(blk_get_from_parent(dev, &blk));
+
+ /* Generate an ordered and an unordered pattern in memory */
+ mkblob(unordered, unordered_mapping);
+ mkblob(identity, identity_mapping);
+
+ /* Create a blkmap that cancels out the disorder */
+ for (m = unordered_mapping; m->cnt; m++) {
+ ut_assertok(blkmap_map_mem(dev, m->src, m->cnt,
+ unordered + m->dst * BLKSZ));
+ }
+
+ /* Read out the data via the blkmap device to another area,
+ * and verify that it matches the ordered pattern.
+ */
+ ut_asserteq(8, blk_read(blk, 0, 8, buffer));
+ ut_assertok(memcmp(buffer, identity, sizeof(buffer)));
+
+ ut_assertok(blkmap_destroy(dev));
+ return 0;
+}
+DM_TEST(dm_test_blkmap_read, 0);
+
+static int dm_test_blkmap_write(struct unit_test_state *uts)
+{
+ struct udevice *dev, *blk;
+ const struct mapping *m;
+
+ ut_assertok(blkmap_create("wrtest", &dev));
+ ut_assertok(blk_get_from_parent(dev, &blk));
+
+ /* Generate an ordered and an unordered pattern in memory */
+ mkblob(unordered, unordered_mapping);
+ mkblob(identity, identity_mapping);
+
+ /* Create a blkmap that mimics the disorder */
+ for (m = unordered_mapping; m->cnt; m++) {
+ ut_assertok(blkmap_map_mem(dev, m->src, m->cnt,
+ buffer + m->dst * BLKSZ));
+ }
+
+ /* Write the ordered data via the blkmap device to another
+ * area, and verify that the result matches the unordered
+ * pattern.
+ */
+ ut_asserteq(8, blk_write(blk, 0, 8, identity));
+ ut_assertok(memcmp(buffer, unordered, sizeof(buffer)));
+
+ ut_assertok(blkmap_destroy(dev));
+ return 0;
+}
+DM_TEST(dm_test_blkmap_write, 0);
+
+static int dm_test_blkmap_slicing(struct unit_test_state *uts)
+{
+ struct udevice *dev;
+
+ ut_assertok(blkmap_create("slicetest", &dev));
+
+ ut_assertok(blkmap_map_mem(dev, 8, 8, NULL));
+
+ /* Can't overlap on the low end */
+ ut_asserteq(-EBUSY, blkmap_map_mem(dev, 4, 5, NULL));
+ /* Can't be inside */
+ ut_asserteq(-EBUSY, blkmap_map_mem(dev, 10, 2, NULL));
+ /* Can't overlap on the high end */
+ ut_asserteq(-EBUSY, blkmap_map_mem(dev, 15, 4, NULL));
+
+ /* But we should be able to add slices right before and
+ * after
+ */
+ ut_assertok(blkmap_map_mem(dev, 4, 4, NULL));
+ ut_assertok(blkmap_map_mem(dev, 16, 4, NULL));
+
+ ut_assertok(blkmap_destroy(dev));
+ return 0;
+}
+DM_TEST(dm_test_blkmap_slicing, 0);
+
+static int dm_test_blkmap_creation(struct unit_test_state *uts)
+{
+ struct udevice *first, *second;
+
+ ut_assertok(blkmap_create("first", &first));
+
+ /* Can't have two "first"s */
+ ut_asserteq(-EBUSY, blkmap_create("first", &second));
+
+ /* But "second" should be fine */
+ ut_assertok(blkmap_create("second", &second));
+
+ /* Once "first" is destroyed, we should be able to create it
+ * again
+ */
+ ut_assertok(blkmap_destroy(first));
+ ut_assertok(blkmap_create("first", &first));
+
+ ut_assertok(blkmap_destroy(first));
+ ut_assertok(blkmap_destroy(second));
+ return 0;
+}
+DM_TEST(dm_test_blkmap_creation, 0);
+
+static int dm_test_cmd_blkmap(struct unit_test_state *uts)
+{
+ ulong loadaddr = env_get_hex("loadaddr", 0);
+ struct udevice *dev;
+
+ console_record_reset();
+
+ ut_assertok(run_command("blkmap info", 0));
+ ut_assert_console_end();
+
+ ut_assertok(run_command("blkmap create ramdisk", 0));
+ ut_assert_nextline("Created \"ramdisk\"");
+ ut_assert_console_end();
+
+ ut_assertnonnull((dev = blkmap_from_label("ramdisk")));
+
+ ut_assertok(run_commandf("blkmap map ramdisk 0 800 mem 0x%lx", loadaddr));
+ ut_assert_nextline("Block 0x0+0x800 mapped to 0x%lx", loadaddr);
+ ut_assert_console_end();
+
+ ut_assertok(run_command("blkmap info", 0));
+ ut_assert_nextline("Device 0: Vendor: U-Boot Rev: 1.0 Prod: blkmap");
+ ut_assert_nextline(" Type: Hard Disk");
+ ut_assert_nextline(" Capacity: 1.0 MB = 0.0 GB (2048 x 512)");
+ ut_assert_console_end();
+
+ ut_assertok(run_command("blkmap get ramdisk dev devnum", 0));
+ ut_asserteq(dev_seq(dev), env_get_hex("devnum", 0xdeadbeef));
+
+ ut_assertok(run_command("blkmap destroy ramdisk", 0));
+ ut_assert_nextline("Destroyed \"ramdisk\"");
+ ut_assert_console_end();
+
+ ut_assertok(run_command("blkmap info", 0));
+ ut_assert_console_end();
+ return 0;
+}
+DM_TEST(dm_test_cmd_blkmap, 0);
--
2.34.1
@@ -0,0 +1,159 @@
From 53e157184110e66144e805e733e5f0a7a4a031a8 Mon Sep 17 00:00:00 2001
From: Tobias Waldekranz <tobias@waldekranz.com>
Date: Thu, 16 Feb 2023 15:14:27 +0100
Subject: [PATCH v2 8/9] doc: blkmap: Add introduction and examples
Explain block maps by going through two common use-cases.
Signed-off-by: Tobias Waldekranz <tobias@waldekranz.com>
---
MAINTAINERS | 1 +
doc/usage/blkmap.rst | 111 +++++++++++++++++++++++++++++++++++++++++++
doc/usage/index.rst | 1 +
3 files changed, 113 insertions(+)
create mode 100644 doc/usage/blkmap.rst
diff --git a/MAINTAINERS b/MAINTAINERS
index bbcb5117fe..e02dacc20a 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -797,6 +797,7 @@ BLKMAP
M: Tobias Waldekranz <tobias@waldekranz.com>
S: Maintained
F: cmd/blkmap.c
+F: doc/usage/blkmap.rst
F: drivers/block/blkmap.c
F: include/blkmap.h
F: test/dm/blkmap.c
diff --git a/doc/usage/blkmap.rst b/doc/usage/blkmap.rst
new file mode 100644
index 0000000000..dbfa8e5aad
--- /dev/null
+++ b/doc/usage/blkmap.rst
@@ -0,0 +1,111 @@
+.. SPDX-License-Identifier: GPL-2.0+
+..
+.. Copyright (c) 2023 Addiva Elektronik
+.. Author: Tobias Waldekranz <tobias@waldekranz.com>
+
+Block Maps (blkmap)
+===================
+
+Block maps are a way of looking at various sources of data through the
+lens of a regular block device. It lets you treat devices that are not
+block devices, like RAM, as if they were. It also lets you export a
+slice of an existing block device, which does not have to correspond
+to a partition boundary, as a new block device.
+
+This is primarily useful because U-Boot's filesystem drivers only
+operate on block devices, so a block map lets you access filesystems
+wherever they might be located.
+
+The implementation is loosely modeled on Linux's "Device Mapper"
+subsystem, see `kernel documentation`_ for more information.
+
+.. _kernel documentation: https://docs.kernel.org/admin-guide/device-mapper/index.html
+
+
+Example: Netbooting an Ext4 Image
+---------------------------------
+
+Say that our system is using an Ext4 filesystem as its rootfs, where
+the kernel is stored in ``/boot``. This image is then typically stored
+in an eMMC partition. In this configuration, we can use something like
+``load mmc 0 ${kernel_addr_r} /boot/Image`` to load the kernel image
+into the expected location, and then boot the system. No problems.
+
+Now imagine that during development, or as a recovery mechanism, we
+want to boot the same type of image by downloading it over the
+network. Getting the image to the target is easy enough:
+
+::
+
+ dhcp ${ramdisk_addr_r} rootfs.ext4
+
+But now we are faced with a predicament: how to we extract the kernel
+image? Block maps to the rescue!
+
+We start by creating a new device:
+
+::
+
+ blkmap create netboot
+
+Before setting up the mapping, we figure out the size of the
+downloaded file, in blocks:
+
+::
+
+ setexpr fileblks ${filesize} + 0x1ff
+ setexpr fileblks ${filesize} / 0x200
+
+Then we can add a mapping to the start of our device, backed by the
+memory at `${loadaddr}`:
+
+::
+
+ blkmap map netboot 0 ${fileblks} mem ${fileaddr}
+
+Now we can access the filesystem via the virtual device:
+
+::
+
+ blkmap get netboot dev devnum
+ load blkmap ${devnum} ${kernel_addr_r} /boot/Image
+
+
+Example: Accessing a filesystem inside an FIT image
+---------------------------------------------------
+
+In this example, an FIT image is stored in an eMMC partition. We would
+like to read the file ``/etc/version``, stored inside a Squashfs image
+in the FIT. Since the Squashfs image is not stored on a partition
+boundary, there is no way of accessing it via ``load mmc ...``.
+
+What we can to instead is to first figure out the offset and size of
+the filesystem:
+
+::
+
+ mmc dev 0
+ mmc read ${loadaddr} 0 0x100
+
+ fdt addr ${loadaddr}
+ fdt get value squashaddr /images/ramdisk data-position
+ fdt get value squashsize /images/ramdisk data-size
+
+ setexpr squashblk ${squashaddr} / 0x200
+ setexpr squashsize ${squashsize} + 0x1ff
+ setexpr squashsize ${squashsize} / 0x200
+
+Then we can create a block map that maps to that slice of the full
+partition:
+
+::
+
+ blkmap create sq
+ blkmap map sq 0 ${squashsize} linear mmc 0 ${squashblk}
+
+Now we can access the filesystem:
+
+::
+
+ blkmap get sq dev devnum
+ load blkmap ${devnum} ${loadaddr} /etc/version
diff --git a/doc/usage/index.rst b/doc/usage/index.rst
index cde7dcb14a..2dfcd4b2b2 100644
--- a/doc/usage/index.rst
+++ b/doc/usage/index.rst
@@ -4,6 +4,7 @@ Use U-Boot
.. toctree::
:maxdepth: 1
+ blkmap
dfu
environment
fdt_overlays
--
2.34.1
@@ -0,0 +1,86 @@
From 0a0ceadab82a1e76d0d21b14b75510d3bd9228ff Mon Sep 17 00:00:00 2001
From: Tobias Waldekranz <tobias@waldekranz.com>
Date: Thu, 16 Feb 2023 15:15:59 +0100
Subject: [PATCH v2 9/9] efi_loader: device_path: support blkmap devices
Create a distinct EFI device path for each blkmap device.
Signed-off-by: Tobias Waldekranz <tobias@waldekranz.com>
---
include/efi_loader.h | 4 ++++
lib/efi_loader/efi_device_path.c | 30 ++++++++++++++++++++++++++++++
2 files changed, 34 insertions(+)
diff --git a/include/efi_loader.h b/include/efi_loader.h
index c664d6cdf2..eb3818b457 100644
--- a/include/efi_loader.h
+++ b/include/efi_loader.h
@@ -134,6 +134,10 @@ static inline efi_status_t efi_launch_capsules(void)
#define U_BOOT_GUID \
EFI_GUID(0xe61d73b9, 0xa384, 0x4acc, \
0xae, 0xab, 0x82, 0xe8, 0x28, 0xf3, 0x62, 0x8b)
+/* GUID used as root for blkmap devices */
+#define U_BOOT_BLKMAP_DEV_GUID \
+ EFI_GUID(0x4cad859d, 0xd644, 0x42ff, \
+ 0x87, 0x0b, 0xc0, 0x2e, 0xac, 0x05, 0x58, 0x63)
/* GUID used as host device on sandbox */
#define U_BOOT_HOST_DEV_GUID \
EFI_GUID(0xbbe4e671, 0x5773, 0x4ea1, \
diff --git a/lib/efi_loader/efi_device_path.c b/lib/efi_loader/efi_device_path.c
index 3b267b713e..4b4c96bc2e 100644
--- a/lib/efi_loader/efi_device_path.c
+++ b/lib/efi_loader/efi_device_path.c
@@ -21,6 +21,9 @@
#include <asm-generic/unaligned.h>
#include <linux/compat.h> /* U16_MAX */
+#ifdef CONFIG_BLKMAP
+const efi_guid_t efi_guid_blkmap_dev = U_BOOT_BLKMAP_DEV_GUID;
+#endif
#ifdef CONFIG_SANDBOX
const efi_guid_t efi_guid_host_dev = U_BOOT_HOST_DEV_GUID;
#endif
@@ -573,6 +576,16 @@ __maybe_unused static unsigned int dp_size(struct udevice *dev)
*/
return dp_size(dev->parent)
+ sizeof(struct efi_device_path_vendor) + 1;
+#endif
+#ifdef CONFIG_BLKMAP
+ case UCLASS_BLKMAP:
+ /*
+ * blkmap devices will be represented as a vendor
+ * device node with an extra byte for the device
+ * number.
+ */
+ return dp_size(dev->parent)
+ + sizeof(struct efi_device_path_vendor) + 1;
#endif
default:
return dp_size(dev->parent);
@@ -631,6 +644,23 @@ __maybe_unused static void *dp_fill(void *buf, struct udevice *dev)
#endif
case UCLASS_BLK:
switch (dev->parent->uclass->uc_drv->id) {
+#ifdef CONFIG_BLKMAP
+ case UCLASS_BLKMAP: {
+ struct efi_device_path_vendor *dp;
+ struct blk_desc *desc = dev_get_uclass_plat(dev);
+
+ dp_fill(buf, dev->parent);
+ dp = buf;
+ ++dp;
+ dp->dp.type = DEVICE_PATH_TYPE_HARDWARE_DEVICE;
+ dp->dp.sub_type = DEVICE_PATH_SUB_TYPE_VENDOR;
+ dp->dp.length = sizeof(*dp) + 1;
+ memcpy(&dp->guid, &efi_guid_blkmap_dev,
+ sizeof(efi_guid_t));
+ dp->vendor_data[0] = desc->devnum;
+ return &dp->vendor_data[1];
+ }
+#endif
#ifdef CONFIG_SANDBOX
case UCLASS_HOST: {
/* stop traversing parents at this point: */
--
2.34.1
+39 -11
View File
@@ -1,14 +1,42 @@
echo "Press Ctrl-C NOW to enter boot menu"
if sleep "${ixbootdelay}"; then
run ixbootorder
setenv valid_media no
echo "FATAL: Exhausted all available boot sources, rebooting"
sleep 1
reset
for tgt in "${boot_targets}"; do
if test "${tgt}" = "mmc0"; then
setenv devtype "mmc"
setenv devnum 0
mmc dev 0
elif test "${tgt}" = "mmc1"; then
setenv devtype "mmc"
setenv devnum 1
mmc dev 1
else
setenv devtype "${tgt}"
setenv devnum 0
fi
if part number ${devtype} ${devnum} aux auxpart; then
if load ${devtype} ${devnum}:${auxpart} ${loadaddr} /uboot.env; then
env import -b ${loadaddr} ${filesize} BOOT_ORDER DEBUG
fi
test -n "${BOOT_ORDER}" || setenv BOOT_ORDER "primary secondary net"
if test -n "${DEBUG}"; then
setenv bootargs_log "debug"
else
setenv bootargs_log "loglevel=4"
fi
setenv valid_media yes
run ixbootmedia
fi
done
if test "${valid_media}" = "no"; then
echo "NO BOOTABLE MEDIA FOUND, falling back to netboot"
setenv BOOT_ORDER "net"
setenv bootargs_log "debug"
run ixbootmedia
fi
bootmenu
if test "${dev_mode}" != "yes"; then
pause "Console shell access PROHIBITED. Press any key to reset..."
reset
fi
reset
@@ -0,0 +1,6 @@
echo "Booting from ${devtype}${devnum} (order: ${BOOT_ORDER})"
for s in "${BOOT_ORDER}"; do
setenv slot "${s}"
run ixbootslot
done
+25 -33
View File
@@ -10,42 +10,34 @@ elif test "${slot}" = "net"; then
fi
if test "${prepared}" = "ok"; then
echo "${slot}: Validating..."
echo "${slot}: Validating..."
if iminfo ${ramdisk_addr_r}; then
echo "${slot}: Booting..."
iminfo ${ramdisk_addr_r}
imok=$?
if test ${imok} -eq 0 || test "${dev_mode}" = "yes"; then
if test ${imok} -ne 0; then
echo "DEVELOPER MODE ACTIVE, BOOTING UNTRUSTED IMAGE"
fi
echo "${slot}: Booting..."
setenv bootargs_user "rauc.slot=${slot}"
if test "${factory_reset}" = "yes"; then
setenv bootargs_user "${bootargs_user} finit.cond=factory-reset"
fi
if test "${dev_mode}" = "yes"; then
setenv bootargs_user "${bootargs_user} finit.cond=dev-mode"
fi
blkmap create boot
blkmap get boot dev blkmapnum
blkmap map boot 0 ${sqblkcnt} mem ${sqaddr}
for conf in "${board}-syslinux.conf syslinux.conf"; do
if test -e blkmap ${blkmapnum} /boot/syslinux/${conf}; then
sysboot blkmap ${blkmapnum} any ${scriptaddr} /boot/syslinux/${conf}
setenv bootargs_user "rauc.slot=${slot}"
if test "${factory_reset}" = "yes"; then
setenv bootargs_user "${bootargs_user} finit.cond=factory-reset"
fi
if test "${dev_mode}" = "yes"; then
setenv bootargs_user "${bootargs_user} finit.cond=dev-mode"
fi
done
blkmap destroy boot
blkmap create boot
blkmap get boot dev blkmapnum
blkmap map boot 0 ${sqblkcnt} mem ${sqaddr}
echo "${slot}: ERROR: Boot failed"
else
echo "${slot}: ERROR: Validation failed"
fi
for conf in "${board}-syslinux.conf syslinux.conf"; do
if test -e blkmap ${blkmapnum} /boot/syslinux/${conf}; then
sysboot blkmap ${blkmapnum} any ${scriptaddr} /boot/syslinux/${conf}
fi
done
blkmap destroy boot
echo "${slot}: ERROR: Boot failed"
else
echo "${slot}: ERROR: Validation failed"
fi
else
echo "${slot}: ERROR: Unable to use slot"
echo "${slot}: ERROR: Unable to use slot"
fi
@@ -1,6 +0,0 @@
if button factory-reset; then
echo "Keep button pressed for 10 seconds to engage factory reset"
if sleep 10 && button factory-reset; then
run ixfactory
fi
fi

Some files were not shown because too many files have changed in this diff Show More