Initial commit: boot, wifi and ssh work
Signed-off-by: Maurizio Porrato <maurizio.porrato@gmail.com>
|
|
@ -0,0 +1,6 @@
|
|||
*.img
|
||||
!config/
|
||||
config/*
|
||||
!config/etc/
|
||||
config/etc/*
|
||||
!config/etc/motd
|
||||
|
|
@ -0,0 +1,72 @@
|
|||
.PHONY: sdcard images clean
|
||||
|
||||
A=./artifacts
|
||||
R=./resources
|
||||
S=./scripts
|
||||
|
||||
#############################################################################
|
||||
# Tunable parameters are in this section
|
||||
ALPINE_VERSION?=latest
|
||||
FACTORY_IMAGE?=factory.img
|
||||
SD_SIZE?=250M
|
||||
RESOURCES_SIZE?=8M
|
||||
ROOTFS_SIZE?=100M
|
||||
#############################################################################
|
||||
|
||||
SPL=$(A)/spl.img
|
||||
UBOOT=$(A)/u-boot.img
|
||||
ENV=$(A)/env.img
|
||||
RESOURCES=$(A)/boot-resources.img
|
||||
BOOT=$(A)/boot.img
|
||||
BOOTCFG=$(A)/bootimg.cfg
|
||||
KERNEL=$(A)/zImage
|
||||
INITRD=$(A)/initramfs
|
||||
FIRMWARE_TAR=$(A)/firmware.tar
|
||||
MODULES_TAR=$(A)/modules.tar
|
||||
ROOTFS_TAR=$(A)/rootfs.tar
|
||||
ROOTFS=$(A)/rootfs.img
|
||||
IMAGES=$(SPL) $(UBOOT) $(ENV) $(RESOURCES) $(BOOT) $(ROOTFS)
|
||||
SD=$(A)/alpine-h700.img
|
||||
|
||||
sdcard: $(SD)
|
||||
|
||||
images: $(IMAGES)
|
||||
|
||||
$(SD): $(IMAGES)
|
||||
$(RM) $@
|
||||
truncate -s $(SD_SIZE) $@
|
||||
$(S)/mkpart.sh $@ $^
|
||||
|
||||
$(SPL) $(UBOOT): $(FACTORY_IMAGE)
|
||||
$(S)/extract-blobs.py $^ -o $(A)
|
||||
|
||||
$(ENV): env.txt
|
||||
$(S)/mkenv.py $^ $@
|
||||
|
||||
$(BOOT): $(BOOTCFG) $(KERNEL) $(INITRD)
|
||||
abootimg --create $@ -f $(BOOTCFG) -k $(KERNEL) -r $(INITRD)
|
||||
|
||||
$(KERNEL) $(BOOTCFG): $(FACTORY_IMAGE)
|
||||
$(S)/extract-kernel.sh $^ $(A)
|
||||
|
||||
$(INITRD):
|
||||
$(S)/mkinitrd.sh $(ALPINE_VERSION)
|
||||
|
||||
$(RESOURCES): $(shell find $(R) -type f -print0 | xargs -0)
|
||||
$(RM) $@
|
||||
truncate -s $(RESOURCES_SIZE) $@
|
||||
$(S)/mkfsimage.sh $@ 0 vfat resources $(R)
|
||||
|
||||
$(ROOTFS_TAR):
|
||||
$(S)/build-rootfs.sh $(ALPINE_VERSION) $(A)
|
||||
|
||||
$(FIRMWARE_TAR) $(MODULES_TAR): $(FACTORY_IMAGE)
|
||||
$(S)/extract-modules.sh $< $(A)
|
||||
|
||||
$(ROOTFS): $(ROOTFS_TAR) $(FIRMWARE_TAR) $(MODULES_TAR)
|
||||
$(RM) $@
|
||||
truncate -s $(ROOTFS_SIZE) $@
|
||||
$(S)/mkfsimage.sh $@ 0 ext4 rootfs $(ROOTFS_TAR) $(FIRMWARE_TAR):/lib/firmware/ $(MODULES_TAR):/lib/modules/ config
|
||||
|
||||
clean:
|
||||
$(RM) $(A)/*
|
||||
|
|
@ -0,0 +1,89 @@
|
|||
# Alpine Linux for the Allwinner H700 SoC
|
||||
|
||||
This repository contains a collection of scripts to create a custom Alpine
|
||||
Linux based SD card image bootable on Allwinner H700 based devices.
|
||||
|
||||
In the standard configuration, a very basic system is installed, providing
|
||||
a login prompt on `/dev/ttyS0`, automatic connection to a WiFi netowk on boot
|
||||
and an SSH daemon running.
|
||||
|
||||
The scripts have been tested on a Fedora Linux 40 system and the generated
|
||||
image has been tested on an Anbernic RG35XX Plus portable console.
|
||||
|
||||
## Requirements
|
||||
|
||||
The scripts require the following software:
|
||||
|
||||
- `make` (specifically, GNU Make) to orchestrate the build and track dependencies
|
||||
- `python3` to run some of the provided scripts; only modules from the standard
|
||||
library are used
|
||||
- `sgdisk` to manipulate GPT partition tables
|
||||
- `guestfish` to manipulate filesystem images without root privileges
|
||||
- `podman` to provide an Alpine Linux environment
|
||||
- `qemu-user-static-aarch64` to enable `podman` to run aarch64 container
|
||||
images on a different architecture like x86_64
|
||||
|
||||
An image of a stock SD card is required in order to extract components that are
|
||||
specific to the H700 SoC that do not have open source alternatives yet; those
|
||||
components are:
|
||||
|
||||
- the SPL
|
||||
- the U-Boot bootloader
|
||||
- the kernel
|
||||
- the kernel's modules
|
||||
- various firmware blobs
|
||||
|
||||
## Preparation
|
||||
|
||||
### Configuration
|
||||
|
||||
Some extra configuration must be provided to connect to a WiFi network and
|
||||
allow SSH connections.
|
||||
|
||||
Anything under the `config` directory will be injected in the rootfs image.
|
||||
|
||||
A good staring point would be something like this (replace `$ssid` and
|
||||
`$password` with the correct network name and password for your WiFi network):
|
||||
|
||||
```shell
|
||||
mkdir -p config/etc/wpa_supplicant
|
||||
wpa_passphrase '$ssid' '$password' >config/etc/wpa_supplicant/wpa_supplicant.conf
|
||||
|
||||
mkdir -p config/root/.ssh
|
||||
cat ~/.ssh/id_*.pub >config/root/.ssh/authorized_keys
|
||||
```
|
||||
|
||||
### Stock SD card image
|
||||
|
||||
The scripts expect to find an image of the stock SD card in a file called
|
||||
`factory.img` in the root of the repository. It can be either an image file or
|
||||
a link to the actual image file or device, as long as the user running the
|
||||
scripts has permission to read it. The name of the image can be overridden by
|
||||
specifying a different path in the `FACTORY_IMAGE` variable when calling the
|
||||
makefile.
|
||||
|
||||
## Usage
|
||||
|
||||
To build an image, just run:
|
||||
|
||||
```shell
|
||||
make
|
||||
```
|
||||
|
||||
Or, to use a path to the stock image other than the default:
|
||||
|
||||
```shell
|
||||
make FACTORY_IMAGE=/tmp/RG35XX+-P-V1.1.3-EN16GB-240614.IMG
|
||||
```
|
||||
|
||||
The resulting image will be saved to `./artifacts/alpine-h700.img` and can be
|
||||
flashed to an SD card, for example, if the card is presented to the system as
|
||||
`/dev/sde`:
|
||||
|
||||
```shell
|
||||
dd if=artifacts/alpine-h700.img of=/dev/sde bs=1M oflag=dsync status=progress
|
||||
```
|
||||
|
||||
There are other tunable settings: for an exaustive list, see the top of
|
||||
`Makefile`. Keep in mind that tweaking those values between builds may require
|
||||
forcing a clean build by issuing a `make clean`.
|
||||
|
|
@ -0,0 +1,24 @@
|
|||
This is free and unencumbered software released into the public domain.
|
||||
|
||||
Anyone is free to copy, modify, publish, use, compile, sell, or
|
||||
distribute this software, either in source code form or as a compiled
|
||||
binary, for any purpose, commercial or non-commercial, and by any
|
||||
means.
|
||||
|
||||
In jurisdictions that recognize copyright laws, the author or authors
|
||||
of this software dedicate any and all copyright interest in the
|
||||
software to the public domain. We make this dedication for the benefit
|
||||
of the public at large and to the detriment of our heirs and
|
||||
successors. We intend this dedication to be an overt act of
|
||||
relinquishment in perpetuity of all present and future rights to this
|
||||
software under copyright law.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
|
||||
OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
|
||||
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||
OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
For more information, please refer to <https://unlicense.org/>
|
||||
|
|
@ -0,0 +1,2 @@
|
|||
*
|
||||
!.gitignore
|
||||
|
|
@ -0,0 +1,11 @@
|
|||
Welcome to Alpine!
|
||||
|
||||
This is an unofficial port to the Allwinner H700 SoC: please report
|
||||
issues to https://github.com/mporrato/alpine-h700 .
|
||||
|
||||
The Alpine Wiki contains a large amount of how-to guides and general
|
||||
information about administrating Alpine systems.
|
||||
See <https://wiki.alpinelinux.org/>.
|
||||
|
||||
You may change this message by editing /etc/motd.
|
||||
|
||||
|
|
@ -0,0 +1,26 @@
|
|||
earlyprintk=sunxi-uart,0x05000000
|
||||
initcall_debug=0
|
||||
console=ttyS0,115200
|
||||
rootfstype=ext4
|
||||
nand_root=/dev/nand0p4
|
||||
mmc_root=/dev/mmcblk0p4
|
||||
init=/sbin/init
|
||||
loglevel=4
|
||||
selinux=0
|
||||
cma=64M
|
||||
mac=
|
||||
wifi_mac=
|
||||
bt_mac=
|
||||
specialstr=
|
||||
keybox_list=hdcpkey,widevine
|
||||
setargs_nand=setenv bootargs earlyprintk=${earlyprintk} initcall_debug=${initcall_debug} console=${console} loglevel=${loglevel} rootfstype=${rootfstype} root=${nand_root} init=${init} partitions=${partitions} cma=${cma} snum=${snum} mac_addr=${mac} wifi_mac=${wifi_mac} bt_mac=${bt_mac} selinux=${selinux} specialstr=${specialstr} gpt=1
|
||||
setargs_mmc=setenv bootargs earlyprintk=${earlyprintk} initcall_debug=${initcall_debug} console=${console} loglevel=${loglevel} rootfstype=${rootfstype} root=${mmc_root} init=${init} partitions=${partitions} cma=${cma} snum=${snum} mac_addr=${mac} wifi_mac=${wifi_mac} bt_mac=${bt_mac} selinux=${selinux} specialstr=${specialstr} gpt=1
|
||||
boot_normal=sunxi_flash read 45000000 boot;bootm 45000000
|
||||
boot_recovery=sunxi_flash read 45000000 recovery;bootm 45000000
|
||||
boot_fastboot=fastboot
|
||||
recovery_key_value_max=0x13
|
||||
recovery_key_value_min=0x10
|
||||
fastboot_key_value_max=0x8
|
||||
fastboot_key_value_min=0x2
|
||||
bootdelay=0
|
||||
bootcmd=run setargs_nand boot_normal
|
||||
|
|
@ -0,0 +1 @@
|
|||
features="base"
|
||||
|
After Width: | Height: | Size: 88 KiB |
|
After Width: | Height: | Size: 117 KiB |
|
After Width: | Height: | Size: 117 KiB |
|
After Width: | Height: | Size: 117 KiB |
|
After Width: | Height: | Size: 117 KiB |
|
After Width: | Height: | Size: 117 KiB |
|
After Width: | Height: | Size: 117 KiB |
|
After Width: | Height: | Size: 117 KiB |
|
After Width: | Height: | Size: 117 KiB |
|
After Width: | Height: | Size: 117 KiB |
|
After Width: | Height: | Size: 117 KiB |
|
After Width: | Height: | Size: 58 B |
|
After Width: | Height: | Size: 234 KiB |
|
After Width: | Height: | Size: 234 KiB |
|
After Width: | Height: | Size: 117 KiB |
|
After Width: | Height: | Size: 87 KiB |
|
After Width: | Height: | Size: 117 KiB |
|
After Width: | Height: | Size: 337 KiB |
|
After Width: | Height: | Size: 192 KiB |
|
After Width: | Height: | Size: 900 KiB |
|
After Width: | Height: | Size: 186 KiB |
|
|
@ -0,0 +1 @@
|
|||
a1sp9maKde37ee6c-6dc4-4d74-86f0-db32116efb53e0e40ccf-7a66-406b-88c3-415b4a62a8f7777622ab-6bd0-464f-9da5-4cc203e855ea8ce5671f-e8b5-442e-9300-2ee6836c538aabf5f481-c961-4895-8245-631f74851d0c2bbb4229-55a8-4929-a165-3f406f0ee441ab5d09a9-c4dc-44bb-a175-cfb7c978a062329ea51e-1ddc-44ff-ac09-9ef7b64e0c52a712e47d-13f7-4490-9fea-bdcd587b8a4a5ed4d4e6-0ba3-45c5-a778-3232a42d4d960a9b7466-d7b3-4087-b8ff-c51763b852a50cd78bb6-a6d5-43a8-8661-fb91abd346433e8a86ee-711e-49c1-ad54-b59dd01fe513e22b0d8b-647f-4417-a115-9806c5d64eec
|
||||
|
|
@ -0,0 +1,36 @@
|
|||
#!/bin/sh
|
||||
# This script runs inside an aarch64 alpine linux container and creates a
|
||||
# base rootfs tarball with wifi support and an ssh daemon active at boot.
|
||||
set -e
|
||||
|
||||
target="$(mktemp -d)"
|
||||
trap 'rm -rf "$target"' 0
|
||||
|
||||
apk update
|
||||
apk -X "$(awk '/\/alpine\/[^\/]+\/main$/{print;exit}' /etc/apk/repositories)" \
|
||||
--keys-dir /etc/apk/keys -U -p "$target/" --initdb \
|
||||
add alpine-base alpine-release ca-certificates wpa_supplicant dropbear
|
||||
cp /etc/apk/repositories "$target/etc/apk/"
|
||||
echo "nameserver 8.8.8.8" >"$target/etc/resolv.conf"
|
||||
sed -Ei 's/^(tty[0-9]+:)/#\1/;s/^#ttyS0:/ttyS0:/' "$target/etc/inittab"
|
||||
echo h700 >"$target/etc/hostname"
|
||||
echo 8821cs >"$target/etc/modules"
|
||||
cat >"$target/etc/network/interfaces" <<__EOF__
|
||||
auto lo
|
||||
iface lo inet loopback
|
||||
|
||||
auto wlan0
|
||||
iface wlan0 inet dhcp
|
||||
__EOF__
|
||||
for svc in devfs dmesg mdev ; do
|
||||
chroot "$target" rc-update add "$svc" sysinit
|
||||
done
|
||||
for svc in hwclock modules sysctl hostname bootmisc syslog wpa_supplicant networking ; do
|
||||
chroot "$target" rc-update add "$svc" boot
|
||||
done
|
||||
for svc in mount-ro killprocs savecache ; do
|
||||
chroot "$target" rc-update add "$svc" shutdown
|
||||
done
|
||||
chroot "$target" rc-update add dropbear default
|
||||
|
||||
tar cf "${1:-/tmp/rootfs.tar}" -C "$target" .
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
#!/bin/bash
|
||||
|
||||
podman run --arch=aarch64 --security-opt=label=disable \
|
||||
-v "${2:-./artifacts}:/artifacts" \
|
||||
-v ./scripts/_build.sh:/usr/local/bin/_build.sh \
|
||||
--rm "docker.io/library/alpine:${1:-latest}" \
|
||||
sh /usr/local/bin/_build.sh /artifacts/rootfs.tar
|
||||
|
|
@ -0,0 +1,82 @@
|
|||
#!/usr/bin/env python3
|
||||
"""
|
||||
Extract SPL and U-Boot images from an Allwinner boot image
|
||||
"""
|
||||
|
||||
import argparse
|
||||
import mmap
|
||||
from pathlib import Path
|
||||
import struct
|
||||
import sys
|
||||
|
||||
|
||||
SPL_SIGNATURE = b"eGON.BT0"
|
||||
# The SPL can be located at different locations depending on the SoC type
|
||||
SPL_OFFSETS = [8 * 1024, 128 * 1024, 256 * 1024]
|
||||
SPL_FILENAME = "spl.img"
|
||||
|
||||
UBOOT_SIGNATURE = b"sunxi-package"
|
||||
UBOOT_OFFSET = 16400 * 1024
|
||||
UBOOT_FILENAME = "u-boot.img"
|
||||
|
||||
|
||||
class InvalidImageError(Exception):
|
||||
pass
|
||||
|
||||
|
||||
def extract_blobs(image: Path, output_dir: Path = Path(), verbose: bool = True):
|
||||
with image.open("rb") as f:
|
||||
# The first partition starts at 36MB: map all space before that into memory
|
||||
mm = mmap.mmap(f.fileno(), 36 * 1024**2, prot=mmap.PROT_READ)
|
||||
spl_offset = spl_size = None
|
||||
for offset in SPL_OFFSETS:
|
||||
sig_offset = offset + 4
|
||||
if mm[sig_offset : sig_offset + len(SPL_SIGNATURE)] == SPL_SIGNATURE:
|
||||
spl_offset = offset
|
||||
(spl_size,) = struct.unpack("<I", mm[offset + 16 : offset + 16 + 4])
|
||||
break
|
||||
if spl_offset is None:
|
||||
raise InvalidImageError("Can't find SPL")
|
||||
if verbose:
|
||||
print(
|
||||
f"Found SPL at offset {spl_offset / 1024}KiB, size {spl_size / 1024}KiB"
|
||||
)
|
||||
if mm[UBOOT_OFFSET : UBOOT_OFFSET + len(UBOOT_SIGNATURE)] != UBOOT_SIGNATURE:
|
||||
raise InvalidImageError("Can't find U-Boot")
|
||||
(uboot_size,) = struct.unpack(
|
||||
"<I", mm[UBOOT_OFFSET + 36 : UBOOT_OFFSET + 36 + 4]
|
||||
)
|
||||
if verbose:
|
||||
print(
|
||||
f"Found U-Boot at offset {UBOOT_OFFSET / 1024}KiB, size {uboot_size / 1024}KiB"
|
||||
)
|
||||
if not output_dir.exists():
|
||||
output_dir.mkdir(mode=0o755, parents=True)
|
||||
spl_image = output_dir / SPL_FILENAME
|
||||
if verbose:
|
||||
print(f"Writing SPL image to {spl_image}")
|
||||
spl_image.write_bytes(mm[spl_offset : spl_offset + spl_size])
|
||||
uboot_image = output_dir / UBOOT_FILENAME
|
||||
if verbose:
|
||||
print(f"Writing U-Boot image to {uboot_image}")
|
||||
uboot_image.write_bytes(mm[UBOOT_OFFSET : UBOOT_OFFSET + uboot_size])
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
parser = argparse.ArgumentParser(
|
||||
description="Extract Allwinner H700 binary blobs from SD card images"
|
||||
)
|
||||
parser.add_argument("image", type=Path, help="source image or device")
|
||||
parser.add_argument(
|
||||
"--output", "-o", type=Path, default=Path(), help="output directory"
|
||||
)
|
||||
parser.add_argument(
|
||||
"--verbose", "-v", action="store_true", help="show what's being done"
|
||||
)
|
||||
args = parser.parse_args()
|
||||
try:
|
||||
extract_blobs(args.image, args.output, args.verbose)
|
||||
sys.exit(0)
|
||||
except Exception as e:
|
||||
sys.stderr.write(f"{e}\n")
|
||||
sys.exit(1)
|
||||
|
|
@ -0,0 +1,21 @@
|
|||
#!/bin/bash
|
||||
# Extract the kernel and boot image configuration from the given
|
||||
# android boot image.
|
||||
set -e
|
||||
|
||||
image="$1"
|
||||
outdir="${2:-./artifacts}"
|
||||
|
||||
boot_part="$(sgdisk -p "$image" | awk '$7=="boot"{print $2 " " $3-$2+1;exit}')"
|
||||
read -r -a boot <<<"$boot_part"
|
||||
|
||||
block_shift="$(factor -h "${boot[@]}" | grep -Eo "2\^[0-9]+" | sed 's/^2\^//' | sort -n | head -n1)"
|
||||
block_size="$((2 ** block_shift))"
|
||||
start_blocks="$((boot[0] / block_size))"
|
||||
size_blocks="$((boot[1] / block_size))"
|
||||
|
||||
tmp="$(mktemp -d)"
|
||||
trap 'rm -rf "$tmp"' 0
|
||||
|
||||
dd if="$image" of="$tmp/boot.img" bs="$((512 * block_size))" skip="$start_blocks" count="$size_blocks" conv=sparse status=none
|
||||
abootimg -x "$tmp/boot.img" "$outdir/bootimg.cfg" "$outdir/zImage" /dev/null /dev/null
|
||||
|
|
@ -0,0 +1,22 @@
|
|||
#!/bin/bash
|
||||
# Extracts kernel modules and firmware blobs from the given
|
||||
# rootfs image.
|
||||
set -e
|
||||
|
||||
if [[ $# -lt 2 ]] ; then
|
||||
echo "Syntax: $0 IMAGE OUTDIR [PARTNO]"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
image="$1"
|
||||
outdir="$2"
|
||||
partno="${3:-5}"
|
||||
|
||||
device="/dev/sda$partno"
|
||||
|
||||
guestfish --ro --format=raw -a "$image" <<__EOF__
|
||||
run
|
||||
mount "$device" /
|
||||
tar-out /lib/modules "$outdir/modules.tar"
|
||||
tar-out /lib/firmware "$outdir/firmware.tar"
|
||||
__EOF__
|
||||
|
|
@ -0,0 +1,87 @@
|
|||
#!/usr/bin/env python3
|
||||
"""
|
||||
Create a U-Boot environment image from a text environment file
|
||||
|
||||
This is required because the Anbernic environment format is not compatible
|
||||
with the binary format produced by the mkenvimage tool from the uboot-tools
|
||||
package
|
||||
"""
|
||||
|
||||
import argparse
|
||||
import struct
|
||||
import sys
|
||||
import zlib
|
||||
|
||||
|
||||
ENCODING = "utf-8"
|
||||
DEFAULT_IMG_SIZE = 128 * 1024
|
||||
DEFAULT_IMG_FLAGS = 0
|
||||
|
||||
|
||||
class EnvError(Exception):
|
||||
pass
|
||||
|
||||
|
||||
def makebinenv(infile, outfile, size, flags):
|
||||
"""
|
||||
Create a U-Boot environment image from a text environment file
|
||||
"""
|
||||
|
||||
buf = b""
|
||||
for line in infile:
|
||||
clean_line = line.strip()
|
||||
if clean_line and not clean_line.startswith("#"):
|
||||
buf += bytes(clean_line, ENCODING) + b"\0"
|
||||
infile.close()
|
||||
buf += b"\0"
|
||||
if flags is not None:
|
||||
buf = bytes([flags]) + buf
|
||||
envsize = 4 + len(buf)
|
||||
if envsize > size:
|
||||
raise EnvError(f"Insufficient environment space: need at least {envsize} bytes")
|
||||
buf += bytes(size - envsize)
|
||||
crc = zlib.crc32(buf, 0)
|
||||
buf = struct.pack("<I", crc) + buf
|
||||
outfile.write(buf)
|
||||
outfile.close()
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
parser = argparse.ArgumentParser(
|
||||
prog="mkenv.py",
|
||||
description=(
|
||||
"Create an Anbernic U-Boot environment image from a text environment file"
|
||||
),
|
||||
)
|
||||
parser.add_argument(
|
||||
"textfile",
|
||||
type=argparse.FileType("r", encoding=ENCODING),
|
||||
help="input text environment file",
|
||||
)
|
||||
parser.add_argument(
|
||||
"binfile",
|
||||
type=argparse.FileType("wb"),
|
||||
help="output binary environment image file",
|
||||
)
|
||||
parser.add_argument(
|
||||
"-s",
|
||||
"--size",
|
||||
type=int,
|
||||
default=DEFAULT_IMG_SIZE,
|
||||
help=(f"size of the output binary image in bytes (default={DEFAULT_IMG_SIZE})"),
|
||||
)
|
||||
parser.add_argument(
|
||||
"-f",
|
||||
"--flags",
|
||||
type=int,
|
||||
default=0,
|
||||
help=f"binary image flags (default={DEFAULT_IMG_FLAGS})",
|
||||
)
|
||||
args = parser.parse_args()
|
||||
|
||||
try:
|
||||
makebinenv(args.textfile, args.binfile, args.size, args.flags)
|
||||
sys.exit(0)
|
||||
except Exception as e:
|
||||
sys.stderr.write(f"{e}\n")
|
||||
sys.exit(1)
|
||||
|
|
@ -0,0 +1,54 @@
|
|||
#!/bin/bash
|
||||
# Create a new filesystem and populate it with the specified files.
|
||||
# Automatically extracts tarballs.
|
||||
set -e
|
||||
|
||||
if [[ $# -lt 5 ]] ; then
|
||||
echo "Syntax: $0 IMAGE PART# FSTYPE LABEL SOURCE [...]"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
image="$1" ; shift
|
||||
partition="$1" ; shift
|
||||
fstype="$1" ; shift
|
||||
label="$1" ; shift
|
||||
|
||||
device="/dev/sda"
|
||||
[[ $partition -ne 0 ]] && device="$device$partition"
|
||||
|
||||
script=(
|
||||
"run"
|
||||
"mkfs $fstype $device label:$label"
|
||||
"mount $device /"
|
||||
)
|
||||
|
||||
while [ $# -gt 0 ] ; do
|
||||
src="$1"
|
||||
if [[ "$src" =~ .+:.+ ]] ; then
|
||||
dest="${src##*:}"
|
||||
src="${src%%:*}"
|
||||
script+=("mkdir-p \"$dest\"")
|
||||
else
|
||||
dest="/"
|
||||
fi
|
||||
if [ -d "$src" ] ; then
|
||||
for item in "$src"/* ; do
|
||||
cmd="copy-in \"$item\" \"$dest\""
|
||||
script+=("$cmd")
|
||||
done
|
||||
else
|
||||
case "$src" in
|
||||
*.tar) cmd="tar-in \"$src\" \"$dest\"" ;;
|
||||
*.tar.gz) cmd="tar-in \"$src\" \"$dest\" compress:gzip" ;;
|
||||
*) cmd="copy-in \"$src\" \"$dest\"" ;;
|
||||
esac
|
||||
script+=("$cmd")
|
||||
fi
|
||||
shift
|
||||
done
|
||||
|
||||
script+=("fstrim /")
|
||||
|
||||
for cmd in "${script[@]}"; do
|
||||
echo "$cmd"
|
||||
done | guestfish --format=raw -a "$image"
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
#!/bin/bash
|
||||
|
||||
podman run --arch=arm64 --security-opt=label=disable \
|
||||
-v "${2:-./artifacts}:/artifacts" \
|
||||
-v ./mkinitfs.conf:/tmp/mkinitfs.conf:ro \
|
||||
--rm "docker.io/library/alpine:${1:-latest}" \
|
||||
sh -c "apk update && apk add mkinitfs apk-tools && mkinitfs -c /tmp/mkinitfs.conf -n -o /artifacts/initramfs"
|
||||
|
|
@ -0,0 +1,37 @@
|
|||
#!/bin/bash
|
||||
# Assemble SPL, U-Boot, U-Boot environment, boot-resources, boot and rootfs
|
||||
# images into a final H700 bootable sdcard image.
|
||||
set -e
|
||||
|
||||
if [[ $# -lt 7 ]] ; then
|
||||
echo "Usage: $0 SDCARD SPL UBOOT ENV BOOT-RESOURCE BOOT ROOTFS"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
mb() {
|
||||
# Return the file size in MiB (rounded up)
|
||||
local file_size
|
||||
file_size="$(stat -c "%s" "$1")"
|
||||
echo "$(( (file_size + 1024 ** 2 - 1) / 1024 ** 2 ))M"
|
||||
}
|
||||
|
||||
sgdisk --move-main-table=73696 -I \
|
||||
--new="0:0:+$(mb "$4")" --change-name=0:env --attributes=0:=:c000000000000001 --typecode=0:b000 \
|
||||
--new="0:0:+$(mb "$5")" --change-name=0:boot-resource --attributes=0:=:c000000000000001 --typecode=0:0700 \
|
||||
--new="0:0:+$(mb "$6")" --change-name=0:boot --attributes=0:=:c000000000000001 --typecode=0:a002 \
|
||||
--new="0:0:+$(mb "$7")" --change-name=0:rootfs --attributes=0:=:c000000000000001 --typecode=0:8305 \
|
||||
"$1"
|
||||
|
||||
part_table="$(sgdisk -p artifacts/alpine-h700.img | awk '/^ +[0-9]+ +[0-9]+ +[0-9]+/{print $2 / 2}' | xargs)"
|
||||
read -r -a offsets <<<"$part_table"
|
||||
|
||||
images=("$2" "$3" "$4" "$5" "$6" "$7")
|
||||
offsets=(8 16400 "${offsets[@]}")
|
||||
|
||||
for i in "${!images[@]}"; do
|
||||
img="${images[$i]}"
|
||||
off="${offsets[$i]}"
|
||||
echo "Writing $img at offset ${off}KiB"
|
||||
dd if="$img" of="$1" bs=1K seek="${off}" conv=sparse,notrunc status=none
|
||||
done
|
||||
echo "Your bootable SD image is $1"
|
||||