diff --git a/.codespellrc b/.codespellrc new file mode 100644 index 0000000..2ea390c --- /dev/null +++ b/.codespellrc @@ -0,0 +1,3 @@ +[codespell] +exclude-file = .codespellx +ignore-words-list = "FPT,FTP,fpt,ftp" diff --git a/.codespellx b/.codespellx new file mode 100644 index 0000000..e69de29 diff --git a/.conform.yaml b/.conform.yaml new file mode 100644 index 0000000..f96e4e0 --- /dev/null +++ b/.conform.yaml @@ -0,0 +1,16 @@ +--- +policies: + - type: commit + spec: + header: + length: 80 + imperative: false + invalidLastCharacters: . + body: + required: false + dco: true + gpg: + required: true + spellcheck: + locale: US + maximumOfOneCommit: false diff --git a/.markdownlint.yaml b/.markdownlint.yaml new file mode 100644 index 0000000..a17a36b --- /dev/null +++ b/.markdownlint.yaml @@ -0,0 +1,196 @@ +--- +# Documentation: +# https://github.com/DavidAnson/markdownlint/blob/main/doc/Rules.md + +# Default state for all rules +default: false + +# MD001/heading-increment/header-increment - Heading levels should only increment by one level at a time +MD001: true + +# MD002/first-heading-h1/first-header-h1 - First heading should be a top-level heading +MD002: + # Heading level + level: 1 + +# MD003/heading-style/header-style - Heading style + +MD003: + # Heading style + # # ATX style H1 + style: "atx" + +# MD004/ul-style - Unordered list style +MD004: + # List style + style: "sublist" + +# MD005/list-indent - Inconsistent indentation for list items at the same level +MD005: true + +# MD006/ul-start-left - Consider starting bulleted lists at the beginning of the line +MD006: true + +# MD007/ul-indent - Unordered list indentation +MD007: + # Spaces for indent + indent: 4 + # Whether to indent the first level of the list + start_indented: false + +# MD009/no-trailing-spaces - Trailing spaces +MD009: + # Spaces for line break + br_spaces: 2 + # Allow spaces for empty lines in list items + list_item_empty_lines: false + # Include unnecessary breaks + strict: false + +# MD010/no-hard-tabs - Hard tabs +MD010: + # Include code blocks + code_blocks: false + # Number of spaces for each hard tab + spaces_per_tab: 1 + +# MD011/no-reversed-links - Reversed link syntax +MD011: true + +# MD012/no-multiple-blanks - Multiple consecutive blank lines +MD012: + # Consecutive blank lines + maximum: 1 +# MD013/line-length - Line length +# +MD013: + # Number of characters + line_length: 80 + # Number of characters for headings + heading_line_length: 80 + # Number of characters for code blocks + code_block_line_length: 160 + # Include code blocks + code_blocks: false + # Include tables + tables: false + # Include headings + headings: true + # Strict length checking (e.g. allow for longer URLs) + strict: false + # Stern length checking + stern: false + +# MD014/commands-show-output - Dollar signs used before commands without showing output +# TODO: set false for now but we should consider enabling it +# https://cirosantilli.com/markdown-style-guide#dollar-signs-in-shell-code +MD014: false + +# MD018/no-missing-space-atx - No space after hash on atx style heading +MD018: true + +# MD019/no-multiple-space-atx - Multiple spaces after hash on atx style heading +MD019: true + +# MD022/blanks-around-headings/blanks-around-headers - Headings should be surrounded by blank lines +MD022: + # Blank lines above heading + lines_above: 1 + # Blank lines below heading + lines_below: 1 + +# MD023/heading-start-left/header-start-left - Headings must start at the beginning of the line +MD023: true + +# MD025/single-title/single-h1 - Multiple top-level headings in the same document +# TODO: consider enabling it + +# MD026/no-trailing-punctuation - Trailing punctuation in heading +MD026: + # Punctuation characters + punctuation: ".,;:!。,;:!" + +# MD027/no-multiple-space-blockquote - Multiple spaces after blockquote symbol +MD027: true + +# MD028/no-blanks-blockquote - Blank line inside blockquote +MD028: true + +# MD029/ol-prefix - Ordered list item prefix +MD029: + # List style + style: "one_or_ordered" + +# MD030/list-marker-space - Spaces after list markers +MD030: + # Spaces for single-line unordered list items + ul_single: 1 + # Spaces for single-line ordered list items + ol_single: 1 + # Spaces for multi-line unordered list items + ul_multi: 1 + # Spaces for multi-line ordered list items + ol_multi: 1 + +# MD031/blanks-around-fences - Fenced code blocks should be surrounded by blank lines +MD031: + # Include list items + list_items: true + +# MD033/no-inline-html - Inline HTML +MD033: + # Allowed elements + allowed_elements: ["br", "center", "img", "script", "form", "input"] + +# MD034/no-bare-urls - Bare URL used +MD034: true + +# MD035/hr-style - Horizontal rule style +MD035: + # Horizontal rule style + style: "---" + +# MD037/no-space-in-emphasis - Spaces inside emphasis markers +MD037: true + +# MD038/no-space-in-code - Spaces inside code span elements +MD038: true + +# MD039/no-space-in-links - Spaces inside link text +MD039: true + +# MD040/fenced-code-language - Fenced code blocks should have a language specified +MD040: true + +# MD041/first-line-heading/first-line-h1 - First line in a file should be a top-level heading +MD041: + # Heading level + level: 1 + # RegExp for matching title in front matter + front_matter_title: "^\\s*title\\s*[:=]" + +# MD042/no-empty-links - No empty links +MD042: true + +# MD046/code-block-style - Code block style +MD046: + # Block style + style: "fenced" + +# MD047/single-trailing-newline - Files should end with a single newline character +MD047: true + +# MD048/code-fence-style - Code fence style +MD048: + # Code fence style + style: "backtick" + +# MD049/emphasis-style - Emphasis style should be consistent +MD049: + # Emphasis style should be consistent + style: "underscore" + +# MD050/strong-style - Strong style should be consistent +MD050: + # Strong style should be consistent + style: "asterisk" diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml new file mode 100644 index 0000000..fba945d --- /dev/null +++ b/.pre-commit-config.yaml @@ -0,0 +1,44 @@ +--- +default_stages: [pre-commit] + +default_install_hook_types: [pre-commit, commit-msg] + +ci: + autoupdate_commit_msg: 'pre-commit: autoupdate hooks' + autofix_prs: false + +repos: + - repo: https://github.com/pre-commit/pre-commit-hooks + rev: v4.5.0 + hooks: + - id: check-added-large-files + - id: check-merge-conflict + - id: check-symlinks + - id: detect-private-key + - id: end-of-file-fixer + - id: trailing-whitespace + - id: mixed-line-ending + + - repo: https://github.com/talos-systems/conform + rev: v0.1.0-alpha.27 + hooks: + - id: conform + stages: + - commit-msg + + - repo: https://github.com/codespell-project/codespell + rev: v2.2.6 + hooks: + - id: codespell + + - repo: https://github.com/igorshubovych/markdownlint-cli + rev: v0.37.0 + hooks: + - id: markdownlint + - id: markdownlint-fix + + - repo: https://github.com/koalaman/shellcheck-precommit + rev: v0.9.0 + hooks: + - id: shellcheck + args: ["--severity=warning"] diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000..2f16eb4 --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,3 @@ +{ + "search.useIgnoreFiles": true +} diff --git a/.yamllint b/.yamllint new file mode 100644 index 0000000..1a23bc1 --- /dev/null +++ b/.yamllint @@ -0,0 +1,16 @@ +--- +extends: default + +rules: + comments: + require-starting-space: true + ignore-shebangs: true + min-spaces-from-content: 2 + document-start: + present: true + level: error + indentation: + spaces: 2 + line-length: disable + truthy: + check-keys: false diff --git a/README.md b/README.md index b8ce10f..6de6430 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,38 @@ -# dcu -Dasharo Configuration Utility +# dcu - Dasharo Configuration Utility + +## Introduction + +The Dasharo Configuration Utility is a script designed to facilitate tasks such +as customizing the boot logo and setting unique UUIDs or Serial Numbers for +SMBIOS. This readme provides only the most basic information. For details +please refer to [our guide](https://docs.dasharo.com/guides/image-customization/) +. + +## Prerequisites + +Following packages must be installed: + +* `imagemagick` (for `convert` command) +* `util-linux` (for `uuidparse` command) +* [coreboot's +cbfstool](https://github.com/coreboot/coreboot/tree/master/util/cbfstool) + +## Usage + +```txt +Usage: dcu OPTIONS coreboot.rom + + coreboot.rom - Dasharo coreboot file to modify + + OPTIONS: + -u | --uuid - UUID in RFC4122 format to be set in SMBIOS type 1 structure + -s | --serial-number - Serial number to be set in SMBIOS type 1 and type 2 structure + -l | --logo - Custom logo in BMP/PNG/JPG/SVG format to be displayed on boot + + Examples: + ./dcu -u 96bcfa1a-42b4-6717-a44c-d8bbc18cbea4 -s D07229051 -l ~/logo.svg coreboot.rom + + ./dcu -u `dmidecode -s system-uuid` -s `dmidecode -s baseboard-serial-number` coreboot.rom + Above command will obtain the current SMBIOS UUID and Serial Number + from the system and patch the coreboot binary. +``` diff --git a/dcu b/dcu new file mode 100755 index 0000000..c9d377a --- /dev/null +++ b/dcu @@ -0,0 +1,211 @@ +#!/usr/bin/env bash + +POSITIONAL_ARGS=() + +echo "Dasharo Configuration Utility" +echo "" + +usage() { + echo "Usage: $0 OPTIONS coreboot.rom" + echo " coreboot.rom - coreboot file to modify" + echo "" + echo " OPTIONS:" + echo " -u | --uuid - UUID in RFC4122 format to be set in SMBIOS type 1 structure" + echo " -s | --serial-number - Serial number to be set in SMBIOS type 1 and type 2 structure" + echo " -l | --logo - Custom logo in BMP/PNG/JPG/SVG format to be displayed on boot" + echo "" + echo " Examples:" + echo " $0 -u 96bcfa1a-42b4-6717-a44c-d8bbc18cbea4 -s D07229051 coreboot.rom" + echo " $0 -u \`dmidecode -s system-uuid\` -s \`dmidecode -s baseboard-serial-number\` coreboot.rom" + echo " Above command will obtain the current SMBIOS UUID and Serial Number" + echo " from the system and patch the coreboot binary." +} + +set_uuid() { + echo "$CB_CONFIG" | grep -q "CONFIG_DRIVERS_GENERIC_CBFS_UUID=y" + if [[ $? -ne 0 ]]; then + echo "Configurable UUID not supported by the coreboot image" + exit 7 + fi + uuidparse "$SYSTEM_UUID" | grep -q "invalid" + if [[ $? -eq 0 ]]; then + echo "Invalid UUID format" + exit 8 + fi + echo "Setting System UUID to $1" + echo -n "$1" > /tmp/system_uuid + $CBFSTOOL $COREBOOT_ROM remove -n system_uuid -r COREBOOT > /dev/null 2> /dev/null + CBFSTOOL_ERR="$($CBFSTOOL $COREBOOT_ROM add -f /tmp/system_uuid -n system_uuid -t raw -r COREBOOT 2>&1)" + rm /tmp/system_uuid + echo "$CBFSTOOL_ERR" |grep -q "The image will be left unmodified" + if [[ $? -eq 0 ]]; then + echo "An error occurred when adding setting the UUID" + echo "cbfstool output:" + echo "$CBFSTOOL_ERR" + exit 9 + fi +} + +set_serial_number() { + echo "$CB_CONFIG" | grep -q "CONFIG_DRIVERS_GENERIC_CBFS_SERIAL=y" + if [[ $? -ne 0 ]]; then + echo "Configurable Serial Number not supported by the coreboot image" + exit 10 + fi + echo "Setting Serial Number to $1" + echo -n "$1" > /tmp/serial_number + $CBFSTOOL $COREBOOT_ROM remove -n serial_number -r COREBOOT > /dev/null 2> /dev/null + CBFSTOOL_ERR="$($CBFSTOOL $COREBOOT_ROM add -f /tmp/serial_number -n serial_number -t raw -r COREBOOT 2>&1)" + rm /tmp/serial_number + echo "$CBFSTOOL_ERR" |grep -q "The image will be left unmodified" + if [[ $? -eq 0 ]]; then + echo "An error occurred when adding setting the Serial Number" + echo "cbfstool output:" + echo "$CBFSTOOL_ERR" + exit 11 + fi +} + +set_logo() { + if [[ ! -f $1 ]]; then + echo "Logo file not found or invalid path." + exit 12 + fi + + file $1 | grep -qE 'PNG image|JPEG image|Scalable Vector Graphics image|PC bitmap' + if [[ $? -ne 0 ]]; then + echo "Invalid or unsupported logo file format" + echo "cbfstool output:" + echo "$CBFSTOOL_ERR" + exit 13 + fi + + $CBFSTOOL $COREBOOT_ROM layout -w | grep -q "BOOTSPLASH" + if [[ $? -ne 0 ]]; then + echo "Customizable logo not supported by the coreboot image" + exit 14 + fi + + echo "Setting $1 as custom logo" + convert -background None $1 BMP3:/tmp/logo.bmp + $CBFSTOOL $COREBOOT_ROM remove -n logo.bmp -r BOOTSPLASH > /dev/null 2> /dev/null + CBFSTOOL_ERR="$(cbfstool $COREBOOT_ROM add -f /tmp/logo.bmp -r BOOTSPLASH -n logo.bmp -t raw -c lzma 2>&1)" + rm /tmp/logo.bmp + + echo "$CBFSTOOL_ERR" |grep -q "too big" + if [[ $? -eq 0 ]]; then + echo "Logo file too big to fit in the coreboot image" + exit 15 + fi + + echo "$CBFSTOOL_ERR" |grep -q "The image will be left unmodified" + if [[ $? -eq 0 ]]; then + echo "An error occurred when adding the logo to coreboot image" + echo "cbfstool output:" + echo "$CBFSTOOL_ERR" + exit 16 + fi +} + + +if [[ $# -eq 0 ]]; then + usage + exit 0 +fi + +while [[ $# -gt 0 ]]; do + case $1 in + -u|--UUID) + SET_UUID=1 + SYSTEM_UUID="$2" + shift # past argument + shift # past value + + which uuidparse > /dev/null 2> /dev/null + if [[ $? -ne 0 ]]; then + echo "uuidparse not found. Please install util-linux package" + echo "ubuntu/debian: apt install util-linux" + echo "fedora: dnf install util-linux" + echo "redhat/centos: yum install util-linux" + exit 2 + fi + ;; + -s|--serial-number) + SET_SERIAL=1 + SERIAL_NUMBER="$2" + shift # past argument + shift # past value + ;; + -l|--logo) + SET_LOGO=1 + LOGO_FILE="$(readlink -f $2)" + shift # past argument + shift # past value + + which convert > /dev/null 2> /dev/null + if [[ $? -ne 0 ]]; then + echo "convert not found. Please install imagemagick package" + echo "ubuntu/debian: apt install imagemagick" + echo "fedora: dnf install imagemagick" + echo "redhat/centos: yum install imagemagick" + exit 3 + fi + ;; + -*) + echo "Unknown option $1" + exit 1 + ;; + *) + POSITIONAL_ARGS+=("$(readlink -f $1)") # save positional arg + shift # past argument + ;; + esac +done + +set -- "${POSITIONAL_ARGS[@]}" # restore positional parameters + +COREBOOT_ROM=${POSITIONAL_ARGS[0]} + +if [[ ! -f $COREBOOT_ROM ]]; then + echo "coreboot image not found or invalid path." + exit 4 +fi + +CBFSTOOL="${CBFSTOOL:-$PWD/cbfstool}" + +if [[ ! -f "$CBFSTOOL" ]]; then + CBFSTOOL=$(which cbfstool 2> /dev/null | head -n1 | cut -d " " -f1) + if [[ $? -ne 0 ]]; then + wget https://dl.3mdeb.com/open-source-firmware/utilities/cbfstool > /dev/null 2> /dev/null + if [[ $? -eq 0 ]]; then + CBFSTOOL="$PWD/cbfstool" + else + echo "cbfstool not found. Please obtain/compile cbfstool first" + exit 5 + fi + fi +fi + +$CBFSTOOL $COREBOOT_ROM extract -n config -r COREBOOT -f /tmp/cb_config > /dev/null 2> /dev/null +if [[ $? -ne 0 ]]; then + echo "Failed to extract coreboot configuration from the image" + exit 6 +fi + +CB_CONFIG="$(cat /tmp/cb_config)" +rm /tmp/cb_config + +echo "Will modify $COREBOOT_ROM" +echo "" + +if [[ $SET_UUID -eq 1 ]]; then + set_uuid "$SYSTEM_UUID" +fi + +if [[ $SET_SERIAL -eq 1 ]]; then + set_serial_number "$SERIAL_NUMBER" +fi + +if [[ $SET_LOGO -eq 1 ]]; then + set_logo "$LOGO_FILE" +fi