Compare commits
10 Commits
f647a9f733
...
033d6b6a7d
Author | SHA1 | Date |
---|---|---|
minish | 033d6b6a7d | |
minish | 8b44ba1b0c | |
ading2210 | 3f213fc4ca | |
ading2210 | 91486b067f | |
ading2210 | 645e03cfd8 | |
ading2210 | 291f616b6b | |
ading2210 | e76d04244f | |
Darkn | 12b29ef8b2 | |
Darkn | 71cff4ca1a | |
ading2210 | 73ff47a6b7 |
|
@ -0,0 +1,4 @@
|
||||||
|
if ! has nix_direnv_version || ! nix_direnv_version 3.0.5; then
|
||||||
|
source_url "https://raw.githubusercontent.com/nix-community/nix-direnv/3.0.5/direnvrc" "sha256-RuwIS+QKFj/T9M2TFXScjBsLR6V3A17YVoEW/Q6AZ1w="
|
||||||
|
fi
|
||||||
|
use flake
|
|
@ -9,7 +9,7 @@ jobs:
|
||||||
|
|
||||||
strategy:
|
strategy:
|
||||||
matrix:
|
matrix:
|
||||||
board: [dedede, octopus, coral, grunt, nissa, zork]
|
board: [dedede, octopus, coral, grunt, nissa, zork, corsola, jacuzzi]
|
||||||
|
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
|
|
44
README.md
44
README.md
|
@ -2,6 +2,10 @@
|
||||||
|
|
||||||
Shimboot is a collection of scripts for patching a Chrome OS RMA shim to serve as a bootloader for a standard Linux distribution. It allows you to boot a full desktop Debian install on a Chromebook, without needing to unenroll it or modify the firmware.
|
Shimboot is a collection of scripts for patching a Chrome OS RMA shim to serve as a bootloader for a standard Linux distribution. It allows you to boot a full desktop Debian install on a Chromebook, without needing to unenroll it or modify the firmware.
|
||||||
|
|
||||||
|
| <img src="/website/assets/shimboot_demo_1.jpg" alt="Shimboot (KDE) on an HP Chromebook 11 G9 EE." width="400"/> | <img src="/website/assets/shimboot_demo_2.jpg" alt="Shimboot (XFCE) on an Acer Chromebook 311 C722." width="400"/> |
|
||||||
|
| ----- | ----- |
|
||||||
|
| Shimboot (KDE) on an HP Chromebook 11 G9 EE | Shimboot (XFCE) on an Acer Chromebook 311 C722 |
|
||||||
|
|
||||||
## Features:
|
## Features:
|
||||||
- Run a full Debian installation on a Chromebook
|
- Run a full Debian installation on a Chromebook
|
||||||
- Does not modify the firmware
|
- Does not modify the firmware
|
||||||
|
@ -34,16 +38,17 @@ Note that rootfs partitions have to be named `shimboot_rootfs:<partname>` for th
|
||||||
Driver support depends on the device you are using shimboot on. The `patch_rootfs.sh` script attempts to copy all the firmware and drivers from the shim and recovery image into the rootfs, so expect most things to work on other boards. ARM Chromebooks are not supported at the moment.
|
Driver support depends on the device you are using shimboot on. The `patch_rootfs.sh` script attempts to copy all the firmware and drivers from the shim and recovery image into the rootfs, so expect most things to work on other boards. ARM Chromebooks are not supported at the moment.
|
||||||
|
|
||||||
### Device Compatibility Table:
|
### Device Compatibility Table:
|
||||||
| Feature \ Board Name | [`dedede`](https://chrome100.dev/board/dedede/) | [`octopus`](https://chrome100.dev/board/octopus/) | [`nissa`](https://chrome100.dev/board/nissa/) | [`reks`](https://chrome100.dev/board/reks/) | [`kefka`](https://chrome100.dev/board/kefka) | [`zork`](https://chrome100.dev/board/zork) | [`grunt`](https://chrome100.dev/board/grunt) |
|
| Board Name | X11 | Wifi | Speakers | Backlight | Touchscreen | 3D Accel | Bluetooth | Webcam |
|
||||||
|----------------------|-------------------------------------------------|---------------------------------------------------|-----------------------------------------------|---------------------------------------------|----------------------------------------------|--------------------------------------------|----------------------------------------------|
|
|------------------------------------------------ |-------------------|------|----------|-----------|-------------|----------|-----------|----------|
|
||||||
| X11 | yes | yes | yes | no <sup>[1]</sup> | no <sup>[1]</sup> | yes | yes |
|
| [`dedede`](https://chrome100.dev/board/dedede) | yes | yes | no | yes | yes | yes | yes | yes |
|
||||||
| Wifi | yes | yes | yes | yes | yes | yes | yes |
|
| [`octopus`](https://chrome100.dev/board/octopus) | yes | yes | yes | yes | yes | yes | yes | yes |
|
||||||
| Internal Audio | no | yes | no | untested | yes | no | no |
|
| [`nissa`](https://chrome100.dev/board/nissa) | yes | yes | no | yes | yes | yes | yes | yes |
|
||||||
| Backlight | yes | yes | yes | untested | yes | untested | yes |
|
| [`reks`](https://chrome100.dev/board/reks) | no<sup>[1]</sup> | yes | untested | untested | untested | no | untested | untested |
|
||||||
| Touchscreen | yes | yes | yes | untested | untested | yes | yes |
|
| [`kefka`](https://chrome100.dev/board/kefka) | no<sup>[1]</sup> | yes | yes | yes | untested | no | untested | untested |
|
||||||
| 3D Acceleration | yes | yes | yes | no | no | yes | yes |
|
| [`zork`](https://chrome100.dev/board/zork) | yes | yes | no | untested | yes | yes | yes | yes |
|
||||||
| Bluetooth | yes | yes | yes | untested | untested | yes | yes |
|
| [`grunt`](https://chrome100.dev/board/grunt) | yes | yes | no | yes | yes | yes | yes | yes |
|
||||||
| Webcam | yes | yes | yes | untested | untested | yes | yes |
|
| [`jacuzzi`](https://chrome100.dev/board/jacuzzi) | yes | yes | no | yes | untested | no | no | yes |
|
||||||
|
| [`corsola`](https://chrome100.dev/board/corsola) | yes | yes | untested | untested | untested | untested | untested | untested |
|
||||||
|
|
||||||
<sup>1. The kernel is too old.</sup>
|
<sup>1. The kernel is too old.</sup>
|
||||||
|
|
||||||
|
@ -62,7 +67,6 @@ On all devices, the following features will not work:
|
||||||
- Transparent disk compression
|
- Transparent disk compression
|
||||||
- Full disk encryption
|
- Full disk encryption
|
||||||
- Support for more distros (Ubuntu and Arch maybe)
|
- Support for more distros (Ubuntu and Arch maybe)
|
||||||
- Support for ARM based Chromebooks (see [issue #8](https://github.com/ading2210/shimboot/issues/8))
|
|
||||||
- Eliminate binwalk dependency
|
- Eliminate binwalk dependency
|
||||||
- Get audio to work on dedede
|
- Get audio to work on dedede
|
||||||
- Get kexec working
|
- Get kexec working
|
||||||
|
@ -76,14 +80,17 @@ PRs and contributions are welcome to help implement these features.
|
||||||
- WSL2 is supported if you are on Windows
|
- WSL2 is supported if you are on Windows
|
||||||
- Github Codespaces is not supported at the moment
|
- Github Codespaces is not supported at the moment
|
||||||
- A USB drive that is at least 8GB in size
|
- A USB drive that is at least 8GB in size
|
||||||
|
- Cheap USB 2.0 drives typically won't work well due to their slow speeds
|
||||||
- At least 20GB of free disk space
|
- At least 20GB of free disk space
|
||||||
|
|
||||||
### Build Instructions:
|
### Build Instructions:
|
||||||
1. Find the board name of your Chromebook. You can search for the model name on [chrome100.dev](https://chrome100.dev/).
|
1. Find the board name of your Chromebook. You can search for the model name on [chrome100.dev](https://chrome100.dev/).
|
||||||
1. Clone this repository and cd into it.
|
2. Clone this repository and cd into it.
|
||||||
2. Run `sudo ./build_complete.sh <board_name>` to download the required data and build the disk image. If you have an ARM-based Chromebook, pass `arch=arm64` in as an option.
|
3. Run `sudo ./build_complete.sh <board_name>` to download the required data and build the disk image.
|
||||||
|
|
||||||
Alternatively, you can run each of the steps manually:
|
Note: If you are building for an ARM Chromebook, you need the `qemu-user-static` and `binfmt-support` packages.
|
||||||
|
|
||||||
|
#### Alternatively, you can run each of the steps manually:
|
||||||
1. Grab a Chrome OS RMA Shim from somewhere. Most of them have already been leaked and aren't too difficult to find.
|
1. Grab a Chrome OS RMA Shim from somewhere. Most of them have already been leaked and aren't too difficult to find.
|
||||||
2. Download a Chrome OS [recovery image](https://chromiumdash.appspot.com/serving-builds?deviceCategory=ChromeOS) for your board.
|
2. Download a Chrome OS [recovery image](https://chromiumdash.appspot.com/serving-builds?deviceCategory=ChromeOS) for your board.
|
||||||
3. Unzip the shim and the recovery image if you have not done so already.
|
3. Unzip the shim and the recovery image if you have not done so already.
|
||||||
|
@ -108,10 +115,11 @@ Alternatively, you can run each of the steps manually:
|
||||||
#### I want to use a different Linux distribution. How can I do that?
|
#### I want to use a different Linux distribution. How can I do that?
|
||||||
Using any Linux distro is possible, provided that you apply the [proper patches](https://github.com/ading2210/chromeos-systemd) to systemd and recompile it. Most distros have some sort of bootstrapping tool that allows you to install it to a directory on your host PC. Then, you can just pass that rootfs directory into `patch_rootfs.sh` and `build.sh`.
|
Using any Linux distro is possible, provided that you apply the [proper patches](https://github.com/ading2210/chromeos-systemd) to systemd and recompile it. Most distros have some sort of bootstrapping tool that allows you to install it to a directory on your host PC. Then, you can just pass that rootfs directory into `patch_rootfs.sh` and `build.sh`.
|
||||||
|
|
||||||
Debian Sid (the rolling release version of Debian) is also supported if you just want newer packages, and you can install it by passing an argument to `build_rootfs.sh`:
|
Debian Sid (the rolling release version of Debian) is also supported if you just want newer packages, and you can install it by passing an argument to `build_complete.sh`:
|
||||||
```bash
|
```bash
|
||||||
sudo ./build_rootfs.sh data/rootfs unstable
|
sudo ./build_complete.sh dedede release=unstable
|
||||||
```
|
```
|
||||||
|
|
||||||
#### How can I install a desktop environment other than XFCE?
|
#### How can I install a desktop environment other than XFCE?
|
||||||
You can pass the `desktop` argument to the `build_complete.sh` script, like this:
|
You can pass the `desktop` argument to the `build_complete.sh` script, like this:
|
||||||
```bash
|
```bash
|
||||||
|
@ -133,12 +141,14 @@ sudo resize2fs /dev/mmcblk1p4
|
||||||
|
|
||||||
#### GPU acceleration isn't working, how can I fix this?
|
#### GPU acceleration isn't working, how can I fix this?
|
||||||
If your kernel version is too old, the standard Mesa drivers will fail to load. Instead, you must download and install the `mesa-amber` drivers. Run the following commands:
|
If your kernel version is too old, the standard Mesa drivers will fail to load. Instead, you must download and install the `mesa-amber` drivers. Run the following commands:
|
||||||
```
|
```bash
|
||||||
sudo apt install libglx-amber0 libegl-amber0
|
sudo apt install libglx-amber0 libegl-amber0
|
||||||
echo "MESA_LOADER_DRIVER_OVERRIDE=i965" | sudo tee -a /etc/environment
|
echo "MESA_LOADER_DRIVER_OVERRIDE=i965" | sudo tee -a /etc/environment
|
||||||
```
|
```
|
||||||
You may need to change `i965` to `i915` (or `r100`/`r200` for AMD hardware), depending on what GPU you have.
|
You may need to change `i965` to `i915` (or `r100`/`r200` for AMD hardware), depending on what GPU you have.
|
||||||
|
|
||||||
|
For ARM Chromebooks, you may have to tweak the [Xorg configuration](https://xkcd.com/963/) instead.
|
||||||
|
|
||||||
#### Can the rootfs be compressed to save space?
|
#### Can the rootfs be compressed to save space?
|
||||||
Compressing the Debian rootfs with a squashfs is supported, and you can do this by running the regular Debian rootfs through `./build_squashfs.sh`. For example:
|
Compressing the Debian rootfs with a squashfs is supported, and you can do this by running the regular Debian rootfs through `./build_squashfs.sh`. For example:
|
||||||
```bash
|
```bash
|
||||||
|
|
|
@ -94,7 +94,7 @@ move_mounts() {
|
||||||
|
|
||||||
print_license() {
|
print_license() {
|
||||||
cat << EOF
|
cat << EOF
|
||||||
Shimboot v1.0.2
|
Shimboot v1.1.1
|
||||||
|
|
||||||
ading2210/shimboot: Boot desktop Linux from a Chrome OS RMA shim.
|
ading2210/shimboot: Boot desktop Linux from a Chrome OS RMA shim.
|
||||||
Copyright (C) 2023 ading2210
|
Copyright (C) 2023 ading2210
|
||||||
|
@ -184,18 +184,6 @@ get_selection() {
|
||||||
return 1
|
return 1
|
||||||
}
|
}
|
||||||
|
|
||||||
contains_word() {
|
|
||||||
local substr="$1"
|
|
||||||
local str="$2"
|
|
||||||
for word in $str; do
|
|
||||||
if [ "$word" = "$substr" ]; then
|
|
||||||
return 0
|
|
||||||
fi
|
|
||||||
done
|
|
||||||
|
|
||||||
return 1
|
|
||||||
}
|
|
||||||
|
|
||||||
copy_progress() {
|
copy_progress() {
|
||||||
local source="$1"
|
local source="$1"
|
||||||
local destination="$2"
|
local destination="$2"
|
||||||
|
@ -223,6 +211,24 @@ print_donor_selector() {
|
||||||
done
|
done
|
||||||
}
|
}
|
||||||
|
|
||||||
|
yes_no_prompt() {
|
||||||
|
local prompt="$1"
|
||||||
|
local var_name="$2"
|
||||||
|
|
||||||
|
while true; do
|
||||||
|
read -p "$prompt" temp_result
|
||||||
|
|
||||||
|
if [ "$temp_result" = "y" ] || [ "$temp_result" = "n" ]; then
|
||||||
|
#the busybox shell has no other way to declare a variable from a string
|
||||||
|
#the declare command and printf -v are both bashisms
|
||||||
|
eval "$var_name='$temp_result'"
|
||||||
|
return 0
|
||||||
|
else
|
||||||
|
echo "invalid selection"
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
}
|
||||||
|
|
||||||
get_donor_selection() {
|
get_donor_selection() {
|
||||||
local rootfs_partitions="$1"
|
local rootfs_partitions="$1"
|
||||||
local target="$2"
|
local target="$2"
|
||||||
|
@ -240,16 +246,9 @@ get_donor_selection() {
|
||||||
|
|
||||||
if [ "$selection" = "$i" ]; then
|
if [ "$selection" = "$i" ]; then
|
||||||
echo "selected $part_path as the donor partition"
|
echo "selected $part_path as the donor partition"
|
||||||
read -p "would you like to spoof verified mode? this is useful if you're planning on using chrome os while enrolled. (y/n): " use_crossystem
|
yes_no_prompt "would you like to spoof verified mode? this is useful if you're planning on using chrome os while enrolled. (y/n): " use_crossystem
|
||||||
|
yes_no_prompt "would you like to spoof an invalid hwid? this will forcibly prevent the device from being enrolled. (y/n): " invalid_hwid
|
||||||
if [ "$use_crossystem" = "y" ] || [ "$use_crossystem" = "n" ]; then
|
boot_chromeos $target $part_path $use_crossystem $invalid_hwid
|
||||||
boot_chromeos $target $part_path $use_crossystem
|
|
||||||
return 0
|
|
||||||
else
|
|
||||||
echo "invalid selection"
|
|
||||||
sleep 1
|
|
||||||
return 1
|
|
||||||
fi
|
|
||||||
fi
|
fi
|
||||||
|
|
||||||
i=$((i+1))
|
i=$((i+1))
|
||||||
|
@ -278,6 +277,7 @@ boot_chromeos() {
|
||||||
local target="$1"
|
local target="$1"
|
||||||
local donor="$2"
|
local donor="$2"
|
||||||
local use_crossystem="$3"
|
local use_crossystem="$3"
|
||||||
|
local invalid_hwid="$4"
|
||||||
|
|
||||||
echo "mounting target"
|
echo "mounting target"
|
||||||
mkdir /newroot
|
mkdir /newroot
|
||||||
|
@ -314,10 +314,17 @@ boot_chromeos() {
|
||||||
echo "patching chrome os rootfs"
|
echo "patching chrome os rootfs"
|
||||||
cat /newroot/etc/ui_use_flags.txt | sed "/reven_branding/d" | sed "/os_install_service/d" > /newroot/tmp/ui_use_flags.txt
|
cat /newroot/etc/ui_use_flags.txt | sed "/reven_branding/d" | sed "/os_install_service/d" > /newroot/tmp/ui_use_flags.txt
|
||||||
mount -o bind /newroot/tmp/ui_use_flags.txt /newroot/etc/ui_use_flags.txt
|
mount -o bind /newroot/tmp/ui_use_flags.txt /newroot/etc/ui_use_flags.txt
|
||||||
|
cp /opt/mount-encrypted /newroot/tmp/mount-encrypted
|
||||||
|
cp /newroot/usr/sbin/mount-encrypted /newroot/tmp/mount-encrypted.real
|
||||||
|
mount -o bind /newroot/tmp/mount-encrypted /newroot/usr/sbin/mount-encrypted
|
||||||
|
|
||||||
if [ "$use_crossystem" = "y" ]; then
|
if [ "$use_crossystem" = "y" ]; then
|
||||||
echo "patching crossystem"
|
echo "patching crossystem"
|
||||||
cp /opt/crossystem /newroot/tmp/crossystem
|
cp /opt/crossystem /newroot/tmp/crossystem
|
||||||
|
if [ "$invalid_hwid" = "y" ]; then
|
||||||
|
sed -i 's/block_devmode/hwid/' /newroot/tmp/crossystem
|
||||||
|
fi
|
||||||
|
|
||||||
cp /newroot/usr/bin/crossystem /newroot/tmp/crossystem_old
|
cp /newroot/usr/bin/crossystem /newroot/tmp/crossystem_old
|
||||||
mount -o bind /newroot/tmp/crossystem /newroot/usr/bin/crossystem
|
mount -o bind /newroot/tmp/crossystem /newroot/usr/bin/crossystem
|
||||||
fi
|
fi
|
||||||
|
|
|
@ -0,0 +1,5 @@
|
||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
#this fixes chrome os persistence by adding the "--unsafe" flag to all invocations of mount-encrypted
|
||||||
|
|
||||||
|
/tmp/mount-encrypted.real "$@" --unsafe 2>&1 | tee -a /tmp/mount-encrypted.log
|
18
build.sh
18
build.sh
|
@ -14,7 +14,7 @@ print_help() {
|
||||||
}
|
}
|
||||||
|
|
||||||
assert_root
|
assert_root
|
||||||
assert_deps "cpio binwalk pcregrep realpath cgpt mkfs.ext4 mkfs.ext2 fdisk rsync lz4"
|
assert_deps "cpio binwalk pcregrep realpath cgpt mkfs.ext4 mkfs.ext2 fdisk lz4"
|
||||||
assert_args "$3"
|
assert_args "$3"
|
||||||
parse_args "$@"
|
parse_args "$@"
|
||||||
|
|
||||||
|
@ -22,32 +22,32 @@ output_path=$(realpath -m "${1}")
|
||||||
shim_path=$(realpath -m "${2}")
|
shim_path=$(realpath -m "${2}")
|
||||||
rootfs_dir=$(realpath -m "${3}")
|
rootfs_dir=$(realpath -m "${3}")
|
||||||
|
|
||||||
echo "reading the shim image"
|
print_info "reading the shim image"
|
||||||
initramfs_dir=/tmp/shim_initramfs
|
initramfs_dir=/tmp/shim_initramfs
|
||||||
kernel_img=/tmp/kernel.img
|
kernel_img=/tmp/kernel.img
|
||||||
rm -rf $initramfs_dir $kernel_img
|
rm -rf $initramfs_dir $kernel_img
|
||||||
extract_initramfs_full $shim_path $initramfs_dir $kernel_img "${args['arch']}"
|
extract_initramfs_full $shim_path $initramfs_dir $kernel_img "${args['arch']}"
|
||||||
|
|
||||||
echo "patching initramfs"
|
print_info "patching initramfs"
|
||||||
patch_initramfs $initramfs_dir
|
patch_initramfs $initramfs_dir
|
||||||
|
|
||||||
echo "creating disk image"
|
print_info "creating disk image"
|
||||||
rootfs_size=$(du -sm $rootfs_dir | cut -f 1)
|
rootfs_size=$(du -sm $rootfs_dir | cut -f 1)
|
||||||
rootfs_part_size=$(($rootfs_size * 12 / 10 + 5))
|
rootfs_part_size=$(($rootfs_size * 12 / 10 + 5))
|
||||||
#create a 20mb bootloader partition
|
#create a 20mb bootloader partition
|
||||||
#rootfs partition is 20% larger than its contents
|
#rootfs partition is 20% larger than its contents
|
||||||
create_image $output_path 20 $rootfs_part_size
|
create_image $output_path 20 $rootfs_part_size
|
||||||
|
|
||||||
echo "creating loop device for the image"
|
print_info "creating loop device for the image"
|
||||||
image_loop=$(create_loop ${output_path})
|
image_loop=$(create_loop ${output_path})
|
||||||
|
|
||||||
echo "creating partitions on the disk image"
|
print_info "creating partitions on the disk image"
|
||||||
create_partitions $image_loop $kernel_img
|
create_partitions $image_loop $kernel_img
|
||||||
|
|
||||||
echo "copying data into the image"
|
print_info "copying data into the image"
|
||||||
populate_partitions $image_loop $initramfs_dir $rootfs_dir "${args['quiet']}"
|
populate_partitions $image_loop $initramfs_dir $rootfs_dir "${args['quiet']}"
|
||||||
rm -rf $initramfs_dir $kernel_img
|
rm -rf $initramfs_dir $kernel_img
|
||||||
|
|
||||||
echo "cleaning up loop devices"
|
print_info "cleaning up loop devices"
|
||||||
losetup -d $image_loop
|
losetup -d $image_loop
|
||||||
echo "done"
|
print_info "done"
|
|
@ -13,25 +13,43 @@ print_help() {
|
||||||
echo " gnome, xfce, kde, lxde, gnome-flashback, cinnamon, mate, lxqt"
|
echo " gnome, xfce, kde, lxde, gnome-flashback, cinnamon, mate, lxqt"
|
||||||
echo " data_dir - The working directory for the scripts. This defaults to ./data"
|
echo " data_dir - The working directory for the scripts. This defaults to ./data"
|
||||||
echo " arch - The CPU architecture to build the shimboot image for. Set this to 'arm64' if you have an ARM Chromebook."
|
echo " arch - The CPU architecture to build the shimboot image for. Set this to 'arm64' if you have an ARM Chromebook."
|
||||||
|
echo " release - Set this to either 'bookworm' or 'unstable' to build for Debian stable/unstable."
|
||||||
}
|
}
|
||||||
|
|
||||||
assert_root
|
assert_root
|
||||||
assert_args "$1"
|
assert_args "$1"
|
||||||
parse_args "$@"
|
parse_args "$@"
|
||||||
|
|
||||||
|
base_dir="$(realpath -m $(dirname "$0"))"
|
||||||
|
board="$1"
|
||||||
|
|
||||||
compress_img="${args['compress_img']}"
|
compress_img="${args['compress_img']}"
|
||||||
rootfs_dir="${args['rootfs_dir']}"
|
rootfs_dir="${args['rootfs_dir']}"
|
||||||
quiet="${args['quiet']}"
|
quiet="${args['quiet']}"
|
||||||
desktop="${args['desktop']-'xfce'}"
|
desktop="${args['desktop']-'xfce'}"
|
||||||
data_dir="${args['data_dir']}"
|
data_dir="${args['data_dir']}"
|
||||||
arch="${args['arch']-'amd64'}"
|
arch="${args['arch']-amd64}"
|
||||||
|
release="${args['release']-bookworm}"
|
||||||
|
|
||||||
needed_deps="wget python3 unzip zip git debootstrap cpio binwalk pcregrep cgpt mkfs.ext4 mkfs.ext2 fdisk rsync depmod findmnt lz4"
|
arm_boards="
|
||||||
|
corsola hana jacuzzi kukui strongbad nyan-big kevin bob
|
||||||
|
veyron-speedy veyron-jerry veyron-minnie scarlet elm
|
||||||
|
kukui peach-pi peach-pit stumpy daisy-spring
|
||||||
|
"
|
||||||
|
if grep -q "$board" <<< "$arm_boards"; then
|
||||||
|
print_info "automatically detected arm64 device name"
|
||||||
|
arch="arm64"
|
||||||
|
fi
|
||||||
|
|
||||||
|
needed_deps="wget python3 unzip zip git debootstrap cpio binwalk pcregrep cgpt mkfs.ext4 mkfs.ext2 fdisk depmod findmnt lz4 pv"
|
||||||
if [ "$(check_deps "$needed_deps")" ]; then
|
if [ "$(check_deps "$needed_deps")" ]; then
|
||||||
#install deps automatically on debian and ubuntu
|
#install deps automatically on debian and ubuntu
|
||||||
if [ -f "/etc/debian_version" ]; then
|
if [ -f "/etc/debian_version" ]; then
|
||||||
echo "attempting to install build deps"
|
print_title "attempting to install build deps"
|
||||||
apt-get install wget python3-all unzip zip debootstrap cpio binwalk pcregrep cgpt rsync kmod pv -y
|
apt-get install wget python3-all unzip zip debootstrap cpio binwalk pcregrep cgpt kmod pv lz4 -y
|
||||||
|
if [ "$arch" = "arm64" ]; then
|
||||||
|
apt-get install qemu-user-static binfmt-support -y
|
||||||
|
fi
|
||||||
fi
|
fi
|
||||||
assert_deps "$needed_deps"
|
assert_deps "$needed_deps"
|
||||||
fi
|
fi
|
||||||
|
@ -45,8 +63,6 @@ sigint_handler() {
|
||||||
}
|
}
|
||||||
trap sigint_handler SIGINT
|
trap sigint_handler SIGINT
|
||||||
|
|
||||||
base_dir="$(realpath -m $(dirname "$0"))"
|
|
||||||
board="$1"
|
|
||||||
shim_url="https://dl.darkn.bio/api/raw/?path=/SH1mmer/$board.zip"
|
shim_url="https://dl.darkn.bio/api/raw/?path=/SH1mmer/$board.zip"
|
||||||
boards_url="https://chromiumdash.appspot.com/cros/fetch_serving_builds?deviceCategory=ChromeOS"
|
boards_url="https://chromiumdash.appspot.com/cros/fetch_serving_builds?deviceCategory=ChromeOS"
|
||||||
|
|
||||||
|
@ -56,7 +72,7 @@ else
|
||||||
data_dir="$(realpath -m "$data_dir")"
|
data_dir="$(realpath -m "$data_dir")"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
echo "downloading list of recovery images"
|
print_title "downloading list of recovery images"
|
||||||
reco_url="$(wget -qO- --show-progress $boards_url | python3 -c '
|
reco_url="$(wget -qO- --show-progress $boards_url | python3 -c '
|
||||||
import json, sys
|
import json, sys
|
||||||
|
|
||||||
|
@ -71,7 +87,7 @@ if "models" in board:
|
||||||
reco_url = list(board["pushRecoveries"].values())[-1]
|
reco_url = list(board["pushRecoveries"].values())[-1]
|
||||||
print(reco_url)
|
print(reco_url)
|
||||||
' $board)"
|
' $board)"
|
||||||
echo "found url: $reco_url"
|
print_info "found url: $reco_url"
|
||||||
|
|
||||||
shim_bin="$data_dir/shim_$board.bin"
|
shim_bin="$data_dir/shim_$board.bin"
|
||||||
shim_zip="$data_dir/shim_$board.zip"
|
shim_zip="$data_dir/shim_$board.zip"
|
||||||
|
@ -93,7 +109,7 @@ download_and_unzip() {
|
||||||
|
|
||||||
if [ ! -f "$bin_path" ]; then
|
if [ ! -f "$bin_path" ]; then
|
||||||
cleanup_path="$bin_path"
|
cleanup_path="$bin_path"
|
||||||
echo "extracting $zip_path"
|
print_info "extracting $zip_path"
|
||||||
local total_bytes="$(unzip -lq $zip_path | tail -1 | xargs | cut -d' ' -f1)"
|
local total_bytes="$(unzip -lq $zip_path | tail -1 | xargs | cut -d' ' -f1)"
|
||||||
if [ ! "$quiet" ]; then
|
if [ ! "$quiet" ]; then
|
||||||
unzip -p $zip_path | pv -s $total_bytes > $bin_path
|
unzip -p $zip_path | pv -s $total_bytes > $bin_path
|
||||||
|
@ -112,10 +128,10 @@ retry_cmd() {
|
||||||
done
|
done
|
||||||
}
|
}
|
||||||
|
|
||||||
echo "downloading recovery image"
|
print_title "downloading recovery image"
|
||||||
download_and_unzip $reco_url $reco_zip $reco_bin
|
download_and_unzip $reco_url $reco_zip $reco_bin
|
||||||
|
|
||||||
echo "downloading shim image"
|
print_title "downloading shim image"
|
||||||
download_and_unzip $shim_url $shim_zip $shim_bin
|
download_and_unzip $shim_url $shim_zip $shim_bin
|
||||||
|
|
||||||
if [ ! "$rootfs_dir" ]; then
|
if [ ! "$rootfs_dir" ]; then
|
||||||
|
@ -127,8 +143,8 @@ if [ ! "$rootfs_dir" ]; then
|
||||||
rm -rf $rootfs_dir
|
rm -rf $rootfs_dir
|
||||||
mkdir -p $rootfs_dir
|
mkdir -p $rootfs_dir
|
||||||
|
|
||||||
echo "building debian rootfs"
|
print_title "building debian rootfs"
|
||||||
./build_rootfs.sh $rootfs_dir bookworm \
|
./build_rootfs.sh $rootfs_dir $release \
|
||||||
custom_packages=$desktop_package \
|
custom_packages=$desktop_package \
|
||||||
hostname=shimboot-$board \
|
hostname=shimboot-$board \
|
||||||
username=user \
|
username=user \
|
||||||
|
@ -136,22 +152,22 @@ if [ ! "$rootfs_dir" ]; then
|
||||||
arch=$arch
|
arch=$arch
|
||||||
fi
|
fi
|
||||||
|
|
||||||
echo "patching debian rootfs"
|
print_title "patching debian rootfs"
|
||||||
retry_cmd ./patch_rootfs.sh $shim_bin $reco_bin $rootfs_dir "quiet=$quiet"
|
retry_cmd ./patch_rootfs.sh $shim_bin $reco_bin $rootfs_dir "quiet=$quiet"
|
||||||
|
|
||||||
echo "building final disk image"
|
print_title "building final disk image"
|
||||||
final_image="$data_dir/shimboot_$board.bin"
|
final_image="$data_dir/shimboot_$board.bin"
|
||||||
rm -rf $final_image
|
rm -rf $final_image
|
||||||
retry_cmd ./build.sh $final_image $shim_bin $rootfs_dir "quiet=$quiet" "arch=$arch"
|
retry_cmd ./build.sh $final_image $shim_bin $rootfs_dir "quiet=$quiet" "arch=$arch"
|
||||||
echo "build complete! the final disk image is located at $final_image"
|
print_info "build complete! the final disk image is located at $final_image"
|
||||||
|
|
||||||
echo "cleaning up"
|
print_title "cleaning up"
|
||||||
clean_loops
|
clean_loops
|
||||||
|
|
||||||
if [ "$compress_img" ]; then
|
if [ "$compress_img" ]; then
|
||||||
image_zip="$data_dir/shimboot_$board.zip"
|
image_zip="$data_dir/shimboot_$board.zip"
|
||||||
echo "compressing disk image into a zip file"
|
print_title "compressing disk image into a zip file"
|
||||||
zip -j $image_zip $final_image
|
zip -j $image_zip $final_image
|
||||||
echo "finished compressing the disk file"
|
print_info "finished compressing the disk file"
|
||||||
echo "the finished zip file can be found at $image_zip"
|
print_info "the finished zip file can be found at $image_zip"
|
||||||
fi
|
fi
|
|
@ -31,7 +31,7 @@ parse_args "$@"
|
||||||
rootfs_dir=$(realpath -m "${1}")
|
rootfs_dir=$(realpath -m "${1}")
|
||||||
release_name="${2}"
|
release_name="${2}"
|
||||||
packages="${args['custom_packages']-'task-xfce-desktop'}"
|
packages="${args['custom_packages']-'task-xfce-desktop'}"
|
||||||
arch="${args['arch']-'amd64'}"
|
arch="${args['arch']-amd64}"
|
||||||
chroot_mounts="proc sys dev run"
|
chroot_mounts="proc sys dev run"
|
||||||
|
|
||||||
mkdir -p $rootfs_dir
|
mkdir -p $rootfs_dir
|
||||||
|
|
|
@ -50,19 +50,19 @@ root_squashfs="$rootfs_dir/root.squashfs"
|
||||||
modules_squashfs="$rootfs_dir/modules.squashfs"
|
modules_squashfs="$rootfs_dir/modules.squashfs"
|
||||||
unionfs_dir="/tmp/unionfs-fuse"
|
unionfs_dir="/tmp/unionfs-fuse"
|
||||||
|
|
||||||
echo "compiling unionfs-fuse"
|
print_info "compiling unionfs-fuse"
|
||||||
compile_unionfs $unionfs_dir/unionfs $unionfs_dir
|
compile_unionfs $unionfs_dir/unionfs $unionfs_dir
|
||||||
|
|
||||||
echo "reading the shim image"
|
print_info "reading the shim image"
|
||||||
extract_initramfs_full $shim_path $rootfs_dir
|
extract_initramfs_full $shim_path $rootfs_dir
|
||||||
rm -rf $rootfs_dir/init
|
rm -rf $rootfs_dir/init
|
||||||
|
|
||||||
echo "compressing old rootfs"
|
print_info "compressing old rootfs"
|
||||||
mksquashfs $old_dir $root_squashfs -noappend -comp gzip
|
mksquashfs $old_dir $root_squashfs -noappend -comp gzip
|
||||||
|
|
||||||
echo "patching new rootfs"
|
print_info "patching new rootfs"
|
||||||
mv $unionfs_dir/unionfs $rootfs_dir/bin/unionfs
|
mv $unionfs_dir/unionfs $rootfs_dir/bin/unionfs
|
||||||
cp -ar squashfs/* $rootfs_dir/
|
cp -ar squashfs/* $rootfs_dir/
|
||||||
chmod +x $rootfs_dir/bin/*
|
chmod +x $rootfs_dir/bin/*
|
||||||
|
|
||||||
echo "done"
|
print_info "done"
|
26
common.sh
26
common.sh
|
@ -6,6 +6,12 @@ if [ "$DEBUG" ]; then
|
||||||
export DEBUG=1
|
export DEBUG=1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
ANSI_CLEAR='\033[0m'
|
||||||
|
ANSI_BOLD='\033[1m'
|
||||||
|
ANSI_RED='\033[1;31m'
|
||||||
|
ANSI_GREEN='\033[1;32m'
|
||||||
|
ANSI_BLUE='\033[1;34m'
|
||||||
|
|
||||||
check_deps() {
|
check_deps() {
|
||||||
local needed_commands="$1"
|
local needed_commands="$1"
|
||||||
for command in $needed_commands; do
|
for command in $needed_commands; do
|
||||||
|
@ -19,9 +25,9 @@ assert_deps() {
|
||||||
local needed_commands="$1"
|
local needed_commands="$1"
|
||||||
local missing_commands=$(check_deps "$needed_commands")
|
local missing_commands=$(check_deps "$needed_commands")
|
||||||
if [ "${missing_commands}" ]; then
|
if [ "${missing_commands}" ]; then
|
||||||
echo "You are missing dependencies needed for this script."
|
print_error "You are missing dependencies needed for this script."
|
||||||
echo "Commands needed:"
|
print_error "Commands needed:"
|
||||||
echo "${missing_commands}"
|
print_error "${missing_commands}"
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
@ -43,7 +49,7 @@ parse_args() {
|
||||||
|
|
||||||
assert_root() {
|
assert_root() {
|
||||||
if [ "$EUID" -ne 0 ]; then
|
if [ "$EUID" -ne 0 ]; then
|
||||||
echo "this needs to be run as root."
|
print_error "This script needs to be run as root."
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
@ -54,3 +60,15 @@ assert_args() {
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
|
print_title() {
|
||||||
|
printf ">> ${ANSI_GREEN}${1}${ANSI_CLEAR}\n"
|
||||||
|
}
|
||||||
|
|
||||||
|
print_info() {
|
||||||
|
printf "${ANSI_BOLD}${1}${ANSI_CLEAR}\n"
|
||||||
|
}
|
||||||
|
|
||||||
|
print_error() {
|
||||||
|
printf "${ANSI_RED}${1}${ANSI_CLEAR}\n"
|
||||||
|
}
|
|
@ -0,0 +1,58 @@
|
||||||
|
{
|
||||||
|
"nodes": {
|
||||||
|
"flake-parts": {
|
||||||
|
"inputs": {
|
||||||
|
"nixpkgs-lib": "nixpkgs-lib"
|
||||||
|
},
|
||||||
|
"locked": {
|
||||||
|
"lastModified": 1722555600,
|
||||||
|
"narHash": "sha256-XOQkdLafnb/p9ij77byFQjDf5m5QYl9b2REiVClC+x4=",
|
||||||
|
"owner": "hercules-ci",
|
||||||
|
"repo": "flake-parts",
|
||||||
|
"rev": "8471fe90ad337a8074e957b69ca4d0089218391d",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
|
"original": {
|
||||||
|
"owner": "hercules-ci",
|
||||||
|
"repo": "flake-parts",
|
||||||
|
"type": "github"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"nixpkgs": {
|
||||||
|
"locked": {
|
||||||
|
"lastModified": 1722791413,
|
||||||
|
"narHash": "sha256-rCTrlCWvHzMCNcKxPE3Z/mMK2gDZ+BvvpEVyRM4tKmU=",
|
||||||
|
"owner": "nixos",
|
||||||
|
"repo": "nixpkgs",
|
||||||
|
"rev": "8b5b6723aca5a51edf075936439d9cd3947b7b2c",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
|
"original": {
|
||||||
|
"owner": "nixos",
|
||||||
|
"ref": "nixos-24.05",
|
||||||
|
"repo": "nixpkgs",
|
||||||
|
"type": "github"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"nixpkgs-lib": {
|
||||||
|
"locked": {
|
||||||
|
"lastModified": 1722555339,
|
||||||
|
"narHash": "sha256-uFf2QeW7eAHlYXuDktm9c25OxOyCoUOQmh5SZ9amE5Q=",
|
||||||
|
"type": "tarball",
|
||||||
|
"url": "https://github.com/NixOS/nixpkgs/archive/a5d394176e64ab29c852d03346c1fc9b0b7d33eb.tar.gz"
|
||||||
|
},
|
||||||
|
"original": {
|
||||||
|
"type": "tarball",
|
||||||
|
"url": "https://github.com/NixOS/nixpkgs/archive/a5d394176e64ab29c852d03346c1fc9b0b7d33eb.tar.gz"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"root": {
|
||||||
|
"inputs": {
|
||||||
|
"flake-parts": "flake-parts",
|
||||||
|
"nixpkgs": "nixpkgs"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"root": "root",
|
||||||
|
"version": 7
|
||||||
|
}
|
|
@ -0,0 +1,29 @@
|
||||||
|
{
|
||||||
|
description = "k8s land";
|
||||||
|
|
||||||
|
inputs = {
|
||||||
|
nixpkgs.url = "github:nixos/nixpkgs/nixos-24.05";
|
||||||
|
|
||||||
|
flake-parts.url = "github:hercules-ci/flake-parts";
|
||||||
|
};
|
||||||
|
|
||||||
|
outputs = inputs @ {...}:
|
||||||
|
inputs.flake-parts.lib.mkFlake {inherit inputs;} {
|
||||||
|
flake = {};
|
||||||
|
|
||||||
|
systems = ["x86_64-linux"];
|
||||||
|
|
||||||
|
perSystem = {pkgs, system, ...}: {
|
||||||
|
_module.args.pkgs = import inputs.nixpkgs {
|
||||||
|
inherit system;
|
||||||
|
config.allowUnfree = true;
|
||||||
|
};
|
||||||
|
|
||||||
|
devShells.default = pkgs.mkShell {
|
||||||
|
packages = with pkgs; [
|
||||||
|
wget zip debootstrap vboot_reference binwalk pv
|
||||||
|
];
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
|
@ -119,9 +119,9 @@ populate_partitions() {
|
||||||
local rootfs_mount=/tmp/new_rootfs
|
local rootfs_mount=/tmp/new_rootfs
|
||||||
safe_mount "${image_loop}p4" $rootfs_mount
|
safe_mount "${image_loop}p4" $rootfs_mount
|
||||||
if [ "$quiet" ]; then
|
if [ "$quiet" ]; then
|
||||||
rsync --archive --human-readable --hard-links --quiet --sparse $rootfs_dir/ $rootfs_mount/
|
cp -ar $rootfs_dir/* $rootfs_mount
|
||||||
else
|
else
|
||||||
rsync --archive --human-readable --hard-links --info=progress2 --sparse $rootfs_dir/ $rootfs_mount/
|
copy_progress $rootfs_dir $rootfs_mount
|
||||||
fi
|
fi
|
||||||
umount $rootfs_mount
|
umount $rootfs_mount
|
||||||
}
|
}
|
||||||
|
@ -155,8 +155,14 @@ clean_loops() {
|
||||||
local mountpoints="$(cat /proc/mounts | grep "$loop_device")"
|
local mountpoints="$(cat /proc/mounts | grep "$loop_device")"
|
||||||
if [ ! "$mountpoints" ]; then
|
if [ ! "$mountpoints" ]; then
|
||||||
losetup -d $loop_device
|
losetup -d $loop_device
|
||||||
else
|
|
||||||
echo "warning: not removing $loop_device because it is still mounted"
|
|
||||||
fi
|
fi
|
||||||
done
|
done
|
||||||
}
|
}
|
||||||
|
|
||||||
|
copy_progress() {
|
||||||
|
local source="$1"
|
||||||
|
local destination="$2"
|
||||||
|
local total_bytes="$(du -sb "$source" | cut -f1)"
|
||||||
|
mkdir -p "$destination"
|
||||||
|
tar -cf - -C "${source}" . | pv -f -s $total_bytes | tar -xf - -C "${destination}"
|
||||||
|
}
|
||||||
|
|
|
@ -39,7 +39,7 @@ apt-get install -y ca-certificates
|
||||||
apt-get update
|
apt-get update
|
||||||
installed_systemd="$(dpkg-query -W -f='${binary:Package}\n' | grep "systemd")"
|
installed_systemd="$(dpkg-query -W -f='${binary:Package}\n' | grep "systemd")"
|
||||||
apt-get clean
|
apt-get clean
|
||||||
apt-get install --reinstall $installed_systemd
|
apt-get install -y --reinstall --allow-downgrades $installed_systemd
|
||||||
|
|
||||||
#enable shimboot services
|
#enable shimboot services
|
||||||
systemctl enable kill-frecon.service
|
systemctl enable kill-frecon.service
|
||||||
|
|
|
@ -2,6 +2,14 @@
|
||||||
|
|
||||||
#utilties for reading shim disk images
|
#utilties for reading shim disk images
|
||||||
|
|
||||||
|
run_binwalk() {
|
||||||
|
if binwalk -h | grep -- '--run-as' >/dev/null; then
|
||||||
|
binwalk "$@" --run-as=root
|
||||||
|
else
|
||||||
|
binwalk "$@"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
#extract the initramfs from a kernel image
|
#extract the initramfs from a kernel image
|
||||||
extract_initramfs() {
|
extract_initramfs() {
|
||||||
local kernel_bin="$1"
|
local kernel_bin="$1"
|
||||||
|
@ -10,13 +18,13 @@ extract_initramfs() {
|
||||||
|
|
||||||
#extract the compressed kernel image from the partition data
|
#extract the compressed kernel image from the partition data
|
||||||
local kernel_file="$(basename $kernel_bin)"
|
local kernel_file="$(basename $kernel_bin)"
|
||||||
local binwalk_out=$(binwalk --extract $kernel_bin --directory=$working_dir --run-as=root)
|
local binwalk_out=$(run_binwalk --extract $kernel_bin --directory=$working_dir)
|
||||||
local stage1_file=$(echo $binwalk_out | pcregrep -o1 "\d+\s+0x([0-9A-F]+)\s+gzip compressed data")
|
local stage1_file=$(echo $binwalk_out | pcregrep -o1 "\d+\s+0x([0-9A-F]+)\s+gzip compressed data")
|
||||||
local stage1_dir="$working_dir/_$kernel_file.extracted"
|
local stage1_dir="$working_dir/_$kernel_file.extracted"
|
||||||
local stage1_path="$stage1_dir/$stage1_file"
|
local stage1_path="$stage1_dir/$stage1_file"
|
||||||
|
|
||||||
#extract the initramfs cpio archive from the kernel image
|
#extract the initramfs cpio archive from the kernel image
|
||||||
binwalk --extract $stage1_path --directory=$stage1_dir --run-as=root > /dev/null
|
run_binwalk --extract $stage1_path --directory=$stage1_dir > /dev/null
|
||||||
local stage2_dir="$stage1_dir/_$stage1_file.extracted/"
|
local stage2_dir="$stage1_dir/_$stage1_file.extracted/"
|
||||||
local cpio_file=$(file $stage2_dir/* | pcregrep -o1 "([0-9A-F]+):\s+ASCII cpio archive")
|
local cpio_file=$(file $stage2_dir/* | pcregrep -o1 "([0-9A-F]+):\s+ASCII cpio archive")
|
||||||
local cpio_path="$stage2_dir/$cpio_file"
|
local cpio_path="$stage2_dir/$cpio_file"
|
||||||
|
@ -31,7 +39,7 @@ extract_initramfs_arm() {
|
||||||
local output_dir="$3"
|
local output_dir="$3"
|
||||||
|
|
||||||
#extract the kernel lz4 archive from the partition
|
#extract the kernel lz4 archive from the partition
|
||||||
local binwalk_out="$(binwalk $kernel_bin --run-as=root)"
|
local binwalk_out="$(run_binwalk $kernel_bin)"
|
||||||
local lz4_offset="$(echo "$binwalk_out" | pcregrep -o1 "(\d+).+?LZ4 compressed data" | head -n1)"
|
local lz4_offset="$(echo "$binwalk_out" | pcregrep -o1 "(\d+).+?LZ4 compressed data" | head -n1)"
|
||||||
local lz4_file="$working_dir/kernel.lz4"
|
local lz4_file="$working_dir/kernel.lz4"
|
||||||
local kernel_img="$working_dir/kernel_decompressed.bin"
|
local kernel_img="$working_dir/kernel_decompressed.bin"
|
||||||
|
@ -40,7 +48,7 @@ extract_initramfs_arm() {
|
||||||
|
|
||||||
#extract the initramfs cpio archive from the kernel image
|
#extract the initramfs cpio archive from the kernel image
|
||||||
local extracted_dir="$working_dir/_kernel_decompressed.bin.extracted"
|
local extracted_dir="$working_dir/_kernel_decompressed.bin.extracted"
|
||||||
binwalk --extract $kernel_img --directory=$working_dir --run-as=root > /dev/null
|
run_binwalk --extract $kernel_img --directory=$working_dir > /dev/null
|
||||||
local cpio_file=$(file $extracted_dir/* | pcregrep -o1 "([0-9A-F]+):\s+ASCII cpio archive")
|
local cpio_file=$(file $extracted_dir/* | pcregrep -o1 "([0-9A-F]+):\s+ASCII cpio archive")
|
||||||
local cpio_path="$extracted_dir/$cpio_file"
|
local cpio_path="$extracted_dir/$cpio_file"
|
||||||
|
|
||||||
|
|
Binary file not shown.
After Width: | Height: | Size: 1.8 MiB |
Binary file not shown.
After Width: | Height: | Size: 2.3 MiB |
Loading…
Reference in New Issue