├── .generate_device_recipe.py.kate-swp ├── .gitattributes ├── .github └── workflows │ ├── push.yml.disabled │ └── release.yml ├── .gitignore ├── .gitmodules ├── README.md ├── apt └── .dummy ├── devices.yml └── generate_recipe.py /.generate_device_recipe.py.kate-swp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Linux-on-droid/lindroid-rootfs/3260c7e303b83476097418d1e681bb011f036ef2/.generate_device_recipe.py.kate-swp -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | *.deb filter=lfs diff=lfs merge=lfs -text 2 | -------------------------------------------------------------------------------- /.github/workflows/push.yml.disabled: -------------------------------------------------------------------------------- 1 | name: droidian rootfs test build 2 | 3 | on: 4 | push: 5 | branches: 6 | - '**' 7 | tags-ignore: 8 | - '**' 9 | 10 | jobs: 11 | build: 12 | runs-on: ubuntu-20.04 13 | 14 | strategy: 15 | fail-fast: true 16 | matrix: 17 | arch: [amd64] 18 | template: [rootfs-builder] 19 | dist: [bookworm] 20 | namespace: [droidian] 21 | debos_arch: [amd64,armhf,arm64] 22 | 23 | name: ${{ matrix.template }}:${{ matrix.dist }} on ${{ matrix.debos_arch }} 24 | 25 | steps: 26 | - name: Get current date 27 | run: echo "current_date=$(date +'%Y%m%d')" >> $GITHUB_ENV 28 | 29 | - name: Set suffix 30 | run: echo "release_suffix=_${{ env.current_date }}" >> $GITHUB_ENV 31 | 32 | - name: Checkout 33 | uses: actions/checkout@v2 34 | 35 | - name: Checkout submodules 36 | run: git submodule update --init --recursive 37 | 38 | - name: QEMU set-up 39 | uses: docker/setup-qemu-action@v1 40 | 41 | - name: Create build dir 42 | run: mkdir -p /tmp/buildd-results 43 | 44 | - name: Pull container 45 | run: docker pull quay.io/${{ matrix.namespace }}/${{ matrix.template }}:${{ matrix.dist }}-${{ matrix.arch }} 46 | 47 | - name: Start Container 48 | run: echo CONTAINER_HASH=$(docker run --detach --privileged -v /tmp/buildd-results:/buildd -v /dev:/dev -v /sys/fs/cgroup:/sys/fs/cgroup -v ${PWD}:/buildd/sources --security-opt seccomp:unconfined quay.io/${{ matrix.namespace }}/${{ matrix.template }}:${{ matrix.dist }}-${{ matrix.arch }} /sbin/init) >> $GITHUB_ENV 49 | 50 | - name: Build rootfs 51 | run: docker exec $CONTAINER_HASH /bin/sh -c 'cd /buildd/sources; debos -t architecture:${{ matrix.debos_arch }} -t suffix:${{ env.release_suffix }} -t version:nightly device.yml' 52 | 53 | -------------------------------------------------------------------------------- /.github/workflows/release.yml: -------------------------------------------------------------------------------- 1 | name: lindroid rootfs-builder 2 | 3 | on: 4 | workflow_dispatch: 5 | push: 6 | branches: 7 | - trixie 8 | schedule: 9 | - cron: "59 23 * * *" 10 | 11 | jobs: 12 | once: 13 | runs-on: ubuntu-24.04 14 | name: Generate matrix 15 | outputs: 16 | matrix: ${{ steps.gen-matrix.outputs.matrix }} 17 | 18 | steps: 19 | - name: Checkout 20 | uses: actions/checkout@v2 21 | 22 | - name: Generate matrix 23 | id: gen-matrix 24 | run: | 25 | JOBS="$(./generate_recipe.py --matrix)" 26 | echo ::set-output name=matrix::${JOBS} 27 | 28 | build: 29 | runs-on: ubuntu-24.04 30 | needs: once 31 | 32 | strategy: 33 | fail-fast: true 34 | matrix: 35 | config: ${{ fromJson(needs.once.outputs.matrix) }} 36 | 37 | name: ${{ matrix.config.job_name }} 38 | 39 | steps: 40 | - name: Get current date 41 | run: echo "current_date=$(date +'%Y%m%d')" >> $GITHUB_ENV 42 | 43 | - name: Set suffix 44 | run: echo "release_suffix=_${{ env.current_date }}" >> $GITHUB_ENV 45 | 46 | - name: Set nightly version 47 | if: startsWith(github.ref, 'refs/tags/lindroid') != true 48 | run: echo "LINDROID_VERSION=nightly" >> $GITHUB_ENV 49 | 50 | - name: Set version 51 | if: startsWith(github.ref, 'refs/tags/lindroid') == true 52 | run: echo "LINDROID_VERSION=$(echo ${{ github.ref }} | rev | cut -d'/' -f1 | rev)" >> $GITHUB_ENV 53 | 54 | - name: Set identifier 55 | run: echo "LINDROID_IDENTIFIER=${{ matrix.config.arch }}-${{ matrix.config.edition }}" >> $GITHUB_ENV 56 | 57 | - name: Checkout 58 | uses: actions/checkout@v2 59 | with: 60 | lfs: 'true' 61 | submodules: 'recursive' 62 | 63 | - name: Checkout submodules 64 | run: git submodule update --init --recursive 65 | 66 | - name: QEMU set-up 67 | uses: docker/setup-qemu-action@v1 68 | 69 | - name: Create build dir 70 | run: mkdir -p /tmp/buildd-results 71 | 72 | - name: Pull container 73 | run: docker pull registry.lindroid.org/lindroid/rootfs-builder:next-amd64 74 | 75 | - name: Start systemd container 76 | run: | 77 | echo "CONTAINER_HASH=$(docker run --detach --privileged \ 78 | --cgroupns=host \ 79 | --tmpfs /run \ 80 | --tmpfs /run/lock \ 81 | --tmpfs /tmp \ 82 | -v /sys/fs/cgroup:/sys/fs/cgroup:rw \ 83 | -v /tmp/buildd-results:/buildd/out \ 84 | -v /dev:/host-dev \ 85 | -v ${PWD}:/buildd/sources \ 86 | --security-opt seccomp:unconfined \ 87 | registry.lindroid.org/lindroid/rootfs-builder:next-amd64 \ 88 | /sbin/init)" >> $GITHUB_ENV 89 | 90 | 91 | 92 | - name: Build rootfs 93 | run: | 94 | docker exec $CONTAINER_HASH /bin/sh -c 'cd /buildd/sources; ./generate_recipe.py && debos --disable-fakemachine generated/lindroid-${{ matrix.config.edition }}-${{ matrix.config.arch }}.yaml' 95 | 96 | - name: Upload artifacts 97 | uses: actions/upload-artifact@v4 98 | with: 99 | name: lindroid-out-${{ matrix.config.arch }}-${{ matrix.config.edition }} 100 | path: out/* 101 | if-no-files-found: error 102 | retention-days: 1 103 | 104 | prepare: 105 | runs-on: ubuntu-24.04 106 | name: Create GitHub release 107 | needs: build 108 | outputs: 109 | upload_url: ${{ steps.create_release.outputs.upload_url }}${{ steps.create_nightly.outputs.upload_url }} 110 | 111 | steps: 112 | - name: Free up some storage 113 | uses: jlumbroso/free-disk-space@main 114 | with: 115 | tool-cache: true 116 | android: true 117 | dotnet: true 118 | haskell: true 119 | large-packages: true 120 | swap-storage: true 121 | 122 | - name: Delete old nightly release 123 | uses: dev-drprasad/delete-tag-and-release@v0.2.1 124 | if: startsWith(github.ref, 'refs/tags/lindroid') != true 125 | with: 126 | delete_release: true # default: false 127 | tag_name: nightly # tag name to delete 128 | env: 129 | GITHUB_TOKEN: ${{ secrets.PERSONAL_ACCESS_TOKEN }} 130 | 131 | - name: Tag snapshot 132 | if: startsWith(github.ref, 'refs/tags/lindroid') != true 133 | uses: tvdias/github-tagger@v0.0.1 134 | with: 135 | repo-token: ${{ secrets.PERSONAL_ACCESS_TOKEN }} 136 | tag: nightly 137 | 138 | - name: Download artifacts 139 | uses: actions/download-artifact@v4 140 | with: 141 | path: lindroid-out 142 | 143 | - name: Create SHA256SUMS 144 | run: | 145 | cd lindroid-out 146 | for x in lindroid-out-*; do 147 | cd $x 148 | sha256sum * >> ../SHA256SUMS 149 | cd .. 150 | done 151 | 152 | - name: Create stable release (drafted) 153 | id: create_release 154 | if: startsWith(github.ref, 'refs/tags/lindroid') 155 | uses: softprops/action-gh-release@v1 156 | with: 157 | files: lindroid-out/SHA256SUMS 158 | tag_name: ${{ github.ref }} 159 | draft: true 160 | prerelease: false 161 | token: ${{ secrets.PERSONAL_ACCESS_TOKEN }} 162 | 163 | - name: Create nightly release 164 | id: create_nightly 165 | if: startsWith(github.ref, 'refs/tags/lindroid') != true 166 | uses: softprops/action-gh-release@v1 167 | with: 168 | files: lindroid-out/SHA256SUMS 169 | tag_name: nightly 170 | draft: false 171 | prerelease: true 172 | token: ${{ secrets.PERSONAL_ACCESS_TOKEN }} 173 | 174 | publish: 175 | runs-on: ubuntu-24.04 176 | needs: [once, prepare] 177 | outputs: 178 | upload_url: ${{ steps.create_release.outputs.upload_url }}${{ steps.create_nightly.outputs.upload_url }} 179 | 180 | strategy: 181 | fail-fast: false 182 | matrix: 183 | config: ${{ fromJson(needs.once.outputs.matrix) }} 184 | 185 | name: Publish ${{ matrix.config.job_name }} 186 | 187 | steps: 188 | - name: Download artifacts 189 | uses: actions/download-artifact@v4 190 | with: 191 | name: lindroid-out-${{ matrix.config.arch }}-${{ matrix.config.edition }} 192 | path: lindroid-out 193 | 194 | - name: Create stable release (drafted) 195 | id: create_release 196 | if: startsWith(github.ref, 'refs/tags/lindroid') 197 | uses: softprops/action-gh-release@v1 198 | with: 199 | files: lindroid-out/* 200 | tag_name: ${{ github.ref }} 201 | draft: true 202 | prerelease: false 203 | 204 | - name: Create nightly release 205 | id: create_nightly 206 | if: startsWith(github.ref, 'refs/tags/lindroid') != true 207 | uses: softprops/action-gh-release@v1 208 | with: 209 | files: lindroid-out/* 210 | tag_name: nightly 211 | draft: false 212 | prerelease: true 213 | token: ${{ secrets.PERSONAL_ACCESS_TOKEN }} 214 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | out/ 2 | generated/* 3 | *.zip 4 | -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "rootfs-templates"] 2 | path = rootfs-templates 3 | url = https://github.com/Linux-on-droid/rootfs-templates 4 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | Droidian 2 | ======== 3 | 4 | Droidian is a GNU/Linux distribution based on top of Mobian, a Debian-based distribution for mobile devices. The goal of Droidian is to be able to run Mobian on Android phones. 5 | 6 | This repository is the canonical place to get Droidian images. 7 | 8 | # Which image to get? 9 | 10 | There are two different types of images: 11 | 12 | * Fastboot-flashable image 13 | * Recovery-flashable zipfile 14 | 15 | Fastboot-flashable images are, instead, the recommended way to install Droidian. These images are device specific, so if you want one for your device you should create one yourself. 16 | Fastboot-flashable images support Full Disk Encryption, and make use of the whole userdata partition. 17 | 18 | The recovery flashable zipfile needs to be flashed via a suitable Android recovery (such as TWRP). Recovery flashable zipfiles are generic, and are useful to test drive Droidian or in early device porting stages. 19 | You should pick up the correct zipfile for your specific device: 20 | 21 | * Device with an Android 9 vendor: api28 22 | * Device with an Android 10 vendor: api29 23 | * Device with an Android 11 vendor: api30 24 | * Device with an Android 12/12.1 vendor: api32 25 | * Device with an Android 12/12.1 vendor: api33 26 | 27 | If you're in doubt, and there is a fastboot-flashable image available for your device, it's recommended to use that. 28 | 29 | ## Recovery-flashable zipfile: bundles 30 | 31 | Recovery flashable zipfiles support the addition of *bundles*, which allow to add functionality directly during the flashing process. 32 | 33 | Currently available bundles: 34 | 35 | * Devtools: Useful development tools for porters, not available in nightlies as they're embedded in the rootfs 36 | * Adaptation bundle: Device specific bundle (containing kernel, device-specific settings, etc) 37 | 38 | **Keep in mind that is still recommended using fastboot-flashable images if available for your device.** 39 | 40 | # Fastboot-flashable image: installation instructions 41 | 42 | ## Preparations 43 | 44 | If your device is A/B device, it is necessary to have both slots on same Android version. 45 | 46 | Ensure you have `fastboot` installed. 47 | 48 | ## Installation 49 | 50 | Extract the downloaded archive, then run: 51 | 52 | ``` 53 | ./flash_all.sh 54 | ``` 55 | 56 | You might need to execute that at root depending on how your system is configured. 57 | 58 | ## Finalizing installation 59 | 60 | The device will reboot automatically. When the device has booted, you can unlock the device with the default passcode `1234`. 61 | 62 | # Recovery-flashable zipfile: installation instructions 63 | 64 | ## Preparations 65 | 66 | If your device is A/B device, it is necessary to have both slots on same Android version. 67 | 68 | Then, boot your favourite Android recovery. 69 | 70 | ## Installation 71 | 72 | From recovery open adb sideload mode (under advanced on TWRP) and run following commands on your computer replacing `ARCH_YYYYMMDD` with the version of Droidian and `vendor-device` with the vendor and device codenames: 73 | 74 | * `adb sideload droidian-OFFICIAL-phosh-phone-rootfs-apiXX-ARCH-VERSION_DATE.zip` 75 | 76 | If you want to sideload devtools: 77 | 78 | * `adb sideload droidian-devtools-ARCH_YYYYMMDD.zip` 79 | 80 | If you want to sideload an adaptation bundle: 81 | 82 | * `adb sideload droidian-adapatation-vendor-device-ARCH_YYYYMMDD.zip` 83 | 84 | Note that you have to restart the sideload mode by tapping back and starting sideload again before every `adb sideload command`. 85 | 86 | ## Finalizing installation 87 | 88 | Now, you have to reboot the device. It should boot to phosh (a graphical user interface used by Droidian) after rebooting once more automatically. When the device has booted, you can unlock the device with the default passcode `1234`. 89 | 90 | ## Troubleshooting 91 | 92 | If the image does not boot and your userdata is not an ext4 partition, you might try formatting it. **Note that this is a destructive operation, you cannot recover files from userdata afterwards!** 93 | 94 | * `fastboot format:ext4 userdata` 95 | -------------------------------------------------------------------------------- /apt/.dummy: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Linux-on-droid/lindroid-rootfs/3260c7e303b83476097418d1e681bb011f036ef2/apt/.dummy -------------------------------------------------------------------------------- /devices.yml: -------------------------------------------------------------------------------- 1 | ######################################################################## 2 | # Basic anchors # 3 | ######################################################################## 4 | 5 | .devtools_packages: 6 | packages: &devtools_packages 7 | - droidian-devtools 8 | - adaptation-hybris-devtools 9 | 10 | .fxtec_pro1_packages: 11 | packages: &fxtec_pro1_packages 12 | - adaptation-fxtec-pro1 13 | - adaptation-fxtec-pro1-configs 14 | 15 | .fxtec_pro1x_packages: 16 | packages: &fxtec_pro1x_packages 17 | - adaptation-fxtec-pro1x 18 | - adaptation-fxtec-pro1x-configs 19 | 20 | .google_sargo_packages: 21 | packages: &google_sargo_packages 22 | - adaptation-google-sargo 23 | - adaptation-google-sargo-configs 24 | 25 | .sony_bahamut_packages: 26 | packages: &sony_bahamut_packages 27 | - adaptation-sony-bahamut 28 | - adaptation-sony-bahamut-configs 29 | 30 | .volla_mimameid_packages: 31 | packages: &volla_mimameid_packages 32 | - adaptation-volla-mimameid 33 | - adaptation-volla-mimameid-configs 34 | 35 | .volla_yggdrasil_packages: 36 | packages: &volla_yggdrasil_packages 37 | - adaptation-volla-yggdrasil 38 | - adaptation-volla-yggdrasil-configs 39 | 40 | ######################################################################## 41 | # Recovery-flashable rootfses # 42 | ######################################################################## 43 | 44 | rootfs: 45 | type: rootfs 46 | arch: [armhf, arm64] 47 | edition: phosh 48 | variant: phone 49 | apilevel: [28, 29, 30, 32, 33] 50 | 51 | bundles: 52 | # Developer tools bundle 53 | - name: droidian-devtools 54 | arch: any 55 | apilevel: any 56 | only_stable: yes 57 | packages: *devtools_packages 58 | 59 | # F(x)tec Pro1 60 | - name: droidian-adaptation-fxtec-pro1 61 | arch: arm64 62 | apilevel: 28 63 | packages: *fxtec_pro1_packages 64 | 65 | # Sony Xperia 5 66 | - name: droidian-adaptation-sony-bahamut 67 | arch: arm64 68 | apilevel: 30 69 | packages: *sony_bahamut_packages 70 | 71 | ######################################################################## 72 | # Device specific images # 73 | ######################################################################## 74 | 75 | # 76 | # F(x)tec 77 | # 78 | 79 | # F(x)tec Pro1 (qx1000) 80 | fxtec_pro1: 81 | type: image 82 | arch: arm64 83 | edition: phosh 84 | variant: phone 85 | apilevel: 28 86 | 87 | packages: *fxtec_pro1_packages 88 | 89 | # F(x)tec Pro1-X (qx1050) 90 | fxtec_pro1x: 91 | type: image 92 | arch: arm64 93 | edition: phosh 94 | variant: phone 95 | apilevel: 30 96 | 97 | packages: *fxtec_pro1x_packages 98 | 99 | # 100 | # Google 101 | # 102 | 103 | # Google Pixel 3a (sargo) 104 | google_sargo: 105 | type: image 106 | arch: arm64 107 | edition: phosh 108 | variant: phone 109 | apilevel: 28 110 | 111 | packages: *google_sargo_packages 112 | 113 | # 114 | # Sony 115 | # 116 | 117 | # Sony Xperia 5 (bahamut) 118 | sony_bahamut: 119 | type: image 120 | arch: arm64 121 | edition: phosh 122 | variant: phone 123 | apilevel: 30 124 | 125 | packages: *sony_bahamut_packages 126 | 127 | # 128 | # Volla 129 | # 130 | 131 | # Volla Phone (yggdrasil) 132 | volla_yggdrasil: 133 | type: image 134 | arch: arm64 135 | edition: phosh 136 | variant: phone 137 | apilevel: 28 138 | 139 | packages: *volla_yggdrasil_packages 140 | 141 | # Volla Phone 22 (mimameid) 142 | volla_mimameid: 143 | type: rootfs 144 | arch: arm64 145 | edition: phosh 146 | variant: phone 147 | apilevel: 30 148 | 149 | packages: *volla_mimameid_packages 150 | -------------------------------------------------------------------------------- /generate_recipe.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # -*- coding: utf-8 -*- 3 | 4 | import os 5 | import json 6 | from datetime import datetime 7 | import argparse 8 | 9 | # List of architectures and UIs 10 | architectures = ["arm64", "armhf", "amd64"] 11 | uis = ["plasma"] 12 | 13 | # Common suffix for all files 14 | suffix = datetime.today().strftime('%Y%m%d') 15 | 16 | # Function to generate the content 17 | def generate_content(architecture, ui): 18 | return f"""{{{{- $product := or .product "rootfs" -}}}} 19 | {{{{- $architecture := or .architecture "{architecture}" -}}}} 20 | {{{{- $suffix := or .suffix "{suffix}" -}}}} 21 | {{{{- $edition := or .edition "{ui}" -}}}} 22 | {{{{- $version := or .version "nightly" -}}}} 23 | {{{{- $mtype := or .mtype "OFFICIAL" -}}}} 24 | {{{{- $image := or .image (printf "droidian-%s-%s-%s-%s-%s_%s.zip" $mtype $edition $architecture $version $suffix) -}}}} 25 | {{{{- $output_type := or .output_type "rootfs" -}}}} 26 | {{{{- $use_internal_repository := or .use_internal_repository "no" -}}}} 27 | 28 | architecture: {{{{ $architecture }}}} 29 | actions: 30 | 31 | - action: run 32 | description: Do nothing 33 | chroot: false 34 | command: echo "Doing nothing!" 35 | 36 | - action: recipe 37 | description: Build Droidian 38 | recipe: ../rootfs-templates/lindroid_{ui}.yaml 39 | variables: 40 | architecture: {{{{ $architecture }}}} 41 | suffix: {{{{ $suffix }}}} 42 | edition: {{{{ $edition }}}} 43 | version: {{{{ $version }}}} 44 | image: {{{{ $image }}}} 45 | output_type: {{{{ $output_type }}}} 46 | use_internal_repository: {{{{ $use_internal_repository }}}} 47 | """ 48 | 49 | # Directory to save generated files 50 | output_dir = "generated" 51 | os.makedirs(output_dir, exist_ok=True) 52 | 53 | # Generate files and matrix 54 | matrix = [] 55 | for architecture in architectures: 56 | for ui in uis: 57 | filename = f"lindroid-{ui}-{architecture}.yaml" 58 | filepath = os.path.join(output_dir, filename) 59 | content = generate_content(architecture, ui) 60 | with open(filepath, 'w') as file: 61 | file.write(content) 62 | 63 | job_name = f"rootfs ({ui} edition) - {architecture}" 64 | matrix.append({ 65 | "job_name": job_name, 66 | "product": "rootfs", 67 | "arch": architecture, 68 | "edition": ui 69 | }) 70 | 71 | # Parse arguments for matrix generation 72 | parser = argparse.ArgumentParser(description='Generate device recipe files and matrix.') 73 | parser.add_argument('--matrix', action='store_true', help='Generate and display the matrix.') 74 | args = parser.parse_args() 75 | 76 | # Display the matrix if the --matrix flag is set 77 | if args.matrix: 78 | print(json.dumps(matrix, indent=4)) 79 | --------------------------------------------------------------------------------