{"id":17920890,"url":"https://github.com/eth-p/openwrt-abpp","last_synced_at":"2025-10-30T21:35:26.742Z","repository":{"id":224691357,"uuid":"762671607","full_name":"eth-p/openwrt-abpp","owner":"eth-p","description":"OpenWrt A/B Partition Project (for x86_64 Systems)","archived":false,"fork":false,"pushed_at":"2024-05-16T01:37:38.000Z","size":29,"stargazers_count":2,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-02-09T00:31:40.593Z","etag":null,"topics":["openwrt","openwrt-configuration"],"latest_commit_sha":null,"homepage":"","language":"Shell","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/eth-p.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2024-02-24T11:15:41.000Z","updated_at":"2025-01-25T05:05:15.000Z","dependencies_parsed_at":"2024-02-27T10:10:50.492Z","dependency_job_id":"3361e5dd-94b0-48c5-887e-b6b9a74b7da3","html_url":"https://github.com/eth-p/openwrt-abpp","commit_stats":null,"previous_names":["eth-p/openwrt-abpp"],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/eth-p%2Fopenwrt-abpp","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/eth-p%2Fopenwrt-abpp/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/eth-p%2Fopenwrt-abpp/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/eth-p%2Fopenwrt-abpp/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/eth-p","download_url":"https://codeload.github.com/eth-p/openwrt-abpp/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":246989753,"owners_count":20865331,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["openwrt","openwrt-configuration"],"created_at":"2024-10-28T20:29:31.236Z","updated_at":"2025-10-30T21:35:21.682Z","avatar_url":"https://github.com/eth-p.png","language":"Shell","funding_links":[],"categories":[],"sub_categories":[],"readme":"# OpenWrt A/B Partition Project\nThis is a project that enables [OpenWrt](https://openwrt.org/) to be installed using an A/B partition scheme.\n\n\u003e[!caution]\n\u003e The OpenWrt A/B Partition Project is designed for x86_64 systems.  \n\u003e It will *probably not work* for other architectures without modification.\n\n## Requirements\n\n* A Linux live USB stick with `wget`/`curl`, along with both `parted` and `fdisk`.\n* A computer to install OpenWrt to, with at least 8 GiB of storage.\n\n## Installation\n\nThe initial setup for OpenWrt A/B partitioning is entirely manual.  \nPlease follow these instructions carefully.\n\n### Base OpenWrt Installation\n\n(Start by booting up your device with the Linux live USB stick.)\n\nFirst, you will need to download (or copy) both the `generic-squashfs-combined-efi` and\n`generic-squashfs-rootfs` images.\n\n```bash\nwget \"https://archive.openwrt.org/releases/23.05.1/targets/x86/64/openwrt-23.05.1-x86-64-generic-squashfs-combined-efi.img.gz\"\nwget \"https://archive.openwrt.org/releases/23.05.1/targets/x86/64/openwrt-23.05.1-x86-64-generic-squashfs-rootfs.img.gz\"\n```\n\nThe next step is to identify the internal storage device to install OpenWrt on:\n\n```bash\nlsblk\n# NAME      MAJ:MIN RM   SIZE RO TYPE MOUNTPOINTS\n# loop0       7:0    0 766.5M  1 loop /run/archiso/airootfs\n# sda         8:0    0  29.8G  0 disk\n# ├─sda1      8:1    0    16M  0 part\n# └─sda2      8:2    0  29.7G  0 part\n# sdb         8:16   0   1.9G  0 disk\n# ├─sdb1      8:17   0   917M  0 part\n# └─sdb2      8:18   0    15G  0 part\n```\n\nIf you are not sure which device is what, `ls -l /dev/disk/by-id` may help:\n\n```bash\nls -l /dev/disk/by-id\n# total 0\n# lrwxrwxrwx 1 root root  9 Feb 27 13:00 ata-DEVICE_NAME_DEVICE_SERIAL -\u003e ../../sda\n# lrwxrwxrwx 1 root root  9 Feb 27 13:00 ata-DEVICE_NAME_DEVICE_SERIAL-part1 -\u003e ../../sda1\n# lrwxrwxrwx 1 root root  9 Feb 27 13:00 ata-DEVICE_NAME_DEVICE_SERIAL-part2 -\u003e ../../sda2\n# lrwxrwxrwx 1 root root  9 Feb 27 13:00 usb-USBSTICK_NAME_DEVICE_SERIAL -\u003e ../../sdb\n# lrwxrwxrwx 1 root root  9 Feb 27 13:00 usb-USBSTICK_NAME_DEVICE_SERIAL-part1 -\u003e ../../sdb1\n# lrwxrwxrwx 1 root root  9 Feb 27 13:00 usb-USBSTICK_NAME_DEVICE_SERIAL-part2 -\u003e ../../sdb2\n```\n\nOnce you determine which disk to install to, flash the uncompressed `-combined-efi` image to it:\n\n```bash\ngunzip -c *-combined-efi.img.gz | dd of=/dev/sda status=progress\n```\n\n### A/B OpenWrt Modification\n\nWith the base installation complete, you will need to modify it to support an A/B partition scheme.\n\nFirst, you will need to update the partition table using `fdisk`.  \nRemove partition 2 and replace it with the following three partitions:\n\n| Partition ID | Size | Filesystem Type |\n|:--|:--|:--|\n| 2 | 200+ MiB | Microsoft basic data (type 11) |\n| 10 | 50% remaining space | Linux filesystem (type 20) |\n| 11 | 50% remaining space | Linux filesystem (type 20) |\n\nNext, use `parted` to rename each of the partitions:\n\n| Partition ID | Name |\n|:--|:--|\n| 2 | Persistent |\n| 10 | OpenWrt-A |\n| 11 | OpenWrt-B |\n\n\u003e[!important]\n\u003e Partition `10` and `11` **must** be named `OpenWrt-A` and `OpenWrt-B` respectively.  \n\u003e The partition name is used by `abupgrade` to detect which partition to flash.\n\nYou will need the partition UUIDs for `OpenWrt-A` later, so make sure to\nfind it using `blkid` and write it down:\n\n```bash\nblkid | grep 'OpenWrt-A'\n# ...\n#                                                                                 vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv\n# /dev/sda10: BLOCK_SIZE=\"262144\" TYPE=\"squashfs\" PARTLABEL=\"OpenWrt-A\" PARTUUID=\"38fe120b-f6d5-4921-888d-1ffa0b1bc370\"\n```\n\nNow you will need to re-flash the root filesystem to partition 10:\n\n```bash\ngunzip -c *-rootfs.img.gz | dd of=/dev/sda10 status=progress\n```\n\nAfter this, you will want to create a filesystem on partition 2 using `mkfs.vfat`.\nThis will be where you store `openwrt-abpp`.\n\n#### GRUB Changes\n\nFinally, you will need to rename the kernel image and update the GRUB configuration.\nThe `grub.cfg` file is located on partition 1.\n\n```bash\nmkdir -p /mnt/efi\nmount -t vfat /dev/sda1 /mnt/efi\nmv /mnt/efi/boot/vmlinuz /mnt/efi/boot/vmlinuz-a\nnano /mnt/efi/boot/grub/grub.cfg\n```\n\nThe original GRUB config will like something like this:\n\n```perl\nserial --unit=0 --speed=115200 --word=8 --parity=no --stop=1 --rtscts=off\nterminal_input console serial; terminal_output console serial\n\nset default=\"0\"\nset timeout=\"5\"\nsearch -l kernel -s root\n\nmenuentry \"OpenWrt\" {\n        linux /boot/vmlinuz root=PARTUUID=abcdef01-2345-6789-abcd-ef0123456789 rootwait console=ttyS0,115200n8 noinitrd\n}\n\nmenuentry \"OpenWrt (failsafe)\" {\n        linux /boot/vmlinuz failsafe=true root=PARTUUID=abcdef01-2345-6789-abcd-ef0123456789 rootwait console=ttyS0,115200n8 noinitrd\n}\n```\n\n\u003e[!tip]\n\u003e If your device does not have a serial interface, [you will want to comment out the `serial` and `terminal_input`lines](https://forum.openwrt.org/t/solved-boot-hangs-on-lede-item-in-grub-menu-on-x86-no-grub-timeout/24741/10).\n\nYou will need to convert this into a template.\n\n 1. Copy the first non-failsafe `menuentry` to the end of the file.\n 2. Prepend a `#` to the beginning of each line of the original `menuentry` blocks.\n 3. Surround the original menuentry blocks with:\n    \n    ```\n    ###----- BEGIN ABPP TEMPLATE -----###\n    ###----- END ABPP TEMPLATE -----###\n    ```\n\n    This will now be the template section.\n\n 4. In the template section:\n     * Append `-${LETTER}` after `/boot/vmlinuz`.\n     * Append ` ${VERSION}` after `\"OpenWrt\"`.\n     * Replace `root=PARTUUID=...` with `root=${PARTITION}`\n\n 5. Surround the copied menuentry with:\n    \n    ```\n    ###----- BEGIN ABPP GENERATED -----###\n    ###----- END ABPP GENERATED -----###\n    ```\n\n    This will be the generated section.\n\n 6. In the generated section:\n     * Update the `PARTUUID` to the UUID recorded earlier.\n     * Append `-a` after `/boot/vmlinuz`.\n\n\u003e[!caution]\n\u003e It is **critical** that the section markers have the exact spacing and number of `#` and `-` characters.\n\u003e\n\u003e The section markers are used to update the GRUB configuration after upgrades, and it will not be possible to do\n\u003e automatically unless those exact strings are found in the file.\n\nAfter you are finished, it should look similar to this:\n\n```perl\n# serial --unit=0 --speed=115200 --word=8 --parity=no --stop=1 --rtscts=off\n# terminal_input console serial; terminal_output console serial\n\nset default=\"0\"\nset timeout=\"5\"\nsearch -l kernel -s root\n\n###----- BEGIN ABPP TEMPLATE -----###\n# menuentry \"OpenWrt ${VERSION}\" {\n#         linux /boot/vmlinuz-${LETTER} root=${PARTITION} rootwait console=ttyS0,115200n8 noinitrd\n# }\n# \n# menuentry \"OpenWrt ${VERSION} (failsafe)\" {\n#         linux /boot/vmlinuz failsafe=true root=${PARTITION} rootwait console=ttyS0,115200n8 noinitrd\n# }\n###----- END ABPP TEMPLATE -----###\n\n###----- BEGIN ABPP GENERATED -----###\nmenuentry \"OpenWrt\" {\n        linux /boot/vmlinuz-a root=PARTUUID=38fe120b-f6d5-4921-888d-1ffa0b1bc370 rootwait console=ttyS0,115200n8 noinitrd\n}\n###----- END ABPP GENERATED -----###\n```\n\nYou may now reboot into OpenWrt.\n\n### Changes within OpenWrt\n\nOnce you have booted into OpenWrt and have internet connectivity, you will need to\ninstall the following packages using `opkg`:\n\n * `blkid`\n * `block-mount`\n * `dumb-init`\n * `kmod-fs-squashfs`\n * `kmod-fs-vfat`\n * `losetup`\n * `nsenter`\n * `parted`\n * `squashfs-tools-unsquashfs`\n * `unshare`\n\nAfter installing the packages, configure partition 2\n[to be mounted on startup](https://openwrt.org/docs/guide-user/storage/fstab).\n\nFinally, download [a tarball of this repo](https://github.com/eth-p/openwrt-abpp/archive/refs/heads/master.tar.gz) and\nextract somewhere within partition 2.\n\nYou are now done! 🚀\n\n## Usage\n\nTo flash a version of OpenWrt to the inactive partition, run the downloaded `/path/to/openwrt-abpp/bin/abupgrade`\nscript. It will:\n\n * Let you select a version to flash.\n * Download the rootfs.\n * Flash the rootfs to the alternate partition.\n * Copy your configuration (using `sysupgrade -b`) to the alternate partition.\n * Download your currently-installed packages to the alternate partition.\n * Update GRUB to automatically select the newly-flashed partition.\n\nOnce you reboot into the newly-flashed partition, openwrt-abpp will restore your configuration, install your packages,\nand trigger a reboot to finalize everything.\n\n## How it Works\n\nEssentially, it flashes a new OpenWrt installation and copies/downloads your changes to it.\n\nBehind the scenes, it involves:\n * Re-implementing OpenWrt's overlay filesystem initialization code using shell scripts.\n * Creating an extremely lightweight Linux container using `unshare`, `nsenter`, and `dumb-init`.\n * Using the container to run `opkg` within the newly-flashed installation.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Feth-p%2Fopenwrt-abpp","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Feth-p%2Fopenwrt-abpp","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Feth-p%2Fopenwrt-abpp/lists"}