├── .github └── workflows │ ├── build_uncrustify.yml │ └── main.yml ├── .gitignore ├── .shellcheckrc ├── README.md ├── build_testlinux.sh ├── ci-bootstrap.sh ├── clang32-bootstrap.sh ├── codesign ├── appsign.sh └── certificate.p12 ├── coverity ├── covstrap-linux.sh └── covstrap.sh ├── docker-apparmor.sh ├── efibuild.sh ├── external ├── TestConsole.zip ├── TestLinux.zip ├── Uncrustify-Darwin-c82ee0343f412ceba2c9efc85afc1d43d9f45c1f.zip ├── Uncrustify-Darwin.zip ├── Uncrustify-Linux-c82ee0343f412ceba2c9efc85afc1d43d9f45c1f.zip ├── Uncrustify-Linux.zip ├── Uncrustify-Windows-c82ee0343f412ceba2c9efc85afc1d43d9f45c1f.zip ├── Uncrustify-Windows.zip ├── iasl-20200528-macosx.zip ├── iasl-macosx.zip ├── nasm-2.15.05-macosx.zip └── nasm-mac64.zip ├── macosx10.13-sdk-bootstrap.sh ├── patches └── clang-32bit-kexts.patch ├── prospector └── profile.yml ├── requirements.txt ├── scripts ├── fix-macho32 └── libtool32 ├── test_qemu_fw.py ├── tinylinux ├── configs │ └── linux │ │ ├── v5.10.179 │ │ ├── tiny_kernel_arm.config │ │ ├── tiny_kernel_arm64.config │ │ ├── tiny_kernel_x86-64.config │ │ └── tiny_kernel_x86.config │ │ └── v6.3 │ │ ├── tiny_kernel_arm.config │ │ ├── tiny_kernel_arm64.config │ │ ├── tiny_kernel_x86-64.config │ │ └── tiny_kernel_x86.config └── patches │ └── linux │ ├── v5.10.179 │ ├── 0001-x86-boot-Align-vmlinuz-sections-on-page-size.patch │ ├── 0002-x86-build-Remove-RWX-sections-and-align-on-4KB.patch │ ├── 0003-x86-boot-Set-cr0-to-known-state-in-trampoline.patch │ ├── 0004-x86-boot-Increase-boot-page-table-size.patch │ ├── 0005-x86-boot-Support-4KB-pages-for-identity-mapping.patch │ ├── 0006-x86-boot-Setup-memory-protection-for-bzImage-code.patch │ ├── 0007-x86-build-Check-W-X-of-vmlinux-during-build.patch │ ├── 0008-x86-boot-Map-memory-explicitly.patch │ ├── 0009-x86-boot-Remove-mapping-from-page-fault-handler.patch │ ├── 0010-efi-libstub-x86-mixed-increase-supported-argument-co.patch │ ├── 0011-efi-libstub-declare-DXE-services-table.patch │ ├── 0012-efi-libstub-ensure-allocated-memory-to-be-executable.patch │ ├── 0013-efi-x86-libstub-Make-DXE-calls-mixed-mode-safe.patch │ ├── 0014-efi-x86-Set-the-NX-compatibility-flag-in-the-PE-head.patch │ ├── 0015-efi-x86-libstub-Fix-typo-in-__efi64_argmap-name.patch │ ├── 0016-efi-libstub-Move-helper-function-to-related-file.patch │ ├── 0017-x86-boot-Make-console-interface-more-abstract.patch │ ├── 0018-x86-boot-Make-kernel_add_identity_map-a-pointer.patch │ ├── 0019-x86-boot-Split-trampoline-and-pt-init-code.patch │ ├── 0020-x86-boot-Add-EFI-kernel-extraction-interface.patch │ ├── 0021-x86-boot-Reduce-lower-limit-of-physical-KASLR.patch │ ├── 0022-efi-x86-Support-extracting-kernel-from-libstub.patch │ ├── 0023-x86-decompressor-Remove-the-bugger-off-message.patch │ ├── 0024-tools-include-Add-simplified-version-of-pe.h.patch │ ├── 0025-x86-build-Cleanup-tools-build.c.patch │ ├── 0026-efi-x86-Use-private-copy-of-struct-setup_header.patch │ ├── 0027-x86-build-Add-SETUP_HEADER_OFFSET-constant.patch │ ├── 0028-x86-build-set-type_of_loader-for-EFISTUB.patch │ ├── 0029-efi-libstub-Don-t-set-ramdisk_image-ramdisk_size.patch │ ├── 0030-x86-build-Make-generated-PE-more-spec-compliant.patch │ ├── 0031-efi-libstub-Add-memory-attribute-protocol-definition.patch │ ├── 0032-efi-libstub-Use-memory-attribute-protocol.patch │ ├── 0033-efi-libstub-make-memory-protection-warnings-include-.patch │ ├── 0034-efi-x86-don-t-try-to-set-page-attributes-on-0-sized-.patch │ ├── 0035-x86-boot-Add-strlcat-and-strscpy-to-compressed-kerne.patch │ ├── 0036-x86-Add-cmdline_prepare-helper.patch │ ├── 0037-x86-setup-Use-cmdline_prepare-in-setup.c.patch │ ├── 0038-x86-boot-Use-cmdline_prapare-in-compressed-kernel.patch │ └── 0039-x86-boot-Remove-no-longer-needed-includes.patch │ └── v6.3 │ ├── v5-0001-x86-boot-Align-vmlinuz-sections-on-page-size.patch │ ├── v5-0002-x86-build-Remove-RWX-sections-and-align-on-4KB.patch │ ├── v5-0003-x86-boot-Set-cr0-to-known-state-in-trampoline.patch │ ├── v5-0004-x86-boot-Increase-boot-page-table-size.patch │ ├── v5-0005-x86-boot-Support-4KB-pages-for-identity-mapping.patch │ ├── v5-0006-x86-boot-Setup-memory-protection-for-bzImage-code.patch │ ├── v5-0007-x86-build-Check-W-X-of-vmlinux-during-build.patch │ ├── v5-0008-x86-boot-Map-memory-explicitly.patch │ ├── v5-0009-x86-boot-Remove-mapping-from-page-fault-handler.patch │ ├── v5-0010-efi-libstub-Move-helper-function-to-related-file.patch │ ├── v5-0011-x86-boot-Make-console-interface-more-abstract.patch │ ├── v5-0012-x86-boot-Make-kernel_add_identity_map-a-pointer.patch │ ├── v5-0013-x86-boot-Split-trampoline-and-pt-init-code.patch │ ├── v5-0014-x86-boot-Add-EFI-kernel-extraction-interface.patch │ ├── v5-0015-efi-x86-Support-extracting-kernel-from-libstub.patch │ ├── v5-0016-x86-boot-Reduce-lower-limit-of-physical-KASLR.patch │ ├── v5-0017-x86-boot-Reduce-size-of-the-DOS-stub.patch │ ├── v5-0018-tools-include-Add-simplified-version-of-pe.h.patch │ ├── v5-0019-x86-build-Cleanup-tools-build.c.patch │ ├── v5-0020-x86-build-Make-generated-PE-more-spec-compliant.patch │ ├── v5-0021-efi-x86-Explicitly-set-sections-memory-attributes.patch │ ├── v5-0022-efi-libstub-Use-memory-attribute-protocol.patch │ └── v5-0023-efi-libstub-make-memory-protection-warnings-inclu.patch └── uncstrap ├── configs └── unc-UEFI.cfg └── uncstrap.py /.github/workflows/build_uncrustify.yml: -------------------------------------------------------------------------------- 1 | name: Build Uncrustify 2 | 3 | on: 4 | push: 5 | pull_request: 6 | workflow_dispatch: 7 | release: 8 | types: [published] 9 | 10 | env: 11 | PROJECT_TYPE: UEFI 12 | 13 | jobs: 14 | build-macos: 15 | name: macOS 16 | runs-on: macos-latest 17 | env: 18 | JOB_TYPE: BUILD 19 | steps: 20 | - uses: actions/checkout@v4 21 | 22 | - name: Install Dependencies 23 | run: | 24 | python3 -m venv ~/pyenv 25 | source ~/pyenv/bin/activate 26 | python3 -m pip install -r requirements.txt 27 | 28 | - name: CI Bootstrap 29 | run: | 30 | src=$(/usr/bin/curl -Lfs https://raw.githubusercontent.com/acidanthera/ocbuild/master/ci-bootstrap.sh) && eval "$src" || exit 1 31 | 32 | - name: Build Uncrustify 33 | run: | 34 | source ~/pyenv/bin/activate 35 | cd uncstrap && python3 ./uncstrap.py -b 36 | echo "UNC_SHA=$(cat unc-sha.txt)" >> $GITHUB_ENV 37 | 38 | - name: Upload to Artifacts 39 | uses: actions/upload-artifact@v4 40 | with: 41 | name: Uncrustify-Darwin-${{ env.UNC_SHA }} 42 | path: ./uncstrap/uncrustify 43 | if-no-files-found: error 44 | 45 | build-linux: 46 | name: Linux 47 | runs-on: ubuntu-latest 48 | steps: 49 | - uses: actions/checkout@v4 50 | 51 | - name: Install Dependencies 52 | run: | 53 | sudo apt-get update 54 | sudo apt-get install cmake curl git 55 | sudo python3 -m pip install -r requirements.txt 56 | 57 | - name: CI Bootstrap 58 | run: | 59 | src=$(/usr/bin/curl -Lfs https://raw.githubusercontent.com/acidanthera/ocbuild/master/ci-bootstrap.sh) && eval "$src" || exit 1 60 | 61 | - name: Build Uncrustify 62 | run: | 63 | cd uncstrap && python3 ./uncstrap.py -b 64 | echo "UNC_SHA=$(cat unc-sha.txt)" >> $GITHUB_ENV 65 | 66 | - name: Upload to Artifacts 67 | uses: actions/upload-artifact@v4 68 | with: 69 | name: Uncrustify-Linux-${{ env.UNC_SHA }} 70 | path: ./uncstrap/uncrustify 71 | if-no-files-found: error 72 | 73 | build-windows: 74 | name: Windows VS2019 75 | runs-on: windows-2019 76 | defaults: 77 | run: 78 | shell: bash 79 | steps: 80 | - uses: actions/checkout@v4 81 | 82 | - name: Install Dependencies 83 | run: | 84 | choco install cmake make --no-progress 85 | python3 -m pip install -r requirements.txt 86 | 87 | - name: CI Bootstrap 88 | run: | 89 | src=$(curl -Lfs https://raw.githubusercontent.com/acidanthera/ocbuild/master/ci-bootstrap.sh) && eval "$src" || exit 1 90 | 91 | - name: Build Uncrustify 92 | run: | 93 | cd uncstrap && python3 ./uncstrap.py -b 94 | echo "UNC_SHA=$(cat unc-sha.txt)" >> $GITHUB_ENV 95 | 96 | - name: Upload to Artifacts 97 | uses: actions/upload-artifact@v4 98 | with: 99 | name: Uncrustify-Windows-${{ env.UNC_SHA }} 100 | path: ./uncstrap/uncrustify.exe 101 | if-no-files-found: error 102 | -------------------------------------------------------------------------------- /.github/workflows/main.yml: -------------------------------------------------------------------------------- 1 | name: Analyze 2 | 3 | on: 4 | push: 5 | pull_request: 6 | workflow_dispatch: 7 | release: 8 | types: [published] 9 | 10 | jobs: 11 | analyze-shell-scripts: 12 | name: Shell Scripts 13 | runs-on: macos-latest 14 | env: 15 | JOB_TYPE: ANALYZE 16 | steps: 17 | - uses: actions/checkout@v4 18 | 19 | - name: Install Dependencies 20 | run: | 21 | brew install shellcheck 22 | env: 23 | HOMEBREW_NO_INSTALL_CLEANUP: 1 24 | 25 | - name: Run shellcheck 26 | run: find . \( -name "*.tool" -o -name "*.command" -o -name "*.sh" \) -exec sh -c 'for TargetFile; do shellcheck --severity=info "${TargetFile}" || exit 1; done' sh {} + 27 | 28 | analyze-python-scripts: 29 | name: Python Scripts 30 | runs-on: ubuntu-latest 31 | env: 32 | JOB_TYPE: ANALYZE 33 | steps: 34 | - uses: actions/checkout@v4 35 | 36 | - name: Install Dependencies 37 | run: | 38 | python3 -m venv ~/pyenv 39 | source ~/pyenv/bin/activate 40 | python3 -m pip install -r requirements.txt 41 | 42 | - name: Run prospector 43 | run: | 44 | source ~/pyenv/bin/activate 45 | python3 -m prospector . -P ./prospector/profile.yml > prospector_result.txt || exit 1 46 | 47 | - name: Upload prospector result to Artifacts 48 | uses: actions/upload-artifact@v4 49 | if: failure() 50 | with: 51 | name: Prospector Artifacts 52 | path: ./prospector_result.txt 53 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | TestConsole 3 | TestLinux 4 | tinylinux/build 5 | tinylinux/busybox.tar.bz2 6 | tinylinux/initrd* 7 | tinylinux/src 8 | -------------------------------------------------------------------------------- /.shellcheckrc: -------------------------------------------------------------------------------- 1 | # Ignore sourced files if any 2 | disable=SC1091 3 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ocbuild 2 | ======= 3 | 4 | [![Build Status](https://github.com/acidanthera/ocbuild/actions/workflows/main.yml/badge.svg?branch=master)](https://github.com/acidanthera/ocbuild/actions) 5 | 6 | Buildscripts and tools for various packages used in [Acidanthera](https://github.com/acidanthera). 7 | -------------------------------------------------------------------------------- /ci-bootstrap.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | abort() { 4 | echo "ERROR: $1!" 5 | exit 1 6 | } 7 | 8 | unamer() { 9 | NAME="$(uname)" 10 | 11 | if [ "$(echo "${NAME}" | grep MINGW)" != "" ] || [ "$(echo "${NAME}" | grep MSYS)" != "" ]; then 12 | echo "Windows" 13 | else 14 | echo "${NAME}" 15 | fi 16 | } 17 | 18 | if [ "$(unamer)" = "Darwin" ]; then 19 | XCODE_DIR="/Applications/Xcode_VERSION.app/Contents/Developer" 20 | 21 | # In GitHub Actions: 22 | # env: 23 | # PROJECT_TYPE: "UEFI" 24 | 25 | # TODO: Get rid of 13.4.1 after fully migrating to macOS 13 workers. 26 | if [ "$(uname -r | cut -f1 -d'.')" = "21" ]; then 27 | XCODE_VERSION="13.4.1" 28 | else 29 | # Stick to 15.2 because current default download version of Coverity cannot support higher yet: 30 | # https://sig-synopsys.my.site.com/community/s/article/coverity-capture-failed-for-Xcode-15-4-version-on-Mac-OS 31 | # https://documentation.blackduck.com/bundle/coverity-docs/page/webhelp-files/relnotes_latest.html#:~:text=Bug%20fixes-,CAP%2D2296,-Reported%20in%20version 32 | XCODE_VERSION="15.2.0" 33 | fi 34 | 35 | case "${PROJECT_TYPE}" in 36 | UEFI) 37 | BUILD_DEVELOPER_DIR="${XCODE_DIR/VERSION/${XCODE_VERSION}}" 38 | ANALYZE_DEVELOPER_DIR="${XCODE_DIR/VERSION/${XCODE_VERSION}}" 39 | COVERITY_DEVELOPER_DIR="${XCODE_DIR/VERSION/${XCODE_VERSION}}" 40 | ;; 41 | 42 | KEXT | TOOL) 43 | BUILD_DEVELOPER_DIR="${XCODE_DIR/VERSION/${XCODE_VERSION}}" 44 | ANALYZE_DEVELOPER_DIR="${XCODE_DIR/VERSION/${XCODE_VERSION}}" 45 | COVERITY_DEVELOPER_DIR="${XCODE_DIR/VERSION/${XCODE_VERSION}}" 46 | ;; 47 | 48 | *) 49 | abort "Invalid project type" 50 | ;; 51 | esac 52 | 53 | SELECTED_DEVELOPER_DIR="${JOB_TYPE}_DEVELOPER_DIR" 54 | 55 | export BUILD_DEVELOPER_DIR 56 | export ANALYZE_DEVELOPER_DIR 57 | export COVERITY_DEVELOPER_DIR 58 | export SELECTED_DEVELOPER_DIR 59 | 60 | if [ -z "${!SELECTED_DEVELOPER_DIR}" ]; then 61 | abort "Invalid or missing job type" 62 | fi 63 | 64 | echo "DEVELOPER_DIR=${!SELECTED_DEVELOPER_DIR}" >> "$GITHUB_ENV" 65 | 66 | # Since GITHUB_ENV doesn't affect the current step, need to export DEVELOPER_DIR for subsequent commands. 67 | export DEVELOPER_DIR="${!SELECTED_DEVELOPER_DIR}" 68 | 69 | if [ -n "${ACID32}" ]; then 70 | echo "OVERRIDE_PYTHON3=${DEVELOPER_DIR}/usr/bin/python3" >> "$GITHUB_ENV" 71 | export OVERRIDE_PYTHON3="${DEVELOPER_DIR}/usr/bin/python3" 72 | src=$(curl -Lfs https://raw.githubusercontent.com/acidanthera/ocbuild/master/clang32-bootstrap.sh) && eval "$src" || exit 1 73 | fi 74 | fi 75 | 76 | colored_text() { 77 | echo -e "\033[0;36m${1}\033[0m" 78 | } 79 | 80 | # Print runner details 81 | colored_text "OS version" 82 | if [ "$(unamer)" = "Darwin" ]; then 83 | sw_vers 84 | elif [ "$(unamer)" = "Windows" ]; then 85 | wmic os get caption, version 86 | else 87 | lsb_release -a 88 | fi 89 | 90 | colored_text "git version" 91 | git --version 92 | 93 | colored_text "bash version" 94 | bash --version 95 | 96 | colored_text "curl version" 97 | curl --version 98 | 99 | if [ "$(unamer)" = "Darwin" ]; then 100 | colored_text "clang version" 101 | clang --version 102 | 103 | if [ -n "${ACID32}" ]; then 104 | colored_text "clang32 version" 105 | ./clang32/clang-12 --version 106 | fi 107 | 108 | colored_text "Xcode version" 109 | xcode-select --print-path 110 | else 111 | colored_text "gcc version" 112 | gcc --version 113 | fi 114 | 115 | if [ "$(unamer)" = "Windows" ]; then 116 | colored_text "VS latest version" 117 | echo "$(vswhere -latest -products '*' -requires Microsoft.VisualStudio.Component.VC.Tools.x86.x64 -property catalog_productSemanticVersion)" 118 | fi 119 | -------------------------------------------------------------------------------- /clang32-bootstrap.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | abort() { 4 | echo "ERROR: $1!" 5 | exit 1 6 | } 7 | 8 | ret=0 9 | 10 | # Avoid conflicts with PATH overrides. 11 | CHMOD="/bin/chmod" 12 | CURL="/usr/bin/curl" 13 | MKDIR="/bin/mkdir" 14 | RM="/bin/rm" 15 | UNZIP="/usr/bin/unzip" 16 | 17 | if [ -z "${OVERRIDE_PYTHON3}" ]; then 18 | # Use whatever is in PATH 19 | OVERRIDE_PYTHON3=python3 20 | fi 21 | 22 | CLANG32_DIR="clang32" 23 | 24 | CLANG32_SCRIPTS_URL="https://raw.githubusercontent.com/acidanthera/ocbuild/master/scripts/" 25 | CLANG32_SCRIPTS=( 26 | "fix-macho32" 27 | "libtool32" 28 | ) 29 | 30 | CLANG32_ZIP="clang-12-xcode-14.zip" 31 | 32 | "${CURL}" -LfsO "https://github.com/acidanthera/ocbuild/releases/download/llvm-kext32-latest/${CLANG32_ZIP}" || ret=$? 33 | if [ $ret -ne 0 ]; then 34 | abort "Failed to download clang32 with code ${ret}" 35 | fi 36 | 37 | "${MKDIR}" "${CLANG32_DIR}" 38 | if [ $ret -ne 0 ]; then 39 | abort "Failed to create clang32 directory with code ${ret}" 40 | fi 41 | 42 | "${UNZIP}" -q "${CLANG32_ZIP}" -d "${CLANG32_DIR}" || ret=$? 43 | if [ $ret -ne 0 ]; then 44 | abort "Failed to extract downloaded clang32 with code ${ret}" 45 | fi 46 | 47 | "${RM}" -rf "${CLANG32_ZIP}" 48 | 49 | # Download tools to override 50 | for tool in "${CLANG32_SCRIPTS[@]}"; do 51 | url="${CLANG32_SCRIPTS_URL}/${tool}" 52 | "${CURL}" -Lfs "${url}" -o "${CLANG32_DIR}/${tool}" || ret=$? 53 | if [ $ret -ne 0 ]; then 54 | abort "Failed to download ${tool} with code ${ret}" 55 | fi 56 | "${CHMOD}" a+x "${CLANG32_DIR}/${tool}" || ret=$? 57 | if [ $ret -ne 0 ]; then 58 | abort "Failed to chmod ${tool} with code ${ret}" 59 | fi 60 | done 61 | 62 | # macholib required for fix-macho32 63 | "${OVERRIDE_PYTHON3}" -m pip install --disable-pip-version-check --user -q macholib || ret=$? 64 | if [ $ret -ne 0 ]; then 65 | abort "Failed to install macholib with code ${ret}" 66 | fi 67 | -------------------------------------------------------------------------------- /codesign/appsign.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # 4 | # Based on pkgAndNotarize.sh 5 | # Copyright (c) 2019 - Armin Briegel - Scripting OS X 6 | # 7 | 8 | cleanup() { 9 | rm -rf dmg-build certificate.p12 build.keychain 10 | } 11 | 12 | abort() { 13 | echo "ERROR: ${1}!" 14 | if [ "$2" != "" ]; then 15 | echo "Hint: ${2}." 16 | fi 17 | 18 | revertkeychain 19 | cleanup 20 | exit 1 21 | } 22 | 23 | revertkeychain() { 24 | if [ -f "${syskeychain}" ]; then 25 | echo "Reverting keychain..." 26 | security default-keychain -s "${syskeychain}" || echo "WARN: Failed to revert keychain!" 27 | security delete-keychain "${workdir}/build.keychain" || echo "WARN: Failed to delete keychain!" 28 | fi 29 | } 30 | 31 | downloadcert() { 32 | if [ "$MAC_CERTIFICATE_PASSWORD" = "" ]; then 33 | abort "Unable to find macOS certificate password" "Set MAC_CERTIFICATE_PASSWORD environment variable" 34 | fi 35 | 36 | curl -OL "https://github.com/acidanthera/ocbuild/raw/master/codesign/certificate.p12" || abort "Failed to download certificates" 37 | 38 | local pw 39 | pw=$(uuidgen) 40 | rm -f "${workdir}/build.keychain" 41 | security create-keychain -p "${pw}" "${workdir}/build.keychain" || abort "Cannot create keychain" 42 | security default-keychain -s "${workdir}/build.keychain" || abort "Cannot set default keychain" 43 | security unlock-keychain -p "${pw}" "${workdir}/build.keychain" || abort "Cannot unlock keychain" 44 | security import certificate.p12 -k "${workdir}/build.keychain" -P "$MAC_CERTIFICATE_PASSWORD" -T /usr/bin/codesign || abort "Cannot import certificate" 45 | security set-key-partition-list -S apple-tool:,apple:,codesign: -s -k "${pw}" "${workdir}/build.keychain" || abort "Cannot set keychain key list" 46 | } 47 | 48 | compressapp() { 49 | if [ "$(which create-dmg)" = "" ]; then 50 | abort "Unable to locate create-dmg command" 51 | fi 52 | 53 | mkdir "dmg-build" || abort "Unable to create dmg-build directory" 54 | 55 | apppath="$1" 56 | outfile="$2" 57 | appname="$(basename "${apppath}")" 58 | 59 | cp -a "${apppath}" "dmg-build/" || abort "Unable to copy application to dmg-build" 60 | 61 | create-dmg \ 62 | --volname "${appname/.app/}" \ 63 | --window-pos 200 120 \ 64 | --window-size 800 400 \ 65 | --icon-size 100 \ 66 | --icon "${appname}" 200 190 \ 67 | --hide-extension "${appname}" \ 68 | --app-drop-link 600 185 \ 69 | "${outfile}" \ 70 | "dmg-build/" || abort "Unable to create dmg file" 71 | 72 | rm -rf dmg-build 73 | } 74 | 75 | notarizefile() { # $1: path to file to notarize, $2: identifier 76 | filepath="${1}" 77 | identifier="${2}" 78 | 79 | if [ "$MAC_ACCOUNT_NAME" = "" ]; then 80 | abort "Unable to find Apple account name" "Set MAC_ACCOUNT_NAME environment variable" 81 | fi 82 | 83 | if [ "$MAC_ACCOUNT_PASSWORD" = "" ]; then 84 | abort "Unable to find Apple account name" "Set MAC_ACCOUNT_PASSWORD environment variable" 85 | fi 86 | 87 | asc_provider=$(security find-certificate -a -c "Developer ID" "${workdir}/build.keychain" | grep "alis" | head -1 | cut -d'"' -f4 | cut -d'(' -f2 | cut -d')' -f1) 88 | if [ "$asc_provider" = "" ]; then 89 | abort "Unable to find ASC provider" 90 | fi 91 | 92 | # Upload file 93 | echo "Uploading ${filepath} for notarization for ${asc_provider}" 94 | notarytoolOutput=$(xcrun notarytool submit \ 95 | "$filepath" \ 96 | --apple-id "${MAC_ACCOUNT_NAME}" \ 97 | --password "${MAC_ACCOUNT_PASSWORD}" \ 98 | --team-id "${asc_provider}" \ 99 | --output-format plist \ 100 | --wait) 101 | 102 | requestUUID="$(echo "${notarytoolOutput}" | plutil -extract id raw -)" 103 | requestStatus="$(echo "${notarytoolOutput}" | plutil -extract status raw -)" 104 | 105 | # This will handle errors as well 106 | if [ "$requestStatus" != "Accepted" ]; then 107 | abort "Could not notarize ${filepath}: ${notarytoolOutput}" 108 | fi 109 | 110 | # Print status information 111 | xcrun notarytool info \ 112 | "$requestUUID" \ 113 | --apple-id "${MAC_ACCOUNT_NAME}" \ 114 | --password "${MAC_ACCOUNT_PASSWORD}" \ 115 | --team-id "${asc_provider}" 116 | echo 117 | } 118 | 119 | cleanup 120 | 121 | # Obtain system data. 122 | echo "Gathering system data..." 123 | workdir=$(pwd) 124 | syskeychain=$(security default-keychain | xargs echo) 125 | if [ ! -f "${syskeychain}" ]; then 126 | abort "Unable to locate default keychain at ${syskeychain}" 127 | fi 128 | 129 | # Obtain application data. 130 | echo "Gathering application data..." 131 | if [ ! -d "$1" ]; then 132 | abort "Unable to locate application to sign" "Pass application path as an argument" 133 | fi 134 | 135 | cd "$1" || abort "Cannot get app full path" 136 | apppath="$(pwd)" 137 | cd - || abort "Cannot switch directory back" 138 | 139 | if [ "$2" = "" ]; then 140 | abort "Missing archive filename for target file" "Pass path to archived file as an argument" 141 | fi 142 | 143 | # TODO: Accept relative paths. 144 | apppkg="$2" 145 | rm -f "${apppkg}" 146 | 147 | identifier="$(defaults read "${apppath}/Contents/Info.plist" CFBundleIdentifier)" 148 | if [ "$identifier" = "" ]; then 149 | abort "Unable to locate application identifier" "Set CFBundleIdentifier in Info.plist" 150 | fi 151 | 152 | #shellcheck disable=SC2207 153 | extraflags=($(echo "$3")) 154 | 155 | # Obtain certificate data. 156 | echo "Downloading the certificates..." 157 | downloadcert 158 | 159 | # Codesign inner applications. 160 | echo "Codesigning inner applications..." 161 | find "${apppath}"/* -name '*.app' -exec \ 162 | /usr/bin/codesign --force --deep --options runtime "${extraflags[@]}" -s "Developer ID" {} \; || abort "Unable to sign inner applications" 163 | 164 | echo "Codesigning inner plugins..." 165 | find "${apppath}"/* -name '*.qlgenerator' -exec \ 166 | /usr/bin/codesign --force --deep --options runtime "${extraflags[@]}" -s "Developer ID" {} \; || abort "Unable to sign inner plugins" 167 | 168 | # Codesign the application. 169 | echo "Codesigning application..." 170 | /usr/bin/codesign --force --deep --options runtime "${extraflags[@]}" -s "Developer ID" "${apppath}" || abort "Unable to sign application" 171 | 172 | # Compress the application. 173 | echo "Compressing application..." 174 | compressapp "${apppath}" "${apppkg}" 175 | 176 | # Notarize the application. 177 | notarizefile "${apppkg}" "${identifier}" 178 | 179 | # Staple the application. 180 | echo "Stapling application..." 181 | xcrun stapler staple "${apppkg}" 182 | 183 | echo 'All done!' 184 | revertkeychain 185 | cleanup 186 | -------------------------------------------------------------------------------- /codesign/certificate.p12: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/acidanthera/ocbuild/6d1002b66db865456e1bf72bd66d73c9d2230e60/codesign/certificate.p12 -------------------------------------------------------------------------------- /coverity/covstrap-linux.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # 4 | # covstrap-linux.sh 5 | # ocbuild 6 | # 7 | # Copyright © 2018-2022 vit9696, PMheart. All rights reserved. 8 | # 9 | 10 | # 11 | # This script is supposed to quickly bootstrap Coverity Scan environment for GitHub Actions 12 | # to be later used with OpenCore. 13 | # 14 | # Latest version available at: 15 | # https://raw.githubusercontent.com/acidanthera/ocbuild/master/coverity/covstrap-linux.sh 16 | # 17 | # Example usage: 18 | # src=$(/usr/bin/curl -Lfs https://raw.githubusercontent.com/acidanthera/ocbuild/master/coverity/covstrap-linux.sh) && eval "$src" || exit 1 19 | # 20 | 21 | abort() { 22 | echo "ERROR: $1!" 23 | exit 1 24 | } 25 | 26 | PROJECT_PATH="$(pwd)" 27 | # shellcheck disable=SC2181 28 | if [ $? -ne 0 ] || [ ! -d "${PROJECT_PATH}" ]; then 29 | abort "Failed to determine working directory" 30 | fi 31 | 32 | if [ "${COVERITY_SCAN_TOKEN}" = "" ]; then 33 | abort "No COVERITY_SCAN_TOKEN provided" 34 | fi 35 | 36 | if [ "${COVERITY_SCAN_EMAIL}" = "" ]; then 37 | abort "No COVERITY_SCAN_EMAIL provided" 38 | fi 39 | 40 | if [ "${GITHUB_REPOSITORY}" = "" ]; then 41 | abort "No GITHUB_REPOSITORY provided" 42 | fi 43 | 44 | # Avoid conflicts with PATH overrides. 45 | CHMOD="/bin/chmod" 46 | CURL="/usr/bin/curl" 47 | MKDIR="/bin/mkdir" 48 | MV="/bin/mv" 49 | RM="/bin/rm" 50 | TAR="/usr/bin/tar" 51 | 52 | TOOLS=( 53 | "${CHMOD}" 54 | "${CURL}" 55 | "${MKDIR}" 56 | "${MV}" 57 | "${RM}" 58 | "${TAR}" 59 | ) 60 | for tool in "${TOOLS[@]}"; do 61 | if [ ! -x "${tool}" ]; then 62 | abort "Missing ${tool}" 63 | fi 64 | done 65 | 66 | # Download Coverity 67 | COVERITY_ANALYSIS_DIR="${PROJECT_PATH}/cov-analysis" 68 | COVERITY_SCAN_ARCHIVE=cov-analysis.tar.gz 69 | COVERITY_SCAN_LINK="https://scan.coverity.com/download/cxx/linux64" 70 | 71 | ret=0 72 | echo "Downloading Coverity analysis tool..." 73 | "${CURL}" -LfsS "${COVERITY_SCAN_LINK}" -d "token=${COVERITY_SCAN_TOKEN}&project=${GITHUB_REPOSITORY}" -o "${COVERITY_SCAN_ARCHIVE}" || ret=$? 74 | if [ $ret -ne 0 ]; then 75 | abort "Failed to download Coverity analysis tool with code ${ret}" 76 | fi 77 | 78 | "${TAR}" -xzf cov-analysis.tar.gz 79 | if [ $ret -ne 0 ]; then 80 | abort "Failed to decompress Coverity analysis tool with code ${ret}" 81 | fi 82 | 83 | "${MV}" cov-analysis-linux64-* "${COVERITY_ANALYSIS_DIR}" 84 | if [ $ret -ne 0 ]; then 85 | abort "Failed to rename cov-analysis-linux64 directory to cov-analysis" 86 | fi 87 | 88 | # Export override variables 89 | export COVERITY_RESULTS_DIR="${PROJECT_PATH}/cov-int" 90 | 91 | # Refresh PATH to apply overrides 92 | export PATH="${COVERITY_ANALYSIS_DIR}/bin:${PATH}" 93 | 94 | # Run Coverity 95 | # shellcheck disable=SC2086 96 | cov-build --dir "${COVERITY_RESULTS_DIR}" ${COVERITY_BUILD_COMMAND} || ret=$? 97 | if [ $ret -ne 0 ]; then 98 | abort "Coverity build tool failed with code ${ret}" 99 | fi 100 | 101 | # Upload results 102 | COVERITY_RESULTS_FILE=results.tgz 103 | ${TAR} czf "${COVERITY_RESULTS_FILE}" -C "${COVERITY_RESULTS_DIR}/.." "$(basename "${COVERITY_RESULTS_DIR}")" || ret=$? 104 | if [ $ret -ne 0 ]; then 105 | abort "Failed to compress Coverity results dir ${COVERITY_RESULTS_DIR} with code ${ret}" 106 | fi 107 | 108 | upload () { 109 | ${CURL} \ 110 | --form project="${GITHUB_REPOSITORY}" \ 111 | --form token="${COVERITY_SCAN_TOKEN}" \ 112 | --form email="${COVERITY_SCAN_EMAIL}" \ 113 | --form file="@${COVERITY_RESULTS_FILE}" \ 114 | --form version="${GITHUB_SHA}" \ 115 | --form description="GitHub Actions build" \ 116 | "https://scan.coverity.com/builds?project=${GITHUB_REPOSITORY}" 117 | return $? 118 | } 119 | 120 | for i in {1..3} 121 | do 122 | echo "Uploading results... (Trial $i/3)" 123 | upload && exit 0 || ret=$? 124 | done 125 | abort "Failed to upload Coverity results ${COVERITY_RESULTS_FILE} with code ${ret}" 126 | -------------------------------------------------------------------------------- /coverity/covstrap.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # 4 | # covstrap.sh 5 | # ocbuild 6 | # 7 | # Copyright © 2018 vit9696. All rights reserved. 8 | # 9 | 10 | # 11 | # This script is supposed to quickly bootstrap Coverity Scan environment for GitHub Actions 12 | # to be later used with Acidanthera products. 13 | # 14 | # Latest version available at: 15 | # https://raw.githubusercontent.com/acidanthera/ocbuild/master/coverity/covstrap.sh 16 | # 17 | # Example usage: 18 | # src=$(/usr/bin/curl -Lfs https://raw.githubusercontent.com/acidanthera/ocbuild/master/coverity/covstrap.sh) && eval "$src" || exit 1 19 | # 20 | 21 | abort() { 22 | echo "ERROR: $1!" 23 | exit 1 24 | } 25 | 26 | PROJECT_PATH="$(pwd)" 27 | # shellcheck disable=SC2181 28 | if [ $? -ne 0 ] || [ ! -d "${PROJECT_PATH}" ]; then 29 | abort "Failed to determine working directory" 30 | fi 31 | 32 | if [ "${COVERITY_SCAN_TOKEN}" = "" ]; then 33 | abort "No COVERITY_SCAN_TOKEN provided" 34 | fi 35 | 36 | if [ "${COVERITY_SCAN_EMAIL}" = "" ]; then 37 | abort "No COVERITY_SCAN_EMAIL provided" 38 | fi 39 | 40 | if [ "${GITHUB_REPOSITORY}" = "" ]; then 41 | abort "No GITHUB_REPOSITORY provided" 42 | fi 43 | 44 | # Avoid conflicts with PATH overrides. 45 | CHMOD="/bin/chmod" 46 | CURL="/usr/bin/curl" 47 | MKDIR="/bin/mkdir" 48 | MV="/bin/mv" 49 | RM="/bin/rm" 50 | TAR="/usr/bin/tar" 51 | 52 | TOOLS=( 53 | "${CHMOD}" 54 | "${CURL}" 55 | "${MKDIR}" 56 | "${MV}" 57 | "${RM}" 58 | "${TAR}" 59 | ) 60 | for tool in "${TOOLS[@]}"; do 61 | if [ ! -x "${tool}" ]; then 62 | abort "Missing ${tool}" 63 | fi 64 | done 65 | 66 | # Download Coverity 67 | COVERITY_SCAN_DIR="${PROJECT_PATH}/cov-scan" 68 | COVERITY_SCAN_ARCHIVE=cov-analysis.dmg 69 | COVERITY_SCAN_INSTALLER=cov-analysis.sh 70 | COVERITY_SCAN_LINK="https://scan.coverity.com/download/cxx/macOS" 71 | 72 | ret=0 73 | echo "Downloading Coverity build tool..." 74 | "${CURL}" -LfsS "${COVERITY_SCAN_LINK}" -d "token=${COVERITY_SCAN_TOKEN}&project=${GITHUB_REPOSITORY}" -o "${COVERITY_SCAN_ARCHIVE}" || ret=$? 75 | if [ $ret -ne 0 ]; then 76 | abort "Failed to download Coverity build tool with code ${ret}" 77 | fi 78 | 79 | hdiutil attach "${COVERITY_SCAN_ARCHIVE}" || ret=$? 80 | if [ $ret -ne 0 ]; then 81 | abort "Failed to mount Coverity build tool with code ${ret}" 82 | fi 83 | 84 | cp "$(ls /Volumes/cov-analysis-macosx-*/cov-analysis-macosx-*)" "${COVERITY_SCAN_INSTALLER}" || ret=$? 85 | if [ $ret -ne 0 ]; then 86 | abort "Failed to copy Coverity installer with code ${ret}" 87 | fi 88 | 89 | mkdir -p cov-analysis 90 | cd cov-analysis || ret=$? 91 | if [ $ret -ne 0 ]; then 92 | abort "Failed to cd to cov-analysis ${ret}" 93 | fi 94 | 95 | ../"${COVERITY_SCAN_INSTALLER}" || ret=$? 96 | if [ $ret -ne 0 ]; then 97 | abort "Failed to extract Coverity build tool with code ${ret}" 98 | fi 99 | 100 | COVERITY_EXTRACT_DIR=$(pwd) 101 | if [ "${COVERITY_EXTRACT_DIR}" = "" ]; then 102 | abort "Failed to find Coverity build tool directory" 103 | fi 104 | 105 | cd .. 106 | "${RM}" -rf "${COVERITY_SCAN_DIR}" 107 | "${MV}" "${COVERITY_EXTRACT_DIR}" "${COVERITY_SCAN_DIR}" || ret=$? 108 | if [ "${COVERITY_EXTRACT_DIR}" = "" ]; then 109 | abort "Failed to move Coverity build tool from ${COVERITY_EXTRACT_DIR} to ${COVERITY_SCAN_DIR}" 110 | fi 111 | 112 | # Export override variables 113 | export COVERITY_RESULTS_DIR="${PROJECT_PATH}/cov-int" 114 | export CC="/usr/bin/clang" 115 | export CXX="/usr/bin/clang++" 116 | 117 | # Refresh PATH to apply overrides 118 | export PATH="${COVERITY_SCAN_DIR}/bin:${PATH}" 119 | 120 | # Run Coverity 121 | export COVERITY_UNSUPPORTED=1 122 | # Configure Coverity for an unsupported compiler. 123 | cov-configure --clang || ret=$? 124 | if [ $ret -ne 0 ]; then 125 | abort "Coverity configure for clang failed with code ${ret}" 126 | fi 127 | # shellcheck disable=SC2086 128 | cov-build --dir "${COVERITY_RESULTS_DIR}" ${COVERITY_BUILD_COMMAND} || ret=$? 129 | if [ $ret -ne 0 ]; then 130 | abort "Coverity build tool failed with code ${ret}" 131 | fi 132 | 133 | # Upload results 134 | COVERITY_RESULTS_FILE=results.tgz 135 | ${TAR} czf "${COVERITY_RESULTS_FILE}" -C "${COVERITY_RESULTS_DIR}/.." "$(basename "${COVERITY_RESULTS_DIR}")" || ret=$? 136 | if [ $ret -ne 0 ]; then 137 | abort "Failed to compress Coverity results dir ${COVERITY_RESULTS_DIR} with code ${ret}" 138 | fi 139 | 140 | upload () { 141 | ${CURL} \ 142 | --form project="${GITHUB_REPOSITORY}" \ 143 | --form token="${COVERITY_SCAN_TOKEN}" \ 144 | --form email="${COVERITY_SCAN_EMAIL}" \ 145 | --form file="@${COVERITY_RESULTS_FILE}" \ 146 | --form version="${GITHUB_SHA}" \ 147 | --form description="GitHub Actions build" \ 148 | "https://scan.coverity.com/builds?project=${GITHUB_REPOSITORY}" 149 | return $? 150 | } 151 | 152 | for i in {1..3} 153 | do 154 | echo "Uploading results... (Trial $i/3)" 155 | upload && exit 0 || ret=$? 156 | done 157 | abort "Failed to upload Coverity results ${COVERITY_RESULTS_FILE} with code ${ret}" 158 | -------------------------------------------------------------------------------- /docker-apparmor.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # 4 | # REF: https://github.com/docker/docs/pull/19638/files 5 | # REF: https://stackoverflow.com/a/20293759/795690 6 | # 7 | sudo tee -a "/etc/apparmor.d/$(echo "$HOME/bin/rootlesskit" | sed -e s@^/@@ -e s@/@.@g)" > /dev/null << EOF 8 | abi , 9 | include 10 | 11 | $HOME/bin/rootlesskit flags=(unconfined) { 12 | userns, 13 | 14 | include if exists 15 | } 16 | EOF 17 | 18 | sudo systemctl restart apparmor.service 19 | -------------------------------------------------------------------------------- /external/TestConsole.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/acidanthera/ocbuild/6d1002b66db865456e1bf72bd66d73c9d2230e60/external/TestConsole.zip -------------------------------------------------------------------------------- /external/TestLinux.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/acidanthera/ocbuild/6d1002b66db865456e1bf72bd66d73c9d2230e60/external/TestLinux.zip -------------------------------------------------------------------------------- /external/Uncrustify-Darwin-c82ee0343f412ceba2c9efc85afc1d43d9f45c1f.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/acidanthera/ocbuild/6d1002b66db865456e1bf72bd66d73c9d2230e60/external/Uncrustify-Darwin-c82ee0343f412ceba2c9efc85afc1d43d9f45c1f.zip -------------------------------------------------------------------------------- /external/Uncrustify-Darwin.zip: -------------------------------------------------------------------------------- 1 | Uncrustify-Darwin-c82ee0343f412ceba2c9efc85afc1d43d9f45c1f.zip -------------------------------------------------------------------------------- /external/Uncrustify-Linux-c82ee0343f412ceba2c9efc85afc1d43d9f45c1f.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/acidanthera/ocbuild/6d1002b66db865456e1bf72bd66d73c9d2230e60/external/Uncrustify-Linux-c82ee0343f412ceba2c9efc85afc1d43d9f45c1f.zip -------------------------------------------------------------------------------- /external/Uncrustify-Linux.zip: -------------------------------------------------------------------------------- 1 | Uncrustify-Linux-c82ee0343f412ceba2c9efc85afc1d43d9f45c1f.zip -------------------------------------------------------------------------------- /external/Uncrustify-Windows-c82ee0343f412ceba2c9efc85afc1d43d9f45c1f.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/acidanthera/ocbuild/6d1002b66db865456e1bf72bd66d73c9d2230e60/external/Uncrustify-Windows-c82ee0343f412ceba2c9efc85afc1d43d9f45c1f.zip -------------------------------------------------------------------------------- /external/Uncrustify-Windows.zip: -------------------------------------------------------------------------------- 1 | Uncrustify-Windows-c82ee0343f412ceba2c9efc85afc1d43d9f45c1f.zip -------------------------------------------------------------------------------- /external/iasl-20200528-macosx.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/acidanthera/ocbuild/6d1002b66db865456e1bf72bd66d73c9d2230e60/external/iasl-20200528-macosx.zip -------------------------------------------------------------------------------- /external/iasl-macosx.zip: -------------------------------------------------------------------------------- 1 | iasl-20200528-macosx.zip -------------------------------------------------------------------------------- /external/nasm-2.15.05-macosx.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/acidanthera/ocbuild/6d1002b66db865456e1bf72bd66d73c9d2230e60/external/nasm-2.15.05-macosx.zip -------------------------------------------------------------------------------- /external/nasm-mac64.zip: -------------------------------------------------------------------------------- 1 | nasm-2.15.05-macosx.zip -------------------------------------------------------------------------------- /macosx10.13-sdk-bootstrap.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | abort() { 4 | echo "ERROR: $1!" 5 | exit 1 6 | } 7 | 8 | # Get Xcode SDK directory 9 | OSX_PLAT=`xcrun --sdk macosx --show-sdk-platform-path` 10 | 11 | # Lower minimum SDK version 12 | sudo plutil -replace MinimumSDKVersion -string 10.6 "$OSX_PLAT"/Info.plist 13 | 14 | # Grab macOS 10.13 SDK and extract 15 | wget -P /tmp https://github.com/acidanthera/ocbuild/releases/download/macos13-sdk/Xcode1013SDK.tar.gz 16 | sudo tar -xf /tmp/Xcode1013SDK.tar.gz -C "$OSX_PLAT"/Developer 17 | rm /tmp/Xcode1013SDK.tar.gz 18 | 19 | # Check SDK is present 20 | xcrun --sdk macosx10.13 --show-sdk-path || exit 1 21 | -------------------------------------------------------------------------------- /patches/clang-32bit-kexts.patch: -------------------------------------------------------------------------------- 1 | From fe4aea44c5e44931be588dbb540ac50418221932 Mon Sep 17 00:00:00 2001 2 | From: Goldfish64 3 | Date: Tue, 29 Jun 2021 18:31:03 -0500 4 | Subject: [PATCH 1/2] Implement vtable fixes for 32-bit Apple kexts 5 | 6 | --- 7 | clang/lib/AST/VTableBuilder.cpp | 8 +++++++- 8 | 1 file changed, 7 insertions(+), 1 deletion(-) 9 | 10 | diff --git a/clang/lib/AST/VTableBuilder.cpp b/clang/lib/AST/VTableBuilder.cpp 11 | index f5865ce96b64..77abdcf40d35 100644 12 | --- a/clang/lib/AST/VTableBuilder.cpp 13 | +++ b/clang/lib/AST/VTableBuilder.cpp 14 | @@ -1661,6 +1661,8 @@ void ItaniumVTableBuilder::LayoutPrimaryAndSecondaryVTables( 15 | if (Base.getBase() == MostDerivedClass) 16 | VBaseOffsetOffsets = Builder.getVBaseOffsetOffsets(); 17 | 18 | + uint64_t AddressPoint = Components.size(); 19 | + 20 | // Add the offset to top. 21 | CharUnits OffsetToTop = MostDerivedClassOffset - OffsetInLayoutClass; 22 | Components.push_back(VTableComponent::MakeOffsetToTop(OffsetToTop)); 23 | @@ -1668,7 +1670,11 @@ void ItaniumVTableBuilder::LayoutPrimaryAndSecondaryVTables( 24 | // Next, add the RTTI. 25 | Components.push_back(VTableComponent::MakeRTTI(MostDerivedClass)); 26 | 27 | - uint64_t AddressPoint = Components.size(); 28 | + // -fapple-kext mode on 32-bit has the vtable pointer placed at the start of 29 | + // the vtable. 30 | + if (!(Context.getLangOpts().AppleKext && 31 | + Context.getTargetInfo().getTriple().isArch32Bit())) 32 | + AddressPoint = Components.size(); 33 | 34 | // Now go through all virtual member functions and add them. 35 | PrimaryBasesSetVectorTy PrimaryBases; 36 | -- 37 | 2.24.3 (Apple Git-128) 38 | 39 | 40 | From 9f869667a82aab11072807de598714bd54b49f3b Mon Sep 17 00:00:00 2001 41 | From: Goldfish64 42 | Date: Sat, 10 Jul 2021 18:50:28 -0500 43 | Subject: [PATCH 2/2] Prevent 16 byte const sections 44 | 45 | --- 46 | lldb/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp | 2 +- 47 | llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp | 4 ++-- 48 | 2 files changed, 3 insertions(+), 3 deletions(-) 49 | 50 | diff --git a/lldb/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp b/lldb/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp 51 | index 463a2a52f5df..54a8af9939bf 100644 52 | --- a/lldb/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp 53 | +++ b/lldb/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp 54 | @@ -1526,7 +1526,7 @@ static lldb::SectionType GetSectionType(uint32_t flags, 55 | // interposing 56 | return eSectionTypeCode; 57 | case S_16BYTE_LITERALS: // section with only 16 byte literals 58 | - return eSectionTypeData16; 59 | + return eSectionTypeData; 60 | case S_DTRACE_DOF: 61 | return eSectionTypeDebug; 62 | case S_LAZY_DYLIB_SYMBOL_POINTERS: 63 | diff --git a/llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp b/llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp 64 | index fe64b38cf0be..1f9f051b93f8 100644 65 | --- a/llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp 66 | +++ b/llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp 67 | @@ -1219,7 +1219,7 @@ MCSection *TargetLoweringObjectFileMachO::SelectSectionForGlobal( 68 | if (Kind.isMergeableConst8()) 69 | return EightByteConstantSection; 70 | if (Kind.isMergeableConst16()) 71 | - return SixteenByteConstantSection; 72 | + return DataSection; 73 | } 74 | 75 | // Otherwise, if it is readonly, but not something we can specially optimize, 76 | @@ -1259,7 +1259,7 @@ MCSection *TargetLoweringObjectFileMachO::getSectionForConstant( 77 | if (Kind.isMergeableConst8()) 78 | return EightByteConstantSection; 79 | if (Kind.isMergeableConst16()) 80 | - return SixteenByteConstantSection; 81 | + return ReadOnlySection; 82 | return ReadOnlySection; // .const 83 | } 84 | 85 | -- 86 | 2.24.3 (Apple Git-128) 87 | 88 | -------------------------------------------------------------------------------- /prospector/profile.yml: -------------------------------------------------------------------------------- 1 | output-format: grouped 2 | strictness: veryhigh 3 | test-warnings: true 4 | member-warnings: true 5 | autodetect: true 6 | 7 | pylint: 8 | disable: 9 | - broad-except 10 | - line-too-long 11 | - too-many-public-methods 12 | - too-many-statements 13 | - invalid-name 14 | - too-many-arguments 15 | - too-many-locals 16 | load-plugins: 17 | - pylint.extensions.no_self_use 18 | run: true 19 | 20 | pycodestyle: 21 | disable: 22 | - E501 23 | run: true 24 | 25 | dodgy: 26 | run: true 27 | 28 | mccabe: 29 | run: false 30 | 31 | pyflakes: 32 | run: false 33 | -------------------------------------------------------------------------------- /requirements.txt: -------------------------------------------------------------------------------- 1 | requests 2 | pyyaml 3 | gitpython 4 | pexpect 5 | argparse 6 | prospector -------------------------------------------------------------------------------- /scripts/fix-macho32: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | 3 | import os 4 | import sys 5 | import tempfile 6 | import subprocess 7 | import macholib.MachO 8 | 9 | from io import BytesIO 10 | from pathlib import Path 11 | from sys import argv 12 | 13 | from macholib.mach_o import ( 14 | LC_VERSION_MIN_MACOSX, 15 | LC_DATA_IN_CODE, 16 | ) 17 | 18 | # 19 | # Binary specified in arguments. 20 | # 21 | input_path = Path(argv[1].strip()) 22 | 23 | # 24 | # Check if we even have a 32-bit binary or 32-bit slice. 25 | # 26 | result = subprocess.run(["lipo", input_path, "-info"], stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True) 27 | if "i386" not in result.stdout: 28 | print("Binary is not 32-bit, nothing to do") 29 | sys.exit(0) 30 | 31 | # 32 | # Extract i386 slice from FAT binary if needed. 33 | # 34 | print("Processing {}".format(input_path)) 35 | if "Non-fat" not in result.stdout: 36 | print("Binary is fat, extracting 32-bit slice") 37 | is_fat_binary = True 38 | slice_temp_file, slice_path = tempfile.mkstemp() 39 | slice_path = Path(slice_path) 40 | os.close(slice_temp_file) 41 | subprocess.run(["lipo", input_path, "-thin", "i386", "-output", slice_path], stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True) 42 | 43 | else: 44 | print("Binary is pure 32-bit") 45 | is_fat_binary = False 46 | slice_path = input_path 47 | 48 | # 49 | # Read Mach-O binary. 50 | # 51 | original_file = BytesIO(slice_path.read_bytes()) 52 | machFile = macholib.MachO.MachO(slice_path) 53 | 54 | # 55 | # Strip LC_VERSION_MIN_MACOSX command. 56 | # 57 | for cmd in machFile.headers[0].commands: 58 | if (cmd[0].cmd == LC_VERSION_MIN_MACOSX): 59 | machFile.headers[0].changedHeaderSizeBy(-cmd[0].cmdsize) 60 | machFile.headers[0].commands.remove(cmd) 61 | machFile.headers[0].header.ncmds -= 1 62 | print("Removed LC_VERSION_MIN_MACOSX") 63 | 64 | # 65 | # Strip LC_DATA_IN_CODE command if zero. 66 | # 67 | for cmd in machFile.headers[0].commands: 68 | if (cmd[0].cmd == LC_DATA_IN_CODE): 69 | if (cmd[1].datasize == 0): 70 | machFile.headers[0].changedHeaderSizeBy(-cmd[0].cmdsize) 71 | machFile.headers[0].commands.remove(cmd) 72 | machFile.headers[0].header.ncmds -= 1 73 | print("Removed LC_DATA_IN_CODE") 74 | else: 75 | print("LC_DATA_IN_CODE data size is non-zero!") 76 | if (is_fat_binary): 77 | slice_path.unlink() 78 | sys.exit(-1) 79 | 80 | # 81 | # Align symbol table offset. 82 | # 83 | symCmd = machFile.headers[0].getSymbolTableCommand() 84 | 85 | oldSymOff = symCmd.symoff 86 | newSymOff = (oldSymOff + 3) & ~(3) 87 | print("Old symbol table offset at {}, new symbol table will be at {}".format(oldSymOff, newSymOff)) 88 | symOffDelta = newSymOff - oldSymOff 89 | 90 | # 91 | # Align string table offset. 92 | # 93 | oldStrOff = symCmd.stroff 94 | newStrOff = ((oldStrOff + symOffDelta) + 3) & ~(3) 95 | print("Old string table offset at {}, new string table will be at {}".format(oldStrOff, newStrOff)) 96 | strOffDelta = newStrOff - (oldStrOff + symOffDelta) 97 | 98 | # 99 | # Write new offsets to symbol table command. 100 | # 101 | symCmd.symoff = newSymOff 102 | symCmd.stroff = newStrOff 103 | 104 | # 105 | # Write Mach-O header to new file. 106 | # 107 | with open(slice_path, "wb") as new_file: 108 | machFile.headers[0].write(new_file) 109 | original_file.seek(new_file.tell()) 110 | 111 | # 112 | # Copy rest of file and pad accordingly. 113 | # 114 | if oldSymOff > oldStrOff: 115 | new_file.write(original_file.read(oldStrOff - original_file.tell())) 116 | new_file.write(b"\0" * strOffDelta) 117 | new_file.write(original_file.read(oldSymOff - original_file.tell())) 118 | new_file.write(b"\0" * symOffDelta) 119 | new_file.write(original_file.read()) 120 | else: 121 | new_file.write(original_file.read(oldSymOff - original_file.tell())) 122 | new_file.write(b"\0" * symOffDelta) 123 | new_file.write(original_file.read(oldStrOff - original_file.tell())) 124 | new_file.write(b"\0" * strOffDelta) 125 | new_file.write(original_file.read()) 126 | 127 | print("Wrote new binary to {}".format(slice_path)) 128 | if is_fat_binary: 129 | print("Replacing 32-bit slice in fat binary") 130 | result = subprocess.run(["lipo", input_path, "-replace", "i386", slice_path, "-output", input_path], stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True) 131 | slice_path.unlink() 132 | -------------------------------------------------------------------------------- /scripts/libtool32: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | command="libtool $*" 4 | command=${command/arch_only ACID32/arch_only i386} 5 | echo "${command}" 6 | ${command} 7 | -------------------------------------------------------------------------------- /test_qemu_fw.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # -*- coding: utf-8 -*- 3 | 4 | import argparse 5 | import os 6 | import re 7 | import sys 8 | import zipfile 9 | import logging 10 | import tempfile 11 | import shutil 12 | 13 | import pexpect 14 | 15 | OCBUILD_PATH = os.path.dirname(os.path.realpath(__file__)) 16 | TEST_LINUX_PATH = f"{OCBUILD_PATH}/TestLinux" 17 | TEST_WINPE_PATH = f"{OCBUILD_PATH}/winpe.iso" 18 | TESTCONSOLE_PATH = f"{OCBUILD_PATH}/TestConsole" 19 | 20 | 21 | def get_qemu_version() -> tuple: 22 | """ 23 | Get QEMU version in system 24 | 25 | :return version tuple (major, minor, patch): 26 | """ 27 | version = None 28 | p = pexpect.spawn('qemu-system-x86_64 -version') 29 | p.expect(pexpect.EOF) 30 | output = p.before.decode('utf-8') 31 | version_pattern = re.compile("(\\d+\\.)(\\d+\\.)(\\*|\\d+)") 32 | collection = version_pattern.findall(output) 33 | if collection: 34 | version = tuple(int(el.strip('.')) for el in collection[0]) 35 | 36 | return version 37 | 38 | 39 | def test_firmware(args, boot_drive_path: str, expected_string: str, timeout: int) -> bool: 40 | """ 41 | Run QEMU and check whether firmware can start given image 42 | 43 | :param args.fw_path: The path points to the firmware to run (OVMF) 44 | :param boot_drive_path: The path points to ESP or raw image to boot from 45 | :param expected_string: The expected string we wait for during image run 46 | :param timeout: Timeout for image run 47 | :param args.rdrand: Run with rdrand support or not 48 | :return the boolean result: 49 | """ 50 | fw_arch = parse_fw_arch(args.fw_arch) 51 | result = False 52 | qemu_version = get_qemu_version() 53 | if qemu_version is None: 54 | logging.error("Can't retrieve QEMU version!") 55 | return False 56 | 57 | qemu_x86_runner = f"qemu-system-x86_64 {'-enable-kvm ' if qemu_version < (6, 2, 0) else ''}" 58 | qemu_arm_runner = 'qemu-system-arm ' 59 | qemu_arm64_runner = 'qemu-system-aarch64 ' 60 | machine_string_x86 = f" -cpu Penryn,+smep,+smap{',+rdrand' if args.rdrand else ''} -smp 2 -machine q35 -m 2048 " 61 | machine_string_arm = ' -cpu cortex-a15 -smp 2 -machine virt,highmem=off ' \ 62 | ' -accel tcg,tb-size=1024 -m 2048 ' 63 | machine_string_arm64 = f" -cpu cortex-a76 -smp 2 -machine virt{',virtualization=on' if args.test_winpe else ''} -accel tcg,tb-size=1024 -m 2048 " 64 | if fw_arch == "x86": 65 | p = pexpect.spawn(qemu_x86_runner + machine_string_x86 + 66 | '-bios ' + args.fw_path + ' -display none -serial stdio ' 67 | + boot_drive_path) 68 | elif fw_arch == "arm": 69 | p = pexpect.spawn(qemu_arm_runner + machine_string_arm + 70 | '-bios ' + args.fw_path + ' -display none -serial stdio ' 71 | + boot_drive_path) 72 | elif fw_arch == "arm64": 73 | p = pexpect.spawn(qemu_arm64_runner + machine_string_arm64 + 74 | '-bios ' + args.fw_path + ' -display none -serial stdio ' 75 | + boot_drive_path) 76 | else: 77 | logging.error("Unsupported arch specified!") 78 | return False 79 | 80 | p.timeout = timeout 81 | res = p.expect([expected_string, pexpect.TIMEOUT, pexpect.EOF]) 82 | if res == 0: 83 | print("OK") 84 | result = True 85 | else: 86 | logging.error("Timeout! Something went wrong, check log below") 87 | try: 88 | error_log = p.before.decode() 89 | except UnicodeDecodeError: 90 | error_log = p.before 91 | logging.error("Process output before timeout:\n %s", error_log) 92 | p.close() 93 | print("Exit Status = " + str(p.exitstatus)) 94 | print("Signal Status = " + str(p.signalstatus)) 95 | return result 96 | 97 | 98 | def prepare_test_console(esp_path: str) -> bool: 99 | """ 100 | Prepares ESP folder with TestConsole application 101 | 102 | :param esp_path: The path points to ESP folder 103 | :return the boolean result: 104 | """ 105 | if not os.path.exists(esp_path): 106 | # Unpack TestConsole 107 | print("Preparing ESP with TestConsole") 108 | try: 109 | with zipfile.ZipFile(f'{OCBUILD_PATH}/external/TestConsole.zip', 'r') as zip_ref: 110 | zip_ref.extractall(esp_path) 111 | except Exception as e: 112 | logging.error("%s", e) 113 | return False 114 | return True 115 | 116 | 117 | def prepare_test_linux_image(esp_path: str) -> bool: 118 | """ 119 | Prepares ESP folder with tiny linux kernel with efistub and W^X patches 120 | It prints Hello World and gives simple shell /bin/sh 121 | 122 | :param esp_path: The path points to ESP folder 123 | :return the boolean result: 124 | """ 125 | if not os.path.exists(esp_path): 126 | # Unpack TestLinux 127 | print("Preparing ESP with TestLinux") 128 | try: 129 | with zipfile.ZipFile(f'{OCBUILD_PATH}/external/TestLinux.zip', 'r') as zip_ref: 130 | zip_ref.extractall(esp_path) 131 | except Exception as e: 132 | logging.error("%s", e) 133 | return False 134 | return True 135 | 136 | 137 | def parse_fw_arch(fw_arch: str) -> str: 138 | if fw_arch in ['i386', 'x86', 'IA32', 'Ia32', 'X64', 'x64', 'x86_64', 'X86', '3264']: 139 | return 'x86' 140 | if fw_arch in ['arm', 'arm32', 'aarch32', 'AARCH32', 'ARM']: 141 | return 'arm' 142 | if fw_arch in ['AARCH64', 'aarch64', 'arm64', 'ARM64', 'AA64', 'aa64']: 143 | return 'arm64' 144 | return "Unknown" 145 | 146 | 147 | def main(): 148 | """ The QEMU-based firmware checker """ 149 | parser = argparse.ArgumentParser(description='Run QEMU and determine whether firmware can start bootloader.') 150 | parser.add_argument('fw_path', type=str, help='Path to firmware.') 151 | parser.add_argument('--no-rdrand', dest='rdrand', action='store_false') 152 | parser.add_argument('--test-console-path', dest='user_testconsole_path', action='store') 153 | parser.add_argument('--test-linux-path', dest='user_testlinux_path', action='store') 154 | parser.add_argument('--test-linux', dest='test_linux', action='store_true') 155 | parser.add_argument('--test-winpe-path', dest='user_testwinpe_path', action='store') 156 | parser.add_argument('--test-winpe', dest='test_winpe', action='store_true') 157 | parser.add_argument('--fw-arch', dest='fw_arch', action='store') 158 | parser.set_defaults(rdrand=True) 159 | parser.set_defaults(test_linux=False) 160 | parser.set_defaults(test_winpe=False) 161 | parser.set_defaults(fw_arch="x86") 162 | pexpect_timeout = 60 # default 30 163 | testconsole_path = TESTCONSOLE_PATH 164 | testlinux_path = TEST_LINUX_PATH 165 | testwinpe_path = TEST_WINPE_PATH 166 | 167 | args = parser.parse_args() 168 | logging.basicConfig( 169 | format="%(asctime)-15s [%(levelname)s] %(funcName)s: %(message)s", 170 | level=logging.INFO) 171 | 172 | if not args.test_linux and args.user_testlinux_path: 173 | parser.error("--test-linux-path requires --test-linux") 174 | 175 | if args.test_linux and args.test_winpe: 176 | parser.error("you can't specify both --test-linux and --test-winpe simultaneously") 177 | 178 | if args.user_testlinux_path is not None: 179 | testlinux_path = args.user_testlinux_path 180 | elif args.user_testconsole_path is not None: 181 | testconsole_path = args.user_testconsole_path 182 | elif args.user_testwinpe_path is not None: 183 | testwinpe_path = args.user_testwinpe_path 184 | 185 | # Use a temporary directory for the ESP to combat NvVars mixing and QEMU 186 | # host directory corruption. 187 | with tempfile.TemporaryDirectory() as temp_dir: 188 | esp_dir = os.path.join(temp_dir, 'ESP') 189 | boot_drive = '-drive format=raw,file=fat:rw:' + esp_dir 190 | if args.test_linux: 191 | if not prepare_test_linux_image(testlinux_path): 192 | sys.exit(1) 193 | shutil.copytree(testlinux_path, esp_dir) 194 | expected_string = 'Hello World!' 195 | pexpect_timeout = 180 196 | elif args.test_winpe: 197 | os.makedirs(esp_dir) 198 | boot_drive = ' -cdrom ' + testwinpe_path 199 | expected_string = 'EVENT: The CMD command is now available' 200 | pexpect_timeout = 600 201 | else: 202 | if not prepare_test_console(testconsole_path): 203 | sys.exit(1) 204 | shutil.copytree(testconsole_path, esp_dir) 205 | expected_string = 'GPT entry is not accessible' 206 | print("Testing ...") 207 | if test_firmware(args, boot_drive, expected_string, pexpect_timeout): 208 | sys.exit(0) 209 | else: 210 | sys.exit(1) 211 | 212 | 213 | if __name__ == '__main__': 214 | main() 215 | -------------------------------------------------------------------------------- /tinylinux/patches/linux/v5.10.179/0001-x86-boot-Align-vmlinuz-sections-on-page-size.patch: -------------------------------------------------------------------------------- 1 | From 586c4dbd7dc88f7e147f7140b142d188e5c2347b Mon Sep 17 00:00:00 2001 2 | Message-Id: <> 3 | In-Reply-To: <> 4 | References: <> 5 | From: Evgeniy Baskov <> 6 | Date: Thu, 11 May 2023 13:49:20 +0300 7 | Subject: [PATCH 01/39] x86/boot: Align vmlinuz sections on page size 8 | 9 | To protect sections on page table level each section needs to be 10 | aligned on page size (4KB). 11 | 12 | Set sections alignment in linker script for the kernel decompressor 13 | (boot/compressed/vmlinux.lds.S). 14 | 15 | Signed-off-by: Evgeniy Baskov <> 16 | --- 17 | arch/x86/boot/compressed/vmlinux.lds.S | 15 ++++++++------- 18 | 1 file changed, 8 insertions(+), 7 deletions(-) 19 | 20 | diff --git a/arch/x86/boot/compressed/vmlinux.lds.S b/arch/x86/boot/compressed/vmlinux.lds.S 21 | index 112b2375d021..361de34cfc5c 100644 22 | --- a/arch/x86/boot/compressed/vmlinux.lds.S 23 | +++ b/arch/x86/boot/compressed/vmlinux.lds.S 24 | @@ -27,22 +27,24 @@ SECTIONS 25 | HEAD_TEXT 26 | _ehead = . ; 27 | } 28 | - .rodata..compressed : { 29 | + .rodata..compressed : ALIGN(PAGE_SIZE) { 30 | + _compressed = .; 31 | *(.rodata..compressed) 32 | + _ecompressed = .; 33 | } 34 | - .text : { 35 | + .text : ALIGN(PAGE_SIZE) { 36 | _text = .; /* Text */ 37 | *(.text) 38 | *(.text.*) 39 | _etext = . ; 40 | } 41 | - .rodata : { 42 | + .rodata : ALIGN(PAGE_SIZE) { 43 | _rodata = . ; 44 | *(.rodata) /* read-only data */ 45 | *(.rodata.*) 46 | _erodata = . ; 47 | } 48 | - .data : { 49 | + .data : ALIGN(PAGE_SIZE) { 50 | _data = . ; 51 | *(.data) 52 | *(.data.*) 53 | @@ -50,7 +52,7 @@ SECTIONS 54 | _edata = . ; 55 | } 56 | . = ALIGN(L1_CACHE_BYTES); 57 | - .bss : { 58 | + .bss : ALIGN(PAGE_SIZE) { 59 | _bss = . ; 60 | *(.bss) 61 | *(.bss.*) 62 | @@ -59,8 +61,7 @@ SECTIONS 63 | _ebss = .; 64 | } 65 | #ifdef CONFIG_X86_64 66 | - . = ALIGN(PAGE_SIZE); 67 | - .pgtable : { 68 | + .pgtable : ALIGN(PAGE_SIZE) { 69 | _pgtable = . ; 70 | *(.pgtable) 71 | _epgtable = . ; 72 | -- 73 | 2.40.1 74 | 75 | -------------------------------------------------------------------------------- /tinylinux/patches/linux/v5.10.179/0002-x86-build-Remove-RWX-sections-and-align-on-4KB.patch: -------------------------------------------------------------------------------- 1 | From 20435163b523a34bcc411f054d7038166f3a9764 Mon Sep 17 00:00:00 2001 2 | Message-Id: <> 3 | In-Reply-To: <> 4 | References: <> 5 | From: Evgeniy Baskov <> 6 | Date: Thu, 11 May 2023 13:51:49 +0300 7 | Subject: [PATCH 02/39] x86/build: Remove RWX sections and align on 4KB 8 | 9 | Avoid creating sections simultaneously writable and readable to prepare 10 | for W^X implementation for the kernel itself (not the decompressor). 11 | Align kernel sections on page size (4KB) to allow protecting them in the 12 | page tables. 13 | 14 | Split init code form ".init" segment into separate R_X ".inittext" 15 | segment and make ".init" segment non-executable. 16 | 17 | Also add these segments to x86_32 architecture for consistency. 18 | Currently paging is disabled in x86_32 in compressed kernel, so 19 | protection is not applied anyways, but .init code was incorrectly 20 | placed in non-executable ".data" segment. This should not change 21 | anything meaningful in memory layout now, but might be required in case 22 | memory protection will also be implemented in compressed kernel for 23 | x86_32. 24 | 25 | Signed-off-by: Evgeniy Baskov <> 26 | --- 27 | arch/x86/kernel/vmlinux.lds.S | 15 ++++++++------- 28 | 1 file changed, 8 insertions(+), 7 deletions(-) 29 | 30 | diff --git a/arch/x86/kernel/vmlinux.lds.S b/arch/x86/kernel/vmlinux.lds.S 31 | index a21cd2381fa8..9efeff45716f 100644 32 | --- a/arch/x86/kernel/vmlinux.lds.S 33 | +++ b/arch/x86/kernel/vmlinux.lds.S 34 | @@ -102,12 +102,11 @@ jiffies = jiffies_64; 35 | PHDRS { 36 | text PT_LOAD FLAGS(5); /* R_E */ 37 | data PT_LOAD FLAGS(6); /* RW_ */ 38 | -#ifdef CONFIG_X86_64 39 | -#ifdef CONFIG_SMP 40 | +#if defined(CONFIG_X86_64) && defined(CONFIG_SMP) 41 | percpu PT_LOAD FLAGS(6); /* RW_ */ 42 | #endif 43 | - init PT_LOAD FLAGS(7); /* RWE */ 44 | -#endif 45 | + inittext PT_LOAD FLAGS(5); /* R_E */ 46 | + init PT_LOAD FLAGS(6); /* RW_ */ 47 | note PT_NOTE FLAGS(0); /* ___ */ 48 | } 49 | 50 | @@ -227,9 +226,10 @@ SECTIONS 51 | #endif 52 | 53 | INIT_TEXT_SECTION(PAGE_SIZE) 54 | -#ifdef CONFIG_X86_64 55 | - :init 56 | -#endif 57 | + :inittext 58 | + 59 | + . = ALIGN(PAGE_SIZE); 60 | + 61 | 62 | /* 63 | * Section for code used exclusively before alternatives are run. All 64 | @@ -241,6 +241,7 @@ SECTIONS 65 | .altinstr_aux : AT(ADDR(.altinstr_aux) - LOAD_OFFSET) { 66 | *(.altinstr_aux) 67 | } 68 | + :init 69 | 70 | INIT_DATA_SECTION(16) 71 | 72 | -- 73 | 2.40.1 74 | 75 | -------------------------------------------------------------------------------- /tinylinux/patches/linux/v5.10.179/0003-x86-boot-Set-cr0-to-known-state-in-trampoline.patch: -------------------------------------------------------------------------------- 1 | From fd5da421008bbbbaf41a5865a2a1c48f02a6e5f0 Mon Sep 17 00:00:00 2001 2 | Message-Id: <> 3 | In-Reply-To: <> 4 | References: <> 5 | From: Evgeniy Baskov <> 6 | Date: Thu, 11 May 2023 13:54:47 +0300 7 | Subject: [PATCH 03/39] x86/boot: Set cr0 to known state in trampoline 8 | 9 | Ensure WP bit to be set to prevent boot code from writing to 10 | non-writable memory pages. 11 | 12 | Signed-off-by: Evgeniy Baskov <> 13 | --- 14 | arch/x86/boot/compressed/head_64.S | 4 ++-- 15 | 1 file changed, 2 insertions(+), 2 deletions(-) 16 | 17 | diff --git a/arch/x86/boot/compressed/head_64.S b/arch/x86/boot/compressed/head_64.S 18 | index b55e2007b30c..e04ba0790301 100644 19 | --- a/arch/x86/boot/compressed/head_64.S 20 | +++ b/arch/x86/boot/compressed/head_64.S 21 | @@ -648,8 +648,8 @@ SYM_CODE_START(trampoline_32bit_src) 22 | pushl $__KERNEL_CS 23 | pushl %eax 24 | 25 | - /* Enable paging again */ 26 | - movl $(X86_CR0_PG | X86_CR0_PE), %eax 27 | + /* Enable paging and set CR0 to known state (this also sets WP flag) */ 28 | + movl $CR0_STATE, %eax 29 | movl %eax, %cr0 30 | 31 | lret 32 | -- 33 | 2.40.1 34 | 35 | -------------------------------------------------------------------------------- /tinylinux/patches/linux/v5.10.179/0004-x86-boot-Increase-boot-page-table-size.patch: -------------------------------------------------------------------------------- 1 | From af8f05acd689785e782ea093a926d48c680dda17 Mon Sep 17 00:00:00 2001 2 | Message-Id: <> 3 | In-Reply-To: <> 4 | References: <> 5 | From: Evgeniy Baskov <> 6 | Date: Thu, 9 Jun 2022 18:18:32 +0300 7 | Subject: [PATCH 04/39] x86/boot: Increase boot page table size 8 | 9 | Previous upper limit ignored pages implicitly mapped from #PF handler 10 | by code accessing ACPI tables (boot/compressed/{acpi.c,efi.c}), 11 | so theoretical upper limit is higher than it was set. 12 | 13 | Using 4KB pages is desirable for better memory protection granularity. 14 | Approximately twice as much memory is required for those. 15 | 16 | Increase initial page table size to 64 4KB page tables. 17 | 18 | Tested-by: Mario Limonciello <> 19 | Signed-off-by: Evgeniy Baskov <> 20 | --- 21 | arch/x86/include/asm/boot.h | 28 ++++++++++++++++------------ 22 | 1 file changed, 16 insertions(+), 12 deletions(-) 23 | 24 | diff --git a/arch/x86/include/asm/boot.h b/arch/x86/include/asm/boot.h 25 | index 9191280d9ea3..88836067f88c 100644 26 | --- a/arch/x86/include/asm/boot.h 27 | +++ b/arch/x86/include/asm/boot.h 28 | @@ -41,22 +41,26 @@ 29 | # define BOOT_STACK_SIZE 0x4000 30 | 31 | # define BOOT_INIT_PGT_SIZE (6*4096) 32 | -# ifdef CONFIG_RANDOMIZE_BASE 33 | /* 34 | * Assuming all cross the 512GB boundary: 35 | * 1 page for level4 36 | - * (2+2)*4 pages for kernel, param, cmd_line, and randomized kernel 37 | - * 2 pages for first 2M (video RAM: CONFIG_X86_VERBOSE_BOOTUP). 38 | - * Total is 19 pages. 39 | + * (3+3)*2 pages for param and cmd_line 40 | + * (2+2+S)*2 pages for kernel and randomized kernel, where S is total number 41 | + * of sections of kernel. Explanation: 2+2 are upper level page tables. 42 | + * We can have only S unaligned parts of section: 1 at the end of the kernel 43 | + * and (S-1) at the section borders. The start address of the kernel is 44 | + * aligned, so an extra page table. There are at most S=6 sections in 45 | + * vmlinux ELF image. 46 | + * 3 pages for first 2M (video RAM: CONFIG_X86_VERBOSE_BOOTUP). 47 | + * Total is 36 pages. 48 | + * 49 | + * Some number of page tables is also required for the ACPI and UEFI table 50 | + * mappings, so we round up 36 to 64. Since ACPI tables are generally getting 51 | + * allocated in a few contiguous regions of memory, they are very unlikely to be 52 | + * spread out enough to require more than 28 extra page tables and this 53 | + * would work fine in all more or less sane environments. 54 | */ 55 | -# ifdef CONFIG_X86_VERBOSE_BOOTUP 56 | -# define BOOT_PGT_SIZE (19*4096) 57 | -# else /* !CONFIG_X86_VERBOSE_BOOTUP */ 58 | -# define BOOT_PGT_SIZE (17*4096) 59 | -# endif 60 | -# else /* !CONFIG_RANDOMIZE_BASE */ 61 | -# define BOOT_PGT_SIZE BOOT_INIT_PGT_SIZE 62 | -# endif 63 | +# define BOOT_PGT_SIZE (64*4096) 64 | 65 | #else /* !CONFIG_X86_64 */ 66 | # define BOOT_STACK_SIZE 0x1000 67 | -- 68 | 2.40.1 69 | 70 | -------------------------------------------------------------------------------- /tinylinux/patches/linux/v5.10.179/0007-x86-build-Check-W-X-of-vmlinux-during-build.patch: -------------------------------------------------------------------------------- 1 | From 6a55ce14456c84d81a8960964cbc257374ffc245 Mon Sep 17 00:00:00 2001 2 | Message-Id: <> 3 | In-Reply-To: <> 4 | References: <> 5 | From: Evgeniy Baskov <> 6 | Date: Thu, 11 May 2023 16:28:49 +0300 7 | Subject: [PATCH 07/39] x86/build: Check W^X of vmlinux during build 8 | 9 | Check if there are simultaneously writable and executable 10 | program segments in vmlinux ELF image and fail build if there are any. 11 | 12 | This would prevent accidental introduction of RWX segments. 13 | 14 | Signed-off-by: Evgeniy Baskov <> 15 | --- 16 | arch/x86/boot/compressed/Makefile | 7 ++++++- 17 | 1 file changed, 6 insertions(+), 1 deletion(-) 18 | 19 | diff --git a/arch/x86/boot/compressed/Makefile b/arch/x86/boot/compressed/Makefile 20 | index ad268a15bc7b..e1af3fa8dcef 100644 21 | --- a/arch/x86/boot/compressed/Makefile 22 | +++ b/arch/x86/boot/compressed/Makefile 23 | @@ -109,9 +109,14 @@ efi-obj-$(CONFIG_EFI_STUB) = $(objtree)/drivers/firmware/efi/libstub/lib.a 24 | $(obj)/vmlinux: $(vmlinux-objs-y) $(efi-obj-y) FORCE 25 | $(call if_changed,ld) 26 | 27 | +quiet_cmd_objcopy_and_wx_check = $(quiet_cmd_objcopy) 28 | +cmd_objcopy_and_wx_check = if $(OBJDUMP) -p $< | grep "flags .wx" > /dev/null; then \ 29 | + (echo >&2 "$<: Simultaneously writable and executable sections are prohibited"; \ 30 | + /bin/false); else $(cmd_objcopy); fi 31 | + 32 | OBJCOPYFLAGS_vmlinux.bin := -R .comment -S 33 | $(obj)/vmlinux.bin: vmlinux FORCE 34 | - $(call if_changed,objcopy) 35 | + $(call if_changed,objcopy_and_wx_check) 36 | 37 | targets += $(patsubst $(obj)/%,%,$(vmlinux-objs-y)) vmlinux.bin.all vmlinux.relocs 38 | 39 | -- 40 | 2.40.1 41 | 42 | -------------------------------------------------------------------------------- /tinylinux/patches/linux/v5.10.179/0008-x86-boot-Map-memory-explicitly.patch: -------------------------------------------------------------------------------- 1 | From 1e723d25828029742491fba545cba7c81648930b Mon Sep 17 00:00:00 2001 2 | Message-Id: <> 3 | In-Reply-To: <> 4 | References: <> 5 | From: Evgeniy Baskov <> 6 | Date: Tue, 13 Dec 2022 13:02:28 +0300 7 | Subject: [PATCH 08/39] x86/boot: Map memory explicitly 8 | 9 | Implicit mappings hide possible memory errors, e.g. allocations for 10 | ACPI tables were not included in boot page table size. 11 | 12 | Replace all implicit mappings from page fault handler with 13 | explicit mappings. 14 | 15 | Tested-by: Mario Limonciello <> 16 | Signed-off-by: Evgeniy Baskov <> 17 | --- 18 | arch/x86/boot/compressed/acpi.c | 39 +++++++++++++++++++++++++++++++- 19 | arch/x86/boot/compressed/kaslr.c | 2 ++ 20 | 2 files changed, 40 insertions(+), 1 deletion(-) 21 | 22 | diff --git a/arch/x86/boot/compressed/acpi.c b/arch/x86/boot/compressed/acpi.c 23 | index 8bcbcee54aa1..a2ff68455520 100644 24 | --- a/arch/x86/boot/compressed/acpi.c 25 | +++ b/arch/x86/boot/compressed/acpi.c 26 | @@ -33,6 +33,13 @@ __efi_get_rsdp_addr(unsigned long config_tables, unsigned int nr_tables, 27 | #ifdef CONFIG_EFI 28 | int i; 29 | 30 | + unsigned long ctab_len = efi_64 ? sizeof(efi_config_table_64_t) : 31 | + sizeof(efi_config_table_64_t); 32 | + 33 | + kernel_add_identity_map(config_tables, 34 | + config_tables + nr_tables*ctab_len, 0); 35 | + 36 | + 37 | /* Get EFI tables from systab. */ 38 | for (i = 0; i < nr_tables; i++) { 39 | acpi_physical_address table; 40 | @@ -110,6 +117,9 @@ static acpi_physical_address kexec_get_rsdp_addr(void) 41 | if (!systab) 42 | error("EFI system table not found in kexec boot_params."); 43 | 44 | + kernel_add_identity_map((unsigned long)systab, 45 | + (unsigned long)(systab + 1), 0); 46 | + 47 | return __efi_get_rsdp_addr((unsigned long)esd->tables, systab->nr_tables, true); 48 | } 49 | #else 50 | @@ -152,11 +162,15 @@ static acpi_physical_address efi_get_rsdp_addr(void) 51 | 52 | /* Handle EFI bitness properly */ 53 | if (efi_64) { 54 | + kernel_add_identity_map(systab, systab + sizeof(efi_config_table_64_t), 0); 55 | + 56 | efi_system_table_64_t *stbl = (efi_system_table_64_t *)systab; 57 | 58 | config_tables = stbl->tables; 59 | nr_tables = stbl->nr_tables; 60 | } else { 61 | + kernel_add_identity_map(systab, systab + sizeof(efi_config_table_32_t), 0); 62 | + 63 | efi_system_table_32_t *stbl = (efi_system_table_32_t *)systab; 64 | 65 | config_tables = stbl->tables; 66 | @@ -191,6 +205,8 @@ static u8 *scan_mem_for_rsdp(u8 *start, u32 length) 67 | 68 | end = start + length; 69 | 70 | + kernel_add_identity_map((unsigned long)start, (unsigned long)end, 0); 71 | + 72 | /* Search from given start address for the requested length */ 73 | for (address = start; address < end; address += ACPI_RSDP_SCAN_STEP) { 74 | /* 75 | @@ -226,6 +242,9 @@ static acpi_physical_address bios_get_rsdp_addr(void) 76 | unsigned long address; 77 | u8 *rsdp; 78 | 79 | + kernel_add_identity_map((unsigned long)ACPI_EBDA_PTR_LOCATION, 80 | + (unsigned long)ACPI_EBDA_PTR_LOCATION + 2, 0); 81 | + 82 | /* Get the location of the Extended BIOS Data Area (EBDA) */ 83 | address = *(u16 *)ACPI_EBDA_PTR_LOCATION; 84 | address <<= 4; 85 | @@ -321,6 +340,9 @@ static unsigned long get_acpi_srat_table(void) 86 | if (!rsdp) 87 | return 0; 88 | 89 | + kernel_add_identity_map((unsigned long)rsdp, 90 | + (unsigned long)(rsdp + 1), 0); 91 | + 92 | /* Get ACPI root table from RSDP.*/ 93 | if (!(cmdline_find_option("acpi", arg, sizeof(arg)) == 4 && 94 | !strncmp(arg, "rsdt", 4)) && 95 | @@ -337,10 +359,17 @@ static unsigned long get_acpi_srat_table(void) 96 | return 0; 97 | 98 | header = (struct acpi_table_header *)root_table; 99 | + 100 | + kernel_add_identity_map((unsigned long)header, 101 | + (unsigned long)(header + 1), 0); 102 | + 103 | len = header->length; 104 | if (len < sizeof(struct acpi_table_header) + size) 105 | return 0; 106 | 107 | + kernel_add_identity_map((unsigned long)header, 108 | + (unsigned long)header + len, 0); 109 | + 110 | num_entries = (len - sizeof(struct acpi_table_header)) / size; 111 | entry = (u8 *)(root_table + sizeof(struct acpi_table_header)); 112 | 113 | @@ -353,8 +382,16 @@ static unsigned long get_acpi_srat_table(void) 114 | if (acpi_table) { 115 | header = (struct acpi_table_header *)acpi_table; 116 | 117 | - if (ACPI_COMPARE_NAMESEG(header->signature, ACPI_SIG_SRAT)) 118 | + kernel_add_identity_map(acpi_table, 119 | + acpi_table + sizeof(*header), 120 | + 0); 121 | + 122 | + if (ACPI_COMPARE_NAMESEG(header->signature, ACPI_SIG_SRAT)) { 123 | + kernel_add_identity_map(acpi_table, 124 | + acpi_table + header->length, 125 | + 0); 126 | return acpi_table; 127 | + } 128 | } 129 | entry += size; 130 | } 131 | diff --git a/arch/x86/boot/compressed/kaslr.c b/arch/x86/boot/compressed/kaslr.c 132 | index b92fffbe761f..12a0bac89fab 100644 133 | --- a/arch/x86/boot/compressed/kaslr.c 134 | +++ b/arch/x86/boot/compressed/kaslr.c 135 | @@ -708,6 +708,8 @@ process_efi_entries(unsigned long minimum, unsigned long image_size) 136 | pmap = (e->efi_memmap | ((__u64)e->efi_memmap_hi << 32)); 137 | #endif 138 | 139 | + kernel_add_identity_map(pmap, pmap + e->efi_memmap_size, 0); 140 | + 141 | nr_desc = e->efi_memmap_size / e->efi_memdesc_size; 142 | for (i = 0; i < nr_desc; i++) { 143 | md = efi_early_memdesc_ptr(pmap, e->efi_memdesc_size, i); 144 | -- 145 | 2.40.1 146 | 147 | -------------------------------------------------------------------------------- /tinylinux/patches/linux/v5.10.179/0009-x86-boot-Remove-mapping-from-page-fault-handler.patch: -------------------------------------------------------------------------------- 1 | From 279b64a8f13c8d78439a2a1c37088eb2cb205213 Mon Sep 17 00:00:00 2001 2 | Message-Id: <> 3 | In-Reply-To: <> 4 | References: <> 5 | From: Evgeniy Baskov <> 6 | Date: Thu, 9 Jun 2022 19:35:18 +0300 7 | Subject: [PATCH 09/39] x86/boot: Remove mapping from page fault handler 8 | 9 | After every implicit mapping is removed, this code is no longer needed. 10 | 11 | Remove memory mapping from page fault handler to ensure that there are 12 | no hidden invalid memory accesses. 13 | 14 | Tested-by: Mario Limonciello <> 15 | Signed-off-by: Evgeniy Baskov <> 16 | --- 17 | arch/x86/boot/compressed/ident_map_64.c | 26 ++++++++++--------------- 18 | 1 file changed, 10 insertions(+), 16 deletions(-) 19 | 20 | diff --git a/arch/x86/boot/compressed/ident_map_64.c b/arch/x86/boot/compressed/ident_map_64.c 21 | index 547a6503bb5c..8a3e6b8d822e 100644 22 | --- a/arch/x86/boot/compressed/ident_map_64.c 23 | +++ b/arch/x86/boot/compressed/ident_map_64.c 24 | @@ -381,27 +381,21 @@ void do_boot_page_fault(struct pt_regs *regs, unsigned long error_code) 25 | { 26 | unsigned long address = native_read_cr2(); 27 | unsigned long end; 28 | - bool ghcb_fault; 29 | + char *msg; 30 | 31 | - ghcb_fault = sev_es_check_ghcb_fault(address); 32 | + if (sev_es_check_ghcb_fault(address)) 33 | + msg = "Page-fault on GHCB page:"; 34 | + else 35 | + msg = "Unexpected page-fault:"; 36 | 37 | address &= PMD_MASK; 38 | end = address + PMD_SIZE; 39 | 40 | /* 41 | - * Check for unexpected error codes. Unexpected are: 42 | - * - Faults on present pages 43 | - * - User faults 44 | - * - Reserved bits set 45 | - */ 46 | - if (error_code & (X86_PF_PROT | X86_PF_USER | X86_PF_RSVD)) 47 | - do_pf_error("Unexpected page-fault:", error_code, address, regs->ip); 48 | - else if (ghcb_fault) 49 | - do_pf_error("Page-fault on GHCB page:", error_code, address, regs->ip); 50 | - 51 | - /* 52 | - * Error code is sane - now identity map the 2M region around 53 | - * the faulting address. 54 | + * Since all memory allocations are made explicit 55 | + * now, every page fault at this stage is an 56 | + * error and the error handler is there only 57 | + * for debug purposes. 58 | */ 59 | - kernel_add_identity_map(address, end, MAP_WRITE); 60 | + do_pf_error(msg, error_code, address, regs->ip); 61 | } 62 | -- 63 | 2.40.1 64 | 65 | -------------------------------------------------------------------------------- /tinylinux/patches/linux/v5.10.179/0010-efi-libstub-x86-mixed-increase-supported-argument-co.patch: -------------------------------------------------------------------------------- 1 | From 5c034b13f0504d745e0052a350c401e47cef3a7d Mon Sep 17 00:00:00 2001 2 | Message-Id: <> 3 | In-Reply-To: <> 4 | References: <> 5 | From: Ard Biesheuvel <> 6 | Date: Fri, 19 Nov 2021 13:47:43 +0200 7 | Subject: [PATCH 10/39] efi/libstub: x86/mixed: increase supported argument 8 | count 9 | 10 | Increase the number of arguments supported by mixed mode calls, so that 11 | we will be able to call into the TCG2 protocol to measure the initrd 12 | and extend the associated PCR. This involves the TCG2 protocol's 13 | hash_log_extend_event() method, which takes five arguments, three of 14 | which are u64 and need to be split, producing a total of 8 outgoing 15 | 16 | Signed-off-by: Ard Biesheuvel <> 17 | Signed-off-by: Ilias Apalodimas <> 18 | Link: https://lore.kernel.org/r/ 19 | Signed-off-by: Ard Biesheuvel <> 20 | --- 21 | arch/x86/boot/compressed/efi_thunk_64.S | 14 +++++++++++--- 22 | arch/x86/include/asm/efi.h | 10 ++++++---- 23 | arch/x86/platform/efi/efi_thunk_64.S | 14 ++++++++++++-- 24 | 3 files changed, 29 insertions(+), 9 deletions(-) 25 | 26 | diff --git a/arch/x86/boot/compressed/efi_thunk_64.S b/arch/x86/boot/compressed/efi_thunk_64.S 27 | index c8052a141b08..3cd3d4610bf1 100644 28 | --- a/arch/x86/boot/compressed/efi_thunk_64.S 29 | +++ b/arch/x86/boot/compressed/efi_thunk_64.S 30 | @@ -27,8 +27,6 @@ SYM_FUNC_START(__efi64_thunk) 31 | push %rbp 32 | push %rbx 33 | 34 | - leaq 1f(%rip), %rbp 35 | - 36 | movl %ds, %eax 37 | push %rax 38 | movl %es, %eax 39 | @@ -36,6 +34,11 @@ SYM_FUNC_START(__efi64_thunk) 40 | movl %ss, %eax 41 | push %rax 42 | 43 | + /* Copy args passed on stack */ 44 | + movq 0x30(%rsp), %rbp 45 | + movq 0x38(%rsp), %rbx 46 | + movq 0x40(%rsp), %rax 47 | + 48 | /* 49 | * Convert x86-64 ABI params to i386 ABI 50 | */ 51 | @@ -45,10 +48,15 @@ SYM_FUNC_START(__efi64_thunk) 52 | movl %ecx, 0x8(%rsp) 53 | movl %r8d, 0xc(%rsp) 54 | movl %r9d, 0x10(%rsp) 55 | + movl %ebp, 0x14(%rsp) 56 | + movl %ebx, 0x18(%rsp) 57 | + movl %eax, 0x1c(%rsp) 58 | 59 | - leaq 0x14(%rsp), %rbx 60 | + leaq 0x20(%rsp), %rbx 61 | sgdt (%rbx) 62 | 63 | + leaq 1f(%rip), %rbp 64 | + 65 | /* 66 | * Switch to gdt with 32-bit segments. This is the firmware GDT 67 | * that was installed when the kernel started executing. This 68 | diff --git a/arch/x86/include/asm/efi.h b/arch/x86/include/asm/efi.h 69 | index bc9758ef292e..89d68a6e15c8 100644 70 | --- a/arch/x86/include/asm/efi.h 71 | +++ b/arch/x86/include/asm/efi.h 72 | @@ -45,13 +45,14 @@ extern unsigned long efi_fw_vendor, efi_config_table; 73 | 74 | #define __efi_nargs(...) __efi_nargs_(__VA_ARGS__) 75 | #define __efi_nargs_(...) __efi_nargs__(0, ##__VA_ARGS__, \ 76 | + __efi_arg_sentinel(9), __efi_arg_sentinel(8), \ 77 | __efi_arg_sentinel(7), __efi_arg_sentinel(6), \ 78 | __efi_arg_sentinel(5), __efi_arg_sentinel(4), \ 79 | __efi_arg_sentinel(3), __efi_arg_sentinel(2), \ 80 | __efi_arg_sentinel(1), __efi_arg_sentinel(0)) 81 | -#define __efi_nargs__(_0, _1, _2, _3, _4, _5, _6, _7, n, ...) \ 82 | +#define __efi_nargs__(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, n, ...) \ 83 | __take_second_arg(n, \ 84 | - ({ BUILD_BUG_ON_MSG(1, "__efi_nargs limit exceeded"); 8; })) 85 | + ({ BUILD_BUG_ON_MSG(1, "__efi_nargs limit exceeded"); 10; })) 86 | #define __efi_arg_sentinel(n) , n 87 | 88 | /* 89 | @@ -168,8 +169,9 @@ extern u64 efi_setup; 90 | extern efi_status_t __efi64_thunk(u32, ...); 91 | 92 | #define efi64_thunk(...) ({ \ 93 | - __efi_nargs_check(efi64_thunk, 6, __VA_ARGS__); \ 94 | - __efi64_thunk(__VA_ARGS__); \ 95 | + u64 __pad[3]; /* must have space for 3 args on the stack */ \ 96 | + __efi_nargs_check(efi64_thunk, 9, __VA_ARGS__); \ 97 | + __efi64_thunk(__VA_ARGS__, __pad); \ 98 | }) 99 | 100 | static inline bool efi_is_mixed(void) 101 | diff --git a/arch/x86/platform/efi/efi_thunk_64.S b/arch/x86/platform/efi/efi_thunk_64.S 102 | index 9eac088ef4de..d1bb7c0ecb52 100644 103 | --- a/arch/x86/platform/efi/efi_thunk_64.S 104 | +++ b/arch/x86/platform/efi/efi_thunk_64.S 105 | @@ -37,6 +37,17 @@ SYM_CODE_START(__efi64_thunk) 106 | movq efi_scratch(%rip), %rsp 107 | push %rax 108 | 109 | + /* 110 | + * Copy args passed via the stack 111 | + */ 112 | + subq $0x24, %rsp 113 | + movq 0x18(%rax), %rbp 114 | + movq 0x20(%rax), %rbx 115 | + movq 0x28(%rax), %rax 116 | + movl %ebp, 0x18(%rsp) 117 | + movl %ebx, 0x1c(%rsp) 118 | + movl %eax, 0x20(%rsp) 119 | + 120 | /* 121 | * Calculate the physical address of the kernel text. 122 | */ 123 | @@ -48,7 +59,6 @@ SYM_CODE_START(__efi64_thunk) 124 | subq %rax, %rbp 125 | subq %rax, %rbx 126 | 127 | - subq $28, %rsp 128 | movl %ebx, 0x0(%rsp) /* return address */ 129 | movl %esi, 0x4(%rsp) 130 | movl %edx, 0x8(%rsp) 131 | @@ -61,7 +71,7 @@ SYM_CODE_START(__efi64_thunk) 132 | pushq %rdi /* EFI runtime service address */ 133 | lretq 134 | 135 | -1: movq 24(%rsp), %rsp 136 | +1: movq 0x20(%rsp), %rsp 137 | pop %rbx 138 | pop %rbp 139 | ANNOTATE_UNRET_SAFE 140 | -- 141 | 2.40.1 142 | 143 | -------------------------------------------------------------------------------- /tinylinux/patches/linux/v5.10.179/0011-efi-libstub-declare-DXE-services-table.patch: -------------------------------------------------------------------------------- 1 | From 36638de250e13edd22f2250256a3cc8d063e390c Mon Sep 17 00:00:00 2001 2 | Message-Id: <> 3 | In-Reply-To: <> 4 | References: <> 5 | From: Baskov Evgeniy <> 6 | Date: Thu, 3 Mar 2022 17:21:19 +0300 7 | Subject: [PATCH 11/39] efi: libstub: declare DXE services table 8 | 9 | UEFI DXE services are not yet used in kernel code 10 | but are required to manipulate page table memory 11 | protection flags. 12 | 13 | Add required declarations to use DXE services functions. 14 | 15 | Signed-off-by: Baskov Evgeniy <> 16 | Link: https://lore.kernel.org/r/ 17 | [ardb: ignore absent DXE table but warn if the signature check fails] 18 | Signed-off-by: Ard Biesheuvel <> 19 | --- 20 | arch/x86/include/asm/efi.h | 5 ++ 21 | drivers/firmware/efi/libstub/efistub.h | 74 +++++++++++++++++++++++++ 22 | drivers/firmware/efi/libstub/x86-stub.c | 9 ++- 23 | include/linux/efi.h | 2 + 24 | 4 files changed, 89 insertions(+), 1 deletion(-) 25 | 26 | diff --git a/arch/x86/include/asm/efi.h b/arch/x86/include/asm/efi.h 27 | index 89d68a6e15c8..ab9cc21220ba 100644 28 | --- a/arch/x86/include/asm/efi.h 29 | +++ b/arch/x86/include/asm/efi.h 30 | @@ -344,6 +344,11 @@ static inline u32 efi64_convert_status(efi_status_t status) 31 | runtime), \ 32 | func, __VA_ARGS__)) 33 | 34 | +#define efi_dxe_call(func, ...) \ 35 | + (efi_is_native() \ 36 | + ? efi_dxe_table->func(__VA_ARGS__) \ 37 | + : __efi64_thunk_map(efi_dxe_table, func, __VA_ARGS__)) 38 | + 39 | #else /* CONFIG_EFI_MIXED */ 40 | 41 | static inline bool efi_is_64bit(void) 42 | diff --git a/drivers/firmware/efi/libstub/efistub.h b/drivers/firmware/efi/libstub/efistub.h 43 | index c5e0c6e99d20..d5bec95258cc 100644 44 | --- a/drivers/firmware/efi/libstub/efistub.h 45 | +++ b/drivers/firmware/efi/libstub/efistub.h 46 | @@ -37,6 +37,9 @@ extern bool efi_novamap; 47 | 48 | extern const efi_system_table_t *efi_system_table; 49 | 50 | +typedef union efi_dxe_services_table efi_dxe_services_table_t; 51 | +extern const efi_dxe_services_table_t *efi_dxe_table; 52 | + 53 | efi_status_t __efiapi efi_pe_entry(efi_handle_t handle, 54 | efi_system_table_t *sys_table_arg); 55 | 56 | @@ -45,6 +48,7 @@ efi_status_t __efiapi efi_pe_entry(efi_handle_t handle, 57 | #define efi_is_native() (true) 58 | #define efi_bs_call(func, ...) efi_system_table->boottime->func(__VA_ARGS__) 59 | #define efi_rt_call(func, ...) efi_system_table->runtime->func(__VA_ARGS__) 60 | +#define efi_dxe_call(func, ...) efi_dxe_table->func(__VA_ARGS__) 61 | #define efi_table_attr(inst, attr) (inst->attr) 62 | #define efi_call_proto(inst, func, ...) inst->func(inst, ##__VA_ARGS__) 63 | 64 | @@ -330,6 +334,76 @@ union efi_boot_services { 65 | } mixed_mode; 66 | }; 67 | 68 | +typedef enum { 69 | + EfiGcdMemoryTypeNonExistent, 70 | + EfiGcdMemoryTypeReserved, 71 | + EfiGcdMemoryTypeSystemMemory, 72 | + EfiGcdMemoryTypeMemoryMappedIo, 73 | + EfiGcdMemoryTypePersistent, 74 | + EfiGcdMemoryTypeMoreReliable, 75 | + EfiGcdMemoryTypeMaximum 76 | +} efi_gcd_memory_type_t; 77 | + 78 | +typedef struct { 79 | + efi_physical_addr_t base_address; 80 | + u64 length; 81 | + u64 capabilities; 82 | + u64 attributes; 83 | + efi_gcd_memory_type_t gcd_memory_type; 84 | + void *image_handle; 85 | + void *device_handle; 86 | +} efi_gcd_memory_space_desc_t; 87 | + 88 | +/* 89 | + * EFI DXE Services table 90 | + */ 91 | +union efi_dxe_services_table { 92 | + struct { 93 | + efi_table_hdr_t hdr; 94 | + void *add_memory_space; 95 | + void *allocate_memory_space; 96 | + void *free_memory_space; 97 | + void *remove_memory_space; 98 | + efi_status_t (__efiapi *get_memory_space_descriptor)(efi_physical_addr_t, 99 | + efi_gcd_memory_space_desc_t *); 100 | + efi_status_t (__efiapi *set_memory_space_attributes)(efi_physical_addr_t, 101 | + u64, u64); 102 | + void *get_memory_space_map; 103 | + void *add_io_space; 104 | + void *allocate_io_space; 105 | + void *free_io_space; 106 | + void *remove_io_space; 107 | + void *get_io_space_descriptor; 108 | + void *get_io_space_map; 109 | + void *dispatch; 110 | + void *schedule; 111 | + void *trust; 112 | + void *process_firmware_volume; 113 | + void *set_memory_space_capabilities; 114 | + }; 115 | + struct { 116 | + efi_table_hdr_t hdr; 117 | + u32 add_memory_space; 118 | + u32 allocate_memory_space; 119 | + u32 free_memory_space; 120 | + u32 remove_memory_space; 121 | + u32 get_memory_space_descriptor; 122 | + u32 set_memory_space_attributes; 123 | + u32 get_memory_space_map; 124 | + u32 add_io_space; 125 | + u32 allocate_io_space; 126 | + u32 free_io_space; 127 | + u32 remove_io_space; 128 | + u32 get_io_space_descriptor; 129 | + u32 get_io_space_map; 130 | + u32 dispatch; 131 | + u32 schedule; 132 | + u32 trust; 133 | + u32 process_firmware_volume; 134 | + u32 set_memory_space_capabilities; 135 | + } mixed_mode; 136 | +}; 137 | + 138 | typedef union efi_uga_draw_protocol efi_uga_draw_protocol_t; 139 | 140 | union efi_uga_draw_protocol { 141 | diff --git a/drivers/firmware/efi/libstub/x86-stub.c b/drivers/firmware/efi/libstub/x86-stub.c 142 | index 5d0f1b1966fc..58740b3cefa2 100644 143 | --- a/drivers/firmware/efi/libstub/x86-stub.c 144 | +++ b/drivers/firmware/efi/libstub/x86-stub.c 145 | @@ -22,6 +22,7 @@ 146 | #define MAXMEM_X86_64_4LEVEL (1ull << 46) 147 | 148 | const efi_system_table_t *efi_system_table; 149 | +const efi_dxe_services_table_t *efi_dxe_table; 150 | extern u32 image_offset; 151 | static efi_loaded_image_t *image = NULL; 152 | 153 | @@ -683,11 +684,17 @@ unsigned long efi_main(efi_handle_t handle, 154 | efi_status_t status; 155 | 156 | efi_system_table = sys_table_arg; 157 | - 158 | /* Check if we were booted by the EFI firmware */ 159 | if (efi_system_table->hdr.signature != EFI_SYSTEM_TABLE_SIGNATURE) 160 | efi_exit(handle, EFI_INVALID_PARAMETER); 161 | 162 | + efi_dxe_table = get_efi_config_table(EFI_DXE_SERVICES_TABLE_GUID); 163 | + if (efi_dxe_table && 164 | + efi_dxe_table->hdr.signature != EFI_DXE_SERVICES_TABLE_SIGNATURE) { 165 | + efi_warn("Ignoring DXE services table: invalid signature\n"); 166 | + efi_dxe_table = NULL; 167 | + } 168 | + 169 | /* 170 | * If the kernel isn't already loaded at a suitable address, 171 | * relocate it. 172 | diff --git a/include/linux/efi.h b/include/linux/efi.h 173 | index 084990390420..f5bbc1979a64 100644 174 | --- a/include/linux/efi.h 175 | +++ b/include/linux/efi.h 176 | @@ -341,6 +341,7 @@ void efi_native_runtime_setup(void); 177 | #define EFI_LOAD_FILE_PROTOCOL_GUID EFI_GUID(0x56ec3091, 0x954c, 0x11d2, 0x8e, 0x3f, 0x00, 0xa0, 0xc9, 0x69, 0x72, 0x3b) 178 | #define EFI_LOAD_FILE2_PROTOCOL_GUID EFI_GUID(0x4006c0c1, 0xfcb3, 0x403e, 0x99, 0x6d, 0x4a, 0x6c, 0x87, 0x24, 0xe0, 0x6d) 179 | #define EFI_RT_PROPERTIES_TABLE_GUID EFI_GUID(0xeb66918a, 0x7eef, 0x402a, 0x84, 0x2e, 0x93, 0x1d, 0x21, 0xc3, 0x8a, 0xe9) 180 | +#define EFI_DXE_SERVICES_TABLE_GUID EFI_GUID(0x05ad34ba, 0x6f02, 0x4214, 0x95, 0x2e, 0x4d, 0xa0, 0x39, 0x8e, 0x2b, 0xb9) 181 | 182 | #define EFI_IMAGE_SECURITY_DATABASE_GUID EFI_GUID(0xd719b2cb, 0x3d3a, 0x4596, 0xa3, 0xbc, 0xda, 0xd0, 0x0e, 0x67, 0x65, 0x6f) 183 | #define EFI_SHIM_LOCK_GUID EFI_GUID(0x605dab50, 0xe046, 0x4300, 0xab, 0xb6, 0x3d, 0xd8, 0x10, 0xdd, 0x8b, 0x23) 184 | @@ -392,6 +393,7 @@ typedef struct { 185 | } efi_config_table_type_t; 186 | 187 | #define EFI_SYSTEM_TABLE_SIGNATURE ((u64)0x5453595320494249ULL) 188 | +#define EFI_DXE_SERVICES_TABLE_SIGNATURE ((u64)0x565245535f455844ULL) 189 | 190 | #define EFI_2_30_SYSTEM_TABLE_REVISION ((2 << 16) | (30)) 191 | #define EFI_2_20_SYSTEM_TABLE_REVISION ((2 << 16) | (20)) 192 | -- 193 | 2.40.1 194 | 195 | -------------------------------------------------------------------------------- /tinylinux/patches/linux/v5.10.179/0012-efi-libstub-ensure-allocated-memory-to-be-executable.patch: -------------------------------------------------------------------------------- 1 | From 9b598054d1a299bf90bbfbcb03813c9860bbccaf Mon Sep 17 00:00:00 2001 2 | Message-Id: <> 3 | In-Reply-To: <> 4 | References: <> 5 | From: Baskov Evgeniy <> 6 | Date: Thu, 3 Mar 2022 17:21:20 +0300 7 | Subject: [PATCH 12/39] efi: libstub: ensure allocated memory to be executable 8 | 9 | There are UEFI versions that restrict execution of memory regions, 10 | preventing the kernel from booting. Parts that needs to be executable 11 | are: 12 | 13 | * Area used for trampoline placement. 14 | * All memory regions that the kernel may be relocated before 15 | and during extraction. 16 | 17 | Use DXE services to ensure aforementioned address ranges 18 | to be executable. Only modify attributes that does not 19 | have appropriate attributes. 20 | 21 | Signed-off-by: Baskov Evgeniy <> 22 | Link: https://lore.kernel.org/r/ 23 | Signed-off-by: Ard Biesheuvel <> 24 | --- 25 | drivers/firmware/efi/Kconfig | 12 +++ 26 | drivers/firmware/efi/libstub/x86-stub.c | 110 +++++++++++++++++++++++- 27 | 2 files changed, 118 insertions(+), 4 deletions(-) 28 | 29 | diff --git a/drivers/firmware/efi/Kconfig b/drivers/firmware/efi/Kconfig 30 | index d9895491ff34..f1bfc493e573 100644 31 | --- a/drivers/firmware/efi/Kconfig 32 | +++ b/drivers/firmware/efi/Kconfig 33 | @@ -91,6 +91,18 @@ config EFI_SOFT_RESERVE 34 | 35 | If unsure, say Y. 36 | 37 | +config EFI_DXE_MEM_ATTRIBUTES 38 | + bool "Adjust memory attributes in EFISTUB" 39 | + depends on EFI && EFI_STUB && X86 40 | + default y 41 | + help 42 | + UEFI specification does not guarantee all memory to be 43 | + accessible for both write and execute as the kernel expects 44 | + it to be. 45 | + Use DXE services to check and alter memory protection 46 | + attributes during boot via EFISTUB to ensure that memory 47 | + ranges used by the kernel are writable and executable. 48 | + 49 | config EFI_PARAMS_FROM_FDT 50 | bool 51 | help 52 | diff --git a/drivers/firmware/efi/libstub/x86-stub.c b/drivers/firmware/efi/libstub/x86-stub.c 53 | index 58740b3cefa2..eda02f925cbf 100644 54 | --- a/drivers/firmware/efi/libstub/x86-stub.c 55 | +++ b/drivers/firmware/efi/libstub/x86-stub.c 56 | @@ -212,9 +212,110 @@ static void retrieve_apple_device_properties(struct boot_params *boot_params) 57 | } 58 | } 59 | 60 | +static void 61 | +adjust_memory_range_protection(unsigned long start, unsigned long size) 62 | +{ 63 | + efi_status_t status; 64 | + efi_gcd_memory_space_desc_t desc; 65 | + unsigned long end, next; 66 | + unsigned long rounded_start, rounded_end; 67 | + unsigned long unprotect_start, unprotect_size; 68 | + int has_system_memory = 0; 69 | + 70 | + if (efi_dxe_table == NULL) 71 | + return; 72 | + 73 | + rounded_start = rounddown(start, EFI_PAGE_SIZE); 74 | + rounded_end = roundup(start + size, EFI_PAGE_SIZE); 75 | + 76 | + /* 77 | + * Don't modify memory region attributes, they are 78 | + * already suitable, to lower the possibility to 79 | + * encounter firmware bugs. 80 | + */ 81 | + 82 | + for (end = start + size; start < end; start = next) { 83 | + 84 | + status = efi_dxe_call(get_memory_space_descriptor, start, &desc); 85 | + 86 | + if (status != EFI_SUCCESS) 87 | + return; 88 | + 89 | + next = desc.base_address + desc.length; 90 | + 91 | + /* 92 | + * Only system memory is suitable for trampoline/kernel image placement, 93 | + * so only this type of memory needs its attributes to be modified. 94 | + */ 95 | + 96 | + if (desc.gcd_memory_type != EfiGcdMemoryTypeSystemMemory || 97 | + (desc.attributes & (EFI_MEMORY_RO | EFI_MEMORY_XP)) == 0) 98 | + continue; 99 | + 100 | + unprotect_start = max(rounded_start, (unsigned long)desc.base_address); 101 | + unprotect_size = min(rounded_end, next) - unprotect_start; 102 | + 103 | + status = efi_dxe_call(set_memory_space_attributes, 104 | + unprotect_start, unprotect_size, 105 | + EFI_MEMORY_WB); 106 | + 107 | + if (status != EFI_SUCCESS) { 108 | + efi_warn("Unable to unprotect memory range [%08lx,%08lx]: %d\n", 109 | + unprotect_start, 110 | + unprotect_start + unprotect_size, 111 | + (int)status); 112 | + } 113 | + } 114 | +} 115 | + 116 | +/* 117 | + * Trampoline takes 2 pages and can be loaded in first megabyte of memory 118 | + * with its end placed between 128k and 640k where BIOS might start. 119 | + * (see arch/x86/boot/compressed/pgtable_64.c) 120 | + * 121 | + * We cannot find exact trampoline placement since memory map 122 | + * can be modified by UEFI, and it can alter the computed address. 123 | + */ 124 | + 125 | +#define TRAMPOLINE_PLACEMENT_BASE ((128 - 8)*1024) 126 | +#define TRAMPOLINE_PLACEMENT_SIZE (640*1024 - (128 - 8)*1024) 127 | + 128 | +void startup_32(struct boot_params *boot_params); 129 | + 130 | +static void 131 | +setup_memory_protection(unsigned long image_base, unsigned long image_size) 132 | +{ 133 | + /* 134 | + * Allow execution of possible trampoline used 135 | + * for switching between 4- and 5-level page tables 136 | + * and relocated kernel image. 137 | + */ 138 | + 139 | + adjust_memory_range_protection(TRAMPOLINE_PLACEMENT_BASE, 140 | + TRAMPOLINE_PLACEMENT_SIZE); 141 | + 142 | +#ifdef CONFIG_64BIT 143 | + if (image_base != (unsigned long)startup_32) 144 | + adjust_memory_range_protection(image_base, image_size); 145 | +#else 146 | + /* 147 | + * Clear protection flags on a whole range of possible 148 | + * addresses used for KASLR. We don't need to do that 149 | + * on x86_64, since KASLR/extraction is performed after 150 | + * dedicated identity page tables are built and we only 151 | + * need to remove possible protection on relocated image 152 | + * itself disregarding further relocations. 153 | + */ 154 | + adjust_memory_range_protection(LOAD_PHYSICAL_ADDR, 155 | + KERNEL_IMAGE_SIZE - LOAD_PHYSICAL_ADDR); 156 | +#endif 157 | +} 158 | + 159 | static const efi_char16_t apple[] = L"Apple"; 160 | 161 | -static void setup_quirks(struct boot_params *boot_params) 162 | +static void setup_quirks(struct boot_params *boot_params, 163 | + unsigned long image_base, 164 | + unsigned long image_size) 165 | { 166 | efi_char16_t *fw_vendor = (efi_char16_t *)(unsigned long) 167 | efi_table_attr(efi_system_table, fw_vendor); 168 | @@ -223,6 +324,9 @@ static void setup_quirks(struct boot_params *boot_params) 169 | if (IS_ENABLED(CONFIG_APPLE_PROPERTIES)) 170 | retrieve_apple_device_properties(boot_params); 171 | } 172 | + 173 | + if (IS_ENABLED(CONFIG_EFI_DXE_MEM_ATTRIBUTES)) 174 | + setup_memory_protection(image_base, image_size); 175 | } 176 | 177 | /* 178 | @@ -342,8 +446,6 @@ static void __noreturn efi_exit(efi_handle_t handle, efi_status_t status) 179 | asm("hlt"); 180 | } 181 | 182 | -void startup_32(struct boot_params *boot_params); 183 | - 184 | void __noreturn efi_stub_entry(efi_handle_t handle, 185 | efi_system_table_t *sys_table_arg, 186 | struct boot_params *boot_params); 187 | @@ -808,7 +910,7 @@ unsigned long efi_main(efi_handle_t handle, 188 | 189 | setup_efi_pci(boot_params); 190 | 191 | - setup_quirks(boot_params); 192 | + setup_quirks(boot_params, bzimage_addr, buffer_end - buffer_start); 193 | 194 | status = exit_boot(boot_params, handle); 195 | if (status != EFI_SUCCESS) { 196 | -- 197 | 2.40.1 198 | 199 | -------------------------------------------------------------------------------- /tinylinux/patches/linux/v5.10.179/0013-efi-x86-libstub-Make-DXE-calls-mixed-mode-safe.patch: -------------------------------------------------------------------------------- 1 | From 04f5627dde90ce94aa35bd2cecf852f505bbea3e Mon Sep 17 00:00:00 2001 2 | Message-Id: <> 3 | In-Reply-To: <> 4 | References: <> 5 | From: Ard Biesheuvel <> 6 | Date: Fri, 20 May 2022 12:07:58 +0200 7 | Subject: [PATCH 13/39] efi/x86: libstub: Make DXE calls mixed mode safe 8 | 9 | The newly added DXE calls use 64-bit quantities, which means we need to 10 | marshall them explicitly when running in mixed mode. Currently, we get 11 | away without it because we just bail when GetMemorySpaceDescriptor() 12 | fails, which is guaranteed to happen due to the function argument mixup. 13 | 14 | Let's fix this properly, though, by defining the macros that describe 15 | how to marshall the arguments. While at it, drop an incorrect cast on a 16 | status variable. 17 | 18 | Signed-off-by: Ard Biesheuvel <> 19 | --- 20 | arch/x86/include/asm/efi.h | 13 +++++++++++++ 21 | drivers/firmware/efi/libstub/x86-stub.c | 4 ++-- 22 | 2 files changed, 15 insertions(+), 2 deletions(-) 23 | 24 | diff --git a/arch/x86/include/asm/efi.h b/arch/x86/include/asm/efi.h 25 | index ab9cc21220ba..bb6cd09005bc 100644 26 | --- a/arch/x86/include/asm/efi.h 27 | +++ b/arch/x86/include/asm/efi.h 28 | @@ -261,6 +261,8 @@ static inline u32 efi64_convert_status(efi_status_t status) 29 | return (u32)(status | (u64)status >> 32); 30 | } 31 | 32 | +#define __efi64_split(val) (val) & U32_MAX, (u64)(val) >> 32 33 | + 34 | #define __efi64_argmap_free_pages(addr, size) \ 35 | ((addr), 0, (size)) 36 | 37 | @@ -304,6 +306,17 @@ static inline u32 efi64_convert_status(efi_status_t status) 38 | #define __efi64_argmap_query_mode(gop, mode, size, info) \ 39 | ((gop), (mode), efi64_zero_upper(size), efi64_zero_upper(info)) 40 | 41 | +/* TCG2 protocol */ 42 | +#define __efi64_argmap_hash_log_extend_event(prot, fl, addr, size, ev) \ 43 | + ((prot), (fl), 0ULL, (u64)(addr), 0ULL, (u64)(size), 0ULL, ev) 44 | + 45 | +/* DXE services */ 46 | +#define __efi64_argmap_get_memory_space_descriptor(phys, desc) \ 47 | + (__efi64_split(phys), (desc)) 48 | + 49 | +#define __efi64_argmap_set_memory_space_descriptor(phys, size, flags) \ 50 | + (__efi64_split(phys), __efi64_split(size), __efi64_split(flags)) 51 | + 52 | /* 53 | * The macros below handle the plumbing for the argument mapping. To add a 54 | * mapping for a specific EFI method, simply define a macro 55 | diff --git a/drivers/firmware/efi/libstub/x86-stub.c b/drivers/firmware/efi/libstub/x86-stub.c 56 | index eda02f925cbf..ff0fad3fc08d 100644 57 | --- a/drivers/firmware/efi/libstub/x86-stub.c 58 | +++ b/drivers/firmware/efi/libstub/x86-stub.c 59 | @@ -260,10 +260,10 @@ adjust_memory_range_protection(unsigned long start, unsigned long size) 60 | EFI_MEMORY_WB); 61 | 62 | if (status != EFI_SUCCESS) { 63 | - efi_warn("Unable to unprotect memory range [%08lx,%08lx]: %d\n", 64 | + efi_warn("Unable to unprotect memory range [%08lx,%08lx]: %lx\n", 65 | unprotect_start, 66 | unprotect_start + unprotect_size, 67 | - (int)status); 68 | + status); 69 | } 70 | } 71 | } 72 | -- 73 | 2.40.1 74 | 75 | -------------------------------------------------------------------------------- /tinylinux/patches/linux/v5.10.179/0014-efi-x86-Set-the-NX-compatibility-flag-in-the-PE-head.patch: -------------------------------------------------------------------------------- 1 | From 8686d73a9a675aa4dfe03419c7ed3a26365bc1ea Mon Sep 17 00:00:00 2001 2 | Message-Id: <> 3 | In-Reply-To: <> 4 | References: <> 5 | From: Peter Jones <> 6 | Date: Tue, 29 Mar 2022 14:47:43 -0400 7 | Subject: [PATCH 14/39] efi: x86: Set the NX-compatibility flag in the PE 8 | header 9 | 10 | Following Baskov Evgeniy's "Handle UEFI NX-restricted page tables" 11 | patches, it's safe to set this compatibility flag to let loaders know 12 | they don't need to make special accommodations for kernel to load if 13 | pre-boot NX is enabled. 14 | 15 | Signed-off-by: Peter Jones <> 16 | Link: https://lore.kernel.org/all// 17 | Signed-off-by: Ard Biesheuvel <> 18 | --- 19 | arch/x86/boot/header.S | 4 ++++ 20 | 1 file changed, 4 insertions(+) 21 | 22 | diff --git a/arch/x86/boot/header.S b/arch/x86/boot/header.S 23 | index 6dbd7e9f74c9..0352e4589efa 100644 24 | --- a/arch/x86/boot/header.S 25 | +++ b/arch/x86/boot/header.S 26 | @@ -163,7 +163,11 @@ extra_header_fields: 27 | .long 0x200 # SizeOfHeaders 28 | .long 0 # CheckSum 29 | .word IMAGE_SUBSYSTEM_EFI_APPLICATION # Subsystem (EFI application) 30 | +#ifdef CONFIG_DXE_MEM_ATTRIBUTES 31 | + .word IMAGE_DLL_CHARACTERISTICS_NX_COMPAT # DllCharacteristics 32 | +#else 33 | .word 0 # DllCharacteristics 34 | +#endif 35 | #ifdef CONFIG_X86_32 36 | .long 0 # SizeOfStackReserve 37 | .long 0 # SizeOfStackCommit 38 | -- 39 | 2.40.1 40 | 41 | -------------------------------------------------------------------------------- /tinylinux/patches/linux/v5.10.179/0015-efi-x86-libstub-Fix-typo-in-__efi64_argmap-name.patch: -------------------------------------------------------------------------------- 1 | From 508e17014705cb669f9bce65ff8ddc4a69622eaf Mon Sep 17 00:00:00 2001 2 | Message-Id: <> 3 | In-Reply-To: <> 4 | References: <> 5 | From: Evgeniy Baskov <> 6 | Date: Thu, 9 Jun 2022 14:37:30 +0300 7 | Subject: [PATCH 15/39] efi/x86: libstub: Fix typo in __efi64_argmap* name 8 | 9 | The actual name of the DXE services function used 10 | is set_memory_space_attributes(), not set_memory_space_descriptor(). 11 | 12 | Change EFI mixed mode helper macro name to match the function name. 13 | 14 | Fixes: 31f1a0edff78 ("efi/x86: libstub: Make DXE calls mixed mode safe") 15 | Signed-off-by: Evgeniy Baskov <> 16 | Signed-off-by: Ard Biesheuvel <> 17 | --- 18 | arch/x86/include/asm/efi.h | 2 +- 19 | 1 file changed, 1 insertion(+), 1 deletion(-) 20 | 21 | diff --git a/arch/x86/include/asm/efi.h b/arch/x86/include/asm/efi.h 22 | index bb6cd09005bc..6cae68a39ef2 100644 23 | --- a/arch/x86/include/asm/efi.h 24 | +++ b/arch/x86/include/asm/efi.h 25 | @@ -314,7 +314,7 @@ static inline u32 efi64_convert_status(efi_status_t status) 26 | #define __efi64_argmap_get_memory_space_descriptor(phys, desc) \ 27 | (__efi64_split(phys), (desc)) 28 | 29 | -#define __efi64_argmap_set_memory_space_descriptor(phys, size, flags) \ 30 | +#define __efi64_argmap_set_memory_space_attributes(phys, size, flags) \ 31 | (__efi64_split(phys), __efi64_split(size), __efi64_split(flags)) 32 | 33 | /* 34 | -- 35 | 2.40.1 36 | 37 | -------------------------------------------------------------------------------- /tinylinux/patches/linux/v5.10.179/0016-efi-libstub-Move-helper-function-to-related-file.patch: -------------------------------------------------------------------------------- 1 | From 4ce38206edb114c555b3fb45f314bb8fce5cab02 Mon Sep 17 00:00:00 2001 2 | Message-Id: <> 3 | In-Reply-To: <> 4 | References: <> 5 | From: Evgeniy Baskov <> 6 | Date: Thu, 11 May 2023 17:29:41 +0300 7 | Subject: [PATCH 16/39] efi/libstub: Move helper function to related file 8 | 9 | efi_adjust_memory_range_protection() can be useful outside x86-stub.c. 10 | 11 | Move it to mem.c, where memory related code resides and make it 12 | non-static. 13 | 14 | Change its behavior to disallow making memory regions readable and 15 | writable simultaneously. 16 | 17 | Signed-off-by: Evgeniy Baskov <> 18 | --- 19 | drivers/firmware/efi/libstub/efistub.h | 4 + 20 | drivers/firmware/efi/libstub/mem.c | 99 +++++++++++++++++++++++++ 21 | drivers/firmware/efi/libstub/x86-stub.c | 66 ++--------------- 22 | 3 files changed, 108 insertions(+), 61 deletions(-) 23 | 24 | diff --git a/drivers/firmware/efi/libstub/efistub.h b/drivers/firmware/efi/libstub/efistub.h 25 | index d5bec95258cc..08233aea572e 100644 26 | --- a/drivers/firmware/efi/libstub/efistub.h 27 | +++ b/drivers/firmware/efi/libstub/efistub.h 28 | @@ -877,6 +877,10 @@ efi_status_t efi_relocate_kernel(unsigned long *image_addr, 29 | unsigned long alignment, 30 | unsigned long min_addr); 31 | 32 | +efi_status_t efi_adjust_memory_range_protection(unsigned long start, 33 | + unsigned long size, 34 | + unsigned long attributes); 35 | + 36 | efi_status_t efi_parse_options(char const *cmdline); 37 | 38 | void efi_parse_option_graphics(char *option); 39 | diff --git a/drivers/firmware/efi/libstub/mem.c b/drivers/firmware/efi/libstub/mem.c 40 | index feef8d4be113..733782932fdb 100644 41 | --- a/drivers/firmware/efi/libstub/mem.c 42 | +++ b/drivers/firmware/efi/libstub/mem.c 43 | @@ -130,3 +130,102 @@ void efi_free(unsigned long size, unsigned long addr) 44 | nr_pages = round_up(size, EFI_ALLOC_ALIGN) / EFI_PAGE_SIZE; 45 | efi_bs_call(free_pages, addr, nr_pages); 46 | } 47 | + 48 | +/** 49 | + * efi_adjust_memory_range_protection() - change memory range protection attributes 50 | + * @start: memory range start address 51 | + * @size: memory range size 52 | + * 53 | + * Actual memory range for which memory attributes are modified is 54 | + * the smallest ranged with start address and size aligned to EFI_PAGE_SIZE 55 | + * that includes [start, start + size]. 56 | + * 57 | + * @return: status code 58 | + */ 59 | +efi_status_t efi_adjust_memory_range_protection(unsigned long start, 60 | + unsigned long size, 61 | + unsigned long attributes) 62 | +{ 63 | + efi_status_t status; 64 | + efi_gcd_memory_space_desc_t desc; 65 | + efi_physical_addr_t end, next; 66 | + efi_physical_addr_t rounded_start, rounded_end; 67 | + efi_physical_addr_t unprotect_start, unprotect_size; 68 | + 69 | + if (efi_dxe_table == NULL) 70 | + return EFI_UNSUPPORTED; 71 | + 72 | + /* 73 | + * This function should not be used to modify attributes 74 | + * other than writable/executable. 75 | + */ 76 | + 77 | + if ((attributes & ~(EFI_MEMORY_RO | EFI_MEMORY_XP)) != 0) 78 | + return EFI_INVALID_PARAMETER; 79 | + 80 | + rounded_start = rounddown(start, EFI_PAGE_SIZE); 81 | + rounded_end = roundup(start + size, EFI_PAGE_SIZE); 82 | + 83 | + /* 84 | + * Disallow simultaniously executable and writable memory 85 | + * to inforce W^X policy if direct extraction code is enabled. 86 | + */ 87 | + 88 | + if ((attributes & (EFI_MEMORY_RO | EFI_MEMORY_XP)) == 0) { 89 | + efi_warn("W^X violation at [%08lx,%08lx]\n", 90 | + (unsigned long)rounded_start, 91 | + (unsigned long)rounded_end); 92 | + } 93 | + 94 | + for (end = start + size; start < end; start = next) { 95 | + 96 | + status = efi_dxe_call(get_memory_space_descriptor, 97 | + start, &desc); 98 | + 99 | + if (status != EFI_SUCCESS) { 100 | + efi_warn("Unable to get memory descriptor at %lx\n", 101 | + (unsigned long)start); 102 | + return status; 103 | + } 104 | + 105 | + next = desc.base_address + desc.length; 106 | + 107 | + /* 108 | + * Only system memory is suitable for trampoline/kernel image 109 | + * placement, so only this type of memory needs its attributes 110 | + * to be modified. 111 | + */ 112 | + 113 | + if (desc.gcd_memory_type != EfiGcdMemoryTypeSystemMemory) { 114 | + efi_warn("Attempted to change protection of special memory range\n"); 115 | + return EFI_UNSUPPORTED; 116 | + } 117 | + 118 | + /* 119 | + * Don't modify memory region attributes, if they are already 120 | + * suitable, to lower the possibility to encounter firmware 121 | + * bugs. We do not apply XP/RO, only remove them. 122 | + */ 123 | + if ((desc.attributes & ~attributes) == 0) 124 | + continue; 125 | + 126 | + desc.attributes &= attributes | ~(EFI_MEMORY_RO | EFI_MEMORY_XP); 127 | + 128 | + unprotect_start = max(rounded_start, desc.base_address); 129 | + unprotect_size = min(rounded_end, next) - unprotect_start; 130 | + 131 | + status = efi_dxe_call(set_memory_space_attributes, 132 | + unprotect_start, unprotect_size, 133 | + desc.attributes); 134 | + 135 | + if (status != EFI_SUCCESS) { 136 | + efi_warn("Unable to unprotect memory range [%08lx,%08lx]: %lx\n", 137 | + (unsigned long)unprotect_start, 138 | + (unsigned long)(unprotect_start + unprotect_size), 139 | + status); 140 | + return status; 141 | + } 142 | + } 143 | + 144 | + return EFI_SUCCESS; 145 | +} 146 | diff --git a/drivers/firmware/efi/libstub/x86-stub.c b/drivers/firmware/efi/libstub/x86-stub.c 147 | index ff0fad3fc08d..f2c10e66f6d7 100644 148 | --- a/drivers/firmware/efi/libstub/x86-stub.c 149 | +++ b/drivers/firmware/efi/libstub/x86-stub.c 150 | @@ -212,62 +212,6 @@ static void retrieve_apple_device_properties(struct boot_params *boot_params) 151 | } 152 | } 153 | 154 | -static void 155 | -adjust_memory_range_protection(unsigned long start, unsigned long size) 156 | -{ 157 | - efi_status_t status; 158 | - efi_gcd_memory_space_desc_t desc; 159 | - unsigned long end, next; 160 | - unsigned long rounded_start, rounded_end; 161 | - unsigned long unprotect_start, unprotect_size; 162 | - int has_system_memory = 0; 163 | - 164 | - if (efi_dxe_table == NULL) 165 | - return; 166 | - 167 | - rounded_start = rounddown(start, EFI_PAGE_SIZE); 168 | - rounded_end = roundup(start + size, EFI_PAGE_SIZE); 169 | - 170 | - /* 171 | - * Don't modify memory region attributes, they are 172 | - * already suitable, to lower the possibility to 173 | - * encounter firmware bugs. 174 | - */ 175 | - 176 | - for (end = start + size; start < end; start = next) { 177 | - 178 | - status = efi_dxe_call(get_memory_space_descriptor, start, &desc); 179 | - 180 | - if (status != EFI_SUCCESS) 181 | - return; 182 | - 183 | - next = desc.base_address + desc.length; 184 | - 185 | - /* 186 | - * Only system memory is suitable for trampoline/kernel image placement, 187 | - * so only this type of memory needs its attributes to be modified. 188 | - */ 189 | - 190 | - if (desc.gcd_memory_type != EfiGcdMemoryTypeSystemMemory || 191 | - (desc.attributes & (EFI_MEMORY_RO | EFI_MEMORY_XP)) == 0) 192 | - continue; 193 | - 194 | - unprotect_start = max(rounded_start, (unsigned long)desc.base_address); 195 | - unprotect_size = min(rounded_end, next) - unprotect_start; 196 | - 197 | - status = efi_dxe_call(set_memory_space_attributes, 198 | - unprotect_start, unprotect_size, 199 | - EFI_MEMORY_WB); 200 | - 201 | - if (status != EFI_SUCCESS) { 202 | - efi_warn("Unable to unprotect memory range [%08lx,%08lx]: %lx\n", 203 | - unprotect_start, 204 | - unprotect_start + unprotect_size, 205 | - status); 206 | - } 207 | - } 208 | -} 209 | - 210 | /* 211 | * Trampoline takes 2 pages and can be loaded in first megabyte of memory 212 | * with its end placed between 128k and 640k where BIOS might start. 213 | @@ -291,12 +235,12 @@ setup_memory_protection(unsigned long image_base, unsigned long image_size) 214 | * and relocated kernel image. 215 | */ 216 | 217 | - adjust_memory_range_protection(TRAMPOLINE_PLACEMENT_BASE, 218 | - TRAMPOLINE_PLACEMENT_SIZE); 219 | + efi_adjust_memory_range_protection(TRAMPOLINE_PLACEMENT_BASE, 220 | + TRAMPOLINE_PLACEMENT_SIZE); 221 | 222 | #ifdef CONFIG_64BIT 223 | if (image_base != (unsigned long)startup_32) 224 | - adjust_memory_range_protection(image_base, image_size); 225 | + efi_adjust_memory_range_protection(image_base, image_size); 226 | #else 227 | /* 228 | * Clear protection flags on a whole range of possible 229 | @@ -306,8 +250,8 @@ setup_memory_protection(unsigned long image_base, unsigned long image_size) 230 | * need to remove possible protection on relocated image 231 | * itself disregarding further relocations. 232 | */ 233 | - adjust_memory_range_protection(LOAD_PHYSICAL_ADDR, 234 | - KERNEL_IMAGE_SIZE - LOAD_PHYSICAL_ADDR); 235 | + efi_adjust_memory_range_protection(LOAD_PHYSICAL_ADDR, 236 | + KERNEL_IMAGE_SIZE - LOAD_PHYSICAL_ADDR); 237 | #endif 238 | } 239 | 240 | -- 241 | 2.40.1 242 | 243 | -------------------------------------------------------------------------------- /tinylinux/patches/linux/v5.10.179/0018-x86-boot-Make-kernel_add_identity_map-a-pointer.patch: -------------------------------------------------------------------------------- 1 | From 3f7942258875eb13736b3792cb5a6c028b47a85b Mon Sep 17 00:00:00 2001 2 | Message-Id: <> 3 | In-Reply-To: <> 4 | References: <> 5 | From: Evgeniy Baskov <> 6 | Date: Tue, 13 Dec 2022 13:34:55 +0300 7 | Subject: [PATCH 18/39] x86/boot: Make kernel_add_identity_map() a pointer 8 | 9 | Convert kernel_add_identity_map() into a function pointer to be able 10 | to provide alternative implementations of this function. Required 11 | to enable calling the code using this function from EFI environment. 12 | 13 | Tested-by: Mario Limonciello <> 14 | Signed-off-by: Evgeniy Baskov <> 15 | --- 16 | arch/x86/boot/compressed/ident_map_64.c | 7 ++++--- 17 | arch/x86/boot/compressed/misc.c | 24 ++++++++++++++++++++++++ 18 | arch/x86/boot/compressed/misc.h | 15 +++------------ 19 | 3 files changed, 31 insertions(+), 15 deletions(-) 20 | 21 | diff --git a/arch/x86/boot/compressed/ident_map_64.c b/arch/x86/boot/compressed/ident_map_64.c 22 | index 8a3e6b8d822e..d131ca7fcc2a 100644 23 | --- a/arch/x86/boot/compressed/ident_map_64.c 24 | +++ b/arch/x86/boot/compressed/ident_map_64.c 25 | @@ -94,9 +94,9 @@ _Bool has_nx; /* set in head_64.S */ 26 | /* 27 | * Adds the specified range to the identity mappings. 28 | */ 29 | -unsigned long kernel_add_identity_map(unsigned long start, 30 | - unsigned long end, 31 | - unsigned int flags) 32 | +static unsigned long kernel_add_identity_map_impl(unsigned long start, 33 | + unsigned long end, 34 | + unsigned int flags) 35 | { 36 | int ret; 37 | 38 | @@ -144,6 +144,7 @@ void initialize_identity_maps(void *rmode) 39 | struct setup_data *sd; 40 | 41 | boot_params = rmode; 42 | + kernel_add_identity_map = kernel_add_identity_map_impl; 43 | 44 | /* Exclude the encryption mask from __PHYSICAL_MASK */ 45 | physical_mask &= ~sme_me_mask; 46 | diff --git a/arch/x86/boot/compressed/misc.c b/arch/x86/boot/compressed/misc.c 47 | index 8916de581ed9..1555830bc581 100644 48 | --- a/arch/x86/boot/compressed/misc.c 49 | +++ b/arch/x86/boot/compressed/misc.c 50 | @@ -269,6 +269,22 @@ static void parse_elf(void *output, unsigned long output_len, 51 | free(phdrs); 52 | } 53 | 54 | +/* 55 | + * This points to actual implementation of mapping function 56 | + * for current environment: either EFI API wrapper, 57 | + * own implementation or dummy implementation below. 58 | + */ 59 | +unsigned long (*kernel_add_identity_map)(unsigned long start, 60 | + unsigned long end, 61 | + unsigned int flags); 62 | + 63 | +static unsigned long kernel_add_identity_map_dummy(unsigned long start, 64 | + unsigned long end, 65 | + unsigned int flags) 66 | +{ 67 | + return start; 68 | +} 69 | + 70 | /* 71 | * The compressed kernel image (ZO), has been moved so that its position 72 | * is against the end of the buffer used to hold the uncompressed kernel 73 | @@ -306,6 +322,14 @@ asmlinkage __visible void *extract_kernel(void *rmode, memptr heap, 74 | 75 | init_bare_console(); 76 | 77 | + /* 78 | + * On 64-bit this pointer is set during page table uninitialization, 79 | + * but on 32-bit it remains uninitialized, since paging is disabled. 80 | + */ 81 | + if (IS_ENABLED(CONFIG_X86_32)) 82 | + kernel_add_identity_map = kernel_add_identity_map_dummy; 83 | + 84 | + 85 | /* 86 | * Save RSDP address for later use. Have this after console_init() 87 | * so that early debugging output from the RSDP parsing code can be 88 | diff --git a/arch/x86/boot/compressed/misc.h b/arch/x86/boot/compressed/misc.h 89 | index 8411ef3bfa0f..e798a1c2fe0e 100644 90 | --- a/arch/x86/boot/compressed/misc.h 91 | +++ b/arch/x86/boot/compressed/misc.h 92 | @@ -156,18 +156,9 @@ static inline int count_immovable_mem_regions(void) { return 0; } 93 | extern unsigned int __pgtable_l5_enabled, pgdir_shift, ptrs_per_p4d; 94 | #endif 95 | 96 | -#ifdef CONFIG_X86_64 97 | -extern unsigned long kernel_add_identity_map(unsigned long start, 98 | - unsigned long end, 99 | - unsigned int flags); 100 | -#else 101 | -static inline unsigned long kernel_add_identity_map(unsigned long start, 102 | - unsigned long end, 103 | - unsigned int flags) 104 | -{ 105 | - return start; 106 | -} 107 | -#endif 108 | +extern unsigned long (*kernel_add_identity_map)(unsigned long start, 109 | + unsigned long end, 110 | + unsigned int flags); 111 | 112 | /* Used by PAGE_KERN* macros: */ 113 | extern pteval_t __default_kernel_pte_mask; 114 | -- 115 | 2.40.1 116 | 117 | -------------------------------------------------------------------------------- /tinylinux/patches/linux/v5.10.179/0019-x86-boot-Split-trampoline-and-pt-init-code.patch: -------------------------------------------------------------------------------- 1 | From 4b9cde6f98bd734c1049f26038c200d5b12f3494 Mon Sep 17 00:00:00 2001 2 | Message-Id: <> 3 | In-Reply-To: <> 4 | References: <> 5 | From: Evgeniy Baskov <> 6 | Date: Thu, 16 Jun 2022 15:30:22 +0300 7 | Subject: [PATCH 19/39] x86/boot: Split trampoline and pt init code 8 | 9 | When allocating trampoline from libstub trampoline allocation is 10 | performed separately, so it needs to be skipped. 11 | 12 | Split trampoline initialization and allocation code into two 13 | functions to make them invokable separately. 14 | 15 | Tested-by: Mario Limonciello <> 16 | Signed-off-by: Evgeniy Baskov <> 17 | --- 18 | arch/x86/boot/compressed/pgtable_64.c | 73 +++++++++++++++++---------- 19 | 1 file changed, 46 insertions(+), 27 deletions(-) 20 | 21 | diff --git a/arch/x86/boot/compressed/pgtable_64.c b/arch/x86/boot/compressed/pgtable_64.c 22 | index dbda2b685394..7b360611eb95 100644 23 | --- a/arch/x86/boot/compressed/pgtable_64.c 24 | +++ b/arch/x86/boot/compressed/pgtable_64.c 25 | @@ -105,12 +105,8 @@ static unsigned long find_trampoline_placement(void) 26 | return bios_start - TRAMPOLINE_32BIT_SIZE; 27 | } 28 | 29 | -struct paging_config paging_prepare(void *rmode) 30 | +bool trampoline_pgtable_init(struct boot_params *boot_params) 31 | { 32 | - struct paging_config paging_config = {}; 33 | - 34 | - /* Initialize boot_params. Required for cmdline_find_option_bool(). */ 35 | - boot_params = rmode; 36 | 37 | /* 38 | * Check if LA57 is desired and supported. 39 | @@ -124,26 +120,10 @@ struct paging_config paging_prepare(void *rmode) 40 | * 41 | * That's substitute for boot_cpu_has() in early boot code. 42 | */ 43 | - if (IS_ENABLED(CONFIG_X86_5LEVEL) && 44 | - !cmdline_find_option_bool("no5lvl") && 45 | - native_cpuid_eax(0) >= 7 && 46 | - (native_cpuid_ecx(7) & (1 << (X86_FEATURE_LA57 & 31)))) { 47 | - paging_config.l5_required = 1; 48 | - } 49 | - 50 | - paging_config.trampoline_start = find_trampoline_placement(); 51 | - 52 | - trampoline_32bit = (unsigned long *)paging_config.trampoline_start; 53 | - 54 | - /* Preserve trampoline memory */ 55 | - memcpy(trampoline_save, trampoline_32bit, TRAMPOLINE_32BIT_SIZE); 56 | - 57 | - /* Clear trampoline memory first */ 58 | - memset(trampoline_32bit, 0, TRAMPOLINE_32BIT_SIZE); 59 | - 60 | - /* Copy trampoline code in place */ 61 | - memcpy(trampoline_32bit + TRAMPOLINE_32BIT_CODE_OFFSET / sizeof(unsigned long), 62 | - &trampoline_32bit_src, TRAMPOLINE_32BIT_CODE_SIZE); 63 | + bool l5_required = IS_ENABLED(CONFIG_X86_5LEVEL) && 64 | + !cmdline_find_option_bool("no5lvl") && 65 | + native_cpuid_eax(0) >= 7 && 66 | + (native_cpuid_ecx(7) & (1 << (X86_FEATURE_LA57 & 31))); 67 | 68 | /* 69 | * The code below prepares page table in trampoline memory. 70 | @@ -159,10 +139,10 @@ struct paging_config paging_prepare(void *rmode) 71 | * We are not going to use the page table in trampoline memory if we 72 | * are already in the desired paging mode. 73 | */ 74 | - if (paging_config.l5_required == !!(native_read_cr4() & X86_CR4_LA57)) 75 | + if (l5_required == !!(native_read_cr4() & X86_CR4_LA57)) 76 | goto out; 77 | 78 | - if (paging_config.l5_required) { 79 | + if (l5_required) { 80 | /* 81 | * For 4- to 5-level paging transition, set up current CR3 as 82 | * the first and the only entry in a new top-level page table. 83 | @@ -184,6 +164,45 @@ struct paging_config paging_prepare(void *rmode) 84 | (void *)src, PAGE_SIZE); 85 | } 86 | 87 | +out: 88 | + return l5_required; 89 | +} 90 | + 91 | +struct paging_config paging_prepare(void *rmode) 92 | +{ 93 | + struct paging_config paging_config = {}; 94 | + bool early_trampoline_alloc = 0; 95 | + 96 | + /* Initialize boot_params. Required for cmdline_find_option_bool(). */ 97 | + boot_params = rmode; 98 | + 99 | + /* 100 | + * We only need to find trampoline placement, if we have 101 | + * not already done it from libstub. 102 | + */ 103 | + 104 | + paging_config.trampoline_start = find_trampoline_placement(); 105 | + trampoline_32bit = (unsigned long *)paging_config.trampoline_start; 106 | + early_trampoline_alloc = 0; 107 | + 108 | + /* 109 | + * Preserve trampoline memory. 110 | + * When trampoline is located in memory 111 | + * owned by us, i.e. allocated in EFISTUB, 112 | + * we don't care about previous contents 113 | + * of this memory so copying can also be skipped. 114 | + */ 115 | + memcpy(trampoline_save, trampoline_32bit, TRAMPOLINE_32BIT_SIZE); 116 | + 117 | + /* Clear trampoline memory first */ 118 | + memset(trampoline_32bit, 0, TRAMPOLINE_32BIT_SIZE); 119 | + 120 | + /* Copy trampoline code in place */ 121 | + memcpy(trampoline_32bit + TRAMPOLINE_32BIT_CODE_OFFSET / sizeof(unsigned long), 122 | + &trampoline_32bit_src, TRAMPOLINE_32BIT_CODE_SIZE); 123 | + 124 | + paging_config.l5_required = trampoline_pgtable_init(boot_params); 125 | + 126 | out: 127 | return paging_config; 128 | } 129 | -- 130 | 2.40.1 131 | 132 | -------------------------------------------------------------------------------- /tinylinux/patches/linux/v5.10.179/0020-x86-boot-Add-EFI-kernel-extraction-interface.patch: -------------------------------------------------------------------------------- 1 | From 60fc39ba84bf101b9d186ef7dbb337385263422f Mon Sep 17 00:00:00 2001 2 | Message-Id: <> 3 | In-Reply-To: <> 4 | References: <> 5 | From: Evgeniy Baskov <> 6 | Date: Tue, 13 Dec 2022 13:41:16 +0300 7 | Subject: [PATCH 20/39] x86/boot: Add EFI kernel extraction interface 8 | 9 | To enable extraction of kernel image from EFI stub code directly 10 | extraction code needs to have separate interface that avoid part 11 | of low level initialization logic, i.e. serial port setup. 12 | 13 | Add kernel extraction function callable from libstub as a part 14 | of preparation for extracting the kernel directly from EFI environment. 15 | 16 | Tested-by: Mario Limonciello <> 17 | Signed-off-by: Evgeniy Baskov <> 18 | --- 19 | arch/x86/boot/compressed/head_32.S | 3 +- 20 | arch/x86/boot/compressed/head_64.S | 2 +- 21 | arch/x86/boot/compressed/misc.c | 77 +++++++++++++++++++++--------- 22 | arch/x86/boot/compressed/misc.h | 1 + 23 | 4 files changed, 57 insertions(+), 26 deletions(-) 24 | 25 | diff --git a/arch/x86/boot/compressed/head_32.S b/arch/x86/boot/compressed/head_32.S 26 | index 659fad53ca82..ed9b1c44eb56 100644 27 | --- a/arch/x86/boot/compressed/head_32.S 28 | +++ b/arch/x86/boot/compressed/head_32.S 29 | @@ -218,8 +218,7 @@ SYM_DATA(image_offset, .long 0) 30 | */ 31 | .bss 32 | .balign 4 33 | -boot_heap: 34 | - .fill BOOT_HEAP_SIZE, 1, 0 35 | +SYM_DATA(boot_heap, .fill BOOT_HEAP_SIZE, 1, 0) 36 | boot_stack: 37 | .fill BOOT_STACK_SIZE, 1, 0 38 | boot_stack_end: 39 | diff --git a/arch/x86/boot/compressed/head_64.S b/arch/x86/boot/compressed/head_64.S 40 | index adecfe366edd..8dd8b57196a4 100644 41 | --- a/arch/x86/boot/compressed/head_64.S 42 | +++ b/arch/x86/boot/compressed/head_64.S 43 | @@ -899,7 +899,7 @@ SYM_FUNC_END(startup32_check_sev_cbit) 44 | */ 45 | .bss 46 | .balign 4 47 | -SYM_DATA_LOCAL(boot_heap, .fill BOOT_HEAP_SIZE, 1, 0) 48 | +SYM_DATA(boot_heap, .fill BOOT_HEAP_SIZE, 1, 0) 49 | 50 | SYM_DATA_START_LOCAL(boot_stack) 51 | .fill BOOT_STACK_SIZE, 1, 0 52 | diff --git a/arch/x86/boot/compressed/misc.c b/arch/x86/boot/compressed/misc.c 53 | index 1555830bc581..793bbde4ebb3 100644 54 | --- a/arch/x86/boot/compressed/misc.c 55 | +++ b/arch/x86/boot/compressed/misc.c 56 | @@ -302,11 +302,11 @@ static unsigned long kernel_add_identity_map_dummy(unsigned long start, 57 | * |-------uncompressed kernel image---------| 58 | * 59 | */ 60 | -asmlinkage __visible void *extract_kernel(void *rmode, memptr heap, 61 | - unsigned char *input_data, 62 | - unsigned long input_len, 63 | - unsigned char *output, 64 | - unsigned long output_len) 65 | +static void *do_extract_kernel(void *rmode, 66 | + unsigned char *input_data, 67 | + unsigned long input_len, 68 | + unsigned char *output, 69 | + unsigned long output_len) 70 | { 71 | const unsigned long kernel_total_size = VO__end - VO__text; 72 | unsigned long virt_addr = LOAD_PHYSICAL_ADDR; 73 | @@ -320,16 +320,6 @@ asmlinkage __visible void *extract_kernel(void *rmode, memptr heap, 74 | 75 | sanitize_boot_params(boot_params); 76 | 77 | - init_bare_console(); 78 | - 79 | - /* 80 | - * On 64-bit this pointer is set during page table uninitialization, 81 | - * but on 32-bit it remains uninitialized, since paging is disabled. 82 | - */ 83 | - if (IS_ENABLED(CONFIG_X86_32)) 84 | - kernel_add_identity_map = kernel_add_identity_map_dummy; 85 | - 86 | - 87 | /* 88 | * Save RSDP address for later use. Have this after console_init() 89 | * so that early debugging output from the RSDP parsing code can be 90 | @@ -337,11 +327,6 @@ asmlinkage __visible void *extract_kernel(void *rmode, memptr heap, 91 | */ 92 | boot_params->acpi_rsdp_addr = get_rsdp_addr(); 93 | 94 | - debug_putstr("early console in extract_kernel\n"); 95 | - 96 | - free_mem_ptr = heap; /* Heap */ 97 | - free_mem_end_ptr = heap + BOOT_HEAP_SIZE; 98 | - 99 | /* 100 | * The memory hole needed for the kernel is the larger of either 101 | * the entire decompressed kernel plus relocation table, or the 102 | @@ -395,12 +380,12 @@ asmlinkage __visible void *extract_kernel(void *rmode, memptr heap, 103 | if (virt_addr & (MIN_KERNEL_ALIGN - 1)) 104 | error("Destination virtual address inappropriately aligned"); 105 | #ifdef CONFIG_X86_64 106 | - if (heap > 0x3fffffffffffUL) 107 | + if (phys_addr > 0x3fffffffffffUL) 108 | error("Destination address too large"); 109 | if (virt_addr + max(output_len, kernel_total_size) > KERNEL_IMAGE_SIZE) 110 | error("Destination virtual address is beyond the kernel mapping area"); 111 | #else 112 | - if (heap > ((-__PAGE_OFFSET-(128<<20)-1) & 0x7fffffff)) 113 | + if (phys_addr > ((-__PAGE_OFFSET-(128<<20)-1) & 0x7fffffff)) 114 | error("Destination address too large"); 115 | #endif 116 | #ifndef CONFIG_RELOCATABLE 117 | @@ -416,13 +401,59 @@ asmlinkage __visible void *extract_kernel(void *rmode, memptr heap, 118 | parse_elf(output, output_len, virt_addr); 119 | debug_putstr("done.\nBooting the kernel.\n"); 120 | 121 | + return output; 122 | +} 123 | + 124 | +asmlinkage __visible void *extract_kernel(void *rmode, memptr heap, 125 | + unsigned char *input_data, 126 | + unsigned long input_len, 127 | + unsigned char *output, 128 | + unsigned long output_len) 129 | +{ 130 | + void *entry; 131 | + 132 | + /* 133 | + * On 64-bit this pointer is set during page table uninitialization, 134 | + * but on 32-bit it remains uninitialized, since paging is disabled. 135 | + */ 136 | + if (IS_ENABLED(CONFIG_X86_32)) 137 | + kernel_add_identity_map = kernel_add_identity_map_dummy; 138 | + 139 | + init_bare_console(); 140 | + 141 | + debug_putstr("early console in extract_kernel\n"); 142 | + 143 | + free_mem_ptr = heap; /* Heap */ 144 | + free_mem_end_ptr = heap + BOOT_HEAP_SIZE; 145 | + 146 | + entry = do_extract_kernel(rmode, input_data, 147 | + input_len, output, output_len); 148 | + 149 | /* 150 | * Flush GHCB from cache and map it encrypted again when running as 151 | * SEV-ES guest. 152 | */ 153 | sev_es_shutdown_ghcb(); 154 | 155 | - return output; 156 | + return entry; 157 | +} 158 | + 159 | +void *efi_extract_kernel(struct boot_params *rmode, 160 | + struct efi_extract_callbacks *cb, 161 | + unsigned char *input_data, 162 | + unsigned long input_len, 163 | + unsigned long output_len) 164 | +{ 165 | + extern char boot_heap[BOOT_HEAP_SIZE]; 166 | + 167 | + free_mem_ptr = (unsigned long)boot_heap; /* Heap */ 168 | + free_mem_end_ptr = (unsigned long)boot_heap + BOOT_HEAP_SIZE; 169 | + 170 | + init_console_func(cb->putstr, cb->puthex); 171 | + kernel_add_identity_map = cb->map_range; 172 | + 173 | + return do_extract_kernel(rmode, input_data, 174 | + input_len, (void *)LOAD_PHYSICAL_ADDR, output_len); 175 | } 176 | 177 | void fortify_panic(const char *name) 178 | diff --git a/arch/x86/boot/compressed/misc.h b/arch/x86/boot/compressed/misc.h 179 | index e798a1c2fe0e..3be97e6a2af5 100644 180 | --- a/arch/x86/boot/compressed/misc.h 181 | +++ b/arch/x86/boot/compressed/misc.h 182 | @@ -24,6 +24,7 @@ 183 | #include 184 | #include 185 | #include 186 | +#include 187 | 188 | #define BOOT_CTYPE_H 189 | #include 190 | -- 191 | 2.40.1 192 | 193 | -------------------------------------------------------------------------------- /tinylinux/patches/linux/v5.10.179/0021-x86-boot-Reduce-lower-limit-of-physical-KASLR.patch: -------------------------------------------------------------------------------- 1 | From 5a48e1e86f8fa51bb85368c1f7a280bdb14bd452 Mon Sep 17 00:00:00 2001 2 | Message-Id: <> 3 | In-Reply-To: <> 4 | References: <> 5 | From: Evgeniy Baskov <> 6 | Date: Fri, 21 Oct 2022 19:56:57 +0300 7 | Subject: [PATCH 21/39] x86/boot: Reduce lower limit of physical KASLR 8 | 9 | Set lower limit of physical KASLR to 64M. 10 | 11 | Previously is was set to 512M when kernel is loaded higher than that. 12 | That prevented physical KASLR from being performed on x86_32, where 13 | upper limit is also set to 512M. The limit is pretty arbitrary, and the 14 | most important is to set it above the ISA hole, i.e. higher than 16M. 15 | 16 | It was not that important before, but now kernel is not getting 17 | relocated to the lower address when booting via EFI, exposing the 18 | KASLR failures. 19 | 20 | Tested-by: Mario Limonciello <> 21 | Signed-off-by: Evgeniy Baskov <> 22 | --- 23 | arch/x86/boot/compressed/kaslr.c | 4 ++-- 24 | 1 file changed, 2 insertions(+), 2 deletions(-) 25 | 26 | diff --git a/arch/x86/boot/compressed/kaslr.c b/arch/x86/boot/compressed/kaslr.c 27 | index 12a0bac89fab..39fd1f881e66 100644 28 | --- a/arch/x86/boot/compressed/kaslr.c 29 | +++ b/arch/x86/boot/compressed/kaslr.c 30 | @@ -854,10 +854,10 @@ void choose_random_location(unsigned long input, 31 | 32 | /* 33 | * Low end of the randomization range should be the 34 | - * smaller of 512M or the initial kernel image 35 | + * smaller of 64M or the initial kernel image 36 | * location: 37 | */ 38 | - min_addr = min(*output, 512UL << 20); 39 | + min_addr = min(*output, 64UL << 20); 40 | /* Make sure minimum is aligned. */ 41 | min_addr = ALIGN(min_addr, CONFIG_PHYSICAL_ALIGN); 42 | 43 | -- 44 | 2.40.1 45 | 46 | -------------------------------------------------------------------------------- /tinylinux/patches/linux/v5.10.179/0023-x86-decompressor-Remove-the-bugger-off-message.patch: -------------------------------------------------------------------------------- 1 | From 8f439fb72ff907f9f4bd06517db3202e01bf622b Mon Sep 17 00:00:00 2001 2 | Message-Id: <> 3 | In-Reply-To: <> 4 | References: <> 5 | From: Evgeniy Baskov <> 6 | Date: Thu, 11 May 2023 17:55:05 +0300 7 | Subject: [PATCH 23/39] x86: decompressor: Remove the 'bugger off' message 8 | 9 | Ancient (pre-2003) x86 kernels could boot from a floppy disk straight from 10 | the BIOS, using a small real mode boot stub at the start of the image 11 | where the BIOS would expect the boot record (or boot block) to appear. 12 | 13 | Due to its limitations (kernel size < 1 MiB, no support for IDE, USB or 14 | El Torito floppy emulation), this support was dropped, and a Linux aware 15 | bootloader is now always required to boot the kernel. 16 | 17 | To smoothen this transition, the boot stub was not removed entirely, but 18 | replaced with one that just prints an error message telling you to 19 | install a bootloader. 20 | 21 | As it is unlikely that anyone doing direct floppy boot with such an 22 | ancient kernel is going to upgrade to v6.4+ and expect that this boot 23 | method still works, printing this message is kind of pointless, and so 24 | we should be able to remove the logic that emits it. 25 | 26 | Let's free up this space so we can use it to expand the PE header in a 27 | subsequent patch. 28 | 29 | Signed-off-by: Ard Biesheuvel <> 30 | --- 31 | arch/x86/boot/header.S | 47 ------------------------------------------ 32 | arch/x86/boot/setup.ld | 7 ++++--- 33 | 2 files changed, 4 insertions(+), 50 deletions(-) 34 | 35 | diff --git a/arch/x86/boot/header.S b/arch/x86/boot/header.S 36 | index 0352e4589efa..85c14546f707 100644 37 | --- a/arch/x86/boot/header.S 38 | +++ b/arch/x86/boot/header.S 39 | @@ -39,62 +39,15 @@ SYSSEG = 0x1000 /* historical load address >> 4 */ 40 | .code16 41 | .section ".bstext", "ax" 42 | 43 | - .global bootsect_start 44 | -bootsect_start: 45 | #ifdef CONFIG_EFI_STUB 46 | # "MZ", MS-DOS header 47 | .word MZ_MAGIC 48 | -#endif 49 | - 50 | - # Normalize the start address 51 | - ljmp $BOOTSEG, $start2 52 | - 53 | -start2: 54 | - movw %cs, %ax 55 | - movw %ax, %ds 56 | - movw %ax, %es 57 | - movw %ax, %ss 58 | - xorw %sp, %sp 59 | - sti 60 | - cld 61 | - 62 | - movw $bugger_off_msg, %si 63 | - 64 | -msg_loop: 65 | - lodsb 66 | - andb %al, %al 67 | - jz bs_die 68 | - movb $0xe, %ah 69 | - movw $7, %bx 70 | - int $0x10 71 | - jmp msg_loop 72 | - 73 | -bs_die: 74 | - # Allow the user to press a key, then reboot 75 | - xorw %ax, %ax 76 | - int $0x16 77 | - int $0x19 78 | 79 | - # int 0x19 should never return. In case it does anyway, 80 | - # invoke the BIOS reset code... 81 | - ljmp $0xf000,$0xfff0 82 | - 83 | -#ifdef CONFIG_EFI_STUB 84 | .org 0x3c 85 | # 86 | # Offset to the PE header. 87 | # 88 | .long pe_header 89 | -#endif /* CONFIG_EFI_STUB */ 90 | - 91 | - .section ".bsdata", "a" 92 | -bugger_off_msg: 93 | - .ascii "Use a boot loader.\r\n" 94 | - .ascii "\n" 95 | - .ascii "Remove disk and press any key to reboot...\r\n" 96 | - .byte 0 97 | - 98 | -#ifdef CONFIG_EFI_STUB 99 | pe_header: 100 | .long PE_MAGIC 101 | 102 | diff --git a/arch/x86/boot/setup.ld b/arch/x86/boot/setup.ld 103 | index 49546c247ae2..31419b7c9c3f 100644 104 | --- a/arch/x86/boot/setup.ld 105 | +++ b/arch/x86/boot/setup.ld 106 | @@ -10,10 +10,11 @@ ENTRY(_start) 107 | SECTIONS 108 | { 109 | . = 0; 110 | - .bstext : { *(.bstext) } 111 | - .bsdata : { *(.bsdata) } 112 | + .bstext : { 113 | + *(.bstext) 114 | + . = 495; 115 | + } =0xff 116 | 117 | - . = 495; 118 | .header : { *(.header) } 119 | .entrytext : { *(.entrytext) } 120 | .inittext : { *(.inittext) } 121 | -- 122 | 2.40.1 123 | 124 | -------------------------------------------------------------------------------- /tinylinux/patches/linux/v5.10.179/0024-tools-include-Add-simplified-version-of-pe.h.patch: -------------------------------------------------------------------------------- 1 | From 2725aefa352dfda859f78aacf027802f1afa65a9 Mon Sep 17 00:00:00 2001 2 | Message-Id: <> 3 | In-Reply-To: <> 4 | References: <> 5 | From: Evgeniy Baskov <> 6 | Date: Tue, 25 Oct 2022 11:56:21 +0300 7 | Subject: [PATCH 24/39] tools/include: Add simplified version of pe.h 8 | 9 | This is needed to remove magic numbers from x86 bzImage building tool 10 | (arch/x86/boot/tools/build.c). 11 | 12 | Tested-by: Mario Limonciello <> 13 | Signed-off-by: Evgeniy Baskov <> 14 | --- 15 | tools/include/linux/pe.h | 150 +++++++++++++++++++++++++++++++++++++++ 16 | 1 file changed, 150 insertions(+) 17 | create mode 100644 tools/include/linux/pe.h 18 | 19 | diff --git a/tools/include/linux/pe.h b/tools/include/linux/pe.h 20 | new file mode 100644 21 | index 000000000000..41c09ec371d8 22 | --- /dev/null 23 | +++ b/tools/include/linux/pe.h 24 | @@ -0,0 +1,150 @@ 25 | +/* SPDX-License-Identifier: GPL-2.0-only */ 26 | +/* 27 | + * Simplified version of include/linux/pe.h: 28 | + * Copyright 2011 Red Hat, Inc. All rights reserved. 29 | + * Author(s): Peter Jones <> 30 | + */ 31 | +#ifndef __LINUX_PE_H 32 | +#define __LINUX_PE_H 33 | + 34 | +#include 35 | + 36 | +#define IMAGE_FILE_MACHINE_I386 0x014c 37 | + 38 | +#define IMAGE_SCN_CNT_CODE 0x00000020 /* .text */ 39 | +#define IMAGE_SCN_CNT_INITIALIZED_DATA 0x00000040 /* .data */ 40 | +#define IMAGE_SCN_ALIGN_4096BYTES 0x00d00000 41 | +#define IMAGE_SCN_MEM_DISCARDABLE 0x02000000 /* scn can be discarded */ 42 | +#define IMAGE_SCN_MEM_EXECUTE 0x20000000 /* can be executed as code */ 43 | +#define IMAGE_SCN_MEM_READ 0x40000000 /* readable */ 44 | +#define IMAGE_SCN_MEM_WRITE 0x80000000 /* writeable */ 45 | + 46 | +#define MZ_HEADER_PEADDR_OFFSET 0x3c 47 | + 48 | +struct pe_hdr { 49 | + uint32_t magic; /* PE magic */ 50 | + uint16_t machine; /* machine type */ 51 | + uint16_t sections; /* number of sections */ 52 | + uint32_t timestamp; /* time_t */ 53 | + uint32_t symbol_table; /* symbol table offset */ 54 | + uint32_t symbols; /* number of symbols */ 55 | + uint16_t opt_hdr_size; /* size of optional header */ 56 | + uint16_t flags; /* flags */ 57 | +}; 58 | + 59 | +/* the fact that pe32 isn't padded where pe32+ is 64-bit means union won't 60 | + * work right. vomit. */ 61 | +struct pe32_opt_hdr { 62 | + /* "standard" header */ 63 | + uint16_t magic; /* file type */ 64 | + uint8_t ld_major; /* linker major version */ 65 | + uint8_t ld_minor; /* linker minor version */ 66 | + uint32_t text_size; /* size of text section(s) */ 67 | + uint32_t data_size; /* size of data section(s) */ 68 | + uint32_t bss_size; /* size of bss section(s) */ 69 | + uint32_t entry_point; /* file offset of entry point */ 70 | + uint32_t code_base; /* relative code addr in ram */ 71 | + uint32_t data_base; /* relative data addr in ram */ 72 | + /* "windows" header */ 73 | + uint32_t image_base; /* preferred load address */ 74 | + uint32_t section_align; /* alignment in bytes */ 75 | + uint32_t file_align; /* file alignment in bytes */ 76 | + uint16_t os_major; /* major OS version */ 77 | + uint16_t os_minor; /* minor OS version */ 78 | + uint16_t image_major; /* major image version */ 79 | + uint16_t image_minor; /* minor image version */ 80 | + uint16_t subsys_major; /* major subsystem version */ 81 | + uint16_t subsys_minor; /* minor subsystem version */ 82 | + uint32_t win32_version; /* reserved, must be 0 */ 83 | + uint32_t image_size; /* image size */ 84 | + uint32_t header_size; /* header size rounded up to 85 | + file_align */ 86 | + uint32_t csum; /* checksum */ 87 | + uint16_t subsys; /* subsystem */ 88 | + uint16_t dll_flags; /* more flags! */ 89 | + uint32_t stack_size_req;/* amt of stack requested */ 90 | + uint32_t stack_size; /* amt of stack required */ 91 | + uint32_t heap_size_req; /* amt of heap requested */ 92 | + uint32_t heap_size; /* amt of heap required */ 93 | + uint32_t loader_flags; /* reserved, must be 0 */ 94 | + uint32_t data_dirs; /* number of data dir entries */ 95 | +}; 96 | + 97 | +struct pe32plus_opt_hdr { 98 | + uint16_t magic; /* file type */ 99 | + uint8_t ld_major; /* linker major version */ 100 | + uint8_t ld_minor; /* linker minor version */ 101 | + uint32_t text_size; /* size of text section(s) */ 102 | + uint32_t data_size; /* size of data section(s) */ 103 | + uint32_t bss_size; /* size of bss section(s) */ 104 | + uint32_t entry_point; /* file offset of entry point */ 105 | + uint32_t code_base; /* relative code addr in ram */ 106 | + /* "windows" header */ 107 | + uint64_t image_base; /* preferred load address */ 108 | + uint32_t section_align; /* alignment in bytes */ 109 | + uint32_t file_align; /* file alignment in bytes */ 110 | + uint16_t os_major; /* major OS version */ 111 | + uint16_t os_minor; /* minor OS version */ 112 | + uint16_t image_major; /* major image version */ 113 | + uint16_t image_minor; /* minor image version */ 114 | + uint16_t subsys_major; /* major subsystem version */ 115 | + uint16_t subsys_minor; /* minor subsystem version */ 116 | + uint32_t win32_version; /* reserved, must be 0 */ 117 | + uint32_t image_size; /* image size */ 118 | + uint32_t header_size; /* header size rounded up to 119 | + file_align */ 120 | + uint32_t csum; /* checksum */ 121 | + uint16_t subsys; /* subsystem */ 122 | + uint16_t dll_flags; /* more flags! */ 123 | + uint64_t stack_size_req;/* amt of stack requested */ 124 | + uint64_t stack_size; /* amt of stack required */ 125 | + uint64_t heap_size_req; /* amt of heap requested */ 126 | + uint64_t heap_size; /* amt of heap required */ 127 | + uint32_t loader_flags; /* reserved, must be 0 */ 128 | + uint32_t data_dirs; /* number of data dir entries */ 129 | +}; 130 | + 131 | +struct data_dirent { 132 | + uint32_t virtual_address; /* relative to load address */ 133 | + uint32_t size; 134 | +}; 135 | + 136 | +struct data_directory { 137 | + struct data_dirent exports; /* .edata */ 138 | + struct data_dirent imports; /* .idata */ 139 | + struct data_dirent resources; /* .rsrc */ 140 | + struct data_dirent exceptions; /* .pdata */ 141 | + struct data_dirent certs; /* certs */ 142 | + struct data_dirent base_relocations; /* .reloc */ 143 | + struct data_dirent debug; /* .debug */ 144 | + struct data_dirent arch; /* reservered */ 145 | + struct data_dirent global_ptr; /* global pointer reg. Size=0 */ 146 | + struct data_dirent tls; /* .tls */ 147 | + struct data_dirent load_config; /* load configuration structure */ 148 | + struct data_dirent bound_imports; /* no idea */ 149 | + struct data_dirent import_addrs; /* import address table */ 150 | + struct data_dirent delay_imports; /* delay-load import table */ 151 | + struct data_dirent clr_runtime_hdr; /* .cor (object only) */ 152 | + struct data_dirent reserved; 153 | +}; 154 | + 155 | +struct section_header { 156 | + char name[8]; /* name or "/12\0" string tbl offset */ 157 | + uint32_t virtual_size; /* size of loaded section in ram */ 158 | + uint32_t virtual_address; /* relative virtual address */ 159 | + uint32_t raw_data_size; /* size of the section */ 160 | + uint32_t data_addr; /* file pointer to first page of sec */ 161 | + uint32_t relocs; /* file pointer to relocation entries */ 162 | + uint32_t line_numbers; /* line numbers! */ 163 | + uint16_t num_relocs; /* number of relocations */ 164 | + uint16_t num_lin_numbers; /* srsly. */ 165 | + uint32_t flags; 166 | +}; 167 | + 168 | +struct coff_reloc { 169 | + uint32_t virtual_address; 170 | + uint32_t symbol_table_index; 171 | + uint16_t data; 172 | +}; 173 | + 174 | +#endif /* __LINUX_PE_H */ 175 | -- 176 | 2.40.1 177 | 178 | -------------------------------------------------------------------------------- /tinylinux/patches/linux/v5.10.179/0026-efi-x86-Use-private-copy-of-struct-setup_header.patch: -------------------------------------------------------------------------------- 1 | From bdcdf13c28488c5edf5b0d5f3c854ab832fbfb15 Mon Sep 17 00:00:00 2001 2 | Message-Id: <> 3 | In-Reply-To: <> 4 | References: <> 5 | From: Ard Biesheuvel <> 6 | Date: Wed, 8 Mar 2023 20:22:06 +0000 7 | Subject: [PATCH 26/39] efi: x86: Use private copy of struct setup_header 8 | 9 | The native EFI entrypoint does not take a struct boot_params from the 10 | loader, but instead, it constructs one from scratch, using the setup 11 | header data from the start of the image. 12 | 13 | This setup header is placed in a way that permits legacy loaders to 14 | manipulate the contents (i.e., to pass the kernel command line or the 15 | address and size of an initial ramdisk), but EFI boot does not use it in 16 | that way - it only copies the contents that were placed there at build 17 | time, but EFI loaders will not (and should not) manipulate the setup 18 | header to configure the boot. (Commit 63bf28ceb3ebbe76 "efi: x86: Wipe 19 | setup_data on pure EFI boot" deals with some of the fallout of using 20 | setup_data in a way that breaks EFI boot.) So having a pristine, private 21 | copy of the setup header rather than copying the one legacy boot loaders 22 | use would be an advantage for EFI boot. 23 | 24 | As it turns out, there is another reason why copying this header is 25 | slightly problematic: the fixed offset of 0x1f1 bytes into the image 26 | makes it difficult to describe all the sections of the image, as we are 27 | running out of space. We could mitigate this by placing some parts of 28 | the PE/COFF header after this setup header (which will happen in a 29 | subsequent patch), but this makes the setup_header fundamentally part of 30 | the PE header as well, which means that it is no longer part of the 31 | 'in-memory' representation of the PE image, but only part of the 32 | 'on-disk' representation. This means copying the setup header from the 33 | running image may not work, as the PE loader may not have put it in 34 | memory to begin with. 35 | 36 | So let's work around this, and simplify things at the same time, by just 37 | copying the setup header into a EFI stub private allocation at build 38 | time, and use that instead of copying it from the loaded image after it 39 | has been started. 40 | 41 | Signed-off-by: Ard Biesheuvel <> 42 | --- 43 | arch/x86/boot/Makefile | 2 +- 44 | arch/x86/boot/tools/build.c | 8 +++++ 45 | drivers/firmware/efi/libstub/x86-stub.c | 43 ++++--------------------- 46 | 3 files changed, 15 insertions(+), 38 deletions(-) 47 | 48 | diff --git a/arch/x86/boot/Makefile b/arch/x86/boot/Makefile 49 | index 59a42342b555..d1db64f221ec 100644 50 | --- a/arch/x86/boot/Makefile 51 | +++ b/arch/x86/boot/Makefile 52 | @@ -90,7 +90,7 @@ $(obj)/vmlinux.bin: $(obj)/compressed/vmlinux FORCE 53 | 54 | SETUP_OBJS = $(addprefix $(obj)/,$(setup-y)) 55 | 56 | -sed-zoffset := -e 's/^\([0-9a-fA-F]*\) [a-zA-Z] \(startup_32\|startup_64\|efi32_stub_entry\|efi64_stub_entry\|efi_pe_entry\|efi32_pe_entry\|input_data\|kernel_info\|_end\|_ehead\|_text\|z_.*\)$$/\#define ZO_\2 0x\1/p' 57 | +sed-zoffset := -e 's/^\([0-9a-fA-F]*\) [a-zA-Z] \(startup_32\|startup_64\|efi32_stub_entry\|efi64_stub_entry\|efi_pe_entry\|efi32_pe_entry\|efi_boot_params\|input_data\|kernel_info\|_end\|_ehead\|_text\|z_.*\)$$/\#define ZO_\2 0x\1/p' 58 | 59 | quiet_cmd_zoffset = ZOFFSET $@ 60 | cmd_zoffset = $(NM) $< | sed -n $(sed-zoffset) > $@ 61 | diff --git a/arch/x86/boot/tools/build.c b/arch/x86/boot/tools/build.c 62 | index bc26ac3f9451..2af18c19ef85 100644 63 | --- a/arch/x86/boot/tools/build.c 64 | +++ b/arch/x86/boot/tools/build.c 65 | @@ -105,6 +105,7 @@ static unsigned long efi32_stub_entry; 66 | static unsigned long efi64_stub_entry; 67 | static unsigned long efi_pe_entry; 68 | static unsigned long efi32_pe_entry; 69 | +static unsigned long efi_boot_params; 70 | static unsigned long kernel_info; 71 | static unsigned long startup_64; 72 | static unsigned long _ehead; 73 | @@ -439,6 +440,7 @@ static void parse_zoffset(char *fname) 74 | PARSE_ZOFS(p, efi64_stub_entry); 75 | PARSE_ZOFS(p, efi_pe_entry); 76 | PARSE_ZOFS(p, efi32_pe_entry); 77 | + PARSE_ZOFS(p, efi_boot_params); 78 | PARSE_ZOFS(p, kernel_info); 79 | PARSE_ZOFS(p, startup_64); 80 | PARSE_ZOFS(p, _ehead); 81 | @@ -575,6 +577,12 @@ int main(int argc, char **argv) 82 | memcpy(output + setup_size, kernel, kern_file_size); 83 | memset(output + setup_size + kern_file_size, 0, kern_size - kern_file_size); 84 | 85 | +#ifdef CONFIG_EFI_STUB 86 | + /* Copy the setup header */ 87 | + memcpy(output + setup_size + efi_boot_params + 0x1f1, &buf[0x1f1], 88 | + 0x290 - 0x1f1 /* == max possible sizeof(struct setup_header) */); 89 | +#endif 90 | + 91 | /* Calculate and write kernel checksum. */ 92 | crc = partial_crc32(output, total_size - 4, crc); 93 | put_unaligned_le32(crc, &output[total_size - 4]); 94 | diff --git a/drivers/firmware/efi/libstub/x86-stub.c b/drivers/firmware/efi/libstub/x86-stub.c 95 | index 816523006c50..08d3428fb860 100644 96 | --- a/drivers/firmware/efi/libstub/x86-stub.c 97 | +++ b/drivers/firmware/efi/libstub/x86-stub.c 98 | @@ -347,6 +347,8 @@ void __noreturn efi_stub_entry(efi_handle_t handle, 99 | efi_system_table_t *sys_table_arg, 100 | struct boot_params *boot_params); 101 | 102 | +struct boot_params efi_boot_params __section(".data") __aligned(SZ_4K); 103 | + 104 | /* 105 | * Because the x86 boot code expects to be passed a boot_params we 106 | * need to create one ourselves (usually the bootloader would create 107 | @@ -355,7 +357,6 @@ void __noreturn efi_stub_entry(efi_handle_t handle, 108 | efi_status_t __efiapi efi_pe_entry(efi_handle_t handle, 109 | efi_system_table_t *sys_table_arg) 110 | { 111 | - struct boot_params *boot_params; 112 | struct setup_header *hdr; 113 | void *image_base; 114 | efi_guid_t proto = LOADED_IMAGE_PROTOCOL_GUID; 115 | @@ -378,55 +379,23 @@ efi_status_t __efiapi efi_pe_entry(efi_handle_t handle, 116 | image_base = efi_table_attr(image, image_base); 117 | image_offset = (void *)startup_32 - image_base; 118 | 119 | - status = efi_allocate_pages(sizeof(struct boot_params), 120 | - (unsigned long *)&boot_params, ULONG_MAX); 121 | - if (status != EFI_SUCCESS) { 122 | - efi_err("Failed to allocate lowmem for boot params\n"); 123 | - efi_exit(handle, status); 124 | - } 125 | - 126 | - memset(boot_params, 0x0, sizeof(struct boot_params)); 127 | - 128 | - hdr = &boot_params->hdr; 129 | - 130 | - /* Copy the setup header from the second sector to boot_params */ 131 | - memcpy(&hdr->jump, image_base + 512, 132 | - sizeof(struct setup_header) - offsetof(struct setup_header, jump)); 133 | - 134 | - /* 135 | - * Fill out some of the header fields ourselves because the 136 | - * EFI firmware loader doesn't load the first sector. 137 | - */ 138 | - hdr->root_flags = 1; 139 | - hdr->vid_mode = 0xffff; 140 | - hdr->boot_flag = 0xAA55; 141 | - 142 | - hdr->type_of_loader = 0x21; 143 | + hdr = &efi_boot_params.hdr; 144 | 145 | /* Convert unicode cmdline to ascii */ 146 | cmdline_ptr = efi_convert_cmdline(image, &options_size); 147 | if (!cmdline_ptr) 148 | goto fail; 149 | 150 | - efi_set_u64_split((unsigned long)cmdline_ptr, 151 | - &hdr->cmd_line_ptr, &boot_params->ext_cmd_line_ptr); 152 | + efi_set_u64_split((unsigned long)cmdline_ptr, &hdr->cmd_line_ptr, 153 | + &efi_boot_params.ext_cmd_line_ptr); 154 | 155 | hdr->ramdisk_image = 0; 156 | hdr->ramdisk_size = 0; 157 | 158 | - /* 159 | - * Disregard any setup data that was provided by the bootloader: 160 | - * setup_data could be pointing anywhere, and we have no way of 161 | - * authenticating or validating the payload. 162 | - */ 163 | - hdr->setup_data = 0; 164 | - 165 | - efi_stub_entry(handle, sys_table_arg, boot_params); 166 | + efi_stub_entry(handle, sys_table_arg, &efi_boot_params); 167 | /* not reached */ 168 | 169 | fail: 170 | - efi_free(sizeof(struct boot_params), (unsigned long)boot_params); 171 | - 172 | efi_exit(handle, status); 173 | } 174 | 175 | -- 176 | 2.40.1 177 | 178 | -------------------------------------------------------------------------------- /tinylinux/patches/linux/v5.10.179/0027-x86-build-Add-SETUP_HEADER_OFFSET-constant.patch: -------------------------------------------------------------------------------- 1 | From f70582bb9886c3694322352074397404665f6be5 Mon Sep 17 00:00:00 2001 2 | Message-Id: <> 3 | In-Reply-To: <> 4 | References: <> 5 | From: Evgeniy Baskov <> 6 | Date: Mon, 13 Mar 2023 13:41:03 +0300 7 | Subject: [PATCH 27/39] x86/build: Add SETUP_HEADER_OFFSET constant 8 | 9 | Add and use SETUP_HEADER_OFFSET constant in tools/build.c for 10 | readability purposes. It equals to the struct boot_params offset in 11 | kernel image. 12 | 13 | Signed-off-by: Evgeniy Baskov <> 14 | --- 15 | arch/x86/boot/tools/build.c | 25 +++++++++++++++---------- 16 | 1 file changed, 15 insertions(+), 10 deletions(-) 17 | 18 | diff --git a/arch/x86/boot/tools/build.c b/arch/x86/boot/tools/build.c 19 | index 2af18c19ef85..99cfe7724d4d 100644 20 | --- a/arch/x86/boot/tools/build.c 21 | +++ b/arch/x86/boot/tools/build.c 22 | @@ -51,6 +51,8 @@ typedef unsigned int u32; 23 | #define SETUP_SECT_MIN 5 24 | #define SETUP_SECT_MAX 64 25 | 26 | +#define SETUP_HEADER_OFFSET 0x1f1 27 | + 28 | #define PARAGRAPH_SIZE 16 29 | #define SECTOR_SIZE 512 30 | #define FILE_ALIGNMENT 512 31 | @@ -471,7 +473,7 @@ static unsigned int read_setup(char *path) 32 | if (file_size < 2 * SECTOR_SIZE) 33 | die("The setup must be at least 1024 bytes"); 34 | 35 | - if (get_unaligned_le16(&buf[SECTOR_SIZE - 2]) != 0xAA55) 36 | + if (get_unaligned_le16(&buf[SETUP_HEADER_OFFSET + 0xD]) != 0xAA55) 37 | die("Boot block hasn't got boot flag (0xAA55)"); 38 | 39 | fclose(file); 40 | @@ -507,6 +509,7 @@ int main(int argc, char **argv) 41 | unsigned int kern_size; 42 | void *kernel; 43 | u32 crc = 0xffffffffUL; 44 | + u8 *setup_header; 45 | u8 *output; 46 | 47 | if (argc != 5) 48 | @@ -518,9 +521,10 @@ int main(int argc, char **argv) 49 | setup_size = read_setup(argv[1]); 50 | 51 | setup_sectors = setup_size/SECTOR_SIZE; 52 | + setup_header = buf + SETUP_HEADER_OFFSET; 53 | 54 | /* Set the default root device */ 55 | - put_unaligned_le16(DEFAULT_ROOT_DEV, &buf[508]); 56 | + put_unaligned_le16(DEFAULT_ROOT_DEV, &setup_header[0xB]); 57 | 58 | /* Map kernel file to memory */ 59 | kernel = map_file(argv[2], &kern_file_size); 60 | @@ -535,13 +539,13 @@ int main(int argc, char **argv) 61 | #endif 62 | 63 | /* Patch the setup code with the appropriate size parameters */ 64 | - buf[0x1f1] = setup_sectors - 1; 65 | - put_unaligned_le32(kern_size/PARAGRAPH_SIZE, &buf[0x1f4]); 66 | + setup_header[0] = setup_sectors - 1; 67 | + put_unaligned_le32(kern_size/PARAGRAPH_SIZE, &setup_header[3]); 68 | 69 | - /* Update kernel_info offset. */ 70 | - put_unaligned_le32(kernel_info, &buf[0x268]); 71 | + /* Update kernel_info_offset. */ 72 | + put_unaligned_le32(kernel_info, &setup_header[0x77]); 73 | 74 | - init_size = get_unaligned_le32(&buf[0x260]); 75 | + init_size = get_unaligned_le32(&setup_header[0x6F]); 76 | 77 | #ifdef CONFIG_EFI_STUB 78 | /* 79 | @@ -560,7 +564,7 @@ int main(int argc, char **argv) 80 | 81 | if (init_size - _end < setup_size + _ehead) { 82 | init_size = round_up(setup_size + _ehead + _end, SECTION_ALIGNMENT); 83 | - put_unaligned_le32(init_size, &buf[0x260]); 84 | + put_unaligned_le32(init_size, &setup_header[0x6F]); 85 | } 86 | 87 | total_size = update_pecoff_sections(setup_size, kern_size, init_size); 88 | @@ -579,8 +583,9 @@ int main(int argc, char **argv) 89 | 90 | #ifdef CONFIG_EFI_STUB 91 | /* Copy the setup header */ 92 | - memcpy(output + setup_size + efi_boot_params + 0x1f1, &buf[0x1f1], 93 | - 0x290 - 0x1f1 /* == max possible sizeof(struct setup_header) */); 94 | + memcpy(output + setup_size + efi_boot_params + SETUP_HEADER_OFFSET, 95 | + setup_header, 0x290 - SETUP_HEADER_OFFSET 96 | + /* == max possible sizeof(struct setup_header) */); 97 | #endif 98 | 99 | /* Calculate and write kernel checksum. */ 100 | -- 101 | 2.40.1 102 | 103 | -------------------------------------------------------------------------------- /tinylinux/patches/linux/v5.10.179/0028-x86-build-set-type_of_loader-for-EFISTUB.patch: -------------------------------------------------------------------------------- 1 | From 03f086531c1b72f95b38a77dc4c59d3211080682 Mon Sep 17 00:00:00 2001 2 | Message-Id: <> 3 | In-Reply-To: <> 4 | References: <> 5 | From: Evgeniy Baskov <> 6 | Date: Mon, 13 Mar 2023 13:43:24 +0300 7 | Subject: [PATCH 28/39] x86/build: set type_of_loader for EFISTUB 8 | 9 | After switching to the local copy of bootparams, EFISTUB stopped 10 | setting type_of_loader, using the default value of 0. Restore that 11 | behavior by assigning the right value at the build time. 12 | 13 | Signed-off-by: Evgeniy Baskov <> 14 | --- 15 | arch/x86/boot/tools/build.c | 2 ++ 16 | 1 file changed, 2 insertions(+) 17 | 18 | diff --git a/arch/x86/boot/tools/build.c b/arch/x86/boot/tools/build.c 19 | index 99cfe7724d4d..cd9fe2bf2c87 100644 20 | --- a/arch/x86/boot/tools/build.c 21 | +++ b/arch/x86/boot/tools/build.c 22 | @@ -586,6 +586,8 @@ int main(int argc, char **argv) 23 | memcpy(output + setup_size + efi_boot_params + SETUP_HEADER_OFFSET, 24 | setup_header, 0x290 - SETUP_HEADER_OFFSET 25 | /* == max possible sizeof(struct setup_header) */); 26 | + /* Set type_of_loader to the one that EFISTUB uses for the local copy */ 27 | + output[setup_size + efi_boot_params + SETUP_HEADER_OFFSET + 0x1E] = 0x21; 28 | #endif 29 | 30 | /* Calculate and write kernel checksum. */ 31 | -- 32 | 2.40.1 33 | 34 | -------------------------------------------------------------------------------- /tinylinux/patches/linux/v5.10.179/0029-efi-libstub-Don-t-set-ramdisk_image-ramdisk_size.patch: -------------------------------------------------------------------------------- 1 | From 869380d44b2338d59295cf0f6be90cba325b6ba0 Mon Sep 17 00:00:00 2001 2 | Message-Id: <> 3 | In-Reply-To: <> 4 | References: <> 5 | From: Evgeniy Baskov <> 6 | Date: Mon, 13 Mar 2023 15:34:07 +0300 7 | Subject: [PATCH 29/39] efi/libstub: Don't set ramdisk_image/ramdisk_size 8 | 9 | The local copy of the boot_params made during build time is used now, 10 | so setting ramdisk_image/ramdisk_size fields is no longer needed, 11 | since they are already set to 0. 12 | 13 | Remove no longer required assignments. 14 | 15 | Signed-off-by: Evgeniy Baskov <> 16 | --- 17 | drivers/firmware/efi/libstub/x86-stub.c | 3 --- 18 | 1 file changed, 3 deletions(-) 19 | 20 | diff --git a/drivers/firmware/efi/libstub/x86-stub.c b/drivers/firmware/efi/libstub/x86-stub.c 21 | index 08d3428fb860..cec866ed9b7a 100644 22 | --- a/drivers/firmware/efi/libstub/x86-stub.c 23 | +++ b/drivers/firmware/efi/libstub/x86-stub.c 24 | @@ -389,9 +389,6 @@ efi_status_t __efiapi efi_pe_entry(efi_handle_t handle, 25 | efi_set_u64_split((unsigned long)cmdline_ptr, &hdr->cmd_line_ptr, 26 | &efi_boot_params.ext_cmd_line_ptr); 27 | 28 | - hdr->ramdisk_image = 0; 29 | - hdr->ramdisk_size = 0; 30 | - 31 | efi_stub_entry(handle, sys_table_arg, &efi_boot_params); 32 | /* not reached */ 33 | 34 | -- 35 | 2.40.1 36 | 37 | -------------------------------------------------------------------------------- /tinylinux/patches/linux/v5.10.179/0031-efi-libstub-Add-memory-attribute-protocol-definition.patch: -------------------------------------------------------------------------------- 1 | From cbc09cd49d4504073bdaa007792a206125928d44 Mon Sep 17 00:00:00 2001 2 | Message-Id: <> 3 | In-Reply-To: <> 4 | References: <> 5 | From: Evgeniy Baskov <> 6 | Date: Thu, 11 May 2023 18:16:47 +0300 7 | Subject: [PATCH 31/39] efi/libstub: Add memory attribute protocol definitions 8 | 9 | EFI_MEMORY_ATTRIBUTE_PROTOCOL servers as a better alternative to 10 | DXE services for setting memory attributes in EFI Boot Services 11 | environment. This protocol is better since it is a part of UEFI 12 | specification itself and not UEFI PI specification like DXE 13 | services. 14 | 15 | Add EFI_MEMORY_ATTRIBUTE_PROTOCOL definitions. 16 | Support mixed mode properly for its calls. 17 | 18 | Signed-off-by: Evgeniy Baskov <> 19 | --- 20 | arch/x86/include/asm/efi.h | 7 +++++++ 21 | drivers/firmware/efi/libstub/efistub.h | 20 ++++++++++++++++++++ 22 | include/linux/efi.h | 1 + 23 | 3 files changed, 28 insertions(+) 24 | 25 | diff --git a/arch/x86/include/asm/efi.h b/arch/x86/include/asm/efi.h 26 | index 6cae68a39ef2..33410789fa00 100644 27 | --- a/arch/x86/include/asm/efi.h 28 | +++ b/arch/x86/include/asm/efi.h 29 | @@ -317,6 +317,13 @@ static inline u32 efi64_convert_status(efi_status_t status) 30 | #define __efi64_argmap_set_memory_space_attributes(phys, size, flags) \ 31 | (__efi64_split(phys), __efi64_split(size), __efi64_split(flags)) 32 | 33 | +/* Memory Attribute Protocol */ 34 | +#define __efi64_argmap_set_memory_attributes(protocol, phys, size, flags) \ 35 | + ((protocol), __efi64_split(phys), __efi64_split(size), __efi64_split(flags)) 36 | + 37 | +#define __efi64_argmap_clear_memory_attributes(protocol, phys, size, flags) \ 38 | + ((protocol), __efi64_split(phys), __efi64_split(size), __efi64_split(flags)) 39 | + 40 | /* 41 | * The macros below handle the plumbing for the argument mapping. To add a 42 | * mapping for a specific EFI method, simply define a macro 43 | diff --git a/drivers/firmware/efi/libstub/efistub.h b/drivers/firmware/efi/libstub/efistub.h 44 | index 08233aea572e..ec4dd5530a36 100644 45 | --- a/drivers/firmware/efi/libstub/efistub.h 46 | +++ b/drivers/firmware/efi/libstub/efistub.h 47 | @@ -404,6 +404,26 @@ union efi_dxe_services_table { 48 | } mixed_mode; 49 | }; 50 | 51 | +typedef union efi_memory_attribute_protocol efi_memory_attribute_protocol_t; 52 | + 53 | +union efi_memory_attribute_protocol { 54 | + struct { 55 | + efi_status_t (__efiapi *get_memory_attributes)( 56 | + efi_memory_attribute_protocol_t *, efi_physical_addr_t, u64, u64 *); 57 | + 58 | + efi_status_t (__efiapi *set_memory_attributes)( 59 | + efi_memory_attribute_protocol_t *, efi_physical_addr_t, u64, u64); 60 | + 61 | + efi_status_t (__efiapi *clear_memory_attributes)( 62 | + efi_memory_attribute_protocol_t *, efi_physical_addr_t, u64, u64); 63 | + }; 64 | + struct { 65 | + u32 get_memory_attributes; 66 | + u32 set_memory_attributes; 67 | + u32 clear_memory_attributes; 68 | + } mixed_mode; 69 | +}; 70 | + 71 | typedef union efi_uga_draw_protocol efi_uga_draw_protocol_t; 72 | 73 | union efi_uga_draw_protocol { 74 | diff --git a/include/linux/efi.h b/include/linux/efi.h 75 | index f5bbc1979a64..7bb79a81c9f6 100644 76 | --- a/include/linux/efi.h 77 | +++ b/include/linux/efi.h 78 | @@ -342,6 +342,7 @@ void efi_native_runtime_setup(void); 79 | #define EFI_LOAD_FILE2_PROTOCOL_GUID EFI_GUID(0x4006c0c1, 0xfcb3, 0x403e, 0x99, 0x6d, 0x4a, 0x6c, 0x87, 0x24, 0xe0, 0x6d) 80 | #define EFI_RT_PROPERTIES_TABLE_GUID EFI_GUID(0xeb66918a, 0x7eef, 0x402a, 0x84, 0x2e, 0x93, 0x1d, 0x21, 0xc3, 0x8a, 0xe9) 81 | #define EFI_DXE_SERVICES_TABLE_GUID EFI_GUID(0x05ad34ba, 0x6f02, 0x4214, 0x95, 0x2e, 0x4d, 0xa0, 0x39, 0x8e, 0x2b, 0xb9) 82 | +#define EFI_MEMORY_ATTRIBUTE_PROTOCOL_GUID EFI_GUID(0xf4560cf6, 0x40ec, 0x4b4a, 0xa1, 0x92, 0xbf, 0x1d, 0x57, 0xd0, 0xb1, 0x89) 83 | 84 | #define EFI_IMAGE_SECURITY_DATABASE_GUID EFI_GUID(0xd719b2cb, 0x3d3a, 0x4596, 0xa3, 0xbc, 0xda, 0xd0, 0x0e, 0x67, 0x65, 0x6f) 85 | #define EFI_SHIM_LOCK_GUID EFI_GUID(0x605dab50, 0xe046, 0x4300, 0xab, 0xb6, 0x3d, 0xd8, 0x10, 0xdd, 0x8b, 0x23) 86 | -- 87 | 2.40.1 88 | 89 | -------------------------------------------------------------------------------- /tinylinux/patches/linux/v5.10.179/0033-efi-libstub-make-memory-protection-warnings-include-.patch: -------------------------------------------------------------------------------- 1 | From 53e17f52455c586cb01433ff02d5e58a0bb7420f Mon Sep 17 00:00:00 2001 2 | Message-Id: <> 3 | In-Reply-To: <> 4 | References: <> 5 | From: Peter Jones <> 6 | Date: Tue, 18 Oct 2022 16:51:18 -0400 7 | Subject: [PATCH 33/39] efi/libstub: make memory protection warnings include 8 | newlines. 9 | 10 | efi_warn() doesn't put newlines on messages, and that makes reading 11 | warnings without newlines hard to do. 12 | 13 | Signed-off-by: Peter Jones <> 14 | --- 15 | drivers/firmware/efi/libstub/mem.c | 4 ++-- 16 | 1 file changed, 2 insertions(+), 2 deletions(-) 17 | 18 | diff --git a/drivers/firmware/efi/libstub/mem.c b/drivers/firmware/efi/libstub/mem.c 19 | index 113d5786ac85..6d3dcdeedf4a 100644 20 | --- a/drivers/firmware/efi/libstub/mem.c 21 | +++ b/drivers/firmware/efi/libstub/mem.c 22 | @@ -300,7 +300,7 @@ efi_status_t efi_adjust_memory_range_protection(unsigned long start, 23 | rounded_end - rounded_start, 24 | attr_clear); 25 | if (status != EFI_SUCCESS) { 26 | - efi_warn("Failed to clear memory attributes at [%08lx,%08lx]: %lx", 27 | + efi_warn("Failed to clear memory attributes at [%08lx,%08lx]: %lx\n", 28 | (unsigned long)rounded_start, 29 | (unsigned long)rounded_end, 30 | status); 31 | @@ -313,7 +313,7 @@ efi_status_t efi_adjust_memory_range_protection(unsigned long start, 32 | rounded_end - rounded_start, 33 | attributes); 34 | if (status != EFI_SUCCESS) { 35 | - efi_warn("Failed to set memory attributes at [%08lx,%08lx]: %lx", 36 | + efi_warn("Failed to set memory attributes at [%08lx,%08lx]: %lx\n", 37 | (unsigned long)rounded_start, 38 | (unsigned long)rounded_end, 39 | status); 40 | -- 41 | 2.40.1 42 | 43 | -------------------------------------------------------------------------------- /tinylinux/patches/linux/v5.10.179/0034-efi-x86-don-t-try-to-set-page-attributes-on-0-sized-.patch: -------------------------------------------------------------------------------- 1 | From 2280f10647abbf8b9a1ee58f2755b30e954fe0c4 Mon Sep 17 00:00:00 2001 2 | Message-Id: <> 3 | In-Reply-To: <> 4 | References: <> 5 | From: Peter Jones <> 6 | Date: Tue, 13 Dec 2022 17:59:01 +0000 7 | Subject: [PATCH 34/39] efi/x86: don't try to set page attributes on 0-sized 8 | regions. 9 | 10 | In "efi/x86: Explicitly set sections memory attributes", the following 11 | region is defined to help compute page permissions: 12 | 13 | /* .setup [image_base, _head] */ 14 | efi_adjust_memory_range_protection(image_base, 15 | (unsigned long)_head - image_base, 16 | EFI_MEMORY_RO | EFI_MEMORY_XP); 17 | 18 | In at least some cases, that will result in a size of 0, which will 19 | produce an error and a message on the console, though no actual failure 20 | will be caused in the boot process. 21 | 22 | This patch checks that case in efi_adjust_memory_range_protection() and 23 | returns the error without logging. 24 | 25 | Signed-off-by: Peter Jones <> 26 | --- 27 | drivers/firmware/efi/libstub/mem.c | 3 +++ 28 | 1 file changed, 3 insertions(+) 29 | 30 | diff --git a/drivers/firmware/efi/libstub/mem.c b/drivers/firmware/efi/libstub/mem.c 31 | index 6d3dcdeedf4a..89691b35e4ef 100644 32 | --- a/drivers/firmware/efi/libstub/mem.c 33 | +++ b/drivers/firmware/efi/libstub/mem.c 34 | @@ -253,6 +253,9 @@ efi_status_t efi_adjust_memory_range_protection(unsigned long start, 35 | efi_physical_addr_t rounded_start, rounded_end; 36 | unsigned long attr_clear; 37 | 38 | + if (size == 0) 39 | + return EFI_INVALID_PARAMETER; 40 | + 41 | /* 42 | * This function should not be used to modify attributes 43 | * other than writable/executable. 44 | -- 45 | 2.40.1 46 | 47 | -------------------------------------------------------------------------------- /tinylinux/patches/linux/v5.10.179/0035-x86-boot-Add-strlcat-and-strscpy-to-compressed-kerne.patch: -------------------------------------------------------------------------------- 1 | From 74969f3422af0a6673945fef58c483c20d3523e4 Mon Sep 17 00:00:00 2001 2 | Message-Id: <> 3 | In-Reply-To: <> 4 | References: <> 5 | From: Evgeniy Baskov <> 6 | Date: Wed, 4 May 2022 22:51:19 +0300 7 | Subject: [PATCH 35/39] x86/boot: Add strlcat() and strscpy() to compressed 8 | kernel 9 | 10 | These functions simplify the code of command line concatenation 11 | helper and reduce the probability of mistakes. 12 | 13 | Use simpler implementation of strscpy than used in it kernel itself 14 | to avoid code bloat in compressed kernel. 15 | 16 | Signed-off-by: Evgeniy Baskov <> 17 | --- 18 | arch/x86/boot/compressed/string.c | 50 +++++++++++++++++++++++++++++++ 19 | arch/x86/purgatory/purgatory.c | 1 + 20 | 2 files changed, 51 insertions(+) 21 | 22 | diff --git a/arch/x86/boot/compressed/string.c b/arch/x86/boot/compressed/string.c 23 | index 81fc1eaa3229..5c193fa0a09b 100644 24 | --- a/arch/x86/boot/compressed/string.c 25 | +++ b/arch/x86/boot/compressed/string.c 26 | @@ -40,6 +40,56 @@ static void *____memcpy(void *dest, const void *src, size_t n) 27 | } 28 | #endif 29 | 30 | +size_t strlcat(char *dest, const char *src, size_t count) 31 | +{ 32 | + size_t dsize = strlen(dest); 33 | + size_t len = strlen(src); 34 | + size_t res = dsize + len; 35 | + 36 | + /* This would be a bug */ 37 | + if (dsize >= count) 38 | + error("strlcat(): destination too big\n"); 39 | + 40 | + dest += dsize; 41 | + count -= dsize; 42 | + if (len >= count) 43 | + len = count-1; 44 | + memcpy(dest, src, len); 45 | + dest[len] = 0; 46 | + return res; 47 | +} 48 | + 49 | +/* Don't include word-at-a-time code path in compressed kernel for simplicity */ 50 | +size_t strscpy(char *dest, const char *src, size_t count) 51 | +{ 52 | + long res = 0; 53 | + 54 | + if (count == 0) 55 | + return -E2BIG; 56 | + 57 | + if (count > INT_MAX) { 58 | + warn("strscpy(): Count is too big"); 59 | + return -E2BIG; 60 | + } 61 | + 62 | + while (count) { 63 | + char c; 64 | + 65 | + c = src[res]; 66 | + dest[res] = c; 67 | + if (!c) 68 | + return res; 69 | + res++; 70 | + count--; 71 | + } 72 | + 73 | + /* Hit buffer length without finding a NUL; force NUL-termination. */ 74 | + if (res) 75 | + dest[res-1] = '\0'; 76 | + 77 | + return -E2BIG; 78 | +} 79 | + 80 | void *memset(void *s, int c, size_t n) 81 | { 82 | int i; 83 | diff --git a/arch/x86/purgatory/purgatory.c b/arch/x86/purgatory/purgatory.c 84 | index 7b37a412f829..b621411d0027 100644 85 | --- a/arch/x86/purgatory/purgatory.c 86 | +++ b/arch/x86/purgatory/purgatory.c 87 | @@ -55,3 +55,4 @@ void purgatory(void) 88 | * arch/x86/boot/compressed/string.c 89 | */ 90 | void warn(const char *msg) {} 91 | +void error(char *m) {} 92 | -- 93 | 2.40.1 94 | 95 | -------------------------------------------------------------------------------- /tinylinux/patches/linux/v5.10.179/0036-x86-Add-cmdline_prepare-helper.patch: -------------------------------------------------------------------------------- 1 | From 5c3296a97ebc1df9f53ba087906187fd814a89de Mon Sep 17 00:00:00 2001 2 | Message-Id: <> 3 | In-Reply-To: <> 4 | References: <> 5 | From: Evgeniy Baskov <> 6 | Date: Wed, 4 May 2022 22:54:08 +0300 7 | Subject: [PATCH 36/39] x86: Add cmdline_prepare() helper 8 | 9 | Command line needs to be combined in both compressed and uncompressed 10 | kernel from built-in and boot command line strings, which requires 11 | non-trivial logic depending on CONFIG_CMDLINE_BOOL and 12 | CONFIG_CMDLINE_OVERRIDE. 13 | 14 | Add a helper function to avoid code duplication. 15 | 16 | Signed-off-by: Evgeniy Baskov <> 17 | --- 18 | arch/x86/include/asm/shared/cmdline.h | 35 +++++++++++++++++++++++++++ 19 | 1 file changed, 35 insertions(+) 20 | create mode 100644 arch/x86/include/asm/shared/cmdline.h 21 | 22 | diff --git a/arch/x86/include/asm/shared/cmdline.h b/arch/x86/include/asm/shared/cmdline.h 23 | new file mode 100644 24 | index 000000000000..119f8b93f8e6 25 | --- /dev/null 26 | +++ b/arch/x86/include/asm/shared/cmdline.h 27 | @@ -0,0 +1,35 @@ 28 | +/* SPDX-License-Identifier: GPL-2.0 */ 29 | + 30 | +#ifndef _ASM_X86_SETUP_CMDLINE_H 31 | +#define _ASM_X86_SETUP_CMDLINE_H 32 | + 33 | +#define _SETUP 34 | +#include /* For COMMAND_LINE_SIZE */ 35 | +#undef _SETUP 36 | + 37 | +#include 38 | + 39 | +#ifdef CONFIG_CMDLINE_BOOL 40 | +#define COMMAND_LINE_INIT CONFIG_CMDLINE 41 | +#else 42 | +#define COMMAND_LINE_INIT "" 43 | +#endif 44 | + 45 | +/* 46 | + * command_line and boot_command_line are expected to be at most 47 | + * COMMAND_LINE_SIZE length. command_line needs to be initialized 48 | + * with COMMAND_LINE_INIT. 49 | + */ 50 | +static inline void cmdline_prepare(char *command_line, 51 | + const char *boot_command_line) 52 | +{ 53 | + if (!IS_ENABLED(CONFIG_CMDLINE_BOOL)) { 54 | + strscpy(command_line, boot_command_line, COMMAND_LINE_SIZE); 55 | + } else if (!IS_ENABLED(CONFIG_CMDLINE_OVERRIDE)) { 56 | + /* Append boot loader cmdline to builtin one. */ 57 | + strlcat(command_line, " ", COMMAND_LINE_SIZE); 58 | + strlcat(command_line, boot_command_line, COMMAND_LINE_SIZE); 59 | + } 60 | +} 61 | + 62 | +#endif /* _ASM_X86_SETUP_CMDLINE_H */ 63 | -- 64 | 2.40.1 65 | 66 | -------------------------------------------------------------------------------- /tinylinux/patches/linux/v5.10.179/0037-x86-setup-Use-cmdline_prepare-in-setup.c.patch: -------------------------------------------------------------------------------- 1 | From 70dcd8e5669c41a5b74d9a40cd4e5a11c9774674 Mon Sep 17 00:00:00 2001 2 | Message-Id: <> 3 | In-Reply-To: <> 4 | References: <> 5 | From: Evgeniy Baskov <> 6 | Date: Tue, 13 Dec 2022 13:56:17 +0300 7 | Subject: [PATCH 37/39] x86/setup: Use cmdline_prepare() in setup.c 8 | 9 | Use a common helper function for command line resolving in 10 | arch/x86/kernel/setup.c for code unification. 11 | 12 | Signed-off-by: Evgeniy Baskov <> 13 | --- 14 | arch/x86/kernel/setup.c | 22 ++++------------------ 15 | 1 file changed, 4 insertions(+), 18 deletions(-) 16 | 17 | diff --git a/arch/x86/kernel/setup.c b/arch/x86/kernel/setup.c 18 | index 065152d9265e..b41268f70161 100644 19 | --- a/arch/x86/kernel/setup.c 20 | +++ b/arch/x86/kernel/setup.c 21 | @@ -45,6 +45,7 @@ 22 | #include 23 | #include 24 | #include 25 | +#include 26 | #include 27 | #include 28 | #include 29 | @@ -166,10 +167,7 @@ unsigned long saved_video_mode; 30 | #define RAMDISK_PROMPT_FLAG 0x8000 31 | #define RAMDISK_LOAD_FLAG 0x4000 32 | 33 | -static char __initdata command_line[COMMAND_LINE_SIZE]; 34 | -#ifdef CONFIG_CMDLINE_BOOL 35 | -static char __initdata builtin_cmdline[COMMAND_LINE_SIZE] = CONFIG_CMDLINE; 36 | -#endif 37 | +static char command_line[COMMAND_LINE_SIZE] __initdata = COMMAND_LINE_INIT; 38 | 39 | #if defined(CONFIG_EDD) || defined(CONFIG_EDD_MODULE) 40 | struct edd edd; 41 | @@ -909,20 +907,8 @@ void __init setup_arch(char **cmdline_p) 42 | bss_resource.start = __pa_symbol(__bss_start); 43 | bss_resource.end = __pa_symbol(__bss_stop)-1; 44 | 45 | -#ifdef CONFIG_CMDLINE_BOOL 46 | -#ifdef CONFIG_CMDLINE_OVERRIDE 47 | - strlcpy(boot_command_line, builtin_cmdline, COMMAND_LINE_SIZE); 48 | -#else 49 | - if (builtin_cmdline[0]) { 50 | - /* append boot loader cmdline to builtin */ 51 | - strlcat(builtin_cmdline, " ", COMMAND_LINE_SIZE); 52 | - strlcat(builtin_cmdline, boot_command_line, COMMAND_LINE_SIZE); 53 | - strlcpy(boot_command_line, builtin_cmdline, COMMAND_LINE_SIZE); 54 | - } 55 | -#endif 56 | -#endif 57 | - 58 | - strlcpy(command_line, boot_command_line, COMMAND_LINE_SIZE); 59 | + cmdline_prepare(command_line, boot_command_line); 60 | + strscpy(boot_command_line, command_line, COMMAND_LINE_SIZE); 61 | *cmdline_p = command_line; 62 | 63 | /* 64 | -- 65 | 2.40.1 66 | 67 | -------------------------------------------------------------------------------- /tinylinux/patches/linux/v5.10.179/0038-x86-boot-Use-cmdline_prapare-in-compressed-kernel.patch: -------------------------------------------------------------------------------- 1 | From bc21f837e1456e64aa9d43005a9c98ae7df9fc18 Mon Sep 17 00:00:00 2001 2 | Message-Id: <> 3 | In-Reply-To: <> 4 | References: <> 5 | From: Evgeniy Baskov <> 6 | Date: Tue, 13 Dec 2022 13:57:50 +0300 7 | Subject: [PATCH 38/39] x86/boot: Use cmdline_prapare() in compressed kernel 8 | 9 | CONFIG_CMDLINE_BOOL and CONFIG_CMDLINE_OVERRIDE were ignored during 10 | options lookup in compressed kernel, including earlyprintk option, 11 | so it was impossible to get earlyprintk messages from that stage 12 | of boot process via command line provided at compile time. 13 | Being able to enable earlyprintk via compile-time option might 14 | be desirable for booting on systems with broken UEFI command line 15 | arguments via EFISTUB. 16 | 17 | Use a common helper function to handle CONFIG_CMDLINE_* in compressed 18 | kernel. 19 | 20 | Place command_line_init explicitly in '.data' section since it is 21 | used before '.bss' section is zeroed and it is expected to be equal 22 | to zero. 23 | 24 | Signed-off-by: Evgeniy Baskov <> 25 | --- 26 | arch/x86/boot/compressed/cmdline.c | 24 ++++++++++++++++++++++-- 27 | arch/x86/boot/compressed/misc.h | 1 + 28 | 2 files changed, 23 insertions(+), 2 deletions(-) 29 | 30 | diff --git a/arch/x86/boot/compressed/cmdline.c b/arch/x86/boot/compressed/cmdline.c 31 | index f1add5d85da9..717f450662aa 100644 32 | --- a/arch/x86/boot/compressed/cmdline.c 33 | +++ b/arch/x86/boot/compressed/cmdline.c 34 | @@ -12,6 +12,15 @@ static inline char rdfs8(addr_t addr) 35 | return *((char *)(fs + addr)); 36 | } 37 | #include "../cmdline.c" 38 | + 39 | +static char command_line[COMMAND_LINE_SIZE] __section(".data") = COMMAND_LINE_INIT; 40 | +static bool command_line_init __section(".data"); 41 | + 42 | +/* 43 | + * This always returns runtime command line and does not account for built-in 44 | + * command line, so this should not be used for cmdline parsing. 45 | + * Use get_cmdline() instead. 46 | + */ 47 | unsigned long get_cmd_line_ptr(void) 48 | { 49 | unsigned long cmd_line_ptr = boot_params->hdr.cmd_line_ptr; 50 | @@ -20,11 +29,22 @@ unsigned long get_cmd_line_ptr(void) 51 | 52 | return cmd_line_ptr; 53 | } 54 | + 55 | +static inline unsigned long get_cmdline(void) 56 | +{ 57 | + if (!command_line_init) { 58 | + cmdline_prepare(command_line, (char *)get_cmd_line_ptr()); 59 | + command_line_init = 1; 60 | + } 61 | + 62 | + return (unsigned long)command_line; 63 | +} 64 | + 65 | int cmdline_find_option(const char *option, char *buffer, int bufsize) 66 | { 67 | - return __cmdline_find_option(get_cmd_line_ptr(), option, buffer, bufsize); 68 | + return __cmdline_find_option(get_cmdline(), option, buffer, bufsize); 69 | } 70 | int cmdline_find_option_bool(const char *option) 71 | { 72 | - return __cmdline_find_option_bool(get_cmd_line_ptr(), option); 73 | + return __cmdline_find_option_bool(get_cmdline(), option); 74 | } 75 | diff --git a/arch/x86/boot/compressed/misc.h b/arch/x86/boot/compressed/misc.h 76 | index 3be97e6a2af5..6036a1dc213f 100644 77 | --- a/arch/x86/boot/compressed/misc.h 78 | +++ b/arch/x86/boot/compressed/misc.h 79 | @@ -25,6 +25,7 @@ 80 | #include 81 | #include 82 | #include 83 | +#include 84 | 85 | #define BOOT_CTYPE_H 86 | #include 87 | -- 88 | 2.40.1 89 | 90 | -------------------------------------------------------------------------------- /tinylinux/patches/linux/v5.10.179/0039-x86-boot-Remove-no-longer-needed-includes.patch: -------------------------------------------------------------------------------- 1 | From 1959e515c0c56b0b416bbad04e81dc58d694137c Mon Sep 17 00:00:00 2001 2 | Message-Id: <> 3 | In-Reply-To: <> 4 | References: <> 5 | From: Evgeniy Baskov <> 6 | Date: Tue, 13 Dec 2022 13:59:06 +0300 7 | Subject: [PATCH 39/39] x86/boot: Remove no longer needed includes 8 | 9 | x86/incldue/asm/shared/cmdline.h header already provides 10 | COMMAND_LINE_SIZE definition. 11 | 12 | Signed-off-by: Evgeniy Baskov <> 13 | --- 14 | arch/x86/boot/compressed/ident_map_64.c | 4 ---- 15 | arch/x86/boot/compressed/kaslr.c | 4 ---- 16 | 2 files changed, 8 deletions(-) 17 | 18 | diff --git a/arch/x86/boot/compressed/ident_map_64.c b/arch/x86/boot/compressed/ident_map_64.c 19 | index d131ca7fcc2a..008e7f00401d 100644 20 | --- a/arch/x86/boot/compressed/ident_map_64.c 21 | +++ b/arch/x86/boot/compressed/ident_map_64.c 22 | @@ -35,10 +35,6 @@ 23 | #define __PAGE_OFFSET __PAGE_OFFSET_BASE 24 | #include "../../mm/ident_map.c" 25 | 26 | -#define _SETUP 27 | -#include /* For COMMAND_LINE_SIZE */ 28 | -#undef _SETUP 29 | - 30 | extern unsigned long get_cmd_line_ptr(void); 31 | 32 | /* Used by PAGE_KERN* macros: */ 33 | diff --git a/arch/x86/boot/compressed/kaslr.c b/arch/x86/boot/compressed/kaslr.c 34 | index 39fd1f881e66..c36f094bda6c 100644 35 | --- a/arch/x86/boot/compressed/kaslr.c 36 | +++ b/arch/x86/boot/compressed/kaslr.c 37 | @@ -36,10 +36,6 @@ 38 | #define STATIC 39 | #include 40 | 41 | -#define _SETUP 42 | -#include /* For COMMAND_LINE_SIZE */ 43 | -#undef _SETUP 44 | - 45 | extern unsigned long get_cmd_line_ptr(void); 46 | 47 | /* Simplified build-specific string for starting entropy. */ 48 | -- 49 | 2.40.1 50 | 51 | -------------------------------------------------------------------------------- /tinylinux/patches/linux/v6.3/v5-0001-x86-boot-Align-vmlinuz-sections-on-page-size.patch: -------------------------------------------------------------------------------- 1 | From 43e368ff943c2278e5642eaaa4d5171ba3b4fb26 Mon Sep 17 00:00:00 2001 2 | Message-Id: <...> 3 | In-Reply-To: <...> 4 | References: <...> 5 | From: Evgeniy Baskov <...> 6 | To: Ard Biesheuvel <...> 7 | Cc: Borislav Petkov <...> 8 | Cc: Andy Lutomirski <...> 9 | Cc: Dave Hansen <...> 10 | Cc: Ingo Molnar <...> 11 | Cc: Peter Zijlstra <...> 12 | Cc: Thomas Gleixner <...> 13 | Cc: Alexey Khoroshilov <...> 14 | Cc: Peter Jones <...> 15 | Cc: "Limonciello, Mario" <...> 16 | Cc: joeyli <...> 17 | Cc: ... 18 | Cc: ... 19 | Cc: ... 20 | Cc: ... 21 | Cc: ... 22 | Date: Thu, 9 Jun 2022 18:01:49 +0300 23 | Subject: [PATCH v5 01/23] x86/boot: Align vmlinuz sections on page size 24 | 25 | To protect sections on page table level each section 26 | needs to be aligned on page size (4KB). 27 | 28 | Set sections alignment in linker script. 29 | 30 | Tested-by: Mario Limonciello <...> 31 | Signed-off-by: Evgeniy Baskov <...> 32 | --- 33 | arch/x86/boot/compressed/vmlinux.lds.S | 6 ++++++ 34 | 1 file changed, 6 insertions(+) 35 | 36 | diff --git a/arch/x86/boot/compressed/vmlinux.lds.S b/arch/x86/boot/compressed/vmlinux.lds.S 37 | index b22f34b8684a..f339404041a1 100644 38 | --- a/arch/x86/boot/compressed/vmlinux.lds.S 39 | +++ b/arch/x86/boot/compressed/vmlinux.lds.S 40 | @@ -27,9 +27,13 @@ SECTIONS 41 | HEAD_TEXT 42 | _ehead = . ; 43 | } 44 | + . = ALIGN(PAGE_SIZE); 45 | .rodata..compressed : { 46 | + _compressed = .; 47 | *(.rodata..compressed) 48 | + _ecompressed = .; 49 | } 50 | + . = ALIGN(PAGE_SIZE); 51 | .text : { 52 | _text = .; /* Text */ 53 | *(.text) 54 | @@ -37,12 +41,14 @@ SECTIONS 55 | *(.noinstr.text) 56 | _etext = . ; 57 | } 58 | + . = ALIGN(PAGE_SIZE); 59 | .rodata : { 60 | _rodata = . ; 61 | *(.rodata) /* read-only data */ 62 | *(.rodata.*) 63 | _erodata = . ; 64 | } 65 | + . = ALIGN(PAGE_SIZE); 66 | .data : { 67 | _data = . ; 68 | *(.data) 69 | -- 70 | 2.39.2 71 | 72 | -------------------------------------------------------------------------------- /tinylinux/patches/linux/v6.3/v5-0002-x86-build-Remove-RWX-sections-and-align-on-4KB.patch: -------------------------------------------------------------------------------- 1 | From d5d3fbfa1ec0c727d2a5efa360e1e73f57288863 Mon Sep 17 00:00:00 2001 2 | Message-Id: <...> 3 | In-Reply-To: <...> 4 | References: <...> 5 | From: Evgeniy Baskov <...> 6 | To: Ard Biesheuvel <...> 7 | Cc: Borislav Petkov <...> 8 | Cc: Andy Lutomirski <...> 9 | Cc: Dave Hansen <...> 10 | Cc: Ingo Molnar <...> 11 | Cc: Peter Zijlstra <...> 12 | Cc: Thomas Gleixner <...> 13 | Cc: Alexey Khoroshilov <...> 14 | Cc: Peter Jones <...> 15 | Cc: "Limonciello, Mario" <...> 16 | Cc: joeyli <...> 17 | Cc: ... 18 | Cc: ... 19 | Cc: ... 20 | Cc: ... 21 | Cc: ... 22 | Date: Thu, 9 Jun 2022 18:04:38 +0300 23 | Subject: [PATCH v5 02/23] x86/build: Remove RWX sections and align on 4KB 24 | 25 | Avoid creating sections simultaneously writable and readable 26 | to prepare for W^X implementation. Align sections on page size (4KB) to 27 | allow protecting them in the page tables. 28 | 29 | Split init code form ".init" segment into separate R_X ".inittext" 30 | segment and make ".init" segment non-executable. 31 | 32 | Also add these segments to x86_32 architecture for consistency. 33 | Currently paging is disabled in x86_32 in compressed kernel, so 34 | protection is not applied anyways, but .init code was incorrectly 35 | placed in non-executable ".data" segment. This should not change 36 | anything meaningful in memory layout now, but might be required in case 37 | memory protection will also be implemented in compressed kernel for 38 | x86_32. 39 | 40 | Tested-by: Mario Limonciello <...> 41 | Signed-off-by: Evgeniy Baskov <...> 42 | --- 43 | arch/x86/kernel/vmlinux.lds.S | 15 ++++++++------- 44 | 1 file changed, 8 insertions(+), 7 deletions(-) 45 | 46 | diff --git a/arch/x86/kernel/vmlinux.lds.S b/arch/x86/kernel/vmlinux.lds.S 47 | index 25f155205770..81ea1236d293 100644 48 | --- a/arch/x86/kernel/vmlinux.lds.S 49 | +++ b/arch/x86/kernel/vmlinux.lds.S 50 | @@ -102,12 +102,11 @@ jiffies = jiffies_64; 51 | PHDRS { 52 | text PT_LOAD FLAGS(5); /* R_E */ 53 | data PT_LOAD FLAGS(6); /* RW_ */ 54 | -#ifdef CONFIG_X86_64 55 | -#ifdef CONFIG_SMP 56 | +#if defined(CONFIG_X86_64) && defined(CONFIG_SMP) 57 | percpu PT_LOAD FLAGS(6); /* RW_ */ 58 | #endif 59 | - init PT_LOAD FLAGS(7); /* RWE */ 60 | -#endif 61 | + inittext PT_LOAD FLAGS(5); /* R_E */ 62 | + init PT_LOAD FLAGS(6); /* RW_ */ 63 | note PT_NOTE FLAGS(0); /* ___ */ 64 | } 65 | 66 | @@ -226,9 +225,10 @@ SECTIONS 67 | #endif 68 | 69 | INIT_TEXT_SECTION(PAGE_SIZE) 70 | -#ifdef CONFIG_X86_64 71 | - :init 72 | -#endif 73 | + :inittext 74 | + 75 | + . = ALIGN(PAGE_SIZE); 76 | + 77 | 78 | /* 79 | * Section for code used exclusively before alternatives are run. All 80 | @@ -240,6 +240,7 @@ SECTIONS 81 | .altinstr_aux : AT(ADDR(.altinstr_aux) - LOAD_OFFSET) { 82 | *(.altinstr_aux) 83 | } 84 | + :init 85 | 86 | INIT_DATA_SECTION(16) 87 | 88 | -- 89 | 2.39.2 90 | 91 | -------------------------------------------------------------------------------- /tinylinux/patches/linux/v6.3/v5-0003-x86-boot-Set-cr0-to-known-state-in-trampoline.patch: -------------------------------------------------------------------------------- 1 | From 0b55cc0cc16dab08f019e21c44e133b2835dec55 Mon Sep 17 00:00:00 2001 2 | Message-Id: <...> 3 | In-Reply-To: <...> 4 | References: <...> 5 | From: Evgeniy Baskov <...> 6 | To: Ard Biesheuvel <...> 7 | Cc: Borislav Petkov <...> 8 | Cc: Andy Lutomirski <...> 9 | Cc: Dave Hansen <...> 10 | Cc: Ingo Molnar <...> 11 | Cc: Peter Zijlstra <...> 12 | Cc: Thomas Gleixner <...> 13 | Cc: Alexey Khoroshilov <...> 14 | Cc: Peter Jones <...> 15 | Cc: "Limonciello, Mario" <...> 16 | Cc: joeyli <...> 17 | Cc: ... 18 | Cc: ... 19 | Cc: ... 20 | Cc: ... 21 | Cc: ... 22 | Date: Thu, 9 Jun 2022 18:16:24 +0300 23 | Subject: [PATCH v5 03/23] x86/boot: Set cr0 to known state in trampoline 24 | 25 | Ensure WP bit to be set to prevent boot code from writing to 26 | non-writable memory pages. 27 | 28 | Tested-by: Mario Limonciello <...> 29 | Signed-off-by: Evgeniy Baskov <...> 30 | --- 31 | arch/x86/boot/compressed/head_64.S | 5 ++--- 32 | 1 file changed, 2 insertions(+), 3 deletions(-) 33 | 34 | diff --git a/arch/x86/boot/compressed/head_64.S b/arch/x86/boot/compressed/head_64.S 35 | index 03c4328a88cb..01fa42d31648 100644 36 | --- a/arch/x86/boot/compressed/head_64.S 37 | +++ b/arch/x86/boot/compressed/head_64.S 38 | @@ -660,9 +660,8 @@ SYM_CODE_START(trampoline_32bit_src) 39 | pushl $__KERNEL_CS 40 | pushl %eax 41 | 42 | - /* Enable paging again. */ 43 | - movl %cr0, %eax 44 | - btsl $X86_CR0_PG_BIT, %eax 45 | + /* Enable paging and set CR0 to known state (this also sets WP flag) */ 46 | + movl $CR0_STATE, %eax 47 | movl %eax, %cr0 48 | 49 | lret 50 | -- 51 | 2.39.2 52 | 53 | -------------------------------------------------------------------------------- /tinylinux/patches/linux/v6.3/v5-0004-x86-boot-Increase-boot-page-table-size.patch: -------------------------------------------------------------------------------- 1 | From 51cf93f016647fd1a1ffa6e16e61a9ea8e726293 Mon Sep 17 00:00:00 2001 2 | Message-Id: <...> 3 | In-Reply-To: <...> 4 | References: <...> 5 | From: Evgeniy Baskov <...> 6 | To: Ard Biesheuvel <...> 7 | Cc: Borislav Petkov <...> 8 | Cc: Andy Lutomirski <...> 9 | Cc: Dave Hansen <...> 10 | Cc: Ingo Molnar <...> 11 | Cc: Peter Zijlstra <...> 12 | Cc: Thomas Gleixner <...> 13 | Cc: Alexey Khoroshilov <...> 14 | Cc: Peter Jones <...> 15 | Cc: "Limonciello, Mario" <...> 16 | Cc: joeyli <...> 17 | Cc: ... 18 | Cc: ... 19 | Cc: ... 20 | Cc: ... 21 | Cc: ... 22 | Date: Thu, 9 Jun 2022 18:18:32 +0300 23 | Subject: [PATCH v5 04/23] x86/boot: Increase boot page table size 24 | 25 | Previous upper limit ignored pages implicitly mapped from #PF handler 26 | by code accessing ACPI tables (boot/compressed/{acpi.c,efi.c}), 27 | so theoretical upper limit is higher than it was set. 28 | 29 | Using 4KB pages is desirable for better memory protection granularity. 30 | Approximately twice as much memory is required for those. 31 | 32 | Increase initial page table size to 64 4KB page tables. 33 | 34 | Tested-by: Mario Limonciello <...> 35 | Signed-off-by: Evgeniy Baskov <...> 36 | --- 37 | arch/x86/include/asm/boot.h | 28 ++++++++++++++++------------ 38 | 1 file changed, 16 insertions(+), 12 deletions(-) 39 | 40 | diff --git a/arch/x86/include/asm/boot.h b/arch/x86/include/asm/boot.h 41 | index 9191280d9ea3..88836067f88c 100644 42 | --- a/arch/x86/include/asm/boot.h 43 | +++ b/arch/x86/include/asm/boot.h 44 | @@ -41,22 +41,26 @@ 45 | # define BOOT_STACK_SIZE 0x4000 46 | 47 | # define BOOT_INIT_PGT_SIZE (6*4096) 48 | -# ifdef CONFIG_RANDOMIZE_BASE 49 | /* 50 | * Assuming all cross the 512GB boundary: 51 | * 1 page for level4 52 | - * (2+2)*4 pages for kernel, param, cmd_line, and randomized kernel 53 | - * 2 pages for first 2M (video RAM: CONFIG_X86_VERBOSE_BOOTUP). 54 | - * Total is 19 pages. 55 | + * (3+3)*2 pages for param and cmd_line 56 | + * (2+2+S)*2 pages for kernel and randomized kernel, where S is total number 57 | + * of sections of kernel. Explanation: 2+2 are upper level page tables. 58 | + * We can have only S unaligned parts of section: 1 at the end of the kernel 59 | + * and (S-1) at the section borders. The start address of the kernel is 60 | + * aligned, so an extra page table. There are at most S=6 sections in 61 | + * vmlinux ELF image. 62 | + * 3 pages for first 2M (video RAM: CONFIG_X86_VERBOSE_BOOTUP). 63 | + * Total is 36 pages. 64 | + * 65 | + * Some number of page tables is also required for the ACPI and UEFI table 66 | + * mappings, so we round up 36 to 64. Since ACPI tables are generally getting 67 | + * allocated in a few contiguous regions of memory, they are very unlikely to be 68 | + * spread out enough to require more than 28 extra page tables and this 69 | + * would work fine in all more or less sane environments. 70 | */ 71 | -# ifdef CONFIG_X86_VERBOSE_BOOTUP 72 | -# define BOOT_PGT_SIZE (19*4096) 73 | -# else /* !CONFIG_X86_VERBOSE_BOOTUP */ 74 | -# define BOOT_PGT_SIZE (17*4096) 75 | -# endif 76 | -# else /* !CONFIG_RANDOMIZE_BASE */ 77 | -# define BOOT_PGT_SIZE BOOT_INIT_PGT_SIZE 78 | -# endif 79 | +# define BOOT_PGT_SIZE (64*4096) 80 | 81 | #else /* !CONFIG_X86_64 */ 82 | # define BOOT_STACK_SIZE 0x1000 83 | -- 84 | 2.39.2 85 | 86 | -------------------------------------------------------------------------------- /tinylinux/patches/linux/v6.3/v5-0007-x86-build-Check-W-X-of-vmlinux-during-build.patch: -------------------------------------------------------------------------------- 1 | From 45fc736c825b91047d1abe9e47ece762ef4ccd7f Mon Sep 17 00:00:00 2001 2 | Message-Id: <...> 3 | In-Reply-To: <...> 4 | References: <...> 5 | From: Evgeniy Baskov <...> 6 | To: Ard Biesheuvel <...> 7 | Cc: Borislav Petkov <...> 8 | Cc: Andy Lutomirski <...> 9 | Cc: Dave Hansen <...> 10 | Cc: Ingo Molnar <...> 11 | Cc: Peter Zijlstra <...> 12 | Cc: Thomas Gleixner <...> 13 | Cc: Alexey Khoroshilov <...> 14 | Cc: Peter Jones <...> 15 | Cc: "Limonciello, Mario" <...> 16 | Cc: joeyli <...> 17 | Cc: ... 18 | Cc: ... 19 | Cc: ... 20 | Cc: ... 21 | Cc: ... 22 | Date: Mon, 24 Oct 2022 08:55:59 +0300 23 | Subject: [PATCH v5 07/23] x86/build: Check W^X of vmlinux during build 24 | 25 | Check if there are simultaneously writable and executable 26 | program segments in vmlinux ELF image and fail build if there are any. 27 | 28 | This would prevent accidental introduction of RWX segments. 29 | 30 | Tested-by: Mario Limonciello <...> 31 | Signed-off-by: Evgeniy Baskov <...> 32 | --- 33 | arch/x86/boot/compressed/Makefile | 7 ++++++- 34 | 1 file changed, 6 insertions(+), 1 deletion(-) 35 | 36 | diff --git a/arch/x86/boot/compressed/Makefile b/arch/x86/boot/compressed/Makefile 37 | index 6b6cfe607bdb..0c6e25279ec1 100644 38 | --- a/arch/x86/boot/compressed/Makefile 39 | +++ b/arch/x86/boot/compressed/Makefile 40 | @@ -112,12 +112,17 @@ vmlinux-objs-$(CONFIG_EFI) += $(obj)/efi.o 41 | vmlinux-objs-$(CONFIG_EFI_MIXED) += $(obj)/efi_mixed.o 42 | vmlinux-objs-$(CONFIG_EFI_STUB) += $(objtree)/drivers/firmware/efi/libstub/lib.a 43 | 44 | +quiet_cmd_objcopy_and_wx_check = $(quiet_cmd_objcopy) 45 | +cmd_objcopy_and_wx_check = if $(OBJDUMP) -p $< | grep "flags .wx" > /dev/null; then \ 46 | + (echo >&2 "$<: Simultaneously writable and executable sections are prohibited"; \ 47 | + /bin/false); else $(cmd_objcopy); fi 48 | + 49 | $(obj)/vmlinux: $(vmlinux-objs-y) FORCE 50 | $(call if_changed,ld) 51 | 52 | OBJCOPYFLAGS_vmlinux.bin := -R .comment -S 53 | $(obj)/vmlinux.bin: vmlinux FORCE 54 | - $(call if_changed,objcopy) 55 | + $(call if_changed,objcopy_and_wx_check) 56 | 57 | targets += $(patsubst $(obj)/%,%,$(vmlinux-objs-y)) vmlinux.bin.all vmlinux.relocs 58 | 59 | -- 60 | 2.39.2 61 | 62 | -------------------------------------------------------------------------------- /tinylinux/patches/linux/v6.3/v5-0008-x86-boot-Map-memory-explicitly.patch: -------------------------------------------------------------------------------- 1 | From 1be48ff121d58ab544d76ea2d77f53c91262526b Mon Sep 17 00:00:00 2001 2 | Message-Id: <...> 3 | In-Reply-To: <...> 4 | References: <...> 5 | From: Evgeniy Baskov <...> 6 | To: Ard Biesheuvel <...> 7 | Cc: Borislav Petkov <...> 8 | Cc: Andy Lutomirski <...> 9 | Cc: Dave Hansen <...> 10 | Cc: Ingo Molnar <...> 11 | Cc: Peter Zijlstra <...> 12 | Cc: Thomas Gleixner <...> 13 | Cc: Alexey Khoroshilov <...> 14 | Cc: Peter Jones <...> 15 | Cc: "Limonciello, Mario" <...> 16 | Cc: joeyli <...> 17 | Cc: ... 18 | Cc: ... 19 | Cc: ... 20 | Cc: ... 21 | Cc: ... 22 | Date: Thu, 9 Jun 2022 19:29:00 +0300 23 | Subject: [PATCH v5 08/23] x86/boot: Map memory explicitly 24 | 25 | Implicit mappings hide possible memory errors, e.g. allocations for 26 | ACPI tables were not included in boot page table size. 27 | 28 | Replace all implicit mappings from page fault handler with 29 | explicit mappings. 30 | 31 | Tested-by: Mario Limonciello <...> 32 | Signed-off-by: Evgeniy Baskov <...> 33 | --- 34 | arch/x86/boot/compressed/acpi.c | 21 ++++++++++++++++++++- 35 | arch/x86/boot/compressed/efi.c | 19 ++++++++++++++++++- 36 | arch/x86/boot/compressed/kaslr.c | 2 ++ 37 | 3 files changed, 40 insertions(+), 2 deletions(-) 38 | 39 | diff --git a/arch/x86/boot/compressed/acpi.c b/arch/x86/boot/compressed/acpi.c 40 | index 9caf89063e77..633ac56262ee 100644 41 | --- a/arch/x86/boot/compressed/acpi.c 42 | +++ b/arch/x86/boot/compressed/acpi.c 43 | @@ -93,6 +93,8 @@ static u8 *scan_mem_for_rsdp(u8 *start, u32 length) 44 | 45 | end = start + length; 46 | 47 | + kernel_add_identity_map((unsigned long)start, (unsigned long)end, 0); 48 | + 49 | /* Search from given start address for the requested length */ 50 | for (address = start; address < end; address += ACPI_RSDP_SCAN_STEP) { 51 | /* 52 | @@ -128,6 +130,9 @@ static acpi_physical_address bios_get_rsdp_addr(void) 53 | unsigned long address; 54 | u8 *rsdp; 55 | 56 | + kernel_add_identity_map((unsigned long)ACPI_EBDA_PTR_LOCATION, 57 | + (unsigned long)ACPI_EBDA_PTR_LOCATION + 2, 0); 58 | + 59 | /* Get the location of the Extended BIOS Data Area (EBDA) */ 60 | address = *(u16 *)ACPI_EBDA_PTR_LOCATION; 61 | address <<= 4; 62 | @@ -215,6 +220,9 @@ static unsigned long get_acpi_srat_table(void) 63 | if (!rsdp) 64 | return 0; 65 | 66 | + kernel_add_identity_map((unsigned long)rsdp, 67 | + (unsigned long)(rsdp + 1), 0); 68 | + 69 | /* Get ACPI root table from RSDP.*/ 70 | if (!(cmdline_find_option("acpi", arg, sizeof(arg)) == 4 && 71 | !strncmp(arg, "rsdt", 4)) && 72 | @@ -235,6 +243,9 @@ static unsigned long get_acpi_srat_table(void) 73 | if (len < sizeof(struct acpi_table_header) + size) 74 | return 0; 75 | 76 | + kernel_add_identity_map((unsigned long)header, 77 | + (unsigned long)header + len, 0); 78 | + 79 | num_entries = (len - sizeof(struct acpi_table_header)) / size; 80 | entry = (u8 *)(root_table + sizeof(struct acpi_table_header)); 81 | 82 | @@ -247,8 +258,16 @@ static unsigned long get_acpi_srat_table(void) 83 | if (acpi_table) { 84 | header = (struct acpi_table_header *)acpi_table; 85 | 86 | - if (ACPI_COMPARE_NAMESEG(header->signature, ACPI_SIG_SRAT)) 87 | + kernel_add_identity_map(acpi_table, 88 | + acpi_table + sizeof(*header), 89 | + 0); 90 | + 91 | + if (ACPI_COMPARE_NAMESEG(header->signature, ACPI_SIG_SRAT)) { 92 | + kernel_add_identity_map(acpi_table, 93 | + acpi_table + header->length, 94 | + 0); 95 | return acpi_table; 96 | + } 97 | } 98 | entry += size; 99 | } 100 | diff --git a/arch/x86/boot/compressed/efi.c b/arch/x86/boot/compressed/efi.c 101 | index 6edd034b0b30..ce70103fbbc0 100644 102 | --- a/arch/x86/boot/compressed/efi.c 103 | +++ b/arch/x86/boot/compressed/efi.c 104 | @@ -57,10 +57,14 @@ enum efi_type efi_get_type(struct boot_params *bp) 105 | */ 106 | unsigned long efi_get_system_table(struct boot_params *bp) 107 | { 108 | - unsigned long sys_tbl_pa; 109 | + static unsigned long sys_tbl_pa __section(".data"); 110 | struct efi_info *ei; 111 | + unsigned long sys_tbl_size; 112 | enum efi_type et; 113 | 114 | + if (sys_tbl_pa) 115 | + return sys_tbl_pa; 116 | + 117 | /* Get systab from boot params. */ 118 | ei = &bp->efi_info; 119 | #ifdef CONFIG_X86_64 120 | @@ -73,6 +77,13 @@ unsigned long efi_get_system_table(struct boot_params *bp) 121 | return 0; 122 | } 123 | 124 | + if (efi_get_type(bp) == EFI_TYPE_64) 125 | + sys_tbl_size = sizeof(efi_system_table_64_t); 126 | + else 127 | + sys_tbl_size = sizeof(efi_system_table_32_t); 128 | + 129 | + kernel_add_identity_map(sys_tbl_pa, sys_tbl_pa + sys_tbl_size, 0); 130 | + 131 | return sys_tbl_pa; 132 | } 133 | 134 | @@ -92,6 +103,10 @@ static struct efi_setup_data *get_kexec_setup_data(struct boot_params *bp, 135 | 136 | pa_data = bp->hdr.setup_data; 137 | while (pa_data) { 138 | + unsigned long pa_data_end = pa_data + sizeof(struct setup_data) 139 | + + sizeof(struct efi_setup_data); 140 | + kernel_add_identity_map(pa_data, pa_data_end, 0); 141 | + 142 | data = (struct setup_data *)pa_data; 143 | if (data->type == SETUP_EFI) { 144 | esd = (struct efi_setup_data *)(pa_data + sizeof(struct setup_data)); 145 | @@ -160,6 +175,8 @@ int efi_get_conf_table(struct boot_params *bp, unsigned long *cfg_tbl_pa, 146 | return -EINVAL; 147 | } 148 | 149 | + kernel_add_identity_map(*cfg_tbl_pa, *cfg_tbl_pa + *cfg_tbl_len, 0); 150 | + 151 | return 0; 152 | } 153 | 154 | diff --git a/arch/x86/boot/compressed/kaslr.c b/arch/x86/boot/compressed/kaslr.c 155 | index 454757fbdfe5..69966481b82d 100644 156 | --- a/arch/x86/boot/compressed/kaslr.c 157 | +++ b/arch/x86/boot/compressed/kaslr.c 158 | @@ -704,6 +704,8 @@ process_efi_entries(unsigned long minimum, unsigned long image_size) 159 | pmap = (e->efi_memmap | ((__u64)e->efi_memmap_hi << 32)); 160 | #endif 161 | 162 | + kernel_add_identity_map(pmap, pmap + e->efi_memmap_size, 0); 163 | + 164 | nr_desc = e->efi_memmap_size / e->efi_memdesc_size; 165 | for (i = 0; i < nr_desc; i++) { 166 | md = efi_early_memdesc_ptr(pmap, e->efi_memdesc_size, i); 167 | -- 168 | 2.39.2 169 | 170 | -------------------------------------------------------------------------------- /tinylinux/patches/linux/v6.3/v5-0009-x86-boot-Remove-mapping-from-page-fault-handler.patch: -------------------------------------------------------------------------------- 1 | From 0d68287de4cd4701db28bb5b763c54895641f395 Mon Sep 17 00:00:00 2001 2 | Message-Id: <...> 3 | In-Reply-To: <...> 4 | References: <...> 5 | From: Evgeniy Baskov <...> 6 | To: Ard Biesheuvel <...> 7 | Cc: Borislav Petkov <...> 8 | Cc: Andy Lutomirski <...> 9 | Cc: Dave Hansen <...> 10 | Cc: Ingo Molnar <...> 11 | Cc: Peter Zijlstra <...> 12 | Cc: Thomas Gleixner <...> 13 | Cc: Alexey Khoroshilov <...> 14 | Cc: Peter Jones <...> 15 | Cc: "Limonciello, Mario" <...> 16 | Cc: joeyli <...> 17 | Cc: ... 18 | Cc: ... 19 | Cc: ... 20 | Cc: ... 21 | Cc: ... 22 | Date: Thu, 9 Jun 2022 19:35:18 +0300 23 | Subject: [PATCH v5 09/23] x86/boot: Remove mapping from page fault handler 24 | 25 | After every implicit mapping is removed, this code is no longer needed. 26 | 27 | Remove memory mapping from page fault handler to ensure that there are 28 | no hidden invalid memory accesses. 29 | 30 | Tested-by: Mario Limonciello <...> 31 | Signed-off-by: Evgeniy Baskov <...> 32 | --- 33 | arch/x86/boot/compressed/ident_map_64.c | 26 ++++++++++--------------- 34 | 1 file changed, 10 insertions(+), 16 deletions(-) 35 | 36 | diff --git a/arch/x86/boot/compressed/ident_map_64.c b/arch/x86/boot/compressed/ident_map_64.c 37 | index eb28ce9812c5..378f99b1d7e8 100644 38 | --- a/arch/x86/boot/compressed/ident_map_64.c 39 | +++ b/arch/x86/boot/compressed/ident_map_64.c 40 | @@ -393,27 +393,21 @@ void do_boot_page_fault(struct pt_regs *regs, unsigned long error_code) 41 | { 42 | unsigned long address = native_read_cr2(); 43 | unsigned long end; 44 | - bool ghcb_fault; 45 | + char *msg; 46 | 47 | - ghcb_fault = sev_es_check_ghcb_fault(address); 48 | + if (sev_es_check_ghcb_fault(address)) 49 | + msg = "Page-fault on GHCB page:"; 50 | + else 51 | + msg = "Unexpected page-fault:"; 52 | 53 | address &= PMD_MASK; 54 | end = address + PMD_SIZE; 55 | 56 | /* 57 | - * Check for unexpected error codes. Unexpected are: 58 | - * - Faults on present pages 59 | - * - User faults 60 | - * - Reserved bits set 61 | - */ 62 | - if (error_code & (X86_PF_PROT | X86_PF_USER | X86_PF_RSVD)) 63 | - do_pf_error("Unexpected page-fault:", error_code, address, regs->ip); 64 | - else if (ghcb_fault) 65 | - do_pf_error("Page-fault on GHCB page:", error_code, address, regs->ip); 66 | - 67 | - /* 68 | - * Error code is sane - now identity map the 2M region around 69 | - * the faulting address. 70 | + * Since all memory allocations are made explicit 71 | + * now, every page fault at this stage is an 72 | + * error and the error handler is there only 73 | + * for debug purposes. 74 | */ 75 | - kernel_add_identity_map(address, end, MAP_WRITE); 76 | + do_pf_error(msg, error_code, address, regs->ip); 77 | } 78 | -- 79 | 2.39.2 80 | 81 | -------------------------------------------------------------------------------- /tinylinux/patches/linux/v6.3/v5-0012-x86-boot-Make-kernel_add_identity_map-a-pointer.patch: -------------------------------------------------------------------------------- 1 | From d7f050a8ab84333d3b5fca6481f18d129ef81cd5 Mon Sep 17 00:00:00 2001 2 | Message-Id: <...> 3 | In-Reply-To: <...> 4 | References: <...> 5 | From: Evgeniy Baskov <...> 6 | To: Ard Biesheuvel <...> 7 | Cc: Borislav Petkov <...> 8 | Cc: Andy Lutomirski <...> 9 | Cc: Dave Hansen <...> 10 | Cc: Ingo Molnar <...> 11 | Cc: Peter Zijlstra <...> 12 | Cc: Thomas Gleixner <...> 13 | Cc: Alexey Khoroshilov <...> 14 | Cc: Peter Jones <...> 15 | Cc: "Limonciello, Mario" <...> 16 | Cc: joeyli <...> 17 | Cc: ... 18 | Cc: ... 19 | Cc: ... 20 | Cc: ... 21 | Cc: ... 22 | Date: Thu, 20 Oct 2022 13:16:50 +0300 23 | Subject: [PATCH v5 12/23] x86/boot: Make kernel_add_identity_map() a pointer 24 | 25 | Convert kernel_add_identity_map() into a function pointer to be able 26 | to provide alternative implementations of this function. Required 27 | to enable calling the code using this function from EFI environment. 28 | 29 | Tested-by: Mario Limonciello <...> 30 | Signed-off-by: Evgeniy Baskov <...> 31 | 32 | Warnings on the previous version were 33 | Reported-by: kernel test robot <...> 34 | Link: https://lore.kernel.org/oe-kbuild-all/.../ 35 | --- 36 | arch/x86/boot/compressed/ident_map_64.c | 7 ++++--- 37 | arch/x86/boot/compressed/misc.c | 24 ++++++++++++++++++++++++ 38 | arch/x86/boot/compressed/misc.h | 15 +++------------ 39 | 3 files changed, 31 insertions(+), 15 deletions(-) 40 | 41 | diff --git a/arch/x86/boot/compressed/ident_map_64.c b/arch/x86/boot/compressed/ident_map_64.c 42 | index 378f99b1d7e8..c32d88bb1f89 100644 43 | --- a/arch/x86/boot/compressed/ident_map_64.c 44 | +++ b/arch/x86/boot/compressed/ident_map_64.c 45 | @@ -92,9 +92,9 @@ bool has_nx; /* set in head_64.S */ 46 | /* 47 | * Adds the specified range to the identity mappings. 48 | */ 49 | -unsigned long kernel_add_identity_map(unsigned long start, 50 | - unsigned long end, 51 | - unsigned int flags) 52 | +static unsigned long kernel_add_identity_map_(unsigned long start, 53 | + unsigned long end, 54 | + unsigned int flags) 55 | { 56 | int ret; 57 | 58 | @@ -143,6 +143,7 @@ void initialize_identity_maps(void *rmode) 59 | struct setup_data *sd; 60 | 61 | boot_params = rmode; 62 | + kernel_add_identity_map = kernel_add_identity_map_; 63 | 64 | /* Exclude the encryption mask from __PHYSICAL_MASK */ 65 | physical_mask &= ~sme_me_mask; 66 | diff --git a/arch/x86/boot/compressed/misc.c b/arch/x86/boot/compressed/misc.c 67 | index 961c3eadcbe5..bbf85c74a20a 100644 68 | --- a/arch/x86/boot/compressed/misc.c 69 | +++ b/arch/x86/boot/compressed/misc.c 70 | @@ -276,6 +276,22 @@ static size_t parse_elf(void *output, unsigned long output_len, 71 | return ehdr.e_entry - LOAD_PHYSICAL_ADDR; 72 | } 73 | 74 | +/* 75 | + * This points to actual implementation of mapping function 76 | + * for current environment: either EFI API wrapper, 77 | + * own implementation or dummy implementation below. 78 | + */ 79 | +unsigned long (*kernel_add_identity_map)(unsigned long start, 80 | + unsigned long end, 81 | + unsigned int flags); 82 | + 83 | +static inline unsigned long kernel_add_identity_map_dummy(unsigned long start, 84 | + unsigned long end, 85 | + unsigned int flags) 86 | +{ 87 | + return start; 88 | +} 89 | + 90 | /* 91 | * The compressed kernel image (ZO), has been moved so that its position 92 | * is against the end of the buffer used to hold the uncompressed kernel 93 | @@ -314,6 +330,14 @@ asmlinkage __visible void *extract_kernel(void *rmode, memptr heap, 94 | 95 | init_default_io_ops(); 96 | 97 | + /* 98 | + * On 64-bit this pointer is set during page table uninitialization, 99 | + * but on 32-bit it remains uninitialized, since paging is disabled. 100 | + */ 101 | + if (IS_ENABLED(CONFIG_X86_32)) 102 | + kernel_add_identity_map = kernel_add_identity_map_dummy; 103 | + 104 | + 105 | /* 106 | * Detect TDX guest environment. 107 | * 108 | diff --git a/arch/x86/boot/compressed/misc.h b/arch/x86/boot/compressed/misc.h 109 | index e20f60bfe91b..fe201b45b038 100644 110 | --- a/arch/x86/boot/compressed/misc.h 111 | +++ b/arch/x86/boot/compressed/misc.h 112 | @@ -182,18 +182,9 @@ static inline int count_immovable_mem_regions(void) { return 0; } 113 | #ifdef CONFIG_X86_5LEVEL 114 | extern unsigned int __pgtable_l5_enabled, pgdir_shift, ptrs_per_p4d; 115 | #endif 116 | -#ifdef CONFIG_X86_64 117 | -extern unsigned long kernel_add_identity_map(unsigned long start, 118 | - unsigned long end, 119 | - unsigned int flags); 120 | -#else 121 | -static inline unsigned long kernel_add_identity_map(unsigned long start, 122 | - unsigned long end, 123 | - unsigned int flags) 124 | -{ 125 | - return start; 126 | -} 127 | -#endif 128 | +extern unsigned long (*kernel_add_identity_map)(unsigned long start, 129 | + unsigned long end, 130 | + unsigned int flags); 131 | /* Used by PAGE_KERN* macros: */ 132 | extern pteval_t __default_kernel_pte_mask; 133 | 134 | -- 135 | 2.39.2 136 | 137 | -------------------------------------------------------------------------------- /tinylinux/patches/linux/v6.3/v5-0013-x86-boot-Split-trampoline-and-pt-init-code.patch: -------------------------------------------------------------------------------- 1 | From a9c813e4af03d4c013092eee8e4c67651e878b08 Mon Sep 17 00:00:00 2001 2 | Message-Id: <...> 3 | In-Reply-To: <...> 4 | References: <...> 5 | From: Evgeniy Baskov <...> 6 | To: Ard Biesheuvel <...> 7 | Cc: Borislav Petkov <...> 8 | Cc: Andy Lutomirski <...> 9 | Cc: Dave Hansen <...> 10 | Cc: Ingo Molnar <...> 11 | Cc: Peter Zijlstra <...> 12 | Cc: Thomas Gleixner <...> 13 | Cc: Alexey Khoroshilov <...> 14 | Cc: Peter Jones <...> 15 | Cc: "Limonciello, Mario" <...> 16 | Cc: joeyli <...> 17 | Cc: ... 18 | Cc: ... 19 | Cc: ... 20 | Cc: ... 21 | Cc: ... 22 | Date: Thu, 16 Jun 2022 15:30:22 +0300 23 | Subject: [PATCH v5 13/23] x86/boot: Split trampoline and pt init code 24 | 25 | When allocating trampoline from libstub trampoline allocation is 26 | performed separately, so it needs to be skipped. 27 | 28 | Split trampoline initialization and allocation code into two 29 | functions to make them invokable separately. 30 | 31 | Tested-by: Mario Limonciello <...> 32 | Signed-off-by: Evgeniy Baskov <...> 33 | --- 34 | arch/x86/boot/compressed/pgtable_64.c | 73 +++++++++++++++++---------- 35 | 1 file changed, 46 insertions(+), 27 deletions(-) 36 | 37 | diff --git a/arch/x86/boot/compressed/pgtable_64.c b/arch/x86/boot/compressed/pgtable_64.c 38 | index c7cf5a1059a8..1f7169248612 100644 39 | --- a/arch/x86/boot/compressed/pgtable_64.c 40 | +++ b/arch/x86/boot/compressed/pgtable_64.c 41 | @@ -106,12 +106,8 @@ static unsigned long find_trampoline_placement(void) 42 | return bios_start - TRAMPOLINE_32BIT_SIZE; 43 | } 44 | 45 | -struct paging_config paging_prepare(void *rmode) 46 | +bool trampoline_pgtable_init(struct boot_params *boot_params) 47 | { 48 | - struct paging_config paging_config = {}; 49 | - 50 | - /* Initialize boot_params. Required for cmdline_find_option_bool(). */ 51 | - boot_params = rmode; 52 | 53 | /* 54 | * Check if LA57 is desired and supported. 55 | @@ -125,26 +121,10 @@ struct paging_config paging_prepare(void *rmode) 56 | * 57 | * That's substitute for boot_cpu_has() in early boot code. 58 | */ 59 | - if (IS_ENABLED(CONFIG_X86_5LEVEL) && 60 | - !cmdline_find_option_bool("no5lvl") && 61 | - native_cpuid_eax(0) >= 7 && 62 | - (native_cpuid_ecx(7) & (1 << (X86_FEATURE_LA57 & 31)))) { 63 | - paging_config.l5_required = 1; 64 | - } 65 | - 66 | - paging_config.trampoline_start = find_trampoline_placement(); 67 | - 68 | - trampoline_32bit = (unsigned long *)paging_config.trampoline_start; 69 | - 70 | - /* Preserve trampoline memory */ 71 | - memcpy(trampoline_save, trampoline_32bit, TRAMPOLINE_32BIT_SIZE); 72 | - 73 | - /* Clear trampoline memory first */ 74 | - memset(trampoline_32bit, 0, TRAMPOLINE_32BIT_SIZE); 75 | - 76 | - /* Copy trampoline code in place */ 77 | - memcpy(trampoline_32bit + TRAMPOLINE_32BIT_CODE_OFFSET / sizeof(unsigned long), 78 | - &trampoline_32bit_src, TRAMPOLINE_32BIT_CODE_SIZE); 79 | + bool l5_required = IS_ENABLED(CONFIG_X86_5LEVEL) && 80 | + !cmdline_find_option_bool("no5lvl") && 81 | + native_cpuid_eax(0) >= 7 && 82 | + (native_cpuid_ecx(7) & (1 << (X86_FEATURE_LA57 & 31))); 83 | 84 | /* 85 | * The code below prepares page table in trampoline memory. 86 | @@ -160,10 +140,10 @@ struct paging_config paging_prepare(void *rmode) 87 | * We are not going to use the page table in trampoline memory if we 88 | * are already in the desired paging mode. 89 | */ 90 | - if (paging_config.l5_required == !!(native_read_cr4() & X86_CR4_LA57)) 91 | + if (l5_required == !!(native_read_cr4() & X86_CR4_LA57)) 92 | goto out; 93 | 94 | - if (paging_config.l5_required) { 95 | + if (l5_required) { 96 | /* 97 | * For 4- to 5-level paging transition, set up current CR3 as 98 | * the first and the only entry in a new top-level page table. 99 | @@ -185,6 +165,45 @@ struct paging_config paging_prepare(void *rmode) 100 | (void *)src, PAGE_SIZE); 101 | } 102 | 103 | +out: 104 | + return l5_required; 105 | +} 106 | + 107 | +struct paging_config paging_prepare(void *rmode) 108 | +{ 109 | + struct paging_config paging_config = {}; 110 | + bool early_trampoline_alloc = 0; 111 | + 112 | + /* Initialize boot_params. Required for cmdline_find_option_bool(). */ 113 | + boot_params = rmode; 114 | + 115 | + /* 116 | + * We only need to find trampoline placement, if we have 117 | + * not already done it from libstub. 118 | + */ 119 | + 120 | + paging_config.trampoline_start = find_trampoline_placement(); 121 | + trampoline_32bit = (unsigned long *)paging_config.trampoline_start; 122 | + early_trampoline_alloc = 0; 123 | + 124 | + /* 125 | + * Preserve trampoline memory. 126 | + * When trampoline is located in memory 127 | + * owned by us, i.e. allocated in EFISTUB, 128 | + * we don't care about previous contents 129 | + * of this memory so copying can also be skipped. 130 | + */ 131 | + memcpy(trampoline_save, trampoline_32bit, TRAMPOLINE_32BIT_SIZE); 132 | + 133 | + /* Clear trampoline memory first */ 134 | + memset(trampoline_32bit, 0, TRAMPOLINE_32BIT_SIZE); 135 | + 136 | + /* Copy trampoline code in place */ 137 | + memcpy(trampoline_32bit + TRAMPOLINE_32BIT_CODE_OFFSET / sizeof(unsigned long), 138 | + &trampoline_32bit_src, TRAMPOLINE_32BIT_CODE_SIZE); 139 | + 140 | + paging_config.l5_required = trampoline_pgtable_init(boot_params); 141 | + 142 | out: 143 | return paging_config; 144 | } 145 | -- 146 | 2.39.2 147 | 148 | -------------------------------------------------------------------------------- /tinylinux/patches/linux/v6.3/v5-0016-x86-boot-Reduce-lower-limit-of-physical-KASLR.patch: -------------------------------------------------------------------------------- 1 | From c37ad2e2294ab424500550e65a49d1410fc121f4 Mon Sep 17 00:00:00 2001 2 | Message-Id: <...> 3 | In-Reply-To: <...> 4 | References: <...> 5 | From: Evgeniy Baskov <...> 6 | To: Ard Biesheuvel <...> 7 | Cc: Borislav Petkov <...> 8 | Cc: Andy Lutomirski <...> 9 | Cc: Dave Hansen <...> 10 | Cc: Ingo Molnar <...> 11 | Cc: Peter Zijlstra <...> 12 | Cc: Thomas Gleixner <...> 13 | Cc: Alexey Khoroshilov <...> 14 | Cc: Peter Jones <...> 15 | Cc: "Limonciello, Mario" <...> 16 | Cc: joeyli <...> 17 | Cc: ... 18 | Cc: ... 19 | Cc: ... 20 | Cc: ... 21 | Cc: ... 22 | Date: Fri, 21 Oct 2022 19:56:57 +0300 23 | Subject: [PATCH v5 16/23] x86/boot: Reduce lower limit of physical KASLR 24 | 25 | Set lower limit of physical KASLR to 64M. 26 | 27 | Previously is was set to 512M when kernel is loaded higher than that. 28 | That prevented physical KASLR from being performed on x86_32, where 29 | upper limit is also set to 512M. The limit is pretty arbitrary, and the 30 | most important is to set it above the ISA hole, i.e. higher than 16M. 31 | 32 | It was not that important before, but now kernel is not getting 33 | relocated to the lower address when booting via EFI, exposing the 34 | KASLR failures. 35 | 36 | Tested-by: Mario Limonciello <...> 37 | Signed-off-by: Evgeniy Baskov <...> 38 | --- 39 | arch/x86/boot/compressed/kaslr.c | 4 ++-- 40 | 1 file changed, 2 insertions(+), 2 deletions(-) 41 | 42 | diff --git a/arch/x86/boot/compressed/kaslr.c b/arch/x86/boot/compressed/kaslr.c 43 | index 69966481b82d..806df3912396 100644 44 | --- a/arch/x86/boot/compressed/kaslr.c 45 | +++ b/arch/x86/boot/compressed/kaslr.c 46 | @@ -850,10 +850,10 @@ void choose_random_location(unsigned long input, 47 | 48 | /* 49 | * Low end of the randomization range should be the 50 | - * smaller of 512M or the initial kernel image 51 | + * smaller of 64M or the initial kernel image 52 | * location: 53 | */ 54 | - min_addr = min(*output, 512UL << 20); 55 | + min_addr = min(*output, 64UL << 20); 56 | /* Make sure minimum is aligned. */ 57 | min_addr = ALIGN(min_addr, CONFIG_PHYSICAL_ALIGN); 58 | 59 | -- 60 | 2.39.2 61 | 62 | -------------------------------------------------------------------------------- /tinylinux/patches/linux/v6.3/v5-0017-x86-boot-Reduce-size-of-the-DOS-stub.patch: -------------------------------------------------------------------------------- 1 | From 1d76d75bd1acb272bb3d9aca06983a421985aa95 Mon Sep 17 00:00:00 2001 2 | Message-Id: <...> 3 | In-Reply-To: <...> 4 | References: <...> 5 | From: Evgeniy Baskov <...> 6 | To: Ard Biesheuvel <...> 7 | Cc: Borislav Petkov <...> 8 | Cc: Andy Lutomirski <...> 9 | Cc: Dave Hansen <...> 10 | Cc: Ingo Molnar <...> 11 | Cc: Peter Zijlstra <...> 12 | Cc: Thomas Gleixner <...> 13 | Cc: Alexey Khoroshilov <...> 14 | Cc: Peter Jones <...> 15 | Cc: "Limonciello, Mario" <...> 16 | Cc: joeyli <...> 17 | Cc: ... 18 | Cc: ... 19 | Cc: ... 20 | Cc: ... 21 | Cc: ... 22 | Date: Sun, 23 Oct 2022 20:04:15 +0300 23 | Subject: [PATCH v5 17/23] x86/boot: Reduce size of the DOS stub 24 | 25 | This is required to fit more sections in PE section tables, 26 | since its size is restricted by zero page located at specific offset 27 | after the PE header. 28 | 29 | Tested-by: Mario Limonciello <...> 30 | Signed-off-by: Evgeniy Baskov <...> 31 | --- 32 | arch/x86/boot/header.S | 14 ++++++-------- 33 | 1 file changed, 6 insertions(+), 8 deletions(-) 34 | 35 | diff --git a/arch/x86/boot/header.S b/arch/x86/boot/header.S 36 | index 9338c68e7413..9fec80bc504b 100644 37 | --- a/arch/x86/boot/header.S 38 | +++ b/arch/x86/boot/header.S 39 | @@ -59,17 +59,16 @@ start2: 40 | cld 41 | 42 | movw $bugger_off_msg, %si 43 | + movw $bugger_off_msg_size, %cx 44 | 45 | msg_loop: 46 | lodsb 47 | - andb %al, %al 48 | - jz bs_die 49 | movb $0xe, %ah 50 | movw $7, %bx 51 | int $0x10 52 | - jmp msg_loop 53 | + decw %cx 54 | + jnz msg_loop 55 | 56 | -bs_die: 57 | # Allow the user to press a key, then reboot 58 | xorw %ax, %ax 59 | int $0x16 60 | @@ -90,10 +89,9 @@ bs_die: 61 | 62 | .section ".bsdata", "a" 63 | bugger_off_msg: 64 | - .ascii "Use a boot loader.\r\n" 65 | - .ascii "\n" 66 | - .ascii "Remove disk and press any key to reboot...\r\n" 67 | - .byte 0 68 | + .ascii "Use a boot loader. " 69 | + .ascii "Press a key to reboot" 70 | + .set bugger_off_msg_size, . - bugger_off_msg 71 | 72 | #ifdef CONFIG_EFI_STUB 73 | pe_header: 74 | -- 75 | 2.39.2 76 | 77 | -------------------------------------------------------------------------------- /tinylinux/patches/linux/v6.3/v5-0018-tools-include-Add-simplified-version-of-pe.h.patch: -------------------------------------------------------------------------------- 1 | From df66c7c3af6af517e4f146f8f2c2079eaa686e26 Mon Sep 17 00:00:00 2001 2 | Message-Id: <...> 3 | In-Reply-To: <...> 4 | References: <...> 5 | From: Evgeniy Baskov <...> 6 | To: Ard Biesheuvel <...> 7 | Cc: Borislav Petkov <...> 8 | Cc: Andy Lutomirski <...> 9 | Cc: Dave Hansen <...> 10 | Cc: Ingo Molnar <...> 11 | Cc: Peter Zijlstra <...> 12 | Cc: Thomas Gleixner <...> 13 | Cc: Alexey Khoroshilov <...> 14 | Cc: Peter Jones <...> 15 | Cc: "Limonciello, Mario" <...> 16 | Cc: joeyli <...> 17 | Cc: ... 18 | Cc: ... 19 | Cc: ... 20 | Cc: ... 21 | Cc: ... 22 | Date: Tue, 25 Oct 2022 11:56:21 +0300 23 | Subject: [PATCH v5 18/23] tools/include: Add simplified version of pe.h 24 | 25 | This is needed to remove magic numbers from x86 bzImage building tool 26 | (arch/x86/boot/tools/build.c). 27 | 28 | Tested-by: Mario Limonciello <...> 29 | Signed-off-by: Evgeniy Baskov <...> 30 | --- 31 | tools/include/linux/pe.h | 150 +++++++++++++++++++++++++++++++++++++++ 32 | 1 file changed, 150 insertions(+) 33 | create mode 100644 tools/include/linux/pe.h 34 | 35 | diff --git a/tools/include/linux/pe.h b/tools/include/linux/pe.h 36 | new file mode 100644 37 | index 000000000000..41c09ec371d8 38 | --- /dev/null 39 | +++ b/tools/include/linux/pe.h 40 | @@ -0,0 +1,150 @@ 41 | +/* SPDX-License-Identifier: GPL-2.0-only */ 42 | +/* 43 | + * Simplified version of include/linux/pe.h: 44 | + * Copyright 2011 Red Hat, Inc. All rights reserved. 45 | + * Author(s): Peter Jones <...> 46 | + */ 47 | +#ifndef __LINUX_PE_H 48 | +#define __LINUX_PE_H 49 | + 50 | +#include 51 | + 52 | +#define IMAGE_FILE_MACHINE_I386 0x014c 53 | + 54 | +#define IMAGE_SCN_CNT_CODE 0x00000020 /* .text */ 55 | +#define IMAGE_SCN_CNT_INITIALIZED_DATA 0x00000040 /* .data */ 56 | +#define IMAGE_SCN_ALIGN_4096BYTES 0x00d00000 57 | +#define IMAGE_SCN_MEM_DISCARDABLE 0x02000000 /* scn can be discarded */ 58 | +#define IMAGE_SCN_MEM_EXECUTE 0x20000000 /* can be executed as code */ 59 | +#define IMAGE_SCN_MEM_READ 0x40000000 /* readable */ 60 | +#define IMAGE_SCN_MEM_WRITE 0x80000000 /* writeable */ 61 | + 62 | +#define MZ_HEADER_PEADDR_OFFSET 0x3c 63 | + 64 | +struct pe_hdr { 65 | + uint32_t magic; /* PE magic */ 66 | + uint16_t machine; /* machine type */ 67 | + uint16_t sections; /* number of sections */ 68 | + uint32_t timestamp; /* time_t */ 69 | + uint32_t symbol_table; /* symbol table offset */ 70 | + uint32_t symbols; /* number of symbols */ 71 | + uint16_t opt_hdr_size; /* size of optional header */ 72 | + uint16_t flags; /* flags */ 73 | +}; 74 | + 75 | +/* the fact that pe32 isn't padded where pe32+ is 64-bit means union won't 76 | + * work right. vomit. */ 77 | +struct pe32_opt_hdr { 78 | + /* "standard" header */ 79 | + uint16_t magic; /* file type */ 80 | + uint8_t ld_major; /* linker major version */ 81 | + uint8_t ld_minor; /* linker minor version */ 82 | + uint32_t text_size; /* size of text section(s) */ 83 | + uint32_t data_size; /* size of data section(s) */ 84 | + uint32_t bss_size; /* size of bss section(s) */ 85 | + uint32_t entry_point; /* file offset of entry point */ 86 | + uint32_t code_base; /* relative code addr in ram */ 87 | + uint32_t data_base; /* relative data addr in ram */ 88 | + /* "windows" header */ 89 | + uint32_t image_base; /* preferred load address */ 90 | + uint32_t section_align; /* alignment in bytes */ 91 | + uint32_t file_align; /* file alignment in bytes */ 92 | + uint16_t os_major; /* major OS version */ 93 | + uint16_t os_minor; /* minor OS version */ 94 | + uint16_t image_major; /* major image version */ 95 | + uint16_t image_minor; /* minor image version */ 96 | + uint16_t subsys_major; /* major subsystem version */ 97 | + uint16_t subsys_minor; /* minor subsystem version */ 98 | + uint32_t win32_version; /* reserved, must be 0 */ 99 | + uint32_t image_size; /* image size */ 100 | + uint32_t header_size; /* header size rounded up to 101 | + file_align */ 102 | + uint32_t csum; /* checksum */ 103 | + uint16_t subsys; /* subsystem */ 104 | + uint16_t dll_flags; /* more flags! */ 105 | + uint32_t stack_size_req;/* amt of stack requested */ 106 | + uint32_t stack_size; /* amt of stack required */ 107 | + uint32_t heap_size_req; /* amt of heap requested */ 108 | + uint32_t heap_size; /* amt of heap required */ 109 | + uint32_t loader_flags; /* reserved, must be 0 */ 110 | + uint32_t data_dirs; /* number of data dir entries */ 111 | +}; 112 | + 113 | +struct pe32plus_opt_hdr { 114 | + uint16_t magic; /* file type */ 115 | + uint8_t ld_major; /* linker major version */ 116 | + uint8_t ld_minor; /* linker minor version */ 117 | + uint32_t text_size; /* size of text section(s) */ 118 | + uint32_t data_size; /* size of data section(s) */ 119 | + uint32_t bss_size; /* size of bss section(s) */ 120 | + uint32_t entry_point; /* file offset of entry point */ 121 | + uint32_t code_base; /* relative code addr in ram */ 122 | + /* "windows" header */ 123 | + uint64_t image_base; /* preferred load address */ 124 | + uint32_t section_align; /* alignment in bytes */ 125 | + uint32_t file_align; /* file alignment in bytes */ 126 | + uint16_t os_major; /* major OS version */ 127 | + uint16_t os_minor; /* minor OS version */ 128 | + uint16_t image_major; /* major image version */ 129 | + uint16_t image_minor; /* minor image version */ 130 | + uint16_t subsys_major; /* major subsystem version */ 131 | + uint16_t subsys_minor; /* minor subsystem version */ 132 | + uint32_t win32_version; /* reserved, must be 0 */ 133 | + uint32_t image_size; /* image size */ 134 | + uint32_t header_size; /* header size rounded up to 135 | + file_align */ 136 | + uint32_t csum; /* checksum */ 137 | + uint16_t subsys; /* subsystem */ 138 | + uint16_t dll_flags; /* more flags! */ 139 | + uint64_t stack_size_req;/* amt of stack requested */ 140 | + uint64_t stack_size; /* amt of stack required */ 141 | + uint64_t heap_size_req; /* amt of heap requested */ 142 | + uint64_t heap_size; /* amt of heap required */ 143 | + uint32_t loader_flags; /* reserved, must be 0 */ 144 | + uint32_t data_dirs; /* number of data dir entries */ 145 | +}; 146 | + 147 | +struct data_dirent { 148 | + uint32_t virtual_address; /* relative to load address */ 149 | + uint32_t size; 150 | +}; 151 | + 152 | +struct data_directory { 153 | + struct data_dirent exports; /* .edata */ 154 | + struct data_dirent imports; /* .idata */ 155 | + struct data_dirent resources; /* .rsrc */ 156 | + struct data_dirent exceptions; /* .pdata */ 157 | + struct data_dirent certs; /* certs */ 158 | + struct data_dirent base_relocations; /* .reloc */ 159 | + struct data_dirent debug; /* .debug */ 160 | + struct data_dirent arch; /* reservered */ 161 | + struct data_dirent global_ptr; /* global pointer reg. Size=0 */ 162 | + struct data_dirent tls; /* .tls */ 163 | + struct data_dirent load_config; /* load configuration structure */ 164 | + struct data_dirent bound_imports; /* no idea */ 165 | + struct data_dirent import_addrs; /* import address table */ 166 | + struct data_dirent delay_imports; /* delay-load import table */ 167 | + struct data_dirent clr_runtime_hdr; /* .cor (object only) */ 168 | + struct data_dirent reserved; 169 | +}; 170 | + 171 | +struct section_header { 172 | + char name[8]; /* name or "/12\0" string tbl offset */ 173 | + uint32_t virtual_size; /* size of loaded section in ram */ 174 | + uint32_t virtual_address; /* relative virtual address */ 175 | + uint32_t raw_data_size; /* size of the section */ 176 | + uint32_t data_addr; /* file pointer to first page of sec */ 177 | + uint32_t relocs; /* file pointer to relocation entries */ 178 | + uint32_t line_numbers; /* line numbers! */ 179 | + uint16_t num_relocs; /* number of relocations */ 180 | + uint16_t num_lin_numbers; /* srsly. */ 181 | + uint32_t flags; 182 | +}; 183 | + 184 | +struct coff_reloc { 185 | + uint32_t virtual_address; 186 | + uint32_t symbol_table_index; 187 | + uint16_t data; 188 | +}; 189 | + 190 | +#endif /* __LINUX_PE_H */ 191 | -- 192 | 2.39.2 193 | 194 | -------------------------------------------------------------------------------- /tinylinux/patches/linux/v6.3/v5-0021-efi-x86-Explicitly-set-sections-memory-attributes.patch: -------------------------------------------------------------------------------- 1 | From d9b93baf0cb43ab3a4ecbafe334a32a456c3adbb Mon Sep 17 00:00:00 2001 2 | Message-Id: <...> 3 | In-Reply-To: <...> 4 | References: <...> 5 | From: Evgeniy Baskov <...> 6 | To: Ard Biesheuvel <...> 7 | Cc: Borislav Petkov <...> 8 | Cc: Andy Lutomirski <...> 9 | Cc: Dave Hansen <...> 10 | Cc: Ingo Molnar <...> 11 | Cc: Peter Zijlstra <...> 12 | Cc: Thomas Gleixner <...> 13 | Cc: Alexey Khoroshilov <...> 14 | Cc: Peter Jones <...> 15 | Cc: "Limonciello, Mario" <...> 16 | Cc: joeyli <...> 17 | Cc: ... 18 | Cc: ... 19 | Cc: ... 20 | Cc: ... 21 | Cc: ... 22 | Date: Sun, 23 Oct 2022 20:15:52 +0300 23 | Subject: [PATCH v5 21/23] efi/x86: Explicitly set sections memory attributes 24 | 25 | Explicitly change sections memory attributes in efi_pe_entry in case 26 | of incorrect EFI implementations and to reduce access rights to 27 | compressed kernel blob. By default it is set executable due to 28 | restriction in maximum number of sections that can fit before zero 29 | page. 30 | 31 | Signed-off-by: Evgeniy Baskov <...> 32 | --- 33 | drivers/firmware/efi/libstub/x86-stub.c | 54 +++++++++++++++++++++++++ 34 | 1 file changed, 54 insertions(+) 35 | 36 | diff --git a/drivers/firmware/efi/libstub/x86-stub.c b/drivers/firmware/efi/libstub/x86-stub.c 37 | index 1f0a2e7075c3..60697fcd8950 100644 38 | --- a/drivers/firmware/efi/libstub/x86-stub.c 39 | +++ b/drivers/firmware/efi/libstub/x86-stub.c 40 | @@ -27,6 +27,12 @@ const efi_dxe_services_table_t *efi_dxe_table; 41 | u32 image_offset __section(".data"); 42 | static efi_loaded_image_t *image __section(".data"); 43 | 44 | +extern char _head[], _ehead[]; 45 | +extern char _compressed[], _ecompressed[]; 46 | +extern char _text[], _etext[]; 47 | +extern char _rodata[], _erodata[]; 48 | +extern char _data[]; 49 | + 50 | static efi_status_t 51 | preserve_pci_rom_image(efi_pci_io_protocol_t *pci, struct pci_setup_rom **__rom) 52 | { 53 | @@ -343,6 +349,52 @@ void __noreturn efi_exit(efi_handle_t handle, efi_status_t status) 54 | asm("hlt"); 55 | } 56 | 57 | + 58 | +/* 59 | + * Manually setup memory protection attributes for each ELF section 60 | + * since we cannot do it properly by using PE sections. 61 | + */ 62 | +static void setup_sections_memory_protection(unsigned long image_base) 63 | +{ 64 | +#ifdef CONFIG_EFI_DXE_MEM_ATTRIBUTES 65 | + efi_dxe_table = get_efi_config_table(EFI_DXE_SERVICES_TABLE_GUID); 66 | + 67 | + if (!efi_dxe_table || 68 | + efi_dxe_table->hdr.signature != EFI_DXE_SERVICES_TABLE_SIGNATURE) { 69 | + efi_warn("Unable to locate EFI DXE services table\n"); 70 | + efi_dxe_table = NULL; 71 | + return; 72 | + } 73 | + 74 | + /* .setup [image_base, _head] */ 75 | + efi_adjust_memory_range_protection(image_base, 76 | + (unsigned long)_head - image_base, 77 | + EFI_MEMORY_RO | EFI_MEMORY_XP); 78 | + /* .head.text [_head, _ehead] */ 79 | + efi_adjust_memory_range_protection((unsigned long)_head, 80 | + (unsigned long)_ehead - (unsigned long)_head, 81 | + EFI_MEMORY_RO); 82 | + /* .rodata..compressed [_compressed, _ecompressed] */ 83 | + efi_adjust_memory_range_protection((unsigned long)_compressed, 84 | + (unsigned long)_ecompressed - (unsigned long)_compressed, 85 | + EFI_MEMORY_RO | EFI_MEMORY_XP); 86 | + /* .text [_text, _etext] */ 87 | + efi_adjust_memory_range_protection((unsigned long)_text, 88 | + (unsigned long)_etext - (unsigned long)_text, 89 | + EFI_MEMORY_RO); 90 | + /* .rodata [_rodata, _erodata] */ 91 | + efi_adjust_memory_range_protection((unsigned long)_rodata, 92 | + (unsigned long)_erodata - (unsigned long)_rodata, 93 | + EFI_MEMORY_RO | EFI_MEMORY_XP); 94 | + /* .data, .bss [_data, _end] */ 95 | + efi_adjust_memory_range_protection((unsigned long)_data, 96 | + (unsigned long)_end - (unsigned long)_data, 97 | + EFI_MEMORY_XP); 98 | +#else 99 | + (void)image_base; 100 | +#endif 101 | +} 102 | + 103 | void __noreturn efi_stub_entry(efi_handle_t handle, 104 | efi_system_table_t *sys_table_arg, 105 | struct boot_params *boot_params); 106 | @@ -687,6 +739,8 @@ asmlinkage unsigned long efi_main(efi_handle_t handle, 107 | efi_dxe_table = NULL; 108 | } 109 | 110 | + setup_sections_memory_protection(bzimage_addr - image_offset); 111 | + 112 | #ifdef CONFIG_CMDLINE_BOOL 113 | status = efi_parse_options(CONFIG_CMDLINE); 114 | if (status != EFI_SUCCESS) { 115 | -- 116 | 2.39.2 117 | 118 | -------------------------------------------------------------------------------- /tinylinux/patches/linux/v6.3/v5-0023-efi-libstub-make-memory-protection-warnings-inclu.patch: -------------------------------------------------------------------------------- 1 | From 8bc86eabbf2a697fe2c09b41796dede70909e4ea Mon Sep 17 00:00:00 2001 2 | Message-Id: <...> 3 | In-Reply-To: <...> 4 | References: <...> 5 | From: Peter Jones <...> 6 | To: Ard Biesheuvel <...> 7 | Cc: Borislav Petkov <...> 8 | Cc: Andy Lutomirski <...> 9 | Cc: Dave Hansen <...> 10 | Cc: Ingo Molnar <...> 11 | Cc: Peter Zijlstra <...> 12 | Cc: Thomas Gleixner <...> 13 | Cc: Alexey Khoroshilov <...> 14 | Cc: Peter Jones <...> 15 | Cc: "Limonciello, Mario" <...> 16 | Cc: joeyli <...> 17 | Cc: ... 18 | Cc: ... 19 | Cc: ... 20 | Cc: ... 21 | Cc: ... 22 | Date: Tue, 18 Oct 2022 16:51:18 -0400 23 | Subject: [PATCH v5 23/23] efi/libstub: make memory protection warnings include 24 | newlines. 25 | 26 | efi_warn() doesn't put newlines on messages, and that makes reading 27 | warnings without newlines hard to do. 28 | 29 | Signed-off-by: Peter Jones <...> 30 | --- 31 | drivers/firmware/efi/libstub/mem.c | 4 ++-- 32 | 1 file changed, 2 insertions(+), 2 deletions(-) 33 | 34 | diff --git a/drivers/firmware/efi/libstub/mem.c b/drivers/firmware/efi/libstub/mem.c 35 | index 2d9ae1fae9c3..d8e5710c987b 100644 36 | --- a/drivers/firmware/efi/libstub/mem.c 37 | +++ b/drivers/firmware/efi/libstub/mem.c 38 | @@ -300,7 +300,7 @@ efi_status_t efi_adjust_memory_range_protection(unsigned long start, 39 | rounded_end - rounded_start, 40 | attr_clear); 41 | if (status != EFI_SUCCESS) { 42 | - efi_warn("Failed to clear memory attributes at [%08lx,%08lx]: %lx", 43 | + efi_warn("Failed to clear memory attributes at [%08lx,%08lx]: %lx\n", 44 | (unsigned long)rounded_start, 45 | (unsigned long)rounded_end, 46 | status); 47 | @@ -313,7 +313,7 @@ efi_status_t efi_adjust_memory_range_protection(unsigned long start, 48 | rounded_end - rounded_start, 49 | attributes); 50 | if (status != EFI_SUCCESS) { 51 | - efi_warn("Failed to set memory attributes at [%08lx,%08lx]: %lx", 52 | + efi_warn("Failed to set memory attributes at [%08lx,%08lx]: %lx\n", 53 | (unsigned long)rounded_start, 54 | (unsigned long)rounded_end, 55 | status); 56 | -- 57 | 2.39.2 58 | 59 | -------------------------------------------------------------------------------- /uncstrap/uncstrap.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | 3 | import os 4 | import platform 5 | import shutil 6 | import stat 7 | import subprocess 8 | import sys 9 | 10 | # pip install requests 11 | import requests 12 | 13 | # pip install pyyaml 14 | import yaml 15 | 16 | # pip install gitpython 17 | from git import Repo 18 | 19 | 20 | def abort(message): 21 | print('ERROR: ' + message + '!') 22 | sys.exit(1) 23 | 24 | 25 | UNSUPPORTED_DIST = os.getenv('UNSUPPORTED_DIST', '0') 26 | DIST = platform.uname().system 27 | if UNSUPPORTED_DIST != 1: 28 | if DIST not in ('Darwin', 'Linux', 'Windows'): 29 | abort('Unsupported OS distribution ' + DIST) 30 | 31 | PROJECT_TYPE = os.getenv('PROJECT_TYPE', '') 32 | if PROJECT_TYPE != 'UEFI': 33 | abort('Unsupported project type ' + PROJECT_TYPE) 34 | 35 | cmake_stat = shutil.which('cmake') 36 | if cmake_stat is None: 37 | abort('Missing cmake') 38 | 39 | try: 40 | os.chdir(os.getcwd()) 41 | except OSError as ex: 42 | print(ex) 43 | abort('Failed to switch to current directory') 44 | 45 | UNC_REPO = 'Uncrustify-repo' 46 | UNC_LINK = 'https://projectmu@dev.azure.com/projectmu/Uncrustify/_git/Uncrustify' 47 | UNC_CONF = 'unc-' + PROJECT_TYPE + '.cfg' 48 | SRC_LIST = 'unc-srclist.txt' 49 | UNC_DIFF = 'uncrustify.diff' 50 | BUILD_SCHEME = 'Release' 51 | 52 | 53 | def dump_file_list(yml_file): 54 | with open(yml_file, mode='r', encoding='UTF-8') as buffer: 55 | yaml_buffer = yaml.safe_load(buffer) 56 | exclude_list = yaml_buffer['exclude_list'] 57 | 58 | # Match .c and .h files 59 | file_list = [os.path.join(path, name) for path, subdirs, files in os.walk(os.getcwd()) for name in files if name.lower().endswith((".c", ".h"))] 60 | with open(SRC_LIST, 'w', encoding='UTF-8') as list_txt: 61 | for file in file_list: 62 | skip = False 63 | for excl in exclude_list: 64 | if os.path.normpath(excl) in os.path.normpath(file): 65 | skip = True 66 | 67 | if skip: 68 | continue 69 | 70 | list_txt.write(file + '\n') 71 | 72 | 73 | # 74 | # shutil.rmtree error handling. 75 | # From: https://stackoverflow.com/a/2656405 76 | # 77 | def onerror(func, path, *_): 78 | """ 79 | Error handler for ``shutil.rmtree``. 80 | 81 | If the error is due to an access error (read only file) 82 | it attempts to add write permission and then retries. 83 | 84 | If the error is for another reason it re-raises the error. 85 | 86 | Usage : ``shutil.rmtree(path, onerror=onerror)`` 87 | """ 88 | # Is the error an access error? 89 | if not os.access(path, os.W_OK): 90 | os.chmod(path, stat.S_IWUSR) 91 | func(path) 92 | 93 | 94 | def build_uncrustify(url): 95 | if os.path.isdir(UNC_REPO): 96 | shutil.rmtree(UNC_REPO, onexc=onerror) 97 | 98 | proj_root = os.getcwd() 99 | 100 | repo = Repo.clone_from(url, UNC_REPO) 101 | os.chdir(UNC_REPO) 102 | sha = repo.head.object.hexsha 103 | 104 | # write sha to a file, so that actions/upload-artifact has access to it 105 | sha_txt = 'unc-sha.txt' 106 | with open(sha_txt, 'w', encoding='UTF-8') as unc_sha: 107 | unc_sha.write(sha) 108 | shutil.move(sha_txt, proj_root) 109 | 110 | os.mkdir('build') 111 | os.chdir('build') 112 | cmake_args = ['cmake', '..'] 113 | ret = subprocess.check_call(cmake_args) 114 | if ret != 0: 115 | abort('Failed to generate makefile with cmake') 116 | cmake_args = ['cmake', '--build', '.', '--config', BUILD_SCHEME] 117 | ret = subprocess.check_call(cmake_args) 118 | if ret != 0: 119 | abort('Failed to build Uncrustify ' + BUILD_SCHEME) 120 | 121 | exe = next((os.path.abspath(os.path.join(root, name)) for root, dirs, files in os.walk(os.getcwd()) for name in files if name in ('uncrustify', 'uncrustify.exe')), None) 122 | if exe is None: 123 | raise ValueError('Uncrustify binary is not found!') 124 | shutil.move(exe, proj_root) 125 | 126 | os.chdir(proj_root) 127 | 128 | 129 | def download_uncrustify_conf(): 130 | response = requests.get('https://raw.githubusercontent.com/acidanthera/ocbuild/master/uncstrap/configs/' + UNC_CONF, timeout=5) 131 | with open(UNC_CONF, 'wb') as conf: 132 | conf.write(response.content) 133 | 134 | 135 | def download_uncrustify_bin(): 136 | zip_name = 'Uncrustify-' + DIST + '.zip' 137 | if os.path.isfile(zip_name): 138 | os.remove(zip_name) 139 | 140 | response = requests.get('https://raw.githubusercontent.com/acidanthera/ocbuild/master/external/' + zip_name, timeout=5) 141 | real_filename = response.text 142 | 143 | response = requests.get('https://raw.githubusercontent.com/acidanthera/ocbuild/master/external/' + real_filename, timeout=5) 144 | with open(zip_name, 'wb') as archive: 145 | archive.write(response.content) 146 | 147 | unzip_args = ['unzip', '-qu', zip_name] 148 | ret = subprocess.check_call(unzip_args) 149 | if ret != 0: 150 | abort('Failed to unzip ' + zip_name) 151 | os.remove(zip_name) 152 | 153 | exe = next((os.path.abspath(os.path.join(root, name)) for root, dirs, files in os.walk(os.getcwd()) for name in files if name in ('uncrustify', 'uncrustify.exe')), None) 154 | if exe is None: 155 | raise ValueError('Uncrustify binary is not found!') 156 | 157 | exe_stat = os.stat(exe) 158 | os.chmod(exe, exe_stat.st_mode | stat.S_IEXEC) 159 | 160 | return exe 161 | 162 | 163 | def run_uncrustify(unc_exec): 164 | if os.path.isfile(UNC_DIFF): 165 | os.remove(UNC_DIFF) 166 | 167 | unc_args = [unc_exec, '-c', UNC_CONF, '-F', SRC_LIST, '--replace', '--no-backup', '--if-changed'] 168 | subprocess.check_call(unc_args) 169 | 170 | with open(SRC_LIST, 'r', encoding='UTF-8') as list_buffer: 171 | lines = list_buffer.read().splitlines() 172 | 173 | repo = Repo(os.getcwd()) 174 | with open(UNC_DIFF, 'w', encoding='UTF-8') as diff_txt: 175 | for line in lines: 176 | diff_output = repo.git.diff(line) 177 | if diff_output != '': 178 | print(diff_output + '\n') 179 | diff_txt.write(diff_output + '\n') 180 | 181 | file_cleanup = [SRC_LIST, unc_exec, UNC_CONF] 182 | for file in file_cleanup: 183 | if os.path.isfile(file): 184 | os.remove(file) 185 | 186 | if os.stat(UNC_DIFF).st_size != 0: 187 | abort('Uncrustify detects codestyle problems! Please fix') 188 | 189 | print('All done! Uncrustify detects no problems!') 190 | os.remove(UNC_DIFF) 191 | 192 | 193 | def main(): 194 | if sys.argv[1] in ('-b', '--build'): 195 | build_uncrustify(UNC_LINK) 196 | sys.exit(0) 197 | 198 | dump_file_list(sys.argv[1]) 199 | download_uncrustify_conf() 200 | unc_exec = download_uncrustify_bin() 201 | run_uncrustify(unc_exec) 202 | 203 | 204 | if __name__ == '__main__': 205 | try: 206 | main() 207 | except Exception as ex: 208 | print(f"Bailed beacuse: {ex}") 209 | sys.exit(1) 210 | --------------------------------------------------------------------------------