Skip to content

Commit

Permalink
Merge branch 'dev'
Browse files Browse the repository at this point in the history
  • Loading branch information
ading2210 committed Aug 28, 2024
2 parents e9f4759 + 62d9244 commit 6fe2192
Show file tree
Hide file tree
Showing 13 changed files with 434 additions and 63 deletions.
70 changes: 55 additions & 15 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,24 @@ Shimboot is a collection of scripts for patching a Chrome OS RMA shim to serve a
| ----- | ----- |
| Shimboot (KDE) on an HP Chromebook 11 G9 EE | Shimboot (XFCE) on an Acer Chromebook 311 C722 |

## Table of Contents:
- [Features](#features)
- [About](#about)
* [Partition Layout](#partition-layout)
- [Status](#status)
* [Device Compatibility Table](#device-compatibility-table)
* [TODO](#todo)
- [Usage](#usage)
* [Prerequisites](#prerequisites)
* [Video Tutorial](#video-tutorial)
* [Build Instructions](#build-instructions)
* [Booting the Image](#booting-the-image)
- [FAQ](#faq)
- [Copyright](#copyright)
* [Copyright Notice](#copyright-notice)

<small><i>Table of contents generated with <a href='http://ecotrust-canada.github.io/markdown-toc/'>markdown-toc</a></i>.</small>

## Features:
- Run a full Debian installation on a Chromebook
- Does not modify the firmware
Expand Down Expand Up @@ -95,36 +113,51 @@ PRs and contributions are welcome to help implement these features.

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.
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.
4. Run `mkdir -p data/rootfs` to create a directory to hold the rootfs.
5. Run `sudo ./build_rootfs.sh data/rootfs bookworm` to build the base rootfs.
6. Run `sudo ./patch_rootfs.sh path_to_shim path_to_reco data/rootfs` to patch the base rootfs and add any needed drivers.
7. Run `sudo ./build.sh image.bin path_to_shim data/rootfs` to generate a disk image at `image.bin`.

[Prebuilt images](https://github.com/ading2210/shimboot/releases) are available if you don't have a suitable device to run the build on.

<details>
<summary><b>Alternatively, you can run each of the steps manually:</b></summary>

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.
3. Unzip the shim and the recovery image if you have not done so already.
4. Run `mkdir -p data/rootfs` to create a directory to hold the rootfs.
5. Run `sudo ./build_rootfs.sh data/rootfs bookworm` to build the base rootfs.
6. Run `sudo ./patch_rootfs.sh path_to_shim path_to_reco data/rootfs` to patch the base rootfs and add any needed drivers.
7. Run `sudo ./build.sh image.bin path_to_shim data/rootfs` to generate a disk image at `image.bin`.
</details>

### Booting the Image:
1. Obtain a shimboot image by downloading a [prebuilt one](https://github.com/ading2210/shimboot/releases) or building it yourself.
2. Flash the shimboot image to a USB drive or SD card. Use the [Chromebook Recovery Utility](https://chrome.google.com/webstore/detail/chromebook-recovery-utili/pocpnlppkickgojjlmhdmidojbmbodfm) or [dd](https://linux.die.net/man/1/dd) if you're on Linux.
3. Enable developer mode on your Chromebook. If the Chromebook is enrolled, follow the instructions on the [sh1mmer website](https://sh1mmer.me) (see the "Executing on Chromebook" section).
4. Plug the USB into your Chromebook and enter recovery mode. It should detect the USB and run the shimboot bootloader.
5. Boot into Debian and log in with the username and password that you configured earlier. The default username/password for the prebuilt images is `user/user`.
6. Expand the rootfs partition so that it fills up the entire disk by running `sudo growpart /dev/sdX 4` (replacing `sdX` with the block device corresponding to your disk) to expand the partition, then running `sudo resize2fs /dev/sdX4` to expand the filesystem.
7. Change the user password by running `passwd user`. The root user is disabled by default.
6. Expand the rootfs partition so that it fills up the entire disk by running `sudo expand_rootfs`.
7. Change your own password by running `passwd user`. The root user is disabled by default.

## FAQ:

#### 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`.

Here is a list of distros that are supported out of the box:
- Debian 12
- Debian Unstable
- Alpine Linux

PRs to enable support for other distros are welcome.

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
sudo ./build_complete.sh dedede release=unstable
```

There is also experimental support for Alpine Linux. The Alpine disk image is about half the size compared to Debian, although some applications are missing. Pass the `distro=alpine` to use it:
```bash
sudo ./build_complete.sh dedede distro=alpine
```

#### How can I install a desktop environment other than XFCE?
You can pass the `desktop` argument to the `build_complete.sh` script, like this:
```bash
Expand All @@ -138,10 +171,12 @@ Shimboot does not touch the internal storage at all, so you will be able to use
#### Can I unplug the USB drive while using Debian?
By default, this is not possible. However, you can simply copy your Debian rootfs onto your internal storage by first using `fdisk` to repartition it, using `dd` to copy the partition, and `resize2fs` to have it take up the entire drive. In the future, loading the OS to RAM may be supported, but this isn't a priority at the moment. You can also just blindly copy the contents of your Shimboot USB to the internal storage without bothering to repartition:
```bash
#assuming the usb drive is on sda and internal storage is on mmcblk1
sudo dd if=/dev/sda of=/dev/mmcblk1 bs=1M oflag=direct status=progress
sudo growpart /dev/mmcblk1 4
sudo resize2fs /dev/mmcblk1p4
#check the output of this to know what disk you're copying to and from
fdisk -l

#run this from within the shimboot bootloader
#this assumes the usb drive is on sda and internal storage is on mmcblk1
dd if=/dev/sda of=/dev/mmcblk1 bs=1M oflag=direct status=progress
```

#### GPU acceleration isn't working, how can I fix this?
Expand Down Expand Up @@ -174,6 +209,11 @@ $ nmcli connection edit <your connection name>
> activate
```

#### Steam doesn't work.
Steam should be installed using the `sudo apt install steam` command, however it doesn't work out of the box due to security features in the shim kernel preventing the `bwrap` library from working. See [issue #12](https://github.com/ading2210/shimboot/issues/26#issuecomment-2151893062) for more info.

To get Steam running, install and run it normally. It will fail and show a message saying that "Steam now requires user namespaces to be enabled." Run `fix_bwrap` in your terminal, relaunch Steam, and it should be working again.

## Copyright:
Shimboot is licensed under the [GNU GPL v3](https://www.gnu.org/licenses/gpl-3.0.txt). Unless otherwise indicated, all code has been written by me, [ading2210](https://github.com/ading2210).

Expand Down
13 changes: 12 additions & 1 deletion bootloader/bin/bootstrap.sh
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@
#set -x
set +x

SHIMBOOT_VERSION="v1.2.0"

invoke_terminal() {
local tty="$1"
local title="$2"
Expand Down Expand Up @@ -93,8 +95,11 @@ move_mounts() {
}

print_license() {
if [ -f "/opt/.shimboot_version_dev" ]; then
suffix="-dev"
fi
cat << EOF
Shimboot v1.1.1
Shimboot ${SHIMBOOT_VERSION}${suffix}
ading2210/shimboot: Boot desktop Linux from a Chrome OS RMA shim.
Copyright (C) 2023 ading2210
Expand Down Expand Up @@ -265,6 +270,12 @@ boot_target() {
echo "moving mounts to newroot"
mkdir /newroot
mount $target /newroot
#bind mount /dev/console to show systemd boot msgs
if [ -f "/bin/frecon-lite" ]; then
rm -f /dev/console
touch /dev/console #this has to be a regular file otherwise the system crashes afterwards
mount -o bind "$TTY1" /dev/console
fi
move_mounts /newroot

echo "switching root"
Expand Down
11 changes: 8 additions & 3 deletions build.sh
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ print_help() {
echo "Valid named arguments (specify with 'key=value'):"
echo " quiet - Don't use progress indicators which may clog up log files."
echo " arch - Set this to 'arm64' to specify that the shim is for an ARM chromebook."
echo " name - The name for the shimboot rootfs partition."
}

assert_root
Expand All @@ -22,11 +23,15 @@ output_path=$(realpath -m "${1}")
shim_path=$(realpath -m "${2}")
rootfs_dir=$(realpath -m "${3}")

quiet="${args['quiet']}"
arch="${args['arch']}"
name="${args['name']}"

print_info "reading the shim image"
initramfs_dir=/tmp/shim_initramfs
kernel_img=/tmp/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 "$arch"

print_info "patching initramfs"
patch_initramfs $initramfs_dir
Expand All @@ -36,7 +41,7 @@ rootfs_size=$(du -sm $rootfs_dir | cut -f 1)
rootfs_part_size=$(($rootfs_size * 12 / 10 + 5))
#create a 20mb bootloader partition
#rootfs partition is 20% larger than its contents
create_image $output_path 20 $rootfs_part_size
create_image $output_path 20 $rootfs_part_size $name

print_info "creating loop device for the image"
image_loop=$(create_loop ${output_path})
Expand All @@ -45,7 +50,7 @@ print_info "creating partitions on the disk image"
create_partitions $image_loop $kernel_img

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 "$quiet"
rm -rf $initramfs_dir $kernel_img

print_info "cleaning up loop devices"
Expand Down
43 changes: 37 additions & 6 deletions build_complete.sh
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ print_help() {
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 " release - Set this to either 'bookworm' or 'unstable' to build for Debian stable/unstable."
echo " distro - The Linux distro to use. This should be either 'debian', 'ubuntu', or 'alpine'."
}

assert_root
Expand All @@ -29,7 +30,8 @@ quiet="${args['quiet']}"
desktop="${args['desktop']-'xfce'}"
data_dir="${args['data_dir']}"
arch="${args['arch']-amd64}"
release="${args['release']-bookworm}"
release="${args['release']}"
distro="${args['distro']-debian}"

#a list of all arm board names
arm_boards="
Expand Down Expand Up @@ -102,7 +104,12 @@ reco_url="$(wget -qO- --show-progress $boards_url | python3 -c '
import json, sys
all_builds = json.load(sys.stdin)
board = all_builds["builds"][sys.argv[1]]
board_name = sys.argv[1]
if not board_name in all_builds["builds"]:
print("Invalid board name: " + board_name, file=sys.stderr)
sys.exit(1)
board = all_builds["builds"][board_name]
if "models" in board:
for device in board["models"].values():
if device["pushRecoveries"]:
Expand Down Expand Up @@ -159,22 +166,46 @@ download_and_unzip $reco_url $reco_zip $reco_bin
print_title "downloading shim image"
download_and_unzip $shim_url $shim_zip $shim_bin

print_title "building $distro rootfs"
if [ ! "$rootfs_dir" ]; then
rootfs_dir="$(realpath -m data/rootfs_$board)"
desktop_package="task-$desktop-desktop"
rootfs_dir="$(realpath -m data/rootfs_$board)"
if [ "$(findmnt -T "$rootfs_dir/dev")" ]; then
sudo umount -l $rootfs_dir/* 2>/dev/null || true
fi
rm -rf $rootfs_dir
mkdir -p $rootfs_dir

print_title "building debian rootfs"
if [ "$distro" = "debian" ]; then
release="${release:-bookworm}"
elif [ "$distro" = "ubuntu" ]; then
release="${release:-noble}"
elif [ "$distro" = "alpine" ]; then
release="${release:-edge}"
else
print_error "invalid distro selection"
exit 1
fi

#install a newer debootstrap version if needed
if [ -f "/etc/debian_version" ] && [ "$distro" = "ubuntu" -o "$distro" = "debian" ]; then
if [ ! -f "/usr/share/debootstrap/scripts/$release" ]; then
print_info "installing newer debootstrap version"
mirror_url="https://deb.debian.org/debian/pool/main/d/debootstrap/"
deb_file="$(curl "https://deb.debian.org/debian/pool/main/d/debootstrap/" | pcregrep -o1 'href="(debootstrap_.+?\.deb)"' | tail -n1)"
deb_url="${mirror_url}${deb_file}"
wget -q --show-progress "$deb_url" -O "/tmp/$deb_file"
apt-get install -y "/tmp/$deb_file"
fi
fi

./build_rootfs.sh $rootfs_dir $release \
custom_packages=$desktop_package \
hostname=shimboot-$board \
username=user \
user_passwd=user \
arch=$arch
arch=$arch \
distro=$distro
fi

print_title "patching debian rootfs"
Expand All @@ -183,7 +214,7 @@ retry_cmd ./patch_rootfs.sh $shim_bin $reco_bin $rootfs_dir "quiet=$quiet"
print_title "building final disk image"
final_image="$data_dir/shimboot_$board.bin"
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" "name=$distro"
print_info "build complete! the final disk image is located at $final_image"

print_title "cleaning up"
Expand Down
Loading

0 comments on commit 6fe2192

Please sign in to comment.