├── .editorconfig ├── .gitattributes ├── .github ├── FUNDING.yml ├── ISSUE_TEMPLATE │ ├── bug_report.md │ ├── custom_build.md │ └── feature_request.md └── workflows │ ├── build.yml │ ├── custom.yml │ ├── data.yml │ └── grub.yml ├── .gitignore ├── LICENSE ├── README.md ├── Taskfile.yaml ├── bootcmdline_to_test.txt ├── files ├── initrd │ └── opt │ │ └── arc │ │ ├── arc-functions.sh │ │ ├── arc.sh │ │ ├── boot.sh │ │ ├── bzImage-template-v4.gz │ │ ├── bzImage-template-v5.gz │ │ ├── bzImage-to-vmlinux.sh │ │ ├── evo.sh │ │ ├── extract-vmlinux │ │ ├── grub.img.gz │ │ ├── include │ │ ├── addons.sh │ │ ├── configFile.sh │ │ ├── consts.sh │ │ ├── functions.py │ │ ├── functions.sh │ │ ├── i915ids │ │ ├── logo.png │ │ ├── modulelist │ │ ├── modules.sh │ │ ├── syno.png │ │ └── update.sh │ │ ├── init.sh │ │ ├── kpatch │ │ ├── ramdisk-patch.sh │ │ ├── vmlinux-to-bzImage.sh │ │ └── zimage-patch.sh ├── p1 │ ├── EFI │ │ └── BOOT │ │ │ ├── SynoBootLoader.conf │ │ │ └── SynoBootLoader.efi │ └── boot │ │ └── grub │ │ ├── gfxblacklist.txt │ │ ├── grub.cfg │ │ └── memtest └── p3 │ ├── addons │ └── .gitkeep │ ├── configs │ └── .gitkeep │ ├── custom │ └── .gitkeep │ ├── lkms │ └── .gitkeep │ ├── modules │ └── .gitkeep │ └── patches │ └── .gitkeep ├── img-gen.sh └── scripts ├── functions.py ├── functions.sh ├── grub.sh ├── requirements.txt └── vm.sh /.editorconfig: -------------------------------------------------------------------------------- 1 | # top-most EditorConfig file 2 | root = true 3 | 4 | # Unix-style newlines with a newline ending every file 5 | [*] 6 | end_of_line = lf 7 | insert_final_newline = true 8 | charset = utf-8 9 | indent_size = 2 10 | 11 | # Tab indentation (no size specified) 12 | [Makefile] 13 | indent_style = tab 14 | 15 | # YAML 16 | [*.yml] 17 | indent_style = space 18 | indent_size = 2 19 | 20 | [*.{c,h}] 21 | indent_style = space 22 | indent_size = 4 23 | -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | *.sh eol=lf -------------------------------------------------------------------------------- /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | # These are supported funding model platforms 2 | 3 | github: AuxXxilium 4 | buy_me_a_coffee: auxxxilium -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/bug_report.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Bug report 3 | about: Create a Bug Report 4 | title: '' 5 | labels: bug 6 | assignees: '' 7 | 8 | --- 9 | 10 | **Describe the Bug** 11 | First read Wiki to find a Solution. If you can't find a Solution, provide a clear and concise description of what the bug is. 12 | 13 | **Screenshots** 14 | Actual Screenshot from Systeminfo (Config Mode - Sysinfo) or use new "Full Sysinfo - Upload" Function provide the Code!!! <- IMPORTANT 15 | 16 | **Hardware** 17 | Add your Hardware Informations here. CPU / Board / Networkcontroller / Storagecontroller / ... 18 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/custom_build.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Custom Build 3 | about: Create a Customized Build 4 | title: '' 5 | labels: 'custom' 6 | assignees: '' 7 | 8 | --- 9 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/feature_request.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Feature request 3 | about: Suggest an idea for this project 4 | title: '' 5 | labels: enhancement 6 | assignees: '' 7 | 8 | --- 9 | 10 | **Is your Feature request related to a Problem? Please describe.** 11 | A clear and concise Description of what the Problem is. Ex. I'm always frustrated when [...] 12 | 13 | **Additional Context** 14 | Add any other Context or Screenshots about the Feature request here. 15 | -------------------------------------------------------------------------------- /.github/workflows/build.yml: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright (C) 2025 AuxXxilium 3 | # 4 | # This is free software, licensed under the MIT License. 5 | # See /LICENSE for more information. 6 | # 7 | 8 | name: Build Arc Image 9 | 10 | on: 11 | workflow_dispatch: 12 | inputs: 13 | runs: 14 | description: "runs-on" 15 | type: choice 16 | options: 17 | - ubuntu-latest 18 | - self-hosted 19 | version: 20 | description: "version (1.0.0)" 21 | required: true 22 | type: string 23 | notice: 24 | description: "Notice here" 25 | required: false 26 | type: string 27 | stable: 28 | description: "stable" 29 | default: true 30 | type: boolean 31 | beta: 32 | description: "beta" 33 | default: false 34 | type: boolean 35 | clean: 36 | description: "clean" 37 | default: false 38 | type: boolean 39 | 40 | jobs: 41 | build: 42 | runs-on: ${{ inputs.runs }} 43 | steps: 44 | - name: Checkout 45 | uses: actions/checkout@main 46 | 47 | - name: Delete releases and workflows runs 48 | if: ${{ inputs.clean }} 49 | uses: ophub/delete-releases-workflows@main 50 | with: 51 | delete_releases: true 52 | releases_keep_latest: 1 53 | delete_workflows: false 54 | delete_tags: true 55 | gh_token: ${{ secrets.BUILD_TOKEN }} 56 | 57 | # Install Dependencies 58 | - name: Install Dependencies 59 | if: ${{ inputs.runs == 'ubuntu-latest' }} 60 | run: | 61 | git config --global user.email "info@auxxxilium.tech" 62 | git config --global user.name "AuxXxilium" 63 | sudo timedatectl set-timezone "Europe/Berlin" 64 | 65 | sudo apt update 66 | sudo apt install -y locales busybox dialog gettext sed gawk jq curl 67 | sudo apt install -y python-is-python3 python3-pip libelf-dev qemu-utils cpio xz-utils lz4 lzma bzip2 gzip zstd 68 | # sudo snap install yq 69 | if ! command -v yq &>/dev/null || ! yq --version 2>/dev/null | grep -q "v4."; then 70 | sudo curl -kL https://github.com/mikefarah/yq/releases/latest/download/yq_linux_amd64 -o /usr/bin/yq && sudo chmod a+x /usr/bin/yq 71 | fi 72 | 73 | df -h 74 | 75 | # Get extractor, LKM, Addons, Modules, Theme and Configs 76 | - name: Get Dependencies for all Image 77 | run: | 78 | . scripts/functions.sh "${{ secrets.BUILD_TOKEN }}" 79 | 80 | echo "Get Dependencies" 81 | getAddons "files/p3/addons" 82 | getModules "files/p3/modules" 83 | getConfigs "files/p3/configs" 84 | getPatches "files/p3/patches" 85 | getCustom "files/p3/custom" 86 | getOffline "files/p3/configs" 87 | getLKMs "files/p3/lkms" 88 | getTheme "files/p1/boot/grub" 89 | getBuildroot "evo" "bre" 90 | echo "BRETAG=${BRTAG}" >> $GITHUB_ENV 91 | getBuildroot "minimal" "brm" 92 | echo "BRMTAG=${BRTAG}" >> $GITHUB_ENV 93 | 94 | # Export Dependencies Version to env 95 | echo "ADDONTAG=${ADDONTAG}" >> $GITHUB_ENV 96 | echo "MODULETAG=${MODULETAG}" >> $GITHUB_ENV 97 | echo "CONFIGTAG=${CONFIGTAG}" >> $GITHUB_ENV 98 | echo "PATCHTAG=${PATCHTAG}" >> $GITHUB_ENV 99 | echo "CUSTOMTAG=${CUSTOMTAG}" >> $GITHUB_ENV 100 | echo "LKMTAG=${LKMTAG}" >> $GITHUB_ENV 101 | echo "THEMETAG=${THEMETAG}" >> $GITHUB_ENV 102 | echo "BUILD_TIME=$(date +'%Y-%m-%d %H:%M')" >> $GITHUB_ENV 103 | 104 | echo "OK" 105 | 106 | # Build incremental 107 | - name: Build Image Evo 108 | run: | 109 | . scripts/functions.sh 110 | 111 | # Modify Source File 112 | ARC_BUILD="$(date +'%y%m%d')" 113 | ARC_VERSION="${{ inputs.version }}" 114 | ARC_BRANCH="evo" 115 | echo "${ARC_BUILD}" > "files/p1/ARC-BUILD" 116 | echo "ARC_BUILD=${ARC_BUILD}" >> $GITHUB_ENV 117 | echo "${ARC_VERSION}" > "files/p1/ARC-VERSION" 118 | echo "ARC_VERSION=${ARC_VERSION}" >> $GITHUB_ENV 119 | 120 | echo "Create Arc Image" 121 | IMAGE_FILE="arc.img" 122 | gzip -dc "files/initrd/opt/arc/grub.img.gz" >"${IMAGE_FILE}" 123 | fdisk -l "${IMAGE_FILE}" 124 | 125 | LOOPX=$(sudo losetup -f) 126 | sudo losetup -P "${LOOPX}" "${IMAGE_FILE}" 127 | 128 | echo "Mounting Image File" 129 | mkdir -p "/tmp/p1" 130 | mkdir -p "/tmp/p3" 131 | sudo mount ${LOOPX}p1 "/tmp/p1" 132 | sudo mount ${LOOPX}p3 "/tmp/p3" 133 | 134 | [ ! -f "bre/bzImage-arc" ] || [ ! -f "bre/initrd-arc" ] && return 1 135 | 136 | echo "Repack initrd" 137 | cp -f "bre/bzImage-arc" "files/p3/bzImage-arc" 138 | repackInitrd "bre/initrd-arc" "files/initrd" "files/p3/initrd-arc" 139 | 140 | echo "Copying files" 141 | sudo cp -rf "files/p1/"* "/tmp/p1" 142 | sudo cp -rf "files/p3/"* "/tmp/p3" 143 | sudo sync 144 | 145 | echo "Unmount image file" 146 | sudo umount "/tmp/p1" 147 | sudo umount "/tmp/p3" 148 | rmdir "/tmp/p1" 149 | rmdir "/tmp/p3" 150 | 151 | sudo losetup --detach ${LOOPX} 152 | 153 | echo "Image Converter" 154 | qemu-img convert -p -f raw -O vmdk ${IMAGE_FILE} arc-dyn.vmdk 155 | qemu-img convert -p -f raw -o subformat=monolithicFlat -O vmdk ${IMAGE_FILE} arc.vmdk 156 | 157 | echo "Create Arc vhd" 158 | createvmc "arc.vmc" 159 | qemu-img convert -p -f raw -O vpc ${IMAGE_FILE} arc.vhd 160 | 161 | echo "Create Arc ova" 162 | convertova "${IMAGE_FILE}" "arc.ova" 163 | 164 | # Zip image and generate checksum 165 | - name: Pack Image Evo 166 | run: | 167 | if [ -n "${{ env.ARC_VERSION }}" ]; then 168 | zip -9 "arc-${{ env.ARC_VERSION }}.img.zip" arc.img 169 | zip -9 "arc-${{ env.ARC_VERSION }}.vmdk-dyn.zip" arc-dyn.vmdk 170 | zip -9 "arc-${{ env.ARC_VERSION }}.vmdk-flat.zip" arc.vmdk arc-flat.vmdk 171 | zip -9 "arc-${{ env.ARC_VERSION }}.vhd.zip" arc.vhd arc.vmc 172 | zip -9 "arc-${{ env.ARC_VERSION }}.ova.zip" arc.ova 173 | (cd files && zip -r ../update-${{ env.ARC_VERSION }}.zip ./p1 ./p3) 174 | sha256sum update-${{ env.ARC_VERSION }}.zip >"update-${{ env.ARC_VERSION }}.hash" 175 | fi 176 | 177 | # Publish a release if beta is true 178 | - name: Release 179 | if: success() && env.ARC_VERSION != '' && inputs.beta == true 180 | uses: ncipollo/release-action@v1 181 | with: 182 | tag: ${{ env.ARC_VERSION }} 183 | makeLatest: true 184 | allowUpdates: true 185 | owner: AuxXxilium 186 | repo: arc-beta 187 | token: ${{ secrets.BUILD_TOKEN }} 188 | body: | 189 | ### Note: 190 | - ${{ inputs.notice }} 191 | 192 | ### Information: 193 | - Discord Account for Arc Patch needed 194 | - Changelog is available in my Discord 195 | - Based on VisionZ Evolution Code 196 | 197 | ### Dependencies: 198 | - Addons: ${{ env.ADDONTAG }} 199 | - Modules: ${{ env.MODULETAG }} 200 | - Configs: ${{ env.CONFIGTAG }} 201 | - Patches: ${{ env.PATCHTAG }} 202 | - Custom: ${{ env.CUSTOMTAG }} 203 | - LKMs: ${{ env.LKMTAG }} 204 | - Basesystem Evolution: ${{ env.BRETAG }} 205 | 206 | ### Release 207 | - ${{ env.BUILD_TIME }} 208 | artifacts: | 209 | arc-*.zip 210 | update-*.zip 211 | update-*.hash 212 | 213 | # Publish a release if stable is true 214 | - name: Release 215 | if: success() && env.ARC_VERSION != '' && inputs.stable == true 216 | uses: ncipollo/release-action@v1 217 | with: 218 | tag: ${{ env.ARC_VERSION }} 219 | makeLatest: true 220 | allowUpdates: true 221 | owner: AuxXxilium 222 | repo: arc 223 | token: ${{ secrets.BUILD_TOKEN }} 224 | body: | 225 | ### Note: 226 | - ${{ inputs.notice }} 227 | 228 | ### Information: 229 | - Discord Account for Arc Patch needed 230 | - Changelog is available in my Discord 231 | - Based on VisionZ Evolution Code 232 | 233 | ### Dependencies: 234 | - Addons: ${{ env.ADDONTAG }} 235 | - Modules: ${{ env.MODULETAG }} 236 | - Configs: ${{ env.CONFIGTAG }} 237 | - Patches: ${{ env.PATCHTAG }} 238 | - Custom: ${{ env.CUSTOMTAG }} 239 | - LKMs: ${{ env.LKMTAG }} 240 | - Basesystem Evolution: ${{ env.BRETAG }} 241 | 242 | ### Release 243 | - ${{ env.BUILD_TIME }} 244 | artifacts: | 245 | arc-*.zip 246 | update-*.zip 247 | update-*.hash 248 | -------------------------------------------------------------------------------- /.github/workflows/custom.yml: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright (C) 2023 AuxXxilium 3 | # 4 | # This is free software, licensed under the MIT License. 5 | # See /LICENSE for more information. 6 | # 7 | 8 | name: Custom Build 9 | on: 10 | issues: 11 | types: 12 | - labeled 13 | 14 | jobs: 15 | build: 16 | if: github.event.label.name == 'custom' 17 | runs-on: ubuntu-latest 18 | steps: 19 | - name: Checkout 20 | uses: actions/checkout@main 21 | 22 | - name: Init Env 23 | run: | 24 | git config --global user.email "info@auxxxilium.tech" 25 | git config --global user.name "AuxXxilium" 26 | sudo timedatectl set-timezone "Europe/Berlin" 27 | 28 | - name: Check Custom 29 | shell: python 30 | run: | 31 | # -*- coding: utf-8 -*- 32 | import json, subprocess 33 | def set_output(name, value): 34 | subprocess.call(["echo '{}={}' >> $GITHUB_ENV".format(name, value)], shell=True) 35 | 36 | issuetitle = ${{ toJSON(github.event.issue.title) }}; 37 | issuebody = ${{ toJSON(github.event.issue.body) }}; 38 | 39 | MODEL = '' 40 | PRODUCTVER = '' 41 | ADDONS = '' 42 | KERNEL = '' 43 | FORMAT = '' 44 | try: 45 | jsonbody = json.loads(issuebody) 46 | MODEL = jsonbody.get('model', '') 47 | PRODUCTVER = jsonbody.get('version', '') 48 | ADDONS = jsonbody.get('addons', '') 49 | KERNEL = jsonbody.get('kernel', '') 50 | FORMAT = jsonbody.get('format', '') 51 | except ValueError as e: 52 | pass 53 | 54 | set_output("MODEL", MODEL) 55 | set_output("PRODUCTVER", PRODUCTVER) 56 | set_output("ADDONS", ADDONS) 57 | set_output("KERNEL", KERNEL) 58 | set_output("FORMAT", FORMAT) 59 | 60 | # calculates the version number and push 61 | - name: Calculate Version 62 | run: | 63 | # Calculate Version 64 | VERSION="`date +'%y.%-m.%-d'`-custom" 65 | 66 | echo "Version: ${VERSION}" 67 | echo "VERSION=${VERSION}" >> $GITHUB_ENV 68 | 69 | - name: Update Comment Building 70 | id: comment 71 | uses: actions-cool/issues-helper@v3 72 | with: 73 | actions: 'create-comment' 74 | token: ${{ secrets.GITHUB_TOKEN }} 75 | issue-number: ${{ github.event.issue.number }} 76 | body: | 77 | Hi @${{ github.event.issue.user.login }}. 78 | building arc-${{ env.MODEL }}-${{ env.VERSION }}, it will be uploaded here and sent to your email later.. 79 | > ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }} 80 | ---- 81 | 82 | # Install dependencies 83 | - name: Install Dependencies 84 | run: | 85 | sudo apt update 86 | sudo apt install -y jq gawk cpio gettext libelf-dev qemu-utils busybox dialog curl sed 87 | sudo pip install -r scripts/requirements.txt 88 | sudo snap install yq 89 | 90 | # Build incremental 91 | - name: Build image 92 | run: | 93 | . scripts/functions.sh 94 | 95 | function writeConfigKey() { 96 | [ "${2}" = "{}" ] && sudo yq eval '.'${1}' = {}' --inplace "${3}" 2>/dev/null || sudo yq eval '.'${1}' = "'"${2}"'"' --inplace "${3}" 2>/dev/null 97 | } 98 | 99 | TAG="$(curl -m 5 -kL https://api.github.com/repos/AuxXxilium/arc/releases/latest | grep "tag_name" | awk '{print substr($2, 2, length($2)-3)}')" 100 | curl -kL "https://github.com/AuxXxilium/arc/releases/download/${TAG}/arc-${TAG}.img.zip" -o "/tmp/arc.img.zip" 101 | unzip -o "/tmp/arc.img.zip" -d "/tmp" 102 | 103 | echo "Modify Arc Image" 104 | IMAGE_FILE="/tmp/arc.img" 105 | fdisk -l "${IMAGE_FILE}" 106 | 107 | LOOPX=$(sudo losetup -f) 108 | sudo losetup -P "${LOOPX}" "${IMAGE_FILE}" 109 | 110 | echo "Mounting image file" 111 | mkdir -p "/tmp/p1" 112 | mkdir -p "/tmp/p3" 113 | sudo mount ${LOOPX}p1 "/tmp/p1" 114 | sudo mount ${LOOPX}p3 "/tmp/p3" 115 | 116 | echo "Set Custom Config" 117 | PRESET_CONFIG_FILE="/tmp/p1/user-config.yml" 118 | sudo touch "${PRESET_CONFIG_FILE}" 119 | MODEL="${{ env.MODEL }}" 120 | writeConfigKey "model" "${MODEL}" "${PRESET_CONFIG_FILE}" 121 | PRODUCTVER="${{ env.PRODUCTVER }}" 122 | PJ="$(python scripts/functions.py getpats4mv -m "${MODEL}" -v "${PRODUCTVER:0:3}")" 123 | PAT_URL=$(echo "${PJ}" | jq -r ".\"${PRODUCTVER}\".url") 124 | PAT_HASH=$(echo "${PJ}" | jq -r ".\"${PRODUCTVER}\".sum") 125 | writeConfigKey "productver" "${PRODUCTVER:0:3}" "${PRESET_CONFIG_FILE}" 126 | writeConfigKey "paturl" "${PAT_URL}" "${PRESET_CONFIG_FILE}" 127 | writeConfigKey "pathash" "${PAT_HASH}" "${PRESET_CONFIG_FILE}" 128 | if [ "${{ env.MODEL }}" = "SA6400" ]; then 129 | writeConfigKey "kernel" "${{ env.KERNEL }}" "${PRESET_CONFIG_FILE}" 130 | fi 131 | writeConfigKey "addons" "{}" "${PRESET_CONFIG_FILE}" 132 | if [ -n "${{ env.ADDONS }}" ]; then 133 | for A in $(echo "${{ env.ADDONS }}" | tr ',' ' ' | sed 's/\[//g' | sed 's/\]//g'); do 134 | VALUE="" 135 | writeConfigKey "addons.\"${A}\"" "${VALUE}" "${PRESET_CONFIG_FILE}" 136 | done 137 | fi 138 | echo "$(cat "${PRESET_CONFIG_FILE}")" 139 | sudo echo "arc-${MODEL}-${PRODUCTVER:0:3}-${TAG}" >"/tmp/automated" 140 | sudo mv -f "/tmp/automated" "/tmp/p3/automated" 141 | DSM_FILE="${PAT_HASH}.tar" 142 | DSM_URL="https://raw.githubusercontent.com/AuxXxilium/arc-dsm/main/files/${MODEL/+/%2B}/${PRODUCTVER:0:3}/${PAT_HASH}.tar" 143 | sudo curl -skL "${DSM_URL}" -o "/tmp/${DSM_FILE}" 144 | [ -f "/tmp/${DSM_FILE}" ] && echo "dsm: download successful" || exit 1 145 | sudo mkdir -p "/tmp/p3/users" 146 | sudo mv -f "/tmp/${DSM_FILE}" "/tmp/p3/users/${DSM_FILE}" 147 | echo "Syncing files" 148 | sync 149 | 150 | echo "Unmount image file" 151 | sudo umount "/tmp/p1" 152 | sudo umount "/tmp/p3" 153 | rmdir "/tmp/p1" 154 | rmdir "/tmp/p3" 155 | 156 | sudo losetup --detach ${LOOPX} 157 | 158 | cp -f "${IMAGE_FILE}" "arc.img" 159 | 160 | # Zip image and generate checksum 161 | - name: Convert & Pack 162 | run: | 163 | rm -rf arc-*.zip 2>/dev/null 164 | if [ "${{ env.FORMAT }}" = "img" ]; then 165 | zip -9 "arc-${{ env.MODEL }}-${{ env.VERSION }}.img.zip" arc.img 166 | elif [ "${{ env.FORMAT }}" = "dyn" ]; then 167 | echo "Image Converter -> dyn" 168 | qemu-img convert arc.img -O vmdk -o adapter_type=lsilogic,compat6 arc-dyn.vmdk 169 | zip -9 "arc-${{ env.MODEL }}-${{ env.VERSION }}.vmdk-dyn.zip" arc-dyn.vmdk 170 | elif [ "${{ env.FORMAT }}" = "flat" ]; then 171 | echo "Image Converter -> flat" 172 | qemu-img convert arc.img -O vmdk -o adapter_type=lsilogic,subformat=monolithicFlat,compat6 arc.vmdk 173 | zip -9 "arc-${{ env.MODEL }}-${{ env.VERSION }}.vmdk-flat.zip" arc.vmdk arc-flat.vmdk 174 | elif [ "${{ env.FORMAT }}" = "vhdx" ]; then 175 | echo "Image Converter -> vhdx" 176 | qemu-img convert arc.img -O vhdx -o subformat=dynamic arc.vhdx 177 | zip -9 "arc-${{ env.MODEL }}-${{ env.VERSION }}.vhdx.zip" arc.vhdx 178 | elif [ "${{ env.FORMAT }}" = "ova" ]; then 179 | echo "Image Converter -> ova" 180 | convertova "arc.img" "arc.ova" 181 | zip -9 "arc-${{ env.MODEL }}-${{ env.VERSION }}.ova.zip" arc.ova 182 | fi 183 | 184 | EMAIL=$(curl -s -H "Authorization: token ${{ secrets.ACTION }}" "https://api.github.com/users/${{ github.event.issue.user.login }}" | jq -r '.email') 185 | echo "EMAIL=${EMAIL}" >> $GITHUB_ENV 186 | 187 | # Upload artifact 188 | - name: Upload to Artifacts 189 | uses: actions/upload-artifact@v4 190 | with: 191 | name: arc-${{ env.MODEL }}-${{ env.VERSION }}-${{ github.run_id }} 192 | path: | 193 | arc-*.zip 194 | retention-days: 1 195 | 196 | - name: Send mail 197 | if: success() && env.EMAIL != 'null' 198 | uses: dawidd6/action-send-mail@v3 199 | with: 200 | server_address: smtp.gmail.com 201 | server_port: 587 202 | username: ${{ secrets.MAIL_USERNAME }} 203 | password: ${{ secrets.MAIL_PASSWORD }} 204 | subject: arc-${{ env.model }}-${{ env.VERSION }} 205 | to: ${{ env.EMAIL }} 206 | from: ${{ secrets.MAIL_USERNAME }} 207 | body: | 208 | Hi @${{ github.event.issue.user.login }}. 209 | arc-${{ env.MODEL }}-${{ env.VERSION }} is ready to download: 210 | > ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }} 211 | 212 | If this isn't working, do not use customized Versions! 213 | ---- 214 | 215 | - name: Update Comment Success 216 | if: success() 217 | uses: actions-cool/issues-helper@v3 218 | with: 219 | actions: 'update-comment' 220 | token: ${{ secrets.GITHUB_TOKEN }} 221 | comment-id: ${{ steps.comment.outputs.comment-id }} 222 | update-mode: replace 223 | body: | 224 | Hi @${{ github.event.issue.user.login }}. 225 | arc-${{ env.MODEL }}-${{ env.VERSION }} is ready to download: 226 | > ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }} 227 | 228 | If this isn't working, do not use customized Versions! 229 | ---- 230 | 231 | - name: Update Comment Fail 232 | if: failure() 233 | uses: actions-cool/issues-helper@v3 234 | with: 235 | actions: 'update-comment' 236 | token: ${{ secrets.GITHUB_TOKEN }} 237 | comment-id: ${{ steps.comment.outputs.comment-id }} 238 | update-mode: replace 239 | body: | 240 | Hi @${{ github.event.issue.user.login }}. 241 | arc-${{ env.MODEL }}-${{ env.PRODUCTVER }}-${{ env.VERSION }} failed to build and package, please try again later. 242 | > ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }} 243 | ---- 244 | 245 | - name: Close Issues 246 | if: success() 247 | uses: actions-cool/issues-helper@v3 248 | with: 249 | actions: 'close-issue' 250 | token: ${{ secrets.GITHUB_TOKEN }} 251 | issue-number: ${{ github.event.issue.number }} 252 | 253 | comment: 254 | if: github.event.label.name == 'bug' 255 | runs-on: ubuntu-latest 256 | steps: 257 | - name: Init Env 258 | run: | 259 | git config --global user.email "info@auxxxilium.tech" 260 | git config --global user.name "AuxXxilium" 261 | sudo timedatectl set-timezone "Europe/Berlin" 262 | 263 | - name: Check Issues 264 | run: | 265 | if echo "${{ github.event.issue.body }}" | grep -q "Screenshots"; then 266 | echo "FALG=true" >> $GITHUB_ENV 267 | else 268 | echo "FALG=false" >> $GITHUB_ENV 269 | fi 270 | 271 | - name: Create Issues comment 272 | if: env.FALG == 'false' 273 | uses: actions-cool/issues-helper@v3 274 | with: 275 | actions: "create-comment" 276 | token: ${{ secrets.GITHUB_TOKEN }} 277 | issue-number: ${{ github.event.issue.number }} 278 | body: | 279 | **Describe the Bug** 280 | A clear and concise description of what the bug is. 281 | 282 | **Screenshots** 283 | Screenshot the Systeminfo (Arc - Sysinfo) or use new "Full Sysinfo - Upload" Function provide the Code!!! <- IMPORTANT 284 | 285 | **Hardware** 286 | Add your Hardware Informations here. CPU / Board / Networkcontroller / Storagecontroller / ... 287 | 288 | - name: Close Issues 289 | if: env.FALG == 'false' 290 | uses: actions-cool/issues-helper@v3 291 | with: 292 | actions: 'close-issue' 293 | token: ${{ secrets.GITHUB_TOKEN }} 294 | issue-number: ${{ github.event.issue.number }} 295 | -------------------------------------------------------------------------------- /.github/workflows/data.yml: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright (C) 2023 AuxXxilium and Ing 3 | # 4 | # This is free software, licensed under the MIT License. 5 | # See /LICENSE for more information. 6 | # 7 | 8 | name: Data 9 | on: 10 | workflow_dispatch: 11 | inputs: 12 | push: 13 | description: "push" 14 | default: false 15 | type: boolean 16 | 17 | jobs: 18 | build: 19 | runs-on: ubuntu-latest 20 | steps: 21 | - name: Checkout 22 | uses: actions/checkout@main 23 | with: 24 | ref: page 25 | 26 | - name: Init Env 27 | run: | 28 | git config --global user.email "info@auxxxilium.tech" 29 | git config --global user.name "AuxXxilium" 30 | sudo timedatectl set-timezone "Europe/Berlin" 31 | 32 | sudo apt update 33 | sudo apt install -y build-essential libtool pkgconf libzstd-dev liblzma-dev libssl-dev busybox dialog curl xz-utils cpio sed qemu-utils 34 | 35 | YQ=$(command -v yq) 36 | if [ -z "${YQ}" ] || ! ${YQ} --version 2>/dev/null | grep -q "v4."; then 37 | wget https://github.com/mikefarah/yq/releases/latest/download/yq_linux_amd64 -O "${YQ:-"/usr/bin/yq"}" && chmod +x "${YQ:-"/usr/bin/yq"}" 38 | fi 39 | 40 | - name: Get Addon Data for Arc 41 | run: | 42 | REPO="https://github.com/AuxXxilium/arc-addons" 43 | PRERELEASE="true" 44 | 45 | TAG="" 46 | if [ "${PRERELEASE}" = "true" ]; then 47 | TAG="$(curl -skL --connect-timeout 10 "${REPO}/tags" | grep /refs/tags/.*\.zip | sed -r 's/.*\/refs\/tags\/(.*)\.zip.*$/\1/' | sort -rV | head -1)" 48 | else 49 | LATESTURL="$(curl -skL --connect-timeout 10 -w %{url_effective} -o /dev/null "${REPO}/releases/latest")" 50 | TAG="${LATESTURL##*/}" 51 | fi 52 | [ "${TAG:0:1}" = "v" ] && TAG="${TAG:1}" 53 | rm -f addons.zip 54 | STATUS=$(curl -kL --connect-timeout 10 -w "%{http_code}" "${REPO}/releases/download/${TAG}/addons-${TAG}.zip" -o "addons.zip") 55 | if [ $? -ne 0 -o ${STATUS:-0} -ne 200 ]; then 56 | echo "Download failed" 57 | exit 1 58 | fi 59 | 60 | mkdir -p "mnt/p3/addons" 61 | unzip addons.zip -d "mnt/p3/addons" 62 | for i in $(find "mnt/p3/addons" -type f -name "*.addon"); do 63 | if [ -f "${i}" ]; then 64 | mkdir -p "mnt/p3/addons/$(basename "${i}" .addon)" 65 | tar -xaf "${i}" -C "mnt/p3/addons/$(basename "${i}" .addon)" 66 | fi 67 | done 68 | rm -f addons.zip 69 | 70 | - name: Get Config Data for Arc 71 | run: | 72 | REPO="https://github.com/AuxXxilium/arc-configs" 73 | LATESTURL="$(curl -skL --connect-timeout 10 -w %{url_effective} -o /dev/null "${REPO}/releases/latest")" 74 | TAG="${LATESTURL##*/}" 75 | [ "${TAG:0:1}" = "v" ] && TAG="${TAG:1}" 76 | rm -f configs.zip 77 | STATUS=$(curl -kL --connect-timeout 10 -w "%{http_code}" "${REPO}/releases/download/${TAG}/configs-${TAG}.zip" -o "configs.zip") 78 | if [ $? -ne 0 -o ${STATUS:-0} -ne 200 ]; then 79 | echo "Download failed" 80 | exit 1 81 | fi 82 | 83 | mkdir -p "mnt/p3/configs" 84 | unzip configs.zip -d "mnt/p3/configs" 85 | rm -f configs.zip 86 | 87 | - name: Get data 88 | run: | 89 | pip install -r scripts/requirements.txt 90 | python scripts/functions.py getmodels -w "." -j "docs/models.json" 91 | python scripts/functions.py getaddons -w "." -j "docs/addons.json" 92 | python scripts/functions.py getpats -w "." -j "docs/pats.json" 93 | 94 | - name: Upload to Artifacts 95 | if: success() 96 | uses: actions/upload-artifact@v4 97 | with: 98 | name: docs 99 | path: | 100 | docs/*.json 101 | retention-days: 5 102 | 103 | - name: Check and Push 104 | if: success() && (inputs.push == true || github.event.action == 'created') 105 | run: | 106 | echo "Git push ..." 107 | # git checkout main 108 | git pull 109 | status=$(git status -s | grep -E "docs" | awk '{printf " %s", $2}') 110 | if [ -n "${status}" ]; then 111 | git add ${status} 112 | git commit -m "data: update $(date +%Y-%m-%d" "%H:%M:%S)" 113 | git push -f 114 | fi -------------------------------------------------------------------------------- /.github/workflows/grub.yml: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright (C) 2025 AuxXxilium 3 | # 4 | # This is free software, licensed under the MIT License. 5 | # See /LICENSE for more information. 6 | # 7 | 8 | name: Grub 9 | 10 | on: 11 | workflow_dispatch: 12 | inputs: 13 | push: 14 | description: "push" 15 | default: false 16 | type: boolean 17 | jobs: 18 | grub: 19 | runs-on: ubuntu-latest 20 | steps: 21 | - name: Checkout 22 | uses: actions/checkout@main 23 | 24 | - name: Initialization environment 25 | run : | 26 | git config --global user.email "info@auxxxilium.tech" 27 | git config --global user.name "AuxXxilium" 28 | sudo timedatectl set-timezone "Europe/Berlin" 29 | 30 | sudo apt update 31 | sudo apt install -y autoconf automake autopoint build-essential pkg-config bison flex gettext gawk libtool dosfstools e2fsprogs 32 | sudo apt install -y libfreetype6-dev unifont fonts-dejavu libfuse-dev libzfslinux-dev liblzma-dev libdevmapper-dev 33 | 34 | - name: Make Grub 35 | run: | 36 | rm -f "files/initrd/opt/arc/grub.img.gz" 37 | . scripts/grub.sh "grub-2.12" "i386-pc i386-efi x86_64-efi" "ARC" 38 | 39 | - name: Check and Push 40 | if: success() && inputs.push == true 41 | run: | 42 | if [ -f "grub.img.gz" ]; then 43 | mv -f "grub.img.gz" "files/initrd/opt/arc/grub.img.gz" 44 | echo "Git push ..." 45 | git pull 46 | status=$(git status -s | grep -E 'grub.img.gz' | awk '{printf " %s", $2}') 47 | if [ -n "${status}" ]; then 48 | git add ${status} 49 | git commit -m "grub: update $(date +%Y-%m-%d" "%H:%M:%S)" 50 | git push -f 51 | fi 52 | else 53 | echo "No change ..." 54 | fi 55 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | !.gitkeep 2 | .vscode 3 | arc.img 4 | arc*.vmdk 5 | *.zip 6 | .buildroot 7 | test*.sh 8 | docker/syno-compiler/Dockerfile 9 | cache 10 | *.bak 11 | *.o 12 | /files/board/arc/p3/addons 13 | /files/board/arc/p3/lkms 14 | /files/board/arc/p3/modules 15 | /files/board/arc/p3/configs 16 | /files/board/arc/p3/extensions 17 | /tests -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 |
arc_loader
2 | 3 | The Arc Loader is a customized version of the Redpill Loader for DSM 7.x (Xpenology), offering enhanced hardware support, additional addons, a guided (semi-automated) installation process, and more. It includes various built-in customization options and has been modified to run on a wide range of hardware platforms (see the Wiki for more information). 4 | 5 | - Commercial use is not permitted and strictly forbidden!!! 6 | - DSM and all Parts are under Copyright / Ownership or Registered Trademark by Synology Inc. 7 | 8 | ### Bugreport 9 | 10 | - Before you report an issue or bug please read the FAQ & Wiki and make sure your setting are correct. 11 | - If you have to report an issue or bug: 12 | - Hardware you use (Networkchip, Sata/HBA/Raid Controller) 13 | - Screenshot the Systeminfo (Arc - Sysinfo) or use new "Full Sysinfo - Upload" Function and provide the Code!!! <- IMPORTANT 14 | 15 | ### Links 16 | 17 | - Overview 18 | - FAQ & Wiki 19 | - Download latest Build 20 | 21 | ### Developer 22 | 23 | - AuxXxilium 24 | - Fulcrum 25 | 26 | ### Thanks 27 | Code is based on the work of TTG, pocopico, jumkey, fbelavenuto, wjz304 and others involved in continuing TTG's original redpill-load project. 28 | -------------------------------------------------------------------------------- /Taskfile.yaml: -------------------------------------------------------------------------------- 1 | # https://taskfile.dev 2 | 3 | version: "3" 4 | 5 | tasks: 6 | build-evo: 7 | cmds: 8 | - git reset --hard 9 | - git pull 10 | - ./img-gen.sh evo -------------------------------------------------------------------------------- /bootcmdline_to_test.txt: -------------------------------------------------------------------------------- 1 | # Disabled for now 2 | 3 | # CMDLINE['intremap']="off" 4 | # CMDLINE['amd_iommu_intr']="legacy" 5 | # CMDLINE['kvm.ignore_msrs']="1" 6 | # CMDLINE['kvm.report_ignored_msrs']="0" 7 | # CMDLINE['nomodeset']="" 8 | # CMDLINE['module.sig_enforce']="0" 9 | # CMDLINE['loadpin.enforce']="0" 10 | # CMDLINE['nr_cpus']="x" 11 | # CMDLINE['maxcpus']="x" 12 | 13 | # if grep -qi "intel" /proc/cpuinfo; then 14 | # CMDLINE['intel_pstate']="disable" 15 | # elif grep -qi "amd" /proc/cpuinfo; then 16 | # CMDLINE['amd_pstate']="disable" 17 | # fi -------------------------------------------------------------------------------- /files/initrd/opt/arc/arc.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | ############################################################################### 4 | # Overlay Init Section 5 | [[ -z "${ARC_PATH}" || ! -d "${ARC_PATH}/include" ]] && ARC_PATH="$(cd "$(dirname "${BASH_SOURCE[0]}")" 2>/dev/null && pwd)" 6 | 7 | . "${ARC_PATH}/arc-functions.sh" 8 | . "${ARC_PATH}/include/functions.sh" 9 | . "${ARC_PATH}/include/addons.sh" 10 | . "${ARC_PATH}/include/modules.sh" 11 | . "${ARC_PATH}/include/update.sh" 12 | 13 | # Check System 14 | onlineCheck 15 | systemCheck 16 | readData 17 | 18 | ############################################################################### 19 | # Mounts backtitle dynamically 20 | function backtitle() { 21 | BACKTITLE="${ARC_TITLE}$([ -n "${NEWTAG}" ] && [ -n "${ARC_VERSION}" ] && [ ${ARC_VERSION//[!0-9]/} -lt ${NEWTAG//[!0-9]/} ] && echo " > ${NEWTAG}") | " 22 | BACKTITLE+="${MODEL:-(Model)} | " 23 | BACKTITLE+="${DSMVER:-(Version)} | " 24 | BACKTITLE+="${IPCON:-(no IP)} | " 25 | BACKTITLE+="Patch: ${ARC_PATCH} | " 26 | BACKTITLE+="Config: ${CONFDONE} | " 27 | BACKTITLE+="Build: ${BUILDDONE} | " 28 | BACKTITLE+="${MEV}(${BUS}) | " 29 | [ -n "${KEYMAP}" ] && BACKTITLE+="KB: ${KEYMAP}" 30 | [ "${ARC_OFFLINE}" = "true" ] && BACKTITLE+=" | Offline" 31 | echo "${BACKTITLE}" 32 | } 33 | 34 | ############################################################################### 35 | ############################################################################### 36 | # Main loop 37 | if [ "${ARC_MODE}" = "update" ]; then 38 | if [ "${ARC_OFFLINE}" != "true" ]; then 39 | updateLoader 40 | else 41 | dialog --backtitle "$(backtitle)" --title "Arc Update" \ 42 | --infobox "Update is not possible in Offline Mode!" 5 40 43 | sleep 3 44 | exec reboot 45 | fi 46 | elif [ "${ARC_MODE}" = "automated" ]; then 47 | if [ "${BUILDDONE}" = "false" ] || [ "${MODEL}" != "${MODELID}" ]; then 48 | arcModel 49 | else 50 | make 51 | fi 52 | elif [ "${ARC_MODE}" = "config" ]; then 53 | [ "${CONFDONE}" = "true" ] && NEXT="2" || NEXT="1" 54 | [ "${BUILDDONE}" = "true" ] && NEXT="3" || NEXT="1" 55 | while true; do 56 | rm -f "${TMP_PATH}/menu" "${TMP_PATH}/resp" >/dev/null 2>&1 || true 57 | 58 | write_menu "=" "\Z4===== Main =====\Zn" 59 | 60 | if [ -z "${USERID}" ] && [ "${ARC_OFFLINE}" = "false" ]; then 61 | write_menu "0" "HardwareID for Arc Patch" 62 | fi 63 | 64 | write_menu "1" "Choose Model" 65 | 66 | if [ "${CONFDONE}" = "true" ]; then 67 | if [ -f "${MOD_ZIMAGE_FILE}" ] && [ -f "${MOD_RDGZ_FILE}" ]; then 68 | write_menu "2" "Rebuild Loader" 69 | else 70 | write_menu "2" "Build Loader" 71 | fi 72 | fi 73 | 74 | if [ "${BUILDDONE}" = "true" ] && [ -f "${MOD_ZIMAGE_FILE}" ] && [ -f "${MOD_RDGZ_FILE}" ]; then 75 | write_menu "3" "Boot Loader" 76 | fi 77 | 78 | write_menu "=" "\Z4===== Info =====\Zn" 79 | write_menu "a" "Sysinfo" 80 | write_menu "A" "Networkdiag" 81 | 82 | if [ "${CONFDONE}" = "true" ]; then 83 | if [ "${ARCOPTS}" = "true" ]; then 84 | write_menu "5" "\Z1Hide Arc DSM Options\Zn" 85 | write_menu "b" "Addons" 86 | write_menu "d" "Modules" 87 | write_menu "e" "Version" 88 | write_menu "p" "SN/Mac Options" 89 | 90 | if [ "${DT}" = "false" ] && [ "${SATACONTROLLER}" -gt 0 ]; then 91 | write_menu "S" "PortMap (Sata Controller)" 92 | fi 93 | 94 | if [ "${DT}" = "true" ]; then 95 | write_menu "o" "DTS Map Options" 96 | fi 97 | 98 | for addon in "cpufreqscaling" "storagepanel"; do 99 | if readConfigMap "addons" "${USER_CONFIG_FILE}" | grep -q "${addon}"; then 100 | case "${addon}" in 101 | "cpufreqscaling") write_menu "g" "Scaling Governor" ;; 102 | "storagepanel") write_menu "P" "StoragePanel" ;; 103 | esac 104 | fi 105 | done 106 | 107 | if [ "${PLATFORM}" = "epyc7002" ] && [ "${PRODUCTVER}" = "7.2" ]; then 108 | write_menu_value "K" "Kernel" "${KERNEL}" 109 | fi 110 | 111 | if [ "${DT}" = "true" ]; then 112 | write_menu_value "H" "Hotplug/SortDrives" "${HDDSORT}" 113 | else 114 | write_menu_value "h" "USB Disk(s) as Internal" "${USBMOUNT}" 115 | fi 116 | else 117 | write_menu "5" "\Z1Show Arc DSM Options\Zn" 118 | fi 119 | 120 | if [ "${BOOTOPTS}" = "true" ]; then 121 | write_menu "6" "\Z1Hide Boot Options\Zn" 122 | write_menu "f" "Bootscreen Options" 123 | write_menu_value "m" "Boot Kernelload" "${KERNELLOAD}" 124 | write_menu_value "E" "DSM on eMMC Boot Support" "${EMMCBOOT}" 125 | if [ "${DIRECTBOOT}" = "false" ]; then 126 | write_menu_value "i" "Boot IP Waittime" "${BOOTIPWAIT}" 127 | fi 128 | write_menu_value "q" "Directboot" "${DIRECTBOOT}" 129 | else 130 | write_menu "6" "\Z1Show Boot Options\Zn" 131 | fi 132 | 133 | if [ "${DSMOPTS}" = "true" ]; then 134 | write_menu "7" "\Z1Hide DSM Options\Zn" 135 | write_menu "j" "Cmdline" 136 | write_menu "k" "Synoinfo" 137 | write_menu "N" "Add new User" 138 | write_menu "t" "Change User Password" 139 | write_menu "J" "Reset Network Config" 140 | write_menu "T" "Disable all scheduled Tasks" 141 | write_menu "r" "Remove Blocked IP Database" 142 | write_menu "v" "Force enable SSH" 143 | write_menu "M" "Mount DSM Storage Pool" 144 | write_menu "l" "Edit User Config" 145 | write_menu "s" "Allow Downgrade Version" 146 | write_menu_value "O" "Official Driver Priority" "${ODP}" 147 | else 148 | write_menu "7" "\Z1Show DSM Options\Zn" 149 | fi 150 | fi 151 | 152 | if [ "${LOADEROPTS}" = "true" ]; then 153 | write_menu "8" "\Z1Hide Loader Options\Zn" 154 | write_menu_value "c" "Offline Mode" "${ARC_OFFLINE}" 155 | write_menu "D" "StaticIP for Loader/DSM" 156 | write_menu "U" "Change Loader Password" 157 | write_menu "Z" "Change Loader Ports" 158 | write_menu "w" "Reset Loader to Defaults" 159 | write_menu "L" "Grep Logs from dbgutils" 160 | write_menu "B" "Grep DSM Config from Backup" 161 | write_menu "=" "\Z1== Edit with caution! ==\Zn" 162 | write_menu_value "W" "Ramdisk Compression" "${RD_COMPRESSED}" 163 | write_menu_value "X" "Sata DOM" "${SATADOM}" 164 | write_menu_value "u" "LKM Version" "${LKM}" 165 | write_menu "C" "Clone Loader to another Disk" 166 | write_menu "n" "Grub Bootloader Config" 167 | write_menu "y" "Choose a Keymap for Loader" 168 | write_menu "F" "\Z1Formate Disks\Zn" 169 | else 170 | write_menu "8" "\Z1Show Loader Options\Zn" 171 | fi 172 | 173 | write_menu "=" "\Z4===== Misc =====\Zn" 174 | write_menu "x" "Backup/Restore/Recovery" 175 | [ "${ARC_OFFLINE}" = "false" ] && write_menu "z" "Update Menu" 176 | write_menu "I" "Power/Service Menu" 177 | write_menu "V" "Credits" 178 | [ "$TERM" != "xterm-256color" ] && WEBCONFIG="Webconfig: http://${IPCON}:${HTTPPORT:-7080}" || WEBCONFIG="" 179 | dialog --clear --default-item ${NEXT} --backtitle "$(backtitle)" --title "Advanced UI" --colors \ 180 | --cancel-label "Easy UI" --help-button --help-label "Exit" \ 181 | --menu "${WEBCONFIG}" 0 0 0 --file "${TMP_PATH}/menu" \ 182 | 2>"${TMP_PATH}/resp" 183 | RET=$? 184 | case ${RET} in 185 | 0) 186 | resp="$(cat "${TMP_PATH}/resp" 2>/dev/null)" 187 | [ -z "${resp}" ] && return 188 | case ${resp} in 189 | # Main Section 190 | 0) genHardwareID; NEXT="0" ;; 191 | 1) arcModel; NEXT="2" ;; 192 | 2) arcSummary; NEXT="3" ;; 193 | 3) boot; NEXT="3" ;; 194 | # Info Section 195 | a) sysinfo; NEXT="a" ;; 196 | A) networkdiag; NEXT="A" ;; 197 | # System Section 198 | # Arc Section 199 | 5) [ "${ARCOPTS}" = "true" ] && ARCOPTS='false' || ARCOPTS='true' 200 | NEXT="5" 201 | ;; 202 | b) addonMenu; NEXT="b" ;; 203 | d) modulesMenu; NEXT="d" ;; 204 | e) ONLYVERSION="true" && writeConfigKey "productver" "" "${USER_CONFIG_FILE}" && arcVersion; NEXT="e" ;; 205 | p) ONLYPATCH="true" && checkHardwareID && arcPatch; NEXT="p" ;; 206 | S) storageMenu; NEXT="S" ;; 207 | o) dtsMenu; NEXT="o" ;; 208 | g) governorMenu; NEXT="g" ;; 209 | P) storagepanelMenu; NEXT="P" ;; 210 | # Boot Section 211 | 6) [ "${BOOTOPTS}" = "true" ] && BOOTOPTS='false' || BOOTOPTS='true' 212 | NEXT="6" 213 | ;; 214 | f) bootScreen; NEXT="f" ;; 215 | m) [ "${KERNELLOAD}" = "kexec" ] && KERNELLOAD='power' || KERNELLOAD='kexec' 216 | writeConfigKey "kernelload" "${KERNELLOAD}" "${USER_CONFIG_FILE}" 217 | NEXT="m" 218 | ;; 219 | E) [ "${EMMCBOOT}" = "true" ] && EMMCBOOT='false' || EMMCBOOT='true' 220 | if [ "${EMMCBOOT}" = "false" ]; then 221 | writeConfigKey "emmcboot" "false" "${USER_CONFIG_FILE}" 222 | deleteConfigKey "synoinfo.disk_swap" "${USER_CONFIG_FILE}" 223 | deleteConfigKey "synoinfo.supportraid" "${USER_CONFIG_FILE}" 224 | deleteConfigKey "synoinfo.support_emmc_boot" "${USER_CONFIG_FILE}" 225 | deleteConfigKey "synoinfo.support_install_only_dev" "${USER_CONFIG_FILE}" 226 | elif [ "${EMMCBOOT}" = "true" ]; then 227 | writeConfigKey "emmcboot" "true" "${USER_CONFIG_FILE}" 228 | writeConfigKey "synoinfo.disk_swap" "no" "${USER_CONFIG_FILE}" 229 | writeConfigKey "synoinfo.supportraid" "no" "${USER_CONFIG_FILE}" 230 | writeConfigKey "synoinfo.support_emmc_boot" "yes" "${USER_CONFIG_FILE}" 231 | writeConfigKey "synoinfo.support_install_only_dev" "yes" "${USER_CONFIG_FILE}" 232 | fi 233 | writeConfigKey "arc.builddone" "false" "${USER_CONFIG_FILE}" 234 | BUILDDONE="$(readConfigKey "arc.builddone" "${USER_CONFIG_FILE}")" 235 | NEXT="E" 236 | ;; 237 | i) bootipwaittime; NEXT="i" ;; 238 | q) [ "${DIRECTBOOT}" = "false" ] && DIRECTBOOT='true' || DIRECTBOOT='false' 239 | grub-editenv ${USER_GRUBENVFILE} create 240 | writeConfigKey "directboot" "${DIRECTBOOT}" "${USER_CONFIG_FILE}" 241 | NEXT="q" 242 | ;; 243 | # DSM Section 244 | 7) [ "${DSMOPTS}" = "true" ] && DSMOPTS='false' || DSMOPTS='true' 245 | NEXT="7" 246 | ;; 247 | j) cmdlineMenu; NEXT="j" ;; 248 | k) synoinfoMenu; NEXT="k" ;; 249 | l) editUserConfig; NEXT="l" ;; 250 | s) downgradeMenu; NEXT="s" ;; 251 | t) resetPassword; NEXT="t" ;; 252 | N) addNewDSMUser; NEXT="N" ;; 253 | J) resetDSMNetwork; NEXT="J" ;; 254 | M) mountDSM; NEXT="M" ;; 255 | T) disablescheduledTasks; NEXT="T" ;; 256 | K) KERNEL=$([ "${KERNEL}" = "official" ] && echo 'custom' || echo 'official') 257 | writeConfigKey "kernel" "${KERNEL}" "${USER_CONFIG_FILE}" 258 | dialog --backtitle "$(backtitle)" --title "Kernel" \ 259 | --infobox "Switching Kernel to ${KERNEL}! Stay patient..." 3 50 260 | if [ "${ODP}" = "true" ]; then 261 | ODP="false" 262 | writeConfigKey "odp" "${ODP}" "${USER_CONFIG_FILE}" 263 | fi 264 | PLATFORM="$(readConfigKey "platform" "${USER_CONFIG_FILE}")" 265 | PRODUCTVER="$(readConfigKey "productver" "${USER_CONFIG_FILE}")" 266 | KVER="$(readConfigKey "platforms.${PLATFORM}.productvers.\"${PRODUCTVER}\".kver" "${P_FILE}")" 267 | is_in_array "${PLATFORM}" "${KVER5L[@]}" && KVERP="${PRODUCTVER}-${KVER}" || KVERP="${KVER}" 268 | if [ -n "${PLATFORM}" ] && [ -n "${KVERP}" ]; then 269 | writeConfigKey "modules" "{}" "${USER_CONFIG_FILE}" 270 | mergeConfigModules "$(getAllModules "${PLATFORM}" "${KVERP}" | awk '{print $1}')" "${USER_CONFIG_FILE}" 271 | fi 272 | writeConfigKey "arc.builddone" "false" "${USER_CONFIG_FILE}" 273 | BUILDDONE="$(readConfigKey "arc.builddone" "${USER_CONFIG_FILE}")" 274 | NEXT="K" 275 | ;; 276 | H) [ "${HDDSORT}" = "true" ] && HDDSORT='false' || HDDSORT='true' 277 | writeConfigKey "hddsort" "${HDDSORT}" "${USER_CONFIG_FILE}" 278 | writeConfigKey "arc.builddone" "false" "${USER_CONFIG_FILE}" 279 | BUILDDONE="$(readConfigKey "arc.builddone" "${USER_CONFIG_FILE}")" 280 | NEXT="H" 281 | ;; 282 | h) [ "${USBMOUNT}" = "true" ] && USBMOUNT='false' || USBMOUNT='true' 283 | writeConfigKey "usbmount" "${USBMOUNT}" "${USER_CONFIG_FILE}" 284 | writeConfigKey "arc.builddone" "false" "${USER_CONFIG_FILE}" 285 | BUILDDONE="$(readConfigKey "arc.builddone" "${USER_CONFIG_FILE}")" 286 | NEXT="h" 287 | ;; 288 | O) [ "${ODP}" = "false" ] && ODP='true' || ODP='false' 289 | writeConfigKey "odp" "${ODP}" "${USER_CONFIG_FILE}" 290 | writeConfigKey "arc.builddone" "false" "${USER_CONFIG_FILE}" 291 | BUILDDONE="$(readConfigKey "arc.builddone" "${USER_CONFIG_FILE}")" 292 | NEXT="O" 293 | ;; 294 | B) getbackup; NEXT="B" ;; 295 | # Loader Section 296 | 8) [ "${LOADEROPTS}" = "true" ] && LOADEROPTS='false' || LOADEROPTS='true' 297 | NEXT="8" 298 | ;; 299 | 4) rm -f "${MOD_ZIMAGE_FILE}" "${MOD_RDGZ_FILE}" >/dev/null 2>&1 || true 300 | arcSummary; 301 | NEXT="3" 302 | ;; 303 | c) ARC_OFFLINE=$([ "${ARC_OFFLINE}" = "true" ] && echo 'false' || echo 'true') 304 | writeConfigKey "arc.offline" "${ARC_OFFLINE}" "${USER_CONFIG_FILE}" 305 | [ "${ARC_OFFLINE}" = "false" ] && exec arc.sh 306 | NEXT="c" 307 | ;; 308 | D) staticIPMenu; NEXT="D" ;; 309 | Z) loaderPorts; NEXT="Z" ;; 310 | U) loaderPassword; NEXT="U" ;; 311 | W) RD_COMPRESSED=$([ "${RD_COMPRESSED}" = "true" ] && echo 'false' || echo 'true') 312 | writeConfigKey "rd-compressed" "${RD_COMPRESSED}" "${USER_CONFIG_FILE}" 313 | writeConfigKey "arc.builddone" "false" "${USER_CONFIG_FILE}" 314 | BUILDDONE="$(readConfigKey "arc.builddone" "${USER_CONFIG_FILE}")" 315 | NEXT="W" 316 | ;; 317 | X) satadomMenu; NEXT="X" ;; 318 | u) [ "${LKM}" = "prod" ] && LKM='dev' || LKM='prod' 319 | writeConfigKey "lkm" "${LKM}" "${USER_CONFIG_FILE}" 320 | writeConfigKey "arc.builddone" "false" "${USER_CONFIG_FILE}" 321 | BUILDDONE="$(readConfigKey "arc.builddone" "${USER_CONFIG_FILE}")" 322 | NEXT="u" 323 | ;; 324 | L) greplogs; NEXT="L" ;; 325 | w) resetLoader; NEXT="w" ;; 326 | C) cloneLoader; NEXT="C" ;; 327 | n) editGrubCfg; NEXT="n" ;; 328 | y) keymapMenu; NEXT="y" ;; 329 | F) formatDisks; NEXT="F" ;; 330 | # Misc Settings 331 | x) backupMenu; NEXT="x" ;; 332 | z) updateMenu; NEXT="z" ;; 333 | I) rebootMenu; NEXT="I" ;; 334 | V) credits; NEXT="V" ;; 335 | esac 336 | ;; 337 | 1) 338 | exec evo.sh 339 | ;; 340 | *) 341 | break 342 | ;; 343 | esac 344 | done 345 | clear 346 | else 347 | echo "Unknown Mode: ${ARCMODE} - Rebooting to Config Mode" 348 | sleep 3 349 | rebootTo config 350 | fi 351 | 352 | # Inform user 353 | echo -e "Call \033[1;34marc.sh\033[0m to configure Loader" 354 | echo 355 | echo -e "Web Config: \033[1;34mhttp://${IPCON}:${HTTPPORT:-7080}\033[0m" 356 | echo 357 | echo -e "SSH Access:" 358 | echo -e "IP: \033[1;34m${IPCON}\033[0m" 359 | echo -e "User: \033[1;34mroot\033[0m" 360 | echo -e "Password: \033[1;34marc\033[0m" 361 | echo 362 | -------------------------------------------------------------------------------- /files/initrd/opt/arc/boot.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | [[ -z "${ARC_PATH}" || ! -d "${ARC_PATH}/include" ]] && ARC_PATH="$(cd "$(dirname "${BASH_SOURCE[0]}")" 2>/dev/null && pwd)" 4 | 5 | . "${ARC_PATH}/include/functions.sh" 6 | 7 | arc_mode || die "Bootmode not found!" 8 | 9 | # Clear logs for dbgutils addons 10 | rm -rf "${PART1_PATH}/logs" >/dev/null 2>&1 || true 11 | 12 | # Get Loader Disk Bus 13 | [ -z "${LOADER_DISK}" ] && die "Loader Disk not found!" 14 | BUS=$(getBus "${LOADER_DISK}") 15 | EFI=$([ -d /sys/firmware/efi ] && echo 1 || echo 0) 16 | 17 | # Print Title centralized 18 | clear 19 | COLUMNS=$(ttysize 2>/dev/null | awk '{print $1}') 20 | COLUMNS=${COLUMNS:-120} 21 | BANNER="$(figlet -c -w "${COLUMNS}" "Arc Loader")" 22 | TITLE="Version:" 23 | TITLE+=" ${ARC_VERSION} (${ARC_BUILD})" 24 | printf "\033[1;30m%*s\n" ${COLUMNS} "" 25 | printf "\033[1;30m%*s\033[A\n" ${COLUMNS} "" 26 | printf "\033[1;34m%*s\033[0m\n" ${COLUMNS} "${BANNER}" 27 | printf "\033[1;34m%*s\033[0m\n" $(((${#TITLE} + ${COLUMNS}) / 2)) "${TITLE}" 28 | TITLE="Boot:" 29 | [ "${EFI}" = "1" ] && TITLE+=" [UEFI]" || TITLE+=" [BIOS]" 30 | TITLE+=" | Device: [${BUS}] | Mode: [${ARC_MODE}]" 31 | printf "\033[1;34m%*s\033[0m\n" $(((${#TITLE} + ${COLUMNS}) / 2)) "${TITLE}" 32 | # Check if DSM zImage/Ramdisk is changed, patch it if necessary, update Files if necessary 33 | ZIMAGE_HASH="$(readConfigKey "zimage-hash" "${USER_CONFIG_FILE}")" 34 | ZIMAGE_HASH_CUR="$(sha256sum "${ORI_ZIMAGE_FILE}" | awk '{print $1}')" 35 | RAMDISK_HASH="$(readConfigKey "ramdisk-hash" "${USER_CONFIG_FILE}")" 36 | RAMDISK_HASH_CUR="$(sha256sum "${ORI_RDGZ_FILE}" | awk '{print $1}')" 37 | if [ "${ZIMAGE_HASH_CUR}" != "${ZIMAGE_HASH}" ] || [ "${RAMDISK_HASH_CUR}" != "${RAMDISK_HASH}" ]; then 38 | echo -e "\033[1;31mDSM zImage/Ramdisk changed!\033[0m" 39 | livepatch 40 | echo 41 | fi 42 | 43 | # Read model/system variables 44 | PLATFORM="$(readConfigKey "platform" "${USER_CONFIG_FILE}")" 45 | MODEL="$(readConfigKey "model" "${USER_CONFIG_FILE}")" 46 | MODELID="$(readConfigKey "modelid" "${USER_CONFIG_FILE}")" 47 | PRODUCTVER="$(readConfigKey "productver" "${USER_CONFIG_FILE}")" 48 | BUILDNUM="$(readConfigKey "buildnum" "${USER_CONFIG_FILE}")" 49 | SMALLNUM="$(readConfigKey "smallnum" "${USER_CONFIG_FILE}")" 50 | KERNEL="$(readConfigKey "kernel" "${USER_CONFIG_FILE}")" 51 | KVER="$(readConfigKey "platforms.${PLATFORM}.productvers.\"${PRODUCTVER}\".kver" "${P_FILE}")" 52 | CPU="$(echo $(cat /proc/cpuinfo 2>/dev/null | grep 'model name' | uniq | awk -F':' '{print $2}'))" 53 | RAMTOTAL="$(awk '/MemTotal:/ {printf "%.0f\n", $2 / 1024 / 1024 + 0.5}' /proc/meminfo 2>/dev/null)" 54 | VENDOR="$(dmesg 2>/dev/null | grep -i "DMI:" | head -1 | sed 's/\[.*\] DMI: //i')" 55 | MEV="$(virt-what 2>/dev/null | head -1)" 56 | [ -z "${MEV}" ] && MEV="physical" 57 | DSMINFO="$(readConfigKey "bootscreen.dsminfo" "${USER_CONFIG_FILE}")" 58 | SYSTEMINFO="$(readConfigKey "bootscreen.systeminfo" "${USER_CONFIG_FILE}")" 59 | DISKINFO="$(readConfigKey "bootscreen.diskinfo" "${USER_CONFIG_FILE}")" 60 | HWIDINFO="$(readConfigKey "bootscreen.hwidinfo" "${USER_CONFIG_FILE}")" 61 | GOVERNOR="$(readConfigKey "governor" "${USER_CONFIG_FILE}")" 62 | USBMOUNT="$(readConfigKey "usbmount" "${USER_CONFIG_FILE}")" 63 | HDDSORT="$(readConfigKey "hddsort" "${USER_CONFIG_FILE}")" 64 | BUILDDONE="$(readConfigKey "arc.builddone" "${USER_CONFIG_FILE}")" 65 | ARC_PATCH="$(readConfigKey "arc.patch" "${USER_CONFIG_FILE}")" 66 | 67 | # Build Sanity Check 68 | [ "${BUILDDONE}" = "false" ] && die "Build not completed!" 69 | [[ -z "${MODELID}" || "${MODELID}" != "${MODEL}" ]] && die "Build not completed! Model mismatch! -> Rebuild loader!" 70 | 71 | # HardwareID Check 72 | if [ "${ARC_PATCH}" = "true" ]; then 73 | HARDWAREID="$(readConfigKey "arc.hardwareid" "${USER_CONFIG_FILE}")" 74 | HWID="$(genHWID)" 75 | if [ "${HARDWAREID}" != "${HWID}" ]; then 76 | echo -e "\033[1;31m*** HardwareID mismatch! - You need to reconfigure your Loader - Rebooting to Config Mode! ***\033[0m" 77 | rm -f "${USER_CONFIG_FILE}" 2>/dev/null || true 78 | [ -f "${S_FILE}.bak" ] && mv -f "${S_FILE}.bak" "${S_FILE}" 2>/dev/null || true 79 | sleep 5 80 | rebootTo "config" 81 | exit 1 82 | fi 83 | fi 84 | 85 | if [ "${DSMINFO}" = "true" ]; then 86 | echo -e "\033[1;37mDSM:\033[0m" 87 | echo -e "Model: \033[1;37m${MODELID:-${MODEL}}\033[0m" 88 | echo -e "Platform: \033[1;37m${PLATFORM}\033[0m" 89 | echo -e "Version: \033[1;37m${PRODUCTVER} (${BUILDNUM}$([ ${SMALLNUM:-0} -ne 0 ] && echo "u${SMALLNUM}"))\033[0m" 90 | echo -e "Kernel: \033[1;37m${KVER} (${KERNEL})\033[0m" 91 | echo 92 | fi 93 | if [ "${SYSTEMINFO}" = "true" ]; then 94 | echo -e "\033[1;37mSystem:\033[0m" 95 | echo -e "Vendor: \033[1;37m${VENDOR}\033[0m" 96 | echo -e "CPU: \033[1;37m${CPU}\033[0m" 97 | echo -e "Memory: \033[1;37m${RAMTOTAL}GB\033[0m" 98 | echo -e "Governor: \033[1;37m${GOVERNOR}\033[0m" 99 | echo -e "Type: \033[1;37m${MEV}\033[0m" 100 | [ "${USBMOUNT}" = "true" ] && echo -e "USB Mount: \033[1;37m${USBMOUNT}\033[0m" 101 | echo 102 | fi 103 | if [ "${DISKINFO}" = "true" ]; then 104 | echo -e "\033[1;37mDisks:\033[0m" 105 | echo -e "Disks: \033[1;37m$(lsblk -dpno NAME | grep -v "${LOADER_DISK}" | wc -l)\033[0m" 106 | echo 107 | fi 108 | if [ "${HWIDINFO}" = "true" ]; then 109 | echo -e "\033[1;37mHardwareID:\033[0m" 110 | echo -e "HWID: \033[1;37m$(genHWID)\033[0m" 111 | echo 112 | fi 113 | 114 | if ! readConfigMap "addons" "${USER_CONFIG_FILE}" | grep -q nvmesystem; then 115 | HASATA=0 116 | for D in $(lsblk -dpno NAME); do 117 | [ "${D}" = "${LOADER_DISK}" ] && continue 118 | if echo "sata sas scsi" | grep -qw "$(getBus "${D}")"; then 119 | HASATA=1 120 | break 121 | fi 122 | done 123 | [ "${HASATA}" -eq 0 ] && echo -e "\033[1;31m*** Note: Please insert at least one Sata/SAS/SCSI Disk for System installation, except the Bootloader Disk. ***\033[0m" 124 | fi 125 | 126 | if checkBIOS_VT_d && [ "${KVER:0:1}" = "4" ]; then 127 | echo -e "\033[1;31m*** Notice: Disable Intel(VT-d)/AMD(AMD-V) in BIOS/UEFI settings if you encounter a boot issues. ***\033[0m" 128 | echo 129 | fi 130 | 131 | # Read necessary variables 132 | VID="$(readConfigKey "vid" "${USER_CONFIG_FILE}")" 133 | PID="$(readConfigKey "pid" "${USER_CONFIG_FILE}")" 134 | SN="$(readConfigKey "sn" "${USER_CONFIG_FILE}")" 135 | KERNELPANIC="$(readConfigKey "kernelpanic" "${USER_CONFIG_FILE}")" 136 | DT="$(readConfigKey "platforms.${PLATFORM}.dt" "${P_FILE}")" 137 | KVER="$(readConfigKey "platforms.${PLATFORM}.productvers.\"${PRODUCTVER}\".kver" "${P_FILE}")" 138 | EMMCBOOT="$(readConfigKey "emmcboot" "${USER_CONFIG_FILE}")" 139 | MODBLACKLIST="$(readConfigKey "modblacklist" "${USER_CONFIG_FILE}")" 140 | 141 | declare -A CMDLINE 142 | 143 | # Automated Cmdline 144 | CMDLINE['syno_hw_version']="${MODELID:-${MODEL}}" 145 | CMDLINE['vid']="${VID:-"0x46f4"}" 146 | CMDLINE['pid']="${PID:-"0x0001"}" 147 | CMDLINE['sn']="${SN}" 148 | 149 | # NIC Cmdline 150 | ETHX=$(find /sys/class/net/ -mindepth 1 -maxdepth 1 -name 'eth*' -exec basename {} \; | sort) 151 | ETHM=$(readConfigKey "${MODEL}.ports" "${S_FILE}") 152 | ETHN=$(wc -w <<< "${ETHX}") 153 | ETHM=${ETHM:-${ETHN}} 154 | NIC=0 155 | for N in ${ETHX}; do 156 | MAC="$(readConfigKey "${N}" "${USER_CONFIG_FILE}")" 157 | [ -z "${MAC}" ] && MAC="$(cat /sys/class/net/${N}/address 2>/dev/null)" 158 | CMDLINE["mac$((++NIC))"]="${MAC}" 159 | [ "${NIC}" -ge "${ETHM}" ] && break 160 | done 161 | CMDLINE['netif_num']="${NIC}" 162 | 163 | # Boot Cmdline 164 | if grep -q "force_junior" /proc/cmdline; then 165 | CMDLINE["force_junior"]="" 166 | fi 167 | if grep -q "recovery" /proc/cmdline; then 168 | CMDLINE["recovery"]="" 169 | fi 170 | 171 | if [ "${EFI}" = "1" ]; then 172 | CMDLINE['withefi']="" 173 | else 174 | CMDLINE['noefi']="" 175 | fi 176 | 177 | # DSM Cmdline 178 | if [ "${KVER:0:1}" = "4" ]; then 179 | if [ "${BUS}" != "usb" ]; then 180 | SZ=$(blockdev --getsz "${LOADER_DISK}" 2>/dev/null) # SZ=$(cat /sys/block/${LOADER_DISK/\/dev\//}/size) 181 | SS=$(blockdev --getss "${LOADER_DISK}" 2>/dev/null) # SS=$(cat /sys/block/${LOADER_DISK/\/dev\//}/queue/hw_sector_size) 182 | SIZE=$((${SZ:-0} * ${SS:-0} / 1024 / 1024 + 10)) 183 | # Read SATADoM type 184 | SATADOM="$(readConfigKey "satadom" "${USER_CONFIG_FILE}")" 185 | CMDLINE['synoboot_satadom']="${SATADOM:-2}" 186 | CMDLINE['dom_szmax']="${SIZE}" 187 | fi 188 | CMDLINE['elevator']="elevator" 189 | else 190 | CMDLINE['split_lock_detect']="off" 191 | fi 192 | 193 | if [ "${DT}" = "true" ]; then 194 | CMDLINE['syno_ttyS0']="serial,0x3f8" 195 | CMDLINE['syno_ttyS1']="serial,0x2f8" 196 | else 197 | CMDLINE['SMBusHddDynamicPower']="1" 198 | CMDLINE['syno_hdd_detect']="0" 199 | CMDLINE['syno_hdd_powerup_seq']="0" 200 | fi 201 | 202 | CMDLINE['HddHotplug']="1" 203 | CMDLINE['vender_format_version']="2" 204 | CMDLINE['skip_vender_mac_interfaces']="0,1,2,3,4,5,6,7" 205 | CMDLINE['earlyprintk']="" 206 | CMDLINE['earlycon']="uart8250,io,0x3f8,115200n8" 207 | CMDLINE['console']="ttyS0,115200n8" 208 | CMDLINE['consoleblank']="600" 209 | CMDLINE['root']="/dev/md0" 210 | CMDLINE['loglevel']="15" 211 | CMDLINE['log_buf_len']="32M" 212 | CMDLINE['rootwait']="" 213 | CMDLINE['panic']="${KERNELPANIC:-0}" 214 | CMDLINE['pcie_aspm']="off" 215 | CMDLINE['nowatchdog']="" 216 | CMDLINE['mev']="${MEV}" 217 | 218 | if [ "${MEV}" = "vmware" ]; then 219 | CMDLINE['tsc']="reliable" 220 | CMDLINE['pmtmr']="0x0" 221 | fi 222 | 223 | if [ "${HDDSORT}" = "true" ]; then 224 | CMDLINE['hddsort']="" 225 | fi 226 | if [ "${USBMOUNT}" = "true" ]; then 227 | CMDLINE['usbinternal']="" 228 | fi 229 | if [ -n "${GOVERNOR}" ]; then 230 | CMDLINE['governor']="${GOVERNOR}" 231 | fi 232 | 233 | if is_in_array "${PLATFORM}" "${XAPICRL[@]}"; then 234 | CMDLINE['nox2apic']="" 235 | fi 236 | 237 | if is_in_array "${PLATFORM}" "${IGFXRL[@]}"; then 238 | CMDLINE["intel_iommu"]="igfx_off" 239 | fi 240 | 241 | if [ "${PLATFORM}" = "purley" ] || [ "${PLATFORM}" = "broadwellnkv2" ]; then 242 | CMDLINE['SASmodel']="1" 243 | fi 244 | 245 | CMDLINE['modprobe.blacklist']="${MODBLACKLIST}" 246 | if ! is_in_array "${PLATFORM}" "${MPT3PL[@]}"; then 247 | if ! echo "${CMDLINE['modprobe.blacklist']}" | grep -q "mpt3sas"; then 248 | [ -n "${CMDLINE['modprobe.blacklist']}" ] && CMDLINE['modprobe.blacklist']+="," 249 | CMDLINE['modprobe.blacklist']+="mpt3sas" 250 | fi 251 | fi 252 | 253 | # Read user network settings 254 | while IFS=': ' read -r KEY VALUE; do 255 | [ -n "${KEY}" ] && CMDLINE["network.${KEY}"]="${VALUE}" 256 | done < <(readConfigMap "network" "${USER_CONFIG_FILE}") 257 | 258 | # Read user cmdline 259 | while IFS=': ' read -r KEY VALUE; do 260 | [ -n "${KEY}" ] && CMDLINE["${KEY}"]="${VALUE}" 261 | done < <(readConfigMap "cmdline" "${USER_CONFIG_FILE}") 262 | 263 | # Prepare command line 264 | CMDLINE_LINE="" 265 | for KEY in "${!CMDLINE[@]}"; do 266 | VALUE="${CMDLINE[${KEY}]}" 267 | CMDLINE_LINE+=" ${KEY}" 268 | [ -n "${VALUE}" ] && CMDLINE_LINE+="=${VALUE}" 269 | done 270 | CMDLINE_LINE="$(echo "${CMDLINE_LINE}" | sed 's/^ //')" # Remove leading space 271 | echo "${CMDLINE_LINE}" >"${PART1_PATH}/cmdline.yml" 272 | 273 | # Boot 274 | DIRECTBOOT="$(readConfigKey "directboot" "${USER_CONFIG_FILE}")" 275 | if [ "${DIRECTBOOT}" = "true" ]; then 276 | CMDLINE_DIRECT=$(echo ${CMDLINE_LINE} | sed 's/>/\\\\>/g') # Escape special chars 277 | grub-editenv ${USER_GRUBENVFILE} set dsm_cmdline="${CMDLINE_DIRECT}" 278 | grub-editenv ${USER_GRUBENVFILE} set next_entry="direct" 279 | echo -e "\033[1;34mReboot with Directboot\033[0m" 280 | reboot 281 | exit 0 282 | elif [ "${DIRECTBOOT}" = "false" ]; then 283 | grub-editenv ${USER_GRUBENVFILE} unset dsm_cmdline 284 | grub-editenv ${USER_GRUBENVFILE} unset next_entry 285 | KERNELLOAD="$(readConfigKey "kernelload" "${USER_CONFIG_FILE}")" 286 | BOOTIPWAIT="$(readConfigKey "bootipwait" "${USER_CONFIG_FILE}")" 287 | [ -z "${BOOTIPWAIT}" ] && BOOTIPWAIT=30 288 | if [ "${ARC_PATCH}" = "true" ]; then 289 | echo -e "\033[1;37mDetected ${ETHN} NIC:\033[0m" 290 | echo -e "\033[1;34mUsing ${NIC} NIC for Arc Patch\033[0m" 291 | else 292 | echo -e "\033[1;37mDetected ${ETHN} NIC:\033[0m" 293 | fi 294 | 295 | [ ! -f /var/run/dhcpcd/pid ] && /etc/init.d/S41dhcpcd restart >/dev/null 2>&1 && sleep 3 || true 296 | IPCON="" 297 | checkNIC || true 298 | echo 299 | 300 | DSMLOGO="$(readConfigKey "bootscreen.dsmlogo" "${USER_CONFIG_FILE}")" 301 | if [ "${DSMLOGO}" = "true" ] && [ -c "/dev/fb0" ]; then 302 | [[ "${IPCON}" =~ ^169\.254\..* ]] && IPCON="" 303 | [ -n "${IPCON}" ] && URL="http://${IPCON}:5000" || URL="http://find.synology.com/" 304 | python3 "${ARC_PATH}/include/functions.py" "makeqr" -d "${URL}" -l "6" -o "${TMP_PATH}/qrcode_boot.png" 305 | [ -f "${TMP_PATH}/qrcode_boot.png" ] && echo | fbv -acufi "${TMP_PATH}/qrcode_boot.png" >/dev/null 2>/dev/null || true 306 | fi 307 | 308 | for T in $(busybox w 2>/dev/null | grep -v 'TTY' | awk '{print $2}'); do 309 | if [ -w "/dev/${T}" ]; then 310 | [ -n "${IPCON}" ] && echo -e "Use \033[1;34mhttp://${IPCON}:5000\033[0m or try \033[1;34mhttp://find.synology.com/ \033[0mto find DSM and proceed.\n\n\033[1;37mThis interface will not be operational. Wait a few minutes - Network will be unreachable until DSM boot.\033[0m\n" >"/dev/${T}" 2>/dev/null \ 311 | || echo -e "Try \033[1;34mhttp://find.synology.com/ \033[0mto find DSM and proceed.\n\n\033[1;37mThis interface will not be operational. Wait a few minutes - Network will be unreachable until DSM boot.\nNo IP found - DSM will not work properly!\033[0m\n" >"/dev/${T}" 2>/dev/null 312 | fi 313 | done 314 | 315 | echo -e "\033[1;37mLoading DSM Kernel...\033[0m" 316 | if [ ! -f "${TMP_PATH}/.bootlock" ]; then 317 | touch "${TMP_PATH}/.bootlock" 318 | kexec -l "${MOD_ZIMAGE_FILE}" --initrd "${MOD_RDGZ_FILE}" --command-line="${CMDLINE_LINE} kexecboot" || die "Failed to load DSM Kernel!" 319 | [ "${KERNELLOAD}" = "kexec" ] && kexec -e || poweroff 320 | fi 321 | echo -e "\033[1;37mBooting DSM...\033[0m" 322 | exit 0 323 | fi 324 | -------------------------------------------------------------------------------- /files/initrd/opt/arc/bzImage-template-v4.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AuxXxilium/arc/5fc208ac2e6bc86eddb48a22fad3a46aa35e48a9/files/initrd/opt/arc/bzImage-template-v4.gz -------------------------------------------------------------------------------- /files/initrd/opt/arc/bzImage-template-v5.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AuxXxilium/arc/5fc208ac2e6bc86eddb48a22fad3a46aa35e48a9/files/initrd/opt/arc/bzImage-template-v5.gz -------------------------------------------------------------------------------- /files/initrd/opt/arc/bzImage-to-vmlinux.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | read_u8() { 4 | dd if="${1}" bs=1 skip="$((${2}))" count=1 2>/dev/null | od -An -tu1 | grep -Eo '[0-9]+' 5 | } 6 | read_u32() { 7 | dd if="${1}" bs=1 skip="$((${2}))" count=4 2>/dev/null | od -An -tu4 | grep -Eo '[0-9]+' 8 | } 9 | 10 | set -x 11 | setup_size=$(read_u8 "${1}" 0x1f1) 12 | payload_offset=$(read_u32 "${1}" 0x248) 13 | payload_length=$(read_u32 "${1}" 0x24c) 14 | inner_pos=$(((setup_size + 1) * 512)) 15 | 16 | tail -c+$(($inner_pos + 1)) "${1}" | tail -c+$(($payload_offset + 1)) | head -c "${payload_length}" | head -c $(($payload_length - 4)) | unlzma >"${2}" -------------------------------------------------------------------------------- /files/initrd/opt/arc/evo.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | ############################################################################### 4 | # Overlay Init Section 5 | [[ -z "${ARC_PATH}" || ! -d "${ARC_PATH}/include" ]] && ARC_PATH="$(cd "$(dirname "${BASH_SOURCE[0]}")" 2>/dev/null && pwd)" 6 | 7 | . "${ARC_PATH}/arc-functions.sh" 8 | . "${ARC_PATH}/include/functions.sh" 9 | . "${ARC_PATH}/include/addons.sh" 10 | . "${ARC_PATH}/include/modules.sh" 11 | . "${ARC_PATH}/include/update.sh" 12 | 13 | # Check System 14 | onlineCheck 15 | systemCheck 16 | readData 17 | 18 | ############################################################################### 19 | # Mounts backtitle dynamically 20 | function backtitle() { 21 | BACKTITLE="${ARC_TITLE}$([ -n "${NEWTAG}" ] && [ -n "${ARC_VERSION}" ] && [ ${ARC_VERSION//[!0-9]/} -lt ${NEWTAG//[!0-9]/} ] && echo " > ${NEWTAG}") | " 22 | BACKTITLE+="${MODEL:-(Model)} | " 23 | BACKTITLE+="${DSMVER:-(Version)} | " 24 | BACKTITLE+="${IPCON:-(no IP)} | " 25 | BACKTITLE+="Patch: ${ARC_PATCH} | " 26 | BACKTITLE+="Config: ${CONFDONE} | " 27 | BACKTITLE+="Build: ${BUILDDONE} | " 28 | BACKTITLE+="${MEV}(${BUS}) | " 29 | [ -n "${KEYMAP}" ] && BACKTITLE+="KB: ${KEYMAP}" 30 | [ "${ARC_OFFLINE}" = "true" ] && BACKTITLE+=" | Offline" 31 | echo "${BACKTITLE}" 32 | } 33 | 34 | ############################################################################### 35 | # Advanced Menu 36 | function advancedMenu() { 37 | NEXT="a" 38 | while true; do 39 | rm -f "${TMP_PATH}/menu" "${TMP_PATH}/resp" >/dev/null 2>&1 || true 40 | write_menu "=" "\Z4===== System ====\Zn" 41 | 42 | if [ "${CONFDONE}" = "true" ]; then 43 | if [ "${BOOTOPTS}" = "true" ]; then 44 | write_menu "6" "\Z1Hide Boot Options\Zn" 45 | write_menu_value "m" "Kernelload" "${KERNELLOAD}" 46 | write_menu_value "E" "eMMC Boot Support" "${EMMCBOOT}" 47 | if [ "${DIRECTBOOT}" = "false" ]; then 48 | write_menu_value "i" "Boot IP Waittime" "${BOOTIPWAIT}" 49 | fi 50 | write_menu_value "q" "Directboot" "${DIRECTBOOT}" 51 | write_menu_value "W" "RD Compression" "${RD_COMPRESSED}" 52 | write_menu_value "X" "Sata DOM" "${SATADOM}" 53 | write_menu_value "u" "LKM Version" "${LKM}" 54 | else 55 | write_menu "6" "\Z1Show Boot Options\Zn" 56 | fi 57 | 58 | if [ "${DSMOPTS}" = "true" ]; then 59 | write_menu "7" "\Z1Hide DSM Options\Zn" 60 | write_menu "j" "Cmdline" 61 | write_menu "k" "Synoinfo" 62 | write_menu "N" "Add new User" 63 | write_menu "t" "Change User Password" 64 | write_menu "J" "Reset Network Config" 65 | write_menu "T" "Disable all scheduled Tasks" 66 | write_menu "M" "Mount DSM Storage Pool" 67 | write_menu "l" "Edit User Config" 68 | write_menu "s" "Allow Downgrade Version" 69 | else 70 | write_menu "7" "\Z1Show DSM Options\Zn" 71 | fi 72 | fi 73 | 74 | if [ "${LOADEROPTS}" = "true" ]; then 75 | write_menu "8" "\Z1Hide Loader Options\Zn" 76 | write_menu "D" "StaticIP for Loader/DSM" 77 | write_menu "f" "Bootscreen Options" 78 | write_menu "U" "Change Loader Password" 79 | write_menu "Z" "Change Loader Ports" 80 | write_menu "w" "Reset Loader to Defaults" 81 | write_menu "L" "Grep Logs from dbgutils" 82 | write_menu "B" "Grep DSM Config from Backup" 83 | write_menu "=" "\Z1== Edit with caution! ==\Zn" 84 | write_menu "C" "Clone Loader to another Disk" 85 | write_menu "n" "Grub Bootloader Config" 86 | write_menu "y" "Choose a Keymap for Loader" 87 | write_menu "F" "\Z1Formate Disks\Zn" 88 | else 89 | write_menu "8" "\Z1Show Loader Options\Zn" 90 | fi 91 | 92 | dialog --clear --default-item ${NEXT} --backtitle "$(backtitle)" --title "Easy UI Advanced" --colors \ 93 | --cancel-label "Back" \ 94 | --menu "" 0 0 0 --file "${TMP_PATH}/menu" \ 95 | 2>"${TMP_PATH}/resp" 96 | RET=$? 97 | case ${RET} in 98 | 0) 99 | resp="$(cat "${TMP_PATH}/resp" 2>/dev/null)" 100 | [ -z "${resp}" ] && return 101 | case ${resp} in 102 | # DSM Section 103 | 7) [ "${DSMOPTS}" = "true" ] && DSMOPTS='false' || DSMOPTS='true' 104 | DSMOPTS="${DSMOPTS}" 105 | NEXT="7" 106 | ;; 107 | j) cmdlineMenu; NEXT="j" ;; 108 | k) synoinfoMenu; NEXT="k" ;; 109 | l) editUserConfig; NEXT="l" ;; 110 | s) downgradeMenu; NEXT="s" ;; 111 | t) resetPassword; NEXT="t" ;; 112 | N) addNewDSMUser; NEXT="N" ;; 113 | J) resetDSMNetwork; NEXT="J" ;; 114 | M) mountDSM; NEXT="M" ;; 115 | T) disablescheduledTasks; NEXT="T" ;; 116 | B) getbackup; NEXT="B" ;; 117 | # Loader Section 118 | 8) [ "${LOADEROPTS}" = "true" ] && LOADEROPTS='false' || LOADEROPTS='true' 119 | LOADEROPTS="${LOADEROPTS}" 120 | NEXT="8" 121 | ;; 122 | D) staticIPMenu; NEXT="D" ;; 123 | f) bootScreen; NEXT="f" ;; 124 | Z) loaderPorts; NEXT="Z" ;; 125 | U) loaderPassword; NEXT="U" ;; 126 | L) greplogs; NEXT="L" ;; 127 | w) resetLoader; NEXT="w" ;; 128 | C) cloneLoader; NEXT="C" ;; 129 | n) editGrubCfg; NEXT="n" ;; 130 | y) keymapMenu; NEXT="y" ;; 131 | F) formatDisks; NEXT="F" ;; 132 | 6) [ "${BOOTOPTS}" = "true" ] && BOOTOPTS='false' || BOOTOPTS='true' 133 | BOOTOPTS="${BOOTOPTS}" 134 | NEXT="6" 135 | ;; 136 | m) [ "${KERNELLOAD}" = "kexec" ] && KERNELLOAD='power' || KERNELLOAD='kexec' 137 | writeConfigKey "kernelload" "${KERNELLOAD}" "${USER_CONFIG_FILE}" 138 | NEXT="m" 139 | ;; 140 | E) [ "${EMMCBOOT}" = "true" ] && EMMCBOOT='false' || EMMCBOOT='true' 141 | if [ "${EMMCBOOT}" = "false" ]; then 142 | writeConfigKey "emmcboot" "false" "${USER_CONFIG_FILE}" 143 | deleteConfigKey "synoinfo.disk_swap" "${USER_CONFIG_FILE}" 144 | deleteConfigKey "synoinfo.supportraid" "${USER_CONFIG_FILE}" 145 | deleteConfigKey "synoinfo.support_emmc_boot" "${USER_CONFIG_FILE}" 146 | deleteConfigKey "synoinfo.support_install_only_dev" "${USER_CONFIG_FILE}" 147 | elif [ "${EMMCBOOT}" = "true" ]; then 148 | writeConfigKey "emmcboot" "true" "${USER_CONFIG_FILE}" 149 | writeConfigKey "synoinfo.disk_swap" "no" "${USER_CONFIG_FILE}" 150 | writeConfigKey "synoinfo.supportraid" "no" "${USER_CONFIG_FILE}" 151 | writeConfigKey "synoinfo.support_emmc_boot" "yes" "${USER_CONFIG_FILE}" 152 | writeConfigKey "synoinfo.support_install_only_dev" "yes" "${USER_CONFIG_FILE}" 153 | fi 154 | writeConfigKey "arc.builddone" "false" "${USER_CONFIG_FILE}" 155 | BUILDDONE="$(readConfigKey "arc.builddone" "${USER_CONFIG_FILE}")" 156 | NEXT="E" 157 | ;; 158 | W) RD_COMPRESSED=$([ "${RD_COMPRESSED}" = "true" ] && echo 'false' || echo 'true') 159 | writeConfigKey "rd-compressed" "${RD_COMPRESSED}" "${USER_CONFIG_FILE}" 160 | writeConfigKey "arc.builddone" "false" "${USER_CONFIG_FILE}" 161 | BUILDDONE="$(readConfigKey "arc.builddone" "${USER_CONFIG_FILE}")" 162 | NEXT="W" 163 | ;; 164 | X) satadomMenu; NEXT="X" ;; 165 | u) [ "${LKM}" = "prod" ] && LKM='dev' || LKM='prod' 166 | writeConfigKey "lkm" "${LKM}" "${USER_CONFIG_FILE}" 167 | writeConfigKey "arc.builddone" "false" "${USER_CONFIG_FILE}" 168 | BUILDDONE="$(readConfigKey "arc.builddone" "${USER_CONFIG_FILE}")" 169 | NEXT="u" 170 | ;; 171 | i) bootipwaittime; NEXT="i" ;; 172 | q) [ "${DIRECTBOOT}" = "false" ] && DIRECTBOOT='true' || DIRECTBOOT='false' 173 | grub-editenv ${USER_GRUBENVFILE} create 174 | writeConfigKey "directboot" "${DIRECTBOOT}" "${USER_CONFIG_FILE}" 175 | NEXT="q" 176 | ;; 177 | esac 178 | ;; 179 | *) 180 | break 181 | ;; 182 | esac 183 | done 184 | return 185 | } 186 | 187 | ############################################################################### 188 | ############################################################################### 189 | # Main loop 190 | if [ "${ARC_MODE}" = "update" ]; then 191 | if [ "${ARC_OFFLINE}" != "true" ]; then 192 | updateLoader 193 | else 194 | dialog --backtitle "$(backtitle)" --title "Arc Update" \ 195 | --infobox "Update is not possible in Offline Mode!" 5 40 196 | sleep 3 197 | exec reboot 198 | fi 199 | elif [ "${ARC_MODE}" = "automated" ]; then 200 | if [ "${BUILDDONE}" = "false" ] || [ "${MODEL}" != "${MODELID}" ]; then 201 | arcModel 202 | else 203 | make 204 | fi 205 | elif [ "${ARC_MODE}" = "config" ]; then 206 | NEXT="1" 207 | while true; do 208 | rm -f "${TMP_PATH}/menu" "${TMP_PATH}/resp" >/dev/null 2>&1 || true 209 | write_menu "=" "\Z4===== Main =====\Zn" 210 | if [ -z "${USERID}" ] && [ "${ARC_OFFLINE}" = "false" ]; then 211 | write_menu_value "0" "HardwareID" "${HARDWAREID}" 212 | fi 213 | 214 | write_menu_value "1" "Model" "${MODEL}" 215 | 216 | if [ "${CONFDONE}" = "true" ]; then 217 | write_menu_value "e" "Version" "${PRODUCTVER}" 218 | write_menu_value "=" "DT" "${DT}" 219 | write_menu_value "=" "Platform" "${PLATFORM}" 220 | 221 | if [ -n "${USERID}" ] && [ "${ARC_OFFLINE}" = "false" ]; then 222 | write_menu_value "p" "Arc Patch" "${ARC_PATCH}" 223 | elif [ "${ARC_OFFLINE}" = "false" ]; then 224 | write_menu "p" "Arc Patch: \Z4Register HardwareID first\Zn" 225 | else 226 | write_menu "p" "SN/Mac Options" 227 | fi 228 | 229 | if [ "${PLATFORM}" = "epyc7002" ]; then 230 | CPUINFO="$(cat /proc/cpuinfo | grep MHz | wc -l)" 231 | if [ "${CPUINFO}" -gt 24 ]; then 232 | write_menu "=" "Custom Kernel should be used for this CPU" 233 | fi 234 | write_menu_value "K" "Kernel" "${KERNEL}" 235 | fi 236 | 237 | write_menu "b" "Addons" 238 | 239 | for addon in "cpufreqscaling" "storagepanel"; do 240 | if readConfigMap "addons" "${USER_CONFIG_FILE}" | grep -q "${addon}"; then 241 | case "${addon}" in 242 | "cpufreqscaling") write_menu_value "g" "Scaling Governor" "${GOVERNOR}" ;; 243 | "storagepanel") write_menu_value "P" "StoragePanel" "${STORAGEPANEL:-auto}" ;; 244 | esac 245 | fi 246 | done 247 | 248 | write_menu "d" "Modules" 249 | write_menu_value "O" "Official Driver Priority" "${ODP}" 250 | 251 | if [ "${DT}" = "false" ] && [ "${SATACONTROLLER}" -gt 0 ]; then 252 | write_menu_value "S" "PortMap" "${REMAP}" 253 | write_menu_value "=" "Mapping" "${PORTMAP}" 254 | fi 255 | 256 | if [ "${DT}" = "true" ]; then 257 | write_menu_value "H" "Hotplug/SortDrives" "${HDDSORT}" 258 | else 259 | write_menu_value "h" "USB Disk(s) as Internal" "${USBMOUNT}" 260 | fi 261 | fi 262 | 263 | write_menu_value "c" "Offline Mode" "${ARC_OFFLINE}" 264 | write_menu "9" "Advanced Options" 265 | write_menu "=" "\Z4===== Diag =====\Zn" 266 | write_menu "a" "Sysinfo" 267 | write_menu "A" "Networkdiag" 268 | write_menu "=" "\Z4===== Misc =====\Zn" 269 | write_menu "x" "Backup/Restore/Recovery" 270 | [ "${ARC_OFFLINE}" = "false" ] && write_menu "z" "Update Menu" 271 | write_menu "I" "Power/Service Menu" 272 | write_menu "V" "Credits" 273 | 274 | if [ "${CONFDONE}" = "false" ]; then 275 | EXTRA_LABEL="Config" 276 | elif [ "${CONFDONE}" = "true" ]; then 277 | EXTRA_LABEL="Build" 278 | elif [ "${BUILDDONE}" = "true" ]; then 279 | EXTRA_LABEL="Boot" 280 | fi 281 | if [ "$TERM" != "xterm-256color" ]; then 282 | WEBCONFIG="Webconfig: http://${IPCON}:${HTTPPORT:-7080}" 283 | else 284 | WEBCONFIG="" 285 | fi 286 | dialog --clear --default-item ${NEXT} --backtitle "$(backtitle)" --title "Easy UI" --colors \ 287 | --cancel-label "Advanced UI" --help-button --help-label "Exit" \ 288 | --extra-button --extra-label "${EXTRA_LABEL}" \ 289 | --menu "${WEBCONFIG}" 0 0 0 --file "${TMP_PATH}/menu" \ 290 | 2>"${TMP_PATH}/resp" 291 | RET=$? 292 | case ${RET} in 293 | 0) 294 | resp="$(cat "${TMP_PATH}/resp" 2>/dev/null)" 295 | [ -z "${resp}" ] && return 296 | case ${resp} in 297 | 0) genHardwareID; NEXT="0" ;; 298 | 1) arcModel; NEXT="2" ;; 299 | b) addonMenu; NEXT="b" ;; 300 | d) modulesMenu; NEXT="d" ;; 301 | e) ONLYVERSION="true" && writeConfigKey "productver" "" "${USER_CONFIG_FILE}" && arcVersion; NEXT="e" ;; 302 | p) ONLYPATCH="true" && checkHardwareID && arcPatch; NEXT="p" ;; 303 | S) storageMenu; NEXT="S" ;; 304 | g) governorMenu; NEXT="g" ;; 305 | P) storagepanelMenu; NEXT="P" ;; 306 | K) KERNEL=$([ "${KERNEL}" = "official" ] && echo 'custom' || echo 'official') 307 | writeConfigKey "kernel" "${KERNEL}" "${USER_CONFIG_FILE}" 308 | dialog --backtitle "$(backtitle)" --title "Kernel" \ 309 | --infobox "Switching Kernel to ${KERNEL}! Stay patient..." 3 50 310 | if [ "${ODP}" = "true" ]; then 311 | ODP="false" 312 | writeConfigKey "odp" "${ODP}" "${USER_CONFIG_FILE}" 313 | fi 314 | PLATFORM="$(readConfigKey "platform" "${USER_CONFIG_FILE}")" 315 | PRODUCTVER="$(readConfigKey "productver" "${USER_CONFIG_FILE}")" 316 | KVER="$(readConfigKey "platforms.${PLATFORM}.productvers.\"${PRODUCTVER}\".kver" "${P_FILE}")" 317 | is_in_array "${PLATFORM}" "${KVER5L[@]}" && KVERP="${PRODUCTVER}-${KVER}" || KVERP="${KVER}" 318 | if [ -n "${PLATFORM}" ] && [ -n "${KVERP}" ]; then 319 | writeConfigKey "modules" "{}" "${USER_CONFIG_FILE}" 320 | mergeConfigModules "$(getAllModules "${PLATFORM}" "${KVERP}" | awk '{print $1}')" "${USER_CONFIG_FILE}" 321 | fi 322 | writeConfigKey "arc.builddone" "false" "${USER_CONFIG_FILE}" 323 | BUILDDONE="$(readConfigKey "arc.builddone" "${USER_CONFIG_FILE}")" 324 | NEXT="K" 325 | ;; 326 | H) [ "${HDDSORT}" = "true" ] && HDDSORT='false' || HDDSORT='true' 327 | writeConfigKey "hddsort" "${HDDSORT}" "${USER_CONFIG_FILE}" 328 | writeConfigKey "arc.builddone" "false" "${USER_CONFIG_FILE}" 329 | BUILDDONE="$(readConfigKey "arc.builddone" "${USER_CONFIG_FILE}")" 330 | NEXT="H" 331 | ;; 332 | h) [ "${USBMOUNT}" = "true" ] && USBMOUNT='false' || USBMOUNT='true' 333 | writeConfigKey "usbmount" "${USBMOUNT}" "${USER_CONFIG_FILE}" 334 | writeConfigKey "arc.builddone" "false" "${USER_CONFIG_FILE}" 335 | BUILDDONE="$(readConfigKey "arc.builddone" "${USER_CONFIG_FILE}")" 336 | NEXT="h" 337 | ;; 338 | O) [ "${ODP}" = "false" ] && ODP='true' || ODP='false' 339 | writeConfigKey "odp" "${ODP}" "${USER_CONFIG_FILE}" 340 | writeConfigKey "arc.builddone" "false" "${USER_CONFIG_FILE}" 341 | BUILDDONE="$(readConfigKey "arc.builddone" "${USER_CONFIG_FILE}")" 342 | NEXT="O" 343 | ;; 344 | c) ARC_OFFLINE=$([ "${ARC_OFFLINE}" = "true" ] && echo 'false' || echo 'true') 345 | writeConfigKey "arc.offline" "${ARC_OFFLINE}" "${USER_CONFIG_FILE}" 346 | [ "${ARC_OFFLINE}" = "false" ] && exec arc.sh 347 | NEXT="c" 348 | ;; 349 | # Diag Section 350 | a) sysinfo; NEXT="a" ;; 351 | A) networkdiag; NEXT="A" ;; 352 | # Misc Settings 353 | x) backupMenu; NEXT="x" ;; 354 | z) updateMenu; NEXT="z" ;; 355 | I) rebootMenu; NEXT="I" ;; 356 | V) credits; NEXT="V" ;; 357 | 9) advancedMenu; NEXT="9" ;; 358 | esac 359 | ;; 360 | 1) 361 | exec arc.sh 362 | ;; 363 | 3) 364 | if [ "${CONFDONE}" = "false" ]; then 365 | arcModel 366 | elif [ "${CONFDONE}" = "true" ]; then 367 | arcSummary 368 | elif [ "${BUILDDONE}" = "true" ]; then 369 | boot 370 | fi 371 | ;; 372 | *) 373 | break 374 | ;; 375 | esac 376 | done 377 | else 378 | echo "Unknown Mode: ${ARC_MODE} - Rebooting to Config Mode" 379 | sleep 3 380 | rebootTo config 381 | fi 382 | 383 | # Inform user 384 | echo -e "Call \033[1;34marc.sh\033[0m to configure Loader" 385 | echo 386 | echo -e "Web Config: \033[1;34mhttp://${IPCON}:${HTTPPORT:-7080}\033[0m" 387 | echo 388 | echo -e "SSH Access:" 389 | echo -e "IP: \033[1;34m${IPCON}\033[0m" 390 | echo -e "User: \033[1;34mroot\033[0m" 391 | echo -e "Password: \033[1;34marc\033[0m" 392 | echo 393 | -------------------------------------------------------------------------------- /files/initrd/opt/arc/extract-vmlinux: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # SPDX-License-Identifier: GPL-2.0-only 3 | # ---------------------------------------------------------------------- 4 | # extract-vmlinux - Extract uncompressed vmlinux from a kernel image 5 | # 6 | # Inspired from extract-ikconfig 7 | # (c) 2009,2010 Dick Streefland 8 | # 9 | # (c) 2011 Corentin Chary 10 | # 11 | # ---------------------------------------------------------------------- 12 | 13 | check_vmlinux() { 14 | # Use readelf to check if it's a valid ELF 15 | # TODO: find a better to way to check that it's really vmlinux 16 | # and not just an elf 17 | readelf -h $1 >/dev/null 2>&1 || return 1 18 | 19 | cat $1 20 | exit 0 21 | } 22 | 23 | try_decompress() { 24 | # The obscure use of the "tr" filter is to work around older versions of 25 | # "grep" that report the byte offset of the line instead of the pattern. 26 | 27 | # Try to find the header ($1) and decompress from here 28 | for pos in $(tr "$1\n$2" "\n$2=" <"$img" | grep -abo "^$2"); do 29 | pos=${pos%%:*} 30 | tail -c+$pos "$img" | $3 >$tmp 2>/dev/null 31 | check_vmlinux $tmp 32 | done 33 | } 34 | 35 | # Check invocation: 36 | me=${0##*/} 37 | img=$1 38 | if [ $# -ne 1 ] || [ ! -s "$img" ]; then 39 | echo "Usage: $me " >&2 40 | exit 2 41 | fi 42 | 43 | # Prepare temp files: 44 | tmp=$(mktemp /tmp/vmlinux-XXX) 45 | trap "rm -f $tmp" 0 46 | 47 | # That didn't work, so retry after decompression. 48 | try_decompress '\037\213\010' xy gunzip 49 | try_decompress '\3757zXZ\000' abcde unxz 50 | try_decompress 'BZh' xy bunzip2 51 | try_decompress '\135\0\0\0' xxx unlzma 52 | try_decompress '\211\114\132' xy 'lzop -d' 53 | try_decompress '\002!L\030' xxx 'lz4 -d' 54 | try_decompress '(\265/\375' xxx unzstd 55 | 56 | # Finally check for uncompressed images or objects: 57 | check_vmlinux $img 58 | 59 | # Bail out: 60 | echo "$me: Cannot find vmlinux." >&2 -------------------------------------------------------------------------------- /files/initrd/opt/arc/grub.img.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AuxXxilium/arc/5fc208ac2e6bc86eddb48a22fad3a46aa35e48a9/files/initrd/opt/arc/grub.img.gz -------------------------------------------------------------------------------- /files/initrd/opt/arc/include/addons.sh: -------------------------------------------------------------------------------- 1 | ############################################################################### 2 | # Return list of available addons 3 | # 1 - Platform 4 | function availableAddons() { 5 | if [ -z "${1}" ]; then 6 | echo "" 7 | return 1 8 | fi 9 | MACHINE="$(virt-what 2>/dev/null | head -1)" 10 | [ -z "${MACHINE}" ] && MACHINE="physical" || true 11 | for D in $(find "${ADDONS_PATH}" -maxdepth 1 -type d 2>/dev/null | sort); do 12 | [ ! -f "${D}/manifest.yml" ] && continue 13 | local ADDON=$(basename "${D}") 14 | local SYSTEM=$(readConfigKey "system" "${D}/manifest.yml") 15 | [ "${SYSTEM}" = true ] && continue 16 | local AVAILABLE="$(readConfigKey "${1}" "${D}/manifest.yml")" 17 | [ "${AVAILABLE}" = false ] && continue 18 | if [ "${MACHINE}" != "physical" ] && ( [ "${ADDON}" = "cpufreqscaling" ] || [ "${ADDON}" = "fancontrol" ] ); then 19 | continue 20 | fi 21 | local DESC="$(readConfigKey "description" "${D}/manifest.yml")" 22 | local BETA="$(readConfigKey "beta" "${D}/manifest.yml")" 23 | local TARGET="$(readConfigKey "target" "${D}/manifest.yml")" 24 | [ "${BETA}" = true ] && BETA="(Beta) " || BETA="" 25 | if [ "${TARGET}" = "app" ]; then 26 | [ "${AVAILABLE}" = true ] && echo -e "${ADDON}\t\Z4${BETA}${DESC}\Zn" 27 | elif [ "${TARGET}" = "system" ]; then 28 | [ "${AVAILABLE}" = true ] && echo -e "${ADDON}\t\Z1${BETA}${DESC}\Zn" 29 | else 30 | [ "${AVAILABLE}" = true ] && echo -e "${ADDON}\t${BETA}${DESC}" 31 | fi 32 | done 33 | } 34 | 35 | ############################################################################### 36 | # Check if addon exist 37 | # 1 - Addon id 38 | # 2 - Platform 39 | # Return ERROR if not exists 40 | function checkAddonExist() { 41 | if [ -z "${1}" ] || [ -z "${2}" ]; then 42 | return 1 # ERROR 43 | fi 44 | # First check generic files 45 | if [ -f "${ADDONS_PATH}/${1}/all.tgz" ]; then 46 | return 0 # OK 47 | fi 48 | return 1 # ERROR 49 | } 50 | 51 | ############################################################################### 52 | # Install Addon into ramdisk image 53 | # 1 - Addon id 54 | # 2 - Platform 55 | # 3 - Kernel Version 56 | # Return ERROR if not installed 57 | function installAddon() { 58 | if [ -z "${1}" ]; then 59 | echo "ERROR: installAddon: Addon not defined" 60 | return 1 61 | fi 62 | local ADDON="${1}" 63 | mkdir -p "${TMP_PATH}/${ADDON}" 64 | local HAS_FILES=0 65 | # First check generic files 66 | if [ -f "${ADDONS_PATH}/${ADDON}/all.tgz" ]; then 67 | tar -zxf "${ADDONS_PATH}/${ADDON}/all.tgz" -C "${TMP_PATH}/${ADDON}" 2>"${LOG_FILE}" 68 | if [ $? -ne 0 ]; then 69 | return 1 70 | fi 71 | HAS_FILES=1 72 | fi 73 | # Now check specific platform files 74 | if [ -f "${ADDONS_PATH}/${ADDON}/${2}-${3}.tgz" ]; then 75 | tar -zxf "${ADDONS_PATH}/${ADDON}/${2}-${3}.tgz" -C "${TMP_PATH}/${ADDON}" 2>"${LOG_FILE}" 76 | if [ $? -ne 0 ]; then 77 | return 1 78 | fi 79 | HAS_FILES=1 80 | fi 81 | # If has files to copy, copy it, else return error 82 | if [ ${HAS_FILES} -ne 1 ]; then 83 | deleteConfigKey "addon.${ADDON}" "${USER_CONFIG_FILE}" 84 | return 0 85 | fi 86 | cp -f "${TMP_PATH}/${ADDON}/install.sh" "${RAMDISK_PATH}/addons/${ADDON}.sh" 2>"${LOG_FILE}" 87 | chmod +x "${RAMDISK_PATH}/addons/${ADDON}.sh" 88 | [ -d "${TMP_PATH}/${ADDON}/root" ] && cp -rnf "${TMP_PATH}/${ADDON}/root/"* "${RAMDISK_PATH}/" 2>"${LOG_FILE}" 89 | rm -rf "${TMP_PATH}/${ADDON}" 90 | return 0 91 | } 92 | 93 | ############################################################################### 94 | # Untar an addon to correct path 95 | # 1 - Addon file path 96 | # Return name of addon on sucess or empty on error 97 | function untarAddon() { 98 | if [ -z "${1}" ]; then 99 | echo "" 100 | return 1 101 | fi 102 | rm -rf "${TMP_PATH}/addon" 103 | mkdir -p "${TMP_PATH}/addon" 104 | tar -xaf "${1}" -C "${TMP_PATH}/addon" || return 105 | local ADDON=$(readConfigKey "name" "${TMP_PATH}/addon/manifest.yml") 106 | [ -z "${ADDON}" ] && return 107 | rm -rf "${ADDONS_PATH}/${ADDON}" 108 | mv -f "${TMP_PATH}/addon" "${ADDONS_PATH}/${ADDON}" 109 | echo "${ADDON}" 110 | } 111 | 112 | ############################################################################### 113 | # Detect if has new local plugins to install/reinstall 114 | function updateAddon() { 115 | for F in $(ls ${ADDONS_PATH}/*.addon 2>/dev/null); do 116 | local ADDON=$(basename "${F}" | sed 's|.addon||') 117 | rm -rf "${ADDONS_PATH}/${ADDON}" 118 | mkdir -p "${ADDONS_PATH}/${ADDON}" 119 | echo "Installing ${F} to ${ADDONS_PATH}/${ADDON}" 120 | tar -xaf "${F}" -C "${ADDONS_PATH}/${ADDON}" 121 | rm -f "${F}" 122 | done 123 | } 124 | 125 | ############################################################################### 126 | # Read Addon Key 127 | # 1 - Addon 128 | # 2 - key 129 | function readAddonKey() { 130 | if [ -z "${1}" ] || [ -z "${2}" ]; then 131 | echo "" 132 | return 1 133 | fi 134 | if [ ! -f "${ADDONS_PATH}/${1}/manifest.yml" ]; then 135 | echo "" 136 | return 1 137 | fi 138 | readConfigKey "${2}" "${ADDONS_PATH}/${1}/manifest.yml" 139 | } -------------------------------------------------------------------------------- /files/initrd/opt/arc/include/configFile.sh: -------------------------------------------------------------------------------- 1 | ############################################################################### 2 | # Delete a key in config file 3 | # 1 - Path of Key 4 | # 2 - Path of yaml config file 5 | function deleteConfigKey() { 6 | yq eval 'del(.'${1}')' --inplace "${2}" 2>/dev/null 7 | } 8 | 9 | ############################################################################### 10 | # Write to yaml config file 11 | # 1 - Path of Key 12 | # 2 - Value 13 | # 3 - Path of yaml config file 14 | function writeConfigKey() { 15 | local value="${2}" 16 | [ "${value}" = "{}" ] && yq eval ".${1} = {}" --inplace "${3}" 2>/dev/null || yq eval ".${1} = \"${value}\"" --inplace "${3}" 2>/dev/null 17 | } 18 | 19 | ############################################################################### 20 | # Read key value from yaml config file 21 | # 1 - Path of key 22 | # 2 - Path of yaml config file 23 | # Return Value 24 | function readConfigKey() { 25 | local RESULT 26 | RESULT=$(yq eval '.'${1}' | explode(.)' "${2}" 2>/dev/null) 27 | [ "${RESULT}" = "null" ] && echo "" || echo "${RESULT}" 28 | } 29 | 30 | ############################################################################### 31 | # Write to yaml config file 32 | # 1 - Modules 33 | # 2 - Path of yaml config file 34 | function mergeConfigModules() { 35 | local MS="ARCMOD\n${1// /\\n}" 36 | local L="$(echo -en "${MS}" | awk '{print "modules."$1":"}')" 37 | local xmlfile=$(mktemp) 38 | echo -en "${L}" | yq -p p -o=yaml >"${xmlfile}" 39 | deleteConfigKey "modules.\"ARCMOD\"" "${xmlfile}" 40 | yq eval-all --inplace 'select(fileIndex == 0) * select(fileIndex == 1)' "${2}" "${xmlfile}" 2>/dev/null 41 | rm -f "${xmlfile}" 42 | } 43 | 44 | ############################################################################### 45 | # Write to yaml config file if key not exists 46 | # 1 - Path of Key 47 | # 2 - Value 48 | # 3 - Path of yaml config file 49 | function initConfigKey() { 50 | [ -z "$(readConfigKey "${1}" "${3}")" ] && writeConfigKey "${1}" "${2}" "${3}" || true 51 | } 52 | 53 | ############################################################################### 54 | # Read Entries as map(key=value) from yaml config file 55 | # 1 - Path of key 56 | # 2 - Path of yaml config file 57 | # Returns map of values 58 | function readConfigMap() { 59 | yq eval '.'${1}' | explode(.) | to_entries | map([.key, .value] | join(": ")) | .[]' "${2}" 2>/dev/null 60 | } 61 | 62 | ############################################################################### 63 | # Read an array from yaml config file 64 | # 1 - Path of key 65 | # 2 - Path of yaml config file 66 | # Returns array/map of values 67 | function readConfigArray() { 68 | yq eval '.'${1}'[]' "${2}" 2>/dev/null 69 | } 70 | 71 | ############################################################################### 72 | # Read Entries as array from yaml config file 73 | # 1 - Path of key 74 | # 2 - Path of yaml config file 75 | # Returns array of values 76 | function readConfigEntriesArray() { 77 | yq eval '.'${1}' | explode(.) | to_entries | map([.key])[] | .[]' "${2}" 2>/dev/null 78 | } 79 | 80 | ############################################################################### 81 | # Check yaml config file 82 | # 1 - Path of yaml config file 83 | # Returns error information 84 | function checkConfigFile() { 85 | yq eval "${1}" 2>&1 86 | } -------------------------------------------------------------------------------- /files/initrd/opt/arc/include/consts.sh: -------------------------------------------------------------------------------- 1 | # Define paths 2 | PART1_PATH="/mnt/p1" 3 | PART2_PATH="/mnt/p2" 4 | PART3_PATH="/mnt/p3" 5 | TMP_PATH="/tmp" 6 | 7 | [ -f "${PART3_PATH}/automated" ] && rm -f "${PART3_PATH}/automated" >/dev/null 2>&1 || true 8 | [ -f "${PART1_PATH}/ARC-VERSION" ] && ARC_VERSION="$(cat "${PART1_PATH}/ARC-VERSION")" || ARC_VERSION="null" 9 | [ -f "${PART1_PATH}/ARC-BUILD" ] && ARC_BUILD="$(cat "${PART1_PATH}/ARC-BUILD")" || ARC_BUILD="null" 10 | ARC_TITLE="Arc ${ARC_VERSION}" 11 | 12 | RAMDISK_PATH="${TMP_PATH}/ramdisk" 13 | LOG_FILE="${TMP_PATH}/log.txt" 14 | TMP_UP_PATH="${TMP_PATH}/upload" 15 | 16 | GRUB_PATH="${PART1_PATH}/boot/grub" 17 | USER_GRUB_CONFIG="${GRUB_PATH}/grub.cfg" 18 | USER_GRUBENVFILE="${GRUB_PATH}/grubenv" 19 | USER_CONFIG_FILE="${PART1_PATH}/user-config.yml" 20 | 21 | ORI_ZIMAGE_FILE="${PART2_PATH}/zImage" 22 | ORI_RDGZ_FILE="${PART2_PATH}/rd.gz" 23 | ARC_BZIMAGE_FILE="${PART3_PATH}/bzImage-arc" 24 | ARC_RAMDISK_FILE="${PART3_PATH}/initrd-arc" 25 | ARC_RAMDISK_USER_FILE="${PART3_PATH}/initrd-user" 26 | MOD_ZIMAGE_FILE="${PART3_PATH}/zImage-dsm" 27 | MOD_RDGZ_FILE="${PART3_PATH}/initrd-dsm" 28 | 29 | ADDONS_PATH="${PART3_PATH}/addons" 30 | MODULES_PATH="${PART3_PATH}/modules" 31 | MODEL_CONFIG_PATH="${PART3_PATH}/configs" 32 | PATCH_PATH="${PART3_PATH}/patches" 33 | LKMS_PATH="${PART3_PATH}/lkms" 34 | CUSTOM_PATH="${PART3_PATH}/custom" 35 | USER_UP_PATH="${PART3_PATH}/users" 36 | UNTAR_PAT_PATH="${PART3_PATH}/DSM" 37 | 38 | S_FILE="${MODEL_CONFIG_PATH}/serials.yml" 39 | P_FILE="${MODEL_CONFIG_PATH}/platforms.yml" 40 | D_FILE="${MODEL_CONFIG_PATH}/data.yml" 41 | 42 | EXTRACTOR_PATH="${PART3_PATH}/extractor" 43 | EXTRACTOR_BIN="syno_extract_system_patch" 44 | 45 | KVER5L=(epyc7002 geminilakenk r1000nk v1000nk) 46 | IGPU1L=(apollolake geminilake) 47 | IGPU2L=(epyc7002 geminilakenk r1000nk v1000nk) 48 | NVMECACHE=(DS719+ DS918+ DS1019+ DS1621xs+ RS1619xs+) 49 | MPT3PL=(purley broadwellnkv2 epyc7002 geminilakenk r1000nk v1000nk) 50 | IGFXRL=(apollolake geminilake geminilakenk) 51 | XAPICRL=(apollolake geminilake purley geminilakenk) 52 | 53 | HTTPPORT=$(grep -i '^HTTP_PORT=' /etc/arc.conf 2>/dev/null | cut -d'=' -f2) 54 | [ -z "${HTTPPORT}" ] && HTTPPORT="7080" 55 | DUFSPORT=$(grep -i '^DUFS_PORT=' /etc/arc.conf 2>/dev/null | cut -d'=' -f2) 56 | [ -z "${DUFSPORT}" ] && DUFSPORT="7304" 57 | TTYDPORT=$(grep -i '^TTYD_PORT=' /etc/arc.conf 2>/dev/null | cut -d'=' -f2) 58 | [ -z "${TTYDPORT}" ] && TTYDPORT="7681" -------------------------------------------------------------------------------- /files/initrd/opt/arc/include/functions.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # 3 | # Copyright (C) 2025 AuxXxilium and Ing 4 | # 5 | # This is free software, licensed under the MIT License. 6 | # See /LICENSE for more information. 7 | # 8 | 9 | import os, click 10 | 11 | WORK_PATH = os.path.abspath(os.path.dirname(__file__)) 12 | 13 | 14 | @click.group() 15 | def cli(): 16 | """ 17 | The CLI is a commands to Arc. 18 | """ 19 | pass 20 | 21 | 22 | def mutually_exclusive_options(ctx, param, value): 23 | other_option = "file" if param.name == "data" else "data" 24 | if value is not None and ctx.params.get(other_option) is not None: 25 | raise click.UsageError(f"Illegal usage: `{param.name}` is mutually exclusive with `{other_option}`.") 26 | return value 27 | 28 | 29 | def validate_required_param(ctx, param, value): 30 | if not value and "file" not in ctx.params and "data" not in ctx.params: 31 | raise click.MissingParameter(param_decls=[param.name]) 32 | return value 33 | 34 | def __fullversion(ver): 35 | out = ver 36 | arr = ver.split('-') 37 | if len(arr) > 0: 38 | a = arr[0].split('.')[0] if len(arr[0].split('.')) > 0 else '0' 39 | b = arr[0].split('.')[1] if len(arr[0].split('.')) > 1 else '0' 40 | c = arr[0].split('.')[2] if len(arr[0].split('.')) > 2 else '0' 41 | d = arr[1] if len(arr) > 1 else '00000' 42 | e = arr[2] if len(arr) > 2 else '0' 43 | out = '{}.{}.{}-{}-{}'.format(a,b,c,d,e) 44 | return out 45 | 46 | 47 | @cli.command() 48 | @click.option("-d", "--data", type=str, callback=mutually_exclusive_options, is_eager=True, help="The data of QRCode.") 49 | @click.option("-f", "--file", type=str, callback=mutually_exclusive_options, is_eager=True, help="The file of QRCode.") 50 | @click.option("--validate", is_flag=True, callback=validate_required_param, expose_value=False, is_eager=True) 51 | @click.option("-l", "--location", type=click.IntRange(0, 7), required=True, help="The location of QRCode. (range 0<=x<=7)") 52 | @click.option("-o", "--output", type=str, required=True, help="The output file of QRCode.") 53 | def makeqr(data, file, location, output): 54 | """ 55 | Generate a QRCode. 56 | """ 57 | try: 58 | import fcntl, struct 59 | import qrcode 60 | from PIL import Image 61 | 62 | FBIOGET_VSCREENINFO = 0x4600 63 | FBIOPUT_VSCREENINFO = 0x4601 64 | FBIOGET_FSCREENINFO = 0x4602 65 | FBDEV = "/dev/fb0" 66 | if data is not None: 67 | qr = qrcode.QRCode(version=1, box_size=10, error_correction=qrcode.constants.ERROR_CORRECT_H, border=4,) 68 | qr.add_data(data) 69 | qr.make(fit=True) 70 | img = qr.make_image(fill_color="grey", back_color="black") 71 | img = img.convert("RGBA") 72 | pixels = img.load() 73 | for i in range(img.size[0]): 74 | for j in range(img.size[1]): 75 | if pixels[i, j] == (255, 255, 255, 255): 76 | pixels[i, j] = (255, 255, 255, 0) 77 | 78 | if os.path.exists(os.path.join(WORK_PATH, "logo.png")): 79 | icon = Image.open(os.path.join(WORK_PATH, "logo.png")) 80 | icon = icon.convert("RGBA") 81 | img.paste(icon.resize((int(img.size[0] / 5), int(img.size[1] / 5))), (int((img.size[0] - int(img.size[0] / 5)) / 2), int((img.size[1] - int(img.size[1] / 5)) / 2),),) 82 | 83 | if file is not None: 84 | img = Image.open(file) 85 | # img = img.convert("RGBA") 86 | # pixels = img.load() 87 | # for i in range(img.size[0]): 88 | # for j in range(img.size[1]): 89 | # if pixels[i, j] == (255, 255, 255, 255): 90 | # pixels[i, j] = (255, 255, 255, 0) 91 | 92 | (xres, yres) = (1920, 1080) 93 | with open(FBDEV, "rb") as fb: 94 | vi = fcntl.ioctl(fb, FBIOGET_VSCREENINFO, bytes(160)) 95 | res = struct.unpack("I" * 40, vi) 96 | if res[0] != 0 and res[1] != 0: 97 | (xres, yres) = (res[0], res[1]) 98 | xqr, yqr = (int(xres / 8), int(xres / 8)) 99 | img = img.resize((xqr, yqr)) 100 | 101 | alpha = Image.new("RGBA", (xres, yres), (0, 0, 0, 0)) 102 | if int(location) not in range(0, 8): 103 | location = 0 104 | loc = (img.size[0] * int(location), alpha.size[1] - img.size[1]) 105 | alpha.paste(img, loc) 106 | alpha.save(output) 107 | 108 | except: 109 | pass 110 | 111 | if __name__ == "__main__": 112 | cli() -------------------------------------------------------------------------------- /files/initrd/opt/arc/include/i915ids: -------------------------------------------------------------------------------- 1 | # INTEL_I810_IDS 2 | 80867121 3 | 80867123 4 | 80867125 5 | # INTEL_I815_IDS 6 | 80861132 7 | # INTEL_I830_IDS 8 | 80863577 9 | # INTEL_I845G_IDS 10 | 80862562 11 | # INTEL_I85X_IDS 12 | 80863582 13 | 8086358e 14 | # INTEL_I865G_IDS 15 | 80862572 16 | # INTEL_I915G_IDS 17 | 80862582 18 | 8086258a 19 | # INTEL_I915GM_IDS 20 | 80862592 21 | # INTEL_I945G_IDS 22 | 80862772 23 | # INTEL_I945GM_IDS 24 | 808627a2 25 | 808627ae 26 | # INTEL_I965G_IDS 27 | 80862972 28 | 80862982 29 | 80862992 30 | 808629a2 31 | # INTEL_G33_IDS 32 | 808629b2 33 | 808629c2 34 | 808629d2 35 | # INTEL_I965GM_IDS 36 | 80862a02 37 | 80862a12 38 | # INTEL_GM45_IDS 39 | 80862a42 40 | # INTEL_G45_IDS 41 | 80862e02 42 | 80862e12 43 | 80862e22 44 | 80862e32 45 | 80862e42 46 | 80862e92 47 | # INTEL_PINEVIEW_G_IDS 48 | 8086a001 49 | # INTEL_PINEVIEW_M_IDS 50 | 8086a011 51 | # INTEL_IRONLAKE_D_IDS 52 | 80860042 53 | # INTEL_IRONLAKE_M_IDS 54 | 80860046 55 | # INTEL_SNB_D_GT1_IDS 56 | 80860102 57 | 8086010A 58 | # INTEL_SNB_D_GT2_IDS 59 | 80860112 60 | 80860122 61 | # INTEL_SNB_M_GT1_IDS 62 | 80860106 63 | # INTEL_SNB_M_GT2_IDS 64 | 80860116 65 | 80860126 66 | # INTEL_IVB_M_GT1_IDS 67 | 80860156 68 | # INTEL_IVB_M_GT2_IDS 69 | 80860166 70 | # INTEL_IVB_D_GT1_IDS 71 | 80860152 72 | 8086015a 73 | # INTEL_IVB_D_GT2_IDS 74 | 80860162 75 | 8086016a 76 | # INTEL_HSW_ULT_GT1_IDS 77 | 80860A02 78 | 80860A06 79 | 80860A0A 80 | 80860A0B 81 | # INTEL_HSW_ULX_GT1_IDS 82 | 80860A0E 83 | # INTEL_HSW_GT1_IDS 84 | 80860402 85 | 80860406 86 | 8086040A 87 | 8086040B 88 | 8086040E 89 | 80860C02 90 | 80860C06 91 | 80860C0A 92 | 80860C0B 93 | 80860C0E 94 | 80860D02 95 | 80860D06 96 | 80860D0A 97 | 80860D0B 98 | 80860D0E 99 | # INTEL_HSW_ULT_GT2_IDS 100 | 80860A12 101 | 80860A16 102 | 80860A1A 103 | 80860A1B 104 | # INTEL_HSW_ULX_GT2_IDS 105 | 80860A1E 106 | # INTEL_HSW_GT2_IDS 107 | 80860412 108 | 80860416 109 | 8086041A 110 | 8086041B 111 | 8086041E 112 | 80860C12 113 | 80860C16 114 | 80860C1A 115 | 80860C1B 116 | 80860C1E 117 | 80860D12 118 | 80860D16 119 | 80860D1A 120 | 80860D1B 121 | 80860D1E 122 | # INTEL_HSW_ULT_GT3_IDS 123 | 80860A22 124 | 80860A26 125 | 80860A2A 126 | 80860A2B 127 | 80860A2E 128 | # INTEL_HSW_GT3_IDS 129 | 80860422 130 | 80860426 131 | 8086042A 132 | 8086042B 133 | 8086042E 134 | 80860C22 135 | 80860C26 136 | 80860C2A 137 | 80860C2B 138 | 80860C2E 139 | 80860D22 140 | 80860D26 141 | 80860D2A 142 | 80860D2B 143 | 80860D2E 144 | # INTEL_VLV_IDS 145 | 80860f30 146 | 80860f31 147 | 80860f32 148 | 80860f33 149 | # INTEL_BDW_ULT_GT1_IDS 150 | 80861606 151 | 8086160B 152 | # INTEL_BDW_ULX_GT1_IDS 153 | 8086160E 154 | # INTEL_BDW_GT1_IDS 155 | 80861602 156 | 8086160A 157 | 8086160D 158 | # INTEL_BDW_ULT_GT2_IDS 159 | 80861616 160 | 8086161B 161 | # INTEL_BDW_ULX_GT2_IDS 162 | 8086161E 163 | # INTEL_BDW_GT2_IDS 164 | 80861612 165 | 8086161A 166 | 8086161D 167 | # INTEL_BDW_ULT_GT3_IDS 168 | 80861626 169 | 8086162B 170 | # INTEL_BDW_ULX_GT3_IDS 171 | 8086162E 172 | # INTEL_BDW_GT3_IDS 173 | 80861622 174 | 8086162A 175 | 8086162D 176 | # INTEL_BDW_ULT_RSVD_IDS 177 | 80861636 178 | 8086163B 179 | # INTEL_BDW_ULX_RSVD_IDS 180 | 8086163E 181 | # INTEL_BDW_RSVD_IDS 182 | 80861632 183 | 8086163A 184 | 8086163D 185 | # INTEL_CHV_IDS 186 | 808622b0 187 | 808622b1 188 | 808622b2 189 | 808622b3 190 | # INTEL_SKL_ULT_GT1_IDS 191 | 80861906 192 | 80861913~ 193 | # INTEL_SKL_ULX_GT1_IDS 194 | 8086190E 195 | 80861915~ 196 | # INTEL_SKL_GT1_IDS 197 | 80861902 198 | 8086190A 199 | 8086190B 200 | 80861917~ 201 | # INTEL_SKL_ULT_GT2_IDS 202 | 80861916 203 | 80861921 204 | # INTEL_SKL_ULX_GT2_IDS 205 | 8086191E 206 | # INTEL_SKL_GT2_IDS 207 | 80861912 208 | 8086191A 209 | 8086191B 210 | 8086191D 211 | # INTEL_SKL_ULT_GT3_IDS 212 | 80861923 213 | 80861926 214 | 80861927 215 | # INTEL_SKL_GT3_IDS 216 | 8086192A 217 | 8086192B 218 | 8086192D 219 | # INTEL_SKL_GT4_IDS 220 | 80861932 221 | 8086193A 222 | 8086193B 223 | 8086193D 224 | # INTEL_BXT_IDS 225 | 80860A84 226 | 80861A84 227 | 80861A85 228 | 80865A84 229 | 80865A85 230 | # INTEL_GLK_IDS 231 | 80863184 232 | 80863185 233 | # INTEL_KBL_ULT_GT1_IDS 234 | 80865906 235 | 80865913 236 | # INTEL_KBL_ULX_GT1_IDS 237 | 8086590E 238 | 80865915 239 | # INTEL_KBL_GT1_IDS 240 | 80865902 241 | 80865908 242 | 8086590A 243 | 8086590B 244 | # INTEL_KBL_ULT_GT2_IDS 245 | 80865916 246 | 80865921 247 | # INTEL_KBL_ULX_GT2_IDS 248 | 8086591E 249 | # INTEL_KBL_GT2_IDS 250 | 80865912 251 | 80865917 252 | 8086591A 253 | 8086591B 254 | 8086591D 255 | # INTEL_KBL_ULT_GT3_IDS 256 | 80865926 257 | # INTEL_KBL_GT3_IDS 258 | 80865923 259 | 80865927 260 | # INTEL_KBL_GT4_IDS 261 | 8086593B 262 | # INTEL_AML_KBL_GT2_IDS 263 | 8086591C 264 | 808687C0 265 | # INTEL_AML_CFL_GT2_IDS 266 | 808687CA 267 | # INTEL_CML_GT1_IDS 268 | 80869BA2 269 | 80869BA4 270 | 80869BA5 271 | 80869BA8 272 | # INTEL_CML_U_GT1_IDS 273 | 80869B21 274 | 80869BAA 275 | 80869BAC 276 | # INTEL_CML_GT2_IDS 277 | 80869BC2 278 | 80869BC4 279 | 80869BC5 280 | 80869BC6 281 | 80869BC8 282 | 80869BE6 283 | 80869BF6 284 | # INTEL_CML_U_GT2_IDS 285 | 80869B41 286 | 80869BCA 287 | 80869BCC 288 | # INTEL_CFL_S_GT1_IDS 289 | 80863E90 290 | 80863E93 291 | 80863E99 292 | # INTEL_CFL_S_GT2_IDS 293 | 80863E91 294 | 80863E92 295 | 80863E96 296 | 80863E98 297 | 80863E9A 298 | # INTEL_CFL_H_GT1_IDS 299 | 80863E9C 300 | # INTEL_CFL_H_GT2_IDS 301 | 80863E94 302 | 80863E9B 303 | # INTEL_CFL_U_GT2_IDS 304 | 80863EA9 305 | # INTEL_CFL_U_GT3_IDS 306 | 80863EA5 307 | 80863EA6 308 | 80863EA7 309 | 80863EA8 310 | # INTEL_WHL_U_GT1_IDS 311 | 80863EA1 312 | 80863EA4 313 | # INTEL_WHL_U_GT2_IDS 314 | 80863EA0 315 | 80863EA3 316 | # INTEL_WHL_U_GT3_IDS 317 | 80863EA2 318 | # INTEL_CNL_PORT_F_IDS 319 | 80865A44 320 | 80865A4C 321 | 80865A54 322 | 80865A5C 323 | # INTEL_CNL_IDS 324 | 80865A40 325 | 80865A41 326 | 80865A42 327 | 80865A49 328 | 80865A4A 329 | 80865A50 330 | 80865A51 331 | 80865A52 332 | 80865A59 333 | 80865A5A 334 | # INTEL_ICL_PORT_F_IDS 335 | 80868A50 336 | 80868A52 337 | 80868A53 338 | 80868A54 339 | 80868A56 340 | 80868A57 341 | 80868A58 342 | 80868A59 343 | 80868A5A 344 | 80868A5B 345 | 80868A5C 346 | 80868A70 347 | 80868A71 348 | # INTEL_ICL_11_IDS 349 | 80868A51 350 | 80868A5D 351 | # INTEL_EHL_IDS 352 | 80864500~ 353 | 80864541 354 | 80864551 355 | 80864555 356 | 80864557 357 | 80864570~ 358 | 80864571 359 | # INTEL_JSL_IDS 360 | 80864E51 361 | 80864E55 362 | 80864E57 363 | 80864E61 364 | 80864E71 365 | # INTEL_TGL_12_GT1_IDS 366 | 80869A60 367 | 80869A68 368 | 80869A70 369 | # INTEL_TGL_12_GT2_IDS 370 | 80869A40 371 | 80869A49 372 | 80869A59 373 | 80869A78 374 | 80869AC0 375 | 80869AC9 376 | 80869AD9 377 | 80869AF8 378 | # INTEL_RKL_IDS 379 | 80864C80 380 | 80864C8A 381 | 80864C8B 382 | 80864C8C 383 | 80864C90 384 | 80864C9A 385 | # INTEL_DG1_IDS 386 | 80864905 387 | 80864906~ 388 | 80864907~ 389 | 80864908~ 390 | 80864909~ -------------------------------------------------------------------------------- /files/initrd/opt/arc/include/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AuxXxilium/arc/5fc208ac2e6bc86eddb48a22fad3a46aa35e48a9/files/initrd/opt/arc/include/logo.png -------------------------------------------------------------------------------- /files/initrd/opt/arc/include/modulelist: -------------------------------------------------------------------------------- 1 | # `#: comment 2 | # $1: operation 3 | # N: copy module to ramdisk, do not overwrite an existing file 4 | # F: copy module to ramdisk, overwrite an existing file 5 | # $2: module file name (not module name) 6 | # 7 | # eg: N i915.ko 8 | 9 | # kvm 10 | F irqbypass.ko 11 | F kvm-intel.ko 12 | F kvm-amd.ko 13 | F kvm.ko 14 | 15 | # acpi 16 | N acpi_call.ko 17 | N acpi_cpufreq.ko 18 | N processor.ko 19 | N button.ko 20 | 21 | # cpufreq 22 | N cpufreq_governor.ko 23 | N cpufreq_ondemand.ko 24 | N cpufreq_conservative.ko 25 | N cpufreq_performance.ko 26 | N cpufreq_powersave.ko 27 | N cpufreq_userspace.ko 28 | N cpufreq_stats.ko 29 | 30 | # misc 31 | N check_signature.ko 32 | N rfkill.ko 33 | N rfkill-gpio.ko 34 | 35 | # sensors 36 | N coretemp.ko 37 | N k10temp.ko 38 | N hwmon-vid.ko 39 | N it87.ko 40 | N adt7470.ko 41 | N adt7475.ko 42 | N nct6683.ko 43 | N nct6775.ko 44 | 45 | # network 46 | F mii.ko 47 | F cdc_ether.ko 48 | F rndis_host.ko 49 | F r8152.ko 50 | F aqc111.ko 51 | F ax88179_178a.ko 52 | F aic_load_fw.ko 53 | F aic8800_fdrv.ko 54 | 55 | ## i915 56 | #N dmabuf.ko 57 | #N drm.ko 58 | #N drm_buddy.ko 59 | #N drm_display_helper.ko 60 | #N drm_kms_helper.ko 61 | #N drm_mipi_dsi.ko 62 | #N drm_panel_orientation_quirks.ko 63 | #N i2c-algo-bit.ko 64 | #N i915-compat.ko 65 | #N intel-gtt.ko 66 | #N ttm.ko 67 | #N i915.ko -------------------------------------------------------------------------------- /files/initrd/opt/arc/include/modules.sh: -------------------------------------------------------------------------------- 1 | ############################################################################### 2 | # Unpack modules from a tgz file 3 | # 1 - Platform 4 | # 2 - Kernel Version 5 | function unpackModules() { 6 | local PLATFORM=${1} 7 | local KVERP=${2} 8 | local KERNEL 9 | KERNEL="$(readConfigKey "kernel" "${USER_CONFIG_FILE}")" 10 | 11 | rm -rf "${TMP_PATH}/modules" 12 | mkdir -p "${TMP_PATH}/modules" 13 | if [ "${KERNEL}" = "custom" ]; then 14 | tar -zxf "${CUSTOM_PATH}/modules-${PLATFORM}-${KVERP}.tgz" -C "${TMP_PATH}/modules" 15 | else 16 | tar -zxf "${MODULES_PATH}/${PLATFORM}-${KVERP}.tgz" -C "${TMP_PATH}/modules" 17 | fi 18 | } 19 | 20 | ############################################################################### 21 | # Packag modules to a tgz file 22 | # 1 - Platform 23 | # 2 - Kernel Version 24 | function packModules() { 25 | local PLATFORM=${1} 26 | local KVERP=${2} 27 | local KERNEL 28 | KERNEL="$(readConfigKey "kernel" "${USER_CONFIG_FILE}")" 29 | 30 | if [ "${KERNEL}" = "custom" ]; then 31 | tar -zcf "${CUSTOM_PATH}/modules-${PLATFORM}-${KVERP}.tgz" -C "${TMP_PATH}/modules" . 32 | else 33 | tar -zcf "${MODULES_PATH}/${PLATFORM}-${KVERP}.tgz" -C "${TMP_PATH}/modules" . 34 | fi 35 | } 36 | 37 | ############################################################################### 38 | # Return list of all modules available 39 | # 1 - Platform 40 | # 2 - Kernel Version 41 | function getAllModules() { 42 | local PLATFORM=${1} 43 | local KVERP=${2} 44 | 45 | if [ -z "${PLATFORM}" ] || [ -z "${KVERP}" ]; then 46 | return 1 47 | fi 48 | 49 | unpackModules "${PLATFORM}" "${KVERP}" 50 | 51 | # Get list of all modules 52 | for F in $(ls ${TMP_PATH}/modules/*.ko 2>/dev/null); do 53 | [ ! -e "${F}" ] && continue 54 | local N DESC 55 | N="$(basename "${F}" .ko)" 56 | DESC="$(modinfo -F description "${F}" 2>/dev/null)" 57 | DESC="$(echo "${DESC}" | sed -E 's/["\n]/ /g' | xargs)" 58 | echo "${N} \"${DESC:-${N}}\"" 59 | done 60 | rm -rf "${TMP_PATH}/modules" 61 | } 62 | 63 | ############################################################################### 64 | # Return list of all modules available 65 | # 1 - Platform 66 | # 2 - Kernel Version 67 | # 3 - Module list 68 | function installModules() { 69 | local PLATFORM=${1} 70 | local KVERP=${2} 71 | 72 | if [ -z "${PLATFORM}" ] || [ -z "${KVERP}" ]; then 73 | echo "ERROR: Platform or Kernel Version not defined" >"${LOG_FILE}" 74 | return 1 75 | fi 76 | local MLIST ODP KERNEL 77 | shift 2 78 | MLIST="${*}" 79 | 80 | unpackModules "${PLATFORM}" "${KVERP}" 81 | 82 | ODP="$(readConfigKey "odp" "${USER_CONFIG_FILE}")" 83 | for F in ${TMP_PATH}/modules/*.ko; do 84 | [ ! -e "${F}" ] && continue 85 | M=$(basename "${F}") 86 | [ "${ODP}" = "true" ] && [ -f "${RAMDISK_PATH}/usr/lib/modules/${M}" ] && continue 87 | if echo "${MLIST}" | grep -wq "$(basename "${M}" .ko)"; then 88 | cp -f "${F}" "${RAMDISK_PATH}/usr/lib/modules/${M}" 2>"${LOG_FILE}" 89 | else 90 | rm -f "${RAMDISK_PATH}/usr/lib/modules/${M}" 2>"${LOG_FILE}" 91 | fi 92 | done 93 | 94 | mkdir -p "${RAMDISK_PATH}/usr/lib/firmware" 95 | KERNEL=$(readConfigKey "kernel" "${USER_CONFIG_FILE}") 96 | if [ "${KERNEL}" = "custom" ]; then 97 | tar -zxf "${CUSTOM_PATH}/firmware.tgz" -C "${RAMDISK_PATH}/usr/lib/firmware" 2>"${LOG_FILE}" 98 | else 99 | tar -zxf "${MODULES_PATH}/firmware.tgz" -C "${RAMDISK_PATH}/usr/lib/firmware" 2>"${LOG_FILE}" 100 | fi 101 | if [ $? -ne 0 ]; then 102 | return 1 103 | fi 104 | 105 | rm -rf "${TMP_PATH}/modules" 106 | return 0 107 | } 108 | 109 | ############################################################################### 110 | # add a ko of modules.tgz 111 | # 1 - Platform 112 | # 2 - Kernel Version 113 | # 3 - ko file 114 | function addToModules() { 115 | local PLATFORM=${1} 116 | local KVERP=${2} 117 | local KOFILE=${3} 118 | 119 | if [ -z "${PLATFORM}" ] || [ -z "${KVERP}" ] || [ -z "${KOFILE}" ]; then 120 | echo "" 121 | return 1 122 | fi 123 | 124 | unpackModules "${PLATFORM}" "${KVERP}" 125 | 126 | cp -f "${KOFILE}" "${TMP_PATH}/modules" 127 | 128 | packModules "${PLATFORM}" "${KVERP}" 129 | } 130 | 131 | ############################################################################### 132 | # del a ko of modules.tgz 133 | # 1 - Platform 134 | # 2 - Kernel Version 135 | # 3 - ko name 136 | function delToModules() { 137 | local PLATFORM=${1} 138 | local KVERP=${2} 139 | local KONAME=${3} 140 | 141 | if [ -z "${PLATFORM}" ] || [ -z "${KVERP}" ] || [ -z "${KONAME}" ]; then 142 | echo "" 143 | return 1 144 | fi 145 | 146 | unpackModules "${PLATFORM}" "${KVERP}" 147 | 148 | rm -f "${TMP_PATH}/modules/${KONAME}" 149 | 150 | packModules "${PLATFORM}" "${KVERP}" 151 | } 152 | 153 | ############################################################################### 154 | # get depends of ko 155 | # 1 - Platform 156 | # 2 - Kernel Version 157 | # 3 - ko name 158 | function getdepends() { 159 | function _getdepends() { 160 | if [ -f "${TMP_PATH}/modules/${1}.ko" ]; then 161 | local depends 162 | depends="$(modinfo -F depends "${TMP_PATH}/modules/${1}.ko" 2>/dev/null | sed 's/,/\n/g')" 163 | if [ "$(echo "${depends}" | wc -w)" -gt 0 ]; then 164 | for k in ${depends}; do 165 | echo "${k}" 166 | _getdepends "${k}" 167 | done 168 | fi 169 | fi 170 | } 171 | 172 | local PLATFORM=${1} 173 | local KVERP=${2} 174 | local KONAME=${3} 175 | 176 | if [ -z "${PLATFORM}" ] || [ -z "${KVERP}" ] || [ -z "${KONAME}" ]; then 177 | echo "" 178 | return 1 179 | fi 180 | 181 | unpackModules "${PLATFORM}" "${KVERP}" 182 | 183 | _getdepends "${KONAME}" | sort -u 184 | echo "${KONAME}" 185 | rm -rf "${TMP_PATH}/modules" 186 | } -------------------------------------------------------------------------------- /files/initrd/opt/arc/include/syno.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AuxXxilium/arc/5fc208ac2e6bc86eddb48a22fad3a46aa35e48a9/files/initrd/opt/arc/include/syno.png -------------------------------------------------------------------------------- /files/initrd/opt/arc/include/update.sh: -------------------------------------------------------------------------------- 1 | ############################################################################### 2 | # Update Loader 3 | function updateLoader() { 4 | CONFDONE="$(readConfigKey "arc.confdone" "${USER_CONFIG_FILE}")" 5 | local TAG="${1}" 6 | [ -n "${ARC_CONF}" ] && cp -f "${S_FILE}" "${TMP_PATH}/bak.yml" 7 | if [ "${TAG}" != "zip" ]; then 8 | if [ -z "${TAG}" ]; then 9 | idx=0 10 | while [ "${idx}" -le 5 ]; do # Loop 5 times, if successful, break 11 | TAG="$(curl -m 10 -skL "https://api.github.com/repos/AuxXxilium/arc/releases" | jq -r ".[].tag_name" | grep -v "dev" | sort -rV | head -1)" 12 | if [ -n "${TAG}" ]; then 13 | break 14 | fi 15 | sleep 3 16 | idx=$((${idx} + 1)) 17 | done 18 | fi 19 | if [ -n "${TAG}" ]; then 20 | export URL="https://github.com/AuxXxilium/arc/releases/download/${TAG}/update-${TAG}.zip" 21 | export TAG="${TAG}" 22 | { 23 | { 24 | curl -kL "${URL}" -o "${TMP_PATH}/update.zip" 2>&3 3>&- 25 | } 3>&1 >&4 4>&- | 26 | perl -C -lane ' 27 | BEGIN {$header = "Downloading $ENV{URL}...\n\n"; $| = 1} 28 | $pcent = $F[0]; 29 | $_ = join "", unpack("x3 a7 x4 a9 x8 a9 x7 a*") if length > 20; 30 | s/ /\xa0/g; # replacing space with nbsp as dialog squashes spaces 31 | if ($. <= 3) { 32 | $header .= "$_\n"; 33 | $/ = "\r" if $. == 2 34 | } else { 35 | print "XXX\n$pcent\n$header$_\nXXX" 36 | }' 4>&- | 37 | dialog --gauge "Download Update: ${TAG}..." 14 72 4>&- 38 | } 4>&1 39 | fi 40 | fi 41 | if [ -f "${TMP_PATH}/update.zip" ] && [ $(ls -s "${TMP_PATH}/update.zip" | cut -d' ' -f1) -gt 300000 ]; then 42 | if [ "${TAG}" != "zip" ]; then 43 | HASHURL="https://github.com/AuxXxilium/arc/releases/download/${TAG}/update-${TAG}.hash" 44 | HASH="$(curl -skL "${HASHURL}" | awk '{print $1}')" 45 | if [ "${HASH}" != "$(sha256sum "${TMP_PATH}/update.zip" | awk '{print $1}')" ]; then 46 | dialog --backtitle "$(backtitle)" --title "Update Loader" --aspect 18 \ 47 | --infobox "Update failed - Hash mismatch!\nTry again later." 0 0 48 | sleep 3 49 | exec reboot 50 | fi 51 | fi 52 | rm -rf "/mnt/update" 53 | mkdir -p "${TMP_PATH}/update" 54 | dialog --backtitle "$(backtitle)" --title "Update Loader" \ 55 | --infobox "Updating Loader..." 3 50 56 | if unzip -oq "${TMP_PATH}/update.zip" -d "${TMP_PATH}/update"; then 57 | cp -rf "${TMP_PATH}/update"/* "/mnt" 58 | rm -rf "${TMP_PATH}/update" 59 | rm -f "${TMP_PATH}/update.zip" 60 | fi 61 | if [ "$(cat "${PART1_PATH}/ARC-VERSION")" = "${TAG}" ] || [ "${TAG}" = "zip" ]; then 62 | dialog --backtitle "$(backtitle)" --title "Update Loader" \ 63 | --infobox "Update Loader successful!" 3 50 64 | sleep 2 65 | else 66 | if [ "${ARC_MODE}" = "update" ]; then 67 | dialog --backtitle "$(backtitle)" --title "Update Loader" --aspect 18 \ 68 | --infobox "Update failed!\nTry again later." 0 0 69 | sleep 3 70 | exec reboot 71 | else 72 | return 1 73 | fi 74 | fi 75 | else 76 | if [ "${ARC_MODE}" = "update" ]; then 77 | dialog --backtitle "$(backtitle)" --title "Update Loader" --aspect 18 \ 78 | --infobox "Update failed!\nTry again later." 0 0 79 | sleep 3 80 | exec reboot 81 | else 82 | return 1 83 | fi 84 | fi 85 | [ -n "${ARC_CONF}" ] && cp -f "${TMP_PATH}/bak.yml" "${S_FILE}" 86 | if [ "${ARC_MODE}" = "update" ] && [ "${CONFDONE}" = "true" ]; then 87 | dialog --backtitle "$(backtitle)" --title "Update Loader" --aspect 18 \ 88 | --infobox "Update Loader successful! -> Reboot to automated Build Mode..." 3 60 89 | sleep 3 90 | writeConfigKey "arc.builddone" "false" "${USER_CONFIG_FILE}" 91 | rebootTo automated 92 | else 93 | dialog --backtitle "$(backtitle)" --title "Update Loader" --aspect 18 \ 94 | --infobox "Update Loader successful! -> Reboot to Config Mode..." 3 50 95 | sleep 3 96 | writeConfigKey "arc.builddone" "false" "${USER_CONFIG_FILE}" 97 | rebootTo config 98 | fi 99 | } 100 | 101 | ############################################################################### 102 | # Update Loader Beta 103 | function updateLoaderBeta() { 104 | CONFDONE="$(readConfigKey "arc.confdone" "${USER_CONFIG_FILE}")" 105 | local TAG="${1}" 106 | [ -n "${ARC_CONF}" ] && cp -f "${S_FILE}" "${TMP_PATH}/bak.yml" 107 | if [ "${TAG}" != "zip" ]; then 108 | if [ -z "${TAG}" ]; then 109 | idx=0 110 | while [ "${idx}" -le 5 ]; do # Loop 5 times, if successful, break 111 | TAG="$(curl -m 10 -skL "https://api.github.com/repos/AuxXxilium/arc-beta/releases" | jq -r ".[].tag_name" | grep -v "dev" | sort -rV | head -1)" 112 | if [ -n "${TAG}" ]; then 113 | break 114 | fi 115 | sleep 3 116 | idx=$((${idx} + 1)) 117 | done 118 | fi 119 | if [ -n "${TAG}" ]; then 120 | export URL="https://github.com/AuxXxilium/arc-beta/releases/download/${TAG}/update-${TAG}.zip" 121 | export TAG="${TAG}" 122 | { 123 | { 124 | curl -kL "${URL}" -o "${TMP_PATH}/update.zip" 2>&3 3>&- 125 | } 3>&1 >&4 4>&- | 126 | perl -C -lane ' 127 | BEGIN {$header = "Downloading $ENV{URL}...\n\n"; $| = 1} 128 | $pcent = $F[0]; 129 | $_ = join "", unpack("x3 a7 x4 a9 x8 a9 x7 a*") if length > 20; 130 | s/ /\xa0/g; # replacing space with nbsp as dialog squashes spaces 131 | if ($. <= 3) { 132 | $header .= "$_\n"; 133 | $/ = "\r" if $. == 2 134 | } else { 135 | print "XXX\n$pcent\n$header$_\nXXX" 136 | }' 4>&- | 137 | dialog --gauge "Download Update: ${TAG}..." 14 72 4>&- 138 | } 4>&1 139 | fi 140 | fi 141 | if [ -f "${TMP_PATH}/update.zip" ] && [ $(ls -s "${TMP_PATH}/update.zip" | cut -d' ' -f1) -gt 300000 ]; then 142 | if [ "${TAG}" != "zip" ]; then 143 | HASHURL="https://github.com/AuxXxilium/arc-beta/releases/download/${TAG}/update-${TAG}.hash" 144 | HASH="$(curl -skL "${HASHURL}" | awk '{print $1}')" 145 | if [ "${HASH}" != "$(sha256sum "${TMP_PATH}/update.zip" | awk '{print $1}')" ]; then 146 | dialog --backtitle "$(backtitle)" --title "Update Loader" --aspect 18 \ 147 | --infobox "Update failed - Hash mismatch!\nTry again later." 0 0 148 | sleep 3 149 | exec reboot 150 | fi 151 | fi 152 | rm -rf "/mnt/update" 153 | mkdir -p "${TMP_PATH}/update" 154 | dialog --backtitle "$(backtitle)" --title "Update Loader" \ 155 | --infobox "Updating Loader..." 3 50 156 | if unzip -oq "${TMP_PATH}/update.zip" -d "${TMP_PATH}/update"; then 157 | cp -rf "${TMP_PATH}/update"/* "/mnt" 158 | rm -rf "${TMP_PATH}/update" 159 | rm -f "${TMP_PATH}/update.zip" 160 | fi 161 | if [ "$(cat "${PART1_PATH}/ARC-VERSION")" = "${TAG}" ] || [ "${TAG}" = "zip" ]; then 162 | dialog --backtitle "$(backtitle)" --title "Update Loader" \ 163 | --infobox "Update Loader successful!" 3 50 164 | sleep 2 165 | else 166 | return 1 167 | fi 168 | else 169 | return 1 170 | fi 171 | [ -n "${ARC_CONF}" ] && cp -f "${TMP_PATH}/bak.yml" "${S_FILE}" 172 | if [ "${ARC_MODE}" = "update" ] && [ "${CONFDONE}" = "true" ]; then 173 | dialog --backtitle "$(backtitle)" --title "Update Loader" --aspect 18 \ 174 | --infobox "Update Loader successful! -> Reboot to automated Build Mode..." 3 60 175 | sleep 3 176 | writeConfigKey "arc.builddone" "false" "${USER_CONFIG_FILE}" 177 | rebootTo automated 178 | else 179 | dialog --backtitle "$(backtitle)" --title "Update Loader" --aspect 18 \ 180 | --infobox "Update Loader successful! -> Reboot to Config Mode..." 3 50 181 | sleep 3 182 | writeConfigKey "arc.builddone" "false" "${USER_CONFIG_FILE}" 183 | rebootTo config 184 | fi 185 | } 186 | 187 | ############################################################################### 188 | # Upgrade Loader 189 | function upgradeLoader() { 190 | local TAG="${1}" 191 | if [ "${TAG}" != "zip" ]; then 192 | if [ -z "${TAG}" ]; then 193 | idx=0 194 | while [ "${idx}" -le 5 ]; do # Loop 5 times, if successful, break 195 | TAG="$(curl -m 10 -skL "https://api.github.com/repos/AuxXxilium/arc/releases" | jq -r ".[].tag_name" | grep -v "dev" | sort -rV | head -1)" 196 | if [ -n "${TAG}" ]; then 197 | break 198 | fi 199 | sleep 3 200 | idx=$((${idx} + 1)) 201 | done 202 | fi 203 | if [ -n "${TAG}" ]; then 204 | export URL="https://github.com/AuxXxilium/arc/releases/download/${TAG}/arc-${TAG}.img.zip" 205 | export TAG="${TAG}" 206 | { 207 | { 208 | curl -kL "${URL}" -o "${TMP_PATH}/arc.img.zip" 2>&3 3>&- 209 | } 3>&1 >&4 4>&- | 210 | perl -C -lane ' 211 | BEGIN {$header = "Downloading $ENV{URL}...\n\n"; $| = 1} 212 | $pcent = $F[0]; 213 | $_ = join "", unpack("x3 a7 x4 a9 x8 a9 x7 a*") if length > 20; 214 | s/ /\xa0/g; # replacing space with nbsp as dialog squashes spaces 215 | if ($. <= 3) { 216 | $header .= "$_\n"; 217 | $/ = "\r" if $. == 2 218 | } else { 219 | print "XXX\n$pcent\n$header$_\nXXX" 220 | }' 4>&- | 221 | dialog --gauge "Download Loader: ${TAG}..." 14 72 4>&- 222 | } 4>&1 223 | fi 224 | fi 225 | if [ -f "${TMP_PATH}/arc.img.zip" ] && [ $(ls -s "${TMP_PATH}/arc.img.zip" | cut -d' ' -f1) -gt 300000 ]; then 226 | unzip -oq "${TMP_PATH}/arc.img.zip" -d "${TMP_PATH}" 227 | rm -f "${TMP_PATH}/arc.img.zip" 228 | dialog --backtitle "$(backtitle)" --title "Upgrade Loader" \ 229 | --infobox "Installing new Loader Image..." 3 50 230 | umount "${PART1_PATH}" "${PART2_PATH}" "${PART3_PATH}" 231 | local IMG_FILE 232 | IMG_FILE="${TMP_PATH}/arc.img" 233 | if dd if="${IMG_FILE}" of=$(blkid | grep 'LABEL="ARC3"' | cut -d3 -f1) bs=1M conv=fsync; then 234 | rm -f "${IMG_FILE}" 235 | dialog --backtitle "$(backtitle)" --title "Upgrade Loader" \ 236 | --infobox "Upgrade done! -> Rebooting..." 3 50 237 | sleep 2 238 | exec reboot 239 | else 240 | dialog --backtitle "$(backtitle)" --title "Upgrade Loader" --aspect 18 \ 241 | --infobox "Upgrade failed!\nTry again later." 0 0 242 | sleep 3 243 | exec reboot 244 | fi 245 | else 246 | dialog --backtitle "$(backtitle)" --title "Upgrade Loader" --aspect 18 \ 247 | --infobox "Upgrade failed!\nTry again later." 0 0 248 | sleep 3 249 | fi 250 | return 0 251 | } 252 | 253 | ############################################################################### 254 | # Update Addons 255 | function updateAddons() { 256 | [ -f "${ADDONS_PATH}/VERSION" ] && local ADDONSVERSION="$(cat "${ADDONS_PATH}/VERSION")" || ADDONSVERSION="0.0.0" 257 | idx=0 258 | while [ "${idx}" -le 5 ]; do # Loop 5 times, if successful, break 259 | local TAG="$(curl -m 10 -skL "https://api.github.com/repos/AuxXxilium/arc-addons/releases" | jq -r ".[].tag_name" | sort -rV | head -1)" 260 | if [ -n "${TAG}" ]; then 261 | break 262 | fi 263 | sleep 3 264 | idx=$((${idx} + 1)) 265 | done 266 | if [ -n "${TAG}" ]; then 267 | export URL="https://github.com/AuxXxilium/arc-addons/releases/download/${TAG}/addons-${TAG}.zip" 268 | export TAG="${TAG}" 269 | { 270 | { 271 | curl -kL "${URL}" -o "${TMP_PATH}/addons.zip" 2>&3 3>&- 272 | } 3>&1 >&4 4>&- | 273 | perl -C -lane ' 274 | BEGIN {$header = "Downloading $ENV{URL}...\n\n"; $| = 1} 275 | $pcent = $F[0]; 276 | $_ = join "", unpack("x3 a7 x4 a9 x8 a9 x7 a*") if length > 20; 277 | s/ /\xa0/g; # replacing space with nbsp as dialog squashes spaces 278 | if ($. <= 3) { 279 | $header .= "$_\n"; 280 | $/ = "\r" if $. == 2 281 | } else { 282 | print "XXX\n$pcent\n$header$_\nXXX" 283 | }' 4>&- | 284 | dialog --gauge "Download Addons: ${TAG}..." 14 72 4>&- 285 | } 4>&1 286 | if [ -f "${TMP_PATH}/addons.zip" ]; then 287 | rm -rf "${ADDONS_PATH}" 288 | mkdir -p "${ADDONS_PATH}" 289 | dialog --backtitle "$(backtitle)" --title "Update Addons" \ 290 | --infobox "Updating Addons..." 3 50 291 | if unzip -oq "${TMP_PATH}/addons.zip" -d "${ADDONS_PATH}"; then 292 | rm -f "${TMP_PATH}/addons.zip" 293 | for F in "${ADDONS_PATH}"/*.addon; do 294 | ADDON=$(basename "${F}" | sed 's|.addon||') 295 | rm -rf "${ADDONS_PATH}/${ADDON}" 296 | mkdir -p "${ADDONS_PATH}/${ADDON}" 297 | tar -xaf "${F}" -C "${ADDONS_PATH}/${ADDON}" 298 | rm -f "${F}" 299 | done 300 | dialog --backtitle "$(backtitle)" --title "Update Addons" \ 301 | --infobox "Update Addons successful!" 3 50 302 | sleep 2 303 | else 304 | return 1 305 | fi 306 | else 307 | return 1 308 | fi 309 | fi 310 | return 0 311 | } 312 | 313 | ############################################################################### 314 | # Update Patches 315 | function updatePatches() { 316 | [ -f "${PATCH_PATH}/VERSION" ] && local PATCHESVERSION="$(cat "${PATCH_PATH}/VERSION")" || PATCHESVERSION="0.0.0" 317 | idx=0 318 | while [ "${idx}" -le 5 ]; do # Loop 5 times, if successful, break 319 | local TAG="$(curl -m 10 -skL "https://api.github.com/repos/AuxXxilium/arc-patches/releases" | jq -r ".[].tag_name" | sort -rV | head -1)" 320 | if [ -n "${TAG}" ]; then 321 | break 322 | fi 323 | sleep 3 324 | idx=$((${idx} + 1)) 325 | done 326 | if [ -n "${TAG}" ]; then 327 | export URL="https://github.com/AuxXxilium/arc-patches/releases/download/${TAG}/patches-${TAG}.zip" 328 | export TAG="${TAG}" 329 | { 330 | { 331 | curl -kL "${URL}" -o "${TMP_PATH}/patches.zip" 2>&3 3>&- 332 | } 3>&1 >&4 4>&- | 333 | perl -C -lane ' 334 | BEGIN {$header = "Downloading $ENV{URL}...\n\n"; $| = 1} 335 | $pcent = $F[0]; 336 | $_ = join "", unpack("x3 a7 x4 a9 x8 a9 x7 a*") if length > 20; 337 | s/ /\xa0/g; # replacing space with nbsp as dialog squashes spaces 338 | if ($. <= 3) { 339 | $header .= "$_\n"; 340 | $/ = "\r" if $. == 2 341 | } else { 342 | print "XXX\n$pcent\n$header$_\nXXX" 343 | }' 4>&- | 344 | dialog --gauge "Download Patches: ${TAG}..." 14 72 4>&- 345 | } 4>&1 346 | if [ -f "${TMP_PATH}/patches.zip" ]; then 347 | rm -rf "${PATCH_PATH}" 348 | mkdir -p "${PATCH_PATH}" 349 | dialog --backtitle "$(backtitle)" --title "Update Patches" \ 350 | --infobox "Updating Patches..." 3 50 351 | if unzip -oq "${TMP_PATH}/patches.zip" -d "${PATCH_PATH}"; then 352 | rm -f "${TMP_PATH}/patches.zip" 353 | dialog --backtitle "$(backtitle)" --title "Update Patches" \ 354 | --infobox "Update Patches successful!" 3 50 355 | sleep 2 356 | else 357 | return 1 358 | fi 359 | else 360 | return 1 361 | fi 362 | fi 363 | return 0 364 | } 365 | 366 | ############################################################################### 367 | # Update Custom 368 | function updateCustom() { 369 | [ -f "${CUSTOM_PATH}/VERSION" ] && local CUSTOMVERSION="$(cat "${CUSTOM_PATH}/VERSION")" || CUSTOMVERSION="0.0.0" 370 | idx=0 371 | while [ "${idx}" -le 5 ]; do # Loop 5 times, if successful, break 372 | local TAG="$(curl -m 10 -skL "https://api.github.com/repos/AuxXxilium/arc-custom/releases" | jq -r ".[].tag_name" | sort -rV | head -1)" 373 | if [ -n "${TAG}" ]; then 374 | break 375 | fi 376 | sleep 3 377 | idx=$((${idx} + 1)) 378 | done 379 | if [ -n "${TAG}" ]; then 380 | export URL="https://github.com/AuxXxilium/arc-custom/releases/download/${TAG}/custom-${TAG}.zip" 381 | export TAG="${TAG}" 382 | { 383 | { 384 | curl -kL "${URL}" -o "${TMP_PATH}/custom.zip" 2>&3 3>&- 385 | } 3>&1 >&4 4>&- | 386 | perl -C -lane ' 387 | BEGIN {$header = "Downloading $ENV{URL}...\n\n"; $| = 1} 388 | $pcent = $F[0]; 389 | $_ = join "", unpack("x3 a7 x4 a9 x8 a9 x7 a*") if length > 20; 390 | s/ /\xa0/g; # replacing space with nbsp as dialog squashes spaces 391 | if ($. <= 3) { 392 | $header .= "$_\n"; 393 | $/ = "\r" if $. == 2 394 | } else { 395 | print "XXX\n$pcent\n$header$_\nXXX" 396 | }' 4>&- | 397 | dialog --gauge "Download Custom: ${TAG}..." 14 72 4>&- 398 | } 4>&1 399 | if [ -f "${TMP_PATH}/custom.zip" ]; then 400 | rm -rf "${CUSTOM_PATH}" 401 | mkdir -p "${CUSTOM_PATH}" 402 | dialog --backtitle "$(backtitle)" --title "Update Custom Kernel" \ 403 | --infobox "Updating Custom Kernel..." 3 50 404 | if unzip -oq "${TMP_PATH}/custom.zip" -d "${CUSTOM_PATH}"; then 405 | rm -f "${TMP_PATH}/custom.zip" 406 | dialog --backtitle "$(backtitle)" --title "Update Custom Kernel" \ 407 | --infobox "Update Custom successful!" 3 50 408 | sleep 2 409 | else 410 | return 1 411 | fi 412 | else 413 | return 1 414 | fi 415 | fi 416 | return 0 417 | } 418 | 419 | ############################################################################### 420 | # Update Modules 421 | function updateModules() { 422 | [ -f "${MODULES_PATH}/VERSION" ] && local MODULESVERSION="$(cat "${MODULES_PATH}/VERSION")" || MODULESVERSION="0.0.0" 423 | local PRODUCTVER="$(readConfigKey "productver" "${USER_CONFIG_FILE}")" 424 | local PLATFORM="$(readConfigKey "platform" "${USER_CONFIG_FILE}")" 425 | local KVER="$(readConfigKey "platforms.${PLATFORM}.productvers.\"${PRODUCTVER}\".kver" "${P_FILE}")" 426 | is_in_array "${PLATFORM}" "${KVER5L[@]}" && KVERP="${PRODUCTVER}-${KVER}" || KVERP="${KVER}" 427 | idx=0 428 | while [ "${idx}" -le 5 ]; do # Loop 5 times, if successful, break 429 | local TAG="$(curl -m 10 -skL "https://api.github.com/repos/AuxXxilium/arc-modules/releases" | jq -r ".[].tag_name" | sort -rV | head -1)" 430 | if [ -n "${TAG}" ]; then 431 | break 432 | fi 433 | sleep 3 434 | idx=$((${idx} + 1)) 435 | done 436 | if [ -n "${TAG}" ]; then 437 | rm -rf "${MODULES_PATH}" 438 | mkdir -p "${MODULES_PATH}" 439 | export URL="https://github.com/AuxXxilium/arc-modules/releases/download/${TAG}/modules-${TAG}.zip" 440 | export TAG="${TAG}" 441 | { 442 | { 443 | curl -kL "${URL}" -o "${TMP_PATH}/modules.zip" 2>&3 3>&- 444 | } 3>&1 >&4 4>&- | 445 | perl -C -lane ' 446 | BEGIN {$header = "Downloading $ENV{URL}...\n\n"; $| = 1} 447 | $pcent = $F[0]; 448 | $_ = join "", unpack("x3 a7 x4 a9 x8 a9 x7 a*") if length > 20; 449 | s/ /\xa0/g; # replacing space with nbsp as dialog squashes spaces 450 | if ($. <= 3) { 451 | $header .= "$_\n"; 452 | $/ = "\r" if $. == 2 453 | } else { 454 | print "XXX\n$pcent\n$header$_\nXXX" 455 | }' 4>&- | 456 | dialog --gauge "Download Modules: ${TAG}..." 14 72 4>&- 457 | } 4>&1 458 | if [ -f "${TMP_PATH}/modules.zip" ]; then 459 | dialog --backtitle "$(backtitle)" --title "Update Modules" \ 460 | --infobox "Updating Modules..." 3 50 461 | if unzip -oq "${TMP_PATH}/modules.zip" -d "${MODULES_PATH}"; then 462 | rm -f "${TMP_PATH}/modules.zip" 463 | dialog --backtitle "$(backtitle)" --title "Update Modules" \ 464 | --infobox "Update Modules successful!" 3 50 465 | sleep 2 466 | else 467 | return 1 468 | fi 469 | else 470 | return 1 471 | fi 472 | if [ -f "${MODULES_PATH}/${PLATFORM}-${KVERP}.tgz" ] && [ -f "${MODULES_PATH}/firmware.tgz" ]; then 473 | dialog --backtitle "$(backtitle)" --title "Update Modules" \ 474 | --infobox "Rewrite Modules..." 3 50 475 | sleep 2 476 | writeConfigKey "modules" "{}" "${USER_CONFIG_FILE}" 477 | while read -r ID DESC; do 478 | writeConfigKey "modules.${ID}" "" "${USER_CONFIG_FILE}" 479 | done < <(getAllModules "${PLATFORM}" "${KVERP}") 480 | dialog --backtitle "$(backtitle)" --title "Update Modules" \ 481 | --infobox "Rewrite successful!" 3 50 482 | sleep 2 483 | fi 484 | fi 485 | return 0 486 | } 487 | 488 | ############################################################################### 489 | # Update Configs 490 | function updateConfigs() { 491 | [ -f "${MODEL_CONFIG_PATH}/VERSION" ] && local CONFIGSVERSION="$(cat "${MODEL_CONFIG_PATH}/VERSION")" || CONFIGSVERSION="0.0.0" 492 | local USERID="$(readConfigKey "arc.userid" "${USER_CONFIG_FILE}")" 493 | if [ -z "${1}" ]; then 494 | idx=0 495 | while [ "${idx}" -le 5 ]; do # Loop 5 times, if successful, break 496 | local TAG="$(curl -m 10 -skL "https://api.github.com/repos/AuxXxilium/arc-configs/releases" | jq -r ".[].tag_name" | sort -rV | head -1)" 497 | if [ -n "${TAG}" ]; then 498 | break 499 | fi 500 | sleep 3 501 | idx=$((${idx} + 1)) 502 | done 503 | else 504 | local TAG="${1}" 505 | fi 506 | if [ -n "${TAG}" ]; then 507 | export URL="https://github.com/AuxXxilium/arc-configs/releases/download/${TAG}/configs-${TAG}.zip" 508 | export TAG="${TAG}" 509 | { 510 | { 511 | curl -kL "${URL}" -o "${TMP_PATH}/configs.zip" 2>&3 3>&- 512 | } 3>&1 >&4 4>&- | 513 | perl -C -lane ' 514 | BEGIN {$header = "Downloading $ENV{URL}...\n\n"; $| = 1} 515 | $pcent = $F[0]; 516 | $_ = join "", unpack("x3 a7 x4 a9 x8 a9 x7 a*") if length > 20; 517 | s/ /\xa0/g; # replacing space with nbsp as dialog squashes spaces 518 | if ($. <= 3) { 519 | $header .= "$_\n"; 520 | $/ = "\r" if $. == 2 521 | } else { 522 | print "XXX\n$pcent\n$header$_\nXXX" 523 | }' 4>&- | 524 | dialog --gauge "Download Configs: ${TAG}..." 14 72 4>&- 525 | } 4>&1 526 | if [ -f "${TMP_PATH}/configs.zip" ]; then 527 | mkdir -p "${MODEL_CONFIG_PATH}" 528 | dialog --backtitle "$(backtitle)" --title "Update Configs" \ 529 | --infobox "Updating Configs..." 3 50 530 | if unzip -oq "${TMP_PATH}/configs.zip" -d "${MODEL_CONFIG_PATH}"; then 531 | rm -f "${TMP_PATH}/configs.zip" 532 | dialog --backtitle "$(backtitle)" --title "Update Configs" \ 533 | --infobox "Update Configs successful!" 3 50 534 | sleep 2 535 | [ -n "${USERID}" ] && checkHardwareID || true 536 | else 537 | return 1 538 | fi 539 | else 540 | return 1 541 | fi 542 | fi 543 | return 0 544 | } 545 | 546 | ############################################################################### 547 | # Update LKMs 548 | function updateLKMs() { 549 | [ -f "${LKMS_PATH}/VERSION" ] && local LKMVERSION="$(cat "${LKMS_PATH}/VERSION")" || LKMVERSION="0.0.0" 550 | if [ -z "${1}" ]; then 551 | idx=0 552 | while [ "${idx}" -le 5 ]; do # Loop 5 times, if successful, break 553 | local TAG="$(curl -m 10 -skL "https://api.github.com/repos/AuxXxilium/arc-lkm/releases" | jq -r ".[].tag_name" | sort -rV | head -1)" 554 | if [ -n "${TAG}" ]; then 555 | break 556 | fi 557 | sleep 3 558 | idx=$((${idx} + 1)) 559 | done 560 | else 561 | local TAG="${1}" 562 | fi 563 | if [ -n "${TAG}" ]; then 564 | export URL="https://github.com/AuxXxilium/arc-lkm/releases/download/${TAG}/rp-lkms.zip" 565 | export TAG="${TAG}" 566 | { 567 | { 568 | curl -kL "${URL}" -o "${TMP_PATH}/rp-lkms.zip" 2>&3 3>&- 569 | } 3>&1 >&4 4>&- | 570 | perl -C -lane ' 571 | BEGIN {$header = "Downloading $ENV{URL}...\n\n"; $| = 1} 572 | $pcent = $F[0]; 573 | $_ = join "", unpack("x3 a7 x4 a9 x8 a9 x7 a*") if length > 20; 574 | s/ /\xa0/g; # replacing space with nbsp as dialog squashes spaces 575 | if ($. <= 3) { 576 | $header .= "$_\n"; 577 | $/ = "\r" if $. == 2 578 | } else { 579 | print "XXX\n$pcent\n$header$_\nXXX" 580 | }' 4>&- | 581 | dialog --gauge "Download LKMs: ${TAG}..." 14 72 4>&- 582 | } 4>&1 583 | if [ -f "${TMP_PATH}/rp-lkms.zip" ]; then 584 | rm -rf "${LKMS_PATH}" 585 | mkdir -p "${LKMS_PATH}" 586 | dialog --backtitle "$(backtitle)" --title "Update LKMs" \ 587 | --infobox "Updating LKMs..." 3 50 588 | if unzip -oq "${TMP_PATH}/rp-lkms.zip" -d "${LKMS_PATH}"; then 589 | rm -f "${TMP_PATH}/rp-lkms.zip" 590 | dialog --backtitle "$(backtitle)" --title "Update LKMs" \ 591 | --infobox "Update LKMs successful!" 3 50 592 | sleep 2 593 | else 594 | return 1 595 | fi 596 | else 597 | return 1 598 | fi 599 | fi 600 | return 0 601 | } 602 | 603 | ############################################################################### 604 | # Update Offline 605 | function updateOffline() { 606 | updateConfigs 607 | checkHardwareID 608 | local ARC_OFFLINE="$(readConfigKey "arc.offline" "${USER_CONFIG_FILE}")" 609 | if [ "${ARC_OFFLINE}" != "true" ]; then 610 | [ -f "${MODEL_CONFIG_PATH}/data.yml" ] && cp -f "${MODEL_CONFIG_PATH}/data.yml" "${MODEL_CONFIG_PATH}/data.yml.bak" || true 611 | if ! curl -skL "https://raw.githubusercontent.com/AuxXxilium/arc-dsm/refs/heads/main/data.yml" -o "${MODEL_CONFIG_PATH}/data.yml"; then 612 | [ -f "${MODEL_CONFIG_PATH}/data.yml.bak" ] && cp -f "${MODEL_CONFIG_PATH}/data.yml.bak" "${MODEL_CONFIG_PATH}/data.yml" 613 | else 614 | local FILESIZE=$(stat -c%s "${MODEL_CONFIG_PATH}/data.yml") 615 | if [ "${FILESIZE}" -lt 3072 ]; then 616 | [ -f "${MODEL_CONFIG_PATH}/data.yml.bak" ] && cp -f "${MODEL_CONFIG_PATH}/data.yml.bak" "${MODEL_CONFIG_PATH}/data.yml" 617 | fi 618 | fi 619 | fi 620 | return 0 621 | } 622 | 623 | # Define descriptions and their corresponding functions 624 | DEPENDENCY_DESCRIPTIONS=( 625 | "Update Addons" 626 | "Update Modules" 627 | "Update Custom Kernel" 628 | "Update Patches" 629 | "Update LKMs" 630 | "Update Config & Models DB" 631 | ) 632 | DEPENDENCY_FUNCTIONS=( 633 | "updateAddons" 634 | "updateModules" 635 | "updateCustom" 636 | "updatePatches" 637 | "updateLKMs" 638 | "updateOffline" 639 | ) 640 | 641 | function dependenciesUpdate() { 642 | # Build checklist options: index as tag, description as item 643 | CHECKLIST_OPTS=() 644 | for i in "${!DEPENDENCY_DESCRIPTIONS[@]}"; do 645 | CHECKLIST_OPTS+=("$i" "${DEPENDENCY_DESCRIPTIONS[$i]}" "off") 646 | done 647 | 648 | # Show dialog with only descriptions 649 | CHOICES=$(dialog --backtitle "$(backtitle)" --title "Select Dependencies to Update" \ 650 | --checklist "Use SPACE to select and ENTER to confirm:" 15 50 6 \ 651 | "${CHECKLIST_OPTS[@]}" 3>&1 1>&2 2>&3) 652 | 653 | [ $? -ne 0 ] && dialog --infobox "Update canceled by the user." 3 40 && sleep 2 && clear && return 654 | 655 | FAILED=false 656 | for idx in $CHOICES; do 657 | # Remove quotes if any 658 | idx=${idx//\"/} 659 | ${DEPENDENCY_FUNCTIONS[$idx]} || FAILED=true 660 | done 661 | 662 | if $FAILED; then 663 | dialog --infobox "Some updates failed! Try again later." 3 40 664 | else 665 | dialog --infobox "All selected updates completed successfully!" 3 40 666 | writeConfigKey "arc.builddone" "false" "${USER_CONFIG_FILE}" 667 | fi 668 | 669 | sleep 3 670 | clear 671 | exec arc.sh 672 | } -------------------------------------------------------------------------------- /files/initrd/opt/arc/init.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | [[ -z "${ARC_PATH}" || ! -d "${ARC_PATH}/include" ]] && ARC_PATH="$(cd "$(dirname "${BASH_SOURCE[0]}")" 2>/dev/null && pwd)" 4 | 5 | . "${ARC_PATH}/include/functions.sh" 6 | 7 | # VMware time sync 8 | if type vmware-toolbox-cmd >/dev/null 2>&1; then 9 | if [ "Disable" = "$(vmware-toolbox-cmd timesync status 2>/dev/null)" ]; then 10 | vmware-toolbox-cmd timesync enable >/dev/null 2>&1 || true 11 | fi 12 | if [ "Enabled" = "$(vmware-toolbox-cmd timesync status 2>/dev/null)" ]; then 13 | vmware-toolbox-cmd timesync disable >/dev/null 2>&1 || true 14 | fi 15 | fi 16 | 17 | # Get Loader Disk Bus 18 | [ -z "${LOADER_DISK}" ] && die "Loader Disk not found!" 19 | checkBootLoader || die "The loader is corrupted, please rewrite it!" 20 | arc_mode || die "No bootmode found!" 21 | 22 | [ -f "${HOME}/.initialized" ] && exec arc.sh || true 23 | [ -f "${USER_CONFIG_FILE}" ] && sed -i "s/'/\"/g" "${USER_CONFIG_FILE}" >/dev/null 2>&1 || true 24 | 25 | BUS=$(getBus "${LOADER_DISK}") 26 | EFI=$([ -d /sys/firmware/efi ] && echo 1 || echo 0) 27 | 28 | # Print Title centralized 29 | clear 30 | COLUMNS=$(ttysize 2>/dev/null | awk '{print $1}') 31 | COLUMNS=${COLUMNS:-120} 32 | BANNER="$(figlet -c -w "${COLUMNS}" "Arc Loader")" 33 | TITLE="Version:" 34 | TITLE+=" ${ARC_VERSION} (${ARC_BUILD})" 35 | printf "\033[1;30m%*s\n" ${COLUMNS} "" 36 | printf "\033[1;30m%*s\033[A\n" ${COLUMNS} "" 37 | printf "\033[1;34m%*s\033[0m\n" ${COLUMNS} "${BANNER}" 38 | printf "\033[1;34m%*s\033[0m\n" $(((${#TITLE} + ${COLUMNS}) / 2)) "${TITLE}" 39 | TITLE="Boot:" 40 | [ "${EFI}" -eq 1 ] && TITLE+=" [UEFI]" || TITLE+=" [BIOS]" 41 | TITLE+=" | Device: [${BUS}] | Mode: [${ARC_MODE}]" 42 | printf "\033[1;34m%*s\033[0m\n" $(((${#TITLE} + ${COLUMNS}) / 2)) "${TITLE}" 43 | 44 | # Check for Config File 45 | if [ ! -f "${USER_CONFIG_FILE}" ]; then 46 | touch "${USER_CONFIG_FILE}" 47 | fi 48 | initConfigKey "addons" "{}" "${USER_CONFIG_FILE}" 49 | initConfigKey "arc" "{}" "${USER_CONFIG_FILE}" 50 | initConfigKey "arc.builddone" "false" "${USER_CONFIG_FILE}" 51 | initConfigKey "arc.confdone" "false" "${USER_CONFIG_FILE}" 52 | initConfigKey "arc.offline" "false" "${USER_CONFIG_FILE}" 53 | initConfigKey "arc.patch" "false" "${USER_CONFIG_FILE}" 54 | initConfigKey "arc.hardwareid" "" "${USER_CONFIG_FILE}" 55 | initConfigKey "arc.userid" "" "${USER_CONFIG_FILE}" 56 | initConfigKey "arc.version" "${ARC_VERSION}" "${USER_CONFIG_FILE}" 57 | initConfigKey "bootscreen" "{}" "${USER_CONFIG_FILE}" 58 | initConfigKey "bootscreen.dsminfo" "true" "${USER_CONFIG_FILE}" 59 | initConfigKey "bootscreen.systeminfo" "true" "${USER_CONFIG_FILE}" 60 | initConfigKey "bootscreen.diskinfo" "false" "${USER_CONFIG_FILE}" 61 | initConfigKey "bootscreen.hwidinfo" "false" "${USER_CONFIG_FILE}" 62 | initConfigKey "bootscreen.dsmlogo" "true" "${USER_CONFIG_FILE}" 63 | initConfigKey "bootipwait" "20" "${USER_CONFIG_FILE}" 64 | initConfigKey "device" "{}" "${USER_CONFIG_FILE}" 65 | initConfigKey "directboot" "false" "${USER_CONFIG_FILE}" 66 | initConfigKey "dsmver" "" "${USER_CONFIG_FILE}" 67 | initConfigKey "emmcboot" "false" "${USER_CONFIG_FILE}" 68 | initConfigKey "governor" "performance" "${USER_CONFIG_FILE}" 69 | initConfigKey "hddsort" "false" "${USER_CONFIG_FILE}" 70 | initConfigKey "kernel" "official" "${USER_CONFIG_FILE}" 71 | initConfigKey "kernelload" "power" "${USER_CONFIG_FILE}" 72 | initConfigKey "kernelpanic" "5" "${USER_CONFIG_FILE}" 73 | initConfigKey "odp" "false" "${USER_CONFIG_FILE}" 74 | initConfigKey "pathash" "" "${USER_CONFIG_FILE}" 75 | initConfigKey "paturl" "" "${USER_CONFIG_FILE}" 76 | initConfigKey "sn" "" "${USER_CONFIG_FILE}" 77 | initConfigKey "cmdline" "{}" "${USER_CONFIG_FILE}" 78 | initConfigKey "keymap" "" "${USER_CONFIG_FILE}" 79 | initConfigKey "layout" "" "${USER_CONFIG_FILE}" 80 | initConfigKey "lkm" "prod" "${USER_CONFIG_FILE}" 81 | initConfigKey "modblacklist" "evbug,cdc_ether" "${USER_CONFIG_FILE}" 82 | initConfigKey "modules" "{}" "${USER_CONFIG_FILE}" 83 | initConfigKey "model" "" "${USER_CONFIG_FILE}" 84 | initConfigKey "modelid" "" "${USER_CONFIG_FILE}" 85 | initConfigKey "network" "{}" "${USER_CONFIG_FILE}" 86 | initConfigKey "platform" "" "${USER_CONFIG_FILE}" 87 | initConfigKey "productver" "" "${USER_CONFIG_FILE}" 88 | initConfigKey "buildnum" "" "${USER_CONFIG_FILE}" 89 | initConfigKey "smallnum" "" "${USER_CONFIG_FILE}" 90 | initConfigKey "ramdisk-hash" "" "${USER_CONFIG_FILE}" 91 | initConfigKey "rd-compressed" "false" "${USER_CONFIG_FILE}" 92 | initConfigKey "satadom" "2" "${USER_CONFIG_FILE}" 93 | initConfigKey "synoinfo" "{}" "${USER_CONFIG_FILE}" 94 | initConfigKey "time" "{}" "${USER_CONFIG_FILE}" 95 | initConfigKey "usbmount" "false" "${USER_CONFIG_FILE}" 96 | initConfigKey "zimage-hash" "" "${USER_CONFIG_FILE}" 97 | 98 | # Sort network interfaces 99 | if arrayExistItem "sortnetif:" $(readConfigMap "addons" "${USER_CONFIG_FILE}"); then 100 | echo -e "NIC sorting: \033[1;34menabled\033[0m" 101 | _sort_netif "$(readConfigKey "addons.sortnetif" "${USER_CONFIG_FILE}")" 102 | echo 103 | fi 104 | # Read/Write IP/Mac to config 105 | ETHX="$(find /sys/class/net/ -mindepth 1 -maxdepth 1 -name 'eth*' -exec basename {} \; | sort)" 106 | for N in ${ETHX}; do 107 | MACR="$(cat /sys/class/net/${N}/address 2>/dev/null | sed 's/://g')" 108 | IPR="$(readConfigKey "network.${MACR}" "${USER_CONFIG_FILE}")" 109 | if [ -n "${IPR}" ]; then 110 | if [ ! "1" = "$(cat /sys/class/net/${N}/carrier 2>/dev/null)" ]; then 111 | ip link set "${N}" up 2>/dev/null || true 112 | fi 113 | IFS='/' read -r -a IPRA <<<"${IPR}" 114 | ip addr flush dev "${N}" 2>/dev/null || true 115 | ip addr add "${IPRA[0]}/${IPRA[1]:-"255.255.255.0"}" dev "${N}" 2>/dev/null || true 116 | if [ -n "${IPRA[2]}" ]; then 117 | ip route add default via "${IPRA[2]}" dev "${N}" 2>/dev/null || true 118 | fi 119 | if [ -n "${IPRA[3]:-${IPRA[2]}}" ]; then 120 | sed -i "/nameserver ${IPRA[3]:-${IPRA[2]}}/d" /etc/resolv.conf 121 | echo "nameserver ${IPRA[3]:-${IPRA[2]}}" >>/etc/resolv.conf 122 | fi 123 | sleep 1 124 | fi 125 | [ "${N::3}" = "eth" ] && ethtool -s "${N}" wol g 2>/dev/null || true 126 | # [ "${N::3}" = "eth" ] && ethtool -K ${N} rxhash off 2>/dev/null || true 127 | initConfigKey "${N}" "${MACR}" "${USER_CONFIG_FILE}" 128 | done 129 | ETHN=$(echo ${ETHX} | wc -w) 130 | writeConfigKey "device.nic" "${ETHN}" "${USER_CONFIG_FILE}" 131 | # No network devices 132 | echo 133 | [ "${ETHN}" -le 0 ] && die "No NIC found! - Loader does not work without Network connection." 134 | 135 | # Get the VID/PID if we are in USB 136 | VID="0x46f4" 137 | PID="0x0001" 138 | 139 | BUSLIST="usb sata sas scsi nvme mmc ide virtio vmbus xen" 140 | if [ "${BUS}" = "usb" ]; then 141 | VID="0x$(udevadm info --query property --name "${LOADER_DISK}" 2>/dev/null | grep "ID_VENDOR_ID" | cut -d= -f2)" 142 | PID="0x$(udevadm info --query property --name "${LOADER_DISK}" 2>/dev/null | grep "ID_MODEL_ID" | cut -d= -f2)" 143 | elif ! (echo "${BUSLIST}" | grep -wq "${BUS}"); then 144 | die "$(printf "The boot disk does not support the current %s, only %s are supported." "${BUS}" "${BUSLIST// /\/}")" 145 | fi 146 | 147 | # Save variables to user config file 148 | writeConfigKey "vid" "${VID}" "${USER_CONFIG_FILE}" 149 | writeConfigKey "pid" "${PID}" "${USER_CONFIG_FILE}" 150 | 151 | # Inform user and check bus 152 | echo -e "Loader Disk: \033[1;34m${LOADER_DISK}\033[0m" 153 | echo -e "Loader Disk Type: \033[1;34m${BUS}\033[0m" 154 | echo 155 | 156 | # Decide if boot automatically 157 | BUILDDONE="$(readConfigKey "arc.builddone" "${USER_CONFIG_FILE}")" 158 | if [ "${ARC_MODE}" = "config" ]; then 159 | echo -e "\033[1;34mStarting Config Mode...\033[0m" 160 | elif [ "${ARC_MODE}" = "automated" ]; then 161 | echo -e "\033[1;34mStarting automated Build Mode...\033[0m" 162 | elif [ "${ARC_MODE}" = "update" ]; then 163 | echo -e "\033[1;34mStarting Update Mode...\033[0m" 164 | elif [ "${BUILDDONE}" = "true" ] && [ "${ARC_MODE}" = "dsm" ]; then 165 | echo -e "\033[1;34mStarting DSM Mode...\033[0m" 166 | exec boot.sh && exit 0 167 | else 168 | echo -e "\033[1;34mStarting Config Mode...\033[0m" 169 | fi 170 | echo 171 | 172 | BOOTIPWAIT="$(readConfigKey "bootipwait" "${USER_CONFIG_FILE}")" 173 | [ -z "${BOOTIPWAIT}" ] && BOOTIPWAIT=30 174 | IPCON="" 175 | echo -e "\033[1;37mDetected ${ETHN} NIC:\033[0m" 176 | echo 177 | 178 | [ ! -f /var/run/dhcpcd/pid ] && /etc/init.d/S41dhcpcd restart >/dev/null 2>&1 && sleep 3 || true 179 | checkNIC 180 | echo 181 | 182 | mkdir -p "${ADDONS_PATH}" 183 | mkdir -p "${CUSTOM_PATH}" 184 | mkdir -p "${LKMS_PATH}" 185 | mkdir -p "${MODEL_CONFIG_PATH}" 186 | mkdir -p "${MODULES_PATH}" 187 | mkdir -p "${PATCH_PATH}" 188 | mkdir -p "${USER_UP_PATH}" 189 | 190 | # Tell webterminal that the loader is ready 191 | touch "${HOME}/.initialized" 192 | 193 | # Load Arc Overlay 194 | echo -e "\033[1;34mLoading Arc Overlay...\033[0m" 195 | echo 196 | echo -e "Use \033[1;34mDisplay Output\033[0m or \033[1;34mhttp://${IPCON}:${HTTPPORT:-7080}\033[0m to configure Loader." 197 | 198 | # Check memory and load Arc 199 | RAM=$(awk '/MemTotal:/ {printf "%.0f", $2 / 1024}' /proc/meminfo 2>/dev/null) 200 | if [ "${RAM}" -le 3500 ]; then 201 | echo -e "\033[1;31mYou have less than 4GB of RAM, if errors occur in loader creation, please increase the amount of RAM.\033[0m" 202 | read -rp "Press Enter to continue..." 203 | else 204 | exec arc.sh 205 | fi -------------------------------------------------------------------------------- /files/initrd/opt/arc/kpatch: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AuxXxilium/arc/5fc208ac2e6bc86eddb48a22fad3a46aa35e48a9/files/initrd/opt/arc/kpatch -------------------------------------------------------------------------------- /files/initrd/opt/arc/ramdisk-patch.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | # shellcheck disable=SC2034 4 | 5 | [[ -z "${ARC_PATH}" || ! -d "${ARC_PATH}/include" ]] && ARC_PATH="$(cd "$(dirname "${BASH_SOURCE[0]}")" 2>/dev/null && pwd)" 6 | 7 | . "${ARC_PATH}/include/functions.sh" 8 | . "${ARC_PATH}/include/addons.sh" 9 | . "${ARC_PATH}/include/modules.sh" 10 | 11 | set -o pipefail # Get exit code from process piped 12 | 13 | # Sanity check 14 | if [ ! -f "${ORI_RDGZ_FILE}" ]; then 15 | echo "ERROR: ${ORI_RDGZ_FILE} not found!" >"${LOG_FILE}" 16 | exit 1 17 | fi 18 | 19 | # Remove old rd.gz patched 20 | rm -f "${MOD_RDGZ_FILE}" 21 | 22 | # Unzipping ramdisk 23 | rm -rf "${RAMDISK_PATH}" # Force clean 24 | mkdir -p "${RAMDISK_PATH}" 25 | (cd "${RAMDISK_PATH}" && xz -dc <"${ORI_RDGZ_FILE}" | cpio -idm) >/dev/null 2>&1 26 | 27 | # Read Model Data 28 | PLATFORM="$(readConfigKey "platform" "${USER_CONFIG_FILE}")" 29 | MODEL="$(readConfigKey "model" "${USER_CONFIG_FILE}")" 30 | LKM="$(readConfigKey "lkm" "${USER_CONFIG_FILE}")" 31 | SN="$(readConfigKey "sn" "${USER_CONFIG_FILE}")" 32 | LAYOUT="$(readConfigKey "layout" "${USER_CONFIG_FILE}")" 33 | KEYMAP="$(readConfigKey "keymap" "${USER_CONFIG_FILE}")" 34 | KERNEL="$(readConfigKey "kernel" "${USER_CONFIG_FILE}")" 35 | RD_COMPRESSED="$(readConfigKey "rd-compressed" "${USER_CONFIG_FILE}")" 36 | PRODUCTVER="$(readConfigKey "productver" "${USER_CONFIG_FILE}")" 37 | BUILDNUM="$(readConfigKey "buildnum" "${USER_CONFIG_FILE}")" 38 | SMALLNUM="$(readConfigKey "smallnum" "${USER_CONFIG_FILE}")" 39 | # Read new PAT Info from Config 40 | PAT_URL="$(readConfigKey "paturl" "${USER_CONFIG_FILE}")" 41 | PAT_HASH="$(readConfigKey "pathash" "${USER_CONFIG_FILE}")" 42 | 43 | # Check if DSM Version changed 44 | . "${RAMDISK_PATH}/etc/VERSION" 45 | 46 | if [[ -n "${BUILDNUM}" && ("${PRODUCTVER}" != "${majorversion}.${minorversion}" || "${BUILDNUM}" != "${buildnumber}") ]]; then 47 | OLDVER="${PRODUCTVER}(${BUILDNUM}$([[ ${SMALLNUM:-0} -ne 0 ]] && echo "u${SMALLNUM}"))" 48 | NEWVER="${majorversion}.${minorversion}(${buildnumber}$([[ ${smallfixnumber:-0} -ne 0 ]] && echo "u${smallfixnumber}"))" 49 | PAT_URL="" 50 | PAT_HASH="" 51 | echo -e "Version changed from ${OLDVER} to ${NEWVER}" 52 | fi 53 | 54 | PRODUCTVER="${majorversion}.${minorversion}" 55 | BUILDNUM="${buildnumber}" 56 | SMALLNUM="${smallfixnumber}" 57 | 58 | writeConfigKey "productver" "${PRODUCTVER}" "${USER_CONFIG_FILE}" 59 | writeConfigKey "buildnum" "${BUILDNUM}" "${USER_CONFIG_FILE}" 60 | writeConfigKey "smallnum" "${SMALLNUM}" "${USER_CONFIG_FILE}" 61 | 62 | # Read model data 63 | KVER="$(readConfigKey "platforms.${PLATFORM}.productvers.\"${PRODUCTVER}\".kver" "${P_FILE}")" 64 | is_in_array "${PLATFORM}" "${KVER5L[@]}" && KVERP="${PRODUCTVER}-${KVER}" || KVERP="${KVER}" 65 | 66 | # Sanity check 67 | if [ -z "${PLATFORM}" ] || [ -z "${KVER}" ]; then 68 | echo "ERROR: Configuration for Model ${MODEL} and Version ${PRODUCTVER} not found." >"${LOG_FILE}" 69 | exit 1 70 | fi 71 | 72 | # Read addons, modules and synoinfo 73 | declare -A SYNOINFO 74 | declare -A ADDONS 75 | declare -A MODULES 76 | 77 | while IFS=': ' read -r KEY VALUE; do 78 | [ -n "${KEY}" ] && ADDONS["${KEY}"]="${VALUE}" 79 | done < <(readConfigMap "addons" "${USER_CONFIG_FILE}") 80 | 81 | while IFS=': ' read -r KEY VALUE; do 82 | [ -n "${KEY}" ] && MODULES["${KEY}"]="${VALUE}" 83 | done < <(readConfigMap "modules" "${USER_CONFIG_FILE}") 84 | 85 | #SYNOINFO["SN"]="${SN}" 86 | while IFS=': ' read -r KEY VALUE; do 87 | [ -n "${KEY}" ] && SYNOINFO["${KEY}"]="${VALUE}" 88 | done < <(readConfigMap "synoinfo" "${USER_CONFIG_FILE}") 89 | 90 | # Patches (diff -Naru OLDFILE NEWFILE > xxx.patch) 91 | PATCHES=( 92 | "ramdisk-etc-rc-*.patch" 93 | "ramdisk-init-script-*.patch" 94 | "ramdisk-post-init-script-*.patch" 95 | ) 96 | 97 | for PE in "${PATCHES[@]}"; do 98 | RET=1 99 | echo "Patching with ${PE}" >>"${LOG_FILE}" 100 | # ${PE} contains *, so double quotes cannot be added 101 | for PF in ${PATCH_PATH}/${PE}; do 102 | [ ! -e "${PF}" ] && continue 103 | echo "Patching with ${PF}" >>"${LOG_FILE}" 104 | # busybox patch and gun patch have different processing methods and parameters. 105 | (cd "${RAMDISK_PATH}" && busybox patch -p1 -i "${PF}") >>"${LOG_FILE}" 2>&1 106 | RET=$? 107 | [ ${RET} -eq 0 ] && break 108 | done 109 | [ ${RET} -ne 0 ] && exit 1 110 | done 111 | 112 | mkdir -p "${RAMDISK_PATH}/addons" 113 | 114 | # Addons 115 | echo "Create addons.sh" >>"${LOG_FILE}" 116 | { 117 | echo "#!/bin/sh" 118 | echo 'echo "addons.sh called with params ${@}"' 119 | echo "export LOADERLABEL=\"ARC\"" 120 | echo "export LOADERVERSION=\"${ARC_VERSION}\"" 121 | echo "export LOADERBUILD=\"${ARC_BUILD}\"" 122 | echo "export PLATFORM=\"${PLATFORM}\"" 123 | echo "export MODEL=\"${MODEL}\"" 124 | echo "export PRODUCTVERL=\"${PRODUCTVERL}\"" 125 | echo "export MLINK=\"${PAT_URL}\"" 126 | echo "export MCHECKSUM=\"${PAT_HASH}\"" 127 | echo "export LAYOUT=\"${LAYOUT:-qwerty}\"" 128 | echo "export KEYMAP=\"${KEYMAP:-en}\"" 129 | } >"${RAMDISK_PATH}/addons/addons.sh" 130 | chmod +x "${RAMDISK_PATH}/addons/addons.sh" 131 | 132 | # System Addons 133 | for ADDON in "redpill" "revert" "misc" "eudev" "disks" "localrss" "notify" "wol" "mountloader"; do 134 | if [ "${ADDON}" = "disks" ]; then 135 | [ -f "${USER_UP_PATH}/model.dts" ] && cp -f "${USER_UP_PATH}/model.dts" "${RAMDISK_PATH}/addons/model.dts" 136 | [ -f "${USER_UP_PATH}/${MODEL}.dts" ] && cp -f "${USER_UP_PATH}/${MODEL}.dts" "${RAMDISK_PATH}/addons/model.dts" 137 | fi 138 | installAddon "${ADDON}" "${PLATFORM}" "${KVERP}" || exit 1 139 | echo "/addons/${ADDON}.sh \${1}" >>"${RAMDISK_PATH}/addons/addons.sh" 2>>"${LOG_FILE}" || exit 1 140 | done 141 | 142 | # User Addons 143 | for ADDON in "${!ADDONS[@]}"; do 144 | PARAMS="${ADDONS[${ADDON}]}" 145 | installAddon "${ADDON}" "${PLATFORM}" "${KVERP}" || echo "Addon ${ADDON} not found" 146 | echo "/addons/${ADDON}.sh \${1} ${PARAMS}" >>"${RAMDISK_PATH}/addons/addons.sh" 2>>"${LOG_FILE}" || exit 1 147 | done 148 | 149 | # Extract modules to ramdisk 150 | installModules "${PLATFORM}" "${KVERP}" "${!MODULES[@]}" || exit 1 151 | 152 | # Copying fake modprobe 153 | [ "${KVER:0:1}" = "4" ] && cp -f "${PATCH_PATH}/iosched-trampoline.sh" "${RAMDISK_PATH}/usr/sbin/modprobe" 154 | # Copying LKM to /usr/lib/modules 155 | gzip -dc "${LKMS_PATH}/rp-${PLATFORM}-${KVERP}-${LKM}.ko.gz" >"${RAMDISK_PATH}/usr/lib/modules/rp.ko" 2>>"${LOG_FILE}" || exit 1 156 | 157 | # Patch synoinfo.conf 158 | echo -n "" >"${RAMDISK_PATH}/addons/synoinfo.conf" 159 | for KEY in "${!SYNOINFO[@]}"; do 160 | echo "Set synoinfo ${KEY}" >>"${LOG_FILE}" 161 | echo "${KEY}=\"${SYNOINFO[${KEY}]}\"" >>"${RAMDISK_PATH}/addons/synoinfo.conf" 162 | _set_conf_kv "${RAMDISK_PATH}/etc/synoinfo.conf" "${KEY}" "${SYNOINFO[${KEY}]}" || exit 1 163 | _set_conf_kv "${RAMDISK_PATH}/etc.defaults/synoinfo.conf" "${KEY}" "${SYNOINFO[${KEY}]}" || exit 1 164 | done 165 | if [ ! -x "${RAMDISK_PATH}/usr/bin/get_key_value" ]; then 166 | printf '#!/usr/bin/env sh\n%s\n_get_conf_kv "$@"' "$(declare -f _get_conf_kv)" > "${RAMDISK_PATH}/usr/bin/get_key_value" 167 | chmod a+x "${RAMDISK_PATH}/usr/bin/get_key_value" 168 | fi 169 | if [ ! -x "${RAMDISK_PATH}/usr/bin/set_key_value" ]; then 170 | printf '#!/usr/bin/env sh\n%s\n_set_conf_kv "$@"' "$(declare -f _set_conf_kv)" >"${RAMDISK_PATH}/usr/bin/set_key_value" 171 | chmod a+x "${RAMDISK_PATH}/usr/bin/set_key_value" 172 | fi 173 | 174 | echo "Modify files" >>"${LOG_FILE}" 175 | # Remove function from scripts 176 | [ "2" = "${BUILDNUM:0:1}" ] && find "${RAMDISK_PATH}/addons/" -type f -name "*.sh" -exec sed -i 's/function //g' {} \; 177 | 178 | # Copying modulelist 179 | if [ -f "${USER_UP_PATH}/modulelist" ]; then 180 | cp -f "${USER_UP_PATH}/modulelist" "${RAMDISK_PATH}/addons/modulelist" 181 | else 182 | cp -f "${ARC_PATH}/include/modulelist" "${RAMDISK_PATH}/addons/modulelist" 183 | fi 184 | 185 | # backup current loader configs 186 | mkdir -p "${RAMDISK_PATH}/usr/arc" 187 | { 188 | echo "LOADERLABEL=\"Arc\"" 189 | echo "LOADERVERSION=\"${ARC_VERSION}\"" 190 | echo "LOADERBUILD=\"${ARC_BUILD}\"" 191 | } >"${RAMDISK_PATH}/usr/arc/VERSION" 192 | BACKUP_PATH="${RAMDISK_PATH}/usr/arc/backup" 193 | rm -rf "${BACKUP_PATH}" 194 | for F in "${USER_GRUB_CONFIG}" "${USER_CONFIG_FILE}" "${USER_UP_PATH}"; do 195 | if [ -f "${F}" ]; then 196 | FD="$(dirname "${F}")" 197 | mkdir -p "${FD/\/mnt/${BACKUP_PATH}}" 198 | cp -f "${F}" "${FD/\/mnt/${BACKUP_PATH}}" 199 | elif [ -d "${F}" ]; then 200 | SIZE="$(du -sm "${F}" 2>/dev/null | awk '{print $1}')" 201 | if [ ${SIZE:-0} -gt 4 ]; then 202 | echo "Backup of ${F} skipped, size is ${SIZE}MB" >>"${LOG_FILE}" 203 | continue 204 | fi 205 | FD="$(dirname "${F}")" 206 | mkdir -p "${FD/\/mnt/${BACKUP_PATH}}" 207 | cp -rf "${F}" "${FD/\/mnt/${BACKUP_PATH}}" 208 | fi 209 | done 210 | 211 | # Network card configuration file 212 | for N in $(seq 0 7); do 213 | echo -e "DEVICE=eth${N}\nBOOTPROTO=dhcp\nONBOOT=yes\nIPV6INIT=dhcp\nIPV6_ACCEPT_RA=1" >"${RAMDISK_PATH}/etc/sysconfig/network-scripts/ifcfg-eth${N}" 214 | done 215 | 216 | # Kernel 5.x patches 217 | if [ "${KVER:0:1}" = "5" ]; then 218 | echo -e ">>> apply Kernel 5.x Fixes" 219 | sed -i 's#/dev/console#/var/log/lrc#g' ${RAMDISK_PATH}/usr/bin/busybox 220 | sed -i '/^echo "START/a \\nmknod -m 0666 /dev/console c 1 3' ${RAMDISK_PATH}/linuxrc.syno 221 | fi 222 | 223 | # Broadwellntbap patches 224 | if [ "${PLATFORM}" = "broadwellntbap" ]; then 225 | echo -e ">>> apply Broadwellntbap Fixes" 226 | sed -i 's/IsUCOrXA="yes"/XIsUCOrXA="yes"/g; s/IsUCOrXA=yes/XIsUCOrXA=yes/g' ${RAMDISK_PATH}/usr/syno/share/environments.sh 227 | fi 228 | 229 | # Reassembly ramdisk 230 | rm -f "${MOD_RDGZ_FILE}" 231 | if [ "${RD_COMPRESSED}" = "true" ]; then 232 | (cd "${RAMDISK_PATH}" && find . 2>/dev/null | cpio -o -H newc -R root:root | xz -9 --format=lzma >"${MOD_RDGZ_FILE}") >>"${LOG_FILE}" 2>&1 || exit 1 233 | else 234 | (cd "${RAMDISK_PATH}" && find . 2>/dev/null | cpio -o -H newc -R root:root >"${MOD_RDGZ_FILE}") >>"${LOG_FILE}" 2>&1 || exit 1 235 | fi 236 | 237 | sync 238 | 239 | # Clean 240 | rm -rf "${RAMDISK_PATH}" -------------------------------------------------------------------------------- /files/initrd/opt/arc/vmlinux-to-bzImage.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | # Based on code and ideas from @jumkey 3 | 4 | [[ -z "${ARC_PATH}" || ! -d "${ARC_PATH}/include" ]] && ARC_PATH="$(cd "$(dirname "${BASH_SOURCE[0]}")" 2>/dev/null && pwd)" 5 | 6 | . "${ARC_PATH}/include/functions.sh" 7 | 8 | calc_run_size() { 9 | NUM='\([0-9a-fA-F]*[ \t]*\)' 10 | OUT=$(sed -n 's/^[ \t0-9]*.b[sr][sk][ \t]*'"${NUM}${NUM}${NUM}${NUM}"'.*/0x\1 0x\4/p') 11 | 12 | if [ -z "${OUT}" ]; then 13 | echo "Never found .bss or .brk file offset" >&2 14 | return 1 15 | fi 16 | 17 | read -r sizeA offsetA sizeB offsetB <<<$(echo ${OUT} | awk '{printf "%d %d %d %d", strtonum($1), strtonum($2), strtonum($3), strtonum($4)}') 18 | 19 | runSize=$((offsetA + sizeA + sizeB)) 20 | 21 | # BFD linker shows the same file offset in ELF. 22 | if [ "${offsetA}" -ne "${offsetB}" ]; then 23 | # Gold linker shows them as consecutive. 24 | endSize=$((offsetB + sizeB)) 25 | if [ "${endSize}" -ne "${runSize}" ]; then 26 | printf "sizeA: 0x%x\n" ${sizeA} >&2 27 | printf "offsetA: 0x%x\n" ${offsetA} >&2 28 | printf "sizeB: 0x%x\n" ${sizeB} >&2 29 | printf "offsetB: 0x%x\n" ${offsetB} >&2 30 | echo ".bss and .brk are non-contiguous" >&2 31 | return 1 32 | fi 33 | fi 34 | 35 | printf "%d\n" ${runSize} 36 | return 0 37 | } 38 | 39 | # Adapted from: scripts/Makefile.lib 40 | # Usage: size_append FILE [FILE2] [FILEn]... 41 | # Output: LE HEX with size of file in bytes (to STDOUT) 42 | file_size_le() { 43 | printf $( 44 | local dec_size=0 45 | for F in "$@"; do dec_size=$((dec_size + $(stat -c "%s" "${F}"))); done 46 | printf "%08x\n" "${dec_size}" | sed 's/\(..\)/\1 /g' | { 47 | read -r ch0 ch1 ch2 ch3 48 | for ch in "${ch3}" "${ch2}" "${ch1}" "${ch0}"; do printf '%s%03o' '\' "$((0x${ch}))"; done 49 | } 50 | ) 51 | } 52 | 53 | size_le() { 54 | printf $( 55 | printf "%08x\n" "${@}" | sed 's/\(..\)/\1 /g' | { 56 | read -r ch0 ch1 ch2 ch3 57 | for ch in "${ch3}" "${ch2}" "${ch1}" "${ch0}"; do printf '%s%03o' '\' "$((0x${ch}))"; done 58 | } 59 | ) 60 | } 61 | 62 | VMLINUX_MOD=${1} 63 | ZIMAGE_MOD=${2} 64 | 65 | KVER=$(strings "${VMLINUX_MOD}" | grep -Eo "Linux version [0-9]+\.[0-9]+\.[0-9]+" | head -1 | awk '{print $3}') 66 | if [ "${KVER:0:1}" = "4" ]; then 67 | echo -e ">>> patching Kernel 4.x" 68 | gzip -dc "${ARC_PATH}/bzImage-template-v4.gz" >"${ZIMAGE_MOD}" 2>/dev/null || exit 1 69 | 70 | dd if="${VMLINUX_MOD}" of="${ZIMAGE_MOD}" bs=16494 seek=1 conv=notrunc 2>/dev/null || exit 1 71 | file_size_le "${VMLINUX_MOD}" | dd of="${ZIMAGE_MOD}" bs=15745134 seek=1 conv=notrunc 2>/dev/null || exit 1 72 | file_size_le "${VMLINUX_MOD}" | dd of="${ZIMAGE_MOD}" bs=15745244 seek=1 conv=notrunc 2>/dev/null || exit 1 73 | 74 | RUN_SIZE=$(objdump -h "${VMLINUX_MOD}" | calc_run_size 2>/dev/null) 75 | size_le "${RUN_SIZE}" | dd of="${ZIMAGE_MOD}" bs=15745210 seek=1 conv=notrunc 2>/dev/null || exit 1 76 | size_le "$((16#$(crc32 "${ZIMAGE_MOD}" | awk '{print $1}') ^ 0xFFFFFFFF))" | dd of="${ZIMAGE_MOD}" conv=notrunc oflag=append 2>/dev/null || exit 1 77 | elif [ "${KVER:0:1}" = "5" ]; then 78 | echo -e ">>> patching Kernel 5.x" 79 | gzip -dc "${ARC_PATH}/bzImage-template-v5.gz" >"${ZIMAGE_MOD}" 2>/dev/null || exit 1 80 | 81 | dd if="${VMLINUX_MOD}" of="${ZIMAGE_MOD}" bs=14561 seek=1 conv=notrunc 2>/dev/null || exit 1 82 | file_size_le "${VMLINUX_MOD}" | dd of="${ZIMAGE_MOD}" bs=34463421 seek=1 conv=notrunc 2>/dev/null || exit 1 83 | file_size_le "${VMLINUX_MOD}" | dd of="${ZIMAGE_MOD}" bs=34479132 seek=1 conv=notrunc 2>/dev/null || exit 1 84 | # RUN_SIZE=$(objdump -h "${VMLINUX_MOD}" | calc_run_size 2>/dev/null) 85 | # size_le "${RUN_SIZE}" | dd of="${ZIMAGE_MOD}" bs=34626904 seek=1 conv=notrunc 2>/dev/null || exit 1 86 | size_le "$((16#$(crc32 "${ZIMAGE_MOD}" | awk '{print $1}') ^ 0xFFFFFFFF))" | dd of="${ZIMAGE_MOD}" conv=notrunc oflag=append 2>/dev/null || exit 1 87 | else 88 | die "Kernel version ${KVER} not supported!" 89 | exit 1 90 | fi -------------------------------------------------------------------------------- /files/initrd/opt/arc/zimage-patch.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | [[ -z "${ARC_PATH}" || ! -d "${ARC_PATH}/include" ]] && ARC_PATH="$(cd "$(dirname "${BASH_SOURCE[0]}")" 2>/dev/null && pwd)" 4 | 5 | . "${ARC_PATH}/include/functions.sh" 6 | 7 | set -o pipefail # Get exit code from process piped 8 | 9 | # Sanity check 10 | [ -f "${ORI_ZIMAGE_FILE}" ] || (die "${ORI_ZIMAGE_FILE} not found!" | tee -a "${LOG_FILE}") 11 | 12 | rm -f "${MOD_ZIMAGE_FILE}" 13 | 14 | KERNEL="$(readConfigKey "kernel" "${USER_CONFIG_FILE}")" 15 | PLATFORM="$(readConfigKey "platform" "${USER_CONFIG_FILE}")" 16 | PRODUCTVER="$(readConfigKey "productver" "${USER_CONFIG_FILE}")" 17 | KVER="$(readConfigKey "platforms.${PLATFORM}.productvers.\"${PRODUCTVER}\".kver" "${P_FILE}")" 18 | is_in_array "${PLATFORM}" "${KVER5L[@]}" && KVERP="${PRODUCTVER}-${KVER}" || true 19 | if [ "${KERNEL}" = "custom" ]; then 20 | echo -e ">>> using customized Kernel for ${PLATFORM} (${KVER})" 21 | # Extract bzImage 22 | gzip -dc "${CUSTOM_PATH}/bzImage-${PLATFORM}-${KVERP}.gz" >"${MOD_ZIMAGE_FILE}" 23 | else 24 | echo -e ">>> using official Kernel for ${PLATFORM} (${KVER})" 25 | # Extract vmlinux 26 | "${ARC_PATH}/bzImage-to-vmlinux.sh" "${ORI_ZIMAGE_FILE}" "${TMP_PATH}/vmlinux" >"${LOG_FILE}" 2>&1 || dieLog 27 | # Patch boot params and ramdisk check 28 | "${ARC_PATH}/kpatch" "${TMP_PATH}/vmlinux" "${TMP_PATH}/vmlinux-mod" >"${LOG_FILE}" 2>&1 || dieLog 29 | # rebuild zImage 30 | "${ARC_PATH}/vmlinux-to-bzImage.sh" "${TMP_PATH}/vmlinux-mod" "${MOD_ZIMAGE_FILE}" || dieLog 31 | fi 32 | 33 | sync -------------------------------------------------------------------------------- /files/p1/EFI/BOOT/SynoBootLoader.conf: -------------------------------------------------------------------------------- 1 | serial --unit=1 --speed=115200 2 | terminal serial 3 | default 1 4 | timeout 3 5 | verbose 6 | hiddenmenu 7 | fallback 0 8 | 9 | title SYNOLOGY_1 10 | root (hd0,0) 11 | kernel /zImage root=/dev/md0 12 | initrd /rd.gz 13 | 14 | title SYNOLOGY_2 15 | root (hd0,1) 16 | cksum /grub_cksum.syno 17 | vender /vender show 18 | kernel /zImage root=/dev/md0 19 | initrd /rd.gz 20 | -------------------------------------------------------------------------------- /files/p1/EFI/BOOT/SynoBootLoader.efi: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AuxXxilium/arc/5fc208ac2e6bc86eddb48a22fad3a46aa35e48a9/files/p1/EFI/BOOT/SynoBootLoader.efi -------------------------------------------------------------------------------- /files/p1/boot/grub/gfxblacklist.txt: -------------------------------------------------------------------------------- 1 | # GRUB gfxpayload blacklist. The format is a sequence of lines of the 2 | # following form, using lower-case hexadecimal for all ID components: 3 | # 4 | # vVENDORdDEVICEsvSUBVENDORsdSUBDEVICEbcBASECLASSscSUBCLASS 5 | # 6 | # Blacklist lines are regex-matched (currently using Lua's string.find with 7 | # the line surrounded by ^ and $) against a corresponding PCI ID string. In 8 | # practice this means that you can replace any part of the ID string with .* 9 | # to match anything. 10 | # 11 | # There is no need to customise this file locally. If you need to disable 12 | # gfxpayload=keep on your system, just add this line (uncommented) to 13 | # /etc/default/grub: 14 | # 15 | # GRUB_GFXPAYLOAD_LINUX=text 16 | 17 | v15add0710.* 18 | v15add0405.* 19 | v80eedbeef.* 20 | v1002d6738.* 21 | -------------------------------------------------------------------------------- /files/p1/boot/grub/grub.cfg: -------------------------------------------------------------------------------- 1 | 2 | set timeout="5" 3 | set timeout_style="menu" 4 | 5 | if [ -s ${prefix}/grubenv ]; then 6 | load_env --skip-sig --file=${prefix}/grubenv 7 | fi 8 | 9 | if [ "${next_entry}" ]; then 10 | set default="${next_entry}" 11 | unset next_entry 12 | save_env next_entry 13 | else 14 | set default="boot" 15 | fi 16 | 17 | if [ "${linux_gfx_mode}" ]; then 18 | save_env linux_gfx_mode 19 | else 20 | set linux_gfx_mode=keep 21 | save_env linux_gfx_mode 22 | fi 23 | 24 | if [ x"${feature_menuentry_id}" = xy ]; then 25 | menuentry_id_option="--id" 26 | else 27 | menuentry_id_option="" 28 | fi 29 | 30 | export menuentry_id_option 31 | 32 | function load_video { 33 | if [ x"${feature_all_video_module}" = xy ]; then 34 | insmod all_video 35 | else 36 | insmod efi_gop 37 | insmod efi_uga 38 | insmod ieee1275_fb 39 | insmod vbe 40 | insmod vga 41 | insmod video_bochs 42 | insmod video_cirrus 43 | fi 44 | } 45 | 46 | set menu_color_normal=white/black 47 | set menu_color_highlight=white/red 48 | set color_normal=white/black 49 | 50 | if [ x"${feature_default_font_path}" = xy ]; then 51 | font=unicode 52 | else 53 | font=${prefix}/fonts/unicode.pf2 54 | fi 55 | 56 | if loadfont ${font}; then 57 | if [ "${grub_platform}" = "efi" ]; then 58 | set gfxmode=auto 59 | else 60 | set gfxmode=1024x768 61 | fi 62 | load_video 63 | insmod gfxterm 64 | insmod gfxmenu 65 | loadfont ${prefix}/theme/dejavu_bold_14.pf2 66 | loadfont ${prefix}/theme/dejavu_mono_12.pf2 67 | insmod png 68 | set theme=${prefix}/theme/theme.txt 69 | export theme 70 | fi 71 | 72 | terminal_output gfxterm 73 | 74 | if serial --unit=0 --speed=115200 --word=8 --parity=no --stop=1; then 75 | terminal_input --append serial 76 | terminal_output --append serial 77 | fi 78 | 79 | function gfxmode { 80 | set gfxpayload="${linux_gfx_mode}" 81 | } 82 | 83 | set ARC_CMDLINE="earlyprintk earlycon=uart8250,io,0x3f8,115200n8 console=ttyS0,115200n8 root=/dev/ram rootwait intremap=off amd_iommu_intr=legacy net.ifnames=0 panic=5 split_lock_detect=off pcie_aspm=off intel_pstate=disable amd_pstate=disable nox2apic nomodeset nowatchdog" 84 | 85 | search --set=root --label "ARC3" 86 | if [ -e /initrd-user ]; then 87 | set ARCU=/initrd-user 88 | fi 89 | if [ -s /zImage-dsm -a -s /initrd-dsm ]; then 90 | if [ "${default}" = "direct" ]; then 91 | set timeout="1" 92 | if [ -s ${prefix}/rsysenv ]; then 93 | load_env --skip-sig --file=${prefix}/rsysenv 94 | fi 95 | menuentry 'DSM Direct Mode' ${menuentry_id_option} direct { 96 | gfxmode 97 | echo "Loading DSM Kernel..." 98 | linux /zImage-dsm ${dsm_cmdline} 99 | echo "Loading DSM Initramfs..." 100 | initrd /initrd-dsm 101 | echo "Booting..." 102 | echo "Access http://find.synology.com/ to connect the DSM via web." 103 | } 104 | fi 105 | menuentry 'Arc DSM Mode' ${menuentry_id_option} boot { 106 | gfxmode 107 | echo "Loading Arc Kernel..." 108 | linux /bzImage-arc ${ARC_CMDLINE} ${arc_cmdline} 109 | echo "Loading Arc Initramfs..." 110 | initrd /initrd-arc ${ARCU} 111 | echo "Booting..." 112 | } 113 | fi 114 | 115 | if [ -e /automated ]; then 116 | menuentry 'Arc Automated Mode' ${menuentry_id_option} automated { 117 | gfxmode 118 | echo "Loading Arc Kernel..." 119 | linux /bzImage-arc ${ARC_CMDLINE} ${arc_cmdline} automated_arc 120 | echo "Loading Arc Initramfs..." 121 | initrd /initrd-arc ${ARCU} 122 | echo "Booting..." 123 | } 124 | fi 125 | 126 | menuentry 'Arc Config Mode' ${menuentry_id_option} config { 127 | gfxmode 128 | echo "Loading Arc Kernel..." 129 | linux /bzImage-arc ${ARC_CMDLINE} ${arc_cmdline} force_arc 130 | echo "Loading Arc Initramfs..." 131 | initrd /initrd-arc ${ARCU} 132 | echo "Booting..." 133 | } 134 | 135 | if [ -s /zImage-dsm -a -s /initrd-dsm ]; then 136 | menuentry 'Arc Update Mode' ${menuentry_id_option} update { 137 | gfxmode 138 | echo "Loading Arc Kernel..." 139 | linux /bzImage-arc ${ARC_CMDLINE} ${arc_cmdline} update_arc 140 | echo "Loading Arc Initramfs..." 141 | initrd /initrd-arc ${ARCU} 142 | echo "Booting..." 143 | } 144 | menuentry 'DSM Recovery Mode' ${menuentry_id_option} recovery { 145 | gfxmode 146 | echo "Loading Arc Kernel..." 147 | linux /bzImage-arc ${ARC_CMDLINE} ${arc_cmdline} recovery 148 | echo "Loading Arc Initramfs..." 149 | initrd /initrd-arc ${ARCU} 150 | echo "Booting..." 151 | } 152 | menuentry 'DSM Reinstall Mode' ${menuentry_id_option} junior { 153 | gfxmode 154 | echo "Loading Arc Kernel..." 155 | linux /bzImage-arc ${ARC_CMDLINE} ${arc_cmdline} force_junior 156 | echo "Loading Arc Initramfs..." 157 | initrd /initrd-arc ${ARCU} 158 | echo "Booting..." 159 | } 160 | fi 161 | 162 | if [ "${grub_platform}" = "efi" ]; then 163 | insmod bli 164 | menuentry 'UEFI Firmware Settings' ${menuentry_id_option} uefi { 165 | fwsetup 166 | } 167 | fi 168 | 169 | if [ -e ${prefix}/memtest ]; then 170 | menuentry 'System Memtest86+' ${menuentry_id_option} memtest { 171 | echo "Loading memtest86+..." 172 | linux ${prefix}/memtest 173 | } 174 | fi 175 | 176 | if [ "${linux_gfx_mode}" = "keep" ]; then 177 | menuentry 'Change vesa to text video mode' ${menuentry_id_option} videomode { 178 | set linux_gfx_mode=text 179 | save_env linux_gfx_mode 180 | configfile ${prefix}/grub.cfg 181 | } 182 | else 183 | menuentry 'Change text to vesa video mode' ${menuentry_id_option} videomode { 184 | set linux_gfx_mode=keep 185 | save_env linux_gfx_mode 186 | configfile ${prefix}/grub.cfg 187 | } 188 | fi -------------------------------------------------------------------------------- /files/p1/boot/grub/memtest: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AuxXxilium/arc/5fc208ac2e6bc86eddb48a22fad3a46aa35e48a9/files/p1/boot/grub/memtest -------------------------------------------------------------------------------- /files/p3/addons/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AuxXxilium/arc/5fc208ac2e6bc86eddb48a22fad3a46aa35e48a9/files/p3/addons/.gitkeep -------------------------------------------------------------------------------- /files/p3/configs/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AuxXxilium/arc/5fc208ac2e6bc86eddb48a22fad3a46aa35e48a9/files/p3/configs/.gitkeep -------------------------------------------------------------------------------- /files/p3/custom/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AuxXxilium/arc/5fc208ac2e6bc86eddb48a22fad3a46aa35e48a9/files/p3/custom/.gitkeep -------------------------------------------------------------------------------- /files/p3/lkms/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AuxXxilium/arc/5fc208ac2e6bc86eddb48a22fad3a46aa35e48a9/files/p3/lkms/.gitkeep -------------------------------------------------------------------------------- /files/p3/modules/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AuxXxilium/arc/5fc208ac2e6bc86eddb48a22fad3a46aa35e48a9/files/p3/modules/.gitkeep -------------------------------------------------------------------------------- /files/p3/patches/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AuxXxilium/arc/5fc208ac2e6bc86eddb48a22fad3a46aa35e48a9/files/p3/patches/.gitkeep -------------------------------------------------------------------------------- /img-gen.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | # 3 | # Copyright (C) 2025 AuxXxilium 4 | # 5 | # This is free software, licensed under the MIT License. 6 | # See /LICENSE for more information. 7 | # 8 | 9 | set -e 10 | 11 | # Clean cached Files 12 | sudo git clean -fdx 13 | 14 | . scripts/functions.sh "${AUX_TOKEN}" 15 | 16 | # Unmount Image File 17 | sudo umount "/tmp/p1" 2>/dev/null || true 18 | sudo umount "/tmp/p3" 2>/dev/null || true 19 | 20 | # Get extractor, LKM, addons and Modules 21 | echo "Get Dependencies" 22 | getAddons "files/p3/addons" 23 | getModules "files/p3/modules" 24 | getConfigs "files/p3/configs" 25 | getPatches "files/p3/patches" 26 | getCustom "files/p3/custom" 27 | getLKMs "files/p3/lkms" 28 | getTheme "files/p1/boot/grub" 29 | getOffline "files/p3/configs" 30 | case "${1}" in 31 | evo) getBuildroot "${1}" "br" ;; 32 | *) echo "Invalid option specified" ;; 33 | esac 34 | 35 | # Sbase 36 | IMAGE_FILE="arc.img" 37 | gzip -dc "files/initrd/opt/arc/grub.img.gz" >"${IMAGE_FILE}" 38 | fdisk -l "${IMAGE_FILE}" 39 | 40 | LOOPX=$(sudo losetup -f) 41 | sudo losetup -P "${LOOPX}" "${IMAGE_FILE}" 42 | 43 | echo "Mounting Image File" 44 | sudo rm -rf "/tmp/p1" 45 | sudo rm -rf "/tmp/p3" 46 | mkdir -p "/tmp/p1" 47 | mkdir -p "/tmp/p3" 48 | sudo mount ${LOOPX}p1 "/tmp/p1" 49 | sudo mount ${LOOPX}p3 "/tmp/p3" 50 | 51 | ARC_BUILD="$(date +'%y%m%d')" 52 | ARC_VERSION="13.3.7" 53 | echo "${ARC_VERSION}" >"files/p1/ARC-VERSION" 54 | echo "${ARC_BUILD}" >"files/p1/ARC-BUILD" 55 | 56 | echo "Repack initrd" 57 | if [ -f "br/bzImage-arc" ] && [ -f "br/initrd-arc" ]; then 58 | cp -f "br/bzImage-arc" "files/p3/bzImage-arc" 59 | repackInitrd "br/initrd-arc" "files/initrd" "files/p3/initrd-arc" 60 | else 61 | exit 1 62 | fi 63 | 64 | echo "Copying files" 65 | sudo cp -rf "files/p1/"* "/tmp/p1" 66 | sudo cp -rf "files/p3/"* "/tmp/p3" 67 | sudo sync 68 | 69 | echo "Unmount image file" 70 | sudo umount "/tmp/p1" 71 | sudo umount "/tmp/p3" 72 | sudo rm -rf "/tmp/p1" 73 | sudo rm -rf "/tmp/p3" 74 | 75 | sudo losetup --detach ${LOOPX} 76 | 77 | qemu-img convert -p -f raw -o subformat=monolithicFlat -O vmdk ${IMAGE_FILE} arc.vmdk 78 | -------------------------------------------------------------------------------- /scripts/functions.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # 3 | # Copyright (C) 2025 AuxXxilium 4 | # 5 | # This is free software, licensed under the MIT License. 6 | # See /LICENSE for more information. 7 | # 8 | 9 | import os, click 10 | 11 | WORK_PATH = os.path.abspath(os.path.dirname(__file__)) 12 | 13 | 14 | @click.group() 15 | def cli(): 16 | """ 17 | The CLI is a commands to Arc. 18 | """ 19 | pass 20 | 21 | 22 | def mutually_exclusive_options(ctx, param, value): 23 | other_option = "file" if param.name == "data" else "data" 24 | if value is not None and ctx.params.get(other_option) is not None: 25 | raise click.UsageError(f"Illegal usage: `{param.name}` is mutually exclusive with `{other_option}`.") 26 | return value 27 | 28 | 29 | def validate_required_param(ctx, param, value): 30 | if not value and "file" not in ctx.params and "data" not in ctx.params: 31 | raise click.MissingParameter(param_decls=[param.name]) 32 | return value 33 | 34 | def __fullversion(ver): 35 | out = ver 36 | arr = ver.split('-') 37 | if len(arr) > 0: 38 | a = arr[0].split('.')[0] if len(arr[0].split('.')) > 0 else '0' 39 | b = arr[0].split('.')[1] if len(arr[0].split('.')) > 1 else '0' 40 | c = arr[0].split('.')[2] if len(arr[0].split('.')) > 2 else '0' 41 | d = arr[1] if len(arr) > 1 else '00000' 42 | e = arr[2] if len(arr) > 2 else '0' 43 | out = '{}.{}.{}-{}-{}'.format(a,b,c,d,e) 44 | return out 45 | 46 | @cli.command() 47 | @click.option("-p", "--platforms", type=str, help="The platforms of Syno.") 48 | def getmodels(platforms=None): 49 | """ 50 | Get Syno Models. 51 | """ 52 | import re, json, requests, urllib3 53 | from requests.adapters import HTTPAdapter 54 | from requests.packages.urllib3.util.retry import Retry # type: ignore 55 | 56 | adapter = HTTPAdapter(max_retries=Retry(total=3, backoff_factor=1, status_forcelist=[500, 502, 503, 504])) 57 | session = requests.Session() 58 | session.mount("http://", adapter) 59 | session.mount("https://", adapter) 60 | urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning) 61 | 62 | PS = platforms.lower().replace(",", " ").split() if platforms else [] 63 | 64 | models = [] 65 | try: 66 | url = "http://update7.synology.com/autoupdate/genRSS.php?include_beta=1" 67 | #url = "https://update7.synology.com/autoupdate/genRSS.php?include_beta=1" 68 | 69 | req = session.get(url, timeout=10, verify=False) 70 | req.encoding = "utf-8" 71 | p = re.compile(r"(.*?).*?(.*?)", re.MULTILINE | re.DOTALL) 72 | 73 | data = p.findall(req.text) 74 | for item in data: 75 | if not "DSM" in item[1]: 76 | continue 77 | arch = item[0].split("_")[1] 78 | name = item[1].split("/")[-1].split("_")[1].replace("%2B", "+") 79 | if PS and arch.lower() not in PS: 80 | continue 81 | if not any(m["name"] == name for m in models): 82 | models.append({"name": name, "arch": arch}) 83 | 84 | models.sort(key=lambda k: (k["arch"], k["name"])) 85 | 86 | except Exception as e: 87 | # click.echo(f"Error: {e}") 88 | pass 89 | 90 | print(json.dumps(models, indent=4)) 91 | 92 | @cli.command() 93 | @click.option("-m", "--model", type=str, required=True, help="The model of Syno.") 94 | @click.option("-v", "--version", type=str, required=True, help="The version of Syno.") 95 | def getpats4mv(model, version): 96 | import json, requests, urllib3 97 | from requests.adapters import HTTPAdapter 98 | from requests.packages.urllib3.util.retry import Retry # type: ignore 99 | 100 | adapter = HTTPAdapter(max_retries=Retry(total=3, backoff_factor=1, status_forcelist=[500, 502, 503, 504])) 101 | session = requests.Session() 102 | session.mount("http://", adapter) 103 | session.mount("https://", adapter) 104 | urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning) 105 | 106 | pats = {} 107 | try: 108 | urlInfo = "https://www.synology.com/api/support/findDownloadInfo?lang=en-us" 109 | urlSteps = "https://www.synology.com/api/support/findUpgradeSteps?" 110 | #urlInfo = "https://www.synology.cn/api/support/findDownloadInfo?lang=zh-cn" 111 | #urlSteps = "https://www.synology.cn/api/support/findUpgradeSteps?" 112 | 113 | major = f"&major={version.split('.')[0]}" if len(version.split('.')) > 0 else "" 114 | minor = f"&minor={version.split('.')[1]}" if len(version.split('.')) > 1 else "" 115 | req = session.get(f"{urlInfo}&product={model.replace('+', '%2B')}{major}{minor}", timeout=10, verify=False) 116 | req.encoding = "utf-8" 117 | data = json.loads(req.text) 118 | 119 | build_ver = data['info']['system']['detail'][0]['items'][0]['build_ver'] 120 | build_num = data['info']['system']['detail'][0]['items'][0]['build_num'] 121 | buildnano = data['info']['system']['detail'][0]['items'][0]['nano'] 122 | V = __fullversion(f"{build_ver}-{build_num}-{buildnano}") 123 | if V not in pats: 124 | pats[V] = { 125 | 'url': data['info']['system']['detail'][0]['items'][0]['files'][0]['url'].split('?')[0], 126 | 'sum': data['info']['system']['detail'][0]['items'][0]['files'][0]['checksum'] 127 | } 128 | 129 | from_ver = min(I['build'] for I in data['info']['pubVers']) 130 | 131 | for I in data['info']['productVers']: 132 | if not I['version'].startswith(version): 133 | continue 134 | if not major or not minor: 135 | majorTmp = f"&major={I['version'].split('.')[0]}" if len(I['version'].split('.')) > 0 else "" 136 | minorTmp = f"&minor={I['version'].split('.')[1]}" if len(I['version'].split('.')) > 1 else "" 137 | reqTmp = session.get(f"{urlInfo}&product={model.replace('+', '%2B')}{majorTmp}{minorTmp}", timeout=10, verify=False) 138 | reqTmp.encoding = "utf-8" 139 | dataTmp = json.loads(reqTmp.text) 140 | 141 | build_ver = dataTmp['info']['system']['detail'][0]['items'][0]['build_ver'] 142 | build_num = dataTmp['info']['system']['detail'][0]['items'][0]['build_num'] 143 | buildnano = dataTmp['info']['system']['detail'][0]['items'][0]['nano'] 144 | V = __fullversion(f"{build_ver}-{build_num}-{buildnano}") 145 | if V not in pats: 146 | pats[V] = { 147 | 'url': dataTmp['info']['system']['detail'][0]['items'][0]['files'][0]['url'].split('?')[0], 148 | 'sum': dataTmp['info']['system']['detail'][0]['items'][0]['files'][0]['checksum'] 149 | } 150 | 151 | for J in I['versions']: 152 | to_ver = J['build'] 153 | reqSteps = session.get(f"{urlSteps}&product={model.replace('+', '%2B')}&from_ver={from_ver}&to_ver={to_ver}", timeout=10, verify=False) 154 | if reqSteps.status_code != 200: 155 | continue 156 | reqSteps.encoding = "utf-8" 157 | dataSteps = json.loads(reqSteps.text) 158 | for S in dataSteps['upgrade_steps']: 159 | if not S.get('full_patch') or not S['build_ver'].startswith(version): 160 | continue 161 | V = __fullversion(f"{S['build_ver']}-{S['build_num']}-{S['nano']}") 162 | if V not in pats: 163 | pats[V] = { 164 | 'url': S['files'][0]['url'].split('?')[0], 165 | 'sum': S['files'][0]['checksum'] 166 | } 167 | except Exception as e: 168 | # click.echo(f"Error: {e}") 169 | pass 170 | 171 | pats = {k: pats[k] for k in sorted(pats.keys(), reverse=True)} 172 | print(json.dumps(pats, indent=4)) 173 | 174 | 175 | @cli.command() 176 | @click.option("-p", "--models", type=str, help="The models of Syno.") 177 | def getpats(models=None): 178 | import re, json, requests, urllib3 179 | from bs4 import BeautifulSoup 180 | from requests.adapters import HTTPAdapter 181 | from requests.packages.urllib3.util.retry import Retry # type: ignore 182 | 183 | adapter = HTTPAdapter(max_retries=Retry(total=3, backoff_factor=1, status_forcelist=[500, 502, 503, 504])) 184 | session = requests.Session() 185 | session.mount("http://", adapter) 186 | session.mount("https://", adapter) 187 | urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning) 188 | 189 | MS = models.lower().replace(",", " ").split() if models else [] 190 | 191 | pats = {} 192 | try: 193 | req = session.get('https://archive.synology.com/download/Os/DSM', timeout=10, verify=False) 194 | req.encoding = 'utf-8' 195 | bs = BeautifulSoup(req.text, 'html.parser') 196 | p = re.compile(r"(.*?)-(.*?)", re.MULTILINE | re.DOTALL) 197 | l = bs.find_all('a', string=p) 198 | for i in l: 199 | ver = i.attrs['href'].split('/')[-1] 200 | if not ver.startswith('7'): 201 | continue 202 | req = session.get(f'https://archive.synology.com{i.attrs["href"]}', timeout=10, verify=False) 203 | req.encoding = 'utf-8' 204 | bs = BeautifulSoup(req.text, 'html.parser') 205 | p = re.compile(r"DSM_(.*?)_(.*?).pat", re.MULTILINE | re.DOTALL) 206 | data = bs.find_all('a', string=p) 207 | for item in data: 208 | rels = p.search(item.attrs['href']) 209 | if rels: 210 | model, _ = rels.groups() 211 | model = model.replace('%2B', '+') 212 | if MS and model.lower() not in MS: 213 | continue 214 | if model not in pats: 215 | pats[model] = {} 216 | pats[model][__fullversion(ver)] = item.attrs['href'] 217 | except Exception as e: 218 | # click.echo(f"Error: {e}") 219 | pass 220 | 221 | print(json.dumps(pats, indent=4)) 222 | 223 | @cli.command() 224 | @click.option("-p", "--platforms", type=str, help="The platforms of Syno.") 225 | def getmodelsoffline(platforms=None): 226 | """ 227 | Get Syno Models. 228 | """ 229 | import json 230 | import os 231 | 232 | PS = platforms.lower().replace(",", " ").split() if platforms else [] 233 | 234 | with open(os.path.join('/mnt/p3/configs', "offline.json")) as user_file: 235 | data = json.load(user_file) 236 | 237 | models = [] 238 | for item in data["channel"]["item"]: 239 | if not item["title"].startswith("DSM"): 240 | continue 241 | for model in item["model"]: 242 | arch = model["mUnique"].split("_")[1] 243 | name = model["mLink"].split("/")[-1].split("_")[1].replace("%2B", "+") 244 | if PS and arch.lower() not in PS: 245 | continue 246 | if not any(m["name"] == name for m in models): 247 | models.append({"name": name, "arch": arch}) 248 | 249 | models = sorted(models, key=lambda k: (k["arch"], k["name"])) 250 | print(json.dumps(models, indent=4)) 251 | 252 | if __name__ == "__main__": 253 | cli() -------------------------------------------------------------------------------- /scripts/functions.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | # 3 | # Copyright (C) 2025 AuxXxilium 4 | # 5 | # This is free software, licensed under the MIT License. 6 | # See /LICENSE for more information. 7 | # 8 | 9 | [ -n "${1}" ] && export TOKEN="${1}" 10 | 11 | # Get latest LKMs 12 | # $1 path 13 | function getLKMs() { 14 | echo "Getting LKMs begin" 15 | local DEST_PATH="${1}" 16 | local CACHE_FILE="/tmp/rp-lkms.zip" 17 | rm -f "${CACHE_FILE}" 18 | TAG=$(curl -skL -H "Authorization: token ${TOKEN}" "https://api.github.com/repos/AuxXxilium/arc-lkm/releases" | jq -r ".[].tag_name" | sort -rV | head -1) 19 | export LKMTAG="${TAG}" 20 | while read -r ID NAME; do 21 | if [ "${NAME}" = "rp-lkms.zip" ]; then 22 | curl -kL -H "Authorization: token ${TOKEN}" -H "Accept: application/octet-stream" "https://api.github.com/repos/AuxXxilium/arc-lkm/releases/assets/${ID}" -o "${CACHE_FILE}" 23 | # Unzip LKMs 24 | rm -rf "${DEST_PATH}" 25 | mkdir -p "${DEST_PATH}" 26 | if unzip -o "${CACHE_FILE}" -d "${DEST_PATH}"; then 27 | rm -f "${CACHE_FILE}" 28 | echo "Getting LKMs end - ${TAG}" 29 | break 30 | fi 31 | fi 32 | done < <(curl -skL -H "Authorization: token ${TOKEN}" "https://api.github.com/repos/AuxXxilium/arc-lkm/releases/tags/${TAG}" | jq -r '.assets[] | "\(.id) \(.name)"') 33 | } 34 | 35 | # Get latest Addons 36 | # $1 path 37 | function getAddons() { 38 | echo "Getting Addons begin" 39 | local DEST_PATH="${1}" 40 | local CACHE_DIR="/tmp/addons" 41 | local CACHE_FILE="/tmp/addons.zip" 42 | rm -f "${CACHE_FILE}" 43 | TAG=$(curl -skL -H "Authorization: token ${TOKEN}" "https://api.github.com/repos/AuxXxilium/arc-addons/releases" | jq -r ".[].tag_name" | sort -rV | head -1) 44 | export ADDONTAG="${TAG}" 45 | while read -r ID NAME; do 46 | if [ "${NAME}" = "addons-${TAG}.zip" ]; then 47 | curl -kL -H "Authorization: token ${TOKEN}" -H "Accept: application/octet-stream" "https://api.github.com/repos/AuxXxilium/arc-addons/releases/assets/${ID}" -o "${CACHE_FILE}" 48 | # Unzip Addons 49 | rm -rf "${CACHE_DIR}" 50 | mkdir -p "${CACHE_DIR}" 51 | mkdir -p "${DEST_PATH}" 52 | if unzip -o "${CACHE_FILE}" -d "${CACHE_DIR}"; then 53 | echo "Installing Addons to ${DEST_PATH}" 54 | [ -f /tmp/addons/VERSION ] && cp -f /tmp/addons/VERSION ${DEST_PATH}/ 55 | for PKG in $(ls ${CACHE_DIR}/*.addon); do 56 | ADDON=$(basename "${PKG}" .addon) 57 | mkdir -p "${DEST_PATH}/${ADDON}" 58 | echo "Extracting ${PKG} to ${DEST_PATH}/${ADDON}" 59 | tar -xaf "${PKG}" -C "${DEST_PATH}/${ADDON}" 60 | done 61 | rm -f "${CACHE_FILE}" 62 | echo "Getting Addons end - ${TAG}" 63 | break 64 | fi 65 | fi 66 | done < <(curl -skL -H "Authorization: token ${TOKEN}" "https://api.github.com/repos/AuxXxilium/arc-addons/releases/tags/${TAG}" | jq -r '.assets[] | "\(.id) \(.name)"') 67 | } 68 | 69 | # Get latest Modules 70 | # $1 path 71 | function getModules() { 72 | echo "Getting Modules begin" 73 | local DEST_PATH="${1}" 74 | local CACHE_FILE="/tmp/modules.zip" 75 | rm -f "${CACHE_FILE}" 76 | TAG=$(curl -skL -H "Authorization: token ${TOKEN}" "https://api.github.com/repos/AuxXxilium/arc-modules/releases" | jq -r ".[].tag_name" | sort -rV | head -1) 77 | export MODULETAG="${TAG}" 78 | while read -r ID NAME; do 79 | if [ "${NAME}" = "modules-${TAG}.zip" ]; then 80 | curl -kL -H "Authorization: token ${TOKEN}" -H "Accept: application/octet-stream" "https://api.github.com/repos/AuxXxilium/arc-modules/releases/assets/${ID}" -o "${CACHE_FILE}" 81 | # Unzip Modules 82 | rm -rf "${DEST_PATH}" 83 | mkdir -p "${DEST_PATH}" 84 | if unzip -o "${CACHE_FILE}" -d "${DEST_PATH}"; then 85 | rm -f "${CACHE_FILE}" 86 | echo "Getting Modules end - ${TAG}" 87 | break 88 | fi 89 | fi 90 | done < <(curl -skL -H "Authorization: token ${TOKEN}" "https://api.github.com/repos/AuxXxilium/arc-modules/releases/tags/${TAG}" | jq -r '.assets[] | "\(.id) \(.name)"') 91 | } 92 | 93 | # Get latest Configs 94 | # $1 path 95 | function getConfigs() { 96 | echo "Getting Configs begin" 97 | local DEST_PATH="${1}" 98 | local CACHE_FILE="/tmp/configs.zip" 99 | rm -f "${CACHE_FILE}" 100 | TAG=$(curl -skL -H "Authorization: token ${TOKEN}" "https://api.github.com/repos/AuxXxilium/arc-configs/releases" | jq -r ".[].tag_name" | sort -rV | head -1) 101 | export CONFIGTAG="${TAG}" 102 | while read -r ID NAME; do 103 | if [ "${NAME}" = "configs-${TAG}.zip" ]; then 104 | curl -kL -H "Authorization: token ${TOKEN}" -H "Accept: application/octet-stream" "https://api.github.com/repos/AuxXxilium/arc-configs/releases/assets/${ID}" -o "${CACHE_FILE}" 105 | # Unzip Configs 106 | rm -rf "${DEST_PATH}" 107 | mkdir -p "${DEST_PATH}" 108 | if unzip -o "${CACHE_FILE}" -d "${DEST_PATH}"; then 109 | rm -f "${CACHE_FILE}" 110 | echo "Getting Configs end - ${TAG}" 111 | break 112 | fi 113 | fi 114 | done < <(curl -skL -H "Authorization: token ${TOKEN}" "https://api.github.com/repos/AuxXxilium/arc-configs/releases/tags/${TAG}" | jq -r '.assets[] | "\(.id) \(.name)"') 115 | } 116 | 117 | # Get latest Patches 118 | # $1 path 119 | function getPatches() { 120 | echo "Getting Patches begin" 121 | local DEST_PATH="${1}" 122 | local CACHE_FILE="/tmp/patches.zip" 123 | rm -f "${CACHE_FILE}" 124 | TAG=$(curl -skL -H "Authorization: token ${TOKEN}" "https://api.github.com/repos/AuxXxilium/arc-patches/releases" | jq -r ".[].tag_name" | sort -rV | head -1) 125 | export PATCHTAG="${TAG}" 126 | while read -r ID NAME; do 127 | if [ "${NAME}" = "patches-${TAG}.zip" ]; then 128 | curl -kL -H "Authorization: token ${TOKEN}" -H "Accept: application/octet-stream" "https://api.github.com/repos/AuxXxilium/arc-patches/releases/assets/${ID}" -o "${CACHE_FILE}" 129 | # Unzip Patches 130 | rm -rf "${DEST_PATH}" 131 | mkdir -p "${DEST_PATH}" 132 | if unzip -o "${CACHE_FILE}" -d "${DEST_PATH}"; then 133 | rm -f "${CACHE_FILE}" 134 | echo "Getting Patches end - ${TAG}" 135 | break 136 | fi 137 | fi 138 | done < <(curl -skL -H "Authorization: token ${TOKEN}" "https://api.github.com/repos/AuxXxilium/arc-patches/releases/tags/${TAG}" | jq -r '.assets[] | "\(.id) \(.name)"') 139 | } 140 | 141 | # Get latest Custom 142 | # $1 path 143 | function getCustom() { 144 | echo "Getting Custom begin" 145 | local DEST_PATH="${1}" 146 | local CACHE_FILE="/tmp/custom.zip" 147 | rm -f "${CACHE_FILE}" 148 | TAG=$(curl -skL -H "Authorization: token ${TOKEN}" "https://api.github.com/repos/AuxXxilium/arc-custom/releases" | jq -r ".[].tag_name" | sort -rV | head -1) 149 | export CUSTOMTAG="${TAG}" 150 | while read -r ID NAME; do 151 | if [ "${NAME}" = "custom-${TAG}.zip" ]; then 152 | curl -kL -H "Authorization: token ${TOKEN}" -H "Accept: application/octet-stream" "https://api.github.com/repos/AuxXxilium/arc-custom/releases/assets/${ID}" -o "${CACHE_FILE}" 153 | # Unzip Custom 154 | rm -rf "${DEST_PATH}" 155 | mkdir -p "${DEST_PATH}" 156 | if unzip -o "${CACHE_FILE}" -d "${DEST_PATH}"; then 157 | rm -f "${CACHE_FILE}" 158 | echo "Getting Custom end - ${TAG}" 159 | break 160 | fi 161 | fi 162 | done < <(curl -skL -H "Authorization: token ${TOKEN}" "https://api.github.com/repos/AuxXxilium/arc-custom/releases/tags/${TAG}" | jq -r '.assets[] | "\(.id) \(.name)"') 163 | } 164 | 165 | # Get latest Theme 166 | # $1 path 167 | function getTheme() { 168 | echo "Getting Theme begin" 169 | local DEST_PATH="${1}" 170 | local CACHE_FILE="/tmp/theme.zip" 171 | rm -f "${CACHE_FILE}" 172 | TAG=$(curl -skL -H "Authorization: token ${TOKEN}" "https://api.github.com/repos/AuxXxilium/arc-theme/releases" | jq -r ".[].tag_name" | sort -rV | head -1) 173 | export THEMETAG="${TAG}" 174 | while read -r ID NAME; do 175 | if [ "${NAME}" = "arc-theme-${TAG}.zip" ]; then 176 | curl -kL -H "Authorization: token ${TOKEN}" -H "Accept: application/octet-stream" "https://api.github.com/repos/AuxXxilium/arc-theme/releases/assets/${ID}" -o "${CACHE_FILE}" 177 | # Unzip Theme 178 | mkdir -p "${DEST_PATH}" 179 | if unzip -o "${CACHE_FILE}" -d "${DEST_PATH}"; then 180 | rm -f "${CACHE_FILE}" 181 | echo "Getting Theme end - ${TAG}" 182 | break 183 | fi 184 | fi 185 | done < <(curl -skL -H "Authorization: token ${TOKEN}" "https://api.github.com/repos/AuxXxilium/arc-theme/releases/tags/${TAG}" | jq -r '.assets[] | "\(.id) \(.name)"') 186 | } 187 | 188 | # Get latest Buildroot 189 | # $1 type (min for S, ext for X, micro for M) 190 | # $2 path 191 | function getBuildroot() { 192 | local TYPE="${1}" 193 | local DEST_PATH="${2}" 194 | local REPO="" 195 | local ZIP_NAME="" 196 | local TAG_VAR="" 197 | local REPO="arc-buildroot-${TYPE}" 198 | 199 | echo "Getting Buildroot-${TYPE} begin" 200 | TAG=$(curl -skL -H "Authorization: token ${TOKEN}" "https://api.github.com/repos/AuxXxilium/${REPO}/releases" | jq -r ".[].tag_name" | sort -rV | head -1) 201 | export BRTAG="${TAG}-${TYPE}" 202 | [ ! -d "${DEST_PATH}" ] && mkdir -p "${DEST_PATH}" 203 | rm -f "${DEST_PATH}/bzImage-arc" 204 | rm -f "${DEST_PATH}/initrd-arc" 205 | while read -r ID NAME; do 206 | if [ "${NAME}" = "buildroot-${TAG}.zip" ]; then 207 | curl -kL -H "Authorization: token ${TOKEN}" -H "Accept: application/octet-stream" "https://api.github.com/repos/AuxXxilium/${REPO}/releases/assets/${ID}" -o "${DEST_PATH}/br.zip" 208 | echo "Buildroot: ${TAG}-${TYPE}" 209 | unzip -o "${DEST_PATH}/br.zip" -d "${DEST_PATH}" 210 | mv -f "${DEST_PATH}/bzImage" "${DEST_PATH}/bzImage-arc" 211 | mv -f "${DEST_PATH}/rootfs.cpio.zst" "${DEST_PATH}/initrd-arc" 212 | [ -f "${DEST_PATH}/bzImage-arc" ] && [ -f "${DEST_PATH}/initrd-arc" ] && break 213 | fi 214 | done < <(curl -skL -H "Authorization: token ${TOKEN}" "https://api.github.com/repos/AuxXxilium/${REPO}/releases/tags/${TAG}" | jq -r '.assets[] | "\(.id) \(.name)"') 215 | } 216 | 217 | # Get latest Offline 218 | # $1 path 219 | function getOffline() { 220 | echo "Getting Offline begin" 221 | local DEST_PATH="${1}" 222 | 223 | [ ! -d "${DEST_PATH}" ] && mkdir -p "${DEST_PATH}" 224 | rm -f "${DEST_PATH}/data.yml" 225 | if curl -skL "https://raw.githubusercontent.com/AuxXxilium/arc-dsm/refs/heads/main/data.yml" -o "${DEST_PATH}/data.yml"; then 226 | echo "Getting Offline end" 227 | else 228 | echo "Failed to get Offline" 229 | exit 1 230 | fi 231 | } 232 | 233 | # repack initrd 234 | # $1 initrd file 235 | # $2 plugin path 236 | # $3 output file 237 | function repackInitrd() { 238 | local INITRD_FILE="${1}" 239 | local PLUGIN_PATH="${2}" 240 | local OUTPUT_PATH="${3:-${INITRD_FILE}}" 241 | 242 | [ -z "${INITRD_FILE}" ] || [ ! -f "${INITRD_FILE}" ] && exit 1 243 | [ -z "${PLUGIN_PATH}" ] || [ ! -d "${PLUGIN_PATH}" ] && exit 1 244 | 245 | INITRD_FILE="$(realpath "${INITRD_FILE}")" 246 | PLUGIN_PATH="$(realpath "${PLUGIN_PATH}")" 247 | OUTPUT_PATH="$(realpath "${OUTPUT_PATH}")" 248 | 249 | local RDXZ_PATH="rdxz_tmp" 250 | mkdir -p "${RDXZ_PATH}" 251 | local INITRD_FORMAT=$(file -b --mime-type "${INITRD_FILE}") 252 | 253 | case "${INITRD_FORMAT}" in 254 | *'x-cpio'*) (cd "${RDXZ_PATH}" && sudo cpio -idm <"${INITRD_FILE}") >/dev/null 2>&1 ;; 255 | *'x-xz'*) (cd "${RDXZ_PATH}" && xz -dc "${INITRD_FILE}" | sudo cpio -idm) >/dev/null 2>&1 ;; 256 | *'x-lz4'*) (cd "${RDXZ_PATH}" && lz4 -dc "${INITRD_FILE}" | sudo cpio -idm) >/dev/null 2>&1 ;; 257 | *'x-lzma'*) (cd "${RDXZ_PATH}" && lzma -dc "${INITRD_FILE}" | sudo cpio -idm) >/dev/null 2>&1 ;; 258 | *'x-bzip2'*) (cd "${RDXZ_PATH}" && bzip2 -dc "${INITRD_FILE}" | sudo cpio -idm) >/dev/null 2>&1 ;; 259 | *'gzip'*) (cd "${RDXZ_PATH}" && gzip -dc "${INITRD_FILE}" | sudo cpio -idm) >/dev/null 2>&1 ;; 260 | *'zstd'*) (cd "${RDXZ_PATH}" && zstd -dc "${INITRD_FILE}" | sudo cpio -idm) >/dev/null 2>&1 ;; 261 | *) ;; 262 | esac 263 | 264 | sudo cp -rf "${PLUGIN_PATH}/"* "${RDXZ_PATH}/" 265 | [ -f "${OUTPUT_PATH}" ] && rm -rf "${OUTPUT_PATH}" 266 | 267 | case "${INITRD_FORMAT}" in 268 | *'x-cpio'*) (cd "${RDXZ_PATH}" && sudo find . 2>/dev/null | sudo cpio -o -H newc -R root:root >"${OUTPUT_PATH}") >/dev/null 2>&1 ;; 269 | *'x-xz'*) (cd "${RDXZ_PATH}" && sudo find . 2>/dev/null | sudo cpio -o -H newc -R root:root | xz -9 -C crc32 -c - >"${OUTPUT_PATH}") >/dev/null 2>&1 ;; 270 | *'x-lz4'*) (cd "${RDXZ_PATH}" && sudo find . 2>/dev/null | sudo cpio -o -H newc -R root:root | lz4 -9 -l -c - >"${OUTPUT_PATH}") >/dev/null 2>&1 ;; 271 | *'x-lzma'*) (cd "${RDXZ_PATH}" && sudo find . 2>/dev/null | sudo cpio -o -H newc -R root:root | lzma -9 -c - >"${OUTPUT_PATH}") >/dev/null 2>&1 ;; 272 | *'x-bzip2'*) (cd "${RDXZ_PATH}" && sudo find . 2>/dev/null | sudo cpio -o -H newc -R root:root | bzip2 -9 -c - >"${OUTPUT_PATH}") >/dev/null 2>&1 ;; 273 | *'gzip'*) (cd "${RDXZ_PATH}" && sudo find . 2>/dev/null | sudo cpio -o -H newc -R root:root | gzip -9 -c - >"${OUTPUT_PATH}") >/dev/null 2>&1 ;; 274 | *'zstd'*) (cd "${RDXZ_PATH}" && sudo find . 2>/dev/null | sudo cpio -o -H newc -R root:root | zstd -19 -T0 -f -c - >"${OUTPUT_PATH}") >/dev/null 2>&1 ;; 275 | *) ;; 276 | esac 277 | sudo rm -rf "${RDXZ_PATH}" 278 | } 279 | 280 | # resizeimg 281 | # $1 input file 282 | # $2 changsize MB eg: +50M -50M 283 | # $3 output file 284 | function resizeImg() { 285 | local INPUT_FILE="${1}" 286 | local CHANGE_SIZE="${2}" 287 | local OUTPUT_FILE="${3:-${INPUT_FILE}}" 288 | 289 | [ -z "${INPUT_FILE}" ] || [ ! -f "${INPUT_FILE}" ] && exit 1 290 | [ -z "${CHANGE_SIZE}" ] && exit 1 291 | 292 | INPUT_FILE="$(realpath "${INPUT_FILE}")" 293 | OUTPUT_FILE="$(realpath "${OUTPUT_FILE}")" 294 | 295 | local SIZE=$(($(du -sm "${INPUT_FILE}" 2>/dev/null | awk '{print $1}')$(echo "${CHANGE_SIZE}" | sed 's/M//g; s/b//g'))) 296 | [ "${SIZE:-0}" -lt 0 ] && exit 1 297 | 298 | if [ ! "${INPUT_FILE}" = "${OUTPUT_FILE}" ]; then 299 | sudo cp -f "${INPUT_FILE}" "${OUTPUT_FILE}" 300 | fi 301 | 302 | sudo truncate -s ${SIZE}M "${OUTPUT_FILE}" 303 | echo -e "d\n\nn\n\n\n\n\nn\nw" | sudo fdisk "${OUTPUT_FILE}" >/dev/null 2>&1 304 | local LOOPX LOOPXPY 305 | LOOPX=$(sudo losetup -f) 306 | sudo losetup -P "${LOOPX}" "${OUTPUT_FILE}" 307 | LOOPXPY="$(find "${LOOPX}p"* -maxdepth 0 2>/dev/null | sort -n | tail -1)" 308 | sudo e2fsck -fp "${LOOPXPY:-${LOOPX}p3}" 309 | sudo resize2fs "${LOOPXPY:-${LOOPX}p3}" 310 | sudo losetup -d "${LOOPX}" 311 | } 312 | 313 | # createvmx 314 | # $1 bootloader file 315 | # $2 vmx name 316 | function createvmx() { 317 | BLIMAGE=${1} 318 | VMNAME=${2} 319 | 320 | if ! type -p qemu-img >/dev/null 2>&1; then 321 | sudo apt install -y qemu-utils 322 | fi 323 | 324 | # Convert raw image to VMDK 325 | rm -rf "VMX_${VMNAME}" 326 | mkdir -p "VMX_${VMNAME}" 327 | qemu-img convert -O vmdk -o 'adapter_type=lsilogic,subformat=streamOptimized,compat6' "${BLIMAGE}" "VMX_${VMNAME}/${VMNAME}-disk1.vmdk" 328 | qemu-img create -f vmdk "VMX_${VMNAME}/${VMNAME}-disk2.vmdk" "32G" 329 | 330 | # Create VM configuration 331 | cat <<_EOF_ >"VMX_${VMNAME}/${VMNAME}.vmx" 332 | .encoding = "UTF-8" 333 | config.version = "8" 334 | virtualHW.version = "17" 335 | displayName = "${VMNAME}" 336 | annotation = "https://github.com/AuxXxilium/arc" 337 | guestOS = "ubuntu-64" 338 | firmware = "efi" 339 | mks.enable3d = "TRUE" 340 | pciBridge0.present = "TRUE" 341 | pciBridge4.present = "TRUE" 342 | pciBridge4.virtualDev = "pcieRootPort" 343 | pciBridge4.functions = "8" 344 | pciBridge5.present = "TRUE" 345 | pciBridge5.virtualDev = "pcieRootPort" 346 | pciBridge5.functions = "8" 347 | pciBridge6.present = "TRUE" 348 | pciBridge6.virtualDev = "pcieRootPort" 349 | pciBridge6.functions = "8" 350 | pciBridge7.present = "TRUE" 351 | pciBridge7.virtualDev = "pcieRootPort" 352 | pciBridge7.functions = "8" 353 | vmci0.present = "TRUE" 354 | hpet0.present = "TRUE" 355 | nvram = "${VMNAME}.nvram" 356 | virtualHW.productCompatibility = "hosted" 357 | powerType.powerOff = "soft" 358 | powerType.powerOn = "soft" 359 | powerType.suspend = "soft" 360 | powerType.reset = "soft" 361 | tools.syncTime = "FALSE" 362 | sound.autoDetect = "TRUE" 363 | sound.fileName = "-1" 364 | sound.present = "TRUE" 365 | numvcpus = "2" 366 | cpuid.coresPerSocket = "1" 367 | vcpu.hotadd = "TRUE" 368 | memsize = "4096" 369 | mem.hotadd = "TRUE" 370 | usb.present = "TRUE" 371 | ehci.present = "TRUE" 372 | usb_xhci.present = "TRUE" 373 | svga.graphicsMemoryKB = "8388608" 374 | usb.vbluetooth.startConnected = "TRUE" 375 | extendedConfigFile = "${VMNAME}.vmxf" 376 | floppy0.present = "FALSE" 377 | ethernet0.addressType = "generated" 378 | ethernet0.virtualDev = "vmxnet3" 379 | ethernet0.connectionType = "nat" 380 | ethernet0.allowguestconnectioncontrol = "true" 381 | ethernet0.present = "TRUE" 382 | serial0.fileType = "file" 383 | serial0.fileName = "serial0.log" 384 | serial0.present = "TRUE" 385 | sata0.present = "TRUE" 386 | sata0:0.fileName = "${VMNAME}-disk1.vmdk" 387 | sata0:0.present = "TRUE" 388 | sata0:1.fileName = "${VMNAME}-disk2.vmdk" 389 | sata0:1.present = "TRUE" 390 | _EOF_ 391 | } 392 | 393 | # convertvmx 394 | # $1 bootloader file 395 | # $2 vmx file 396 | function convertvmx() { 397 | local BLIMAGE=${1} 398 | local VMXPATH=${2} 399 | 400 | BLIMAGE="$(realpath "${BLIMAGE}")" 401 | VMXPATH="$(realpath "${VMXPATH}")" 402 | local VMNAME="$(basename "${VMXPATH}" .vmx)" 403 | 404 | createvmx "${BLIMAGE}" "${VMNAME}" 405 | 406 | rm -rf "${VMXPATH}" 407 | mv -f "VMX_${VMNAME}" "${VMXPATH}" 408 | } 409 | 410 | # convertova 411 | # $1 bootloader file 412 | # $2 ova file 413 | function convertova() { 414 | local BLIMAGE=${1} 415 | local OVAPATH=${2} 416 | 417 | BLIMAGE="$(realpath "${BLIMAGE}")" 418 | OVAPATH="$(realpath "${OVAPATH}")" 419 | local VMNAME="$(basename "${OVAPATH}" .ova)" 420 | 421 | createvmx "${BLIMAGE}" "${VMNAME}" 422 | 423 | # Download and install ovftool if it doesn't exist 424 | if [ ! -x ovftool/ovftool ]; then 425 | rm -rf ovftool ovftool.zip 426 | curl -skL https://github.com/rgl/ovftool-binaries/raw/main/archive/VMware-ovftool-4.6.0-21452615-lin.x86_64.zip -o ovftool.zip 427 | if [ $? -ne 0 ]; then 428 | echo "Failed to download ovftool" 429 | exit 1 430 | fi 431 | unzip ovftool.zip -d . >/dev/null 2>&1 432 | if [ $? -ne 0 ]; then 433 | echo "Failed to extract ovftool" 434 | exit 1 435 | fi 436 | chmod +x ovftool/ovftool 437 | fi 438 | 439 | rm -f "${OVAPATH}" 440 | ovftool/ovftool "VMX_${VMNAME}/${VMNAME}.vmx" "${OVAPATH}" 441 | rm -rf "VMX_${VMNAME}" 442 | } 443 | 444 | # createvmc 445 | # $1 vhd file 446 | # $2 vmc file 447 | function createvmc() { 448 | local BLIMAGE=${1:-arc.vhd} 449 | local VMCPATH=${2:-arc.vmc} 450 | 451 | BLIMAGE="$(basename "${BLIMAGE}")" 452 | VMCPATH="$(realpath "${VMCPATH}")" 453 | 454 | cat <<_EOF_ >"${VMCPATH}" 455 | 456 | 457 | 2.0 458 | 459 | 460 | 4096 461 | 462 | 463 | 464 | 465 | 466 | 1 467 | 468 | ${BLIMAGE} 469 | 470 | 471 | 472 | 473 | 474 | 475 | 476 | _EOF_ 477 | } -------------------------------------------------------------------------------- /scripts/grub.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | # 3 | # Copyright (C) 2023 AuxXxilium and Ing 4 | # 5 | # This is free software, licensed under the MIT License. 6 | # See /LICENSE for more information. 7 | # 8 | 9 | GRUB=${1:-"grub-2.12"} 10 | BIOS=${2:-"i386-pc i386-efi x86_64-efi"} 11 | NAME=${3:-"ARC"} 12 | 13 | curl -#kLO https://ftp.gnu.org/gnu/grub/${GRUB}.tar.gz 14 | tar -zxvf ${GRUB}.tar.gz 15 | 16 | pushd ${GRUB} 17 | echo depends bli part_gpt > grub-core/extra_deps.lst 18 | for B in ${BIOS}; do 19 | b=${B} 20 | b=(${b//-/ }) 21 | echo "Make ${b[@]} ..." 22 | mkdir -p ${B} 23 | pushd ${B} 24 | ../configure --prefix=$PWD/usr -sbindir=$PWD/sbin --sysconfdir=$PWD/etc --disable-werror --target=${b[0]} --with-platform=${b[1]} 25 | make 26 | make install 27 | popd 28 | done 29 | popd 30 | 31 | rm -f grub.img 32 | dd if=/dev/zero of=grub.img bs=1M seek=2048 count=0 33 | echo -e "n\np\n1\n\n+50M\nn\np\n2\n\n+50M\nn\np\n3\n\n\na\n1\nw\nq\n" | fdisk grub.img 34 | fdisk -l grub.img 35 | 36 | LOOPX=$(sudo losetup -f) 37 | sudo losetup -P ${LOOPX} grub.img 38 | sudo mkdosfs -F32 -n ${NAME}1 ${LOOPX}p1 39 | sudo mkfs.ext2 -F -L ${NAME}2 ${LOOPX}p2 40 | sudo mkfs.ext4 -F -L ${NAME}3 ${LOOPX}p3 41 | 42 | rm -rf ${NAME}1 43 | mkdir -p ${NAME}1 44 | sudo mount ${LOOPX}p1 ${NAME}1 45 | 46 | sudo mkdir -p ${NAME}1/EFI 47 | sudo mkdir -p ${NAME}1/boot/grub 48 | cat >device.map < "${OVFNAME}.ovf" 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | Virtual disk information 27 | 28 | 29 | 30 | 31 | The list of logical networks 32 | 33 | The bridged network 34 | 35 | 36 | 37 | A virtual machine 38 | ${OVFNAME} 39 | 40 | The kind of installed guest operating system 41 | 42 | 43 | Virtual hardware requirements 44 | 45 | Virtual Hardware Family 46 | 0 47 | ${OVFNAME} 48 | vmx-21 49 | 50 | 51 | hertz * 10^6 52 | Number of Virtual CPUs 53 | 2 virtual CPU(s) 54 | 1 55 | 3 56 | 2 57 | 2 58 | 59 | 60 | byte * 2^20 61 | Memory Size 62 | 4096MB of memory 63 | 2 64 | 4 65 | 4096 66 | 1 67 | 68 | 69 | 0 70 | SATA Controller 71 | sataController0 72 | 3 73 | vmware.sata.ahci 74 | 20 75 | 1 76 | 77 | 78 | 0 79 | USB Controller (XHCI) 80 | usb3 81 | 4 82 | vmware.usb.xhci 83 | 23 84 | 1 85 | 86 | 87 | 0 88 | USB Controller (EHCI) 89 | usb 90 | 5 91 | vmware.usb.ehci 92 | 23 93 | 94 | 1 95 | 96 | 97 | true 98 | serial0 99 | 6 100 | 21 101 | 102 | 103 | 1 104 | 105 | 106 | 1 107 | true 108 | bridged 109 | VmxNet3 ethernet adapter on "bridged" 110 | ethernet0 111 | 7 112 | VmxNet3 113 | 10 114 | 115 | 1 116 | 117 | 118 | false 119 | sound 120 | 8 121 | vmware.soundcard.ensoniq1371 122 | 1 123 | 1 124 | 125 | 126 | false 127 | video 128 | 9 129 | 24 130 | 131 | 1 132 | 133 | 134 | false 135 | vmci 136 | 10 137 | vmware.vmci 138 | 1 139 | 1 140 | 141 | 142 | 0 143 | disk0 144 | ovf:/disk/vmdisk1 145 | 11 146 | 3 147 | 17 148 | 1 149 | 150 | 151 | 1 152 | disk1 153 | ovf:/disk/vmdisk2 154 | 12 155 | 3 156 | 17 157 | 1 158 | 159 | 160 | 161 | 162 | 163 | 164 | 165 | 166 | 167 | 168 | 169 | 170 | 171 | 172 | 173 | 174 | 175 | 176 | 177 | 178 | 179 | 180 | 181 | 182 | 183 | 184 | 185 | 186 | 187 | 188 | 189 | 190 | 191 | 192 | A human-readable annotation 193 | Arc Loader 194 | 195 | 196 | 197 | _EOF_ 198 | 199 | # Create manifest file for automatic integrity check 200 | cat << _EOF_ > "${OVFNAME}.mf" 201 | SHA256(${OVFNAME}.ovf)= $(sha256sum "${OVFNAME}.ovf" | mawk '{print $1}') 202 | SHA256(${BLDISKNAME})= $(sha256sum "${BLDISKNAME}" | mawk '{print $1}') 203 | SHA256(${SDDISKNAME})= $(sha256sum "${SDDISKNAME}" | mawk '{print $1}') 204 | _EOF_ 205 | 206 | # Pack everything as OVA appliance for ESXi import 207 | rm -f "${OVFNAME}.ova" 208 | tar -cf "${OVFNAME}.ova" ${OVFNAME}.ovf ${BLDISKNAME} ${SDDISKNAME} ${OVFNAME}.mf 209 | rm -f ${OVFNAME}.ovf ${BLDISKNAME} ${SDDISKNAME} ${OVFNAME}.mf 210 | #gzip "${OVFNAME}.ova" 211 | 212 | --------------------------------------------------------------------------------