├── debian ├── compat ├── source │ ├── format │ └── lintian-overrides ├── edk2-cix.lintian-overrides ├── .gitignore ├── rules ├── common-lintian-overrides ├── edk2-cix.install ├── control ├── edk2-cix.postinst ├── copyright └── changelog ├── po ├── .gitignore ├── messages.pot └── zh-CN.po ├── Makefile ├── logs └── .gitignore ├── .devcontainer ├── .devenv │ └── .gitignore ├── .direnv │ └── .gitignore └── devcontainer.json ├── src ├── .gitignore ├── tools │ └── acpica │ │ └── README.md ├── scripts │ ├── welcome.nsh │ └── startup.nsh └── Makefile ├── theme ├── favicon.png ├── fonts │ ├── open-sans-v17-all-charsets-300.woff2 │ ├── open-sans-v17-all-charsets-600.woff2 │ ├── open-sans-v17-all-charsets-700.woff2 │ ├── open-sans-v17-all-charsets-800.woff2 │ ├── open-sans-v17-all-charsets-italic.woff2 │ ├── open-sans-v17-all-charsets-regular.woff2 │ ├── open-sans-v17-all-charsets-300italic.woff2 │ ├── open-sans-v17-all-charsets-600italic.woff2 │ ├── open-sans-v17-all-charsets-700italic.woff2 │ ├── open-sans-v17-all-charsets-800italic.woff2 │ ├── source-code-pro-v11-all-charsets-500.woff2 │ ├── fonts.css │ ├── SOURCE-CODE-PRO-LICENSE.txt │ └── OPEN-SANS-LICENSE.txt ├── css │ ├── language-picker.css │ ├── print.css │ ├── general.css │ ├── variables.css │ ├── chrome.css │ └── mdbook-admonish.css ├── highlight.css ├── favicon.svg ├── index.hbs └── book.js ├── .github ├── dependabot.yaml ├── local │ ├── Makefile.local │ └── devenv.nix ├── CODEOWNERS ├── workflows │ ├── check_linked_issue.yaml │ ├── dependabot.yaml │ ├── new_version.yaml │ ├── docs.yaml │ └── release.yaml └── common │ └── Makefile ├── docs ├── SUMMARY.md ├── build.md ├── debug.md ├── update.md └── install.md ├── .envrc ├── .gitmodules ├── .gitignore ├── README.md ├── devenv.yaml ├── devenv.local.nix.example ├── book.toml ├── devenv.nix └── devenv.lock /debian/compat: -------------------------------------------------------------------------------- 1 | 12 2 | -------------------------------------------------------------------------------- /po/.gitignore: -------------------------------------------------------------------------------- 1 | /*.po~ 2 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | .github/common/Makefile -------------------------------------------------------------------------------- /logs/.gitignore: -------------------------------------------------------------------------------- 1 | * 2 | !.gitignore -------------------------------------------------------------------------------- /debian/source/format: -------------------------------------------------------------------------------- 1 | 3.0 (quilt) 2 | -------------------------------------------------------------------------------- /.devcontainer/.devenv/.gitignore: -------------------------------------------------------------------------------- 1 | * 2 | !.gitignore 3 | -------------------------------------------------------------------------------- /.devcontainer/.direnv/.gitignore: -------------------------------------------------------------------------------- 1 | * 2 | !.gitignore 3 | -------------------------------------------------------------------------------- /src/.gitignore: -------------------------------------------------------------------------------- 1 | /Build 2 | /output 3 | /tools/gcc 4 | /cix_flash.bin 5 | /patches* 6 | -------------------------------------------------------------------------------- /theme/favicon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/radxa-pkg/edk2-cix/HEAD/theme/favicon.png -------------------------------------------------------------------------------- /debian/edk2-cix.lintian-overrides: -------------------------------------------------------------------------------- 1 | # We use shebang to stop user running UEFI Shell script on Linux 2 | edk2-cix: unusual-interpreter 3 | -------------------------------------------------------------------------------- /.github/dependabot.yaml: -------------------------------------------------------------------------------- 1 | updates: 2 | - directory: "/" 3 | package-ecosystem: "github-actions" 4 | schedule: 5 | interval: "daily" 6 | version: 2 -------------------------------------------------------------------------------- /theme/fonts/open-sans-v17-all-charsets-300.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/radxa-pkg/edk2-cix/HEAD/theme/fonts/open-sans-v17-all-charsets-300.woff2 -------------------------------------------------------------------------------- /theme/fonts/open-sans-v17-all-charsets-600.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/radxa-pkg/edk2-cix/HEAD/theme/fonts/open-sans-v17-all-charsets-600.woff2 -------------------------------------------------------------------------------- /theme/fonts/open-sans-v17-all-charsets-700.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/radxa-pkg/edk2-cix/HEAD/theme/fonts/open-sans-v17-all-charsets-700.woff2 -------------------------------------------------------------------------------- /theme/fonts/open-sans-v17-all-charsets-800.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/radxa-pkg/edk2-cix/HEAD/theme/fonts/open-sans-v17-all-charsets-800.woff2 -------------------------------------------------------------------------------- /theme/fonts/open-sans-v17-all-charsets-italic.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/radxa-pkg/edk2-cix/HEAD/theme/fonts/open-sans-v17-all-charsets-italic.woff2 -------------------------------------------------------------------------------- /theme/fonts/open-sans-v17-all-charsets-regular.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/radxa-pkg/edk2-cix/HEAD/theme/fonts/open-sans-v17-all-charsets-regular.woff2 -------------------------------------------------------------------------------- /theme/fonts/open-sans-v17-all-charsets-300italic.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/radxa-pkg/edk2-cix/HEAD/theme/fonts/open-sans-v17-all-charsets-300italic.woff2 -------------------------------------------------------------------------------- /theme/fonts/open-sans-v17-all-charsets-600italic.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/radxa-pkg/edk2-cix/HEAD/theme/fonts/open-sans-v17-all-charsets-600italic.woff2 -------------------------------------------------------------------------------- /theme/fonts/open-sans-v17-all-charsets-700italic.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/radxa-pkg/edk2-cix/HEAD/theme/fonts/open-sans-v17-all-charsets-700italic.woff2 -------------------------------------------------------------------------------- /theme/fonts/open-sans-v17-all-charsets-800italic.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/radxa-pkg/edk2-cix/HEAD/theme/fonts/open-sans-v17-all-charsets-800italic.woff2 -------------------------------------------------------------------------------- /theme/fonts/source-code-pro-v11-all-charsets-500.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/radxa-pkg/edk2-cix/HEAD/theme/fonts/source-code-pro-v11-all-charsets-500.woff2 -------------------------------------------------------------------------------- /debian/.gitignore: -------------------------------------------------------------------------------- 1 | /.debhelper 2 | /debhelper-build-stamp 3 | /files 4 | /*.debhelper.log 5 | /*.postrm.debhelper 6 | /*.substvars 7 | /SOURCE 8 | /edk2-*/ 9 | /tmp 10 | -------------------------------------------------------------------------------- /docs/SUMMARY.md: -------------------------------------------------------------------------------- 1 | # Summary 2 | 3 | - [Build](build.md) 4 | - [Debug](debug.md) 5 | - [Update BIOS from RadxaOS](update.md) 6 | - [Manually install released binary](install.md) 7 | -------------------------------------------------------------------------------- /.envrc: -------------------------------------------------------------------------------- 1 | source_url "https://raw.githubusercontent.com/cachix/devenv/d1f7b48e35e6dee421cfd0f51481d17f77586997/direnvrc" "sha256-YBzqskFZxmNb3kYVoKD9ZixoPXJh1C9ZvTLGFRkauZ0=" 2 | 3 | use devenv 4 | -------------------------------------------------------------------------------- /.github/local/Makefile.local: -------------------------------------------------------------------------------- 1 | PROJECT ?= edk2-cix 2 | 3 | build: build-edk2 4 | 5 | .PHONY: build-edk2 6 | build-edk2: 7 | make -C src 8 | 9 | clean: clean-edk2 10 | 11 | .PHONY: clean-edk2 12 | clean-edk2: 13 | make -C src clean 14 | -------------------------------------------------------------------------------- /theme/css/language-picker.css: -------------------------------------------------------------------------------- 1 | #language-list { 2 | left: auto; 3 | right: 10px; 4 | } 5 | 6 | [dir="rtl"] #language-list { 7 | left: 10px; 8 | right: auto; 9 | } 10 | 11 | #language-list a { 12 | color: inherit; 13 | } 14 | -------------------------------------------------------------------------------- /debian/source/lintian-overrides: -------------------------------------------------------------------------------- 1 | # Our package is built on GitHub-hosted runner, 2 | # which uses Ubuntu, and will default to zstd compression. 3 | # This is currently not supported in Debian. 4 | edk2-cix source: custom-compression-in-debian-rules 5 | -------------------------------------------------------------------------------- /.github/CODEOWNERS: -------------------------------------------------------------------------------- 1 | # Catch-all code owner 2 | * @RadxaYuntian 3 | 4 | # Disown CI yaml so automerge can work 5 | # https://github.com/orgs/community/discussions/23064#discussioncomment-8383923 6 | .github/actions/**/*.yaml 7 | .github/workflows/*.yaml 8 | -------------------------------------------------------------------------------- /src/tools/acpica/README.md: -------------------------------------------------------------------------------- 1 | ## Submodule removed 2 | 3 | `acpica` has been removed from this repo, as we no longer use it. 4 | 5 | If you are using CIX's build script, you may clone their `acpica` fork here. 6 | 7 | Check the commit that created this file to learn more. 8 | -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "src/edk2"] 2 | path = src/edk2 3 | url = https://github.com/radxa/edk2.git 4 | [submodule "src/edk2-non-osi"] 5 | path = src/edk2-non-osi 6 | url = https://github.com/radxa/edk2-non-osi.git 7 | [submodule "src/edk2-platforms"] 8 | path = src/edk2-platforms 9 | url = https://github.com/radxa/edk2-platforms.git 10 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Devenv 2 | /.devenv* 3 | /devenv.local.nix 4 | 5 | # direnv 6 | /.direnv 7 | 8 | # pre-commit 9 | /.pre-commit-config.yaml 10 | 11 | # node.js 12 | /node_modules 13 | 14 | # Local VS Code configuration 15 | /.vscode* 16 | 17 | # mdbook build output 18 | /book 19 | 20 | # debuild work directory 21 | /.pc 22 | 23 | # intel-corporation.edk2code extension file 24 | /.edkCode 25 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # edk2-cix 2 | 3 | [![Release](https://github.com/radxa-pkg/edk2-cix/actions/workflows/release.yaml/badge.svg)](https://github.com/radxa-pkg/edk2-cix/actions/workflows/release.yaml) 4 | 5 | ## Build 6 | 7 | 1. `git clone --recurse-submodules https://github.com/radxa-pkg/edk2-cix.git` 8 | 2. Open in [`devcontainer`](https://code.visualstudio.com/docs/devcontainers/containers) 9 | 3. `make deb` 10 | -------------------------------------------------------------------------------- /devenv.yaml: -------------------------------------------------------------------------------- 1 | # yaml-language-server: $schema=https://devenv.sh/devenv.schema.json 2 | inputs: 3 | nixpkgs: 4 | url: github:cachix/devenv-nixpkgs/rolling 5 | 6 | # If you're using non-OSS software, you can set allowUnfree to true. 7 | # allowUnfree: true 8 | 9 | # If you're willing to use a package that's vulnerable 10 | # permittedInsecurePackages: 11 | # - "openssl-1.1.1w" 12 | 13 | # If you have more than one devenv you can merge them 14 | #imports: 15 | # - ./backend 16 | -------------------------------------------------------------------------------- /.github/workflows/check_linked_issue.yaml: -------------------------------------------------------------------------------- 1 | jobs: 2 | check_pull_requests: 3 | name: "Check linked issues" 4 | permissions: 5 | issues: "write" 6 | pull-requests: "write" 7 | runs-on: "ubuntu-latest" 8 | steps: 9 | - name: "Check linked issues" 10 | uses: "nearform-actions/github-action-check-linked-issues@v1" 11 | name: "Check linked issues" 12 | "on": 13 | pull_request_target: 14 | types: 15 | - "opened" 16 | - "reopened" 17 | permissions: {} -------------------------------------------------------------------------------- /devenv.local.nix.example: -------------------------------------------------------------------------------- 1 | # You can use devenv.local.nix to override the default settings. 2 | # This file is provided as an example. 3 | 4 | { pkgs, ... }: 5 | 6 | { 7 | # Override rsdk defaults here 8 | env = { 9 | EDK2_EC_UART = "ttyCH9344USB0"; # UART1 10 | EDK2_SE_UART = "ttyCH9344USB1"; # UART5 11 | EDK2_AP_UART = "ttyCH9344USB2"; # UART2 12 | EDK2_DEBUG_UART = "ttyCH9344USB3"; # UART3 13 | DEBEMAIL = "email@example.com"; # Email in debian/changelog 14 | DEBFULLNAME = "\"Example Co., Ltd\""; # Full name in debian/changelog 15 | }; 16 | } 17 | -------------------------------------------------------------------------------- /debian/rules: -------------------------------------------------------------------------------- 1 | #!/usr/bin/make -f 2 | 3 | # This file is auto generated by rsdk infra-package-update. 4 | # DO NOT EDIT IT DIRECTLY! 5 | # Custom rules should be placed in .github/local/rules.local 6 | 7 | include /usr/share/dpkg/pkg-info.mk 8 | include /usr/share/dpkg/architecture.mk 9 | -include .github/local/rules.local 10 | 11 | %: 12 | dh $@ $(EXTRA_DH_OPTIONS) 13 | 14 | override_dh_builddeb: 15 | dh_builddeb -- -Zxz 16 | 17 | # This file is auto generated by rsdk infra-package-update. 18 | # DO NOT EDIT IT DIRECTLY! 19 | # Custom rules should be placed in .github/local/rules.local 20 | -------------------------------------------------------------------------------- /.github/workflows/dependabot.yaml: -------------------------------------------------------------------------------- 1 | jobs: 2 | dependabot: 3 | if: "github.actor == 'dependabot[bot]'" 4 | runs-on: "ubuntu-latest" 5 | steps: 6 | - id: "metadata" 7 | name: "Dependabot metadata" 8 | uses: "dependabot/fetch-metadata@v2" 9 | with: 10 | github-token: "${{ secrets.GITHUB_TOKEN }}" 11 | - env: 12 | GH_TOKEN: "${{secrets.GITHUB_TOKEN}}" 13 | PR_URL: "${{github.event.pull_request.html_url}}" 14 | name: "Approve a PR & Enable auto-merge for Dependabot PRs" 15 | run: | 16 | gh pr review --approve "$PR_URL" 17 | gh pr merge --auto --merge "$PR_URL" 18 | name: "Dependabot auto-merge" 19 | "on": 20 | pull_request: {} 21 | permissions: 22 | contents: "write" 23 | pull-requests: "write" -------------------------------------------------------------------------------- /book.toml: -------------------------------------------------------------------------------- 1 | [book] 2 | authors = ["Radxa Limited"] 3 | language = "en" 4 | multilingual = true 5 | src = "docs" 6 | title = "edk2-cix" 7 | 8 | [build] 9 | extra-watch-dirs = ["po"] 10 | 11 | [output.linkcheck] 12 | 13 | [output.html] 14 | git-repository-url = "https://github.com/radxa-pkg/edk2-cix/tree/main" 15 | edit-url-template = "https://github.com/radxa-pkg/edk2-cix/edit/main/{path}" 16 | additional-css = [ 17 | "./theme/css/mdbook-admonish.css", 18 | "./theme/css/language-picker.css", 19 | ] 20 | 21 | [preprocessor.admonish] 22 | command = "mdbook-admonish" 23 | assets_version = "3.0.2" # do not edit: managed by `mdbook-admonish install` 24 | 25 | [preprocessor.gettext] 26 | after = ["links"] 27 | 28 | [preprocessor.toc] 29 | command = "mdbook-toc" 30 | renderer = ["html"] 31 | 32 | [preprocessor.cmdrun] 33 | -------------------------------------------------------------------------------- /debian/common-lintian-overrides: -------------------------------------------------------------------------------- 1 | # This file is auto generated by rsdk infra-package-update. 2 | # DO NOT EDIT IT DIRECTLY! 3 | # Custom rules should be placed in debian/.lintian-overrides 4 | # or debian/source/.lintian-overrides 5 | 6 | # We do not track this on GitHub 7 | initial-upload-closes-no-bugs 8 | 9 | # We might use our own distribution name 10 | bad-distribution-in-changes-file 11 | 12 | # Our package is built on GitHub-hosted runner, 13 | # which uses Ubuntu, and will default to zstd compression. 14 | # This was not supported in Debian 11. 15 | custom-compression-in-debian-rules 16 | 17 | # Small bug number is very probable for us. 18 | improbable-bug-number-in-closes 19 | 20 | # This file is auto generated by rsdk infra-package-update. 21 | # DO NOT EDIT IT DIRECTLY! 22 | # Custom rules should be placed in debian/.lintian-overrides 23 | # or debian/source/.lintian-overrides 24 | -------------------------------------------------------------------------------- /devenv.nix: -------------------------------------------------------------------------------- 1 | { pkgs, lib, config, ... }: 2 | 3 | { 4 | imports = lib.optional (builtins.pathExists ./.github/local/devenv.nix) ./.github/local/devenv.nix; 5 | 6 | # https://devenv.sh/packages/ 7 | packages = with pkgs; [ 8 | bash-completion 9 | mdbook 10 | mdbook-admonish 11 | mdbook-cmdrun 12 | mdbook-i18n-helpers 13 | mdbook-linkcheck 14 | mdbook-toc 15 | ncurses 16 | ]; 17 | 18 | git-hooks = { 19 | hooks = { 20 | commitizen.enable = true; 21 | shellcheck = { 22 | enable = true; 23 | entry = lib.mkForce "${pkgs.shellcheck}/bin/shellcheck -x"; 24 | }; 25 | shfmt.enable = true; 26 | statix.enable = true; 27 | typos = { 28 | enable = true; 29 | excludes = [ 30 | "theme/highlight.js" 31 | ]; 32 | settings.ignored-words = [ 33 | "Synopsys" 34 | "HSI" 35 | ]; 36 | }; 37 | }; 38 | }; 39 | 40 | starship.enable = true; 41 | } 42 | -------------------------------------------------------------------------------- /theme/css/print.css: -------------------------------------------------------------------------------- 1 | #sidebar, 2 | #menu-bar, 3 | .nav-chapters, 4 | .mobile-nav-chapters { 5 | display: none; 6 | } 7 | 8 | #page-wrapper.page-wrapper { 9 | transform: none; 10 | margin-left: 0px; 11 | overflow-y: initial; 12 | } 13 | 14 | #content { 15 | max-width: none; 16 | margin: 0; 17 | padding: 0; 18 | } 19 | 20 | .page { 21 | overflow-y: initial; 22 | } 23 | 24 | code { 25 | background-color: #666666; 26 | border-radius: 5px; 27 | 28 | /* Force background to be printed in Chrome */ 29 | -webkit-print-color-adjust: exact; 30 | } 31 | 32 | pre > .buttons { 33 | z-index: 2; 34 | } 35 | 36 | a, 37 | a:visited, 38 | a:active, 39 | a:hover { 40 | color: #4183c4; 41 | text-decoration: none; 42 | } 43 | 44 | h1, 45 | h2, 46 | h3, 47 | h4, 48 | h5, 49 | h6 { 50 | page-break-inside: avoid; 51 | page-break-after: avoid; 52 | } 53 | 54 | pre, 55 | code { 56 | page-break-inside: avoid; 57 | white-space: pre-wrap; 58 | } 59 | 60 | .fa { 61 | display: none !important; 62 | } 63 | -------------------------------------------------------------------------------- /debian/edk2-cix.install: -------------------------------------------------------------------------------- 1 | #!/usr/bin/dh-exec 2 | 3 | src/scripts/welcome.nsh => /usr/share/edk2/radxa/startup.nsh 4 | 5 | src/Build/O6/*_GCC5/cix_flash*.bin /usr/share/edk2/radxa/orion-o6/ 6 | src/Build/O6/*_GCC5/BuildOptions /usr/share/edk2/radxa/orion-o6/ 7 | src/Build/O6/*_GCC5/AARCH64/EnrollFromDefaultKeysApp.efi /usr/share/edk2/radxa/orion-o6/ 8 | src/Build/O6/*_GCC5/AARCH64/VariableInfo.efi /usr/share/edk2/radxa/orion-o6/ 9 | src/Build/O6/*_GCC5/AARCH64/Shell.efi /usr/share/edk2/radxa/orion-o6/ 10 | src/edk2-non-osi/Platform/CIX/Sky1/FlashTool/* /usr/share/edk2/radxa/orion-o6/ 11 | src/scripts/startup.nsh /usr/share/edk2/radxa/orion-o6/ 12 | 13 | src/Build/O6N/*_GCC5/cix_flash*.bin /usr/share/edk2/radxa/orion-o6n/ 14 | src/Build/O6N/*_GCC5/BuildOptions /usr/share/edk2/radxa/orion-o6n/ 15 | src/Build/O6N/*_GCC5/AARCH64/EnrollFromDefaultKeysApp.efi /usr/share/edk2/radxa/orion-o6n/ 16 | src/Build/O6N/*_GCC5/AARCH64/VariableInfo.efi /usr/share/edk2/radxa/orion-o6n/ 17 | src/Build/O6N/*_GCC5/AARCH64/Shell.efi /usr/share/edk2/radxa/orion-o6n/ 18 | src/edk2-non-osi/Platform/CIX/Sky1/FlashTool/* /usr/share/edk2/radxa/orion-o6n/ 19 | src/scripts/startup.nsh /usr/share/edk2/radxa/orion-o6n/ 20 | -------------------------------------------------------------------------------- /debian/control: -------------------------------------------------------------------------------- 1 | Source: edk2-cix 2 | Maintainer: "Radxa Computer Co., Ltd" 3 | Section: admin 4 | Priority: standard 5 | Standards-Version: 4.6.0 6 | Build-Depends: debhelper (>=12~), 7 | devscripts, 8 | lintian, 9 | dh-exec, 10 | dos2unix, 11 | pandoc, 12 | shellcheck, 13 | acpica-tools, 14 | uuid-dev, 15 | nasm, 16 | bison, 17 | flex, 18 | curl, 19 | crossbuild-essential-arm64 [!arm64], 20 | 21 | Package: edk2-cix 22 | Architecture: all 23 | Section: admin 24 | Priority: standard 25 | Depends: ${misc:Depends} 26 | Description: CIX EDK II firmwares 27 | This package contains prebuild CIX EDK II firmwares. 28 | 29 | Package: edk2-orion-o6 30 | Architecture: all 31 | Section: admin 32 | Priority: standard 33 | Depends: edk2-cix, 34 | ${misc:Depends} 35 | Description: Radxa EDK II meta-package for Orion O6 36 | This is the meta-package for EDK II. 37 | 38 | Package: edk2-radxa-orion-cix-p1 39 | Architecture: all 40 | Section: admin 41 | Priority: standard 42 | Depends: edk2-cix, 43 | ${misc:Depends} 44 | Description: Radxa EDK II meta-package for generic CIX P1 image 45 | This is the meta-package for EDK II. 46 | -------------------------------------------------------------------------------- /src/scripts/welcome.nsh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env -S echo "This script is for UEFI Shell only:" 2 | 3 | @echo -off 4 | 5 | for %q in 0 1 2 3 4 5 6 7 8 9 A B C D E F then 6 | if "FS%q:\edk2\radxa\startup.nsh" == "%0" then 7 | FS%q: 8 | cd "%0\..\" 9 | goto main 10 | endif 11 | endfor 12 | 13 | echo "Failed to locate %0." 14 | goto EOF 15 | 16 | :main 17 | echo "************************************************************************" 18 | echo " Radxa BIOS Update Console" 19 | echo "************************************************************************" 20 | echo " " 21 | echo "You are now about to update the BIOS for your machine." 22 | echo " " 23 | echo "Updating BIOS incorrectly can cause boot issue." 24 | echo "Radxa recommends to have external SPI flasher at hand for recovery purpose." 25 | echo " " 26 | echo "If you decide to cancel BIOS update, you can run following commands:" 27 | echo " reset to reboot the system" 28 | echo " reset -s to shutdown the system" 29 | pause 30 | 31 | echo "Except the first startup.nsh, following products are currently supported:" 32 | echo " " 33 | 34 | ls -b -r -a startup.nsh 35 | 36 | echo " " 37 | echo "To update the BIOS, please run '\startup.nsh' to start." 38 | echo " " 39 | echo "You can now start updating your BIOS." 40 | 41 | :EOF 42 | -------------------------------------------------------------------------------- /docs/build.md: -------------------------------------------------------------------------------- 1 | # Build 2 | 3 | We use devcontainer to maintain a consistent build environment. 4 | 5 | To build all supported EDK2 variants, please run `make deb` within devcontainer. 6 | 7 | Set `BUILD_TARGET` to `DEBUG` in `src/Makefile` to build for debug artifacts. 8 | 9 | Edit `DSC` in `src/Makefile` to reduce amount of variants that will be built. 10 | You should also edit `debian/edk2-cix.install` to exclude unbuild variants, 11 | otherwise `debuild` will complain that those files are missing. 12 | 13 | ## Update submodules 14 | 15 | We are currently in active development with `edk2-cix`, which means the 16 | underlying submodules can change drastically, and requires main repo to adjust. 17 | 18 | However, since we rebase our submodules fequently, there is not much point to 19 | commit those temporary commit IDs into `edk2-cix`. When those commit IDs 20 | expired, users will not be able to clone repo with submodules without failure. 21 | 22 | In general, if you clone and switch to a tagged release, the build should work 23 | as intended. If you are working with the latest HEAD of `edk2-cix`, you may 24 | encounter build issues, and will need to update your submodules to the latest 25 | development HEAD for it to work. 26 | 27 | The current development branch of the submodules is their default branch. You 28 | can also run `git submodule update --remote` as a quick oneliner to update 29 | submodules. 30 | -------------------------------------------------------------------------------- /docs/debug.md: -------------------------------------------------------------------------------- 1 | # Debug 2 | 3 | ## Serial connection 4 | 5 | The following UARTs can be used to debug EDK2 on Radxa Orion O6: 6 | 7 | * UART1: EC 8 | * UART2: AP 9 | * UART3: Debug 10 | * UART4: PM 11 | * UART5: SE 12 | 13 | UART2 is the default management console for EDK2 and the operationg system. 14 | 15 | UART3 is only available when EDK2 is build as DEBUG image. 16 | 17 | All UARTs use 115200 baud. 18 | 19 | ````admonish info 20 | 21 | If you use version 1.0.0-1 or earlier, EC UART can be viewed with the following command: 22 | 23 | ```bash 24 | picocom -b 460800 --imap lfcrlf /dev/ttyX 25 | ``` 26 | 27 | ```` 28 | 29 | In general, the log output order after power is connected is as follow: 30 | 31 | ``` 32 | EC ---Power On---> SE ---> AP ---> Debug 33 | ``` 34 | 35 | If you enable `devenv`, then you can run `edk2-console` to launch above 4 UART consoles at once. 36 | Please first create a local `devenv.local.nix` based on `devenv.local.nix.example` to define the local UART devices before using this command. 37 | 38 | ## Installation 39 | 40 | Once build completes, you can find the complete set of artifacts under `debian/edk2-cix/usr/share/edk2/`. 41 | 42 | Follow [Installation guide](install.md#create-the-bios-update-disk) to continue. 43 | 44 | If you enable `devenv`, then you can run `edk2-install ` from the project root as a faster method to copy those files to a prepared USB disk. 45 | -------------------------------------------------------------------------------- /debian/edk2-cix.postinst: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | set -e 3 | 4 | case $1 in 5 | configure) 6 | rm -rf /boot/efi/edk2 /boot/efi/loader/entries/edk2-* 7 | 8 | cp -r /usr/share/edk2 /boot/efi/edk2 9 | for i in /boot/efi/edk2/radxa/*/Shell.efi; do 10 | cp "$i" /boot/efi/edk2/radxa/Shell.efi 11 | break 12 | done 13 | if [ ! -f /boot/efi/edk2/radxa/Shell.efi ]; then 14 | echo "Failed to find suitable Shell.efi." >&2 15 | exit 1 16 | fi 17 | 18 | version="$(dpkg -s "$DPKG_MAINTSCRIPT_PACKAGE" | sed -n 's/^Version: //p')" 19 | 20 | cat << EOF > /boot/efi/loader/entries/edk2-shell.conf 21 | title Update BIOS to $version 22 | version $version 23 | efi /edk2/radxa/Shell.efi 24 | architecture aa64 25 | EOF 26 | 27 | for i in /boot/efi/edk2/radxa/*; do 28 | if [ ! -d "$i" ]; then 29 | continue 30 | fi 31 | product=$(basename "$i") 32 | sed -i "s/set product ./set product \" for $product.\"/" "$i/startup.nsh" 33 | cat << EOF > /boot/efi/loader/entries/edk2-$product.conf.disabled 34 | title Install EDK2 $version for $product 35 | version $version 36 | efi /edk2/radxa/$product/Shell.efi 37 | architecture aa64 38 | EOF 39 | done 40 | ;; 41 | esac 42 | 43 | #DEBHELPER# 44 | 45 | exit 0 46 | -------------------------------------------------------------------------------- /debian/copyright: -------------------------------------------------------------------------------- 1 | Format: https://www.debian.org/doc/packaging-manuals/copyright-format/1.0/ 2 | Upstream-Name: edk2-cix 3 | Source: https://github.com/radxa-pkg/edk2-cix 4 | 5 | Files: [git submodules] 6 | License: External Code 7 | 8 | Files: debian/patches/**/*.patch 9 | License: External Code Patch 10 | 11 | Files: * 12 | Copyright: © 2025 Radxa Computer Co., Ltd 13 | License: GPL-3+ 14 | 15 | License: External Code 16 | Unless otherwise specified, they are subject to the relevant License within 17 | the submodule repo. 18 | 19 | License: External Code Patch 20 | Unless otherwise specified, they share the same license to the code being 21 | patched. 22 | 23 | License: GPL-3+ 24 | This program is free software; you can redistribute it and/or modify 25 | it under the terms of the GNU General Public License as published by 26 | the Free Software Foundation; either version 3, or (at your option) 27 | any later version. 28 | . 29 | This program is distributed in the hope that it will be useful, but 30 | WITHOUT ANY WARRANTY; without even the implied warranty of 31 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 32 | General Public License for more details. 33 | . 34 | You should have received a copy of the GNU General Public License 35 | along with this program. If not, see . 36 | . 37 | On Debian systems, the complete text of the GNU General Public License 38 | can be found in /usr/share/common-licenses/GPL-3. 39 | -------------------------------------------------------------------------------- /theme/highlight.css: -------------------------------------------------------------------------------- 1 | /* 2 | * An increased contrast highlighting scheme loosely based on the 3 | * "Base16 Atelier Dune Light" theme by Bram de Haan 4 | * (http://atelierbram.github.io/syntax-highlighting/atelier-schemes/dune) 5 | * Original Base16 color scheme by Chris Kempson 6 | * (https://github.com/chriskempson/base16) 7 | */ 8 | 9 | /* Comment */ 10 | .hljs-comment, 11 | .hljs-quote { 12 | color: #575757; 13 | } 14 | 15 | /* Red */ 16 | .hljs-variable, 17 | .hljs-template-variable, 18 | .hljs-attribute, 19 | .hljs-tag, 20 | .hljs-name, 21 | .hljs-regexp, 22 | .hljs-link, 23 | .hljs-name, 24 | .hljs-selector-id, 25 | .hljs-selector-class { 26 | color: #d70025; 27 | } 28 | 29 | /* Orange */ 30 | .hljs-number, 31 | .hljs-meta, 32 | .hljs-built_in, 33 | .hljs-builtin-name, 34 | .hljs-literal, 35 | .hljs-type, 36 | .hljs-params { 37 | color: #b21e00; 38 | } 39 | 40 | /* Green */ 41 | .hljs-string, 42 | .hljs-symbol, 43 | .hljs-bullet { 44 | color: #008200; 45 | } 46 | 47 | /* Blue */ 48 | .hljs-title, 49 | .hljs-section { 50 | color: #0030f2; 51 | } 52 | 53 | /* Purple */ 54 | .hljs-keyword, 55 | .hljs-selector-tag { 56 | color: #9d00ec; 57 | } 58 | 59 | .hljs { 60 | display: block; 61 | overflow-x: auto; 62 | background: #f6f7f6; 63 | color: #000; 64 | } 65 | 66 | .hljs-emphasis { 67 | font-style: italic; 68 | } 69 | 70 | .hljs-strong { 71 | font-weight: bold; 72 | } 73 | 74 | .hljs-addition { 75 | color: #22863a; 76 | background-color: #f0fff4; 77 | } 78 | 79 | .hljs-deletion { 80 | color: #b31d28; 81 | background-color: #ffeef0; 82 | } 83 | -------------------------------------------------------------------------------- /docs/update.md: -------------------------------------------------------------------------------- 1 | # Update BIOS from RadxaOS 2 | 3 | Since 0.3.0-1, `edk2-cix` now integrates with RadxaOS to provide an easy to use 4 | BIOS update entry. This makes updating BIOS easier to operate, while also allow 5 | a given image to ship its own matching BIOS. 6 | 7 | ## How to start BIOS update? 8 | 9 | Restart the system, and choose `Install EDK2` option for your product. 10 | 11 | Below is the complete process of upgrading BIOS from 0.2.2-1 to 0.3.0-1: 12 | 13 | [![asciicast](https://asciinema.org/a/9uKAUpFuZu2ggUhOXaw4Rf2S2.svg)](https://asciinema.org/a/9uKAUpFuZu2ggUhOXaw4Rf2S2) 14 | 15 | ## Install a different version of BIOS 16 | 17 | Like other system components in RadxaOS, `edk2-cix` are regularly released and 18 | published in Radxa maintained apt archives. Users can use `rsetup` to perform 19 | system update to acquire the latest version of `edk2-cix`. 20 | 21 | Installing a new version of `edk2-cix` package will update the bootloader entry 22 | to that specific version. User still needs to explicitly launch it during boot 23 | up to actually have BIOS updated. 24 | 25 | If user wants to install a different version of BIOS, they can simply install 26 | the `edk2-cix` package of that version, and perform installation after reboot. 27 | 28 | In some cases, the system will be unbootable due to mismatched kernel and BIOS. 29 | This can happen after a system update. The user can either use the bootloader 30 | menu to select an previously installed kernel, or update the matching BIOS for 31 | the latest kernel. 32 | 33 | In rare cases, when neither of the above methods are available, user can try to 34 | [manually install the BIOS](./install.md). 35 | -------------------------------------------------------------------------------- /.devcontainer/devcontainer.json: -------------------------------------------------------------------------------- 1 | { 2 | "customizations": { 3 | "vscode": { 4 | "settings": { 5 | "terminal.integrated.defaultProfile.linux": "bash" 6 | }, 7 | "extensions": [ 8 | "mkhl.direnv", 9 | "github.vscode-github-actions", 10 | "grafana.vscode-jsonnet", 11 | "ms-vscode.cpptools-extension-pack", 12 | "ms-vscode.makefile-tools", 13 | "vivaxy.vscode-conventional-commits" 14 | ] 15 | } 16 | }, 17 | "image": "mcr.microsoft.com/devcontainers/base:bookworm", 18 | "features": { 19 | "ghcr.io/devcontainers/features/nix:1": { 20 | "version": "latest", 21 | "packages": "cachix,direnv,devenv", 22 | "useAttributePath": true, 23 | "extraNixConfig": [ 24 | "experimental-features = nix-command flakes", 25 | // Uncomment below to speed up container building in China 26 | // "substituters = https://mirrors.ustc.edu.cn/nix-channels/store https://devenv.cachix.org https://cache.nixos.org", 27 | "trusted-users = root vscode" 28 | ] 29 | } 30 | }, 31 | "mounts": [ 32 | { 33 | "source": "${localWorkspaceFolder}/.devcontainer/.devenv", 34 | "target": "${containerWorkspaceFolder}/.devenv", 35 | "type": "bind" 36 | }, 37 | { 38 | "source": "${localWorkspaceFolder}/.devcontainer/.direnv", 39 | "target": "${containerWorkspaceFolder}/.direnv", 40 | "type": "bind" 41 | } 42 | ], 43 | "workspaceMount": "source=${localWorkspaceFolder}/..,target=/workspaces,type=bind,consistency=cached", 44 | "runArgs": [ 45 | // https://github.com/moby/moby/issues/27195#issuecomment-1410745778 46 | "--ulimit", "nofile=1024:524288" 47 | ], 48 | "overrideCommand": true, 49 | "updateContentCommand": "make devcontainer_setup" 50 | } 51 | -------------------------------------------------------------------------------- /src/scripts/startup.nsh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env -S echo "This script is for UEFI Shell only:" 2 | 3 | @echo -off 4 | 5 | set product . 6 | 7 | echo "************************************************************************" 8 | echo " Radxa BIOS Update Utility" 9 | echo "************************************************************************" 10 | echo " " 11 | echo "You are about to update the BIOS%product%" 12 | echo "Please make sure the power stays on during the operation." 13 | echo " " 14 | echo "We strongly recommend to perform this operation locally, as the updated" 15 | echo "system should be power cycled to ensure new code to be loaded." 16 | echo "If you are performing this operation remotely, please make sure you have" 17 | echo "means to also power cycle the system in case of issue." 18 | echo " " 19 | echo "If you decide to cancel BIOS update, you can run following commands:" 20 | echo " reset to reboot the system" 21 | echo " reset -s to shutdown the system" 22 | echo " " 23 | pause 24 | 25 | echo "************************************************************************" 26 | echo " Updating BIOS..." 27 | echo "************************************************************************" 28 | echo " " 29 | 30 | "%0\..\FlashUpdate.efi" -f "%0\..\cix_flash_all.bin" -n 31 | 32 | echo " " 33 | echo "************************************************************************" 34 | echo " BIOS Update completed!" 35 | echo "************************************************************************" 36 | echo "System will now power off." 37 | echo "You MUST fully remove all connected power source before connecting them." 38 | echo "Failure to do so may prevent some components to use the updated code." 39 | echo " " 40 | pause 41 | 42 | reset -s "BIOS Update" 43 | 44 | :EOF 45 | -------------------------------------------------------------------------------- /theme/favicon.svg: -------------------------------------------------------------------------------- 1 | 2 | 7 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /.github/workflows/new_version.yaml: -------------------------------------------------------------------------------- 1 | jobs: 2 | release: 3 | permissions: 4 | contents: "write" 5 | runs-on: "ubuntu-latest" 6 | steps: 7 | - name: "Checkout" 8 | uses: "actions/checkout@v6" 9 | with: 10 | fetch-depth: 0 11 | submodules: "recursive" 12 | token: "${{secrets.GIT_PUSH_TOKEN}}" 13 | - if: "github.event.inputs.update == 'true'" 14 | name: "Update submodules" 15 | run: | 16 | git config user.name "github-actions[bot]" 17 | git config user.email "41898282+github-actions[bot]@users.noreply.github.com" 18 | git submodule update --remote 19 | if git diff --quiet; then 20 | echo "Submodules are the latest. Nothing to update." 21 | exit 22 | fi 23 | git add . 24 | git commit -m "chore: update submodules" 25 | shell: "bash" 26 | - name: "Set up QEMU Emulation" 27 | uses: "docker/setup-qemu-action@v3" 28 | with: 29 | image: "tonistiigi/binfmt:latest" 30 | - name: "Test" 31 | uses: "devcontainers/ci@v0.3" 32 | with: 33 | push: "never" 34 | runCmd: | 35 | set -euo pipefail 36 | sudo apt-get update 37 | sudo apt-get install --no-install-recommends -y git-buildpackage 38 | export DEBEMAIL="dev@radxa.com" 39 | export DEBFULLNAME='"Radxa Computer Co., Ltd"' 40 | git config user.name "github-actions[bot]" 41 | git config user.email "41898282+github-actions[bot]@users.noreply.github.com" 42 | make dch 43 | make test deb 44 | - if: "github.event.inputs.release == 'true'" 45 | name: "Push" 46 | run: | 47 | git push 48 | shell: "bash" 49 | name: "Create release" 50 | "on": 51 | workflow_dispatch: 52 | inputs: 53 | release: 54 | default: true 55 | description: "Release new version" 56 | required: true 57 | type: "boolean" 58 | update: 59 | default: false 60 | description: "Update submodule" 61 | required: true 62 | type: "boolean" 63 | permissions: {} 64 | run-name: "${{ inputs.update && 'Update submodule' || '' }}${{ inputs.update && inputs.release && ' & ' || '' }}${{ inputs.release && 'Release new version' }}${{ !inputs.update && !inputs.release && 'Test for new release' || '' }}" -------------------------------------------------------------------------------- /.github/workflows/docs.yaml: -------------------------------------------------------------------------------- 1 | concurrency: 2 | cancel-in-progress: true 3 | group: "${{ github.workflow }}-${{ github.ref }}" 4 | jobs: 5 | build-doc: 6 | permissions: 7 | id-token: "write" 8 | pages: "write" 9 | runs-on: "ubuntu-latest" 10 | steps: 11 | - name: "Checkout" 12 | uses: "actions/checkout@v6" 13 | with: 14 | fetch-depth: 0 15 | - name: "Install Nix" 16 | uses: "cachix/install-nix-action@v31" 17 | - name: "Use cachix" 18 | uses: "cachix/cachix-action@v16" 19 | with: 20 | name: "devenv" 21 | - name: "Install devenv.sh" 22 | run: "nix profile install nixpkgs#devenv" 23 | - name: "Build" 24 | run: | 25 | devenv shell mdbook build 26 | for po_lang in zh-CN 27 | do 28 | POT_CREATION_DATE=$(grep --max-count 1 '^"POT-Creation-Date:' po/$po_lang.po | sed -E 's/".*: (.*)\\n"/\1/') 29 | if [[ $POT_CREATION_DATE == "" ]]; then 30 | POT_CREATION_DATE=now 31 | fi 32 | echo "::group::Building $po_lang translation as of $POT_CREATION_DATE" 33 | rm -r docs/ 34 | git restore --source "$(git rev-list -n 1 --before "$POT_CREATION_DATE" @)" docs/ 35 | # Set language and adjust site URL. Clear the redirects 36 | # since they are in sync with the source files, not the 37 | # translation. 38 | MDBOOK_BOOK__LANGUAGE=$po_lang \ 39 | MDBOOK_OUTPUT__HTML__SITE_URL=/edk2-cix/$po_lang/ \ 40 | MDBOOK_OUTPUT__HTML__REDIRECT='{}' \ 41 | devenv shell mdbook build -d book/$po_lang 42 | mv book/$po_lang/html book/html/$po_lang 43 | echo "::endgroup::" 44 | done 45 | shell: "bash" 46 | - name: "Setup Pages" 47 | uses: "actions/configure-pages@v5" 48 | - name: "Upload artifact" 49 | uses: "actions/upload-pages-artifact@v4" 50 | with: 51 | path: "./book/html" 52 | - if: "github.event_name != 'pull_request'" 53 | name: "Deploy to GitHub Pages" 54 | uses: "actions/deploy-pages@v4" 55 | name: "Deploy documentation" 56 | "on": 57 | merge_group: {} 58 | pull_request: 59 | paths: 60 | - "docs/**" 61 | - "theme/**" 62 | - "po/**" 63 | - "book.toml" 64 | - ".github/workflows/docs.yaml" 65 | push: 66 | branches: 67 | - "main" 68 | paths: 69 | - "docs/**" 70 | - "theme/**" 71 | - "po/**" 72 | - "book.toml" 73 | - ".github/workflows/docs.yaml" 74 | workflow_dispatch: {} 75 | permissions: {} -------------------------------------------------------------------------------- /devenv.lock: -------------------------------------------------------------------------------- 1 | { 2 | "nodes": { 3 | "devenv": { 4 | "locked": { 5 | "dir": "src/modules", 6 | "lastModified": 1759939975, 7 | "owner": "cachix", 8 | "repo": "devenv", 9 | "rev": "6eda3b7af3010d289e6e8e047435956fc80c1395", 10 | "type": "github" 11 | }, 12 | "original": { 13 | "dir": "src/modules", 14 | "owner": "cachix", 15 | "repo": "devenv", 16 | "type": "github" 17 | } 18 | }, 19 | "flake-compat": { 20 | "flake": false, 21 | "locked": { 22 | "lastModified": 1747046372, 23 | "owner": "edolstra", 24 | "repo": "flake-compat", 25 | "rev": "9100a0f413b0c601e0533d1d94ffd501ce2e7885", 26 | "type": "github" 27 | }, 28 | "original": { 29 | "owner": "edolstra", 30 | "repo": "flake-compat", 31 | "type": "github" 32 | } 33 | }, 34 | "git-hooks": { 35 | "inputs": { 36 | "flake-compat": "flake-compat", 37 | "gitignore": "gitignore", 38 | "nixpkgs": [ 39 | "nixpkgs" 40 | ] 41 | }, 42 | "locked": { 43 | "lastModified": 1759523803, 44 | "owner": "cachix", 45 | "repo": "git-hooks.nix", 46 | "rev": "cfc9f7bb163ad8542029d303e599c0f7eee09835", 47 | "type": "github" 48 | }, 49 | "original": { 50 | "owner": "cachix", 51 | "repo": "git-hooks.nix", 52 | "type": "github" 53 | } 54 | }, 55 | "gitignore": { 56 | "inputs": { 57 | "nixpkgs": [ 58 | "git-hooks", 59 | "nixpkgs" 60 | ] 61 | }, 62 | "locked": { 63 | "lastModified": 1709087332, 64 | "owner": "hercules-ci", 65 | "repo": "gitignore.nix", 66 | "rev": "637db329424fd7e46cf4185293b9cc8c88c95394", 67 | "type": "github" 68 | }, 69 | "original": { 70 | "owner": "hercules-ci", 71 | "repo": "gitignore.nix", 72 | "type": "github" 73 | } 74 | }, 75 | "nixpkgs": { 76 | "locked": { 77 | "lastModified": 1759977445, 78 | "owner": "NixOS", 79 | "repo": "nixpkgs", 80 | "rev": "2dad7af78a183b6c486702c18af8a9544f298377", 81 | "type": "github" 82 | }, 83 | "original": { 84 | "owner": "NixOS", 85 | "ref": "nixpkgs-unstable", 86 | "repo": "nixpkgs", 87 | "type": "github" 88 | } 89 | }, 90 | "root": { 91 | "inputs": { 92 | "devenv": "devenv", 93 | "git-hooks": "git-hooks", 94 | "nixpkgs": "nixpkgs", 95 | "pre-commit-hooks": [ 96 | "git-hooks" 97 | ] 98 | } 99 | } 100 | }, 101 | "root": "root", 102 | "version": 7 103 | } 104 | -------------------------------------------------------------------------------- /.github/common/Makefile: -------------------------------------------------------------------------------- 1 | # This file is auto generated by rsdk infra-package-update. 2 | # DO NOT EDIT IT DIRECTLY! 3 | # Custom rules should be placed in .github/local/Makefile.local 4 | 5 | -include .github/local/Makefile.local 6 | -include Makefile.extra 7 | 8 | PROJECT ?= edk2-cix 9 | CUSTOM_DEBUILD_ENV ?= DEB_BUILD_OPTIONS='parallel=1' 10 | CUSTOM_DEBUILD_ARG ?= 11 | 12 | .DEFAULT_GOAL := all 13 | .PHONY: all 14 | all: build 15 | 16 | .PHONY: devcontainer_setup 17 | devcontainer_setup: pre_build_dep main_build_dep post_build_dep 18 | 19 | .PHONY: pre_build_dep 20 | pre_build_dep: 21 | 22 | .PHONY: main_build_dep 23 | main_build_dep: 24 | sudo dpkg --add-architecture arm64 25 | sudo apt-get update 26 | sudo apt-get install -y crossbuild-essential-arm64 binfmt-support qemu-user-static 27 | sudo apt-get build-dep . -y 28 | 29 | .PHONY: post_build_dep 30 | post_build_dep: 31 | 32 | .PHONY: arm64_crossbuild_dep 33 | arm64_crossbuild_dep: 34 | sudo apt-get build-dep . -y --host-architecture arm64 35 | 36 | # 37 | # Test 38 | # 39 | .PHONY: test 40 | test: 41 | 42 | # 43 | # Build 44 | # 45 | .PHONY: build 46 | build: pre_build main_build post_build 47 | 48 | .PHONY: pre_build 49 | pre_build: 50 | # Fix file permissions when created from template 51 | chmod +x debian/rules 52 | 53 | .PHONY: main_build 54 | main_build: 55 | 56 | .PHONY: post_build 57 | post_build: 58 | 59 | # 60 | # Documentation 61 | # 62 | .PHONY: serve 63 | serve: 64 | mdbook serve 65 | 66 | .PHONY: serve_zh-CN 67 | serve_zh-CN: 68 | MDBOOK_BOOK__LANGUAGE=zh-CN mdbook serve -d book/zh-CN 69 | 70 | PO_LOCALE := zh-CN 71 | .PHONY: translate 72 | translate: 73 | MDBOOK_OUTPUT='{"xgettext": {"pot-file": "messages.pot"}}' mdbook build -d po 74 | cd po; \ 75 | for i in $(PO_LOCALE); \ 76 | do \ 77 | if [ ! -f $$i.po ]; \ 78 | then \ 79 | msginit -l $$i --no-translator; \ 80 | else \ 81 | msgmerge --update $$i.po messages.pot; \ 82 | fi \ 83 | done 84 | 85 | # 86 | # Clean 87 | # 88 | .PHONY: distclean 89 | distclean: clean 90 | 91 | .PHONY: clean 92 | clean: clean-deb 93 | 94 | .PHONY: clean-deb 95 | clean-deb: 96 | rm -rf debian/.debhelper debian/$(PROJECT)*/ debian/tmp/ debian/debhelper-build-stamp debian/files debian/*.debhelper.log debian/*.*.debhelper debian/*.substvars 97 | 98 | # 99 | # Release 100 | # 101 | .PHONY: dch 102 | dch: debian/changelog 103 | gbp dch --ignore-branch --multimaint-merge --release --spawn-editor=never \ 104 | --git-log='--no-merges --perl-regexp --invert-grep --grep=^(chore:\stemplates\sgenerated)' \ 105 | --dch-opt=--upstream --commit --commit-msg="feat: release %(version)s" 106 | 107 | .PHONY: deb 108 | deb: debian pre_debuild debuild post_debuild 109 | 110 | .PHONY: pre_debuild 111 | pre_debuild: 112 | 113 | .PHONY: debuild 114 | debuild: 115 | $(CUSTOM_DEBUILD_ENV) debuild --no-lintian --lintian-hook "lintian --fail-on error,warning --suppress-tags-from-file $(PWD)/debian/common-lintian-overrides -- %p_%v_*.changes" --no-sign -b $(CUSTOM_DEBUILD_ARG) 116 | 117 | .PHONY: post_debuild 118 | post_debuild: 119 | 120 | .PHONY: release 121 | release: 122 | gh workflow run .github/workflows/new_version.yaml --ref $(shell git branch --show-current) 123 | 124 | # This file is auto generated by rsdk infra-package-update. 125 | # DO NOT EDIT IT DIRECTLY! 126 | # Custom rules should be placed in .github/local/Makefile.local 127 | -------------------------------------------------------------------------------- /theme/fonts/fonts.css: -------------------------------------------------------------------------------- 1 | /* Open Sans is licensed under the Apache License, Version 2.0. See http://www.apache.org/licenses/LICENSE-2.0 */ 2 | /* Source Code Pro is under the Open Font License. See https://scripts.sil.org/cms/scripts/page.php?site_id=nrsi&id=OFL */ 3 | 4 | /* open-sans-300 - latin_vietnamese_latin-ext_greek-ext_greek_cyrillic-ext_cyrillic */ 5 | @font-face { 6 | font-family: "Open Sans"; 7 | font-style: normal; 8 | font-weight: 300; 9 | src: 10 | local("Open Sans Light"), 11 | local("OpenSans-Light"), 12 | url("open-sans-v17-all-charsets-300.woff2") format("woff2"); 13 | } 14 | 15 | /* open-sans-300italic - latin_vietnamese_latin-ext_greek-ext_greek_cyrillic-ext_cyrillic */ 16 | @font-face { 17 | font-family: "Open Sans"; 18 | font-style: italic; 19 | font-weight: 300; 20 | src: 21 | local("Open Sans Light Italic"), 22 | local("OpenSans-LightItalic"), 23 | url("open-sans-v17-all-charsets-300italic.woff2") format("woff2"); 24 | } 25 | 26 | /* open-sans-regular - latin_vietnamese_latin-ext_greek-ext_greek_cyrillic-ext_cyrillic */ 27 | @font-face { 28 | font-family: "Open Sans"; 29 | font-style: normal; 30 | font-weight: 400; 31 | src: 32 | local("Open Sans Regular"), 33 | local("OpenSans-Regular"), 34 | url("open-sans-v17-all-charsets-regular.woff2") format("woff2"); 35 | } 36 | 37 | /* open-sans-italic - latin_vietnamese_latin-ext_greek-ext_greek_cyrillic-ext_cyrillic */ 38 | @font-face { 39 | font-family: "Open Sans"; 40 | font-style: italic; 41 | font-weight: 400; 42 | src: 43 | local("Open Sans Italic"), 44 | local("OpenSans-Italic"), 45 | url("open-sans-v17-all-charsets-italic.woff2") format("woff2"); 46 | } 47 | 48 | /* open-sans-600 - latin_vietnamese_latin-ext_greek-ext_greek_cyrillic-ext_cyrillic */ 49 | @font-face { 50 | font-family: "Open Sans"; 51 | font-style: normal; 52 | font-weight: 600; 53 | src: 54 | local("Open Sans SemiBold"), 55 | local("OpenSans-SemiBold"), 56 | url("open-sans-v17-all-charsets-600.woff2") format("woff2"); 57 | } 58 | 59 | /* open-sans-600italic - latin_vietnamese_latin-ext_greek-ext_greek_cyrillic-ext_cyrillic */ 60 | @font-face { 61 | font-family: "Open Sans"; 62 | font-style: italic; 63 | font-weight: 600; 64 | src: 65 | local("Open Sans SemiBold Italic"), 66 | local("OpenSans-SemiBoldItalic"), 67 | url("open-sans-v17-all-charsets-600italic.woff2") format("woff2"); 68 | } 69 | 70 | /* open-sans-700 - latin_vietnamese_latin-ext_greek-ext_greek_cyrillic-ext_cyrillic */ 71 | @font-face { 72 | font-family: "Open Sans"; 73 | font-style: normal; 74 | font-weight: 700; 75 | src: 76 | local("Open Sans Bold"), 77 | local("OpenSans-Bold"), 78 | url("open-sans-v17-all-charsets-700.woff2") format("woff2"); 79 | } 80 | 81 | /* open-sans-700italic - latin_vietnamese_latin-ext_greek-ext_greek_cyrillic-ext_cyrillic */ 82 | @font-face { 83 | font-family: "Open Sans"; 84 | font-style: italic; 85 | font-weight: 700; 86 | src: 87 | local("Open Sans Bold Italic"), 88 | local("OpenSans-BoldItalic"), 89 | url("open-sans-v17-all-charsets-700italic.woff2") format("woff2"); 90 | } 91 | 92 | /* open-sans-800 - latin_vietnamese_latin-ext_greek-ext_greek_cyrillic-ext_cyrillic */ 93 | @font-face { 94 | font-family: "Open Sans"; 95 | font-style: normal; 96 | font-weight: 800; 97 | src: 98 | local("Open Sans ExtraBold"), 99 | local("OpenSans-ExtraBold"), 100 | url("open-sans-v17-all-charsets-800.woff2") format("woff2"); 101 | } 102 | 103 | /* open-sans-800italic - latin_vietnamese_latin-ext_greek-ext_greek_cyrillic-ext_cyrillic */ 104 | @font-face { 105 | font-family: "Open Sans"; 106 | font-style: italic; 107 | font-weight: 800; 108 | src: 109 | local("Open Sans ExtraBold Italic"), 110 | local("OpenSans-ExtraBoldItalic"), 111 | url("open-sans-v17-all-charsets-800italic.woff2") format("woff2"); 112 | } 113 | 114 | /* source-code-pro-500 - latin_vietnamese_latin-ext_greek_cyrillic-ext_cyrillic */ 115 | @font-face { 116 | font-family: "Source Code Pro"; 117 | font-style: normal; 118 | font-weight: 500; 119 | src: url("source-code-pro-v11-all-charsets-500.woff2") format("woff2"); 120 | } 121 | -------------------------------------------------------------------------------- /.github/local/devenv.nix: -------------------------------------------------------------------------------- 1 | { pkgs, lib, config, ... }: 2 | 3 | { 4 | scripts = { 5 | edk2-console = { 6 | description = "Launch UART workspace"; 7 | exec = '' 8 | ${lib.getExe pkgs.tmux} kill-session -t edk2-console 9 | sleep 1 # wait for picocom to be closed to release UART resources 10 | ${lib.getExe pkgs.tmux} new-session -d -s edk2-console "${lib.getExe pkgs.picocom} -b 115200 /dev/$EDK2_SE_UART | ${lib.getExe' pkgs.coreutils "tee"} logs/se.log" 11 | ${lib.getExe pkgs.tmux} set-option mouse on 12 | ${lib.getExe pkgs.tmux} split-window -h "${lib.getExe pkgs.picocom} -b 115200 /dev/$EDK2_EC_UART | ${lib.getExe' pkgs.coreutils "tee"} logs/ec.log" 13 | ${lib.getExe pkgs.tmux} split-window -v "${lib.getExe pkgs.picocom} -b 115200 /dev/$EDK2_DEBUG_UART | ${lib.getExe' pkgs.coreutils "tee"} logs/debug.log" 14 | ${lib.getExe pkgs.tmux} split-window -v -t 0 "${lib.getExe pkgs.picocom} -b 115200 /dev/$EDK2_AP_UART | ${lib.getExe' pkgs.coreutils "tee"} logs/ap.log" 15 | ${lib.getExe pkgs.tmux} attach-session -t edk2-console 16 | ''; 17 | }; 18 | edk2-install = { 19 | description = "Copy build artifacts to a thumb disk, require udisk2"; 20 | exec = '' 21 | set -euo pipefail 22 | 23 | if (($# == 0)); then 24 | ${lib.getExe' pkgs.coreutils "echo"} "Usage: $(${lib.getExe' pkgs.coreutils "basename"} "$0") " >&2 25 | exit 1 26 | elif [[ ! -b "$1" ]]; then 27 | ${lib.getExe' pkgs.coreutils "echo"} "Waiting for $1 to be available ..." 28 | fi 29 | 30 | while [[ ! -b "$1" ]]; do 31 | ${lib.getExe' pkgs.coreutils "sleep"} 1 32 | done 33 | 34 | if [[ ! -e debian/edk2-cix/usr/share/edk2/ ]]; then 35 | ${lib.getExe' pkgs.coreutils "echo"} "No EDK2 artifact available!" >&2 36 | ${lib.getExe' pkgs.coreutils "echo"} "Have you ran edk2-build?" >&2 37 | exit 2 38 | fi 39 | 40 | ${lib.getExe' pkgs.udisks "udisksctl"} mount -b "$1" || ${lib.getExe' pkgs.coreutils "true"} 41 | MOUNT_POINT="$(${lib.getExe' pkgs.udisks "udisksctl"} info -b "$1" | \ 42 | ${lib.getExe pkgs.gnugrep} MountPoints | \ 43 | ${lib.getExe pkgs.gnused} -E "s/\s*MountPoints:\s*(.*)/\1/")" 44 | 45 | file_count() { 46 | local f=("$1"/*) 47 | ${lib.getExe' pkgs.coreutils "echo"} ''${#f[@]} 48 | } 49 | 50 | if (( $(file_count debian/edk2-cix/usr/share/edk2/) != 1 )); then 51 | ${lib.getExe' pkgs.coreutils "echo"} "Copying" debian/edk2-cix/usr/share/edk2/ "..." 52 | ${lib.getExe' pkgs.coreutils "cp"} -a debian/edk2-cix/usr/share/edk2/. "$MOUNT_POINT" 53 | elif (( $(file_count debian/edk2-cix/usr/share/edk2/*) != 1 )); then 54 | ${lib.getExe' pkgs.coreutils "echo"} "Copying" debian/edk2-cix/usr/share/edk2/*/ "..." 55 | ${lib.getExe' pkgs.coreutils "cp"} -a debian/edk2-cix/usr/share/edk2/*/. "$MOUNT_POINT" 56 | else 57 | ${lib.getExe' pkgs.coreutils "echo"} "Copying" debian/edk2-cix/usr/share/edk2/*/*/ "..." 58 | ${lib.getExe' pkgs.coreutils "cp"} -a debian/edk2-cix/usr/share/edk2/*/*/. "$MOUNT_POINT" 59 | fi 60 | 61 | ${lib.getExe' pkgs.coreutils "sync"} -f "$MOUNT_POINT" 62 | 63 | ${lib.getExe' pkgs.udisks "udisksctl"} unmount -f -b "$1" 64 | 65 | ${lib.getExe' pkgs.coreutils "echo"} "EDK2 artifacts has been copied to $1." 66 | ${lib.getExe' pkgs.coreutils "echo"} "Please run startup.nsh from UEFI Shell, listed under Boot Manager menu, to install new EDK2 binary." 67 | ''; 68 | }; 69 | cix-push = { 70 | description = "Create PR for a given CIX branch"; 71 | exec = '' 72 | set -euo pipefail 73 | ${lib.getExe pkgs.git} push "''${1%%/*}" "HEAD:refs/for/''${1#*/}%r=UEFI" 74 | ''; 75 | }; 76 | install-gerrit = { 77 | description = "Install Gerrit commig-msg hook"; 78 | exec = '' 79 | set -euo pipefail 80 | GIT_DIR="../../.git/modules/src/$(basename $PWD)" 81 | [[ -d "$GIT_DIR" ]] 82 | mkdir -p "$GIT_DIR/hooks" 83 | ${lib.getExe pkgs.curl} -Lo "$GIT_DIR/hooks/commit-msg" https://git.cixtech.com/tools/hooks/commit-msg 84 | chmod +x "$GIT_DIR/hooks/commit-msg" 85 | ''; 86 | }; 87 | }; 88 | } 89 | -------------------------------------------------------------------------------- /theme/fonts/SOURCE-CODE-PRO-LICENSE.txt: -------------------------------------------------------------------------------- 1 | Copyright 2010, 2012 Adobe Systems Incorporated (http://www.adobe.com/), with Reserved Font Name 'Source'. All Rights Reserved. Source is a trademark of Adobe Systems Incorporated in the United States and/or other countries. 2 | 3 | This Font Software is licensed under the SIL Open Font License, Version 1.1. 4 | This license is copied below, and is also available with a FAQ at: 5 | http://scripts.sil.org/OFL 6 | 7 | 8 | ----------------------------------------------------------- 9 | SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007 10 | ----------------------------------------------------------- 11 | 12 | PREAMBLE 13 | The goals of the Open Font License (OFL) are to stimulate worldwide 14 | development of collaborative font projects, to support the font creation 15 | efforts of academic and linguistic communities, and to provide a free and 16 | open framework in which fonts may be shared and improved in partnership 17 | with others. 18 | 19 | The OFL allows the licensed fonts to be used, studied, modified and 20 | redistributed freely as long as they are not sold by themselves. The 21 | fonts, including any derivative works, can be bundled, embedded, 22 | redistributed and/or sold with any software provided that any reserved 23 | names are not used by derivative works. The fonts and derivatives, 24 | however, cannot be released under any other type of license. The 25 | requirement for fonts to remain under this license does not apply 26 | to any document created using the fonts or their derivatives. 27 | 28 | DEFINITIONS 29 | "Font Software" refers to the set of files released by the Copyright 30 | Holder(s) under this license and clearly marked as such. This may 31 | include source files, build scripts and documentation. 32 | 33 | "Reserved Font Name" refers to any names specified as such after the 34 | copyright statement(s). 35 | 36 | "Original Version" refers to the collection of Font Software components as 37 | distributed by the Copyright Holder(s). 38 | 39 | "Modified Version" refers to any derivative made by adding to, deleting, 40 | or substituting -- in part or in whole -- any of the components of the 41 | Original Version, by changing formats or by porting the Font Software to a 42 | new environment. 43 | 44 | "Author" refers to any designer, engineer, programmer, technical 45 | writer or other person who contributed to the Font Software. 46 | 47 | PERMISSION & CONDITIONS 48 | Permission is hereby granted, free of charge, to any person obtaining 49 | a copy of the Font Software, to use, study, copy, merge, embed, modify, 50 | redistribute, and sell modified and unmodified copies of the Font 51 | Software, subject to the following conditions: 52 | 53 | 1) Neither the Font Software nor any of its individual components, 54 | in Original or Modified Versions, may be sold by itself. 55 | 56 | 2) Original or Modified Versions of the Font Software may be bundled, 57 | redistributed and/or sold with any software, provided that each copy 58 | contains the above copyright notice and this license. These can be 59 | included either as stand-alone text files, human-readable headers or 60 | in the appropriate machine-readable metadata fields within text or 61 | binary files as long as those fields can be easily viewed by the user. 62 | 63 | 3) No Modified Version of the Font Software may use the Reserved Font 64 | Name(s) unless explicit written permission is granted by the corresponding 65 | Copyright Holder. This restriction only applies to the primary font name as 66 | presented to the users. 67 | 68 | 4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font 69 | Software shall not be used to promote, endorse or advertise any 70 | Modified Version, except to acknowledge the contribution(s) of the 71 | Copyright Holder(s) and the Author(s) or with their explicit written 72 | permission. 73 | 74 | 5) The Font Software, modified or unmodified, in part or in whole, 75 | must be distributed entirely under this license, and must not be 76 | distributed under any other license. The requirement for fonts to 77 | remain under this license does not apply to any document created 78 | using the Font Software. 79 | 80 | TERMINATION 81 | This license becomes null and void if any of the above conditions are 82 | not met. 83 | 84 | DISCLAIMER 85 | THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 86 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF 87 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT 88 | OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE 89 | COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 90 | INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL 91 | DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 92 | FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM 93 | OTHER DEALINGS IN THE FONT SOFTWARE. 94 | -------------------------------------------------------------------------------- /.github/workflows/release.yaml: -------------------------------------------------------------------------------- 1 | jobs: 2 | build: 3 | outputs: 4 | distro: "${{ steps.distro_check.outputs.distro }}" 5 | runs-on: "ubuntu-latest" 6 | steps: 7 | - name: "Checkout" 8 | uses: "actions/checkout@v6" 9 | with: 10 | fetch-depth: 0 11 | fetch-tags: true 12 | submodules: "recursive" 13 | - name: "Set up QEMU Emulation" 14 | uses: "docker/setup-qemu-action@v3" 15 | with: 16 | image: "tonistiigi/binfmt:latest" 17 | - name: "Test" 18 | uses: "devcontainers/ci@v0.3" 19 | with: 20 | push: "never" 21 | runCmd: | 22 | set -euo pipefail 23 | sudo apt-get update 24 | sudo apt-get install --no-install-recommends -y git-buildpackage 25 | export DEBEMAIL="dev@radxa.com" 26 | export DEBFULLNAME='"Radxa Computer Co., Ltd"' 27 | git config user.name "github-actions[bot]" 28 | git config user.email "41898282+github-actions[bot]@users.noreply.github.com" 29 | git branch -m GITHUB_RUNNER || true 30 | git branch -D main || true 31 | git switch -c main || true 32 | make dch 33 | make test deb 34 | git reset --hard HEAD~1 35 | rm ../*.deb 36 | - name: "Build" 37 | uses: "devcontainers/ci@v0.3" 38 | with: 39 | push: "never" 40 | runCmd: | 41 | set -euo pipefail 42 | make deb 43 | - id: "artifacts_path" 44 | name: "Workaround actions/upload-artifact#176" 45 | run: | 46 | echo "artifacts_path=$(realpath ..)" | tee -a "$GITHUB_OUTPUT" 47 | shell: "bash" 48 | - name: "Upload artifacts" 49 | uses: "actions/upload-artifact@v6" 50 | with: 51 | name: "${{ github.event.repository.name }}" 52 | path: | 53 | ${{ steps.artifacts_path.outputs.artifacts_path }}/*.deb 54 | - id: "distro_check" 55 | name: "Check if the latest version is releasable" 56 | run: | 57 | version="$(dpkg-parsechangelog -S Version)" 58 | version="${version//\~/.}" 59 | if [[ -n "$(git tag -l "$version")" ]] 60 | then 61 | echo "distro=UNRELEASED" 62 | else 63 | echo "distro=$(dpkg-parsechangelog -S Distribution)" 64 | fi | tee -a "$GITHUB_OUTPUT" 65 | shell: "bash" 66 | release: 67 | if: "${{ github.event_name != 'pull_request' && needs.build.outputs.distro != 'UNRELEASED' }}" 68 | needs: "build" 69 | permissions: 70 | contents: "write" 71 | runs-on: "ubuntu-latest" 72 | steps: 73 | - name: "Checkout" 74 | uses: "actions/checkout@v6" 75 | - name: "Download generated debs" 76 | uses: "actions/download-artifact@v7" 77 | with: 78 | name: "${{ github.event.repository.name }}" 79 | path: ".artifacts" 80 | - name: "Prepare for release" 81 | run: | 82 | version="$(dpkg-parsechangelog -S Version)" 83 | version="${version//\~/.}" 84 | { 85 | echo "version=$version" 86 | echo "changes< Thu, 25 Dec 2025 02:36:01 +0000 7 | 8 | edk2-cix (1.0.0-8) main; urgency=medium 9 | 10 | [ github-actions[bot] ] 11 | * chore: update submodules 12 | 13 | -- "Radxa Computer Co., Ltd" Wed, 17 Dec 2025 11:16:44 +0000 14 | 15 | edk2-cix (1.0.0-7) main; urgency=medium 16 | 17 | [ ZHANG Yuntian ] 18 | * fix: pad full BIOS image to 8M 19 | 20 | [ github-actions[bot] ] 21 | * chore: update submodules 22 | 23 | -- "Radxa Computer Co., Ltd" Mon, 15 Dec 2025 09:47:02 +0000 24 | 25 | edk2-cix (1.0.0-6) main; urgency=medium 26 | 27 | [ ZHANG Yuntian ] 28 | * fix: make BIOS update less easy 29 | * feat: add edk2-radxa-orion-cix-p1 30 | 31 | [ github-actions[bot] ] 32 | * chore: update submodules 33 | 34 | -- "Radxa Computer Co., Ltd" Sun, 30 Nov 2025 12:20:43 +0000 35 | 36 | edk2-cix (1.0.0-5) main; urgency=medium 37 | 38 | [ github-actions[bot] ] 39 | * chore: update submodules 40 | 41 | -- "Radxa Computer Co., Ltd" Thu, 27 Nov 2025 08:33:18 +0000 42 | 43 | edk2-cix (1.0.0-4) main; urgency=medium 44 | 45 | [ github-actions[bot] ] 46 | * chore: update submodules 47 | 48 | -- "Radxa Computer Co., Ltd" Wed, 26 Nov 2025 07:14:23 +0000 49 | 50 | edk2-cix (1.0.0-3) main; urgency=medium 51 | 52 | [ github-actions[bot] ] 53 | * chore: update submodules 54 | 55 | -- "Radxa Computer Co., Ltd" Tue, 11 Nov 2025 04:08:58 +0000 56 | 57 | edk2-cix (1.0.0-2) main; urgency=medium 58 | 59 | [ ZHANG Yuntian ] 60 | * feat: allow board firmware to override default firmware 61 | * fix: clean before making mem_config 62 | * feat: update EC UART Baud 63 | * feat: support aarch64 native build 64 | * fix: handle firmware-less EC-less platform 65 | * docs: add update submodule instruction 66 | * fix: clarify that external code are subject to their own licenses 67 | * feat: add Orion O6N 68 | * chore: remove acpica 69 | 70 | [ github-actions[bot] ] 71 | * chore: update submodules 72 | 73 | -- "Radxa Computer Co., Ltd" Thu, 06 Nov 2025 09:30:53 +0000 74 | 75 | edk2-cix (1.0.0-1) main; urgency=medium 76 | 77 | [ ZHANG Yuntian ] 78 | * docs: add upgrade recording for boot entry method 79 | * fix: add power cycle warning before flashing 80 | * chore: bump to CIX 2025.04 release 81 | * fix: solve dos2unix permission issue in docker 82 | * feat: add more development helpers 83 | * chore: update submodules for Radxa changes 84 | * fix: various build issues 85 | 86 | [ Michal Schulz ] 87 | * Update README.md to mention x86_64 host requirement 88 | 89 | -- "Radxa Computer Co., Ltd" Thu, 17 Jul 2025 09:09:53 +0000 90 | 91 | edk2-cix (0.3.0-1) main; urgency=medium 92 | 93 | [ ZHANG Yuntian ] 94 | * fix: adjust line ending for patch to apply 95 | * chore: update edk2-non-osi 96 | * fix: add example variable configuration for gbp dch 97 | * chore: update to the latest SDK release 98 | * docs: update product name 99 | * feat: support custom memory frequency 100 | * fix: restore configurations from template update 101 | * chore: bump EDK2 release to 2025.03 102 | * fix: rename installation script to startup.nsh 103 | * feat: add help message for EFI Shell power management 104 | * chore: update devenv.lock 105 | * feat: install EDK2 installer to ESP 106 | * chore: update devenv.lock 107 | * chore: update edk2-platforms 108 | * docs: add new systemd-boot update method 109 | 110 | -- "Radxa Computer Co., Ltd" Mon, 28 Apr 2025 11:28:21 +0800 111 | 112 | edk2-cix (0.2.1-1) main; urgency=medium 113 | 114 | [ ZHANG Yuntian ] 115 | * chore: update edk2-platforms 116 | * fix: add gbp for make dch command 117 | 118 | -- "Radxa Computer Co., Ltd" Fri, 17 Jan 2025 02:12:27 +0000 119 | 120 | edk2-cix (0.2.0-1) main; urgency=medium 121 | 122 | [ ZHANG Yuntian ] 123 | * docs: update product name in the documentation 124 | * docs: add installation guide 125 | * docs: add description for 2 development shortcuts 126 | * chore: update to Beta 2 127 | * fix: use tab for Makefile 128 | * chore: update with latest Cix bug fixes 129 | * fix: disable build for CIX targets 130 | * chore: update devenv.lock 131 | * feat: support building in devcontainer 132 | * docs: only supporting devcontainer build 133 | * chore: update edk2-platforms 134 | 135 | -- "Radxa Computer Co., Ltd" Thu, 16 Jan 2025 17:35:45 +0800 136 | 137 | edk2-cix (0.1.1-1) main; urgency=medium 138 | 139 | * First release build 140 | * Based on CIX Beta1 EDK2 141 | 142 | -- "Radxa Computer Co., Ltd" Mon, 06 Jan 2025 15:32:58 +0800 143 | 144 | edk2-cix (0.1.0-1) UNRELEASED; urgency=medium 145 | 146 | * Add initial Debian packaging support 147 | * This version was used on multiple development builds during bring-up. 148 | As such, we will skip this version to avoid the confusion between an 149 | official 0.1.0-1 and pre-release 0.1.0-1. 150 | 151 | -- "Radxa Computer Co., Ltd" Fri, 30 Aug 2024 19:31:58 +0800 152 | -------------------------------------------------------------------------------- /docs/install.md: -------------------------------------------------------------------------------- 1 | # Manually install released binary 2 | 3 | ## Full demo 4 | 5 | Below is the full process of upgrading an 0.1.0 debug build to 0.1.1-1 release build. 6 | 7 | Ventoy were used and HDMI display were connected. The actual process happened over serial. 8 | 9 | [![asciicast](https://asciinema.org/a/O7YsPjUyLIa2174oFgPPdGKyt.svg)](https://asciinema.org/a/O7YsPjUyLIa2174oFgPPdGKyt) 10 | 11 | --- 12 | 13 | ## Where to find releases? 14 | 15 | You can find all released Debian packages under GitHub [Release](https://github.com/radxa-pkg/edk2-cix/releases) page. 16 | 17 | Similar to our other firmware packages, each release contains both the binary package as well as the metapackages. 18 | 19 | Taking release [0.1.1-1](https://github.com/radxa-pkg/edk2-cix/releases/tag/0.1.1-1) as an example, you can see 2 packages: 20 | 21 | | Name | Size| Type | 22 | | ---- | ---- | ---- | 23 | | edk2-cix_0.1.1-1_all.deb | 4.79 MB | Binary package | 24 | | edk2-orion-o6_0.1.1-1_all.deb | 2.09 KB | Metapackage | 25 | 26 | As usual, the binary package is the one with a large size, and the metapackage is usually only a few KB. 27 | 28 | Also, the binary package will usually share the name with the code repository, while metapackages will usually named after a specific product. 29 | 30 | ## Download and extrace the release 31 | 32 | To prepare a BIOS update disk, first, download and extract the package: 33 | 34 | ```bash 35 | mkdir extract 36 | cd extract 37 | wget https://github.com/radxa-pkg/edk2-cix/releases/download/0.1.1-1/edk2-cix_0.1.1-1_all.deb 38 | ar vx *.deb 39 | tar xvf data.tar.xz 40 | ``` 41 | 42 | ## Create the BIOS update disk 43 | 44 | You should now have BIOS for all supported platforms, as well as some supporting files 45 | 46 | ```bash 47 | $ find usr/share/edk2/ 48 | usr/share/edk2/ 49 | usr/share/edk2/cix 50 | usr/share/edk2/cix/merak 51 | usr/share/edk2/cix/merak/BuildOptions 52 | usr/share/edk2/cix/merak/BurnImage.efi 53 | usr/share/edk2/cix/merak/FlashUpdate.efi 54 | usr/share/edk2/cix/merak/Shell.efi 55 | usr/share/edk2/cix/merak/VariableInfo.efi 56 | usr/share/edk2/cix/merak/cix_flash.bin 57 | usr/share/edk2/cix/merak/startup.nsh 58 | usr/share/edk2/radxa 59 | usr/share/edk2/radxa/orion-o6 60 | usr/share/edk2/radxa/orion-o6/BuildOptions 61 | usr/share/edk2/radxa/orion-o6/BurnImage.efi 62 | usr/share/edk2/radxa/orion-o6/FlashUpdate.efi 63 | usr/share/edk2/radxa/orion-o6/Shell.efi 64 | usr/share/edk2/radxa/orion-o6/VariableInfo.efi 65 | usr/share/edk2/radxa/orion-o6/cix_flash.bin 66 | usr/share/edk2/radxa/orion-o6/startup.nsh 67 | ``` 68 | 69 | Copy them to a USB disk formatted in FAT file system, and connect them to the target board. 70 | 71 | Optionally, you can use `Ventoy` to create a BIOS update disk that can also be used to load Linux ISOs, as long as the size is under 4 GiB (due to FAT32 limitation). 72 | 73 | [`Ventoy`](https://www.ventoy.net/) is a popular ISO multi-boot tool. It also supports booting EFI applications and ARM64 architecture. 74 | 75 | First, use `Ventoy` to create a bootable USB disk. Make sure you select GPT partition table in the option. 76 | 77 | You will then reformat the first partition with FAT file system, as the default file system exFAT is not supported by EDK2. 78 | 79 | You can copy the EDK2 build artifacts to the first partition as usual. 80 | 81 | ## Enter UEFI Shell 82 | 83 | You will need to enter UEFI Shell to run the script to update the BIOS. There are 2 ways to achieve that: 84 | 85 | ### Via UEFI Setup 86 | 87 | Press `Escape` key when prompted on the console. Then enter `Boot Manager` menu and select `UEFI Shell`. 88 | 89 | ### Via `Ventoy` 90 | 91 | When you boot the system and missed the `Escape` prmopt, if there is no other bootable media, EDK2 should boot into `Ventoy`. 92 | 93 | ```admonish caution 94 | If screen is connected, Ventoy will boot into graphical mode. Under this mode you will have no output on UART2, but you can still control the menu with it. 95 | 96 | You can enable [`Force Text Mode`](https://github.com/ventoy/Ventoy/issues/2983#issuecomment-2367411817) under the display menu to allow output on UART2. 97 | ``` 98 | 99 | Inside `Ventoy` UI you should have `Shell.efi` listed as an option if you copied everything. Run it to enter UEFI Shell. 100 | 101 | ```admonish caution 102 | If you built for multiple EDK2 variants you may have multiple `Shell.efi` listed in `Ventoy`. They are generally compatible with different platforms, but when in doubt, only use the one come with your target platform, and only copy the EDK2 variant for your platform. 103 | ``` 104 | 105 | ## Update BIOS from UEFI Shell 106 | 107 | Once inside the UEFI Shell, you should first be greeted by a list of available storage devices and their physical paths. 108 | 109 | If you only have the USB disk connected, it should be listed as `fs0`. 110 | 111 | You can rescan the storage device with `map -r` command, which will reprint the available devices as well. 112 | 113 | You can run BIOS flash script from UEFI Shell now. It uses Windows convention, so an example command would be: 114 | 115 | ```cmd 116 | fs0:\radxa\orion-o6\startup.nsh 117 | ``` 118 | 119 | ```admonish info 120 | Before 0.3.0-1, `startup.nsh` is called `setup.nsh`. 121 | ``` 122 | 123 | The first backslash is not mandatory: 124 | 125 | ```cmd 126 | fs0:radxa\orion-o6\startup.nsh 127 | ``` 128 | 129 | There is limited auto completion in the UEFI Shell when pressing `Tab` key. 130 | 131 | Running this command will flash your BIOS. Follow its prompt to complete the process. 132 | -------------------------------------------------------------------------------- /theme/css/general.css: -------------------------------------------------------------------------------- 1 | /* Base styles and content styles */ 2 | 3 | @import "variables.css"; 4 | 5 | :root { 6 | /* Browser default font-size is 16px, this way 1 rem = 10px */ 7 | font-size: 62.5%; 8 | } 9 | 10 | html { 11 | font-family: "Open Sans", sans-serif; 12 | color: var(--fg); 13 | background-color: var(--bg); 14 | text-size-adjust: none; 15 | -webkit-text-size-adjust: none; 16 | } 17 | 18 | body { 19 | margin: 0; 20 | font-size: 1.6rem; 21 | overflow-x: hidden; 22 | } 23 | 24 | code { 25 | font-family: var(--mono-font) !important; 26 | font-size: var(--code-font-size); 27 | } 28 | 29 | /* make long words/inline code not x overflow */ 30 | main { 31 | overflow-wrap: break-word; 32 | } 33 | 34 | /* make wide tables scroll if they overflow */ 35 | .table-wrapper { 36 | overflow-x: auto; 37 | } 38 | 39 | /* Don't change font size in headers. */ 40 | h1 code, 41 | h2 code, 42 | h3 code, 43 | h4 code, 44 | h5 code, 45 | h6 code { 46 | font-size: unset; 47 | } 48 | 49 | .left { 50 | float: left; 51 | } 52 | .right { 53 | float: right; 54 | } 55 | .boring { 56 | opacity: 0.6; 57 | } 58 | .hide-boring .boring { 59 | display: none; 60 | } 61 | .hidden { 62 | display: none !important; 63 | } 64 | 65 | h2, 66 | h3 { 67 | margin-top: 2.5em; 68 | } 69 | h4, 70 | h5 { 71 | margin-top: 2em; 72 | } 73 | 74 | .header + .header h3, 75 | .header + .header h4, 76 | .header + .header h5 { 77 | margin-top: 1em; 78 | } 79 | 80 | h1:target::before, 81 | h2:target::before, 82 | h3:target::before, 83 | h4:target::before, 84 | h5:target::before, 85 | h6:target::before { 86 | display: inline-block; 87 | content: "»"; 88 | margin-left: -30px; 89 | width: 30px; 90 | } 91 | 92 | /* This is broken on Safari as of version 14, but is fixed 93 | in Safari Technology Preview 117 which I think will be Safari 14.2. 94 | https://bugs.webkit.org/show_bug.cgi?id=218076 95 | */ 96 | :target { 97 | scroll-margin-top: calc(var(--menu-bar-height) + 0.5em); 98 | } 99 | 100 | .page { 101 | outline: 0; 102 | padding: 0 var(--page-padding); 103 | margin-top: calc( 104 | 0px - var(--menu-bar-height) 105 | ); /* Compensate for the #menu-bar-hover-placeholder */ 106 | } 107 | .page-wrapper { 108 | box-sizing: border-box; 109 | } 110 | .js:not(.sidebar-resizing) .page-wrapper { 111 | transition: 112 | margin-left 0.3s ease, 113 | transform 0.3s ease; /* Animation: slide away */ 114 | } 115 | 116 | .content { 117 | overflow-y: auto; 118 | padding: 0 5px 50px 5px; 119 | } 120 | .content main { 121 | margin-left: auto; 122 | margin-right: auto; 123 | max-width: var(--content-max-width); 124 | } 125 | .content p { 126 | line-height: 1.45em; 127 | } 128 | .content ol { 129 | line-height: 1.45em; 130 | } 131 | .content ul { 132 | line-height: 1.45em; 133 | } 134 | .content a { 135 | text-decoration: none; 136 | } 137 | .content a:hover { 138 | text-decoration: underline; 139 | } 140 | .content img, 141 | .content video { 142 | max-width: 100%; 143 | } 144 | .content .header:link, 145 | .content .header:visited { 146 | color: var(--fg); 147 | } 148 | .content .header:link, 149 | .content .header:visited:hover { 150 | text-decoration: none; 151 | } 152 | 153 | table { 154 | margin: 0 auto; 155 | border-collapse: collapse; 156 | } 157 | table td { 158 | padding: 3px 20px; 159 | border: 1px var(--table-border-color) solid; 160 | } 161 | table thead { 162 | background: var(--table-header-bg); 163 | } 164 | table thead td { 165 | font-weight: 700; 166 | border: none; 167 | } 168 | table thead th { 169 | padding: 3px 20px; 170 | } 171 | table thead tr { 172 | border: 1px var(--table-header-bg) solid; 173 | } 174 | /* Alternate background colors for rows */ 175 | table tbody tr:nth-child(2n) { 176 | background: var(--table-alternate-bg); 177 | } 178 | 179 | blockquote { 180 | margin: 20px 0; 181 | padding: 0 20px; 182 | color: var(--fg); 183 | background-color: var(--quote-bg); 184 | border-top: 0.1em solid var(--quote-border); 185 | border-bottom: 0.1em solid var(--quote-border); 186 | } 187 | 188 | kbd { 189 | background-color: var(--table-border-color); 190 | border-radius: 4px; 191 | border: solid 1px var(--theme-popup-border); 192 | box-shadow: inset 0 -1px 0 var(--theme-hover); 193 | display: inline-block; 194 | font-size: var(--code-font-size); 195 | font-family: var(--mono-font); 196 | line-height: 10px; 197 | padding: 4px 5px; 198 | vertical-align: middle; 199 | } 200 | 201 | :not(.footnote-definition) + .footnote-definition, 202 | .footnote-definition + :not(.footnote-definition) { 203 | margin-top: 2em; 204 | } 205 | .footnote-definition { 206 | font-size: 0.9em; 207 | margin: 0.5em 0; 208 | } 209 | .footnote-definition p { 210 | display: inline; 211 | } 212 | 213 | .tooltiptext { 214 | position: absolute; 215 | visibility: hidden; 216 | color: #fff; 217 | background-color: #333; 218 | transform: translateX( 219 | -50% 220 | ); /* Center by moving tooltip 50% of its width left */ 221 | left: -8px; /* Half of the width of the icon */ 222 | top: -35px; 223 | font-size: 0.8em; 224 | text-align: center; 225 | border-radius: 6px; 226 | padding: 5px 8px; 227 | margin: 5px; 228 | z-index: 1000; 229 | } 230 | .tooltipped .tooltiptext { 231 | visibility: visible; 232 | } 233 | 234 | .chapter li.part-title { 235 | color: var(--sidebar-fg); 236 | margin: 5px 0px; 237 | font-weight: bold; 238 | } 239 | 240 | .result-no-output { 241 | font-style: italic; 242 | } 243 | -------------------------------------------------------------------------------- /po/messages.pot: -------------------------------------------------------------------------------- 1 | 2 | msgid "" 3 | msgstr "" 4 | "Project-Id-Version: edk2-cix\n" 5 | "POT-Creation-Date: 2024-10-09T14:42:19+08:00\n" 6 | "PO-Revision-Date: \n" 7 | "Last-Translator: \n" 8 | "Language-Team: \n" 9 | "MIME-Version: 1.0\n" 10 | "Content-Type: text/plain; charset=UTF-8\n" 11 | "Content-Transfer-Encoding: 8bit\n" 12 | "Language: en\n" 13 | "Plural-Forms: nplurals=1; plural=0;\n" 14 | 15 | #: docs/SUMMARY.md:1 16 | msgid "Summary" 17 | msgstr "" 18 | 19 | #: docs/SUMMARY.md:3 docs/build.md:1 20 | msgid "Build" 21 | msgstr "" 22 | 23 | #: docs/SUMMARY.md:4 docs/debug.md:1 24 | msgid "Debug" 25 | msgstr "" 26 | 27 | #: docs/build.md:3 28 | msgid "We use docker to maintain a consistent build environment." 29 | msgstr "" 30 | 31 | #: docs/build.md:5 32 | msgid "" 33 | "To build all supported EDK2 variants, please run `.github/common/build-deb`." 34 | msgstr "" 35 | 36 | #: docs/build.md:7 37 | msgid "" 38 | "Set `BUILD_TARGET` to `DEBUG` in `src/Makefile` to build for debug artifacts." 39 | msgstr "" 40 | 41 | #: docs/build.md:9 42 | msgid "" 43 | "Edit `DSC` in `src/Makefile` to reduce amount of variants that will be " 44 | "built. You should also edit `debian/edk2-cix.install` to exclude unbuild " 45 | "variants, otherwise `debuild` will complain that those files are missing." 46 | msgstr "" 47 | 48 | #: docs/debug.md:3 49 | msgid "Serial connection" 50 | msgstr "" 51 | 52 | #: docs/debug.md:5 53 | msgid "The following UARTs can be used to debug EDK2 on Radxa Orion O6:" 54 | msgstr "" 55 | 56 | #: docs/debug.md:7 57 | msgid "UART1: EC" 58 | msgstr "" 59 | 60 | #: docs/debug.md:8 61 | msgid "UART2: AP" 62 | msgstr "" 63 | 64 | #: docs/debug.md:9 65 | msgid "UART3: Debug" 66 | msgstr "" 67 | 68 | #: docs/debug.md:10 69 | msgid "UART4: PM" 70 | msgstr "" 71 | 72 | #: docs/debug.md:11 73 | msgid "UART5: SE" 74 | msgstr "" 75 | 76 | #: docs/debug.md:13 77 | msgid "" 78 | "UART2 is the default management console for EDK2 and the operationg system." 79 | msgstr "" 80 | 81 | #: docs/debug.md:15 82 | msgid "UART3 is only available when EDK2 is build as DEBUG image." 83 | msgstr "" 84 | 85 | #: docs/debug.md:17 86 | msgid "" 87 | "All UARTs other than UART1 use 115200 baud. EC UART can be viewed with the " 88 | "following command:" 89 | msgstr "" 90 | 91 | #: docs/debug.md:23 92 | msgid "In general, the log output order after power is connected is as follow:" 93 | msgstr "" 94 | 95 | #: docs/debug.md:29 96 | msgid "Installation" 97 | msgstr "" 98 | 99 | #: docs/debug.md:31 100 | msgid "" 101 | "Once build completes, you can find the complete set of artifacts under " 102 | "`debian/edk2-cix/usr/share/edk2/`." 103 | msgstr "" 104 | 105 | #: docs/debug.md:33 106 | msgid "" 107 | "Copy them to a USB disk formatted in FAT file system, and connect them to " 108 | "the target board." 109 | msgstr "" 110 | 111 | #: docs/debug.md:35 112 | msgid "" 113 | "You will need to enter UEFI Shell to run the script to update the BIOS. " 114 | "There are 2 ways to achieve that:" 115 | msgstr "" 116 | 117 | #: docs/debug.md:37 118 | msgid "Via UEFI Setup" 119 | msgstr "" 120 | 121 | #: docs/debug.md:39 122 | msgid "" 123 | "Press `Escape` key when prompted on the console. Then enter `Boot Manager` " 124 | "menu and select `UEFI Shell`." 125 | msgstr "" 126 | 127 | #: docs/debug.md:41 128 | msgid "Via `Ventoy`" 129 | msgstr "" 130 | 131 | #: docs/debug.md:43 132 | msgid "" 133 | "[`Ventoy`](https://www.ventoy.net/) is a popular ISO multi-boot tool. It " 134 | "also supports booting EFI applications and ARM64 architecture." 135 | msgstr "" 136 | 137 | #: docs/debug.md:45 138 | msgid "" 139 | "First, use `Ventoy` to create a bootable USB disk. Make sure you select GPT " 140 | "partition table in the option." 141 | msgstr "" 142 | 143 | #: docs/debug.md:47 144 | msgid "" 145 | "You will then reformat the first partition with FAT file system, as the " 146 | "default file system exFAT is not supported by EDK2." 147 | msgstr "" 148 | 149 | #: docs/debug.md:49 150 | msgid "" 151 | "You can then copy the EDK2 build artifacts as usual. When you boot the " 152 | "system and missed the `Escape` prmopt, if there is no other bootable media, " 153 | "EDK2 should boot into `Ventoy`." 154 | msgstr "" 155 | 156 | #: docs/debug.md:51 157 | msgid "" 158 | "```admonish caution\n" 159 | "If screen is connected, Ventoy will boot into graphical mode. Under this " 160 | "mode you will have no output on UART2, but you can still control the menu " 161 | "with it.\n" 162 | "\n" 163 | "You can enable [`Force Text " 164 | "Mode`](https://github.com/ventoy/Ventoy/issues/2983#issuecomment-2367411817) " 165 | "under the display menu to allow output on UART2.\n" 166 | "```" 167 | msgstr "" 168 | 169 | #: docs/debug.md:57 170 | msgid "" 171 | "Inside `Ventoy` UI you should have `Shell.efi` listed as an option if you " 172 | "copied everything from the `debian/edk2-cix.install` folder. Run it to enter " 173 | "UEFI Shell." 174 | msgstr "" 175 | 176 | #: docs/debug.md:66 177 | msgid "" 178 | "Once inside the UEFI Shell, you should first be greeted by a list of " 179 | "available storage devices and their physical paths." 180 | msgstr "" 181 | 182 | #: docs/debug.md:68 183 | msgid "If you only have the USB disk connected, it should be listed as `fs0`." 184 | msgstr "" 185 | 186 | #: docs/debug.md:70 187 | msgid "" 188 | "You can rescan the storage device with `map -r` command, which will reprint " 189 | "the available devices as well." 190 | msgstr "" 191 | 192 | #: docs/debug.md:72 193 | msgid "" 194 | "You can run BIOS flash script from UEFI Shell now. It uses Windows " 195 | "convention, so an example command would be:" 196 | msgstr "" 197 | 198 | #: docs/debug.md:78 199 | msgid "The first backslash is not mandatory:" 200 | msgstr "" 201 | 202 | #: docs/debug.md:84 203 | msgid "" 204 | "There is limited auto completion in the UEFI Shell when pressing `Tab` key." 205 | msgstr "" 206 | 207 | #: docs/debug.md:86 208 | msgid "" 209 | "Running this command will flash your BIOS. Follow its prompt to complete the " 210 | "process." 211 | msgstr "" 212 | 213 | -------------------------------------------------------------------------------- /po/zh-CN.po: -------------------------------------------------------------------------------- 1 | msgid "" 2 | msgstr "" 3 | "Project-Id-Version: edk2-cix\n" 4 | "POT-Creation-Date: 2024-10-09T14:42:19+08:00\n" 5 | "PO-Revision-Date: 2024-10-09 14:43+0800\n" 6 | "Last-Translator: \n" 7 | "Language-Team: Language zh-CN\n" 8 | "MIME-Version: 1.0\n" 9 | "Content-Type: text/plain; charset=UTF-8\n" 10 | "Content-Transfer-Encoding: 8bit\n" 11 | "Language: zh-CN\n" 12 | "Plural-Forms: nplurals=1; plural=0;\n" 13 | 14 | #: docs/SUMMARY.md:1 15 | msgid "Summary" 16 | msgstr "" 17 | 18 | #: docs/SUMMARY.md:3 docs/build.md:1 19 | msgid "Build" 20 | msgstr "" 21 | 22 | #: docs/SUMMARY.md:4 docs/debug.md:1 23 | msgid "Debug" 24 | msgstr "" 25 | 26 | #: docs/build.md:3 27 | msgid "We use docker to maintain a consistent build environment." 28 | msgstr "" 29 | 30 | #: docs/build.md:5 31 | msgid "" 32 | "To build all supported EDK2 variants, please run `.github/common/build-deb`." 33 | msgstr "" 34 | 35 | #: docs/build.md:7 36 | msgid "" 37 | "Set `BUILD_TARGET` to `DEBUG` in `src/Makefile` to build for debug artifacts." 38 | msgstr "" 39 | 40 | #: docs/build.md:9 41 | msgid "" 42 | "Edit `DSC` in `src/Makefile` to reduce amount of variants that will be " 43 | "built. You should also edit `debian/edk2-cix.install` to exclude unbuild " 44 | "variants, otherwise `debuild` will complain that those files are missing." 45 | msgstr "" 46 | 47 | #: docs/debug.md:3 48 | msgid "Serial connection" 49 | msgstr "" 50 | 51 | #: docs/debug.md:5 52 | msgid "The following UARTs can be used to debug EDK2 on Radxa Orion O6:" 53 | msgstr "" 54 | 55 | #: docs/debug.md:7 56 | msgid "UART1: EC" 57 | msgstr "" 58 | 59 | #: docs/debug.md:8 60 | msgid "UART2: AP" 61 | msgstr "" 62 | 63 | #: docs/debug.md:9 64 | msgid "UART3: Debug" 65 | msgstr "" 66 | 67 | #: docs/debug.md:10 68 | msgid "UART4: PM" 69 | msgstr "" 70 | 71 | #: docs/debug.md:11 72 | msgid "UART5: SE" 73 | msgstr "" 74 | 75 | #: docs/debug.md:13 76 | msgid "" 77 | "UART2 is the default management console for EDK2 and the operationg system." 78 | msgstr "" 79 | 80 | #: docs/debug.md:15 81 | msgid "UART3 is only available when EDK2 is build as DEBUG image." 82 | msgstr "" 83 | 84 | #: docs/debug.md:17 85 | msgid "" 86 | "All UARTs other than UART1 use 115200 baud. EC UART can be viewed with the " 87 | "following command:" 88 | msgstr "" 89 | 90 | #: docs/debug.md:23 91 | msgid "In general, the log output order after power is connected is as follow:" 92 | msgstr "" 93 | 94 | #: docs/debug.md:29 95 | msgid "Installation" 96 | msgstr "" 97 | 98 | #: docs/debug.md:31 99 | msgid "" 100 | "Once build completes, you can find the complete set of artifacts under " 101 | "`debian/edk2-cix/usr/share/edk2/`." 102 | msgstr "" 103 | 104 | #: docs/debug.md:33 105 | msgid "" 106 | "Copy them to a USB disk formatted in FAT file system, and connect them to " 107 | "the target board." 108 | msgstr "" 109 | 110 | #: docs/debug.md:35 111 | msgid "" 112 | "You will need to enter UEFI Shell to run the script to update the BIOS. " 113 | "There are 2 ways to achieve that:" 114 | msgstr "" 115 | 116 | #: docs/debug.md:37 117 | msgid "Via UEFI Setup" 118 | msgstr "" 119 | 120 | #: docs/debug.md:39 121 | msgid "" 122 | "Press `Escape` key when prompted on the console. Then enter `Boot Manager` " 123 | "menu and select `UEFI Shell`." 124 | msgstr "" 125 | 126 | #: docs/debug.md:41 127 | msgid "Via `Ventoy`" 128 | msgstr "" 129 | 130 | #: docs/debug.md:43 131 | msgid "" 132 | "[`Ventoy`](https://www.ventoy.net/) is a popular ISO multi-boot tool. It " 133 | "also supports booting EFI applications and ARM64 architecture." 134 | msgstr "" 135 | 136 | #: docs/debug.md:45 137 | msgid "" 138 | "First, use `Ventoy` to create a bootable USB disk. Make sure you select GPT " 139 | "partition table in the option." 140 | msgstr "" 141 | 142 | #: docs/debug.md:47 143 | msgid "" 144 | "You will then reformat the first partition with FAT file system, as the " 145 | "default file system exFAT is not supported by EDK2." 146 | msgstr "" 147 | 148 | #: docs/debug.md:49 149 | msgid "" 150 | "You can then copy the EDK2 build artifacts as usual. When you boot the " 151 | "system and missed the `Escape` prmopt, if there is no other bootable media, " 152 | "EDK2 should boot into `Ventoy`." 153 | msgstr "" 154 | 155 | #: docs/debug.md:51 156 | msgid "" 157 | "```admonish caution\n" 158 | "If screen is connected, Ventoy will boot into graphical mode. Under this " 159 | "mode you will have no output on UART2, but you can still control the menu " 160 | "with it.\n" 161 | "\n" 162 | "You can enable [`Force Text Mode`](https://github.com/ventoy/Ventoy/" 163 | "issues/2983#issuecomment-2367411817) under the display menu to allow output " 164 | "on UART2.\n" 165 | "```" 166 | msgstr "" 167 | 168 | #: docs/debug.md:57 169 | msgid "" 170 | "Inside `Ventoy` UI you should have `Shell.efi` listed as an option if you " 171 | "copied everything from the `debian/edk2-cix.install` folder. Run it to enter " 172 | "UEFI Shell." 173 | msgstr "" 174 | 175 | #: docs/debug.md:66 176 | msgid "" 177 | "Once inside the UEFI Shell, you should first be greeted by a list of " 178 | "available storage devices and their physical paths." 179 | msgstr "" 180 | 181 | #: docs/debug.md:68 182 | msgid "If you only have the USB disk connected, it should be listed as `fs0`." 183 | msgstr "" 184 | 185 | #: docs/debug.md:70 186 | msgid "" 187 | "You can rescan the storage device with `map -r` command, which will reprint " 188 | "the available devices as well." 189 | msgstr "" 190 | 191 | #: docs/debug.md:72 192 | msgid "" 193 | "You can run BIOS flash script from UEFI Shell now. It uses Windows " 194 | "convention, so an example command would be:" 195 | msgstr "" 196 | 197 | #: docs/debug.md:78 198 | msgid "The first backslash is not mandatory:" 199 | msgstr "" 200 | 201 | #: docs/debug.md:84 202 | msgid "" 203 | "There is limited auto completion in the UEFI Shell when pressing `Tab` key." 204 | msgstr "" 205 | 206 | #: docs/debug.md:86 207 | msgid "" 208 | "Running this command will flash your BIOS. Follow its prompt to complete the " 209 | "process." 210 | msgstr "" 211 | -------------------------------------------------------------------------------- /src/Makefile: -------------------------------------------------------------------------------- 1 | UEFI_TARGET ?= RELEASE 2 | # Specify DEBUG build for development 3 | # UEFI_TARGET ?= DEBUG 4 | 5 | .PHONY: all 6 | all: build 7 | 8 | UNAME := $(shell uname -m) 9 | 10 | ifeq ($(UNAME), aarch64) 11 | PACKAGE_TOOL_ARCH := AARCH64 12 | GCC5_AARCH64_PREFIX := 13 | else 14 | PACKAGE_TOOL_ARCH := X86_64 15 | GCC5_AARCH64_PREFIX := aarch64-linux-gnu- 16 | endif 17 | 18 | PACKAGE_TOOL := edk2-non-osi/Platform/CIX/Sky1/PackageTool 19 | DSC := $(shell find edk2-platforms/Platform/Radxa -mindepth 3 -maxdepth 3 -name "*.dsc" -type "f") \ 20 | # $(shell find edk2-platforms/Platform/CIX -mindepth 3 -maxdepth 3 -name "*.dsc" -type "f") 21 | 22 | CIX_FLASH := $(foreach i, $(patsubst edk2-platforms/Platform/%.dsc,%,$(DSC)), Build/$(lastword $(subst /, ,$(i)))/$(UEFI_TARGET)_GCC5/cix_flash_all.bin) \ 23 | $(foreach i, $(patsubst edk2-platforms/Platform/%.dsc,%,$(DSC)), Build/$(lastword $(subst /, ,$(i)))/$(UEFI_TARGET)_GCC5/cix_flash_ota.bin) 24 | .PHONY: build 25 | build: $(CIX_FLASH) 26 | 27 | .SILENT: help 28 | .PHONY: help 29 | help: 30 | echo "Supported targets:" 31 | echo "$(CIX_FLASH)" 32 | 33 | Build/%/$(UEFI_TARGET)_GCC5/cix_flash_ota.bin: Build/%/$(UEFI_TARGET)_GCC5/Firmwares/bootloader3.img 34 | export CFG="$(shell find edk2*/Platform/ -mindepth 4 -maxdepth 4 -path "*/$*/spi_flash_config_ota.json" -type f)" && \ 35 | export PATH_PACKAGE_TOOL="$(shell realpath "$(PACKAGE_TOOL)")" && \ 36 | if [[ -f "$$CFG" ]]; then \ 37 | echo "Found custom flash config."; \ 38 | cp "$$CFG" Build/$*/$(UEFI_TARGET)_GCC5/; \ 39 | else \ 40 | cp "$$PATH_PACKAGE_TOOL/spi_flash_config_ota.json" Build/$*/$(UEFI_TARGET)_GCC5/; \ 41 | fi 42 | 43 | export PATH_PACKAGE_TOOL="$(shell realpath "$(PACKAGE_TOOL)")" && \ 44 | pushd "Build/$*/$(UEFI_TARGET)_GCC5/" && \ 45 | "$$PATH_PACKAGE_TOOL/$(PACKAGE_TOOL_ARCH)/cix_package_tool" -c "./spi_flash_config_ota.json" -O "./cix_flash_ota.bin" && \ 46 | popd 47 | 48 | # MEM_CFG_MEMFREQ ?= 2750 49 | MEM_CFG_MEMFREQ ?= 3000 50 | 51 | Build/%/$(UEFI_TARGET)_GCC5/cix_flash_all.bin: Build/%/$(UEFI_TARGET)_GCC5/Firmwares/bootloader3.img 52 | export MEM="$(shell find edk2*/Platform/ -mindepth 4 -maxdepth 4 -path "*/$*/mem_config" -type d)" && \ 53 | if [[ -d "$$MEM" ]]; then \ 54 | echo "Found custom memory configuration."; \ 55 | make -C "$$MEM" -j$(shell nproc) -e CFLAG:="-DMEM_CFG_MEMFREQ=$(MEM_CFG_MEMFREQ)" clean main; \ 56 | mv "$$MEM/memory_config.bin" Build/$*/$(UEFI_TARGET)_GCC5/Firmwares/; \ 57 | fi 58 | export PM="$(shell find edk2*/Platform/ -mindepth 4 -maxdepth 4 -path "*/$*/pm_config" -type d)" && \ 59 | if [[ -d "$$PM" ]]; then \ 60 | echo "Found custom PM configuration."; \ 61 | make -C "$$PM" -j$(shell nproc); \ 62 | mv "$$PM/csu_pm_config.bin" Build/$*/$(UEFI_TARGET)_GCC5/Firmwares/; \ 63 | fi 64 | 65 | export CFG="$(shell find edk2*/Platform/ -mindepth 4 -maxdepth 4 -path "*/$*/spi_flash_config_all.json" -type f)" && \ 66 | export PATH_PACKAGE_TOOL="$(shell realpath "$(PACKAGE_TOOL)")" && \ 67 | if [[ -f "$$CFG" ]]; then \ 68 | echo "Found custom flash config."; \ 69 | cp "$$CFG" Build/$*/$(UEFI_TARGET)_GCC5/; \ 70 | else \ 71 | cp "$$PATH_PACKAGE_TOOL/spi_flash_config_all.json" Build/$*/$(UEFI_TARGET)_GCC5/; \ 72 | fi 73 | 74 | export PATH_PACKAGE_TOOL="$(shell realpath "$(PACKAGE_TOOL)")" && \ 75 | pushd "Build/$*/$(UEFI_TARGET)_GCC5/" && \ 76 | "$$PATH_PACKAGE_TOOL/$(PACKAGE_TOOL_ARCH)/cix_package_tool" -c "./spi_flash_config_all.json" -o "./cix_flash_all.raw" && \ 77 | 78 | # \377 = 0xFF 79 | head -c 8M < /dev/zero | tr '\000' '\377' > "./cix_flash_all.bin" 80 | dd if="./cix_flash_all.raw" of="./cix_flash_all.bin" conv=notrunc 81 | popd 82 | 83 | Build/%/$(UEFI_TARGET)_GCC5/Firmwares/bootloader3.img: Build/%/$(UEFI_TARGET)_GCC5/FV/SKY1_BL33_UEFI.fd Build/%/$(UEFI_TARGET)_GCC5/Firmwares/dummy.bin 84 | cp -aR $(PACKAGE_TOOL)/Keys/ $(PACKAGE_TOOL)/certs/ Build/$*/$(UEFI_TARGET)_GCC5/ 85 | export PATH_PACKAGE_TOOL="$(shell realpath "$(PACKAGE_TOOL)")" && \ 86 | "$$PATH_PACKAGE_TOOL/$(PACKAGE_TOOL_ARCH)/cert_uefi_create_rsa" --key-alg rsa --key-size 3072 --hash-alg sha256 -p --ntfw-nvctr 223 \ 87 | --nt-fw-cert Build/$*/$(UEFI_TARGET)_GCC5/certs/nt_fw_cert.crt \ 88 | --nt-fw-key-cert Build/$*/$(UEFI_TARGET)_GCC5/certs/nt_fw_key.crt \ 89 | --nt-fw-key Build/$*/$(UEFI_TARGET)_GCC5/Keys/oem_privatekey.pem \ 90 | --non-trusted-world-key Build/$*/$(UEFI_TARGET)_GCC5/Keys/oem_privatekey.pem \ 91 | --nt-fw "$(shell realpath "$<")" && \ 92 | "$$PATH_PACKAGE_TOOL/$(PACKAGE_TOOL_ARCH)/fiptool" create \ 93 | --trusted-key-cert Build/$*/$(UEFI_TARGET)_GCC5/certs/trusted_key_no.crt \ 94 | --nt-fw-key-cert Build/$*/$(UEFI_TARGET)_GCC5/certs/nt_fw_key.crt \ 95 | --nt-fw-cert Build/$*/$(UEFI_TARGET)_GCC5/certs/nt_fw_cert.crt \ 96 | --nt-fw "$(shell realpath "$<")" \ 97 | $@ 98 | 99 | Build/%/$(UEFI_TARGET)_GCC5/Firmwares/dummy.bin: 100 | cp -aR $(PACKAGE_TOOL)/Firmwares/ Build/$*/$(UEFI_TARGET)_GCC5/ 101 | # \377 = 0xFF 102 | head -c 8192 < /dev/zero | tr '\000' '\377' > $@ 103 | 104 | export FW="$(shell find edk2*/Platform/ -mindepth 4 -maxdepth 4 -path "*/$*/Firmwares" -type d)" && \ 105 | if [[ -d "$$FW" ]]; then \ 106 | echo "Found custom firmware."; \ 107 | cp -r "$$FW/." Build/$*/$(UEFI_TARGET)_GCC5/Firmwares/; \ 108 | fi; \ 109 | if [[ ! -e "$$FW" ]] || [[ ! -f "$$FW/ec_fw.bin" ]]; then \ 110 | echo "Found EC-less platform."; \ 111 | ln -sf dummy.bin Build/$*/$(UEFI_TARGET)_GCC5/Firmwares/ec_fw.bin; \ 112 | fi; \ 113 | 114 | .ONESHELL: 115 | SHELL := bash 116 | Build/%/$(UEFI_TARGET)_GCC5/FV/SKY1_BL33_UEFI.fd: 117 | make -C edk2/BaseTools -j$(shell nproc) Source/C 118 | export WORKSPACE="$(shell pwd)" 119 | export PACKAGES_PATH="$$WORKSPACE/edk2:$$WORKSPACE/edk2-platforms:$$WORKSPACE/edk2-non-osi:$$WORKSPACE/edk2-platforms/Silicon/Intel/" 120 | export GCC5_AARCH64_PREFIX="$(GCC5_AARCH64_PREFIX)" 121 | if [[ -f tools/acpica/generate/unix/bin/iasl ]]; then 122 | export IASL_PREFIX="$$WORKSPACE/tools/acpica/generate/unix/bin/" 123 | fi 124 | unset MAKEFLAGS 125 | source edk2/edksetup.sh --reconfig 126 | build -a AARCH64 -t GCC5 -p "$(subst edk2-platforms/,,$(filter %/$*.dsc,$(DSC)))" \ 127 | -b $(UEFI_TARGET) -D BOARD_NAME=$(word 2, $(subst /,, $@)) -D BUILD_DATE=$(shell date -Is) \ 128 | -D SMP_ENABLE=1 -D ACPI_BOOT_ENABLE=1 -D FASTBOOT_LOAD= -D VARIABLE_TYPE=SPI -D STANDARD_MM=TRUE \ 129 | -D COMMIT_HASH=$(shell git rev-parse --short HEAD) \ 130 | -D EDK2_COMMIT_HASH=$(shell cd edk2 && git rev-parse --short HEAD) \ 131 | -D EDK2_NON_OSI_COMMIT_HASH=$(shell cd edk2-non-osi && git rev-parse --short HEAD) \ 132 | -D EDK2_PLATFORMS_COMMIT_HASH=$(shell cd edk2-platforms && git rev-parse --short HEAD) \ 133 | -D DEB_VERSION=$(shell cd .. && dpkg-parsechangelog -S Version) 134 | 135 | tools/acpica/generate/unix/bin/iasl: 136 | make -C tools/acpica -j$(shell nproc) 137 | 138 | .PHONY: clean 139 | clean: 140 | rm -rf Build 141 | make -C edk2/BaseTools -j$(shell nproc) clean 142 | make -C tools/acpica -j$(shell nproc) veryclean || true 143 | 144 | .PHONY: distclean 145 | distclean: clean 146 | -------------------------------------------------------------------------------- /theme/css/variables.css: -------------------------------------------------------------------------------- 1 | /* Globals */ 2 | 3 | :root { 4 | --sidebar-width: 300px; 5 | --page-padding: 15px; 6 | --content-max-width: 750px; 7 | --menu-bar-height: 50px; 8 | --mono-font: "Source Code Pro", Consolas, "Ubuntu Mono", Menlo, 9 | "DejaVu Sans Mono", monospace, monospace; 10 | --code-font-size: 0.875em 11 | /* please adjust the ace font size accordingly in editor.js */; 12 | } 13 | 14 | /* Themes */ 15 | 16 | .ayu { 17 | --bg: hsl(210, 25%, 8%); 18 | --fg: #c5c5c5; 19 | 20 | --sidebar-bg: #14191f; 21 | --sidebar-fg: #c8c9db; 22 | --sidebar-non-existent: #5c6773; 23 | --sidebar-active: #ffb454; 24 | --sidebar-spacer: #2d334f; 25 | 26 | --scrollbar: var(--sidebar-fg); 27 | 28 | --icons: #737480; 29 | --icons-hover: #b7b9cc; 30 | 31 | --links: #0096cf; 32 | 33 | --inline-code-color: #ffb454; 34 | 35 | --theme-popup-bg: #14191f; 36 | --theme-popup-border: #5c6773; 37 | --theme-hover: #191f26; 38 | 39 | --quote-bg: hsl(226, 15%, 17%); 40 | --quote-border: hsl(226, 15%, 22%); 41 | 42 | --table-border-color: hsl(210, 25%, 13%); 43 | --table-header-bg: hsl(210, 25%, 28%); 44 | --table-alternate-bg: hsl(210, 25%, 11%); 45 | 46 | --searchbar-border-color: #848484; 47 | --searchbar-bg: #424242; 48 | --searchbar-fg: #fff; 49 | --searchbar-shadow-color: #d4c89f; 50 | --searchresults-header-fg: #666; 51 | --searchresults-border-color: #888; 52 | --searchresults-li-bg: #252932; 53 | --search-mark-bg: #e3b171; 54 | } 55 | 56 | .coal { 57 | --bg: hsl(200, 7%, 8%); 58 | --fg: #98a3ad; 59 | 60 | --sidebar-bg: #292c2f; 61 | --sidebar-fg: #a1adb8; 62 | --sidebar-non-existent: #505254; 63 | --sidebar-active: #3473ad; 64 | --sidebar-spacer: #393939; 65 | 66 | --scrollbar: var(--sidebar-fg); 67 | 68 | --icons: #43484d; 69 | --icons-hover: #b3c0cc; 70 | 71 | --links: #2b79a2; 72 | 73 | --inline-code-color: #c5c8c6; 74 | 75 | --theme-popup-bg: #141617; 76 | --theme-popup-border: #43484d; 77 | --theme-hover: #1f2124; 78 | 79 | --quote-bg: hsl(234, 21%, 18%); 80 | --quote-border: hsl(234, 21%, 23%); 81 | 82 | --table-border-color: hsl(200, 7%, 13%); 83 | --table-header-bg: hsl(200, 7%, 28%); 84 | --table-alternate-bg: hsl(200, 7%, 11%); 85 | 86 | --searchbar-border-color: #aaa; 87 | --searchbar-bg: #b7b7b7; 88 | --searchbar-fg: #000; 89 | --searchbar-shadow-color: #aaa; 90 | --searchresults-header-fg: #666; 91 | --searchresults-border-color: #98a3ad; 92 | --searchresults-li-bg: #2b2b2f; 93 | --search-mark-bg: #355c7d; 94 | } 95 | 96 | .light { 97 | --bg: hsl(0, 0%, 100%); 98 | --fg: hsl(0, 0%, 0%); 99 | 100 | --sidebar-bg: #fafafa; 101 | --sidebar-fg: hsl(0, 0%, 0%); 102 | --sidebar-non-existent: #aaaaaa; 103 | --sidebar-active: #1f1fff; 104 | --sidebar-spacer: #f4f4f4; 105 | 106 | --scrollbar: #8f8f8f; 107 | 108 | --icons: #747474; 109 | --icons-hover: #000000; 110 | 111 | --links: #20609f; 112 | 113 | --inline-code-color: #301900; 114 | 115 | --theme-popup-bg: #fafafa; 116 | --theme-popup-border: #cccccc; 117 | --theme-hover: #e6e6e6; 118 | 119 | --quote-bg: hsl(197, 37%, 96%); 120 | --quote-border: hsl(197, 37%, 91%); 121 | 122 | --table-border-color: hsl(0, 0%, 95%); 123 | --table-header-bg: hsl(0, 0%, 80%); 124 | --table-alternate-bg: hsl(0, 0%, 97%); 125 | 126 | --searchbar-border-color: #aaa; 127 | --searchbar-bg: #fafafa; 128 | --searchbar-fg: #000; 129 | --searchbar-shadow-color: #aaa; 130 | --searchresults-header-fg: #666; 131 | --searchresults-border-color: #888; 132 | --searchresults-li-bg: #e4f2fe; 133 | --search-mark-bg: #a2cff5; 134 | } 135 | 136 | .navy { 137 | --bg: hsl(226, 23%, 11%); 138 | --fg: #bcbdd0; 139 | 140 | --sidebar-bg: #282d3f; 141 | --sidebar-fg: #c8c9db; 142 | --sidebar-non-existent: #505274; 143 | --sidebar-active: #2b79a2; 144 | --sidebar-spacer: #2d334f; 145 | 146 | --scrollbar: var(--sidebar-fg); 147 | 148 | --icons: #737480; 149 | --icons-hover: #b7b9cc; 150 | 151 | --links: #2b79a2; 152 | 153 | --inline-code-color: #c5c8c6; 154 | 155 | --theme-popup-bg: #161923; 156 | --theme-popup-border: #737480; 157 | --theme-hover: #282e40; 158 | 159 | --quote-bg: hsl(226, 15%, 17%); 160 | --quote-border: hsl(226, 15%, 22%); 161 | 162 | --table-border-color: hsl(226, 23%, 16%); 163 | --table-header-bg: hsl(226, 23%, 31%); 164 | --table-alternate-bg: hsl(226, 23%, 14%); 165 | 166 | --searchbar-border-color: #aaa; 167 | --searchbar-bg: #aeaec6; 168 | --searchbar-fg: #000; 169 | --searchbar-shadow-color: #aaa; 170 | --searchresults-header-fg: #5f5f71; 171 | --searchresults-border-color: #5c5c68; 172 | --searchresults-li-bg: #242430; 173 | --search-mark-bg: #a2cff5; 174 | } 175 | 176 | .rust { 177 | --bg: hsl(60, 9%, 87%); 178 | --fg: #262625; 179 | 180 | --sidebar-bg: #3b2e2a; 181 | --sidebar-fg: #c8c9db; 182 | --sidebar-non-existent: #505254; 183 | --sidebar-active: #e69f67; 184 | --sidebar-spacer: #45373a; 185 | 186 | --scrollbar: var(--sidebar-fg); 187 | 188 | --icons: #737480; 189 | --icons-hover: #262625; 190 | 191 | --links: #2b79a2; 192 | 193 | --inline-code-color: #6e6b5e; 194 | 195 | --theme-popup-bg: #e1e1db; 196 | --theme-popup-border: #b38f6b; 197 | --theme-hover: #99908a; 198 | 199 | --quote-bg: hsl(60, 5%, 75%); 200 | --quote-border: hsl(60, 5%, 70%); 201 | 202 | --table-border-color: hsl(60, 9%, 82%); 203 | --table-header-bg: #b3a497; 204 | --table-alternate-bg: hsl(60, 9%, 84%); 205 | 206 | --searchbar-border-color: #aaa; 207 | --searchbar-bg: #fafafa; 208 | --searchbar-fg: #000; 209 | --searchbar-shadow-color: #aaa; 210 | --searchresults-header-fg: #666; 211 | --searchresults-border-color: #888; 212 | --searchresults-li-bg: #dec2a2; 213 | --search-mark-bg: #e69f67; 214 | } 215 | 216 | @media (prefers-color-scheme: dark) { 217 | .light.no-js { 218 | --bg: hsl(200, 7%, 8%); 219 | --fg: #98a3ad; 220 | 221 | --sidebar-bg: #292c2f; 222 | --sidebar-fg: #a1adb8; 223 | --sidebar-non-existent: #505254; 224 | --sidebar-active: #3473ad; 225 | --sidebar-spacer: #393939; 226 | 227 | --scrollbar: var(--sidebar-fg); 228 | 229 | --icons: #43484d; 230 | --icons-hover: #b3c0cc; 231 | 232 | --links: #2b79a2; 233 | 234 | --inline-code-color: #c5c8c6; 235 | 236 | --theme-popup-bg: #141617; 237 | --theme-popup-border: #43484d; 238 | --theme-hover: #1f2124; 239 | 240 | --quote-bg: hsl(234, 21%, 18%); 241 | --quote-border: hsl(234, 21%, 23%); 242 | 243 | --table-border-color: hsl(200, 7%, 13%); 244 | --table-header-bg: hsl(200, 7%, 28%); 245 | --table-alternate-bg: hsl(200, 7%, 11%); 246 | 247 | --searchbar-border-color: #aaa; 248 | --searchbar-bg: #b7b7b7; 249 | --searchbar-fg: #000; 250 | --searchbar-shadow-color: #aaa; 251 | --searchresults-header-fg: #666; 252 | --searchresults-border-color: #98a3ad; 253 | --searchresults-li-bg: #2b2b2f; 254 | --search-mark-bg: #355c7d; 255 | } 256 | } 257 | -------------------------------------------------------------------------------- /theme/fonts/OPEN-SANS-LICENSE.txt: -------------------------------------------------------------------------------- 1 | 2 | Apache License 3 | Version 2.0, January 2004 4 | http://www.apache.org/licenses/ 5 | 6 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 7 | 8 | 1. Definitions. 9 | 10 | "License" shall mean the terms and conditions for use, reproduction, 11 | and distribution as defined by Sections 1 through 9 of this document. 12 | 13 | "Licensor" shall mean the copyright owner or entity authorized by 14 | the copyright owner that is granting the License. 15 | 16 | "Legal Entity" shall mean the union of the acting entity and all 17 | other entities that control, are controlled by, or are under common 18 | control with that entity. For the purposes of this definition, 19 | "control" means (i) the power, direct or indirect, to cause the 20 | direction or management of such entity, whether by contract or 21 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 22 | outstanding shares, or (iii) beneficial ownership of such entity. 23 | 24 | "You" (or "Your") shall mean an individual or Legal Entity 25 | exercising permissions granted by this License. 26 | 27 | "Source" form shall mean the preferred form for making modifications, 28 | including but not limited to software source code, documentation 29 | source, and configuration files. 30 | 31 | "Object" form shall mean any form resulting from mechanical 32 | transformation or translation of a Source form, including but 33 | not limited to compiled object code, generated documentation, 34 | and conversions to other media types. 35 | 36 | "Work" shall mean the work of authorship, whether in Source or 37 | Object form, made available under the License, as indicated by a 38 | copyright notice that is included in or attached to the work 39 | (an example is provided in the Appendix below). 40 | 41 | "Derivative Works" shall mean any work, whether in Source or Object 42 | form, that is based on (or derived from) the Work and for which the 43 | editorial revisions, annotations, elaborations, or other modifications 44 | represent, as a whole, an original work of authorship. For the purposes 45 | of this License, Derivative Works shall not include works that remain 46 | separable from, or merely link (or bind by name) to the interfaces of, 47 | the Work and Derivative Works thereof. 48 | 49 | "Contribution" shall mean any work of authorship, including 50 | the original version of the Work and any modifications or additions 51 | to that Work or Derivative Works thereof, that is intentionally 52 | submitted to Licensor for inclusion in the Work by the copyright owner 53 | or by an individual or Legal Entity authorized to submit on behalf of 54 | the copyright owner. For the purposes of this definition, "submitted" 55 | means any form of electronic, verbal, or written communication sent 56 | to the Licensor or its representatives, including but not limited to 57 | communication on electronic mailing lists, source code control systems, 58 | and issue tracking systems that are managed by, or on behalf of, the 59 | Licensor for the purpose of discussing and improving the Work, but 60 | excluding communication that is conspicuously marked or otherwise 61 | designated in writing by the copyright owner as "Not a Contribution." 62 | 63 | "Contributor" shall mean Licensor and any individual or Legal Entity 64 | on behalf of whom a Contribution has been received by Licensor and 65 | subsequently incorporated within the Work. 66 | 67 | 2. Grant of Copyright License. Subject to the terms and conditions of 68 | this License, each Contributor hereby grants to You a perpetual, 69 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 70 | copyright license to reproduce, prepare Derivative Works of, 71 | publicly display, publicly perform, sublicense, and distribute the 72 | Work and such Derivative Works in Source or Object form. 73 | 74 | 3. Grant of Patent License. Subject to the terms and conditions of 75 | this License, each Contributor hereby grants to You a perpetual, 76 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 77 | (except as stated in this section) patent license to make, have made, 78 | use, offer to sell, sell, import, and otherwise transfer the Work, 79 | where such license applies only to those patent claims licensable 80 | by such Contributor that are necessarily infringed by their 81 | Contribution(s) alone or by combination of their Contribution(s) 82 | with the Work to which such Contribution(s) was submitted. If You 83 | institute patent litigation against any entity (including a 84 | cross-claim or counterclaim in a lawsuit) alleging that the Work 85 | or a Contribution incorporated within the Work constitutes direct 86 | or contributory patent infringement, then any patent licenses 87 | granted to You under this License for that Work shall terminate 88 | as of the date such litigation is filed. 89 | 90 | 4. Redistribution. You may reproduce and distribute copies of the 91 | Work or Derivative Works thereof in any medium, with or without 92 | modifications, and in Source or Object form, provided that You 93 | meet the following conditions: 94 | 95 | (a) You must give any other recipients of the Work or 96 | Derivative Works a copy of this License; and 97 | 98 | (b) You must cause any modified files to carry prominent notices 99 | stating that You changed the files; and 100 | 101 | (c) You must retain, in the Source form of any Derivative Works 102 | that You distribute, all copyright, patent, trademark, and 103 | attribution notices from the Source form of the Work, 104 | excluding those notices that do not pertain to any part of 105 | the Derivative Works; and 106 | 107 | (d) If the Work includes a "NOTICE" text file as part of its 108 | distribution, then any Derivative Works that You distribute must 109 | include a readable copy of the attribution notices contained 110 | within such NOTICE file, excluding those notices that do not 111 | pertain to any part of the Derivative Works, in at least one 112 | of the following places: within a NOTICE text file distributed 113 | as part of the Derivative Works; within the Source form or 114 | documentation, if provided along with the Derivative Works; or, 115 | within a display generated by the Derivative Works, if and 116 | wherever such third-party notices normally appear. The contents 117 | of the NOTICE file are for informational purposes only and 118 | do not modify the License. You may add Your own attribution 119 | notices within Derivative Works that You distribute, alongside 120 | or as an addendum to the NOTICE text from the Work, provided 121 | that such additional attribution notices cannot be construed 122 | as modifying the License. 123 | 124 | You may add Your own copyright statement to Your modifications and 125 | may provide additional or different license terms and conditions 126 | for use, reproduction, or distribution of Your modifications, or 127 | for any such Derivative Works as a whole, provided Your use, 128 | reproduction, and distribution of the Work otherwise complies with 129 | the conditions stated in this License. 130 | 131 | 5. Submission of Contributions. Unless You explicitly state otherwise, 132 | any Contribution intentionally submitted for inclusion in the Work 133 | by You to the Licensor shall be under the terms and conditions of 134 | this License, without any additional terms or conditions. 135 | Notwithstanding the above, nothing herein shall supersede or modify 136 | the terms of any separate license agreement you may have executed 137 | with Licensor regarding such Contributions. 138 | 139 | 6. Trademarks. This License does not grant permission to use the trade 140 | names, trademarks, service marks, or product names of the Licensor, 141 | except as required for reasonable and customary use in describing the 142 | origin of the Work and reproducing the content of the NOTICE file. 143 | 144 | 7. Disclaimer of Warranty. Unless required by applicable law or 145 | agreed to in writing, Licensor provides the Work (and each 146 | Contributor provides its Contributions) on an "AS IS" BASIS, 147 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 148 | implied, including, without limitation, any warranties or conditions 149 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 150 | PARTICULAR PURPOSE. You are solely responsible for determining the 151 | appropriateness of using or redistributing the Work and assume any 152 | risks associated with Your exercise of permissions under this License. 153 | 154 | 8. Limitation of Liability. In no event and under no legal theory, 155 | whether in tort (including negligence), contract, or otherwise, 156 | unless required by applicable law (such as deliberate and grossly 157 | negligent acts) or agreed to in writing, shall any Contributor be 158 | liable to You for damages, including any direct, indirect, special, 159 | incidental, or consequential damages of any character arising as a 160 | result of this License or out of the use or inability to use the 161 | Work (including but not limited to damages for loss of goodwill, 162 | work stoppage, computer failure or malfunction, or any and all 163 | other commercial damages or losses), even if such Contributor 164 | has been advised of the possibility of such damages. 165 | 166 | 9. Accepting Warranty or Additional Liability. While redistributing 167 | the Work or Derivative Works thereof, You may choose to offer, 168 | and charge a fee for, acceptance of support, warranty, indemnity, 169 | or other liability obligations and/or rights consistent with this 170 | License. However, in accepting such obligations, You may act only 171 | on Your own behalf and on Your sole responsibility, not on behalf 172 | of any other Contributor, and only if You agree to indemnify, 173 | defend, and hold each Contributor harmless for any liability 174 | incurred by, or claims asserted against, such Contributor by reason 175 | of your accepting any such warranty or additional liability. 176 | 177 | END OF TERMS AND CONDITIONS 178 | 179 | APPENDIX: How to apply the Apache License to your work. 180 | 181 | To apply the Apache License to your work, attach the following 182 | boilerplate notice, with the fields enclosed by brackets "[]" 183 | replaced with your own identifying information. (Don't include 184 | the brackets!) The text should be enclosed in the appropriate 185 | comment syntax for the file format. We also recommend that a 186 | file or class name and description of purpose be included on the 187 | same "printed page" as the copyright notice for easier 188 | identification within third-party archives. 189 | 190 | Copyright [yyyy] [name of copyright owner] 191 | 192 | Licensed under the Apache License, Version 2.0 (the "License"); 193 | you may not use this file except in compliance with the License. 194 | You may obtain a copy of the License at 195 | 196 | http://www.apache.org/licenses/LICENSE-2.0 197 | 198 | Unless required by applicable law or agreed to in writing, software 199 | distributed under the License is distributed on an "AS IS" BASIS, 200 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 201 | See the License for the specific language governing permissions and 202 | limitations under the License. 203 | -------------------------------------------------------------------------------- /theme/css/chrome.css: -------------------------------------------------------------------------------- 1 | /* CSS for UI elements (a.k.a. chrome) */ 2 | 3 | @import "variables.css"; 4 | 5 | html { 6 | scrollbar-color: var(--scrollbar) var(--bg); 7 | } 8 | #searchresults a, 9 | .content a:link, 10 | a:visited, 11 | a > .hljs { 12 | color: var(--links); 13 | } 14 | 15 | /* 16 | body-container is necessary because mobile browsers don't seem to like 17 | overflow-x on the body tag when there is a tag. 18 | */ 19 | #body-container { 20 | /* 21 | This is used when the sidebar pushes the body content off the side of 22 | the screen on small screens. Without it, dragging on mobile Safari 23 | will want to reposition the viewport in a weird way. 24 | */ 25 | overflow-x: clip; 26 | } 27 | 28 | /* Menu Bar */ 29 | 30 | #menu-bar, 31 | #menu-bar-hover-placeholder { 32 | z-index: 101; 33 | margin: auto calc(0px - var(--page-padding)); 34 | } 35 | #menu-bar { 36 | position: relative; 37 | display: flex; 38 | flex-wrap: wrap; 39 | background-color: var(--bg); 40 | border-bottom-color: var(--bg); 41 | border-bottom-width: 1px; 42 | border-bottom-style: solid; 43 | } 44 | #menu-bar.sticky, 45 | .js #menu-bar-hover-placeholder:hover + #menu-bar, 46 | .js #menu-bar:hover, 47 | .js.sidebar-visible #menu-bar { 48 | position: -webkit-sticky; 49 | position: sticky; 50 | top: 0 !important; 51 | } 52 | #menu-bar-hover-placeholder { 53 | position: sticky; 54 | position: -webkit-sticky; 55 | top: 0; 56 | height: var(--menu-bar-height); 57 | } 58 | #menu-bar.bordered { 59 | border-bottom-color: var(--table-border-color); 60 | } 61 | #menu-bar i, 62 | #menu-bar .icon-button { 63 | position: relative; 64 | padding: 0 8px; 65 | z-index: 10; 66 | line-height: var(--menu-bar-height); 67 | cursor: pointer; 68 | transition: color 0.5s; 69 | } 70 | @media only screen and (max-width: 420px) { 71 | #menu-bar i, 72 | #menu-bar .icon-button { 73 | padding: 0 5px; 74 | } 75 | } 76 | 77 | .icon-button { 78 | border: none; 79 | background: none; 80 | padding: 0; 81 | color: inherit; 82 | } 83 | .icon-button i { 84 | margin: 0; 85 | } 86 | 87 | .right-buttons { 88 | margin: 0 15px; 89 | } 90 | .right-buttons a { 91 | text-decoration: none; 92 | } 93 | 94 | .left-buttons { 95 | display: flex; 96 | margin: 0 5px; 97 | } 98 | .no-js .left-buttons { 99 | display: none; 100 | } 101 | 102 | .menu-title { 103 | display: inline-block; 104 | font-weight: 200; 105 | font-size: 2.4rem; 106 | line-height: var(--menu-bar-height); 107 | text-align: center; 108 | margin: 0; 109 | flex: 1; 110 | white-space: nowrap; 111 | overflow: hidden; 112 | text-overflow: ellipsis; 113 | } 114 | .js .menu-title { 115 | cursor: pointer; 116 | } 117 | 118 | .menu-bar, 119 | .menu-bar:visited, 120 | .nav-chapters, 121 | .nav-chapters:visited, 122 | .mobile-nav-chapters, 123 | .mobile-nav-chapters:visited, 124 | .menu-bar .icon-button, 125 | .menu-bar a i { 126 | color: var(--icons); 127 | } 128 | 129 | .menu-bar i:hover, 130 | .menu-bar .icon-button:hover, 131 | .nav-chapters:hover, 132 | .mobile-nav-chapters i:hover { 133 | color: var(--icons-hover); 134 | } 135 | 136 | /* Nav Icons */ 137 | 138 | .nav-chapters { 139 | font-size: 2.5em; 140 | text-align: center; 141 | text-decoration: none; 142 | 143 | position: fixed; 144 | top: 0; 145 | bottom: 0; 146 | margin: 0; 147 | max-width: 150px; 148 | min-width: 90px; 149 | 150 | display: flex; 151 | justify-content: center; 152 | align-content: center; 153 | flex-direction: column; 154 | 155 | transition: 156 | color 0.5s, 157 | background-color 0.5s; 158 | } 159 | 160 | .nav-chapters:hover { 161 | text-decoration: none; 162 | background-color: var(--theme-hover); 163 | transition: 164 | background-color 0.15s, 165 | color 0.15s; 166 | } 167 | 168 | .nav-wrapper { 169 | margin-top: 50px; 170 | display: none; 171 | } 172 | 173 | .mobile-nav-chapters { 174 | font-size: 2.5em; 175 | text-align: center; 176 | text-decoration: none; 177 | width: 90px; 178 | border-radius: 5px; 179 | background-color: var(--sidebar-bg); 180 | } 181 | 182 | .previous { 183 | float: left; 184 | } 185 | 186 | .next { 187 | float: right; 188 | right: var(--page-padding); 189 | } 190 | 191 | @media only screen and (max-width: 1080px) { 192 | .nav-wide-wrapper { 193 | display: none; 194 | } 195 | .nav-wrapper { 196 | display: block; 197 | } 198 | } 199 | 200 | @media only screen and (max-width: 1380px) { 201 | .sidebar-visible .nav-wide-wrapper { 202 | display: none; 203 | } 204 | .sidebar-visible .nav-wrapper { 205 | display: block; 206 | } 207 | } 208 | 209 | /* Inline code */ 210 | 211 | :not(pre) > .hljs { 212 | display: inline; 213 | padding: 0.1em 0.3em; 214 | border-radius: 3px; 215 | } 216 | 217 | :not(pre):not(a) > .hljs { 218 | color: var(--inline-code-color); 219 | overflow-x: initial; 220 | } 221 | 222 | a:hover > .hljs { 223 | text-decoration: underline; 224 | } 225 | 226 | pre { 227 | position: relative; 228 | } 229 | pre > .buttons { 230 | position: absolute; 231 | z-index: 100; 232 | right: 0px; 233 | top: 2px; 234 | margin: 0px; 235 | padding: 2px 0px; 236 | 237 | color: var(--sidebar-fg); 238 | cursor: pointer; 239 | visibility: hidden; 240 | opacity: 0; 241 | transition: 242 | visibility 0.1s linear, 243 | opacity 0.1s linear; 244 | } 245 | pre:hover > .buttons { 246 | visibility: visible; 247 | opacity: 1; 248 | } 249 | pre > .buttons :hover { 250 | color: var(--sidebar-active); 251 | border-color: var(--icons-hover); 252 | background-color: var(--theme-hover); 253 | } 254 | pre > .buttons i { 255 | margin-left: 8px; 256 | } 257 | pre > .buttons button { 258 | cursor: inherit; 259 | margin: 0px 5px; 260 | padding: 3px 5px; 261 | font-size: 14px; 262 | 263 | border-style: solid; 264 | border-width: 1px; 265 | border-radius: 4px; 266 | border-color: var(--icons); 267 | background-color: var(--theme-popup-bg); 268 | transition: 100ms; 269 | transition-property: color, border-color, background-color; 270 | color: var(--icons); 271 | } 272 | @media (pointer: coarse) { 273 | pre > .buttons button { 274 | /* On mobile, make it easier to tap buttons. */ 275 | padding: 0.3rem 1rem; 276 | } 277 | } 278 | pre > code { 279 | padding: 1rem; 280 | } 281 | 282 | /* FIXME: ACE editors overlap their buttons because ACE does absolute 283 | positioning within the code block which breaks padding. The only solution I 284 | can think of is to move the padding to the outer pre tag (or insert a div 285 | wrapper), but that would require fixing a whole bunch of CSS rules. 286 | */ 287 | .hljs.ace_editor { 288 | padding: 0rem 0rem; 289 | } 290 | 291 | pre > .result { 292 | margin-top: 10px; 293 | } 294 | 295 | /* Search */ 296 | 297 | #searchresults a { 298 | text-decoration: none; 299 | } 300 | 301 | mark { 302 | border-radius: 2px; 303 | padding: 0 3px 1px 3px; 304 | margin: 0 -3px -1px -3px; 305 | background-color: var(--search-mark-bg); 306 | transition: background-color 300ms linear; 307 | cursor: pointer; 308 | } 309 | 310 | mark.fade-out { 311 | background-color: rgba(0, 0, 0, 0) !important; 312 | cursor: auto; 313 | } 314 | 315 | .searchbar-outer { 316 | margin-left: auto; 317 | margin-right: auto; 318 | max-width: var(--content-max-width); 319 | } 320 | 321 | #searchbar { 322 | width: 100%; 323 | margin: 5px auto 0px auto; 324 | padding: 10px 16px; 325 | transition: box-shadow 300ms ease-in-out; 326 | border: 1px solid var(--searchbar-border-color); 327 | border-radius: 3px; 328 | background-color: var(--searchbar-bg); 329 | color: var(--searchbar-fg); 330 | } 331 | #searchbar:focus, 332 | #searchbar.active { 333 | box-shadow: 0 0 3px var(--searchbar-shadow-color); 334 | } 335 | 336 | .searchresults-header { 337 | font-weight: bold; 338 | font-size: 1em; 339 | padding: 18px 0 0 5px; 340 | color: var(--searchresults-header-fg); 341 | } 342 | 343 | .searchresults-outer { 344 | margin-left: auto; 345 | margin-right: auto; 346 | max-width: var(--content-max-width); 347 | border-bottom: 1px dashed var(--searchresults-border-color); 348 | } 349 | 350 | ul#searchresults { 351 | list-style: none; 352 | padding-left: 20px; 353 | } 354 | ul#searchresults li { 355 | margin: 10px 0px; 356 | padding: 2px; 357 | border-radius: 2px; 358 | } 359 | ul#searchresults li.focus { 360 | background-color: var(--searchresults-li-bg); 361 | } 362 | ul#searchresults span.teaser { 363 | display: block; 364 | clear: both; 365 | margin: 5px 0 0 20px; 366 | font-size: 0.8em; 367 | } 368 | ul#searchresults span.teaser em { 369 | font-weight: bold; 370 | font-style: normal; 371 | } 372 | 373 | /* Sidebar */ 374 | 375 | .sidebar { 376 | position: fixed; 377 | left: 0; 378 | top: 0; 379 | bottom: 0; 380 | width: var(--sidebar-width); 381 | font-size: 0.875em; 382 | box-sizing: border-box; 383 | -webkit-overflow-scrolling: touch; 384 | overscroll-behavior-y: contain; 385 | background-color: var(--sidebar-bg); 386 | color: var(--sidebar-fg); 387 | } 388 | .sidebar-resizing { 389 | -moz-user-select: none; 390 | -webkit-user-select: none; 391 | -ms-user-select: none; 392 | user-select: none; 393 | } 394 | .js:not(.sidebar-resizing) .sidebar { 395 | transition: transform 0.3s; /* Animation: slide away */ 396 | } 397 | .sidebar code { 398 | line-height: 2em; 399 | } 400 | .sidebar .sidebar-scrollbox { 401 | overflow-y: auto; 402 | position: absolute; 403 | top: 0; 404 | bottom: 0; 405 | left: 0; 406 | right: 0; 407 | padding: 10px 10px; 408 | } 409 | .sidebar .sidebar-resize-handle { 410 | position: absolute; 411 | cursor: col-resize; 412 | width: 0; 413 | right: 0; 414 | top: 0; 415 | bottom: 0; 416 | } 417 | .js .sidebar .sidebar-resize-handle { 418 | cursor: col-resize; 419 | width: 5px; 420 | } 421 | .sidebar-hidden .sidebar { 422 | transform: translateX(calc(0px - var(--sidebar-width))); 423 | } 424 | .sidebar::-webkit-scrollbar { 425 | background: var(--sidebar-bg); 426 | } 427 | .sidebar::-webkit-scrollbar-thumb { 428 | background: var(--scrollbar); 429 | } 430 | 431 | .sidebar-visible .page-wrapper { 432 | transform: translateX(var(--sidebar-width)); 433 | } 434 | @media only screen and (min-width: 620px) { 435 | .sidebar-visible .page-wrapper { 436 | transform: none; 437 | margin-left: var(--sidebar-width); 438 | } 439 | } 440 | 441 | .chapter { 442 | list-style: none outside none; 443 | padding-left: 0; 444 | line-height: 2.2em; 445 | } 446 | 447 | .chapter ol { 448 | width: 100%; 449 | } 450 | 451 | .chapter li { 452 | display: flex; 453 | color: var(--sidebar-non-existent); 454 | } 455 | .chapter li a { 456 | display: block; 457 | padding: 0; 458 | text-decoration: none; 459 | color: var(--sidebar-fg); 460 | } 461 | 462 | .chapter li a:hover { 463 | color: var(--sidebar-active); 464 | } 465 | 466 | .chapter li a.active { 467 | color: var(--sidebar-active); 468 | } 469 | 470 | .chapter li > a.toggle { 471 | cursor: pointer; 472 | display: block; 473 | margin-left: auto; 474 | padding: 0 10px; 475 | user-select: none; 476 | opacity: 0.68; 477 | } 478 | 479 | .chapter li > a.toggle div { 480 | transition: transform 0.5s; 481 | } 482 | 483 | /* collapse the section */ 484 | .chapter li:not(.expanded) + li > ol { 485 | display: none; 486 | } 487 | 488 | .chapter li.chapter-item { 489 | line-height: 1.5em; 490 | margin-top: 0.6em; 491 | } 492 | 493 | .chapter li.expanded > a.toggle div { 494 | transform: rotate(90deg); 495 | } 496 | 497 | .spacer { 498 | width: 100%; 499 | height: 3px; 500 | margin: 5px 0px; 501 | } 502 | .chapter .spacer { 503 | background-color: var(--sidebar-spacer); 504 | } 505 | 506 | @media (-moz-touch-enabled: 1), (pointer: coarse) { 507 | .chapter li a { 508 | padding: 5px 0; 509 | } 510 | .spacer { 511 | margin: 10px 0; 512 | } 513 | } 514 | 515 | .section { 516 | list-style: none outside none; 517 | padding-left: 20px; 518 | line-height: 1.9em; 519 | } 520 | 521 | /* Theme Menu Popup */ 522 | 523 | .theme-popup { 524 | position: absolute; 525 | left: 10px; 526 | top: var(--menu-bar-height); 527 | z-index: 1000; 528 | border-radius: 4px; 529 | font-size: 0.7em; 530 | color: var(--fg); 531 | background: var(--theme-popup-bg); 532 | border: 1px solid var(--theme-popup-border); 533 | margin: 0; 534 | padding: 0; 535 | list-style: none; 536 | display: none; 537 | /* Don't let the children's background extend past the rounded corners. */ 538 | overflow: hidden; 539 | } 540 | .theme-popup .default { 541 | color: var(--icons); 542 | } 543 | .theme-popup .theme { 544 | width: 100%; 545 | border: 0; 546 | margin: 0; 547 | padding: 2px 20px; 548 | line-height: 25px; 549 | white-space: nowrap; 550 | text-align: left; 551 | cursor: pointer; 552 | color: inherit; 553 | background: inherit; 554 | font-size: inherit; 555 | } 556 | .theme-popup .theme:hover { 557 | background-color: var(--theme-hover); 558 | } 559 | 560 | .theme-selected::before { 561 | display: inline-block; 562 | content: "✓"; 563 | margin-left: -14px; 564 | width: 14px; 565 | } 566 | -------------------------------------------------------------------------------- /theme/css/mdbook-admonish.css: -------------------------------------------------------------------------------- 1 | @charset "UTF-8"; 2 | :is(.admonition) { 3 | display: flow-root; 4 | margin: 1.5625em 0; 5 | padding: 0 1.2rem; 6 | color: var(--fg); 7 | page-break-inside: avoid; 8 | background-color: var(--bg); 9 | border: 0 solid black; 10 | border-inline-start-width: 0.4rem; 11 | border-radius: 0.2rem; 12 | box-shadow: 0 0.2rem 1rem rgba(0, 0, 0, 0.05), 0 0 0.1rem rgba(0, 0, 0, 0.1); 13 | } 14 | @media print { 15 | :is(.admonition) { 16 | box-shadow: none; 17 | } 18 | } 19 | :is(.admonition) > * { 20 | box-sizing: border-box; 21 | } 22 | :is(.admonition) :is(.admonition) { 23 | margin-top: 1em; 24 | margin-bottom: 1em; 25 | } 26 | :is(.admonition) > .tabbed-set:only-child { 27 | margin-top: 0; 28 | } 29 | html :is(.admonition) > :last-child { 30 | margin-bottom: 1.2rem; 31 | } 32 | 33 | a.admonition-anchor-link { 34 | display: none; 35 | position: absolute; 36 | left: -1.2rem; 37 | padding-right: 1rem; 38 | } 39 | a.admonition-anchor-link:link, a.admonition-anchor-link:visited { 40 | color: var(--fg); 41 | } 42 | a.admonition-anchor-link:link:hover, a.admonition-anchor-link:visited:hover { 43 | text-decoration: none; 44 | } 45 | a.admonition-anchor-link::before { 46 | content: "§"; 47 | } 48 | 49 | :is(.admonition-title, summary.admonition-title) { 50 | position: relative; 51 | min-height: 4rem; 52 | margin-block: 0; 53 | margin-inline: -1.6rem -1.2rem; 54 | padding-block: 0.8rem; 55 | padding-inline: 4.4rem 1.2rem; 56 | font-weight: 700; 57 | background-color: rgba(68, 138, 255, 0.1); 58 | print-color-adjust: exact; 59 | -webkit-print-color-adjust: exact; 60 | display: flex; 61 | } 62 | :is(.admonition-title, summary.admonition-title) p { 63 | margin: 0; 64 | } 65 | html :is(.admonition-title, summary.admonition-title):last-child { 66 | margin-bottom: 0; 67 | } 68 | :is(.admonition-title, summary.admonition-title)::before { 69 | position: absolute; 70 | top: 0.625em; 71 | inset-inline-start: 1.6rem; 72 | width: 2rem; 73 | height: 2rem; 74 | background-color: #448aff; 75 | print-color-adjust: exact; 76 | -webkit-print-color-adjust: exact; 77 | mask-image: url('data:image/svg+xml;charset=utf-8,'); 78 | -webkit-mask-image: url('data:image/svg+xml;charset=utf-8,'); 79 | mask-repeat: no-repeat; 80 | -webkit-mask-repeat: no-repeat; 81 | mask-size: contain; 82 | -webkit-mask-size: contain; 83 | content: ""; 84 | } 85 | :is(.admonition-title, summary.admonition-title):hover a.admonition-anchor-link { 86 | display: initial; 87 | } 88 | 89 | details.admonition > summary.admonition-title::after { 90 | position: absolute; 91 | top: 0.625em; 92 | inset-inline-end: 1.6rem; 93 | height: 2rem; 94 | width: 2rem; 95 | background-color: currentcolor; 96 | mask-image: var(--md-details-icon); 97 | -webkit-mask-image: var(--md-details-icon); 98 | mask-repeat: no-repeat; 99 | -webkit-mask-repeat: no-repeat; 100 | mask-size: contain; 101 | -webkit-mask-size: contain; 102 | content: ""; 103 | transform: rotate(0deg); 104 | transition: transform 0.25s; 105 | } 106 | details[open].admonition > summary.admonition-title::after { 107 | transform: rotate(90deg); 108 | } 109 | 110 | :root { 111 | --md-details-icon: url("data:image/svg+xml;charset=utf-8,"); 112 | } 113 | 114 | :root { 115 | --md-admonition-icon--admonish-note: url("data:image/svg+xml;charset=utf-8,"); 116 | --md-admonition-icon--admonish-abstract: url("data:image/svg+xml;charset=utf-8,"); 117 | --md-admonition-icon--admonish-info: url("data:image/svg+xml;charset=utf-8,"); 118 | --md-admonition-icon--admonish-tip: url("data:image/svg+xml;charset=utf-8,"); 119 | --md-admonition-icon--admonish-success: url("data:image/svg+xml;charset=utf-8,"); 120 | --md-admonition-icon--admonish-question: url("data:image/svg+xml;charset=utf-8,"); 121 | --md-admonition-icon--admonish-warning: url("data:image/svg+xml;charset=utf-8,"); 122 | --md-admonition-icon--admonish-failure: url("data:image/svg+xml;charset=utf-8,"); 123 | --md-admonition-icon--admonish-danger: url("data:image/svg+xml;charset=utf-8,"); 124 | --md-admonition-icon--admonish-bug: url("data:image/svg+xml;charset=utf-8,"); 125 | --md-admonition-icon--admonish-example: url("data:image/svg+xml;charset=utf-8,"); 126 | --md-admonition-icon--admonish-quote: url("data:image/svg+xml;charset=utf-8,"); 127 | } 128 | 129 | :is(.admonition):is(.admonish-note) { 130 | border-color: #448aff; 131 | } 132 | 133 | :is(.admonish-note) > :is(.admonition-title, summary.admonition-title) { 134 | background-color: rgba(68, 138, 255, 0.1); 135 | } 136 | :is(.admonish-note) > :is(.admonition-title, summary.admonition-title)::before { 137 | background-color: #448aff; 138 | mask-image: var(--md-admonition-icon--admonish-note); 139 | -webkit-mask-image: var(--md-admonition-icon--admonish-note); 140 | mask-repeat: no-repeat; 141 | -webkit-mask-repeat: no-repeat; 142 | mask-size: contain; 143 | -webkit-mask-repeat: no-repeat; 144 | } 145 | 146 | :is(.admonition):is(.admonish-abstract, .admonish-summary, .admonish-tldr) { 147 | border-color: #00b0ff; 148 | } 149 | 150 | :is(.admonish-abstract, .admonish-summary, .admonish-tldr) > :is(.admonition-title, summary.admonition-title) { 151 | background-color: rgba(0, 176, 255, 0.1); 152 | } 153 | :is(.admonish-abstract, .admonish-summary, .admonish-tldr) > :is(.admonition-title, summary.admonition-title)::before { 154 | background-color: #00b0ff; 155 | mask-image: var(--md-admonition-icon--admonish-abstract); 156 | -webkit-mask-image: var(--md-admonition-icon--admonish-abstract); 157 | mask-repeat: no-repeat; 158 | -webkit-mask-repeat: no-repeat; 159 | mask-size: contain; 160 | -webkit-mask-repeat: no-repeat; 161 | } 162 | 163 | :is(.admonition):is(.admonish-info, .admonish-todo) { 164 | border-color: #00b8d4; 165 | } 166 | 167 | :is(.admonish-info, .admonish-todo) > :is(.admonition-title, summary.admonition-title) { 168 | background-color: rgba(0, 184, 212, 0.1); 169 | } 170 | :is(.admonish-info, .admonish-todo) > :is(.admonition-title, summary.admonition-title)::before { 171 | background-color: #00b8d4; 172 | mask-image: var(--md-admonition-icon--admonish-info); 173 | -webkit-mask-image: var(--md-admonition-icon--admonish-info); 174 | mask-repeat: no-repeat; 175 | -webkit-mask-repeat: no-repeat; 176 | mask-size: contain; 177 | -webkit-mask-repeat: no-repeat; 178 | } 179 | 180 | :is(.admonition):is(.admonish-tip, .admonish-hint, .admonish-important) { 181 | border-color: #00bfa5; 182 | } 183 | 184 | :is(.admonish-tip, .admonish-hint, .admonish-important) > :is(.admonition-title, summary.admonition-title) { 185 | background-color: rgba(0, 191, 165, 0.1); 186 | } 187 | :is(.admonish-tip, .admonish-hint, .admonish-important) > :is(.admonition-title, summary.admonition-title)::before { 188 | background-color: #00bfa5; 189 | mask-image: var(--md-admonition-icon--admonish-tip); 190 | -webkit-mask-image: var(--md-admonition-icon--admonish-tip); 191 | mask-repeat: no-repeat; 192 | -webkit-mask-repeat: no-repeat; 193 | mask-size: contain; 194 | -webkit-mask-repeat: no-repeat; 195 | } 196 | 197 | :is(.admonition):is(.admonish-success, .admonish-check, .admonish-done) { 198 | border-color: #00c853; 199 | } 200 | 201 | :is(.admonish-success, .admonish-check, .admonish-done) > :is(.admonition-title, summary.admonition-title) { 202 | background-color: rgba(0, 200, 83, 0.1); 203 | } 204 | :is(.admonish-success, .admonish-check, .admonish-done) > :is(.admonition-title, summary.admonition-title)::before { 205 | background-color: #00c853; 206 | mask-image: var(--md-admonition-icon--admonish-success); 207 | -webkit-mask-image: var(--md-admonition-icon--admonish-success); 208 | mask-repeat: no-repeat; 209 | -webkit-mask-repeat: no-repeat; 210 | mask-size: contain; 211 | -webkit-mask-repeat: no-repeat; 212 | } 213 | 214 | :is(.admonition):is(.admonish-question, .admonish-help, .admonish-faq) { 215 | border-color: #64dd17; 216 | } 217 | 218 | :is(.admonish-question, .admonish-help, .admonish-faq) > :is(.admonition-title, summary.admonition-title) { 219 | background-color: rgba(100, 221, 23, 0.1); 220 | } 221 | :is(.admonish-question, .admonish-help, .admonish-faq) > :is(.admonition-title, summary.admonition-title)::before { 222 | background-color: #64dd17; 223 | mask-image: var(--md-admonition-icon--admonish-question); 224 | -webkit-mask-image: var(--md-admonition-icon--admonish-question); 225 | mask-repeat: no-repeat; 226 | -webkit-mask-repeat: no-repeat; 227 | mask-size: contain; 228 | -webkit-mask-repeat: no-repeat; 229 | } 230 | 231 | :is(.admonition):is(.admonish-warning, .admonish-caution, .admonish-attention) { 232 | border-color: #ff9100; 233 | } 234 | 235 | :is(.admonish-warning, .admonish-caution, .admonish-attention) > :is(.admonition-title, summary.admonition-title) { 236 | background-color: rgba(255, 145, 0, 0.1); 237 | } 238 | :is(.admonish-warning, .admonish-caution, .admonish-attention) > :is(.admonition-title, summary.admonition-title)::before { 239 | background-color: #ff9100; 240 | mask-image: var(--md-admonition-icon--admonish-warning); 241 | -webkit-mask-image: var(--md-admonition-icon--admonish-warning); 242 | mask-repeat: no-repeat; 243 | -webkit-mask-repeat: no-repeat; 244 | mask-size: contain; 245 | -webkit-mask-repeat: no-repeat; 246 | } 247 | 248 | :is(.admonition):is(.admonish-failure, .admonish-fail, .admonish-missing) { 249 | border-color: #ff5252; 250 | } 251 | 252 | :is(.admonish-failure, .admonish-fail, .admonish-missing) > :is(.admonition-title, summary.admonition-title) { 253 | background-color: rgba(255, 82, 82, 0.1); 254 | } 255 | :is(.admonish-failure, .admonish-fail, .admonish-missing) > :is(.admonition-title, summary.admonition-title)::before { 256 | background-color: #ff5252; 257 | mask-image: var(--md-admonition-icon--admonish-failure); 258 | -webkit-mask-image: var(--md-admonition-icon--admonish-failure); 259 | mask-repeat: no-repeat; 260 | -webkit-mask-repeat: no-repeat; 261 | mask-size: contain; 262 | -webkit-mask-repeat: no-repeat; 263 | } 264 | 265 | :is(.admonition):is(.admonish-danger, .admonish-error) { 266 | border-color: #ff1744; 267 | } 268 | 269 | :is(.admonish-danger, .admonish-error) > :is(.admonition-title, summary.admonition-title) { 270 | background-color: rgba(255, 23, 68, 0.1); 271 | } 272 | :is(.admonish-danger, .admonish-error) > :is(.admonition-title, summary.admonition-title)::before { 273 | background-color: #ff1744; 274 | mask-image: var(--md-admonition-icon--admonish-danger); 275 | -webkit-mask-image: var(--md-admonition-icon--admonish-danger); 276 | mask-repeat: no-repeat; 277 | -webkit-mask-repeat: no-repeat; 278 | mask-size: contain; 279 | -webkit-mask-repeat: no-repeat; 280 | } 281 | 282 | :is(.admonition):is(.admonish-bug) { 283 | border-color: #f50057; 284 | } 285 | 286 | :is(.admonish-bug) > :is(.admonition-title, summary.admonition-title) { 287 | background-color: rgba(245, 0, 87, 0.1); 288 | } 289 | :is(.admonish-bug) > :is(.admonition-title, summary.admonition-title)::before { 290 | background-color: #f50057; 291 | mask-image: var(--md-admonition-icon--admonish-bug); 292 | -webkit-mask-image: var(--md-admonition-icon--admonish-bug); 293 | mask-repeat: no-repeat; 294 | -webkit-mask-repeat: no-repeat; 295 | mask-size: contain; 296 | -webkit-mask-repeat: no-repeat; 297 | } 298 | 299 | :is(.admonition):is(.admonish-example) { 300 | border-color: #7c4dff; 301 | } 302 | 303 | :is(.admonish-example) > :is(.admonition-title, summary.admonition-title) { 304 | background-color: rgba(124, 77, 255, 0.1); 305 | } 306 | :is(.admonish-example) > :is(.admonition-title, summary.admonition-title)::before { 307 | background-color: #7c4dff; 308 | mask-image: var(--md-admonition-icon--admonish-example); 309 | -webkit-mask-image: var(--md-admonition-icon--admonish-example); 310 | mask-repeat: no-repeat; 311 | -webkit-mask-repeat: no-repeat; 312 | mask-size: contain; 313 | -webkit-mask-repeat: no-repeat; 314 | } 315 | 316 | :is(.admonition):is(.admonish-quote, .admonish-cite) { 317 | border-color: #9e9e9e; 318 | } 319 | 320 | :is(.admonish-quote, .admonish-cite) > :is(.admonition-title, summary.admonition-title) { 321 | background-color: rgba(158, 158, 158, 0.1); 322 | } 323 | :is(.admonish-quote, .admonish-cite) > :is(.admonition-title, summary.admonition-title)::before { 324 | background-color: #9e9e9e; 325 | mask-image: var(--md-admonition-icon--admonish-quote); 326 | -webkit-mask-image: var(--md-admonition-icon--admonish-quote); 327 | mask-repeat: no-repeat; 328 | -webkit-mask-repeat: no-repeat; 329 | mask-size: contain; 330 | -webkit-mask-repeat: no-repeat; 331 | } 332 | 333 | .navy :is(.admonition) { 334 | background-color: var(--sidebar-bg); 335 | } 336 | 337 | .ayu :is(.admonition), 338 | .coal :is(.admonition) { 339 | background-color: var(--theme-hover); 340 | } 341 | 342 | .rust :is(.admonition) { 343 | background-color: var(--sidebar-bg); 344 | color: var(--sidebar-fg); 345 | } 346 | .rust .admonition-anchor-link:link, .rust .admonition-anchor-link:visited { 347 | color: var(--sidebar-fg); 348 | } 349 | -------------------------------------------------------------------------------- /theme/index.hbs: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | {{ title }} 7 | {{#if is_print }} 8 | 9 | {{/if}} 10 | {{#if base_url}} 11 | 12 | {{/if}} 13 | 14 | 15 | {{> head}} 16 | 17 | 18 | 19 | 20 | 21 | {{#if favicon_svg}} 22 | 23 | {{/if}} 24 | {{#if favicon_png}} 25 | 26 | {{/if}} 27 | 28 | 29 | 30 | {{#if print_enable}} 31 | 36 | {{/if}} 37 | 38 | 39 | 43 | {{#if copy_fonts}} 44 | 45 | {{/if}} 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | {{#each additional_css}} 54 | 55 | {{/each}} 56 | 57 | {{#if mathjax_support}} 58 | 59 | 63 | {{/if}} 64 | 65 | 66 |
67 | 68 | 75 | 76 | 77 | 97 | 98 | 99 | 113 | 114 | 115 | 129 | 130 | 134 | 135 |
136 |
137 | {{> header}} 138 | 139 | 298 | 299 | {{#if search_enabled}} 300 | 316 | {{/if}} 317 | 318 | 319 | 332 | 333 |
334 |
335 | {{{ content }}} 336 | 337 | 354 |
355 | 356 | 386 |
387 |
388 | 389 | 416 |
417 | 418 | {{#if live_reload_endpoint}} 419 | 420 | 440 | {{/if}} 441 | 442 | {{#if google_analytics}} 443 | 444 | 474 | {{/if}} 475 | 476 | {{#if playground_line_numbers}} 477 | 480 | {{/if}} 481 | 482 | {{#if playground_copyable}} 483 | 486 | {{/if}} 487 | 488 | {{#if playground_js}} 489 | 490 | 491 | 492 | 493 | 494 | {{/if}} 495 | 496 | {{#if search_js}} 497 | 498 | 499 | 500 | {{/if}} 501 | 502 | 503 | 504 | 505 | 506 | 507 | {{#each additional_js}} 508 | 509 | {{/each}} 510 | 511 | {{#if is_print}} 512 | {{#if mathjax_support}} 513 | 520 | {{else}} 521 | 526 | {{/if}} 527 | {{/if}} 528 |
529 | 530 | 531 | -------------------------------------------------------------------------------- /theme/book.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | // Fix back button cache problem 4 | window.onunload = function () {}; 5 | 6 | // Global variable, shared between modules 7 | function playground_text(playground, hidden = true) { 8 | let code_block = playground.querySelector("code"); 9 | 10 | if (window.ace && code_block.classList.contains("editable")) { 11 | let editor = window.ace.edit(code_block); 12 | return editor.getValue(); 13 | } else if (hidden) { 14 | return code_block.textContent; 15 | } else { 16 | return code_block.innerText; 17 | } 18 | } 19 | 20 | (function codeSnippets() { 21 | function fetch_with_timeout(url, options, timeout = 6000) { 22 | return Promise.race([ 23 | fetch(url, options), 24 | new Promise((_, reject) => 25 | setTimeout(() => reject(new Error("timeout")), timeout), 26 | ), 27 | ]); 28 | } 29 | 30 | var playgrounds = Array.from(document.querySelectorAll(".playground")); 31 | if (playgrounds.length > 0) { 32 | fetch_with_timeout("https://play.rust-lang.org/meta/crates", { 33 | headers: { 34 | "Content-Type": "application/json", 35 | }, 36 | method: "POST", 37 | mode: "cors", 38 | }) 39 | .then((response) => response.json()) 40 | .then((response) => { 41 | // get list of crates available in the rust playground 42 | let playground_crates = response.crates.map((item) => item["id"]); 43 | playgrounds.forEach((block) => 44 | handle_crate_list_update(block, playground_crates), 45 | ); 46 | }); 47 | } 48 | 49 | function handle_crate_list_update(playground_block, playground_crates) { 50 | // update the play buttons after receiving the response 51 | update_play_button(playground_block, playground_crates); 52 | 53 | // and install on change listener to dynamically update ACE editors 54 | if (window.ace) { 55 | let code_block = playground_block.querySelector("code"); 56 | if (code_block.classList.contains("editable")) { 57 | let editor = window.ace.edit(code_block); 58 | editor.addEventListener("change", function (e) { 59 | update_play_button(playground_block, playground_crates); 60 | }); 61 | // add Ctrl-Enter command to execute rust code 62 | editor.commands.addCommand({ 63 | name: "run", 64 | bindKey: { 65 | win: "Ctrl-Enter", 66 | mac: "Ctrl-Enter", 67 | }, 68 | exec: (_editor) => run_rust_code(playground_block), 69 | }); 70 | } 71 | } 72 | } 73 | 74 | // updates the visibility of play button based on `no_run` class and 75 | // used crates vs ones available on http://play.rust-lang.org 76 | function update_play_button(pre_block, playground_crates) { 77 | var play_button = pre_block.querySelector(".play-button"); 78 | 79 | // skip if code is `no_run` 80 | if (pre_block.querySelector("code").classList.contains("no_run")) { 81 | play_button.classList.add("hidden"); 82 | return; 83 | } 84 | 85 | // get list of `extern crate`'s from snippet 86 | var txt = playground_text(pre_block); 87 | var re = /extern\s+crate\s+([a-zA-Z_0-9]+)\s*;/g; 88 | var snippet_crates = []; 89 | var item; 90 | while ((item = re.exec(txt))) { 91 | snippet_crates.push(item[1]); 92 | } 93 | 94 | // check if all used crates are available on play.rust-lang.org 95 | var all_available = snippet_crates.every(function (elem) { 96 | return playground_crates.indexOf(elem) > -1; 97 | }); 98 | 99 | if (all_available) { 100 | play_button.classList.remove("hidden"); 101 | } else { 102 | play_button.classList.add("hidden"); 103 | } 104 | } 105 | 106 | function run_rust_code(code_block) { 107 | var result_block = code_block.querySelector(".result"); 108 | if (!result_block) { 109 | result_block = document.createElement("code"); 110 | result_block.className = "result hljs language-bash"; 111 | 112 | code_block.append(result_block); 113 | } 114 | 115 | let text = playground_text(code_block); 116 | let classes = code_block.querySelector("code").classList; 117 | let edition = "2015"; 118 | if (classes.contains("edition2018")) { 119 | edition = "2018"; 120 | } else if (classes.contains("edition2021")) { 121 | edition = "2021"; 122 | } 123 | var params = { 124 | version: "stable", 125 | optimize: "0", 126 | code: text, 127 | edition: edition, 128 | }; 129 | 130 | if (text.indexOf("#![feature") !== -1) { 131 | params.version = "nightly"; 132 | } 133 | 134 | result_block.innerText = "Running..."; 135 | 136 | fetch_with_timeout("https://play.rust-lang.org/evaluate.json", { 137 | headers: { 138 | "Content-Type": "application/json", 139 | }, 140 | method: "POST", 141 | mode: "cors", 142 | body: JSON.stringify(params), 143 | }) 144 | .then((response) => response.json()) 145 | .then((response) => { 146 | if (response.result.trim() === "") { 147 | result_block.innerText = "No output"; 148 | result_block.classList.add("result-no-output"); 149 | } else { 150 | result_block.innerText = response.result; 151 | result_block.classList.remove("result-no-output"); 152 | } 153 | }) 154 | .catch( 155 | (error) => 156 | (result_block.innerText = 157 | "Playground Communication: " + error.message), 158 | ); 159 | } 160 | 161 | // Syntax highlighting Configuration 162 | hljs.configure({ 163 | tabReplace: " ", // 4 spaces 164 | languages: [], // Languages used for auto-detection 165 | }); 166 | 167 | let code_nodes = Array.from(document.querySelectorAll("code")) 168 | // Don't highlight `inline code` blocks in headers. 169 | .filter(function (node) { 170 | return !node.parentElement.classList.contains("header"); 171 | }); 172 | 173 | if (window.ace) { 174 | // language-rust class needs to be removed for editable 175 | // blocks or highlightjs will capture events 176 | code_nodes 177 | .filter(function (node) { 178 | return node.classList.contains("editable"); 179 | }) 180 | .forEach(function (block) { 181 | block.classList.remove("language-rust"); 182 | }); 183 | 184 | code_nodes 185 | .filter(function (node) { 186 | return !node.classList.contains("editable"); 187 | }) 188 | .forEach(function (block) { 189 | hljs.highlightBlock(block); 190 | }); 191 | } else { 192 | code_nodes.forEach(function (block) { 193 | hljs.highlightBlock(block); 194 | }); 195 | } 196 | 197 | // Adding the hljs class gives code blocks the color css 198 | // even if highlighting doesn't apply 199 | code_nodes.forEach(function (block) { 200 | block.classList.add("hljs"); 201 | }); 202 | 203 | Array.from(document.querySelectorAll("code.language-rust")).forEach( 204 | function (block) { 205 | var lines = Array.from(block.querySelectorAll(".boring")); 206 | // If no lines were hidden, return 207 | if (!lines.length) { 208 | return; 209 | } 210 | block.classList.add("hide-boring"); 211 | 212 | var buttons = document.createElement("div"); 213 | buttons.className = "buttons"; 214 | buttons.innerHTML = 215 | ''; 216 | 217 | // add expand button 218 | var pre_block = block.parentNode; 219 | pre_block.insertBefore(buttons, pre_block.firstChild); 220 | 221 | pre_block 222 | .querySelector(".buttons") 223 | .addEventListener("click", function (e) { 224 | if (e.target.classList.contains("fa-eye")) { 225 | e.target.classList.remove("fa-eye"); 226 | e.target.classList.add("fa-eye-slash"); 227 | e.target.title = "Hide lines"; 228 | e.target.setAttribute("aria-label", e.target.title); 229 | 230 | block.classList.remove("hide-boring"); 231 | } else if (e.target.classList.contains("fa-eye-slash")) { 232 | e.target.classList.remove("fa-eye-slash"); 233 | e.target.classList.add("fa-eye"); 234 | e.target.title = "Show hidden lines"; 235 | e.target.setAttribute("aria-label", e.target.title); 236 | 237 | block.classList.add("hide-boring"); 238 | } 239 | }); 240 | }, 241 | ); 242 | 243 | if (window.playground_copyable) { 244 | Array.from(document.querySelectorAll("pre code")).forEach(function (block) { 245 | var pre_block = block.parentNode; 246 | if (!pre_block.classList.contains("playground")) { 247 | var buttons = pre_block.querySelector(".buttons"); 248 | if (!buttons) { 249 | buttons = document.createElement("div"); 250 | buttons.className = "buttons"; 251 | pre_block.insertBefore(buttons, pre_block.firstChild); 252 | } 253 | 254 | var clipButton = document.createElement("button"); 255 | clipButton.className = "fa fa-copy clip-button"; 256 | clipButton.title = "Copy to clipboard"; 257 | clipButton.setAttribute("aria-label", clipButton.title); 258 | clipButton.innerHTML = ''; 259 | 260 | buttons.insertBefore(clipButton, buttons.firstChild); 261 | } 262 | }); 263 | } 264 | 265 | // Process playground code blocks 266 | Array.from(document.querySelectorAll(".playground")).forEach( 267 | function (pre_block) { 268 | // Add play button 269 | var buttons = pre_block.querySelector(".buttons"); 270 | if (!buttons) { 271 | buttons = document.createElement("div"); 272 | buttons.className = "buttons"; 273 | pre_block.insertBefore(buttons, pre_block.firstChild); 274 | } 275 | 276 | var runCodeButton = document.createElement("button"); 277 | runCodeButton.className = "fa fa-play play-button"; 278 | runCodeButton.hidden = true; 279 | runCodeButton.title = "Run this code"; 280 | runCodeButton.setAttribute("aria-label", runCodeButton.title); 281 | 282 | buttons.insertBefore(runCodeButton, buttons.firstChild); 283 | runCodeButton.addEventListener("click", function (e) { 284 | run_rust_code(pre_block); 285 | }); 286 | 287 | if (window.playground_copyable) { 288 | var copyCodeClipboardButton = document.createElement("button"); 289 | copyCodeClipboardButton.className = "fa fa-copy clip-button"; 290 | copyCodeClipboardButton.innerHTML = ''; 291 | copyCodeClipboardButton.title = "Copy to clipboard"; 292 | copyCodeClipboardButton.setAttribute( 293 | "aria-label", 294 | copyCodeClipboardButton.title, 295 | ); 296 | 297 | buttons.insertBefore(copyCodeClipboardButton, buttons.firstChild); 298 | } 299 | 300 | let code_block = pre_block.querySelector("code"); 301 | if (window.ace && code_block.classList.contains("editable")) { 302 | var undoChangesButton = document.createElement("button"); 303 | undoChangesButton.className = "fa fa-history reset-button"; 304 | undoChangesButton.title = "Undo changes"; 305 | undoChangesButton.setAttribute("aria-label", undoChangesButton.title); 306 | 307 | buttons.insertBefore(undoChangesButton, buttons.firstChild); 308 | 309 | undoChangesButton.addEventListener("click", function () { 310 | let editor = window.ace.edit(code_block); 311 | editor.setValue(editor.originalCode); 312 | editor.clearSelection(); 313 | }); 314 | } 315 | }, 316 | ); 317 | })(); 318 | 319 | (function themes() { 320 | var html = document.querySelector("html"); 321 | var themeToggleButton = document.getElementById("theme-toggle"); 322 | var themePopup = document.getElementById("theme-list"); 323 | var themeColorMetaTag = document.querySelector('meta[name="theme-color"]'); 324 | var stylesheets = { 325 | ayuHighlight: document.querySelector("[href$='ayu-highlight.css']"), 326 | tomorrowNight: document.querySelector("[href$='tomorrow-night.css']"), 327 | highlight: document.querySelector("[href$='highlight.css']"), 328 | }; 329 | 330 | function showThemes() { 331 | themePopup.style.display = "block"; 332 | themeToggleButton.setAttribute("aria-expanded", true); 333 | themePopup.querySelector("button#" + get_theme()).focus(); 334 | } 335 | 336 | function updateThemeSelected() { 337 | themePopup.querySelectorAll(".theme-selected").forEach(function (el) { 338 | el.classList.remove("theme-selected"); 339 | }); 340 | themePopup 341 | .querySelector("button#" + get_theme()) 342 | .classList.add("theme-selected"); 343 | } 344 | 345 | function hideThemes() { 346 | themePopup.style.display = "none"; 347 | themeToggleButton.setAttribute("aria-expanded", false); 348 | themeToggleButton.focus(); 349 | } 350 | 351 | function get_theme() { 352 | var theme; 353 | try { 354 | theme = localStorage.getItem("mdbook-theme"); 355 | } catch (e) {} 356 | if (theme === null || theme === undefined) { 357 | return default_theme; 358 | } else { 359 | return theme; 360 | } 361 | } 362 | 363 | function set_theme(theme, store = true) { 364 | let ace_theme; 365 | 366 | if (theme == "coal" || theme == "navy") { 367 | stylesheets.ayuHighlight.disabled = true; 368 | stylesheets.tomorrowNight.disabled = false; 369 | stylesheets.highlight.disabled = true; 370 | 371 | ace_theme = "ace/theme/tomorrow_night"; 372 | } else if (theme == "ayu") { 373 | stylesheets.ayuHighlight.disabled = false; 374 | stylesheets.tomorrowNight.disabled = true; 375 | stylesheets.highlight.disabled = true; 376 | ace_theme = "ace/theme/tomorrow_night"; 377 | } else { 378 | stylesheets.ayuHighlight.disabled = true; 379 | stylesheets.tomorrowNight.disabled = true; 380 | stylesheets.highlight.disabled = false; 381 | ace_theme = "ace/theme/dawn"; 382 | } 383 | 384 | setTimeout(function () { 385 | themeColorMetaTag.content = getComputedStyle( 386 | document.body, 387 | ).backgroundColor; 388 | }, 1); 389 | 390 | if (window.ace && window.editors) { 391 | window.editors.forEach(function (editor) { 392 | editor.setTheme(ace_theme); 393 | }); 394 | } 395 | 396 | var previousTheme = get_theme(); 397 | 398 | if (store) { 399 | try { 400 | localStorage.setItem("mdbook-theme", theme); 401 | } catch (e) {} 402 | } 403 | 404 | html.classList.remove(previousTheme); 405 | html.classList.add(theme); 406 | updateThemeSelected(); 407 | } 408 | 409 | // Set theme 410 | var theme = get_theme(); 411 | 412 | set_theme(theme, false); 413 | 414 | themeToggleButton.addEventListener("click", function () { 415 | if (themePopup.style.display === "block") { 416 | hideThemes(); 417 | } else { 418 | showThemes(); 419 | } 420 | }); 421 | 422 | themePopup.addEventListener("click", function (e) { 423 | var theme; 424 | if (e.target.className === "theme") { 425 | theme = e.target.id; 426 | } else if (e.target.parentElement.className === "theme") { 427 | theme = e.target.parentElement.id; 428 | } else { 429 | return; 430 | } 431 | set_theme(theme); 432 | }); 433 | 434 | themePopup.addEventListener("focusout", function (e) { 435 | // e.relatedTarget is null in Safari and Firefox on macOS (see workaround below) 436 | if ( 437 | !!e.relatedTarget && 438 | !themeToggleButton.contains(e.relatedTarget) && 439 | !themePopup.contains(e.relatedTarget) 440 | ) { 441 | hideThemes(); 442 | } 443 | }); 444 | 445 | // Should not be needed, but it works around an issue on macOS & iOS: https://github.com/rust-lang/mdBook/issues/628 446 | document.addEventListener("click", function (e) { 447 | if ( 448 | themePopup.style.display === "block" && 449 | !themeToggleButton.contains(e.target) && 450 | !themePopup.contains(e.target) 451 | ) { 452 | hideThemes(); 453 | } 454 | }); 455 | 456 | document.addEventListener("keydown", function (e) { 457 | if (e.altKey || e.ctrlKey || e.metaKey || e.shiftKey) { 458 | return; 459 | } 460 | if (!themePopup.contains(e.target)) { 461 | return; 462 | } 463 | 464 | switch (e.key) { 465 | case "Escape": 466 | e.preventDefault(); 467 | hideThemes(); 468 | break; 469 | case "ArrowUp": 470 | e.preventDefault(); 471 | var li = document.activeElement.parentElement; 472 | if (li && li.previousElementSibling) { 473 | li.previousElementSibling.querySelector("button").focus(); 474 | } 475 | break; 476 | case "ArrowDown": 477 | e.preventDefault(); 478 | var li = document.activeElement.parentElement; 479 | if (li && li.nextElementSibling) { 480 | li.nextElementSibling.querySelector("button").focus(); 481 | } 482 | break; 483 | case "Home": 484 | e.preventDefault(); 485 | themePopup.querySelector("li:first-child button").focus(); 486 | break; 487 | case "End": 488 | e.preventDefault(); 489 | themePopup.querySelector("li:last-child button").focus(); 490 | break; 491 | } 492 | }); 493 | })(); 494 | 495 | (function sidebar() { 496 | var html = document.querySelector("html"); 497 | var sidebar = document.getElementById("sidebar"); 498 | var sidebarLinks = document.querySelectorAll("#sidebar a"); 499 | var sidebarToggleButton = document.getElementById("sidebar-toggle"); 500 | var sidebarResizeHandle = document.getElementById("sidebar-resize-handle"); 501 | var firstContact = null; 502 | 503 | function showSidebar() { 504 | html.classList.remove("sidebar-hidden"); 505 | html.classList.add("sidebar-visible"); 506 | Array.from(sidebarLinks).forEach(function (link) { 507 | link.setAttribute("tabIndex", 0); 508 | }); 509 | sidebarToggleButton.setAttribute("aria-expanded", true); 510 | sidebar.setAttribute("aria-hidden", false); 511 | try { 512 | localStorage.setItem("mdbook-sidebar", "visible"); 513 | } catch (e) {} 514 | } 515 | 516 | var sidebarAnchorToggles = document.querySelectorAll("#sidebar a.toggle"); 517 | 518 | function toggleSection(ev) { 519 | ev.currentTarget.parentElement.classList.toggle("expanded"); 520 | } 521 | 522 | Array.from(sidebarAnchorToggles).forEach(function (el) { 523 | el.addEventListener("click", toggleSection); 524 | }); 525 | 526 | function hideSidebar() { 527 | html.classList.remove("sidebar-visible"); 528 | html.classList.add("sidebar-hidden"); 529 | Array.from(sidebarLinks).forEach(function (link) { 530 | link.setAttribute("tabIndex", -1); 531 | }); 532 | sidebarToggleButton.setAttribute("aria-expanded", false); 533 | sidebar.setAttribute("aria-hidden", true); 534 | try { 535 | localStorage.setItem("mdbook-sidebar", "hidden"); 536 | } catch (e) {} 537 | } 538 | 539 | // Toggle sidebar 540 | sidebarToggleButton.addEventListener("click", function sidebarToggle() { 541 | if (html.classList.contains("sidebar-hidden")) { 542 | var current_width = parseInt( 543 | document.documentElement.style.getPropertyValue("--sidebar-width"), 544 | 10, 545 | ); 546 | if (current_width < 150) { 547 | document.documentElement.style.setProperty("--sidebar-width", "150px"); 548 | } 549 | showSidebar(); 550 | } else if (html.classList.contains("sidebar-visible")) { 551 | hideSidebar(); 552 | } else { 553 | if (getComputedStyle(sidebar)["transform"] === "none") { 554 | hideSidebar(); 555 | } else { 556 | showSidebar(); 557 | } 558 | } 559 | }); 560 | 561 | sidebarResizeHandle.addEventListener("mousedown", initResize, false); 562 | 563 | function initResize(e) { 564 | window.addEventListener("mousemove", resize, false); 565 | window.addEventListener("mouseup", stopResize, false); 566 | html.classList.add("sidebar-resizing"); 567 | } 568 | function resize(e) { 569 | var pos = e.clientX - sidebar.offsetLeft; 570 | if (pos < 20) { 571 | hideSidebar(); 572 | } else { 573 | if (html.classList.contains("sidebar-hidden")) { 574 | showSidebar(); 575 | } 576 | pos = Math.min(pos, window.innerWidth - 100); 577 | document.documentElement.style.setProperty("--sidebar-width", pos + "px"); 578 | } 579 | } 580 | //on mouseup remove windows functions mousemove & mouseup 581 | function stopResize(e) { 582 | html.classList.remove("sidebar-resizing"); 583 | window.removeEventListener("mousemove", resize, false); 584 | window.removeEventListener("mouseup", stopResize, false); 585 | } 586 | 587 | document.addEventListener( 588 | "touchstart", 589 | function (e) { 590 | firstContact = { 591 | x: e.touches[0].clientX, 592 | time: Date.now(), 593 | }; 594 | }, 595 | { passive: true }, 596 | ); 597 | 598 | document.addEventListener( 599 | "touchmove", 600 | function (e) { 601 | if (!firstContact) return; 602 | 603 | var curX = e.touches[0].clientX; 604 | var xDiff = curX - firstContact.x, 605 | tDiff = Date.now() - firstContact.time; 606 | 607 | if (tDiff < 250 && Math.abs(xDiff) >= 150) { 608 | if ( 609 | xDiff >= 0 && 610 | firstContact.x < Math.min(document.body.clientWidth * 0.25, 300) 611 | ) 612 | showSidebar(); 613 | else if (xDiff < 0 && curX < 300) hideSidebar(); 614 | 615 | firstContact = null; 616 | } 617 | }, 618 | { passive: true }, 619 | ); 620 | 621 | // Scroll sidebar to current active section 622 | var activeSection = document 623 | .getElementById("sidebar") 624 | .querySelector(".active"); 625 | if (activeSection) { 626 | // https://developer.mozilla.org/en-US/docs/Web/API/Element/scrollIntoView 627 | activeSection.scrollIntoView({ block: "center" }); 628 | } 629 | })(); 630 | 631 | (function chapterNavigation() { 632 | document.addEventListener("keydown", function (e) { 633 | if (e.altKey || e.ctrlKey || e.metaKey || e.shiftKey) { 634 | return; 635 | } 636 | if (window.search && window.search.hasFocus()) { 637 | return; 638 | } 639 | 640 | switch (e.key) { 641 | case "ArrowRight": 642 | e.preventDefault(); 643 | var nextButton = document.querySelector(".nav-chapters.next"); 644 | if (nextButton) { 645 | window.location.href = nextButton.href; 646 | } 647 | break; 648 | case "ArrowLeft": 649 | e.preventDefault(); 650 | var previousButton = document.querySelector(".nav-chapters.previous"); 651 | if (previousButton) { 652 | window.location.href = previousButton.href; 653 | } 654 | break; 655 | } 656 | }); 657 | })(); 658 | 659 | (function clipboard() { 660 | var clipButtons = document.querySelectorAll(".clip-button"); 661 | 662 | function hideTooltip(elem) { 663 | elem.firstChild.innerText = ""; 664 | elem.className = "fa fa-copy clip-button"; 665 | } 666 | 667 | function showTooltip(elem, msg) { 668 | elem.firstChild.innerText = msg; 669 | elem.className = "fa fa-copy tooltipped"; 670 | } 671 | 672 | var clipboardSnippets = new ClipboardJS(".clip-button", { 673 | text: function (trigger) { 674 | hideTooltip(trigger); 675 | let playground = trigger.closest("pre"); 676 | return playground_text(playground, false); 677 | }, 678 | }); 679 | 680 | Array.from(clipButtons).forEach(function (clipButton) { 681 | clipButton.addEventListener("mouseout", function (e) { 682 | hideTooltip(e.currentTarget); 683 | }); 684 | }); 685 | 686 | clipboardSnippets.on("success", function (e) { 687 | e.clearSelection(); 688 | showTooltip(e.trigger, "Copied!"); 689 | }); 690 | 691 | clipboardSnippets.on("error", function (e) { 692 | showTooltip(e.trigger, "Clipboard error!"); 693 | }); 694 | })(); 695 | 696 | (function scrollToTop() { 697 | var menuTitle = document.querySelector(".menu-title"); 698 | 699 | menuTitle.addEventListener("click", function () { 700 | document.scrollingElement.scrollTo({ top: 0, behavior: "smooth" }); 701 | }); 702 | })(); 703 | 704 | (function controlMenu() { 705 | var menu = document.getElementById("menu-bar"); 706 | 707 | (function controlPosition() { 708 | var scrollTop = document.scrollingElement.scrollTop; 709 | var prevScrollTop = scrollTop; 710 | var minMenuY = -menu.clientHeight - 50; 711 | // When the script loads, the page can be at any scroll (e.g. if you reforesh it). 712 | menu.style.top = scrollTop + "px"; 713 | // Same as parseInt(menu.style.top.slice(0, -2), but faster 714 | var topCache = menu.style.top.slice(0, -2); 715 | menu.classList.remove("sticky"); 716 | var stickyCache = false; // Same as menu.classList.contains('sticky'), but faster 717 | document.addEventListener( 718 | "scroll", 719 | function () { 720 | scrollTop = Math.max(document.scrollingElement.scrollTop, 0); 721 | // `null` means that it doesn't need to be updated 722 | var nextSticky = null; 723 | var nextTop = null; 724 | var scrollDown = scrollTop > prevScrollTop; 725 | var menuPosAbsoluteY = topCache - scrollTop; 726 | if (scrollDown) { 727 | nextSticky = false; 728 | if (menuPosAbsoluteY > 0) { 729 | nextTop = prevScrollTop; 730 | } 731 | } else { 732 | if (menuPosAbsoluteY > 0) { 733 | nextSticky = true; 734 | } else if (menuPosAbsoluteY < minMenuY) { 735 | nextTop = prevScrollTop + minMenuY; 736 | } 737 | } 738 | if (nextSticky === true && stickyCache === false) { 739 | menu.classList.add("sticky"); 740 | stickyCache = true; 741 | } else if (nextSticky === false && stickyCache === true) { 742 | menu.classList.remove("sticky"); 743 | stickyCache = false; 744 | } 745 | if (nextTop !== null) { 746 | menu.style.top = nextTop + "px"; 747 | topCache = nextTop; 748 | } 749 | prevScrollTop = scrollTop; 750 | }, 751 | { passive: true }, 752 | ); 753 | })(); 754 | (function controlBorder() { 755 | menu.classList.remove("bordered"); 756 | document.addEventListener( 757 | "scroll", 758 | function () { 759 | if (menu.offsetTop === 0) { 760 | menu.classList.remove("bordered"); 761 | } else { 762 | menu.classList.add("bordered"); 763 | } 764 | }, 765 | { passive: true }, 766 | ); 767 | })(); 768 | })(); 769 | --------------------------------------------------------------------------------