Compare commits

..
Author SHA1 Message Date
Tobias Waldekranz 964a4c755e [TEMP] save 2023-04-12 09:36:50 +02:00
Tobias Waldekranz 7eec8c2964 sysrest: Initial add
A RESTCONF front-end for sysrepo.
2023-04-05 17:00:01 +02:00
2201 changed files with 22929 additions and 166348 deletions
-41
View File
@@ -1,41 +0,0 @@
Checklists for Pull Requests and Releases
=========================================
Maintainer checklists for reviewing pull requests and doing releases.
Pull Requests
-------------
- If applicable, is there a readable ChangeLog entry?
- If any LICENSE file has been updated, has the `.hash` file been updated?
- If any change to a Finit `.svc` file, does any run/task linger?
I.e., is there a runlevel and/or condition defined to prevent them
from running outside of their intended runlevel?
- If any change to grub or qemu/qeneth setup, has it been tested in GNS3?
- If any change to u-boot/buildroot, has it been tested with `<booloader>_defconfig`
- If any change to logging, have the resulting logs been audited?
- Check for duplicate entries, misspellings
- Check for sneaky severity changes, e.g., error vs note, error vs warning
- If new subsystem, or major changes to a subsystem, have the docs been updated?
- If change to mDNS, has it been tested with netbrowse?
- If change to `_defconfig`, verify `local.mk` and sync with other archs
- Test manually as well, e.g., CLI changes do not have ha regression tests
- Build from distclean, or use artifacts built by build servers, for manual tests
Releases
--------
Recommended checkpoints, use at your own discretion:
- Make at least one -betaN release to verify the GitHub workflow well in time release day
- Stuff happens, remember kernelkit/infix#735
- Make at least one -rcN to flush out any issues in customer repos
- Easy to forget adaptations/hacks in customer repos -- may need Infix change/support
- Verify release artifacts (checksums, completeness, no corrupted files)
- Test on actual hardware for at least one architecture
- Review ChangeLog for completeness
- Check for release-blocking issues
- Verify generated GNS3 appliance, no marketplace update on -rc builds
- Ensure the markdown link for the release diff is updated
- Ensure subrepos are tagged (can be automated, see kernelkit/infix#393)
- Sync tags for all repo. sync activities
+53 -254
View File
@@ -1,279 +1,78 @@
Contributing Guidelines
=======================
Contributing to Infix
=====================
Thank :heart: you for taking the time to read this!
We welcome any and all help in the form of bug reports, fixes, patches
to add new features -- *preferably as GitHub pull requests*. Other
methods are of course also possible: emailing the [maintainers][] a
patch or even a raw file, a feature request or an alert of a problem.
We welcome any help in the form of bug reports, fixes, or patches to add
new features. We *prefer* GitHub pull requests, but are open to other
forms of collaboration as well. [Let's talk!][support] :handshake:
If you are unsure of what to do, or how to implement an idea or bugfix,
open an issue with `"[RFC: Unsure if this is a bug ... ?"`, or use the
GitHub discussions forum, so we can discuss it. Talking about the code
first is the best way to get started before submitting a pull request.
If you are unsure how to start implementing an idea or fix:
- :bug: open an issue, there are human friendly templates for _bugs_
and _feature requests_ at <https://github.com/kernelkit/infix/issues>
- :speech_balloon: use the [Q&A Forum][discuss]
- :technologist: The [Developer's Guide][devguide] is also a useful start
> [!IMPORTANT]
> Talking about code and problems first is often the best way to get
> started before submitting a pull request. We have found it always
> saves time, yours and ours.
:sparkles: General Guidelines
-----------------------------
When submitting bug reports or patches to bugs, please state which
version the change is made against, what it does, and, more importantly
*why* -- from your perspective, why is it a bug, why does the code need
changing in this way. Start with why.
- :bug: Bug reports need metadata like Infix version or commit hash
- :adhesive_bandage: Bug fixes also need version, and (preferably) a
corresponding issue number for the ChangeLog
- :new: New features, you need to get approval of the YANG model first!
:speech_balloon: Please use the [Forum][discuss], e.g., category:
*Ideas*, or open a :pray: feature request issue
- :white_check_mark: New features also need new regression tests, this
can be basic tests or more complex use-case tests comprising multiple
subsystems, see [Testing Changes](#test_tube-testing-changes), below
Either way, when sending an email, patch, or pull request, start by
stating the version the change is made against, what it does, and why.
Please take care to ensure you follow the project coding style and the
commit message format. If you follow these recommendations you help
the maintainers and make it easier for them to include your code.
the maintainer(s) and make it easier for them to include your code.
:woman_technologist: Coding Style
---------------------------------
Before jumping into code, remember to **document new features** and bug
fixes. Both the manual and ChangeLog are in the `doc/` sub-directory
and it is expected that you provide a human-readable summary for the
release notes (ChangeLog) and at least a configuration example in the
manual for new features.
Coding Style
------------
> [!TIP]
> Consider ["Readme driven development"][RDD] for new features. It is
> amazing how many flaws in your own bright ideas come to bare when you
> suddenly have to explain them to someone else!
> **Tip:** Always submit code that follows the style of surrounding code!
We expect code contributions for:
First of all, lines are allowed to be longer than 72 characters these
days. In fact, there exist no enforced maximum, but keeping it around
100 chars is OK.
- C code in [Linux Coding Style][Linux]
- Python code should follow [PEP-8][]
The coding style itself is otherwise strictly Linux [KNF][].
> [!IMPORTANT]
> **However,** always submit code that follows the style of surrounding
> code! Legacy takes precedence, and remember, we read code a lot more
> than write it, so legibility is important.
The ChangeLog deserves a separate mention:
- Releases are listed in reverse chronological order order, so the
latest/next release is at the beginning of the file
- Only *user-facing bugs and features* are detailed, so code refactor,
new tests, etc. are not listed.
- Add your changes/features to the Changes section
- Add your Fix line in the Fixes section, in numeric order
- Changes and fixes without an issue number are listed after all
numbered ones
- YANG model changes are documented in their respective model, for
standard models, e.g., for `ietf-interfaces.yang`, the corresponding
`infix-interfaces.yang` detail augments/deviations as revisions.
A final note, lines of code are allowed to be longer than 72 characters
these days, unless you live by PEP-8 (see above). There is no enforced
maximum, but the team usually keep it around 100 characters for both C
and Python.
:test_tube: Testing Changes
---------------------------
Please test your changes, no matter how trivial or obviously correct
they may seem. Nobody is infallible, making mistakes is only human.
It is also the best insurance policy for your feature, it ensures your
use-case will remain functional as the source base evolves.
For new functionality we expect new regression tests to be added in
the same pull request.
For help getting started with testing, see the following resources:
- [Developer's Guide][devguide]
- [Regression Testing][testing]
:memo: Commit Messages
----------------------
Commit Messages
---------------
Commit messages exist to track *why* a change was made. Try to be as
clear and concise as possible in your commit messages, and always, be
proud of your work and set up a proper GIT identity for your commits:
<img src="../doc/jack.png" width=70 align="right">
git config --global user.name "Jane Doe"
git config --global user.email jane.doe@example.com
```bash
$ git config --global user.name "Jacky Linker"
$ git config --global user.email jacky.linker@example.com
```
Example commit message from the [Pro Git][gitbook] online book, notice
how `git commit -s` is used to automatically add a `Signed-off-by`:
Example commit message from one of many [online guides][cbeams]. Use
`git commit -s` to automatically add a `Signed-off-by` for proof of
origin, see [DCO][] for more info.
Brief, but clear and concise summary of changes
More detailed explanatory text, if necessary. Wrap it to about 72
characters or so. In some contexts, the first line is treated as
the subject of an email and the rest of the text as the body. The
blank line separating the ummary from the body is critical (unless
you omit the body entirely); tools like rebase can get confused if
you run the two together.
Further paragraphs come after blank lines.
- Bullet points are okay, too
- Typically a hyphen or asterisk is used for the bullet, preceded
by a single space, with blank lines in between, but conventions
vary here
Signed-off-by: Jane Doe <jane.doe@example.com>
```text
subsystem: brief, but clear and concise summary of changes
More detailed explanatory text, if necessary. Wrap it to about 72
characters or so. In some contexts, the first line is treated as
the subject of an email and the rest of the text as the body. The
empty line separating summary from body is critical. Tools like
rebase can get confused if the empty line is missing.
Further paragraphs should be separated with empty lines.
- Bullet points are okay, too
- Typically a hyphen or asterisk is used for the bullet, preceded
by a single space, with blank lines in between, but conventions
vary here
If you use an issue tracker, put references to them at the bottom,
like this:
Resolves: #123
See also: #456, #789
Signed-off-by: Jacky Linker <jacky.linker@example.com>
```
This is an example of how to [automatically close][closing] an issue
when the commit is merged to mainline. Several keywords are available.
:lock_with_ink_pen: Signing Commits with GPG
---------------------------------------------
To ensure the authenticity and integrity of your contributions, we
**require** all commits to be signed with GPG. This cryptographically
verifies that commits come from a trusted source.
### Generating a GPG Key
If you don't already have a GPG key, generate one:
```bash
$ gpg --full-generate-key
```
When prompted, choose:
- Key type: `RSA and RSA` (default)
- Key size: `4096` bits (recommended for security)
- Expiration: `0` (key does not expire)
- Real name and email: Use the same email as your Git configuration
> [!NOTE]
> We recommend keys that do not expire for signing commits. Expiration
> creates a "usability time bomb" without providing meaningful security
> benefits for code signing. See [this article][pgpfan] for details.
### Configuring Git to Sign Commits
First, find your GPG key ID:
```bash
$ gpg --list-secret-keys --keyid-format=long
```
Look for the line starting with `sec`, the key ID is the part after the `/`.
For example, in `sec rsa4096/ABCD1234EFGH5678`, the key ID is `ABCD1234EFGH5678`.
Configure Git to use your GPG key:
```bash
$ git config --global user.signingkey ABCD1234EFGH5678
$ git config --global commit.gpgsign true
```
The second command enables automatic signing for all commits. Alternatively,
you can sign individual commits with `git commit -S`.
### Publishing Your Public Key
To allow others to verify your signatures, publish your public key to a
keyserver:
```bash
$ gpg --keyserver hkps://keys.openpgp.org --send-keys ABCD1234EFGH5678
```
> [!IMPORTANT]
> The keyserver will send a verification email to the address associated
> with your key. You **must** click the link in that email to confirm
> ownership before your key becomes searchable by email address.
Alternative keyservers you can use:
- `hkps://keyserver.ubuntu.com`
- `hkps://pgp.mit.edu`
### Adding Your GPG Key to GitHub
For GitHub to show your commits as "Verified", you need to add your public
key to your account:
1. Export your public key:
```bash
$ gpg --armor --export ABCD1234EFGH5678
```
2. Copy the entire output, including the `-----BEGIN PGP PUBLIC KEY BLOCK-----`
and `-----END PGP PUBLIC KEY BLOCK-----` lines.
3. Go to [GitHub Settings → SSH and GPG keys](https://github.com/settings/keys)
4. Click **New GPG key** and paste your public key.
Now your signed commits will display a "Verified" badge on GitHub! :white_check_mark:
For more details, see GitHub's [official documentation on commit signature verification][gpg-verify].
:twisted_rightwards_arrows: Pull Requests
-----------------------------------------
> [!NOTE]
> _The git repository is the canonical location for all information._
A pull request should preferably address a single issue or change. This
may of course include multiple related changes, but what is important to
remember is the bandwidth of the maintainers. A smaller well documented
PR is more likely to get attention quicker in some reviewer's busy day.
Well documented here means that each commit message stands on its own,
telling the complete story of the change. In fact each commit should,
as much as possible, be independent of other changes. This is very
important, not only when digging though logs to understand why a piece
of code exists, but also when bisecting a problem -- each single commit
should also compile and be possible to run.
If you've worked on projects that send patches, like the Linux kernel or
Buildroot, consider the pull request message body similar to the cover
letter for a series of patches -- it's a summary of changes, and it is
lost when the changes are merged to the mainline branch.
:balance_scale: Code of Conduct
-------------------------------
Code of Conduct
---------------
It is expected of everyone to respect the [Code of Conduct][conduct].
The *"maintainers have the right and responsibility to remove, edit, or
reject comments, commits, code, discussion forum threads, issues, and
other contributions that are not aligned to this Code of Conduct."*
The *"maintainers have the right and responsibility to remove, edit,
or reject comments, commits, code, wiki edits, issues, and other
contributions that are not aligned to this Code of Conduct."*
[support]: https://github.com/kernelkit/infix/blob/main/.github/SUPPORT.md
[discuss]: https://github.com/orgs/kernelkit/discussions
[testing]: https://github.com/kernelkit/infix/blob/main/doc/testing.md
[devguide]: https://github.com/kernelkit/infix/blob/main/doc/developers-guide.md
[Linux]: https://www.kernel.org/doc/html/v6.9/process/coding-style.html
[PEP-8]: https://peps.python.org/pep-0008/
[RDD]: https://tom.preston-werner.com/2010/08/23/readme-driven-development
[cbeams]: https://cbea.ms/git-commit/#seven-rules
[conduct]: CODE-OF-CONDUCT.md
[DCO]: https://developercertificate.org/
[closing]: https://docs.github.com/en/get-started/writing-on-github/working-with-advanced-formatting/using-keywords-in-issues-and-pull-requests
[gpg-verify]: https://docs.github.com/en/authentication/managing-commit-signature-verification
[pgpfan]: https://articles.59.ca/doku.php?id=pgpfan:expire
[1]: ../doc/MAINTAINERS
[KNF]: https://en.wikipedia.org/wiki/Kernel_Normal_Form
[gitbook]: https://git-scm.com/book/ch5-2.html
[conduct]: CODE-OF-CONDUCT.md
-69
View File
@@ -1,69 +0,0 @@
# https://docs.github.com/en/communities/using-templates-to-encourage-useful-issues-and-pull-requests/syntax-for-githubs-form-schema
name: "\U0001F41E Bug report"
description: Create a bug report
labels:
- "bug"
- "triage"
body:
- type: markdown
attributes:
value: |
**Thank :heart: you for taking the time to fill out this bug report!**
We kindly ask that you search to see if an issue [already exists](https://github.com/kernelkit/infix/issues?q=is%3Aissue+sort%3Acreated-desc+) for the bug you encountered.
- type: textarea
attributes:
label: Current Behavior
description: |
A clear and concise description of the issue you're experiencing.
value: |
For code snippets, logs, commands, etc., please use triple backticks:
```
admin@infix-c0-ff-ee:/> show log
May 15 07:21:02 infix-00-00-00 container[3192]: Failed creating container test from curios-httpd-v24.03.0
- (press h for help or q to quit)
```
validations:
required: true
- type: textarea
attributes:
label: Expected Behavior
description: |
A clear and concise description of what you expected to happen.
value: |
```
admin@infix-c0-ff-ee:/> show log
May 15 07:21:02 infix-c0-ff-ee container[3192]: Successfully created container test from curios-httpd-v24.03.0
- (press h for help or q to quit)
```
validations:
required: true
- type: textarea
attributes:
label: Steps To Reproduce
description: |
Steps to reproduce the issue. For example:
1. Built from source
2. Upgrade to latest release, vYY.MM.P
3. Factory reset
4. Enable feature
5. Check the logs/show command/operational status
validations:
required: false
- type: textarea
attributes:
label: Additional information
description: |
- Relevant parts of `startup-config`
- Output from `show interfaces`, if applicable
- Other observations, screenshots, log files ...
**Tip:** You can attach images or log files by clicking this area to highlight it and then dragging files in.
validations:
required: false
-7
View File
@@ -1,7 +0,0 @@
contact_links:
- name: "🔍 Look for my Issue"
url: https://github.com/kernelkit/infix/issues?q=is%3Aissue+sort%3Acreated-desc+
about: Thank ❤️ you for your time! We kindly ask that you first check if an issue already exists.
- name: "💬 Discussions and Q&A"
url: https://github.com/kernelkit/infix/discussions
about: Discussions are perfect for quick questions, bouncing ideas, and things that may be a bug.
@@ -1,45 +0,0 @@
# https://docs.github.com/en/communities/using-templates-to-encourage-useful-issues-and-pull-requests/syntax-for-githubs-form-schema
name: "\U0001F6E0 Feature request"
description: Suggest a new feature, idea or improvement of the OS
labels:
- "feature"
- "triage"
body:
- type: markdown
attributes:
value: |
**Thank :heart: you for taking the time to fill out this feature request!**
We kindly ask that you search to see if an issue [already exists](https://github.com/kernelkit/infix/issues?q=is%3Aissue+sort%3Acreated-desc+) for your feature. We are also happy to accept contributions from our users. For details see [CONTRIBUTING](https://github.com/kernelkit/infix/blob/master/.github/CONTRIBUTING.md).
- type: textarea
attributes:
label: Description
description: |
A clear and concise description of the problem or missing feature.
**Example:** *I'm always frustrated when [...]*, or *I'd like to see support for [...]*
validations:
required: true
- type: textarea
attributes:
label: Additional Information
description: |
Any other related information, e.g. existing YANG model(s), or possibly screenshots about the feature request here.
validations:
required: false
- type: textarea
attributes:
label: General Information
description: |
Appended to all feature requests for future readers.
value: |
Anyone can help out by [sponsoring][1] development of new features or [contributing][2] pull requests.
Please use this issue for discussions related to the feature.
[1]: https://github.com/kernelkit/infix/blob/main/.github/SUPPORT.md
[2]: https://github.com/kernelkit/infix/blob/main/.github/CONTRIBUTING.md
validations:
required: true
-26
View File
@@ -1,26 +0,0 @@
# Security Policy
## Reporting a Vulnerability
If you discover a security vulnerability in Infix, please use GitHub's built-in
[Report a Vulnerability](https://github.com/kernelkit/infix/security/advisories/new)
feature for a private and secure disclosure.
When reporting, include:
- A clear description of the vulnerability.
- Steps to reproduce the issue.
- Potential impact of the vulnerability.
## Supported Versions
We provide security updates only for the main branch.
Individual support contracts are provided by _Wires_. See
[Support](https://github.com/kernelkit/infix/blob/main/.github/SUPPORT.md)
for more information.
## Acknowledgments
We appreciate the efforts of the security community to help improve the security
of Infix. Thank you for your responsible disclosure.
-12
View File
@@ -1,12 +0,0 @@
Limited free support is only available using the online resources of the
project on GitHub, and Discord, see <https://github.com/kernelkit>:
&nbsp;&nbsp; :speech_balloon: <https://github.com/orgs/kernelkit/discussions>
&nbsp;&nbsp; :bug: <https://github.com/kernelkit/infix/issues>
Support contracts, development of new features, fast-tracking of reviews
and contributions, customer branding of Infix, and even customer specific
features for dedicated products is provided by _Wires_.
&nbsp;&nbsp; :globe_with_meridians: <https://www.wires.se>
&nbsp;&nbsp; :e-mail: <mailto:infix@wires.se>
-28
View File
@@ -1,28 +0,0 @@
## Description
<!--
-- A description of changes, detailing *why* changes are made.
-- Remember: assign a reviewer, or use @mentions if org. member.
-->
## Checklist
Tick *relevant* boxes, this PR is-a or has-a:
- [ ] Bugfix
- [ ] Regression tests
- [ ] ChangeLog updates (for next release)
- [ ] Feature
- [ ] YANG model change => revision updated?
- [ ] Regression tests added?
- [ ] ChangeLog updates (for next release)
- [ ] Documentation added?
- [ ] Test changes
- [ ] Checked in changed Readme.adoc (make test-spec)
- [ ] Added new test to group Readme.adoc and yaml file
- [ ] Code style update (formatting, renaming)
- [ ] Refactoring (please detail in commit messages)
- [ ] Build related changes
- [ ] Documentation content changes
- [ ] ChangeLog updated (for major changes)
- [ ] Other (please describe):
@@ -1,16 +0,0 @@
name: Adds all issues to project Infix & C:o
on:
issues:
types:
- opened
jobs:
add-to-project:
name: Add issue to project Infix&co
runs-on: ubuntu-latest
steps:
- uses: actions/add-to-project@v1.0.2
with:
project-url: https://github.com/orgs/kernelkit/projects/3
github-token: ${{ secrets.ADD_TO_PROJECT }}
-215
View File
@@ -1,215 +0,0 @@
name: bitSign Infix Release
on:
workflow_dispatch:
inputs:
release_version:
description: 'Release version (e.g., v25.08.0)'
required: true
type: string
push:
branches: [ sign-with-bitsign ]
jobs:
sign-infix-release:
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Validate release version format
id: validate
run: |
# Use default version for push events, input version for manual dispatch
if [ "${{ github.event_name }}" = "push" ]; then
VERSION="v25.08.0"
echo "Using default version for push trigger: $VERSION"
else
VERSION="${{ inputs.release_version }}"
echo "Using input version for manual trigger: $VERSION"
fi
# Check if version starts with 'v' and has proper format
if ! echo "$VERSION" | grep -qE '^v[0-9]+\.[0-9]+(\.[0-9]+)?(-alpha[0-9]*|-beta[0-9]*|-rc[0-9]*)?$'; then
echo "❌ Invalid version format. Expected format: vYY.MM(.PP)(-alphaN|-betaN|-rcN)"
echo "Examples: v25.08.0, v25.08.0-alpha1, v25.08.0-rc1"
exit 1
fi
# Extract version without 'v' prefix for filename
FILE_VERSION="${VERSION#v}"
FILENAME="infix-x86_64-${FILE_VERSION}.tar.gz"
RELEASE_URL="https://github.com/kernelkit/infix/releases/download/${VERSION}/${FILENAME}"
echo "✅ Version format valid"
echo "file_version=${FILE_VERSION}" >> $GITHUB_OUTPUT
echo "filename=${FILENAME}" >> $GITHUB_OUTPUT
echo "release_url=${RELEASE_URL}" >> $GITHUB_OUTPUT
- name: Download Infix release
run: |
RELEASE_URL="${{ steps.validate.outputs.release_url }}"
FILENAME="${{ steps.validate.outputs.filename }}"
echo "Downloading Infix release: $FILENAME"
echo "From: $RELEASE_URL"
if ! curl -L "$RELEASE_URL" -o "$FILENAME" --fail --show-error --progress-bar; then
echo "❌ Failed to download release file from: $RELEASE_URL"
echo "Please verify that the release version exists and contains the x86_64 build."
echo "You can check available releases at: https://github.com/kernelkit/infix/releases"
exit 1
fi
# Verify download
if [ -f "$FILENAME" ] && [ -s "$FILENAME" ]; then
FILE_SIZE=$(ls -lh "$FILENAME" | awk '{print $5}')
echo "✅ Successfully downloaded: $FILENAME ($FILE_SIZE)"
else
echo "❌ Failed to download release file"
exit 1
fi
- name: Create signing request
id: create_request
run: |
FILENAME="${{ steps.validate.outputs.filename }}"
FILE_VERSION="${{ steps.validate.outputs.file_version }}"
RELEASE="infix-x86_64-${FILE_VERSION}"
echo "Creating signing request for $FILENAME..."
echo "RELEASE parameter: $RELEASE"
# Create signing request using bitSign API
RESPONSE=$(curl -s -X POST "https://portal.bitsign.se/api/v1/requests" \
-H "Authorization: Bearer ${{ secrets.BITSIGN_API_KEY }}" \
-F "file=@$FILENAME" \
-F "key=bit42-Demo1" \
-F "job=Infix-x86" \
-F "parameters={\"RELEASE\": \"$RELEASE\"}")
echo "API Response: $RESPONSE"
# Check if request was successful
if echo "$RESPONSE" | jq -e '.success == true' > /dev/null; then
REQUEST_ID=$(echo "$RESPONSE" | jq -r '.requestId')
echo "✅ Request created successfully with ID: $REQUEST_ID"
echo "request_id=$REQUEST_ID" >> $GITHUB_OUTPUT
else
echo "❌ Failed to create signing request"
echo "$RESPONSE" | jq -r '.error // .message // "Unknown error"'
exit 1
fi
- name: Wait for signing completion
id: wait_completion
run: |
REQUEST_ID="${{ steps.create_request.outputs.request_id }}"
echo "Waiting for signing completion for request: $REQUEST_ID"
# Poll status for up to 10 minutes (600 seconds) - longer timeout for larger files
MAX_WAIT=600
WAITED=0
while [ $WAITED -lt $MAX_WAIT ]; do
RESPONSE=$(curl -s -X GET "https://portal.bitsign.se/api/v1/requests/$REQUEST_ID/status" \
-H "Authorization: Bearer ${{ secrets.BITSIGN_API_KEY }}")
STATUS=$(echo "$RESPONSE" | jq -r '.status')
echo "Current status: $STATUS (waited ${WAITED}s)"
if [ "$STATUS" = "completed" ]; then
echo "✅ Signing completed successfully!"
break
elif [ "$STATUS" = "failed" ]; then
echo "❌ Signing failed"
echo "$RESPONSE" | jq -r '.error // .message // "Unknown error"'
exit 1
fi
sleep 10
WAITED=$((WAITED + 10))
done
if [ $WAITED -ge $MAX_WAIT ]; then
echo "❌ Timeout: Signing did not complete within ${MAX_WAIT} seconds"
exit 1
fi
- name: Download signed file
id: download_signed
run: |
REQUEST_ID="${{ steps.create_request.outputs.request_id }}"
FILENAME="${{ steps.validate.outputs.filename }}"
FILE_VERSION="${{ steps.validate.outputs.file_version }}"
SIGNED_FILENAME="infix-x86_64-${FILE_VERSION}-signed.tar.gz"
echo "Downloading signed file for request: $REQUEST_ID"
echo "Expected signed filename: $SIGNED_FILENAME"
# Download the signed file
curl -X GET "https://portal.bitsign.se/api/v1/requests/$REQUEST_ID/download" \
-H "Authorization: Bearer ${{ secrets.BITSIGN_API_KEY }}" \
-o "$SIGNED_FILENAME" \
--fail --show-error
if [ -f "$SIGNED_FILENAME" ] && [ -s "$SIGNED_FILENAME" ]; then
FILE_SIZE=$(ls -lh "$SIGNED_FILENAME" | awk '{print $5}')
echo "Successfully downloaded signed file: $SIGNED_FILENAME ($FILE_SIZE)"
echo "signed_filename=$SIGNED_FILENAME" >> $GITHUB_OUTPUT
# Calculate SHA256 checksums for both files
ORIGINAL_SHA256=$(sha256sum "$FILENAME" | cut -d' ' -f1)
SIGNED_SHA256=$(sha256sum "$SIGNED_FILENAME" | cut -d' ' -f1)
echo "original_sha256=$ORIGINAL_SHA256" >> $GITHUB_OUTPUT
echo "signed_sha256=$SIGNED_SHA256" >> $GITHUB_OUTPUT
else
echo "Failed to download signed file"
exit 1
fi
- name: Upload signed artifacts
uses: actions/upload-artifact@v4
with:
name: signed-infix-${{ steps.validate.outputs.file_version }}
path: ${{ steps.download_signed.outputs.signed_filename }}
retention-days: 90
- name: Summary
run: |
# Determine the actual version used (could be from push or input)
if [ "${{ github.event_name }}" = "push" ]; then
ACTUAL_VERSION="v25.08.0"
else
ACTUAL_VERSION="${{ inputs.release_version }}"
fi
cat >> $GITHUB_STEP_SUMMARY << EOF
# bitSign Infix Release Signing Complete
The Infix release has been successfully signed using the bitSign API.
## Signing Details
| Property | Value |
|----------|-------|
| 📦 **Original File** | \`${{ steps.validate.outputs.filename }}\` (\`${{ steps.download_signed.outputs.original_sha256 }}\`) |
| ✍️ **Signed File** | \`${{ steps.download_signed.outputs.signed_filename }}\` (\`${{ steps.download_signed.outputs.signed_sha256 }}\`) |
| 🔑 **Signing Key** | \`bit42-Demo1\` |
| ⚙️ **Job Type** | \`Infix-x86\` |
| 🆔 **Request ID** | \`${{ steps.create_request.outputs.request_id }}\` |
| 📋 **Release Version** | \`\$ACTUAL_VERSION\` |
| 🌐 **API Endpoint** | \`portal.bitsign.se\` |
## Download Files
> **The signed release file is available as a workflow artifact:**
> **\`signed-infix-${{ steps.validate.outputs.file_version }}\`**
>
> The artifact contains the signed file: \`${{ steps.download_signed.outputs.signed_filename }}\`
---
**Next Steps:** The signed release can now be distributed with cryptographic verification of authenticity.
EOF
-146
View File
@@ -1,146 +0,0 @@
name: Build Bootloaders
on:
workflow_dispatch:
inputs:
branch:
description: 'Branch to build from'
default: 'main'
type: string
jobs:
build:
name: Build ${{ matrix.defconfig }}
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
defconfig:
- aarch64_qemu_boot
- bpi_r3_sd_boot
- bpi_r3_emmc_boot
- cn9130_crb_boot
- fireant_boot
- nanopi_r2s_boot
- rpi64_boot
env:
MAKEFLAGS: -j5
steps:
- name: Cleanup Build Folder
run: |
ls -la ./
rm -rf ./* || true
rm -rf ./.??* || true
ls -la ./
- name: Checkout infix repo
uses: actions/checkout@v4
with:
ref: ${{ github.event_name == 'workflow_dispatch' && github.event.inputs.branch || github.ref }}
clean: true
fetch-depth: 0
submodules: recursive
- name: Set Build Variables
id: vars
run: |
defconfig=${{ matrix.defconfig }}
version=$(awk -F'"' '/BR2_TARGET_UBOOT_CUSTOM_VERSION_VALUE=/ {print $2}' configs/${defconfig}_defconfig)
version=${version:-git}
filename=$(echo "${defconfig}" | tr '_' '-')
# TODO: Replace hardcoded rev with actual revision stepping
rev="latest"
archive="${filename}-${version}-${rev}.tar.gz"
dirname="${filename}-${version}-${rev}"
echo "defconfig=${defconfig}" >> $GITHUB_OUTPUT
echo "version=${version}" >> $GITHUB_OUTPUT
echo "rev=${rev}" >> $GITHUB_OUTPUT
echo "archive=${archive}" >> $GITHUB_OUTPUT
echo "dirname=${dirname}" >> $GITHUB_OUTPUT
echo "Building ${defconfig}_defconfig, version ${version}-${rev}, artifact ${archive} ..."
- name: Restore Cache of dl/
uses: actions/cache@v4
with:
path: dl/
key: dl-boot-${{ hashFiles('.git/modules/buildroot/HEAD', 'configs/*', 'package/*/*.hash') }}
restore-keys: |
dl-boot-
dl-
- name: Restore Cache of .ccache/
uses: actions/cache@v4
with:
path: .ccache/
key: ccache-boot-${{ matrix.defconfig }}-${{ hashFiles('.git/modules/buildroot/HEAD', 'package/*/*.hash') }}
restore-keys: |
ccache-boot-${{ matrix.defconfig }}-
ccache-boot-
ccache-
- name: Configure ${{ matrix.defconfig }}_defconfig
run: |
make ${{ matrix.defconfig }}_defconfig
- name: Build ${{ matrix.defconfig }}_defconfig
run: |
echo "Building ${{ matrix.defconfig }}_defconfig ..."
make -j$((`getconf _NPROCESSORS_ONLN` / 2 + 2))
- name: Resulting size of build
run: |
printf "Size of output/images/: "
ls -l output/images/
- name: Prepare ${{ matrix.defconfig }} Artifact
run: |
cd output/
mv images ${{ steps.vars.outputs.dirname }}
tar cfz ${{ steps.vars.outputs.archive }} ${{ steps.vars.outputs.dirname }}/
- uses: actions/upload-artifact@v4
with:
path: output/${{ steps.vars.outputs.archive }}
name: artifact-${{ matrix.defconfig }}
publish:
name: Upload Bootloader Artifacts
runs-on: ubuntu-latest
needs: build
permissions:
contents: write
steps:
- uses: actions/download-artifact@v4
with:
pattern: "artifact-*"
merge-multiple: true
- name: Create checksums ...
run: |
for file in *.tar.gz; do
sha256sum $file > $file.sha256
done
- uses: ncipollo/release-action@v1
with:
allowUpdates: true
omitName: true
omitBody: true
omitBodyDuringUpdate: true
prerelease: true
tag: "latest-boot"
token: ${{ secrets.GITHUB_TOKEN }}
artifacts: "*.tar.gz*"
- name: Summary
run: |
cat <<EOF >> $GITHUB_STEP_SUMMARY
# Bootloader Build Complete! :rocket:
For the public download links of these bootloader artifacts, please see:
<https://github.com/kernelkit/infix/releases/tag/latest-boot>
EOF
-376
View File
@@ -1,376 +0,0 @@
name: Create SD Card & eMMC Images
on:
workflow_dispatch:
inputs:
board:
description: 'Board to create image for'
type: choice
required: true
options:
- raspberrypi-rpi64
- bananapi-bpi-r3
- friendlyarm-nanopi-r2s
default: 'raspberrypi-rpi64'
use_latest_release:
description: 'Use latest release artifacts instead of workflow artifacts'
type: boolean
default: false
jobs:
create-image:
name: Create SD Card Image for ${{ inputs.board }}
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v4
with:
clean: true
fetch-depth: 0
submodules: recursive
- name: Install dependencies
run: |
sudo apt-get update
sudo apt-get install -y \
genimage \
u-boot-tools \
parted \
gdisk \
qemu-utils \
dosfstools \
e2fsprogs \
genext2fs \
mtools \
jq
- name: Prepare build environment
run: |
# Set up directory structure similar to buildroot build
mkdir -p output/images
mkdir -p build
- name: Set bootloader and target based on board
run: |
case "${{ inputs.board }}" in
raspberrypi-rpi64)
echo "BOOTLOADER=rpi64_boot" >> $GITHUB_ENV
echo "TARGET=aarch64" >> $GITHUB_ENV
echo "BUILD_EMMC=false" >> $GITHUB_ENV
;;
bananapi-bpi-r3)
echo "BOOTLOADER_SD=bpi_r3_sd_boot" >> $GITHUB_ENV
echo "BOOTLOADER_EMMC=bpi_r3_emmc_boot" >> $GITHUB_ENV
echo "TARGET=aarch64" >> $GITHUB_ENV
echo "BUILD_EMMC=true" >> $GITHUB_ENV
;;
friendlyarm-nanopi-r2s)
echo "BOOTLOADER=nanopi_r2s_boot" >> $GITHUB_ENV
echo "TARGET=aarch64" >> $GITHUB_ENV
echo "BUILD_EMMC=false" >> $GITHUB_ENV
;;
*)
echo "Error: Unknown board ${{ inputs.board }}"
exit 1
;;
esac
echo "Target: $TARGET for board: ${{ inputs.board }}"
if [ "$BUILD_EMMC" = "true" ]; then
echo "Building both SD and eMMC images"
echo "SD Bootloader: $BOOTLOADER_SD"
echo "eMMC Bootloader: $BOOTLOADER_EMMC"
else
echo "Building SD image only"
echo "Bootloader: $BOOTLOADER"
fi
- name: Download bootloader artifacts
if: ${{ !inputs.use_latest_release }}
run: |
# Download from latest bootloader build workflow on main branch
gh run list --workflow=build-boot.yml --branch=main --limit=1 --status=success --json databaseId --jq '.[0].databaseId' > latest_boot_run_id
BOOT_RUN_ID=$(cat latest_boot_run_id)
if [ "$BUILD_EMMC" = "true" ]; then
# Download both SD and eMMC bootloaders for boards that support both
echo "Downloading SD bootloader: ${BOOTLOADER_SD}"
gh run download ${BOOT_RUN_ID} --name artifact-${BOOTLOADER_SD} --dir temp_bootloader_sd/
mkdir -p output_sd/images
cd temp_bootloader_sd/
tar -xzf *.tar.gz --strip-components=1 -C ../output_sd/images/
cd ../
rm -rf temp_bootloader_sd/
echo "Downloading eMMC bootloader: ${BOOTLOADER_EMMC}"
gh run download ${BOOT_RUN_ID} --name artifact-${BOOTLOADER_EMMC} --dir temp_bootloader_emmc/
mkdir -p output_emmc/images
cd temp_bootloader_emmc/
tar -xzf *.tar.gz --strip-components=1 -C ../output_emmc/images/
cd ../
rm -rf temp_bootloader_emmc/
echo "SD bootloader files:"
ls -la output_sd/images/
echo "eMMC bootloader files:"
ls -la output_emmc/images/
else
# Single bootloader for boards that only support SD
gh run download ${BOOT_RUN_ID} --name artifact-${BOOTLOADER} --dir temp_bootloader/
# Extract bootloader directly to output/images
cd temp_bootloader/
tar -xzf *.tar.gz --strip-components=1 -C ../output/images/
cd ../
rm -rf temp_bootloader/
echo "Bootloader files extracted to output/images:"
ls -la output/images/
fi
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: Download Infix artifacts
if: ${{ !inputs.use_latest_release }}
run: |
# Download from latest Kernelkit Trigger workflow for main branch
gh run list --workflow=164295764 --branch=main --limit=1 --status=success --json databaseId --jq '.[0].databaseId' > latest_infix_run_id
INFIX_RUN_ID=$(cat latest_infix_run_id)
if [ "$BUILD_EMMC" = "true" ]; then
# Copy Infix artifacts to both SD and eMMC output directories
gh run download ${INFIX_RUN_ID} --name artifact-${TARGET} --dir temp_infix/
cd temp_infix/
tar -xzf *.tar.gz --strip-components=1 -C ../output_sd/images/
tar -xzf *.tar.gz --strip-components=1 -C ../output_emmc/images/
cd ../
rm -rf temp_infix/
echo "Infix files extracted to output_sd/images:"
ls -la output_sd/images/
echo "Infix files extracted to output_emmc/images:"
ls -la output_emmc/images/
else
# Single output directory for SD-only boards
gh run download ${INFIX_RUN_ID} --name artifact-${TARGET} --dir temp_infix/
# Extract Infix directly to output/images
cd temp_infix/
tar -xzf *.tar.gz --strip-components=1 -C ../output/images/
cd ../
rm -rf temp_infix/
echo "Infix files extracted to output/images:"
ls -la output/images/
fi
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: Download from latest releases
if: ${{ inputs.use_latest_release }}
run: |
if [ "$BUILD_EMMC" = "true" ]; then
# Download both SD and eMMC bootloaders
gh release download latest-boot --pattern "*${BOOTLOADER_SD}*" --dir temp_bootloader_sd/
mkdir -p output_sd/images
cd temp_bootloader_sd/
tar -xzf *.tar.gz --strip-components=1 -C ../output_sd/images/
cd ../
rm -rf temp_bootloader_sd/
gh release download latest-boot --pattern "*${BOOTLOADER_EMMC}*" --dir temp_bootloader_emmc/
mkdir -p output_emmc/images
cd temp_bootloader_emmc/
tar -xzf *.tar.gz --strip-components=1 -C ../output_emmc/images/
cd ../
rm -rf temp_bootloader_emmc/
# Download Infix once and extract to both directories
gh release download latest --pattern "*${TARGET}*" --dir temp_infix/
cd temp_infix/
tar -xzf *.tar.gz --strip-components=1 -C ../output_sd/images/
tar -xzf *.tar.gz --strip-components=1 -C ../output_emmc/images/
cd ../
rm -rf temp_infix/
echo "SD files extracted to output_sd/images:"
ls -la output_sd/images/
echo "eMMC files extracted to output_emmc/images:"
ls -la output_emmc/images/
else
# Download latest bootloader release
gh release download latest-boot --pattern "*${BOOTLOADER}*" --dir temp_bootloader/
cd temp_bootloader/
tar -xzf *.tar.gz --strip-components=1 -C ../output/images/
cd ../
rm -rf temp_bootloader/
# Download latest Infix release
gh release download latest --pattern "*${TARGET}*" --dir temp_infix/
cd temp_infix/
tar -xzf *.tar.gz --strip-components=1 -C ../output/images/
cd ../
rm -rf temp_infix/
echo "All files extracted to output/images:"
ls -la output/images/
fi
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: Verify extracted files
run: |
if [ "$BUILD_EMMC" = "true" ]; then
echo "Files available for SD image:"
ls -la output_sd/images/
echo ""
echo "Files available for eMMC image:"
ls -la output_emmc/images/
else
echo "Files available for mkimage.sh:"
ls -la output/images/
echo ""
echo "File types:"
file output/images/* || true
fi
- name: Create SD card image
run: |
if [ "$BUILD_EMMC" = "true" ]; then
export BINARIES_DIR=$PWD/output_sd/images
export BUILD_DIR=$PWD/build
export BR2_EXTERNAL_INFIX_PATH=$PWD
export RELEASE=""
export INFIX_ID="infix"
./utils/mkimage.sh -t sdcard ${{ inputs.board }}
else
export BINARIES_DIR=$PWD/output/images
export BUILD_DIR=$PWD/build
export BR2_EXTERNAL_INFIX_PATH=$PWD
export RELEASE=""
export INFIX_ID="infix"
./utils/mkimage.sh ${{ inputs.board }}
fi
- name: Create eMMC image
if: ${{ env.BUILD_EMMC == 'true' }}
run: |
export BINARIES_DIR=$PWD/output_emmc/images
export BUILD_DIR=$PWD/build
export BR2_EXTERNAL_INFIX_PATH=$PWD
export RELEASE=""
export INFIX_ID="infix"
./utils/mkimage.sh -t emmc ${{ inputs.board }}
- name: Verify created images
run: |
if [ "$BUILD_EMMC" = "true" ]; then
echo "SD card image:"
ls -lh output_sd/images/*-sdcard.img* 2>/dev/null || true
if ls output_sd/images/*-sdcard.img 1> /dev/null 2>&1; then
for img in output_sd/images/*-sdcard.img; do
echo "- $(basename $img)"
file "$img"
fdisk -l "$img" 2>/dev/null | head -20
done
fi
echo ""
echo "eMMC image:"
ls -lh output_emmc/images/*-emmc.img* 2>/dev/null || true
if ls output_emmc/images/*-emmc.img 1> /dev/null 2>&1; then
for img in output_emmc/images/*-emmc.img; do
echo "- $(basename $img)"
file "$img"
fdisk -l "$img" 2>/dev/null | head -20
done
fi
# Copy both images to output/images for artifact upload
mkdir -p output/images
cp output_sd/images/*-sdcard.img* output/images/ 2>/dev/null || true
cp output_emmc/images/*-emmc.img* output/images/ 2>/dev/null || true
else
echo "Contents of output/images after mkimage.sh:"
ls -lh output/images/
# Look for SD card image with pattern: *-sdcard.img
if ls output/images/*-sdcard.img 1> /dev/null 2>&1; then
echo "Found SD card image(s):"
for img in output/images/*-sdcard.img; do
echo "- $(basename $img)"
file "$img"
fdisk -l "$img" 2>/dev/null || true
done
else
echo "No SD card image found matching pattern: *-sdcard.img"
echo "Available files:"
ls -la output/images/
exit 1
fi
fi
- name: Upload images as artifacts
uses: actions/upload-artifact@v4
with:
name: images-${{ inputs.board }}
path: |
output/images/*-sdcard.img*
output/images/*-emmc.img*
retention-days: 30
- name: Create checksums
run: |
cd output/images/
for file in *-sdcard.img *-emmc.img; do
if [ -f "$file" ]; then
sha256sum "$file" > "$file.sha256"
fi
done
- name: Upload to release
uses: ncipollo/release-action@v1
with:
allowUpdates: true
omitName: true
omitBody: true
omitBodyDuringUpdate: true
prerelease: true
tag: "latest-boot"
token: ${{ secrets.GITHUB_TOKEN }}
artifacts: "output/images/*-sdcard.img*,output/images/*-emmc.img*"
- name: Generate summary
run: |
if [ "$BUILD_EMMC" = "true" ]; then
cat <<EOF >> $GITHUB_STEP_SUMMARY
# SD Card & eMMC Image Build Complete! 🚀
**Board:** ${{ inputs.board }}
**Target:** ${{ env.TARGET }}
**SD Bootloader:** ${{ env.BOOTLOADER_SD }}
**eMMC Bootloader:** ${{ env.BOOTLOADER_EMMC }}
**Artifact Source:** ${{ inputs.use_latest_release && 'Latest Release' || 'Latest Workflow Run' }}
## Created Images
$(find output/images/ -name "*.img" -o -name "*.img.bmap" | xargs ls -lh 2>/dev/null | awk '{print "- " $9 " (" $5 ")"}' || echo "- No images found")
## Download
Both SD card and eMMC images are available as workflow artifacts above and in the latest-boot release.
EOF
else
cat <<EOF >> $GITHUB_STEP_SUMMARY
# SD Card Image Build Complete! 🚀
**Board:** ${{ inputs.board }}
**Target:** ${{ env.TARGET }}
**Bootloader:** ${{ env.BOOTLOADER }}
**Artifact Source:** ${{ inputs.use_latest_release && 'Latest Release' || 'Latest Workflow Run' }}
## Created Images
$(find output/images/ -name "*.img" -o -name "*.img.bmap" | xargs ls -lh 2>/dev/null | awk '{print "- " $9 " (" $5 ")"}' || echo "- No images found")
## Download
The SD card image is available as a workflow artifact above.
EOF
fi
-119
View File
@@ -1,119 +0,0 @@
# Needed for make pkg-stats
# sudo apt install python3-aiohttp
---
name: Build Release
on:
workflow_call:
inputs:
version:
required: true
type: string
use_cache:
required: false
type: boolean
default: true
jobs:
build:
name: Build Infix ${{ inputs.version }} [${{ matrix.target }}]
runs-on: [self-hosted, release]
strategy:
matrix:
target: [aarch64, x86_64]
fail-fast: false
steps:
- name: Cleanup podman state
run: |
set -x
podman ps -a || true
podman stop -a || true
podman rm -a -f || true
podman volume prune -f || true
podman system prune -a -f || true
podman system migrate || true
- uses: actions/checkout@v4
with:
clean: true
submodules: recursive
- name: Set Release Variables
id: vars
run: |
ver=${{ inputs.version }}
echo "ver=${ver}" >> $GITHUB_OUTPUT
fver=${ver#v}
target=${{ matrix.target }}-${fver}
echo "dir=infix-$target" >> $GITHUB_OUTPUT
echo "tgz=infix-$target.tar.gz" >> $GITHUB_OUTPUT
- name: Restore Cache of dl/
if: ${{ inputs.use_cache }}
uses: actions/cache@v4
with:
path: dl/
key: dl-${{ hashFiles('.git/modules/buildroot/HEAD', 'configs/*', 'package/*/*.hash') }}
restore-keys: |
dl-
- name: Restore Cache of .ccache/
if: ${{ inputs.use_cache }}
uses: actions/cache@v4
with:
path: .ccache/
key: ccache-${{ matrix.target }}-${{ hashFiles('.git/modules/buildroot/HEAD', 'package/*/*.hash') }}
restore-keys: |
ccache-${{ matrix.target }}-
ccache-
- name: Configure & Build
env:
INFIX_RELEASE: ${{ steps.vars.outputs.ver }}
run: |
target=${{ matrix.target }}_defconfig
echo "Building $target ..."
make $target
make
- name: Generate SBOM from Build
run: |
# Generate manifest files in CSV format for CycloneDX
make legal-info
# Generate cpe.json for CycloneDX
make -s show-info > output/cpe.json
# Generate pkg-stats.{json,html} for humans
make pkg-stats
- name: Build test specification
run: |
make test-spec
- name: Prepare Artifacts
run: |
cd output/
# Collect relevant files for SBOM and CPE info. for more info, see:
# https://github.com/CycloneDX/cyclonedx-buildroot
mkdir images/sbom
mv pkg-stats.* images/sbom/
mv cpe.json images/sbom/
mv legal-info/*.csv images/sbom/
# Remove rootfs.squashfs from release (can be extracted from rootfs.itb)
# Saves ~131MB per architecture. See issue #858
rm -f images/rootfs.squashfs
mv images ${{ steps.vars.outputs.dir }}
ln -s ${{ steps.vars.outputs.dir }} images
tar cfz ${{ steps.vars.outputs.tgz }} ${{ steps.vars.outputs.dir }}
- uses: actions/upload-artifact@v4
with:
name: artifact-${{ matrix.target }}
path: output/*.tar.gz
- uses: actions/upload-artifact@v4
with:
name: artifact-disk-image-${{ matrix.target }}
path: output/images/*.qcow2
+53 -182
View File
@@ -1,208 +1,79 @@
name: Build
name: Bob the Builder
#on:
# push:
# branches:
# - '*'
# pull_request:
# branches:
# - '*'
on:
pull_request:
workflow_dispatch:
inputs:
target:
description: "Build target (e.g. aarch64 or aarch64_minimal)"
default: "x86_64"
type: string
parallel:
description: 'Massive parallel build of each image'
default: true
type: boolean
name:
description: "Name (for spin overrides)"
default: "infix"
type: string
infix_repo:
description: 'Repo to checkout (for spin overrides)'
default: kernelkit/infix
type: string
infix_branch:
description: 'Branch/tag/commit to checkout (for spin overrides)'
default: ''
type: string
workflow_call:
inputs:
target:
required: true
type: string
name:
required: true
type: string
infix_repo:
required: false
type: string
default: kernelkit/infix
infix_branch:
required: false
type: string
default: ''
description: 'Branch/tag/commit to checkout (for spin overrides). Defaults to github.ref if not specified'
parallel:
required: false
type: boolean
default: true
pre_build_script:
required: false
type: string
default: ''
description: 'Optional script to run after checkout (for spin customization)'
secrets:
CHECKOUT_TOKEN:
required: false
description: 'Token for cross-repository access'
env:
NAME: ${{ github.event_name == 'workflow_dispatch' && github.event.inputs.name || inputs.name }}
TARGET: ${{ github.event_name == 'workflow_dispatch' && github.event.inputs.target || inputs.target }}
INFIX_REPO: ${{ github.event_name == 'workflow_dispatch' && github.event.inputs.infix_repo || inputs.infix_repo }}
INFIX_BRANCH: ${{ github.event_name == 'workflow_dispatch' && github.event.inputs.infix_branch || inputs.infix_branch }}
jobs:
build:
name: Build ${{ github.event_name == 'workflow_dispatch' && github.event.inputs.name || inputs.name }} ${{ github.event_name == 'workflow_dispatch' && github.event.inputs.target || inputs.target }}
runs-on: [ self-hosted, latest ]
env:
PARALLEL: ${{ github.event_name == 'workflow_dispatch' && github.event.inputs.parallel == 'true' || github.event_name != 'workflow_dispatch' && inputs.parallel == true }}
name: Build ${{ matrix.platform }}
runs-on: ubuntu-latest
strategy:
matrix:
platform: [aarch64, amd64]
fail-fast: false
outputs:
build_id: ${{ steps.vars.outputs.INFIX_BUILD_ID }}
steps:
- name: Cleanup Build Folder
run: |
ls -la ./
rm -rf ./* || true
rm -rf ./.??* || true
ls -la ./
- name: Cleanup podman state
run: |
set -x
podman ps -a || true
podman stop -a || true
podman rm -a -f || true
podman volume prune -f || true
podman system prune -a -f || true
podman system migrate || true
- name: Checkout infix repo
uses: actions/checkout@v4
with:
repository: ${{ env.INFIX_REPO }}
ref: ${{ env.INFIX_BRANCH != '' && env.INFIX_BRANCH || github.ref }}
clean: true
fetch-depth: 0
submodules: recursive
token: ${{ secrets.CHECKOUT_TOKEN || github.token }}
- name: Run pre-build script
if: ${{ inputs.pre_build_script != '' }}
run: |
cat > ./pre-build.sh << 'EOF'
${{ inputs.pre_build_script }}
EOF
chmod +x ./pre-build.sh
bash ./pre-build.sh
- uses: actions/checkout@v3
- name: Set Build Variables
id: vars
run: |
if [ -n "${{ github.event.pull_request.head.sha }}" ]; then
# Since PRs are built from an internally generated merge
# commit, reverse lookups of PRs and/or commits from
# image version information are cumbersome. Therefore:
# explicitly set a build id that references both the PR
# and the commit.
printf "INFIX_BUILD_ID=pr%d.%.7s\n" \
"${{ github.event.number }}" "${{ github.event.pull_request.head.sha }}" \
| tee -a $GITHUB_OUTPUT $GITHUB_ENV
fi
target=${{ env.TARGET }}
name=${{ env.NAME }}
echo "dir=${name}-${target}" >> $GITHUB_OUTPUT
echo "tgz=${name}-${target}.tar.gz" >> $GITHUB_OUTPUT
echo "Building target ${target}_defconfig"
echo "dir=infix-${{ matrix.platform }}" >> $GITHUB_OUTPUT
echo "tgz=infix-${{ matrix.platform }}.tar.gz" >> $GITHUB_OUTPUT
- name: Restore Cache of dl/
uses: actions/cache@v4
uses: actions/cache@v3
with:
path: dl/
key: dl-${{ hashFiles('.git/modules/buildroot/HEAD', 'configs/*', 'package/*/*.hash') }}
key: dl-${{ matrix.platform }}-${{ hashFiles('.git/modules/buildroot/HEAD', 'configs/*', 'package/*/*.hash') }}
restore-keys: |
dl-${{ matrix.platform }}-
dl-
- name: Restore Cache of .ccache/
uses: actions/cache@v4
uses: actions/cache@v3
with:
path: .ccache/
key: ccache-${{ env.TARGET }}-${{ hashFiles('.git/modules/buildroot/HEAD', 'package/*/*.hash') }}
path: .buildroot-ccache/
key: ccache-${{ matrix.board }}-os-${{ hashFiles('.git/modules/buildroot/HEAD', 'package/*/*.hash') }}
restore-keys: |
ccache-${{ env.TARGET }}-
ccache-
- name: Configure ${{ env.TARGET }}
ccache-${{ matrix.board }}-os-
ccache-${{ matrix.board }}-
ccache--os-
- name: Configure & Build
run: |
make ${{ env.TARGET }}_defconfig
- name: Cleanup stale containers and ports
make ${{ matrix.platform }}_defconfig
make
- name: Prepare Artifact
run: |
podman rm -af || true
pkill -9 -f rootlessport || true
- name: Unit Test ${{ env.TARGET }}
run: |
make test-unit
- name: Prepare parallel build
id: parallel
run: |
if [ "$PARALLEL" == "true" ]; then
echo "BR2_PER_PACKAGE_DIRECTORIES=y" >> output/.config
MAKE="make -j$((`getconf _NPROCESSORS_ONLN` / 2 + 2))"
echo "Building in parallel with -j$((`getconf _NPROCESSORS_ONLN` / 2 + 2))"
else
echo "Disabling parallel build"
MAKE="make"
fi
echo "MAKE=$MAKE" >> $GITHUB_OUTPUT
- name: Build ${{ env.TARGET }}
run: |
echo "Building ${{ env.TARGET }}_defconfig ..."
eval "${{ steps.parallel.outputs.MAKE }}"
- name: Check SBOM from Build
run: |
make legal-info
- name: Build test specification
run: |
make test-spec
- name: Resulting size of build
run: |
printf "Size of complete tree : "
du -sh .
printf "Size of output/ : "
du -sh output
printf "Size of dl/ : "
du -sh dl
printf "Size of output/images/: "
ls -l output/images/
- name: Prepare ${{ env.TARGET }} Artifact
run: |
cd output/
cd output
mv images ${{ steps.vars.outputs.dir }}
ln -s ${{ steps.vars.outputs.dir }} images
tar cfz ${{ steps.vars.outputs.tgz }} ${{ steps.vars.outputs.dir }}
- uses: actions/upload-artifact@v4
ls -l
ls -l ${{ steps.vars.outputs.dir }}
- uses: actions/upload-artifact@v3
with:
path: output/${{ steps.vars.outputs.tgz }}
name: artifact-${{ env.TARGET }}
release:
name: Upload Latest Build
needs: build
runs-on: ubuntu-latest
steps:
- uses: actions/download-artifact@v3
- uses: pyTooling/Actions/releaser@main
with:
tag: latest
rm: true
token: ${{ secrets.GITHUB_TOKEN }}
files: artifact/*
- name: Summary
run: |
cat <<EOF >> $GITHUB_STEP_SUMMARY
# Latest Build Complete! :rocket:
For the public download links of these build artifacts, please see:
<https://github.com/kernelkit/infix/releases/tag/latest>
EOF
-140
View File
@@ -1,140 +0,0 @@
name: Check Kernel 6.12 Release
on:
schedule:
- cron: '0 3 * * *'
workflow_dispatch:
jobs:
check-kernel:
if: github.repository == 'kernelkit/infix'
runs-on: ubuntu-latest
steps:
- name: Check out infix repository
uses: actions/checkout@v4
with:
fetch-depth: 0
token: ${{ secrets.KERNEL_UPDATE_TOKEN }}
- name: Fetch kernel.org and check for 6.12 release
id: check
run: |
set -e -o pipefail
# Fetch the kernel.org frontpage and extract 6.12 version
CURRENT_VERSION=$(curl -s https://www.kernel.org/ | grep -oP '6\.12\.\d+' | head -n1)
if [ -z "$CURRENT_VERSION" ]; then
echo "Failed to fetch kernel version"
exit 1
fi
echo "current_version=$CURRENT_VERSION" >> $GITHUB_OUTPUT
echo "Current 6.12 kernel version: $CURRENT_VERSION"
# Get the version from infix defconfig
INFIX_VERSION=$(grep 'BR2_LINUX_KERNEL_CUSTOM_VERSION_VALUE=' configs/aarch64_defconfig | cut -d'"' -f2)
echo "infix_version=$INFIX_VERSION" >> $GITHUB_OUTPUT
echo "Infix kernel version: $INFIX_VERSION"
if [ "$CURRENT_VERSION" != "$INFIX_VERSION" ]; then
# Check if there's already an open PR for this version
PR_EXISTS=$(gh pr list --state open --search "Upgrade to kernel $CURRENT_VERSION in:title" --json number --jq 'length')
if [ "$PR_EXISTS" -gt 0 ]; then
echo "new_release=false" >> $GITHUB_OUTPUT
echo "PR already exists for kernel $CURRENT_VERSION, skipping"
else
echo "new_release=true" >> $GITHUB_OUTPUT
echo "🎉 New 6.12 kernel released: $CURRENT_VERSION (infix version: $INFIX_VERSION)"
fi
else
echo "new_release=false" >> $GITHUB_OUTPUT
echo "No change - still at $CURRENT_VERSION"
fi
env:
GH_TOKEN: ${{ secrets.KERNEL_UPDATE_TOKEN }}
- name: Generate branch name
if: steps.check.outputs.new_release == 'true'
id: branch
run: |
BRANCH_NAME="kernel-upgrade-$(uuidgen | tr '[:upper:]' '[:lower:]')"
echo "name=$BRANCH_NAME" >> $GITHUB_OUTPUT
echo "Branch name: $BRANCH_NAME"
- name: Import GPG key
if: steps.check.outputs.new_release == 'true'
run: |
# Import the GPG key
echo "${{ secrets.AEL_BOT_GPG_PRIVATE_KEY }}" | gpg --batch --import
# Get the key ID
GPG_KEY_ID=$(gpg --list-secret-keys --keyid-format=long | grep '^sec' | head -1 | awk '{print $2}' | cut -d'/' -f2)
echo "GPG_KEY_ID=$GPG_KEY_ID" >> $GITHUB_ENV
# Configure GPG agent for non-interactive use
echo "allow-loopback-pinentry" >> ~/.gnupg/gpg-agent.conf
echo "pinentry-mode loopback" >> ~/.gnupg/gpg.conf
gpg-connect-agent reloadagent /bye || true
- name: Set up git credentials
if: steps.check.outputs.new_release == 'true'
run: |
set -e -o pipefail
git config --global user.email "ael-bot@users.noreply.github.com"
git config --global user.name "ael-bot"
git config --global commit.gpgsign true
git config --global user.signingkey ${{ env.GPG_KEY_ID }}
# Configure git to use the token for HTTPS operations
git config --global url."https://ael-bot:${{ secrets.KERNEL_UPDATE_TOKEN }}@github.com/".insteadOf "git@github.com:"
git config --global url."https://ael-bot:${{ secrets.KERNEL_UPDATE_TOKEN }}@github.com/".insteadOf "https://github.com/"
- name: Run kernel upgrade script
if: steps.check.outputs.new_release == 'true'
env:
GIT_TERMINAL_PROMPT: 0
BRANCH_NAME: ${{ steps.branch.outputs.name }}
run: |
set -e -o pipefail
./utils/kernel-upgrade.sh linux "$BRANCH_NAME"
- name: Create pull request
if: steps.check.outputs.new_release == 'true'
uses: actions/github-script@v7
with:
github-token: ${{ secrets.KERNEL_UPDATE_TOKEN }}
script: |
const { data: pulls } = await github.rest.pulls.list({
owner: context.repo.owner,
repo: context.repo.repo,
head: `${context.repo.owner}:kernel-upgrade`,
state: 'open'
});
if (pulls.length === 0) {
const { data: pr } = await github.rest.pulls.create({
owner: context.repo.owner,
repo: context.repo.repo,
title: `Upgrade to kernel ${{ steps.check.outputs.current_version }}`,
head: '${{ steps.branch.outputs.name }}',
base: 'main',
body: `Automated kernel upgrade to version ${{ steps.check.outputs.current_version }}.\n\n**Previous version:** ${{ steps.check.outputs.infix_version }}\n**New version:** ${{ steps.check.outputs.current_version }}\n**Source:** https://www.kernel.org/\n\nThis PR was automatically created by the kernel release monitoring workflow.`
});
await github.rest.issues.addLabels({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: pr.number,
labels: ['ci:main']
});
await github.rest.pulls.requestReviewers({
owner: context.repo.owner,
repo: context.repo.repo,
pull_number: pr.number,
reviewers: ['troglobit', 'wkz', 'mattiaswal']
});
}
-94
View File
@@ -1,94 +0,0 @@
name: Coverity Scan
on:
schedule:
- cron: '5 0 * * 6'
workflow_dispatch:
env:
PROJECT_NAME: Infix
CONTACT_EMAIL: troglobit@gmail.com
jobs:
coverity:
if: ${{github.repository_owner == 'kernelkit'}}
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Fetch latest Coverity Scan MD5
id: var
env:
TOKEN: ${{ secrets.COVERITY_SCAN_TOKEN }}
run: |
wget -q https://scan.coverity.com/download/cxx/linux64 \
--post-data "token=$TOKEN&project=${PROJECT_NAME}&md5=1" \
-O coverity-latest.tar.gz.md5
echo "md5=$(cat coverity-latest.tar.gz.md5)" | tee -a $GITHUB_OUTPUT
- uses: actions/cache@v4
id: cache
with:
path: coverity-latest.tar.gz
key: ${{ runner.os }}-coverity-${{ steps.var.outputs.md5 }}
restore-keys: |
${{ runner.os }}-coverity-${{ steps.var.outputs.md5 }}
${{ runner.os }}-coverity-
${{ runner.os }}-coverity
- name: Download Coverity Scan
env:
TOKEN: ${{ secrets.COVERITY_SCAN_TOKEN }}
run: |
if [ ! -f coverity-latest.tar.gz ]; then
wget -q https://scan.coverity.com/download/cxx/linux64 \
--post-data "token=$TOKEN&project=${PROJECT_NAME}" \
-O coverity-latest.tar.gz
else
echo "Latest Coverity Scan available from cache :-)"
md5sum coverity-latest.tar.gz
fi
mkdir coverity
tar xzf coverity-latest.tar.gz --strip 1 -C coverity
- name: Install dependencies
run: |
sudo apt-get -y update
sudo apt-get -y install pkg-config libjansson-dev libev-dev \
libcrypt-dev libglib2.0-dev libpcre2-dev \
libuev-dev
- name: Build dependencies
run: |
git clone https://github.com/CESNET/libyang.git
mkdir libyang/build
(cd libyang/build && cmake .. && make all && sudo make install)
git clone https://github.com/sysrepo/sysrepo.git
mkdir sysrepo/build
(cd sysrepo/build && cmake .. && make all && sudo make install)
git clone https://github.com/troglobit/libite.git
(cd libite && ./autogen.sh && ./configure && make && sudo make install)
make dep
- name: Build applications for Coverity
run: |
export PATH=`pwd`/coverity/bin:$PATH
cov-build --dir cov-int make coverity
- name: Submit results to Coverity Scan
env:
TOKEN: ${{ secrets.COVERITY_SCAN_TOKEN }}
run: |
tar czvf ${PROJECT_NAME}.tgz cov-int
curl \
--form token=$TOKEN \
--form email=${CONTACT_EMAIL} \
--form file=@${PROJECT_NAME}.tgz \
--form version=$(git rev-parse HEAD) \
--form description="${PROJECT_NAME} $(git rev-parse HEAD)" \
https://scan.coverity.com/builds?project=${PROJECT_NAME}
- name: Upload build.log
uses: actions/upload-artifact@v4
with:
name: coverity-build.log
path: cov-int/build-log.txt
-68
View File
@@ -1,68 +0,0 @@
name: User Guide Generator
on:
push:
branches:
- doc
- main
tags:
- 'v*'
paths:
- 'doc/**'
- 'mkdocs.yml'
- '.github/workflows/docs.yml'
permissions:
contents: write
concurrency:
group: "docs-${{ github.ref }}"
cancel-in-progress: false
jobs:
docs:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Setup Python
uses: actions/setup-python@v4
with:
python-version: '3.x'
- name: Install dependencies
run: |
pipx install mkdocs
pipx inject mkdocs mkdocs-material
pipx inject mkdocs pymdown-extensions
pipx inject mkdocs mkdocs-callouts
pipx inject mkdocs mike
pipx inject mkdocs mkdocs-to-pdf
pipx inject mkdocs mkdocs-glightbox
# Workaround, if pipx inject fails to install symlink
ln -s "$(pipx environment -V PIPX_LOCAL_VENVS)/mkdocs/bin/mike" \
"$(pipx environment -V PIPX_BIN_DIR)/mike" || true
- name: Configure Git
run: |
git config --global user.name "github-actions[bot]"
git config --global user.email "github-actions[bot]@users.noreply.github.com"
- name: Deploy dev version
if: github.event_name == 'push' && (github.ref == 'refs/heads/doc' || github.ref == 'refs/heads/main')
run: |
mike deploy --push --update-aliases dev latest
mike set-default --push latest
- name: Deploy tagged version
if: github.event_name == 'push' && startsWith(github.ref, 'refs/tags/v')
run: |
TAG=${GITHUB_REF#refs/tags/v}
# Extract YEAR.MONTH from tag (e.g., v25.06.0-beta1 -> 25.06)
VERSION=$(echo $TAG | sed -E 's/^([0-9]+\.[0-9]+)(\.[0-9]+)?(-.*)?$/\1/')
echo "Deploying tag $TAG as docs version $VERSION"
mike deploy --push --update-aliases $VERSION latest
mike set-default --push latest
-84
View File
@@ -1,84 +0,0 @@
name: Generic X86 GitHub Build
on:
push:
jobs:
build:
if: github.repository != 'kernelkit/infix'
name: Infix x86_64
runs-on: ubuntu-latest
steps:
- name: Free Disk Space
uses: jlumbroso/free-disk-space@main
with:
tool-cache: true
android: true
dotnet: true
haskell: true
large-packages: true
docker-images: true
swap-storage: false
- name: Install build dependencies
run: |
sudo apt-get update
sudo apt-get install -y \
bc binutils build-essential bzip2 cpio \
diffutils file findutils git gzip \
libncurses-dev libssl-dev perl patch \
python3 rsync sed tar unzip wget \
autopoint bison flex autoconf automake \
mtools
- name: Checkout infix repo
uses: actions/checkout@v4
with:
repository: ${{ github.repository }}
ref: ${{ github.ref }}
fetch-depth: 0
submodules: recursive
- name: Set Build Variables
id: vars
run: |
echo "INFIX_BUILD_ID=${{ github.run_id }}" >> $GITHUB_OUTPUT
echo "dir=Infix-x86_64" >> $GITHUB_OUTPUT
echo "tgz=Infix-x86_64.tar.gz" >> $GITHUB_OUTPUT
- name: Configure x86_64_minimal
run: |
make x86_64_minimal_defconfig
- name: Unit Test x86_64
run: |
make test-unit
- name: Build x86_64_minimal
run: |
make
- name: Check SBOM
run: |
make legal-info
- name: Report Build Size
run: |
du -sh .
du -sh output
du -sh dl || true
ls -l output/images/
- name: Prepare Artifact
run: |
cd output/
mv images Infix-x86_64
ln -s Infix-x86_64 images
tar cfz Infix-x86_64.tar.gz Infix-x86_64
- uses: actions/upload-artifact@v4
with:
path: output/Infix-x86_64.tar.gz
name: artifact-x86_64
-100
View File
@@ -1,100 +0,0 @@
name: Manny the Manager
on:
workflow_dispatch:
inputs:
checkout:
required: true
type: boolean
cleanup:
required: true
type: boolean
peek:
required: true
type: boolean
jobs:
inventory:
runs-on: ubuntu-latest
steps:
- name: Disk usage ...
run: |
cd
du -hs .[^.]*
- name: Disk inventory (1/2) ...
run: |
echo "df -h ========================================================================="
df -h
echo "mounts ========================================================================"
mount
- name: File inventory (1/2) ...
run: |
echo "Current directory: $(pwd)"
echo "Files in $HOME ================================================================"
ls $HOME
echo "Find $HOME ===================================================================="
find $HOME
- name: Container inventory ...
run: |
echo "Available container images: ==================================================="
docker images
echo "Available containers: ========================================================="
docker ps -a
checkout:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Restore Cache of dl/
uses: actions/cache@v4
with:
path: dl/
key: dl-netconf-${{ hashFiles('.git/modules/buildroot/HEAD', 'configs/*', 'package/*/*.hash') }}
restore-keys: |
dl-netconf-
dl-
- name: Restore Cache of .ccache/
uses: actions/cache@v4
with:
path: .ccache/
key: ccache-x86_64-${{ hashFiles('.git/modules/buildroot/HEAD', 'package/*/*.hash') }}
restore-keys: |
ccache-x86_64-
ccache-
- name: Disk inventory (2/2) ...
run: |
echo "df -h ========================================================================="
df -h
echo "mounts ========================================================================"
mount
- name: File inventory (2/2) ...
run: |
echo "Current directory: $(pwd)"
echo "Files in $HOME ================================================================"
ls $HOME
echo "Find $HOME ===================================================================="
find $HOME
peeky:
if: ${{ inputs.peek }}
runs-on: ubuntu-latest
steps:
- name: Peek & Poke ...
run: |
whoami
ls -l /mnt/
cat /mnt/DATALOSS_WARNING_README.txt
sudo mkdir /mnt/x-aarch64
sudo chown $(id -un):$(id -gn) /mnt/x-aarch64
ls -l /mnt/
cleanup:
if: ${{ inputs.cleanup }}
needs: [inventory, peeky]
runs-on: ubuntu-latest
steps:
- name: Cleaning up cruft ...
run: |
docker image prune -af
docker volume prune -f
docker container prune -f
-44
View File
@@ -1,44 +0,0 @@
name: Publish latest Infix
on:
workflow_dispatch:
workflow_call:
jobs:
publish:
name: Upload Latest Build
runs-on: ubuntu-latest
permissions:
contents: write
steps:
- uses: actions/download-artifact@v4
with:
pattern: "artifact-*"
merge-multiple: true
- name: Create checksums ...
run: |
for file in *.tar.gz; do
sha256sum $file > $file.sha256
done
- uses: ncipollo/release-action@v1
with:
allowUpdates: true
replacesArtifacts: true
omitName: true
omitBody: true
omitBodyDuringUpdate: true
prerelease: true
tag: "latest"
token: ${{ secrets.GITHUB_TOKEN }}
artifacts: "*.tar.gz*"
- name: Summary
run: |
cat <<EOF >> $GITHUB_STEP_SUMMARY
# Latest Build Complete! :rocket:
For the public download links of these build artifacts, please see:
<https://github.com/kernelkit/infix/releases/tag/latest>
EOF
-130
View File
@@ -1,130 +0,0 @@
# This job can be started by a git tag or using the workflow dispatch.
#
# The version string *must* be of the format: vYY.MM(-alphaN|-betaN|-rcN)
#
# In /etc/os-release this string is used for VERSION, VERSION_ID, and
# IMAGE_VERSION, with the 'v' prefix. In release artifact filenames,
# and zip file directory names, the 'v' is dropped per convention.
name: Release General
on:
push:
tags:
- 'v[0-9]*.*'
workflow_dispatch:
inputs:
version:
required: false
type: string
jobs:
set-version:
if: github.repository == 'kernelkit/infix' && startsWith(github.ref, 'refs/tags/')
runs-on: ubuntu-latest
outputs:
version: ${{ steps.set-ver.outputs.version }}
steps:
- id: set-ver
run: |
if [ -n "${{ inputs.version }}" ]; then
ver=${{ inputs.version }}
else
ver=${GITHUB_REF#refs/tags/}
fi
echo "version=${ver}" >> $GITHUB_OUTPUT
build:
needs: set-version
uses: ./.github/workflows/build-release.yml
with:
version: ${{ needs.set-version.outputs.version }}
use_cache: true
release:
name: Release Infix ${{ github.ref_name }}
needs: build
runs-on: [self-hosted, release]
permissions:
contents: write
discussions: write
steps:
- name: Cleanup podman state
run: |
set -x
podman ps -a || true
podman stop -a || true
podman rm -a -f || true
podman volume prune -f || true
podman system prune -a -f || true
podman system migrate || true
- uses: actions/checkout@v4
with:
submodules: 'true'
- name: Set Release Variables
id: rel
run: |
if [ -n "${{ inputs.version }}" ]; then
ver=${{ inputs.version }}
else
ver=${GITHUB_REF#refs/tags/}
fi
echo "ver=${ver}" >> $GITHUB_OUTPUT
echo "cat=" >> $GITHUB_OUTPUT
if echo $ver | grep -qE 'v[0-9.]+(-alpha|-beta|-rc)[0-9]*'; then
echo "pre=true" >> $GITHUB_OUTPUT
echo "latest=false" >> $GITHUB_OUTPUT
elif echo $ver | grep -qE '^v[0-9]+\.[0-9]+(\.0)?$'; then
echo "pre=false" >> $GITHUB_OUTPUT
echo "latest=true" >> $GITHUB_OUTPUT
echo "cat=Releases" >> $GITHUB_OUTPUT
else
echo "pre=false" >> $GITHUB_OUTPUT
echo "latest=false" >> $GITHUB_OUTPUT
fi
echo "pre=${{ steps.rel.outputs.pre }}"
echo "latest=${{ steps.rel.outputs.latest }}"
- uses: actions/download-artifact@v4
with:
pattern: "artifact-*"
merge-multiple: true
- name: Create checksums ...
run: |
for file in *.tar.gz; do
sha256sum $file > $file.sha256
done
if ls *.qcow2 &>/dev/null; then
for file in *.qcow2; do
sha256sum "$file" > "$file.sha256"
done
fi
- name: Extract ChangeLog entry ...
run: |
awk '/^-----*$/{if (x == 1) exit; x=1;next}x' doc/ChangeLog.md \
|head -n -1 > release.md
echo "" >> release.md
echo "> [!TIP]" >> release.md
echo "> **Try Infix in GNS3!** Download the appliance from the [GNS3 Marketplace](https://gns3.com/marketplace/appliances/infix) to test Infix in a virtual network environment without hardware." >> release.md
cat release.md
- uses: ncipollo/release-action@v1
with:
name: Infix ${{ github.ref_name }}
prerelease: ${{ steps.rel.outputs.pre }}
makeLatest: ${{ steps.rel.outputs.latest }}
discussionCategory: ${{ steps.rel.outputs.cat }}
bodyFile: release.md
artifacts: "*.tar.gz*,*.qcow2*"
- name: Summary
run: |
cat <<EOF >> $GITHUB_STEP_SUMMARY
# Infix ${{ github.ref_name }} Released! :rocket:
For the public download links of this release, please see:
<https://github.com/kernelkit/infix/releases/tag/${{ github.ref_name }}>
EOF
-145
View File
@@ -1,145 +0,0 @@
name: Test Infix
on:
workflow_dispatch:
inputs:
infix_repo:
description: 'Repo to checkout (for spin overrides)'
required: false
default: kernelkit/infix
type: string
infix_branch:
description: 'Branch/tag/commit to checkout (for spin overrides)'
default: ''
type: string
workflow_call:
inputs:
target:
required: true
type: string
name:
required: true
type: string
infix_repo:
required: false
type: string
default: kernelkit/infix
infix_branch:
required: false
type: string
default: ''
description: 'Branch/tag/commit to checkout (for spin overrides). Defaults to github.ref if not specified'
ninepm-conf:
required: false
type: string
default: ''
test-path:
required: false
type: string
default: 'test'
pre_test_script:
required: false
type: string
default: ''
description: 'Optional script to run after checkout (for spin customization)'
secrets:
CHECKOUT_TOKEN:
required: false
description: 'Token for cross-repository access'
env:
TARGET: ${{ github.event_name == 'workflow_dispatch' && github.event.inputs.target || inputs.target }}
INFIX_REPO: ${{ github.event_name == 'workflow_dispatch' && github.event.inputs.infix_repo || inputs.infix_repo }}
INFIX_BRANCH: ${{ github.event_name == 'workflow_dispatch' && github.event.inputs.infix_branch || inputs.infix_branch }}
NINEPM_CONF: ${{ github.event_name == 'workflow_dispatch' && github.event.inputs.ninepm-conf || inputs.ninepm-conf }}
TEST_PATH: ${{ github.event_name == 'workflow_dispatch' && github.event.inputs.test-path || inputs.test-path }}
jobs:
test:
name: Regression Test ${{ github.event_name == 'workflow_dispatch' && github.event.inputs.name || inputs.name }} ${{ github.event_name == 'workflow_dispatch' && github.event.inputs.target || inputs.target }}
runs-on: [self-hosted, regression]
steps:
- name: Cleanup podman state
run: |
set -x
podman ps -a || true
podman stop -a || true
podman rm -a -f || true
podman volume prune -f || true
podman system prune -a -f || true
podman system migrate || true
- name: Checkout infix repo
uses: actions/checkout@v4
with:
repository: ${{ env.INFIX_REPO }}
ref: ${{ env.INFIX_BRANCH != '' && env.INFIX_BRANCH || github.ref }}
clean: true
fetch-depth: 0
submodules: recursive
token: ${{ secrets.CHECKOUT_TOKEN || github.token }}
- name: Run pre-test script
if: ${{ inputs.pre_test_script != '' }}
run: |
cat > ./pre-test.sh << 'EOF'
${{ inputs.pre_test_script }}
EOF
chmod +x ./pre-test.sh
bash ./pre-test.sh
- name: Set Build Variables
id: vars
run: |
if [ -n "${{ needs.build.outputs.build_id }}" ]; then
echo "INFIX_BUILD_ID=${{ needs.build.outputs.build_id }}" \
>>$GITHUB_ENV
fi
- name: Configure ${{ env.TARGET }}
run: |
make ${{ env.TARGET }}_defconfig
- uses: actions/download-artifact@v4
with:
pattern: "artifact-*"
merge-multiple: true
- name: Restore ${{ env.TARGET }} output/
run: |
target=${{ env.TARGET }}
name=${{ inputs.name }}
ls -l
mkdir -p output
mv ${name}-${target}.tar.gz output/
cd output/
tar xf ${name}-${target}.tar.gz
ln -s ${name}-${target} images
- name: Regression Test ${{ env.TARGET }}
run: |
if [ -n "$NINEPM_CONF" ]; then
export NINEPM_PROJ_CONFIG="${GITHUB_WORKSPACE}/$NINEPM_CONF"
echo "DEBUG: NINEPM_PROJ_CONFIG is '$NINEPM_PROJ_CONFIG'"
fi
make test
- name: Publish Test Result for ${{ env.TARGET }}
# Ensure this runs even if Regression Test fails
if: always()
run: |
cat $TEST_PATH/.log/last/result-gh.md >> $GITHUB_STEP_SUMMARY
- name: Generate Test Report for ${{ env.TARGET }}
# Ensure this runs even if Regression Test fails
if: always()
run: |
make test-dir="$(pwd)/$TEST_PATH" test-report
- name: Upload Test Report as Artifact
uses: actions/upload-artifact@v4
with:
name: test-report
path: output/images/test-report.pdf
-75
View File
@@ -1,75 +0,0 @@
name: Kernelkit Trigger
on:
pull_request:
types: [opened, synchronize, reopened, labeled]
push:
branches:
- main
- ci-work
workflow_dispatch:
concurrency:
group: ci-${{ github.event.pull_request.number || github.ref }}
cancel-in-progress: true
jobs:
# Gate all builds through this check to prevent wasted runs. Only run on
# 'labeled' events when the label is actually 'ci:main'. Concurrency control
# above handles canceling the 'opened' event when 'labeled' arrives quickly
# after (e.g., when creating a PR with ci:main already attached). See #1154.
check-trigger:
if: |
startsWith(github.repository, 'kernelkit/') &&
(github.event_name != 'pull_request' ||
github.event.action != 'labeled' ||
github.event.label.name == 'ci:main')
runs-on: ubuntu-latest
outputs:
x86_64_target: ${{ steps.set-targets.outputs.x86_64_target }}
aarch64_target: ${{ steps.set-targets.outputs.aarch64_target }}
steps:
- run: |
echo "Triggering build, logging meta data ..."
echo "Event : ${{ github.event_name }}"
echo "Action : ${{ github.event.action }}"
echo "Ref : ${{ github.ref }}"
echo "PR : ${{ github.event.pull_request.number }}"
echo "Label : ${{ github.event.label.name }}"
- id: set-targets
run: |
if [[ "${{ github.event_name }}" == "pull_request" ]] && \
! echo '${{ toJSON(github.event.pull_request.labels.*.name) }}' \
| grep -q "ci:main"; then
echo "x86_64_target=x86_64_minimal" >> $GITHUB_OUTPUT
echo "aarch64_target=aarch64_minimal" >> $GITHUB_OUTPUT
else
echo "x86_64_target=x86_64" >> $GITHUB_OUTPUT
echo "aarch64_target=aarch64" >> $GITHUB_OUTPUT
fi
build-x86_64:
needs: check-trigger
uses: ./.github/workflows/build.yml
with:
name: "infix"
target: ${{ needs.check-trigger.outputs.x86_64_target }}
build-aarch64:
needs: check-trigger
uses: ./.github/workflows/build.yml
with:
name: "infix"
target: ${{ needs.check-trigger.outputs.aarch64_target }}
test-run-x86_64:
needs: [check-trigger, build-x86_64]
uses: ./.github/workflows/test.yml
with:
target: ${{ needs.check-trigger.outputs.x86_64_target }}
name: "infix"
test-publish-x86_64:
if: ${{ github.repository_owner == 'kernelkit' && github.ref_name == 'main' }}
needs: test-run-x86_64
uses: ./.github/workflows/publish.yml
-68
View File
@@ -1,68 +0,0 @@
# Weekly release build to catch flaky tests and verify clean builds.
# Runs without caches (ccache) to ensure reproducibility. See issue #1003.
name: Weekly Build
on:
schedule:
- cron: '5 0 * * 6' # Saturday at 00:05 UTC, same as Coverity
workflow_dispatch:
jobs:
build:
if: github.repository == 'kernelkit/infix'
uses: ./.github/workflows/build-release.yml
with:
version: "latest"
use_cache: false
publish:
name: Publish Weekly Build
needs: build
runs-on: ubuntu-latest
permissions:
contents: write
steps:
- uses: actions/download-artifact@v4
with:
pattern: "artifact-*"
merge-multiple: true
- name: Create checksums
run: |
for file in *.tar.gz; do
sha256sum $file > $file.sha256
done
if ls *.qcow2 &>/dev/null; then
for file in *.qcow2; do
sha256sum "$file" > "$file.sha256"
done
fi
- uses: ncipollo/release-action@v1
with:
tag: latest
name: "Latest Weekly Build"
prerelease: true
makeLatest: false
allowUpdates: true
removeArtifacts: true
body: |
Automated weekly build from `${{ github.sha }}`.
This build runs without caches to catch potential flaky tests and build issues.
Not intended for production use - use official releases instead.
**Commit:** ${{ github.sha }}
**Built:** ${{ github.run_id }}
artifacts: "*.tar.gz*,*.qcow2*"
- name: Summary
run: |
cat <<EOF >> $GITHUB_STEP_SUMMARY
# Weekly Build Published! :package:
Latest artifacts uploaded to:
<https://github.com/kernelkit/infix/releases/tag/latest>
Built from commit: \`${{ github.sha }}\`
EOF
-6
View File
@@ -1,12 +1,6 @@
*~
.claude
.gdb_history
/.backup
/.ccache
/dl
/output*
/x-*
/test/.venv
/test/.log
/local.mk
/test/spec/Readme.adoc
-6
View File
@@ -1,9 +1,3 @@
[submodule "buildroot"]
path = buildroot
url = ../buildroot.git
[submodule "9pm"]
path = test/9pm
url = ../9pm
[submodule "qeneth"]
path = test/qeneth
url = ../qeneth.git
+7 -124
View File
@@ -1,130 +1,13 @@
source "$BR2_EXTERNAL_INFIX_PATH/board/Config.in"
menu "Packages"
menu "Branding"
config INFIX_VENDOR
string "Vendor name"
default "KernelKit"
help
The name of the operating system vendor. This is the name of the
organization or company which produces the OS.
This name is intended to be exposed in "About this system" UIs or
software update UIs when needed to distinguish the OS vendor from
the OS itself. It is intended to be human readable.
Used for VENDOR_NAME in /etc/os-release and GNS3 appliance files.
config INFIX_VENDOR_HOME
string "Vendor URL"
help
The homepage of the OS vendor. The value should be in RFC3986
format, and should be "http:" or "https:" URLs. Only one URL shall
be listed in the setting.
Optional, used for VENDOR_HOME in /etc/os-release
config INFIX_NAME
string "Operating system name"
default "Infix"
help
Mandatory. Used for identifying the OS as NAME in /etc/os-release
and product_name in GNS3 appliance files.
config INFIX_ID
string "Operating system identifier"
default "infix"
help
A lower-case string (no spaces or other characters outside of 09,
az, '.', '_' and '-') identifying the operating system, excluding
any version information and suitable for processing by scripts or
usage in generated filenames.
Mandatory. Used for identifying the OS as ID in /etc/os-release and
in the generated image name: ID-ARCH-VERSION.img
config INFIX_IMAGE_ID
string "Operating system image name"
default "${INFIX_ID}-${BR2_ARCH}"
help
A lower-case string (no spaces or other characters outside of 09,
az, ".", "_" and "-"), for naming critical image files, directories
and archives containting the operating system.
Mandatory. When INFIX_RELEASE is set, this string is appended to
the IMAGE_ID with a '-' separator.
config INFIX_COMPATIBLE
string "Operating system compatible string"
default "${INFIX_IMAGE_ID}"
help
A lower-case string (no spaces or other characters outside of 09,
az, ".", "_" and "-"), used for image identification at upgrade.
E.g., the RAUC [system] compatible string.
Mandatory. Defaults to $INFIX_IMAGE_ID, which in turn is composed
of $INFIX_ID-$BR2_ARCH.
config INFIX_TAGLINE
string "Operating system tagline"
default "Infix OS — Immutable.Friendly.Secure"
help
Mandatory. Used for identifying the OS, e.g. as PRETTY_NAME in
/etc/os-release and description in the GNS3 appliance.
This is also show at boot when the system init process starts.
config INFIX_DESC
string "Operating system description"
help
Optional. Used for long description texts about the OS. E.g.,
the GNS3 appliance file description field. Saved in the file
/etc/os-release as INFIX_DESC.
config INFIX_HOME
string "Operating system URL"
help
Used for identifying the OS, e.g. as HOME_URL in /etc/os-release
config INFIX_DOC
string "Operating system docs"
help
Optional. Main documentation URL, will be shown in /etc/os-release
as DOCUMENTATION_URL.
config INFIX_SUPPORT
string "Operating system support"
help
Main support page for the operating system, if there is any. This
is primarily intended for operating systems which vendors provide
support for. May be a http:, https:, or mailto: URI.
Optional. Shown, e.g., as SUPPORT_URL in /etc/os-release or
maintainer_email in .gns3a.
config INFIX_OEM_PATH
string "Path to OEM br2-external"
help
A br2-external using Infix will likely want to version the branded
OS using their own GIT tags. Set this variable to point to the base
directory (absolute path) and the Infix post-build.sh will call `git
describe -C $INFIX_OEM_PATH`.
Note: for release builds the global variable INFIX_RELEASE overrides
the version information derived from `git describe`. However, the
GIT version is always saved as the BUILD_ID in /etc/os-releases.
source "$BR2_EXTERNAL_INFIX_PATH/package/Config.in"
endmenu
# For /etc/os-release, uses CondtionArchitechture= from systemd.unit(5)
config INFIX_ARCH
string
default "arm" if BR2_arm
default "arm64" if BR2_aarch64
default "mips64" if BR2_mips64
default "riscv64" if BR2_riscv
default "x86_64" if BR2_x86_64
menu "QEMU Virtualization"
source "$BR2_EXTERNAL_INFIX_PATH/qemu/Config.in"
endmenu
source "$BR2_EXTERNAL_INFIX_PATH/package/Config.in"
source "$BR2_EXTERNAL_INFIX_PATH/package/Config.in.host"
source "$BR2_EXTERNAL_INFIX_PATH/board/common/Config.in"
+4 -23
View File
@@ -1,13 +1,8 @@
export BR2_EXTERNAL ?= $(CURDIR)
export BR2_EXTERNAL := $(CURDIR)
export PATH := $(CURDIR)/bin:$(PATH)
ARCH ?= $(shell uname -m)
O ?= output
# If a relative output path is specified, we have to translate it to
# an absolute one before handing over control to Buildroot, which will
# otherwise treat it as relative to ./buildroot.
override O := $(if $(filter /%,$O),$O,$(CURDIR)/$O)
O ?= $(CURDIR)/output
config := $(O)/.config
bmake = $(MAKE) -C buildroot O=$(O) $1
@@ -16,9 +11,6 @@ bmake = $(MAKE) -C buildroot O=$(O) $1
all: $(config) buildroot/Makefile
@+$(call bmake,$@)
check dep coverity:
@make -C src $@
$(config):
@+$(call bmake,list-defconfigs)
@echo "\e[7mERROR: No configuration selected.\e[0m"
@@ -26,22 +18,11 @@ $(config):
@echo "'make <board>_defconfig' before building an image."
@exit 1
%: | buildroot/Makefile
@+$(call bmake,$@)
legal-info: | buildroot/Makefile
$(call bmake,legal-info LINUX_LICENSE_FILES=COPYING)
cyclonedx: | buildroot/Makefile
@echo "Generating package information..."
@$(MAKE) --no-print-directory -C buildroot O=$(O) show-info | ./buildroot/utils/generate-cyclonedx > $(O)/cyclonedx-sbom.json
@echo "CycloneDX SBOM generated: $(O)/cyclonedx-sbom.json"
# Workaround, see board/x86_64/board.mk
test:
@+$(call bmake,$@)
buildroot/Makefile:
@git submodule update --init
.PHONY: all check coverity dep test cyclonedx
.PHONY: all
+93 -150
View File
@@ -1,186 +1,129 @@
[![License Badge][]][License] [![Release Badge][]][Release] [![GitHub Status][]][GitHub] [![Coverity Status][]][Coverity Scan] [![Discord][discord-badge]][discord-url]
<img align="right" src="doc/text3134.png" alt="Infix Linux Networking Made Easy">
<img align="right" src="doc/logo.png" alt="Infix — Immutable.Friendly.Secure" width=480 padding=10>
* [Introduction](#introduction)
* [Hardware](#hardware)
* [Qemu](#qemu)
* [GNS3](#gns3)
* [Building](#building)
* [Origin & Licensing](origin--licensing)
Turn any ARM or x86 device into a powerful, manageable network appliance
in minutes. From $35 Raspberry Pi boards to enterprise switches — deploy
routers, IoT gateways, edge devices, or custom network solutions that
just work.
## Our Values
Introduction
------------
**🔒 Immutable**
Your system never breaks. Read-only filesystem with atomic upgrades
means no configuration drift, no corrupted updates, and instant rollback
if something goes wrong. Deploy once, trust forever.
Infix is an embedded Linux Network Operating System (NOS) based on
[Buildroot][1], [Finit][2], [ifupdown-ng][3], and [Clixon][6].
Providing an easy-to-maintain and easy-to-port Open Source base for
networked equipment.
**🤝 Friendly**
Actually easy to use. Auto-generated CLI from standard YANG models comes
with built-in help for every command — just hit `?` or TAB for
context-aware assistance. Familiar NETCONF/RESTCONF APIs and
[comprehensive documentation][4] mean you're never stuck. Whether
you're learning networking or managing enterprise infrastructure.
See the [GitHub Releases](https://github.com/kernelkit/infix/releases)
page for out pre-built images. The *Latest Build* has the bleeding edge
images, if possible we recommend using a versioned release.
**🛡️ Secure**
Built with security as a foundation, not an afterthought. Minimal
attack surface, separation between system and data, and container
isolation. Sleep better knowing your infrastructure is protected.
> Login with user 'root', no password by default on plain builds. See
> the online `help` command for an introduction to the system.
## Why Choose Infix
**Hardware Flexibility**: Start with a $35 Raspberry Pi, scale to
enterprise switching hardware. Same OS, same tools, same reliability.
Hardware
--------
**Standards-Based**: Built around YANG models and IETF standards. Learn
once, use everywhere - no vendor lock-in.
### aarch64
**Container Ready**: Run your applications alongside networking
functions. GPIO access, dedicated Ethernet ports, custom protocols —
your device, your rules.
By default, Infix builds with support for the following boards (you
may enable additional boards in the config, of course):
## Use Cases
- Marvell CN9130 CRB
- Marvell EspressoBIN
- Microchip SparX-5i PCB135 (eMMC)
1. **Home Labs & Hobbyists**:
Transform a Raspberry Pi into a full-featured router with WiFi
1. **IoT & Edge Computing**:
Bridge devices to the cloud with reliable, updatable gateways
1. **Small Business Networks**:
Enterprise-grade features without the complexity or cost
1. **Developers & Makers**:
Test networking concepts, prototype IoT solutions, or build custom
appliances
1. **Network Professionals**:
Consistent tooling from development to production deployment.
How about a digital twin using raw Qemu or [GNS3](https://gns3.com/infix)!
See the aarch64 specific [documentation](board/aarch64/README.md) for more
information.
## See It In Action
### amd64
Configure an interface in seconds - the CLI guides you with built-in help:
Primarily intended to be run under [QEMU][] for development & test as
well as evaluation, demo and [training][] purposes, e.g. using [GNS3][]
or [Qeneth][7].
<details><summary><b>Click Here for an example CLI Session</b></summary>
```bash
admin@infix-12-34-56:/> configure
admin@infix-12-34-56:/config/> edit interface eth0
admin@infix-12-34-56:/config/interface/eth0/> set ipv4 <TAB>
address autoconf bind-ni-name enabled
forwarding mtu neighbor
admin@infix-12-34-56:/config/interface/eth0/> set ipv4 address 192.168.2.200 prefix-length 24
admin@infix-12-34-56:/config/interface/eth0/> show
type ethernet;
ipv4 {
address 192.168.2.200 {
prefix-length 24;
}
}
admin@infix-12-34-56:/config/interface/eth0/> diff
interfaces {
interface eth0 {
+ ipv4 {
+ address 192.168.2.200 {
+ prefix-length 24;
+ }
+ }
}
}
admin@infix-12-34-56:/config/interface/eth0/> leave
admin@infix-12-34-56:/> show interfaces
INTERFACE PROTOCOL STATE DATA
eth0 ethernet UP 52:54:00:12:34:56
ipv4 192.168.2.200/24 (static)
ipv6 fe80::5054:ff:fe12:3456/64 (link-layer)
lo ethernet UP 00:00:00:00:00:00
ipv4 127.0.0.1/8 (static)
ipv6 ::1/128 (static)
admin@infix-12-34-56:/> copy running-config startup-config
```
QEMU
----
Notice how TAB completion shows available options, `show` displays
current config, and `diff` shows exactly what changed before you
commit your changes with the `leave` command.
A virtualized instance can easily be launched from a Linux system, with
Qemu installed, by issuing `make run`.
</details>
Some settings, e.g. networking, can be configured via `make menuconfig`
under `External options -> QEMU virtualization`.
> [Full CLI documentation →][3]
## Get Started
GNS3
----
Get [pre-built images][5] for your hardware. Use the CLI, web
interface, or standard NETCONF/RESTCONF tools, e.g., `curl`. Add
containers for any custom functionality you need.
Download the [latest build][0] of amd64, unpack in a dedicated directory
and use ["Import Appliance"][9] to install the `.gns3a` file into GNS3.
Infix will show up in the "Router" category, it has 10 interfaces
available by default for use as switch ports or routing.
### Supported Platforms
- **Raspberry Pi 4B** - Perfect for home labs, learning, and prototyping
- **Banana Pi-R3** - Your next home router and gateway
- **NanoPi R2S** - Compact dual-port router in a tiny package
- **x86_64** - Run in VMs or on mini PCs for development and testing
- **Marvell CN9130 CRB, EspressoBIN** - High-performance ARM64 platforms
- **Microchip SparX-5i** - Enterprise switching capabilities
- **NXP i.MX8MP EVK** - Highly capable ARM64 SoC
- **StarFive VisionFive2** - RISC-V architecture support
Building
--------
*Why start with Raspberry Pi?* It's affordable, widely available, has
built-in WiFi + Ethernet, and runs the exact same Infix OS you'd deploy
in production. Perfect for learning, prototyping, or even small-scale
deployments.
Buildroot is almost stand-alone, but need a few locally installed tools
to bootstrap itself. For details, see the [excellent manual][manual].
Briefly, to build an Infix image; select the target and then make:
> 📖 **[Complete documentation][4]** • 💬 **[Join our Discord][discord-url]**
make amd64_defconfig
make
## Technical Details
Online help is available:
<a href="https://bitsign.se">
<picture>
<source media="(prefers-color-scheme: dark)" srcset="https://bitsign.se/assets/badges/bitsign-badge-dark-mode.png">
<source media="(prefers-color-scheme: light)" srcset="https://bitsign.se/assets/badges/bitsign-badge-light-mode.png">
<img alt="bitSign - Code Signing" src="https://bitsign.se/assets/badges/bitsign-badge-light-mode.png" align="right" width=150 padding=10>
</picture>
</a>
make help
Built on proven open-source foundations: [Linux][0], [Buildroot][1], and
[sysrepo][2] — for reliability you can trust:
To see available defconfigs for supported targets, use:
- **Immutable OS**: Read-only filesystem, atomic updates, instant rollback
- **YANG Configuration**: Industry-standard models with auto-generated tooling
- **Hardware Acceleration**: Linux switchdev support for wire-speed packet processing
- **Container Integration**: Docker support with flexible network and hardware access
- **Memory Efficient**: Runs comfortably on devices with as little as 256 MB RAM
- **Code Signing**: Releases are cryptographically signed for integrity verification
make list-defconfigs
Perfect for everything from resource-constrained edge devices to
high-throughput network appliances.
> **Note:** build dependencies (Debian/Ubuntu): <kbd>sudo apt install make libssl-dev</kbd>
With the entire system modeled in YANG, scalability is no longer an
issue, be it in development, testing, or end users deploying and
monitoring their devices. All knobs and dials are accessible from the
CLI (console/SSH), or remotely using the native NETCONF or RESTCONF
APIs.
> Check the *[Latest Build][]* for bleeding-edge features.
Origin & Licensing
------------------
---
Infix is entirely built on Open Source components (packages). Most of
them, as well as the build system with its helper scripts and tools, is
from [Buiildroot][1], which is distributed under the terms of the GNU
General Public License (GPL). See the file COPYING for details.
<div align="center">
<a href="https://github.com/wires-se"><img src="https://raw.githubusercontent.com/wires-se/.github/main/profile/play.svg" width=300></a>
<br />Infix development is sponsored by <a href="https://wires.se">Wires</a>
</div>
Some files in Buildroot contain a different license statement. Those
files are licensed under the license contained in the file itself.
![Alt](https://repobeats.axiom.co/api/embed/5ce7a2a67edc923823afa0f60c327a6e8575b6e9.svg "Repobeats analytics image")
Buildroot and Infix also bundle patch files, which are applied to the
sources of the various packages. Those patches are not covered by the
license of Buildroot or Infix. Instead, they are covered by the license
of the software to which the patches are applied. When said software is
available under multiple licenses, the patches are only provided under
the publicly accessible licenses.
[0]: https://www.kernel.org
[1]: https://buildroot.org/ "Buildroot Homepage"
[2]: https://www.sysrepo.org/ "Sysrepo Homepage"
[3]: https://kernelkit.org/infix/latest/cli/introduction/
[4]: https://kernelkit.org/infix/
[5]: https://github.com/kernelkit/infix/releases
[Latest Build]: https://github.com/kernelkit/infix/releases/tag/latest "Latest build"
[License]: https://en.wikipedia.org/wiki/GPL_license
[License Badge]: https://img.shields.io/badge/License-GPL%20v2-blue.svg
[Release]: https://github.com/kernelkit/infix/releases
[Release Badge]: https://img.shields.io/github/v/release/kernelkit/infix
[GitHub]: https://github.com/kernelkit/infix/actions/workflows/build.yml/
[GitHub Status]: https://github.com/kernelkit/infix/actions/workflows/build.yml/badge.svg
[Coverity Scan]: https://scan.coverity.com/projects/29393
[Coverity Status]: https://scan.coverity.com/projects/29393/badge.svg
[discord-badge]: https://img.shields.io/discord/1182652155618918411.svg?logo=discord
[discord-url]: https://discord.gg/6bHJWQNVxN
Infix releases include the license information covering all Open Source
packages. This is extracted automatically at build time using the tool
`make legal-info`. Any proprietary software built on top of Infix, or
Buildroot, would need separate auditing to ensure it does not link with
any GPL[^1] licensed library.
[^1]: Infix image builds use GNU libc (GLIBC) which is covered by the
[LGPL][4]. The LGPL *does allow* proprietary software, as long as
said software is linking dynamically, [not statically][5], to GLIBC.
[0]: https://github.com/kernelkit/infix/releases/tag/latest
[1]: https://buildroot.org/
[2]: https://github.com/troglobit/finit
[3]: https://github.com/ifupdown-ng/ifupdown-ng
[4]: https://en.wikipedia.org/wiki/GNU_Lesser_General_Public_License
[5]: https://lwn.net/Articles/117972/
[6]: https://github.com/clicon/clixon
[7]: https://github.com/wkz/qeneth
[9]: https://docs.gns3.com/docs/using-gns3/beginners/import-gns3-appliance/
[QEMU]: https://www.qemu.org/
[GNS3]: https://gns3.com/
[training]: https://addiva-elektronik.github.io/
[manual]: https://buildroot.org/downloads/manual/manual.html
+22
View File
@@ -0,0 +1,22 @@
* TODO doc: User Guide
- Feature set and scope, e.g.
- Device discovery: SSDP, LLDP, mDNS-SD how do they work, interfacing with Windows/macOS/Linux
- Network redundancy protocols: STP/RSTP, MRP
- Configuring the system; using ifupdown2, enabling/disabling services
- Diagnosing the system; using rmon, port mirroring, debugging services, searching logs
- Limitations, e.g., PRP/HSR or IEEE 802.1CB will not be possible to support
- Tips & Trix
* TODO document how to set up passwordless SSH
* TODO add setup wizard, based on pdmenu
- setup-port script to tweak ethtool settings
- setup-iface script to configure a layer-3 interface
- setup-bridge script that creates a new bridge with config from cmdline
- setup-firewall script that can do basic firewall rules and masquerading
* TODO split out qemu Config.in to a "make run-menuconfing"
* TODO rename qemu/ to run/, perhaps?
* TODO ship qemu/* with output/images/ for stand-alone runs of older builds
-8
View File
@@ -1,8 +0,0 @@
menu "Board Support"
source "$BR2_EXTERNAL_INFIX_PATH/board/aarch32/Config.in"
source "$BR2_EXTERNAL_INFIX_PATH/board/aarch64/Config.in"
source "$BR2_EXTERNAL_INFIX_PATH/board/riscv64/Config.in"
source "$BR2_EXTERNAL_INFIX_PATH/board/x86_64/Config.in"
endmenu
-5
View File
@@ -1,5 +0,0 @@
if BR2_arm
source "$BR2_EXTERNAL_INFIX_PATH/board/aarch32/raspberrypi-rpi2/Config.in"
endif
-7
View File
@@ -1,7 +0,0 @@
aarch32
=======
Board Specific Documentation
----------------------------
- [Raspberry Pi 2 Model B (32-bit)](raspberrypi-rpi2/)
-1
View File
@@ -1 +0,0 @@
-7
View File
@@ -1,7 +0,0 @@
blkmap get boot dev devnum
load blkmap ${devnum} ${kernel_addr_r} /boot/zImage
#TODO: LOAD FDT
setenv bootargs "${bootargs_root} ${bootargs_rauc} ${bootargs_log}"
bootz ${kernel_addr_r} ${ramdisk} ${fdt_addr}
-395
View File
@@ -1,395 +0,0 @@
CONFIG_SYSVIPC=y
CONFIG_POSIX_MQUEUE=y
CONFIG_AUDIT=y
CONFIG_NO_HZ_IDLE=y
CONFIG_HIGH_RES_TIMERS=y
CONFIG_BPF_SYSCALL=y
CONFIG_BPF_JIT=y
CONFIG_PREEMPT=y
CONFIG_BSD_PROCESS_ACCT=y
CONFIG_BSD_PROCESS_ACCT_V3=y
CONFIG_TASKSTATS=y
CONFIG_TASK_DELAY_ACCT=y
CONFIG_TASK_XACCT=y
CONFIG_TASK_IO_ACCOUNTING=y
CONFIG_IKCONFIG=y
CONFIG_IKCONFIG_PROC=y
CONFIG_LOG_BUF_SHIFT=18
CONFIG_MEMCG=y
CONFIG_BLK_CGROUP=y
CONFIG_CFS_BANDWIDTH=y
CONFIG_RT_GROUP_SCHED=y
CONFIG_CGROUP_PIDS=y
CONFIG_CGROUP_FREEZER=y
CONFIG_CPUSETS=y
CONFIG_CGROUP_DEVICE=y
CONFIG_CGROUP_CPUACCT=y
CONFIG_CGROUP_PERF=y
CONFIG_CGROUP_BPF=y
CONFIG_USER_NS=y
CONFIG_SCHED_AUTOGROUP=y
CONFIG_BLK_DEV_INITRD=y
CONFIG_KALLSYMS_ALL=y
CONFIG_PROFILING=y
CONFIG_KEXEC=y
CONFIG_ARCH_MULTI_V6=y
CONFIG_ARCH_MULTI_V7=y
CONFIG_ARCH_VIRT=y
CONFIG_ARCH_BCM=y
CONFIG_ARCH_BCM2835=y
CONFIG_SMP=y
CONFIG_NR_CPUS=4
CONFIG_CPU_FREQ=y
CONFIG_CPU_FREQ_STAT=y
CONFIG_CPU_FREQ_DEFAULT_GOV_CONSERVATIVE=y
CONFIG_CPU_FREQ_GOV_POWERSAVE=y
CONFIG_CPU_FREQ_GOV_USERSPACE=y
CONFIG_CPU_FREQ_GOV_ONDEMAND=y
CONFIG_CPUFREQ_DT=y
CONFIG_ARM_RASPBERRYPI_CPUFREQ=y
CONFIG_AEABI=y
CONFIG_VFP=y
CONFIG_NEON=y
CONFIG_KERNEL_MODE_NEON=y
# CONFIG_SUSPEND is not set
CONFIG_PM=y
CONFIG_JUMP_LABEL=y
# CONFIG_GCC_PLUGINS is not set
CONFIG_MODULES=y
CONFIG_MODULE_UNLOAD=y
CONFIG_PARTITION_ADVANCED=y
# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
# CONFIG_COMPAT_BRK is not set
CONFIG_KSM=y
CONFIG_CMA=y
CONFIG_NET=y
CONFIG_PACKET=y
CONFIG_XDP_SOCKETS=y
CONFIG_XDP_SOCKETS_DIAG=y
CONFIG_IP_MULTICAST=y
CONFIG_IP_ADVANCED_ROUTER=y
CONFIG_IP_MULTIPLE_TABLES=y
CONFIG_IP_ROUTE_MULTIPATH=y
CONFIG_NET_IPIP=m
CONFIG_NET_IPGRE_DEMUX=m
CONFIG_NET_IPGRE=m
CONFIG_NET_IPGRE_BROADCAST=y
CONFIG_IP_MROUTE=y
CONFIG_IP_MROUTE_MULTIPLE_TABLES=y
CONFIG_IP_PIMSM_V1=y
CONFIG_IP_PIMSM_V2=y
CONFIG_SYN_COOKIES=y
CONFIG_NET_IPVTI=m
CONFIG_NET_FOU_IP_TUNNELS=y
CONFIG_IPV6_SIT=m
CONFIG_IPV6_GRE=m
CONFIG_IPV6_MULTIPLE_TABLES=y
CONFIG_IPV6_SUBTREES=y
CONFIG_IPV6_MROUTE=y
CONFIG_IPV6_MROUTE_MULTIPLE_TABLES=y
CONFIG_IPV6_PIMSM_V2=y
CONFIG_NETWORK_PHY_TIMESTAMPING=y
CONFIG_NETFILTER=y
CONFIG_BRIDGE_NETFILTER=y
CONFIG_NETFILTER_NETLINK_QUEUE=y
CONFIG_NETFILTER_NETLINK_LOG=y
CONFIG_NF_CONNTRACK=y
CONFIG_NF_CONNTRACK_EVENTS=y
CONFIG_NF_CONNTRACK_FTP=y
CONFIG_NF_TABLES=y
CONFIG_NF_TABLES_INET=y
CONFIG_NF_TABLES_NETDEV=y
CONFIG_NFT_CT=m
CONFIG_NFT_CONNLIMIT=m
CONFIG_NFT_LOG=m
CONFIG_NFT_LIMIT=m
CONFIG_NFT_MASQ=m
CONFIG_NFT_REDIR=m
CONFIG_NFT_NAT=m
CONFIG_NFT_TUNNEL=m
CONFIG_NFT_QUEUE=m
CONFIG_NFT_REJECT=m
CONFIG_NFT_COMPAT=m
CONFIG_NFT_HASH=m
CONFIG_NFT_XFRM=m
CONFIG_NFT_SOCKET=m
CONFIG_NFT_OSF=m
CONFIG_NFT_DUP_NETDEV=m
CONFIG_NFT_FWD_NETDEV=m
CONFIG_NFT_REJECT_NETDEV=m
CONFIG_NETFILTER_XT_TARGET_CHECKSUM=m
CONFIG_NETFILTER_XT_TARGET_LOG=m
CONFIG_NETFILTER_XT_MATCH_ADDRTYPE=m
CONFIG_NETFILTER_XT_MATCH_BPF=m
CONFIG_NETFILTER_XT_MATCH_CGROUP=m
CONFIG_NETFILTER_XT_MATCH_COMMENT=m
CONFIG_NETFILTER_XT_MATCH_CONNLABEL=m
CONFIG_NETFILTER_XT_MATCH_CONNMARK=m
CONFIG_NETFILTER_XT_MATCH_CONNTRACK=m
CONFIG_NETFILTER_XT_MATCH_DSCP=m
CONFIG_NETFILTER_XT_MATCH_HELPER=m
CONFIG_NETFILTER_XT_MATCH_LIMIT=m
CONFIG_NETFILTER_XT_MATCH_MAC=m
CONFIG_NETFILTER_XT_MATCH_MARK=m
CONFIG_NETFILTER_XT_MATCH_MULTIPORT=m
CONFIG_NETFILTER_XT_MATCH_PHYSDEV=m
CONFIG_IP_NF_IPTABLES=m
CONFIG_IP_NF_FILTER=m
CONFIG_IP_NF_TARGET_REJECT=m
CONFIG_IP_NF_NAT=m
CONFIG_IP_NF_TARGET_MASQUERADE=m
CONFIG_IP_NF_MANGLE=m
CONFIG_IP6_NF_IPTABLES=m
CONFIG_IP6_NF_MATCH_AH=m
CONFIG_IP6_NF_MATCH_EUI64=m
CONFIG_IP6_NF_MATCH_IPV6HEADER=m
CONFIG_IP6_NF_FILTER=m
CONFIG_IP6_NF_TARGET_REJECT=m
CONFIG_IP6_NF_RAW=m
CONFIG_IP6_NF_NAT=m
CONFIG_IP6_NF_TARGET_MASQUERADE=m
CONFIG_IP6_NF_TARGET_NPT=m
CONFIG_NF_TABLES_BRIDGE=m
CONFIG_NFT_BRIDGE_META=m
CONFIG_NF_CONNTRACK_BRIDGE=m
CONFIG_BRIDGE_NF_EBTABLES=m
CONFIG_BRIDGE_EBT_BROUTE=m
CONFIG_BRIDGE_EBT_T_FILTER=m
CONFIG_BRIDGE_EBT_T_NAT=m
CONFIG_BRIDGE_EBT_802_3=m
CONFIG_BRIDGE_EBT_ARP=m
CONFIG_BRIDGE_EBT_IP=m
CONFIG_BRIDGE_EBT_IP6=m
CONFIG_BRIDGE_EBT_LIMIT=m
CONFIG_BRIDGE_EBT_PKTTYPE=m
CONFIG_BRIDGE_EBT_STP=m
CONFIG_BRIDGE_EBT_VLAN=m
CONFIG_BRIDGE_EBT_ARPREPLY=m
CONFIG_BRIDGE_EBT_DNAT=m
CONFIG_BRIDGE_EBT_REDIRECT=m
CONFIG_BRIDGE_EBT_SNAT=m
CONFIG_BRIDGE_EBT_LOG=m
CONFIG_BRIDGE_EBT_NFLOG=m
CONFIG_BRIDGE=y
CONFIG_BRIDGE_VLAN_FILTERING=y
CONFIG_BRIDGE_MRP=y
CONFIG_BRIDGE_CFM=y
CONFIG_NET_DSA=y
CONFIG_VLAN_8021Q=y
CONFIG_VLAN_8021Q_GVRP=y
CONFIG_VLAN_8021Q_MVRP=y
CONFIG_NET_SCHED=y
CONFIG_NET_SCH_MQPRIO=y
CONFIG_NET_CLS_BASIC=y
CONFIG_NET_CLS_BPF=y
CONFIG_NET_CLS_FLOWER=y
CONFIG_NET_CLS_ACT=y
CONFIG_NET_ACT_GACT=y
CONFIG_NET_ACT_MIRRED=y
CONFIG_NET_ACT_SKBEDIT=y
CONFIG_DCB=y
CONFIG_NETLINK_DIAG=y
CONFIG_MPLS=y
CONFIG_NET_MPLS_GSO=y
CONFIG_MPLS_ROUTING=m
CONFIG_MPLS_IPTUNNEL=m
CONFIG_NET_PKTGEN=y
# CONFIG_WIRELESS is not set
CONFIG_NET_9P=y
CONFIG_NET_9P_VIRTIO=y
CONFIG_LWTUNNEL=y
CONFIG_PCI=y
CONFIG_PCIEPORTBUS=y
CONFIG_PCI_IOV=y
CONFIG_PCI_AARDVARK=y
CONFIG_PCI_HOST_GENERIC=y
CONFIG_PCIE_ARMADA_8K=y
CONFIG_UEVENT_HELPER=y
CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
CONFIG_DEVTMPFS=y
CONFIG_DEVTMPFS_MOUNT=y
# CONFIG_STANDALONE is not set
CONFIG_RASPBERRYPI_FIRMWARE=y
CONFIG_FW_CFG_SYSFS=y
CONFIG_FW_CFG_SYSFS_CMDLINE=y
CONFIG_OF_OVERLAY=y
CONFIG_BLK_DEV_NULL_BLK=y
CONFIG_BLK_DEV_LOOP=y
CONFIG_BLK_DEV_RAM=y
CONFIG_VIRTIO_BLK=y
CONFIG_BLK_DEV_NVME=y
CONFIG_SRAM=y
CONFIG_EEPROM_AT24=y
# CONFIG_SCSI_PROC_FS is not set
CONFIG_SCSI=y
CONFIG_BLK_DEV_SD=y
CONFIG_SCSI_SAS_LIBSAS=y
CONFIG_SCSI_SAS_ATA=y
CONFIG_SCSI_VIRTIO=y
CONFIG_ATA=y
CONFIG_SATA_AHCI=y
CONFIG_SATA_MOBILE_LPM_POLICY=0
CONFIG_SATA_AHCI_PLATFORM=y
CONFIG_AHCI_MVEBU=y
CONFIG_PATA_OF_PLATFORM=y
CONFIG_MD=y
CONFIG_BLK_DEV_DM=y
CONFIG_DM_INIT=y
CONFIG_DM_VERITY=y
CONFIG_DM_VERITY_VERIFY_ROOTHASH_SIG=y
CONFIG_NETDEVICES=y
CONFIG_BONDING=m
CONFIG_DUMMY=m
CONFIG_MACVLAN=m
CONFIG_MACVTAP=m
CONFIG_IPVLAN=m
CONFIG_IPVTAP=m
CONFIG_VXLAN=m
CONFIG_GENEVE=m
CONFIG_BAREUDP=m
CONFIG_MACSEC=m
CONFIG_TUN=m
CONFIG_VETH=m
CONFIG_VIRTIO_NET=y
CONFIG_NLMON=y
CONFIG_NET_VRF=y
CONFIG_BCMGENET=y
CONFIG_SMSC911X=y
CONFIG_USB_LAN78XX=y
CONFIG_USB_USBNET=y
CONFIG_USB_NET_SMSC95XX=y
CONFIG_BRCMFMAC=m
CONFIG_ZD1211RW=m
CONFIG_INPUT_MOUSEDEV=m
CONFIG_INPUT_EVDEV=y
CONFIG_INPUT_TOUCHSCREEN=y
CONFIG_TOUCHSCREEN_EDT_FT5X06=m
# CONFIG_LEGACY_PTYS is not set
CONFIG_SERIAL_8250=y
CONFIG_SERIAL_8250_CONSOLE=y
CONFIG_SERIAL_8250_EXTENDED=y
CONFIG_SERIAL_8250_SHARE_IRQ=y
CONFIG_SERIAL_8250_BCM2835AUX=y
CONFIG_SERIAL_AMBA_PL011=y
CONFIG_SERIAL_AMBA_PL011_CONSOLE=y
CONFIG_SERIAL_DEV_BUS=y
CONFIG_TTY_PRINTK=y
CONFIG_HVC_DRIVER=y
CONFIG_VIRTIO_CONSOLE=y
CONFIG_I2C_CHARDEV=y
CONFIG_I2C_BCM2835=m
CONFIG_SPI=y
CONFIG_SPI_BCM2835=y
CONFIG_SPI_BCM2835AUX=y
CONFIG_GPIO_SYSFS=y
CONFIG_SENSORS_RASPBERRYPI_HWMON=m
CONFIG_THERMAL=y
CONFIG_BCM2711_THERMAL=y
CONFIG_BCM2835_THERMAL=m
CONFIG_WATCHDOG=y
CONFIG_BCM2835_WDT=y
CONFIG_I6300ESB_WDT=y
CONFIG_MFD_SYSCON=y
CONFIG_REGULATOR=y
CONFIG_REGULATOR_FIXED_VOLTAGE=y
CONFIG_REGULATOR_GPIO=y
CONFIG_MEDIA_SUPPORT=y
CONFIG_DRM=y
CONFIG_DRM_LOAD_EDID_FIRMWARE=y
CONFIG_DRM_PANEL_SIMPLE=m
CONFIG_DRM_TOSHIBA_TC358762=m
CONFIG_DRM_V3D=m
CONFIG_DRM_VC4=m
CONFIG_DRM_VC4_HDMI_CEC=y
CONFIG_DRM_SIMPLEDRM=y
CONFIG_FB=y
CONFIG_BACKLIGHT_CLASS_DEVICE=y
CONFIG_SOUND=y
CONFIG_SND=y
CONFIG_SND_SOC=y
CONFIG_SND_BCM2835_SOC_I2S=y
CONFIG_HID_GENERIC=m
CONFIG_USB=y
CONFIG_USB_OTG=y
CONFIG_USB_STORAGE=y
CONFIG_USB_DWC2=y
CONFIG_NOP_USB_XCEIV=y
CONFIG_USB_GADGET=y
CONFIG_USB_ETH=m
CONFIG_USB_ETH_EEM=y
CONFIG_USB_G_SERIAL=m
CONFIG_MMC=y
CONFIG_MMC_SDHCI=y
CONFIG_MMC_SDHCI_PLTFM=y
CONFIG_MMC_SDHCI_IPROC=y
CONFIG_MMC_BCM2835=y
CONFIG_NEW_LEDS=y
CONFIG_LEDS_CLASS=y
CONFIG_LEDS_GPIO=y
CONFIG_LEDS_TRIGGERS=y
CONFIG_LEDS_TRIGGER_TIMER=y
CONFIG_LEDS_TRIGGER_ONESHOT=y
CONFIG_LEDS_TRIGGER_HEARTBEAT=y
CONFIG_LEDS_TRIGGER_CPU=y
CONFIG_LEDS_TRIGGER_GPIO=y
CONFIG_LEDS_TRIGGER_DEFAULT_ON=y
CONFIG_LEDS_TRIGGER_TRANSIENT=y
CONFIG_LEDS_TRIGGER_CAMERA=y
CONFIG_DMADEVICES=y
CONFIG_DMA_BCM2835=y
CONFIG_VIRTIO_PCI=y
CONFIG_VIRTIO_BALLOON=y
CONFIG_VIRTIO_INPUT=y
CONFIG_VIRTIO_MMIO=y
CONFIG_STAGING=y
CONFIG_SND_BCM2835=m
CONFIG_VIDEO_BCM2835=m
CONFIG_CLK_RASPBERRYPI=y
CONFIG_MAILBOX=y
CONFIG_BCM2835_MBOX=y
# CONFIG_IOMMU_SUPPORT is not set
CONFIG_RASPBERRYPI_POWER=y
CONFIG_PWM=y
CONFIG_PWM_BCM2835=y
CONFIG_EXT2_FS=y
CONFIG_EXT3_FS=y
CONFIG_EXT4_FS_POSIX_ACL=y
CONFIG_BTRFS_FS=y
CONFIG_BTRFS_FS_POSIX_ACL=y
CONFIG_FANOTIFY=y
CONFIG_FANOTIFY_ACCESS_PERMISSIONS=y
CONFIG_QUOTA=y
CONFIG_FUSE_FS=y
CONFIG_VIRTIO_FS=y
CONFIG_OVERLAY_FS=y
CONFIG_VFAT_FS=y
CONFIG_EXFAT_FS=y
CONFIG_TMPFS=y
CONFIG_TMPFS_POSIX_ACL=y
CONFIG_SQUASHFS=y
CONFIG_SQUASHFS_LZO=y
CONFIG_SQUASHFS_XZ=y
CONFIG_SQUASHFS_ZSTD=y
CONFIG_9P_FS=y
CONFIG_NLS_CODEPAGE_437=y
CONFIG_NLS_ISO8859_1=y
CONFIG_NLS_UTF8=y
CONFIG_CRYPTO_CCM=y
CONFIG_CRYPTO_GCM=y
# CONFIG_XZ_DEC_ARM is not set
# CONFIG_XZ_DEC_ARMTHUMB is not set
CONFIG_DMA_CMA=y
CONFIG_CMA_SIZE_MBYTES=32
CONFIG_PRINTK_TIME=y
CONFIG_DEBUG_KERNEL=y
CONFIG_DEBUG_INFO_DWARF_TOOLCHAIN_DEFAULT=y
CONFIG_MAGIC_SYSRQ=y
CONFIG_DEBUG_FS=y
CONFIG_PANIC_ON_OOPS=y
CONFIG_PANIC_TIMEOUT=20
CONFIG_DETECT_HUNG_TASK=y
# CONFIG_SCHED_DEBUG is not set
# CONFIG_RCU_TRACE is not set
CONFIG_FUNCTION_TRACER=y
# CONFIG_STRICT_DEVMEM is not set
CONFIG_MEMTEST=y
-15
View File
@@ -1,15 +0,0 @@
config BR2_PACKAGE_RASPBERRYPI_RPI2
bool "Raspberry Pi 2 Model B (32-bit ARMv7)"
depends on BR2_arm
select SDCARD_AUX
select BR2_PACKAGE_FEATURE_WIFI
select BR2_PACKAGE_BRCMFMAC_SDIO_FIRMWARE_RPI
select BR2_PACKAGE_BRCMFMAC_SDIO_FIRMWARE_RPI_WIFI
help
Support for the 32-bit ARMv7 Raspberry Pi 2B single-board computer
(SBC) with BCM2836 quad-core Cortex-A7 processor.
This was the only Raspberry Pi model with the BCM2836 and the 2B
actually got a BCM2837 (Cortex-A53) underclocked an w/o wifi in
the v1.2 board revision.
-13
View File
@@ -1,13 +0,0 @@
Copyright (c) 2025 The KernelKit Authors
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-96
View File
@@ -1,96 +0,0 @@
Raspberry Pi 2 Model B
======================
The [Raspberry Pi 2 Model B][1] is a 32-bit ARM single-board computer,
powered by the Broadcom BCM2836 quad-core Cortex-A7 processor @ 900 MHz
with 1 GB RAM.
The board features:
- 4x USB 2.0 ports
- Fast Ethernet (100 Mbps)
- microSD card slot for storage
- HDMI port
- GPIO header (40-pin)
> [!NOTE]
> Revision 1.2 of the Pi 2B actually uses a BCM2837 (Cortex-A53) underclocked
> and without WiFi, making it very similar to the Pi 3B hardware-wise but
> running in 32-bit mode. This revision is not supported.
How to Build
------------
Since there are no pre-built images for ARM32, you need to build both Infix
and the bootloader from source.
1. Clone the repository
git clone https://github.com/kernelkit/infix.git
cd infix
2. Build the bootloader (in separate tree)
make O=x-boot rpi2_boot_defconfig
make O=x-boot
3. Build Infix (in another tree)
make O=x-arm32 aarch32_defconfig
make O=x-arm32
4. Create the SD card image
./utils/mkimage.sh -b x-boot -r x-arm32 raspberrypi-rpi2
The resulting image can be found in `x-boot/images/infix-arm-sdcard.img`
Flashing to SD Card
-------------------
[Flash the image][0] to a microSD card (at least 4 GB):
```bash
sudo dd if=x-boot/images/infix-arm-sdcard.img of=/dev/mmcblk0 \
bs=1M status=progress oflag=direct
```
You can also use `bmaptool`:
```bash
sudo bmaptool copy x-boot/images/infix-rpi2-sdcard.img /dev/mmcblk0
```
> [!WARNING]
> Ensure `/dev/mmcblk0` is the correct device for your SD card and not used by
> the host system! Use `lsblk` to verify.
Booting the Board
-----------------
1. Insert the flashed SD card into the Raspberry Pi
2. Connect an Ethernet cable (DHCP will be used to get an IP address)
3. Power up the board using a 5V/2.5A micro-USB power supply
The board will boot and obtain an IP address via DHCP on the Ethernet port.
Find the assigned IP and SSH in with the default login credentials, user/pass:
`admin` / `admin`.
Console Port (Optional)
-----------------------
A serial console can be useful for debugging. Connect a USB-to-TTL
serial adapter (3.3V) to GPIO pins:
- GND → Pin 6, ground
- TxD → Pin 8, GPIO 14
- RxD → Pin 10, GPIO 15
Serial settings: 115200 8N1
> [!WARNING]
> Use only 3.3V serial adapters. 5V adapters will damage your Raspberry Pi!
[0]: https://kernelkit.org/posts/flashing-sdcard/
[1]: https://www.raspberrypi.com/products/raspberry-pi-2-model-b/
-11
View File
@@ -1,11 +0,0 @@
#!/bin/sh
mkdir /mnt/primary
mount /dev/disk0.primary /mnt/primary
global.bootm.image="/mnt/primary/boot/zImage"
global.bootm.oftree="/mnt/primary/boot/broadcom/bcm2836-rpi-2-b.dtb"
global.linux.bootargs.base="quiet console=ttyAMA0,115200 console=tty1 rauc.slot=primary"
global.linux.bootargs.dyn.root="root=PARTLABEL=primary rootwait ro"
bootm
-12
View File
@@ -1,12 +0,0 @@
#!/bin/sh
# Barebox configuration for Raspberry Pi 2
# Boot timeout (seconds)
global autoboot_timeout=3
# Default boot order
global boot.default="mmc net"
# Enable colored output if supported
global allow_color=true
@@ -1,5 +0,0 @@
#!/bin/sh
# Automount MMC partitions
mkdir -p /mnt/mmc
automount /mnt/mmc 'mci0.probe=1 && mount /dev/disk0.0 /mnt/mmc'
@@ -1,4 +0,0 @@
#!/bin/sh
# Set boot order: try mmc first, then network
global.boot.default="mmc net"
@@ -1,17 +0,0 @@
# Minimal Barebox configuration for Raspberry Pi 2
# Basic boot only - A/B partitioning and secure boot to be added later
# Enable custom embedded environment
CONFIG_DEFAULT_ENVIRONMENT=y
CONFIG_DEFAULT_ENVIRONMENT_GENERIC_NEW=y
# Enable GPT partition table support for hybrid partition tables
CONFIG_PARTITION_DISK_EFI=y
# Enable SquashFS support for reading rootfs
CONFIG_FS_SQUASHFS=y
CONFIG_FS_SQUASHFS_LZ4=y
CONFIG_FS_SQUASHFS_LZO=y
CONFIG_FS_SQUASHFS_XZ=y
CONFIG_FS_SQUASHFS_ZLIB=y
CONFIG_FS_SQUASHFS_ZSTD=y
@@ -1 +0,0 @@
root=/dev/mmcblk0p2 rootwait console=tty1 console=ttyAMA0,115200
-19
View File
@@ -1,19 +0,0 @@
# Raspberry Pi bootloader (start.elf) configuration
#
# uart_2ndstage=1 - Enable early boot debug output from the bootloader
# Useful for debugging boot failures before Barebox starts
# Comment out for production to reduce boot noise
[all]
kernel=barebox-raspberry-pi-2.img
disable_overscan=1
enable_uart=1
#uart_2ndstage=1
[pi2]
start_file=start.elf
fixup_file=fixup.dat
gpu_mem=100
@@ -1 +0,0 @@
dtb-y += broadcom/bcm2836-rpi-2-b.dtb
@@ -1 +0,0 @@
# Placeholder - dtb-y is defined in parent Makefile
@@ -1,19 +0,0 @@
#include <arm/broadcom/bcm2836-rpi-2-b.dts>
#include "infix.dtsi"
/ {
/* CMA pool for GPU and video */
reserved-memory {
#address-cells = <1>;
#size-cells = <1>;
ranges;
cma-reserved {
compatible = "shared-dma-pool";
size = <0x4000000>; /* 64MB */
alignment = <0x1000000>; /* 16MB aligned */
linux,cma-default;
reusable;
};
};
};
@@ -1,13 +0,0 @@
// SPDX-License-Identifier: GPL-2.0
/*
* Common Infix OS defaults
*/
/ {
chosen {
infix {
/* Default admin user password: 'admin' */
factory-password-hash = "$5$mI/zpOAqZYKLC2WU$i7iPzZiIjOjrBF3NyftS9CCq8dfYwHwrmUK097Jca9A";
};
};
};
@@ -1,78 +0,0 @@
image boot.vfat {
vfat {
files = {
#BOOT_FILES#
}
}
size = 32M
}
image cfg.ext4 {
empty = true
temporary = true
size = 16M
ext4 {
label = "cfg"
use-mke2fs = true
features = "uninit_bg"
extraargs = "-m 0 -i 4096"
}
}
# The /var partition will be expanded automatically at first boot
# to use the full size of the SD-card or eMMC media.
image var.ext4 {
empty = true
temporary = true
size = 128M
ext4 {
label = "var"
use-mke2fs = true
features = "uninit_bg"
extraargs = "-m 0 -i 4096"
}
}
image #INFIX_ID##VERSION#-rpi2-sdcard.img {
hdimage {
partition-table-type = "hybrid"
}
partition boot {
partition-type = 0xc
bootable = "true"
image = "boot.vfat"
}
partition aux {
partition-type-uuid = srv
image = "aux.ext4"
}
partition primary {
partition-type-uuid = linux
bootable = "true"
size = 250M
image = "rootfs.squashfs"
}
partition secondary {
partition-type-uuid = linux
bootable = "true"
size = 250M
image = "rootfs.squashfs"
}
partition cfg {
partition-type-uuid = srv
image = "cfg.ext4"
}
partition var {
partition-type-uuid = var
image = "var.ext4"
}
}
@@ -1,61 +0,0 @@
# Raspberry Pi 2 Model B specific kernel configuration
define RASPBERRYPI_RPI2_LINUX_CONFIG_FIXUPS
$(call KCONFIG_ENABLE_OPT,CONFIG_SOUND)
$(call KCONFIG_ENABLE_OPT,CONFIG_SND)
$(call KCONFIG_ENABLE_OPT,CONFIG_SND_SOC)
$(call KCONFIG_ENABLE_OPT,CONFIG_INPUT_MOUSE)
$(call KCONFIG_ENABLE_OPT,CONFIG_INPUT_KEYBOARD)
$(call KCONFIG_ENABLE_OPT,CONFIG_INPUT_TOUCHSCREEN)
$(call KCONFIG_SET_OPT,CONFIG_INPUT_MOUSEDEV,m)
$(call KCONFIG_SET_OPT,CONFIG_HID_GENERIC,m)
$(call KCONFIG_ENABLE_OPT,CONFIG_ARCH_BCM)
$(call KCONFIG_ENABLE_OPT,CONFIG_ARCH_BCM2835)
$(call KCONFIG_SET_OPT,CONFIG_BCM2835_MBOX,y)
$(call KCONFIG_ENABLE_OPT,CONFIG_BCM2835_WDT)
$(call KCONFIG_ENABLE_OPT,CONFIG_DMA_BCM2835)
$(call KCONFIG_ENABLE_OPT,CONFIG_RASPBERRYPI_FIRMWARE)
$(call KCONFIG_ENABLE_OPT,CONFIG_PINCTRL_BCM2835)
$(call KCONFIG_ENABLE_OPT,CONFIG_GPIO_BCM2835)
$(call KCONFIG_SET_OPT,CONFIG_BRCMFMAC,m)
$(call KCONFIG_ENABLE_OPT,CONFIG_BRCMFMAC_SDIO)
$(call KCONFIG_SET_OPT,CONFIG_I2C_BCM2835,m)
$(call KCONFIG_SET_OPT,CONFIG_BCM2835_THERMAL,m)
$(call KCONFIG_ENABLE_OPT,CONFIG_MMC_BCM2835)
$(call KCONFIG_ENABLE_OPT,CONFIG_RASPBERRYPI_POWER)
$(call KCONFIG_ENABLE_OPT,CONFIG_SERIAL_8250)
$(call KCONFIG_ENABLE_OPT,CONFIG_SERIAL_8250_CONSOLE)
$(call KCONFIG_ENABLE_OPT,CONFIG_SERIAL_8250_BCM2835AUX)
$(call KCONFIG_ENABLE_OPT,CONFIG_SERIAL_8250_EXTENDED)
$(call KCONFIG_ENABLE_OPT,CONFIG_SERIAL_8250_SHARE_IRQ)
$(call KCONFIG_ENABLE_OPT,CONFIG_NET_VENDOR_BROADCOM)
$(call KCONFIG_SET_OPT,CONFIG_SMSC911X,y)
$(call KCONFIG_SET_OPT,CONFIG_REGULATOR_GPIO,y)
$(call KCONFIG_ENABLE_OPT,CONFIG_COMMON_CLK_BCM2835)
$(call KCONFIG_ENABLE_OPT,CONFIG_CLK_RASPBERRYPI)
$(call KCONFIG_ENABLE_OPT,CONFIG_DRM)
$(call KCONFIG_ENABLE_OPT,CONFIG_DRM_KMS_HELPER)
$(call KCONFIG_SET_OPT,CONFIG_DRM_V3D,m)
$(call KCONFIG_SET_OPT,CONFIG_DRM_VC4,m)
$(call KCONFIG_SET_OPT,CONFIG_STAGING,y)
$(call KCONFIG_SET_OPT,CONFIG_SND_BCM2835,m)
$(call KCONFIG_ENABLE_OPT,CONFIG_DRM_VC4_HDMI_CEC)
$(call KCONFIG_ENABLE_OPT,CONFIG_DRM_LOAD_EDID_FIRMWARE)
$(call KCONFIG_ENABLE_OPT,CONFIG_DRM_PANEL_BRIDGE)
$(call KCONFIG_ENABLE_OPT,CONFIG_DRM_BRIDGE)
$(call KCONFIG_SET_OPT,CONFIG_DRM_TOSHIBA_TC358762,m)
$(call KCONFIG_SET_OPT,CONFIG_DRM_PANEL_SIMPLE,m)
$(call KCONFIG_ENABLE_OPT,CONFIG_FB)
$(call KCONFIG_ENABLE_OPT,CONFIG_FRAMEBUFFER_CONSOLE)
$(call KCONFIG_ENABLE_OPT,CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY)
$(call KCONFIG_ENABLE_OPT,CONFIG_DRM_FBDEV_EMULATION)
$(call KCONFIG_SET_OPT,CONFIG_TOUCHSCREEN_EDT_FT5X06,m)
$(call KCONFIG_ENABLE_OPT,CONFIG_BACKLIGHT_CLASS_DEVICE)
endef
$(eval $(ix-board))
$(eval $(generic-package))
@@ -1,206 +0,0 @@
{
"ieee802-dot1ab-lldp:lldp": {
"infix-lldp:enabled": true
},
"ietf-hardware:hardware": {
"component": [
{
"name": "USB",
"class": "infix-hardware:usb",
"state": {
"admin-state": "unlocked"
}
}
]
},
"ietf-interfaces:interfaces": {
"interface": [
{
"name": "lo",
"type": "infix-if-type:loopback",
"ietf-ip:ipv4": {
"address": [
{
"ip": "127.0.0.1",
"prefix-length": 8
}
]
},
"ietf-ip:ipv6": {
"address": [
{
"ip": "::1",
"prefix-length": 128
}
]
}
},
{
"name": "eth0",
"type": "infix-if-type:ethernet",
"ietf-ip:ipv4": {
"infix-dhcp-client:dhcp": {
"option": [
{"id": "netmask"},
{"id": "broadcast"},
{"id": "router"},
{"id": "domain"},
{"id": "hostname"},
{"id": "dns-server"},
{"id": "ntp-server"},
{"id": "vendor-class", "value": "Raspberry Pi 2 Model B"}
]
}
}
}
]
},
"ietf-keystore:keystore": {
"asymmetric-keys": {
"asymmetric-key": [
{
"name": "genkey",
"public-key-format": "infix-crypto-types:ssh-public-key-format",
"public-key": "",
"private-key-format": "infix-crypto-types:rsa-private-key-format",
"cleartext-private-key": "",
"certificates": {}
}
]
}
},
"ietf-netconf-acm:nacm": {
"enable-nacm": true,
"groups": {
"group": [
{
"name": "admin",
"user-name": [
"admin"
]
}
]
},
"rule-list": [
{
"name": "admin-acl",
"group": [
"admin"
],
"rule": [
{
"name": "permit-all",
"module-name": "*",
"access-operations": "*",
"action": "permit",
"comment": "Allow 'admin' group complete access to all operations and data."
}
]
},
{
"name": "default-deny-all",
"group": [
"*"
],
"rule": [
{
"name": "deny-password-read",
"module-name": "ietf-system",
"path": "/ietf-system:system/authentication/user/password",
"access-operations": "*",
"action": "deny"
}
]
}
]
},
"ietf-netconf-server:netconf-server": {
"listen": {
"endpoints": {
"endpoint": [
{
"name": "default-ssh",
"ssh": {
"tcp-server-parameters": {
"local-address": "::"
},
"ssh-server-parameters": {
"server-identity": {
"host-key": [
{
"name": "default-key",
"public-key": {
"central-keystore-reference": "genkey"
}
}
]
}
}
}
}
]
}
}
},
"ietf-system:system": {
"hostname": "rpi-%m",
"ntp": {
"enabled": true,
"server": [
{
"name": "ntp.org",
"udp": {
"address": "pool.ntp.org"
},
"iburst": true
}
]
},
"authentication": {
"user": [
{
"name": "admin",
"password": "$factory$",
"infix-system:shell": "bash"
}
]
},
"infix-system:motd-banner": "Li0tLS0tLS0uCnwgIC4gLiAgfCBJbmZpeCBPUyDigJQgSW1tdXRhYmxlLkZyaWVuZGx5LlNlY3VyZQp8LS4gdiAuLXwgaHR0cHM6Ly9rZXJuZWxraXQub3JnCictJy0tLSctJwo="
},
"infix-meta:meta": {
"version": "1.6"
},
"infix-services:mdns": {
"enabled": true
},
"infix-services:web": {
"enabled": true,
"console": {
"enabled": true
},
"netbrowse": {
"enabled": true
},
"restconf": {
"enabled": true
}
},
"infix-services:ssh": {
"enabled": true,
"hostkey": [
"genkey"
],
"listen": [
{
"name": "ipv4",
"address": "0.0.0.0",
"port": 22
},
{
"name": "ipv6",
"address": "::",
"port": 22
}
]
}
}
@@ -1,8 +0,0 @@
{
"eth0": {
"phy-detached-when-down": true
},
"@ethtool:driver=smsc95xx": {
"broken-flow-control": true
}
}
@@ -1,13 +0,0 @@
# CONFIG_MMC_PCI is not set
CONFIG_OF_OVERLAY_LIST="rpi-env infix-key"
# CONFIG_ENV_IS_IN_FAT is not set
# Increase early malloc heap to handle DTB with embedded scripts
CONFIG_SYS_MALLOC_F_LEN=0x2000
# Compression support needed for SquashFS
CONFIG_LZ4=y
CONFIG_LZMA=y
CONFIG_CMD_LZMADEC=y
CONFIG_CMD_UNLZ4=y
CONFIG_CMD_UNZIP=y
@@ -1,27 +0,0 @@
/dts-v1/;
/plugin/;
&{/} {
config {
environment {
vendor = "infix";
preboot = "run ixpreboot";
ixbootdelay = "0.5";
bootdelay = "-2";
bootmenu_delay = "10";
boot_targets = "mmc0";
ethprime = "eth0";
bootcmd = "run ixboot";
ixpreboot = /incbin/("scripts/ixpreboot.sh");
ixbtn-devmode = "setenv dev_mode yes; echo Enabled";
ixbtn-factory = "echo \"No button available, use bootmenu\"";
ixfactory = /incbin/("scripts/ixfactory.sh");
ixboot = /incbin/("scripts/ixboot.sh");
ixbootslot = /incbin/("scripts/ixbootslot.sh");
ixprepblk = /incbin/("scripts/ixprepblk.sh");
ixprepdhcp = /incbin/("scripts/ixprepdhcp.sh");
};
};
};
-13
View File
@@ -1,13 +0,0 @@
if BR2_aarch64
source "$BR2_EXTERNAL_INFIX_PATH/board/aarch64/alder-alder/Config.in"
source "$BR2_EXTERNAL_INFIX_PATH/board/aarch64/bananapi-bpi-r3/Config.in"
source "$BR2_EXTERNAL_INFIX_PATH/board/aarch64/freescale-imx8mp-evk/Config.in"
source "$BR2_EXTERNAL_INFIX_PATH/board/aarch64/friendlyarm-nanopi-r2s/Config.in"
source "$BR2_EXTERNAL_INFIX_PATH/board/aarch64/marvell-cn9130-crb/Config.in"
source "$BR2_EXTERNAL_INFIX_PATH/board/aarch64/marvell-espressobin/Config.in"
source "$BR2_EXTERNAL_INFIX_PATH/board/aarch64/microchip-sparx5-pcb135/Config.in"
source "$BR2_EXTERNAL_INFIX_PATH/board/aarch64/raspberrypi-rpi64/Config.in"
source "$BR2_EXTERNAL_INFIX_PATH/board/aarch64/styx-dcp-sc-28p/Config.in"
endif
+63 -7
View File
@@ -1,11 +1,67 @@
aarch64
=======
Board Specific Documentation
----------------------------
Microchip SparX-5i PCB135 (eMMC)
--------------------------------
- [Banana Pi R3](banana-pi-r3/)
- [Marvell CN9130-CRB](cn9130-crb/)
- [Microchip SparX-5i PCB135 (eMMC)](sparx5-pcb135/)
- [NanoPi R2S](r2s/)
- [Raspberry Pi 64-bit](raspberry-pi64/)
At present, only FIT images are supported via the SparX-5i eval
board's U-Boot, which must contain a valid load address. If you are
using this board, after selecting your base configuration, run the
following command to supplement the existing config with the required
FIT options:
make board-enable-sparx-fit
### Unbricking
1. Don't load a corrupt bootloader to begin with
2. Done
If, for some reason, you didn't manage to follow step 1, you can use
the `FLASH_PROG`(`J4`) connector on the board to access the SPI flash
directly.
Using a [Bus Blaster][BB3] in combination with [dangerspi][dangerspi],
you can load a new bootloader. The schematic below details how to
connect the Bus Blaster to the board, but the concept should be
portable to any debugger/device based around an FTDI2232 chip.
```
Bus Blaster: FLASH_PROG (J4):
.---. .---.
VTG >o o| VTG SCK >o o| GND
TRST |o o| GND MISO |o o| #RESET_FLASH
TDI |o o| GND o o| 3V3
TMS |o o| GND #CS |o o| #SYSRESET
TCK o o| GND MOSI |o o| GND
RTCK o o| GND '---'
TDO |o o| GND
TSRST |o o| GND
DBGRQ |o o| GND
DBGACK |o o| GND
'---'
```
| Bus Blaster | FLASH_PROG |
|-------------|----------------|
| `VTG` | `3V3` |
| `GND` | `GND` |
| | |
| `VTG` | `#RESET_FLASH` |
| `GND` | `#SYSRESET` |
| | |
| `TDI` | `MOSI` |
| `TMS` | `#CS` |
| `TCK` | `SCK` |
| `TDO` | `MISO` |
With the cable in place, build U-Boot with the correct configuration:
make fireant_boot_defconfig && make
To flash it to the board, connect the cable to `J4` and run:
make board-sparx-flash-uboot
[BB3]: http://dangerousprototypes.com/docs/Bus_Blaster#Bus_Blaster_v3
[dangerspi]: https://github.com/wkz/dangerspi
-5
View File
@@ -1,5 +0,0 @@
config BR2_PACKAGE_ALDER_ALDER
bool "Alder"
depends on BR2_aarch64
help
Alder
-13
View File
@@ -1,13 +0,0 @@
Copyright (c) 2024 The KernelKit Authors
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-2
View File
@@ -1,2 +0,0 @@
$(eval $(ix-board))
$(eval $(generic-package))
-1
View File
@@ -1 +0,0 @@
dtb-y += alder/alder.dtb
@@ -1,76 +0,0 @@
#ifndef _ALDER_MPP_H
#define _ALDER_MPP_H
#define CP_SMI_MDIO(X) X( "mpp0", none, 0, 0)
#define CP_SMI_MDC(X) X( "mpp1", none, 0, 0)
#define CP_XSMI_MDIO(X) X( "mpp2", none, 0, 0)
#define CP_XSMI_MDC(X) X( "mpp3", none, 0, 0)
/* mpp4: Unused */
/* mpp5: Unused */
/* mpp6: Unused */
#define SFP9_TX_FAULT(X) X( "mpp7", cp0_gpio1, 7, GPIO_ACTIVE_HIGH)
#define SFP9_TX_DISABLE(X) X( "mpp8", cp0_gpio1, 8, GPIO_ACTIVE_HIGH)
#define SFP9_MOD_ABS(X) X( "mpp9", cp0_gpio1, 9, GPIO_ACTIVE_LOW)
#define SW_RESETn(X) X("mpp10", cp0_gpio1, 10, GPIO_ACTIVE_LOW)
#define SFP9_RS0(X) X("mpp11", cp0_gpio1, 11, GPIO_ACTIVE_HIGH)
/* mpp12: Unused */
#define CP_SPI1_MISO(X) X("mpp13", none, 0, 0)
#define CP_SPI1_CS0(X) X("mpp14", none, 0, 0)
#define CP_SPI1_MOSI(X) X("mpp15", none, 0, 0)
#define CP_SPI1_SCK(X) X("mpp16", none, 0, 0)
#define WDT_TICKLE(X) X("mpp17", cp0_gpio1, 17, GPIO_ACTIVE_HIGH)
/* mpp18: Unused */
/* mpp19: Unused */
/* mpp20: Unused */
/* mpp21: Unused */
/* mpp22: Unused */
/* mpp23: Unused */
#define DDR_TEN(X) X("mpp24", cp0_gpio1, 24, GPIO_ACTIVE_HIGH)
#define ETH9_RESETn(X) X("mpp25", cp0_gpio1, 25, GPIO_ACTIVE_LOW)
#define SW_INTn(X) X("mpp26", cp0_gpio1, 26, IRQ_TYPE_LEVEL_LOW)
#define SFP9_RS1(X) X("mpp27", cp0_gpio1, 27, GPIO_ACTIVE_HIGH)
#define SFP10_TX_FAULT(X) X("mpp28", cp0_gpio1, 28, GPIO_ACTIVE_HIGH)
#define CP_UA0_RXD(X) X("mpp29", none, 0, 0)
#define CP_UA0_TXD(X) X("mpp30", none, 0, 0)
#define SFP10_TX_DISABLE(X) X("mpp31", cp0_gpio1, 31, GPIO_ACTIVE_HIGH)
#define SFP10_MOD_ABS(X) X("mpp32", cp0_gpio2, 0, GPIO_ACTIVE_LOW)
#define I2C_IRQ(X) X("mpp33", cp0_gpio2, 1, IRQ_TYPE_LEVEL_LOW)
#define SFP10_RS0(X) X("mpp34", cp0_gpio2, 2, GPIO_ACTIVE_HIGH)
#define CP_I2C1_SDA(X) X("mpp35", none, 0, 0)
#define CP_I2C1_SCK(X) X("mpp36", none, 0, 0)
#define CP_I2C0_SCK(X) X("mpp37", none, 0, 0)
#define CP_I2C0_SDA(X) X("mpp38", none, 0, 0)
#define SFP10_RX_LOS(X) X("mpp39", cp0_gpio2, 7, GPIO_ACTIVE_HIGH)
#define SFP10_RS1(X) X("mpp40", cp0_gpio2, 8, GPIO_ACTIVE_HIGH)
#define CP_SD_CRD_PWR_OFF(X) X("mpp41", none, 0, 0)
#define CP_SD_HST_18_EN(X) X("mpp42", none, 0, 0)
#define CP_SD_CRD_DT(X) X("mpp43", none, 0, 0)
#define ETH9_INTn(X) X("mpp44", cp0_gpio2, 12, GPIO_ACTIVE_LOW)
/* mpp45: Unused */
#define ETH10_RESETn(X) X("mpp46", cp0_gpio2, 14, GPIO_ACTIVE_LOW)
#define I2C_RESETn(X) X("mpp47", cp0_gpio2, 15, GPIO_ACTIVE_LOW)
#define ETH10_INTn(X) X("mpp48", cp0_gpio2, 16, GPIO_ACTIVE_LOW)
#define DEV_MODEn(X) X("mpp49", cp0_gpio2, 17, GPIO_ACTIVE_LOW)
#define USB1_VBUS_ENABLE(X) X("mpp50", cp0_gpio2, 18, GPIO_ACTIVE_HIGH)
#define USB1_VBUS_ERROR_OC(X) X("mpp51", cp0_gpio2, 19, GPIO_ACTIVE_HIGH)
/* mpp52: Unused */
#define SFP9_RX_LOS(X) X("mpp53", cp0_gpio2, 21, GPIO_ACTIVE_HIGH)
/* mpp54: Unused */
#define CP_SD_LED(X) X("mpp55", none, 0, 0)
#define CP_SD_CLK(X) X("mpp56", none, 0, 0)
#define CP_SD_CMD(X) X("mpp57", none, 0, 0)
#define CP_SD_D0(X) X("mpp58", none, 0, 0)
#define CP_SD_D1(X) X("mpp59", none, 0, 0)
#define CP_SD_D2(X) X("mpp60", none, 0, 0)
#define CP_SD_D3(X) X("mpp61", none, 0, 0)
/* mpp62: Unused */
/* Macros to extract MPP info in different formats */
#define MPP_ID(_mpp, _chip, _no, _flags) _mpp
#define MPP_GPIO_CHIP(_mpp, _chip, _no, _flags) _chip
#define MPP_GPIO_REF(_mpp, _chip, _no, _flags) <&_chip _no _flags>
#define MPP_GPIO_REF_NO_CHIP(_mpp, _chip, _no, _flags) <_no _flags>
#define MPP_IRQ_REF(_mpp, _chip, _no, _flags) <&_chip _no _flags>
#endif /* _ALDER_MPP_H */
@@ -1,9 +0,0 @@
// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
/*
* Copyright (C) 2021 Marvell International Ltd.
* Copyright (C) 2023 Addiva Elektronik AB
*
* Device tree for Alder board
*/
#include "alder.dtsi"
@@ -1,719 +0,0 @@
// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
/*
* Copyright (C) 2021 Marvell International Ltd.
* Copyright (C) 2023 Addiva Elektronik AB
*
* Device tree for Alder board
*/
#include <dt-bindings/input/input.h>
#include <dt-bindings/gpio/gpio.h>
#include <dt-bindings/leds/common.h>
#include "../marvell/cn9130-patched.dtsi"
#include "alder-mpp.h"
/ {
model = "Alder";
compatible = "alder,alder",
"marvell,armada-ap807-quad",
"marvell,armada-ap807";
chosen {
stdout-path = "serial0:115200n8";
infix {
vpds = <&vpd_cpu &vpd_product &vpd_power>;
usb-ports = <&cp0_usb3_1>;
usb-port-names = "USB";
};
};
memory@0 {
device_type = "memory";
reg = <0x0 0x0 0x0 0x80000000>;
};
};
/* UART0 (Console) */
&cp0_pinctrl {
cp0_uart0_pins: cp0-uart0-pins {
marvell,pins = CP_UA0_RXD(MPP_ID), CP_UA0_TXD(MPP_ID);
marvell,function = "uart0";
};
};
&uart0 {
status = "okay";
pinctrl-names = "default";
pinctrl-0 = <&cp0_uart0_pins>;
};
/* GPIO */
&cp0_gpio1 {
status = "okay";
};
&cp0_gpio2 {
status = "okay";
};
/* I2C0 (EEPROM) */
&cp0_pinctrl {
cp0_i2c0_pins: cp0-i2c0-pins {
marvell,pins = CP_I2C0_SCK(MPP_ID), CP_I2C0_SDA(MPP_ID);
marvell,function = "i2c0";
};
};
&cp0_i2c0 {
status = "okay";
pinctrl-names = "default";
pinctrl-0 = <&cp0_i2c0_pins>;
vpd_cpu: eeprom@50 {
// AT24C256C-MAHL-T
compatible = "atmel,24c256";
reg = <0x50>;
infix,board = "cpu";
infix,trusted;
};
};
/* I2C1 (Mux) */
&cp0_pinctrl {
cp0_i2c1_pins: cp0-i2c1-pins {
marvell,pins = CP_I2C1_SCK(MPP_ID), CP_I2C1_SDA(MPP_ID);
marvell,function = "i2c1";
};
};
&cp0_i2c1 {
status = "okay";
pinctrl-names = "default";
pinctrl-0 = <&cp0_i2c1_pins>;
i2cmux@70 {
compatible = "nxp,pca9548";
#address-cells = <1>;
#size-cells = <0>;
reg = <0x70>;
reset-gpios = I2C_RESETn(MPP_GPIO_REF);
i2c_sysmgmt: i2c@0 {
#address-cells = <1>;
#size-cells = <0>;
reg = <0>;
};
i2c_pwr: i2c@1 {
#address-cells = <1>;
#size-cells = <0>;
reg = <1>;
};
i2c_sw: i2c@2 {
#address-cells = <1>;
#size-cells = <0>;
reg = <2>;
};
i2c_sfp9: i2c@3 {
#address-cells = <1>;
#size-cells = <0>;
reg = <3>;
};
i2c_sfpa: i2c@4 {
#address-cells = <1>;
#size-cells = <0>;
reg = <4>;
};
i2c@5 {
status = "disabled";
#address-cells = <1>;
#size-cells = <0>;
reg = <5>;
};
i2c@6 {
status = "disabled";
#address-cells = <1>;
#size-cells = <0>;
reg = <6>;
};
i2c@7 {
status = "disabled";
#address-cells = <1>;
#size-cells = <0>;
reg = <7>;
};
};
};
/* System Management */
&i2c_sysmgmt {
vpd_product: eeprom@b {
label = "vpd";
reg = <0x0b>;
compatible = "atmel,24c02";
infix,board = "product";
nvmem-layout {
compatible = "onie,tlv-layout";
base_mac: mac-address {
#nvmem-cell-cells = <1>;
};
};
};
};
/* AP SDHCI (eMMC) */
&ap_sdhci0 {
status = "okay";
pinctrl-names = "default";
/* pinctrl-0 = <&ap_emmc_pins>; No pinctrl in Linux? */
bus-width = <8>;
mmc-ddr-1_8v;
mmc-hs400-1_8v;
};
/* SPI1 (Boot FLASH) */
&cp0_pinctrl {
cp0_spi1_pins: cp0-spi-pins-0 {
marvell,pins = \
CP_SPI1_MISO(MPP_ID), CP_SPI1_CS0(MPP_ID), \
CP_SPI1_MOSI(MPP_ID), CP_SPI1_SCK(MPP_ID);
marvell,function = "spi1";
};
};
&cp0_spi1 {
status = "okay";
pinctrl-names = "default";
pinctrl-0 = <&cp0_spi1_pins>;
/* Boot flash */
spi-flash@0 {
#address-cells = <0x1>;
#size-cells = <0x1>;
compatible = "jedec,spi-nor", "spi-flash";
reg = <0x0>;
/* On-board MUX does not allow higher frequencies */
spi-max-frequency = <40000000>;
partitions {
compatible = "fixed-partitions";
#address-cells = <1>;
#size-cells = <1>;
boot0@0 {
label = "boot0";
reg = <0x0 0x200000>;
};
boot1@200000 {
label = "boot1";
reg = <0x200000 0x200000>;
};
};
};
};
/* USB1 */
/ {
cp0_usb3_0_phy1: cp0_usb3_phy {
compatible = "usb-nop-xceiv";
vcc-supply = <&reg_cp0_usb3_vbus1>;
};
reg_cp0_usb3_vbus1: reg_cp0_usb3_vbus1 {
compatible = "regulator-fixed";
regulator-name = "cp0-xhci1-vbus";
regulator-min-microvolt = <5000000>;
regulator-max-microvolt = <5000000>;
enable-active-high;
gpio = USB1_VBUS_ENABLE(MPP_GPIO_REF);
};
};
&cp0_utmi {
status = "okay";
};
&cp0_utmi1 {
status = "okay";
dr_mode = "host";
};
&cp0_usb3_1 {
status = "okay";
usb-phy = <&cp0_usb3_0_phy1>;
phys = <&cp0_utmi1>, <&cp0_comphy3 1>;
phy-names = "usb", "usb3";
dr_mode = "host";
};
/* ETH0 (DSA connection to switch) */
&cp0_crypto {
status = "okay";
};
&cp0_ethernet {
status = "okay";
};
&cp0_eth0 {
status = "okay";
phy-mode = "10gbase-r";
phys = <&cp0_comphy4 0>;
managed = "in-band-status";
nvmem-cells = <&base_mac 0>;
nvmem-cell-names = "mac-address";
};
/* MDIO (Switch) */
&cp0_pinctrl {
cp0_mdio_pins: cp0-mdio-pins-0 {
marvell,pins = CP_SMI_MDIO(MPP_ID), CP_SMI_MDC(MPP_ID);
marvell,function = "ge";
};
};
&cp0_mdio {
status = "okay";
pinctrl-names = "default";
pinctrl-0 = <&cp0_mdio_pins>;
sw: switch@0 {
compatible = "marvell,mv88e6190";
#address-cells = <1>;
#size-cells = <0>;
reg = <0>;
reset-gpios = SW_RESETn(MPP_GPIO_REF);
interrupts-extended = SW_INTn(MPP_IRQ_REF);
interrupt-controller;
dsa,member = <0 0>;
ports {
#address-cells = <1>;
#size-cells = <0>;
port@0 {
reg = <0x0>;
label = "cpu";
ethernet = <&cp0_eth0>;
phy-mode = "10gbase-r";
fixed-link {
speed = <10000>;
full-duplex;
};
};
#define SWP_COMMON(_n, _label, _mac_offs, _phymode, _phy) \
reg = <0x ## _n>; \
label = _label; \
phy-mode = _phymode; \
phy-handle = <&_phy>; \
\
nvmem-cells = <&base_mac _mac_offs>; \
nvmem-cell-names = "mac-address"
#define XSWP(_n, _label, _mac_offs, _phy) \
port@_n { \
SWP_COMMON(_n, _label, _mac_offs, "usxgmii", _phy); \
managed = "in-band-status"; \
}
#define GSWP(_n, _label, _mac_offs, _phy) \
port@_n { \
SWP_COMMON(_n, _label, _mac_offs, "gmii", _phy); \
\
leds { \
#address-cells = <1>; \
#size-cells = <0>; \
\
led@0 { \
reg = <0>; \
function = "tp"; \
color = <LED_COLOR_ID_GREEN>; \
default-state = "keep"; \
}; \
led@1 { \
reg = <1>; \
function = "tp"; \
color = <LED_COLOR_ID_YELLOW>; \
default-state = "off"; \
}; \
}; \
}
XSWP(9, "x1", 1, xphy9);
XSWP(a, "x2", 2, xphya);
GSWP(8, "x3", 3, swphy8);
GSWP(7, "x4", 4, swphy7);
GSWP(6, "x5", 5, swphy6);
GSWP(5, "x6", 6, swphy5);
GSWP(4, "x7", 7, swphy4);
GSWP(3, "x8", 8, swphy3);
GSWP(2, "x9", 9, swphy2);
GSWP(1, "x10", 10, swphy1);
#undef GSWP
#undef XSWP
#undef SWP_COMMON
};
mdio {
#address-cells = <1>;
#size-cells = <0>;
#define SWPHY(_n) \
ethernet-phy@_n { \
compatible = "ethernet-phy-ieee802.3-c22"; \
reg = <_n>; \
eee-broken-100tx; \
eee-broken-1000t; \
}
swphy1: SWPHY(1);
swphy2: SWPHY(2);
swphy3: SWPHY(3);
swphy4: SWPHY(4);
swphy5: SWPHY(5);
swphy6: SWPHY(6);
swphy7: SWPHY(7);
swphy8: SWPHY(8);
#undef SWPHY
};
};
};
/* XMDIO (88X3310P 10G PHYs) */
&cp0_pinctrl {
cp0_xmdio_pins: cp0-xmdio-pins-0 {
marvell,pins = CP_XSMI_MDIO(MPP_ID), CP_XSMI_MDC(MPP_ID);
marvell,function = "xg";
};
};
&ETH9_RESETn(MPP_GPIO_CHIP) {
xphy9-reset-hog {
gpio-hog;
gpios = ETH9_RESETn(MPP_GPIO_REF_NO_CHIP);
output-low;
line-name = "x1-phy-reset";
};
};
&ETH10_RESETn(MPP_GPIO_CHIP) {
xphya-reset-hog {
gpio-hog;
gpios = ETH10_RESETn(MPP_GPIO_REF_NO_CHIP);
output-low;
line-name = "x2-phy-reset";
};
};
&cp0_xmdio {
status = "okay";
pinctrl-names = "default";
pinctrl-0 = <&cp0_xmdio_pins>;
/* 88X3310 specifices 35ns minimum MDC period (28.57 MHz). */
clock-frequency = <28571428>;
#define XPHY(_n, _sfp) \
ethernet-phy@_n { \
compatible = "ethernet-phy-ieee802.3-c45"; \
reg = <_n>; \
sfp = <&_sfp>; \
\
leds { \
#address-cells = <1>; \
#size-cells = <0>; \
\
led@0 { \
reg = <0>; \
function = "tp"; \
color = <LED_COLOR_ID_YELLOW>; \
default-state = "off"; \
\
marvell,media = "copper"; \
marvell,polarity = "active-high"; \
}; \
led@1 { \
reg = <1>; \
function = "tp"; \
color = <LED_COLOR_ID_GREEN>; \
default-state = "keep"; \
\
marvell,media = "copper"; \
marvell,polarity = "active-high"; \
}; \
\
led@2 { \
reg = <2>; \
function = "sfp"; \
color = <LED_COLOR_ID_YELLOW>; \
default-state = "off"; \
\
marvell,media = "fiber"; \
marvell,polarity = "active-high"; \
}; \
led@3 { \
reg = <3>; \
function = "sfp"; \
color = <LED_COLOR_ID_GREEN>; \
default-state = "keep"; \
\
marvell,media = "fiber"; \
marvell,polarity = "active-high"; \
}; \
}; \
}
xphy9: XPHY(4, sfp9);
xphya: XPHY(5, sfpa);
#undef XPHY
};
/ {
sfp9: sfp@9 {
compatible = "sff,sfp";
i2c-bus = <&i2c_sfp9>;
mod-def0-gpios = SFP9_MOD_ABS(MPP_GPIO_REF);
los-gpios = SFP9_RX_LOS(MPP_GPIO_REF);
tx-disable-gpios = SFP9_TX_DISABLE(MPP_GPIO_REF);
tx-fault-gpios = SFP9_TX_FAULT(MPP_GPIO_REF);
rate-select0-gpios = SFP9_RS0(MPP_GPIO_REF);
rate-select1-gpios = SFP9_RS1(MPP_GPIO_REF);
maximum-power-milliwatt = <3000>;
};
sfpa: sfp@a {
compatible = "sff,sfp";
i2c-bus = <&i2c_sfpa>;
mod-def0-gpios = SFP10_MOD_ABS(MPP_GPIO_REF);
los-gpios = SFP10_RX_LOS(MPP_GPIO_REF);
tx-disable-gpios = SFP10_TX_DISABLE(MPP_GPIO_REF);
tx-fault-gpios = SFP10_TX_FAULT(MPP_GPIO_REF);
rate-select0-gpios = SFP10_RS0(MPP_GPIO_REF);
rate-select1-gpios = SFP10_RS1(MPP_GPIO_REF);
maximum-power-milliwatt = <3000>;
};
};
/* Power Board */
&cp0_pinctrl {
cp0_pwr_gpio_pins: cp0-pwr-gpio-0 {
marvell,pins = I2C_IRQ(MPP_ID);
marvell,function = "gpio";
};
};
&i2c_pwr {
// Shared IRQ on I2C_IRQ
pinctrl-names = "default";
pinctrl-0 = <&cp0_pwr_gpio_pins>;
// 0x26 U13 PCF8574 GPIO I/O
gpio_pwr1: gpio@26 {
compatible = "nxp,pcf8574a";
#gpio-cells = <2>;
gpio-controller;
#interrupt-cells = <2>;
interrupt-controller;
interrupts-extended = I2C_IRQ(MPP_IRQ_REF);
reg = <0x26>;
#define GPIO_PWR1_UNUSED0 gpio_pwr1 0 GPIO_ACTIVE_HIGH
#define GPIO_PWR1_UNUSED1 gpio_pwr1 1 GPIO_ACTIVE_HIGH
#define GPIO_POE_PGOOD gpio_pwr1 2 GPIO_ACTIVE_HIGH
#define GPIO_RESET_BUTTON gpio_pwr1 3 GPIO_ACTIVE_LOW
#define GPIO_VIN1_PGOOD gpio_pwr1 4 GPIO_ACTIVE_LOW
#define GPIO_LED_VIN2_ALERT gpio_pwr1 5 GPIO_ACTIVE_LOW
#define GPIO_VIN2_PGOOD gpio_pwr1 6 GPIO_ACTIVE_LOW
#define GPIO_LED_VIN1_ALERT gpio_pwr1 7 GPIO_ACTIVE_LOW
};
//0x27 U3 PCF8574 GPIO LED
gpio_pwr2: gpio@27 {
compatible = "nxp,pcf8574a";
#gpio-cells = <2>;
gpio-controller;
#interrupt-cells = <2>;
interrupt-controller;
interrupts-extended = I2C_IRQ(MPP_IRQ_REF);
reg = <0x27>;
#define GPIO_LED2G gpio_pwr2 0 GPIO_ACTIVE_LOW
#define GPIO_LED2R gpio_pwr2 1 GPIO_ACTIVE_LOW
#define GPIO_LED1G gpio_pwr2 2 GPIO_ACTIVE_LOW
#define GPIO_LED1R gpio_pwr2 3 GPIO_ACTIVE_LOW
#define GPIO_LED4G gpio_pwr2 4 GPIO_ACTIVE_LOW
#define GPIO_LED4R gpio_pwr2 5 GPIO_ACTIVE_LOW
#define GPIO_LED3G gpio_pwr2 6 GPIO_ACTIVE_LOW
#define GPIO_LED3R gpio_pwr2 7 GPIO_ACTIVE_LOW
};
//0x28* U5 TPS23861PWR PoE Controller
//0x30 U5 TPS23861PWR PoE Controller broadcast
//0x50 U15 AT24C256C EEPROM
vpd_power: eeprom@50 {
// AT24C256C-MAHL-T
compatible = "atmel,24c256";
reg = <0x50>;
infix,board = "power";
};
};
/* Reset button */
/ {
gpio-keys {
compatible = "gpio-keys";
up {
label = "factory-reset";
linux,code = <KEY_RESTART>;
gpios = <&GPIO_RESET_BUTTON>;
};
};
};
/* System LEDs */
/ {
power-a {
compatible = "gpio-charger";
charger-type = "mains";
gpios = <&GPIO_VIN1_PGOOD>;
};
power-b {
compatible = "gpio-charger";
charger-type = "mains";
gpios = <&GPIO_VIN2_PGOOD>;
};
leds: leds {
compatible = "gpio-leds";
led-statg {
function = LED_FUNCTION_STATUS;
color = <LED_COLOR_ID_GREEN>;
gpios = <&GPIO_LED1G>;
};
led-statr {
function = LED_FUNCTION_STATUS;
color = <LED_COLOR_ID_RED>;
gpios = <&GPIO_LED1R>;
};
led-faultg {
function = LED_FUNCTION_FAULT;
color = <LED_COLOR_ID_GREEN>;
gpios = <&GPIO_LED2G>;
};
led-faultr {
function = LED_FUNCTION_FAULT;
color = <LED_COLOR_ID_RED>;
gpios = <&GPIO_LED2R>;
};
led-lang {
function = LED_FUNCTION_LAN;
color = <LED_COLOR_ID_GREEN>;
gpios = <&GPIO_LED3G>;
};
led-lanr {
function = LED_FUNCTION_LAN;
color = <LED_COLOR_ID_RED>;
gpios = <&GPIO_LED3R>;
};
led-bootg {
function = LED_FUNCTION_BOOT;
color = <LED_COLOR_ID_GREEN>;
gpios = <&GPIO_LED4G>;
};
led-bootr {
function = LED_FUNCTION_BOOT;
color = <LED_COLOR_ID_RED>;
gpios = <&GPIO_LED4R>;
default-state = "on";
linux,default-trigger = "timer";
};
led-vin1-alert {
function = "power-a";
color = <LED_COLOR_ID_RED>;
gpios = <&GPIO_LED_VIN1_ALERT>;
};
led-vin2-alert {
function = "power-b";
color = <LED_COLOR_ID_RED>;
gpios = <&GPIO_LED_VIN2_ALERT>;
};
};
};
/* Watchdog */
&cp0_pinctrl {
watchdog_pins: watchdog-pins {
marvell,pins = WDT_TICKLE(MPP_ID);
marvell,function = "gpio";
};
};
/ {
sysmgmt-watchdog {
pinctrl-names = "default";
pinctrl-0 = <&watchdog_pins>;
compatible = "linux,wdt-gpio";
gpios = WDT_TICKLE(MPP_GPIO_REF);
always-running;
hw_algo = "toggle";
hw_margin_ms = <20000>; /* toggle period must be below 1 minute */
};
};
@@ -1,12 +0,0 @@
#include <arm64/marvell/cn9130.dtsi>
&cp0_syscon0 {
cp0_pinctrl: pinctrl {
/* For some reason, this is missing from cn9130.dtsi */
compatible = "marvell,cp115-standalone-pinctrl";
};
};
&cp0_xmdio {
clock-names = "gop_clk", "mg_clk", "mg_core_clk", "axi_clk";
};
-10
View File
@@ -1,10 +0,0 @@
config BR2_PACKAGE_BANANAPI_BPI_R3
bool "Banana Pi R3"
depends on BR2_aarch64
select BR2_PACKAGE_FEATURE_WIFI
select BR2_PACKAGE_LINUX_FIRMWARE
select BR2_PACKAGE_LINUX_FIRMWARE_MEDIATEK
select BR2_PACKAGE_LINUX_FIRMWARE_MEDIATEK_MT7986
select SDCARD_AUX
help
Build Banana PI R3 support
-13
View File
@@ -1,13 +0,0 @@
Copyright (c) 2025 The KernelKit Authors
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-229
View File
@@ -1,229 +0,0 @@
# Banana Pi BPI-R3
<img src="bananapi-bpi-r3.webp" alt="The board" width=800 padding=10>
## Overview
The Banana Pi R3 is a high-performance networking board with full Infix
support for all enabled features including switched Ethernet ports, WiFi,
and SFP interfaces.
### Hardware Features
- MediaTek MT7986 ARM Cortex-A53 quad-core processor @ 2.0 GHz
- 2 GB DDR4 RAM
- 8 GB eMMC storage + microSD card slot
- 5x Gigabit Ethernet ports (4x LAN, 1x WAN)
- 2x SFP cages for fiber connectivity (1G/2.5G)
- Dual-band WiFi (2.4 GHz + 5 GHz)
- USB 3.0 port
- Mini PCIe slot
### Default Network Configuration
Infix comes preconfigured with:
- **LAN ports** (lan1-lan4): Bridged for internal networking
- **WAN port**: DHCP client enabled for internet connectivity
- **SFP ports** (sfp1, sfp2): Available for configuration
- **WiFi interfaces** (wifi0, wifi1): Available for configuration
## Getting Started
### Quick Start with SD Card
The easiest way to get started is using an SD card:
1. **Download the SD card image:** [infix-bpi-r3-sdcard.img][2]
2. **Flash the image to an SD card:** see [this guide][0]
3. **Set boot switches:**
- Set DIP switches to **0000** (SD card boot mode)
- Switch positions are on the underside of the board near the SD slot
4. **Boot the board:**
- Insert the SD card
- Connect power
- Connect to LAN port or console (115200 8N1)
- Default login: `admin` / `admin`
### Boot Switch Reference
The BPI-R3 has a 4-position DIP switch that controls boot media:
<img align="right" src="bootstrap-switch.webp" alt="DIP switches" width=200 padding=10>
| Position | Mode | Description |
|----------|-------------|---------------------------------------|
| 0000 | SD card | Boot from microSD card (recommended) |
| 0110 | eMMC | Boot from internal eMMC storage |
| 1010 | SPI NAND | Boot from SPI NAND (advanced users) |
> [!NOTE]
> Switch position is read from left to right: "0" = OFF, "1" = ON.
> When the DIP switch is in the "UP" position it is OFF(0).
## Advanced: Installing to eMMC
For production deployments or better performance, you can install Infix
to the internal eMMC storage. This is more complex but provides faster
boot times and eliminates the external SD card.
### Why Use eMMC?
**Advantages:**
- Faster boot and better performance
- No external SD card to manage
- More robust for industrial/embedded deployments
**Disadvantages:**
- More complex installation process
- Requires intermediate NAND boot step
- Harder to recover from errors
### Prerequisites
- FTDI USB-to-serial cable (3.3V) for console access
- microSD card with Infix (for initial boot)
- USB flash drive (FAT32 formatted)
- Downloaded files (see below)
### Required Files
Download and place these files on a FAT32-formatted USB drive:
1. **Intermediate NAND bootloader** (from Frank-W's U-Boot):
- [bpi-r3_spim-nand_bl2.img][5] (BL2 loader)
- [bpi-r3_spim-nand_fip.bin][6] (FIP image)
2. **Infix eMMC image:**
- [infix-bpi-r3-emmc.img][3] (Complete system image)
3. **eMMC bootloader** (extracted from):
- [bpi-r3-emmc-boot-2025.01-latest.tar.gz][4]
- Extract `bl2.img` from the tarball to your USB drive
> [!WARNING]
> The following process involves multiple boot mode changes. Take your
> time verify each step carefully.
### Installation Steps
#### Step 1: Boot from SD card
1. Set boot switches to **0000** (SD card mode)
2. Insert SD card with Infix
3. Power on and break into U-Boot (press Ctrl-C during boot)
#### Step 2: Flash intermediate NAND bootloader
This step installs a temporary bootloader to NAND that will help us
flash the eMMC. From the U-Boot prompt:
```
usb start
mtd erase spi-nand0
fatload usb 0:1 0x50000000 bpi-r3_spim-nand_bl2.img
mtd write spi-nand0 0x50000000 0x0 0x100000
fatload usb 0:1 0x50000000 bpi-r3_spim-nand_fip.bin
mtd write spi-nand0 0x50000000 0x380000 0x200000
```
#### Step 3: Boot from NAND
1. Power off the board
2. Set boot switches to **1010** (NAND mode)
3. Power on - you should boot into U-Boot again
#### Step 4: Write Infix image to eMMC
From the U-Boot prompt:
```
usb start
fatload usb 0:1 0x50000000 infix-bpi-r3-emmc.img
setexpr blocks ${filesize} / 0x200
mmc write 0x50000000 0x0 ${blocks}
```
This writes the complete Infix system (partitions, rootfs, etc.) to eMMC.
#### Step 5: Configure eMMC boot
Now configure the eMMC boot partition and write the bootloader:
```
mmc partconf 0 1 1 1
mmc erase 0x0 0x400
fatload usb 0:1 0x50000000 bl2.img
mmc write 0x50000000 0x0 0x400
mmc partconf 0 1 1 0
```
#### Step 6: Boot from eMMC
1. Power off the board
2. Set boot switches to **0110** (eMMC mode)
3. Remove SD card (optional, but recommended to verify eMMC boot)
4. Power on
Your BPI-R3 should now boot Infix from internal eMMC storage!
## Troubleshooting
### Board won't boot
- Verify boot switch positions (check twice!)
- Ensure power supply provides adequate current (12V/2A recommended)
- Try booting from SD card with switches at **0000**
### Can't break into U-Boot
- Ensure serial console is connected properly (115200 8N1, 3.3V)
- Press Ctrl-C immediately when you see boot messages
- Try power cycling and pressing Ctrl-C repeatedly
### eMMC boot fails after installation
- Boot from NAND (**1010**) and verify eMMC image was written
- Check USB drive contents - ensure all files are present
- Re-run Step 5 (eMMC boot configuration)
### Reverting to SD card
Simply set boot switches back to **0000** and boot from SD card. The
eMMC installation does not affect SD card functionality.
## Additional Resources
- [Infix Documentation][1]
- [Official BPI-R3 Wiki][7]
- [Release Downloads][8]
## Building Custom Images
See the main Infix documentation for building from source. To build both
SD card and eMMC images locally:
```bash
# Build bootloaders for both SD and eMMC
make x-bpi-r3-sd-boot
make x-bpi-r3-emmc-boot
# Build main system
make aarch64
# Create SD card image
./utils/mkimage.sh -od bananapi-bpi-r3
# Create eMMC image
./utils/mkimage.sh -odt emmc bananapi-bpi-r3
```
[0]: https://kernelkit.org/posts/flashing-sdcard/
[1]: https://kernelkit.org/infix/latest/
[2]: https://github.com/kernelkit/infix/releases/download/latest-boot/infix-bpi-r3-sdcard.img
[3]: https://github.com/kernelkit/infix/releases/download/latest-boot/infix-bpi-r3-emmc.img
[4]: https://github.com/kernelkit/infix/releases/download/latest-boot/bpi-r3-emmc-boot-2025.01-latest.tar.gz
[5]: https://github.com/frank-w/u-boot/releases/download/CI-BUILD-2025-10-bpi-2025.10-2025-10-13_1032/bpi-r3_spim-nand_bl2.img
[6]: https://github.com/frank-w/u-boot/releases/download/CI-BUILD-2025-10-bpi-2025.10-2025-10-13_1032/bpi-r3_spim-nand_fip.bin
[7]: https://wiki.banana-pi.org/Banana_Pi_BPI-R3
[8]: https://github.com/kernelkit/infix/releases/tag/latest-boot
@@ -1,36 +0,0 @@
define BANANAPI_BPI_R3_LINUX_CONFIG_FIXUPS
$(call KCONFIG_ENABLE_OPT,CONFIG_ARCH_MEDIATEK)
$(call KCONFIG_ENABLE_OPT,CONFIG_MACH_MT7986)
$(call KCONFIG_ENABLE_OPT,CONFIG_PINCTRL_MT7986)
$(call KCONFIG_ENABLE_OPT,CONFIG_SERIAL_8250_MT6577)
$(call KCONFIG_SET_OPT,CONFIG_I2C_GPIO,y)
$(call KCONFIG_SET_OPT,CONFIG_MTK_THERMAL,m)
$(call KCONFIG_ENABLE_OPT,CONFIG_MTK_UART)
$(call KCONFIG_ENABLE_OPT,CONFIG_MTK_WATCHDOG)
$(call KCONFIG_ENABLE_OPT,CONFIG_MEDIATEK_GE_PHY)
$(call KCONFIG_ENABLE_OPT,CONFIG_REALTEK_PHY)
$(call KCONFIG_ENABLE_OPT,CONFIG_NET_VENDOR_MEDIATEK)
$(call KCONFIG_ENABLE_OPT,CONFIG_NET_MEDIATEK_SOC)
$(call KCONFIG_SET_OPT,CONFIG_NET_DSA_MT7530,m)
$(call KCONFIG_SET_OPT,CONFIG_MT7915E,m)
$(call KCONFIG_SET_OPT,CONFIG_PCIE_MEDIATEK_GEN3,m)
$(call KCONFIG_ENABLE_OPT,CONFIG_MTK_SCPSYS)
$(call KCONFIG_ENABLE_OPT,CONFIG_MMC_MTK)
$(call KCONFIG_ENABLE_OPT,CONFIG_MTK_HSDMA)
$(call KCONFIG_SET_OPT,CONFIG_MT7915E,m)
$(call KCONFIG_ENABLE_OPT,CONFIG_MT798X_WMAC)
$(call KCONFIG_SET_OPT,CONFIG_MTK_SOC_THERMAL,m)
$(call KCONFIG_SET_OPT,CONFIG_I2C_MT65XX,m)
$(call KCONFIG_SET_OPT,CONFIG_USB_XHCI_MTK,m)
$(call KCONFIG_SET_OPT,CONFIG_PHY_MTK_TPHY,m)
$(call KCONFIG_SET_OPT,CONFIG_PHY_MTK_XSPHY,m)
$(call KCONFIG_SET_OPT,CONFIG_REGULATOR_GPIO,y)
$(call KCONFIG_SET_OPT,CONFIG_REGULATOR_MT6380,m)
$(call KCONFIG_SET_OPT,CONFIG_PWM_MEDIATEK,m)
$(call KCONFIG_SET_OPT,CONFIG_SENSORS_PWM_FAN,m)
$(call KCONFIG_SET_OPT,CONFIG_NVMEM_MTK_EFUSE,m)
$(call KCONFIG_SET_OPT,CONFIG_CRYPTO_DEV_SAFEXCEL,m)
endef
$(eval $(ix-board))
$(eval $(generic-package))
Binary file not shown.

Before

Width:  |  Height:  |  Size: 108 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 49 KiB

@@ -1 +0,0 @@
dtb-y += mediatek/mt7986a-bananapi-bpi-r3-sd.dtb mediatek/mt7986a-bananapi-bpi-r3-emmc.dtb
@@ -1,2 +0,0 @@
#include "mt7986a-bananapi-bpi-r3.dtsi"
#include "mt7986a-bananapi-bpi-r3-emmc.dtsi"
@@ -1,22 +0,0 @@
// SPDX-License-Identifier: (GPL-2.0 OR MIT)
/*
* Copyright (C) 2021 MediaTek Inc.
* Author: Sam.Shih <sam.shih@mediatek.com>
*/
/*
This is copied from linux where it is an overlay, unfortunatly it is not
possible to use dtbo in sysboot unless present in syslinux.conf
*/
&{/soc/mmc@11230000} {
bus-width = <8>;
max-frequency = <200000000>;
cap-mmc-highspeed;
mmc-hs200-1_8v;
mmc-hs400-1_8v;
hs400-ds-delay = <0x14014>;
non-removable;
no-sd;
no-sdio;
status = "okay";
};
@@ -1,2 +0,0 @@
#include "mt7986a-bananapi-bpi-r3.dtsi"
#include "mt7986a-bananapi-bpi-r3-sd.dtsi"
@@ -1,16 +0,0 @@
// SPDX-License-Identifier: (GPL-2.0 OR MIT)
/*
* Copyright (C) 2021 MediaTek Inc.
* Author: Sam.Shih <sam.shih@mediatek.com>
*/
/*
This is copied from linux where it is an overlay, unfortunatly it is not
possible to use dtbo in sysboot unless present in syslinux.conf
*/
&{/soc/mmc@11230000} {
bus-width = <4>;
max-frequency = <52000000>;
cap-sd-highspeed;
status = "okay";
};
@@ -1,59 +0,0 @@
#include <arm64/mediatek/mt7986a-bananapi-bpi-r3.dts>
/ {
chosen {
infix {
/* Default admin user password: 'admin' */
factory-password-hash = "$5$mI/zpOAqZYKLC2WU$i7iPzZiIjOjrBF3NyftS9CCq8dfYwHwrmUK097Jca9A";
usb-ports = <&ssusb>;
usb-port-names = "USB";
};
};
};
&cpu_thermal {
/delete-node/ trips;
/delete-node/ cooling-maps;
trips {
cpu_trip_active_cool: cpu-trip-active-cool {
temperature = <40000>; // 40°C
hysteresis = <2000>; // 2°C hysteresis
type = "active";
};
cpu_trip_active_low: cpu-trip-active-low {
temperature = <45000>; // 40°C
hysteresis = <2000>; // 2°C hysteresis
type = "active";
};
cpu_trip_active_med: cpu-trip-active-med {
temperature = <60000>; // 60°C
hysteresis = <2000>; // 2°C hysteresis
type = "active";
};
cpu_trip_hot: cpu-trip-hot {
temperature = <80000>; // 80°C
hysteresis = <2000>; // 2°C hysteresis
type = "hot";
};
cpu_trip_critical: cpu-trip-critical {
temperature = <90000>; // 90°C
hysteresis = <2000>; // 2°C hysteresis
type = "critical";
};
};
cooling-maps {
map-cpu-40deg {
cooling-device = <&fan 0 0>;
trip = <&cpu_trip_active_cool>;
};
map-cpu-45deg {
cooling-device = <&fan 1 1>;
trip = <&cpu_trip_active_low>;
};
map-cpu-60deg {
cooling-device = <&fan 2 2>;
trip = <&cpu_trip_active_med>;
};
};
};
@@ -1,82 +0,0 @@
image cfg.ext4 {
empty = true
temporary = true
size = 128M
ext4 {
label = "cfg"
use-mke2fs = true
features = "uninit_bg"
extraargs = "-m 0 -i 4096"
}
}
# The /var partition will be expanded automatically at first boot
# to use the full size of the SD-card or eMMC media.
image var.ext4 {
empty = true
temporary = true
size = 128M
ext4 {
label = "var"
use-mke2fs = true
features = "uninit_bg"
extraargs = "-m 0 -i 4096"
}
}
image #INFIX_ID##VERSION#-bpi-r3-#TARGET#.img {
hdimage {
partition-table-type = "gpt"
}
# BL2 bootloader partition (MediaTek official location)
partition bl2 {
image = "bl2.img"
offset = 1024s # 0x80000 = sector 1024
size = 4M # 0x400000
bootable = true
}
# Factory/calibration data (sectors 9216-13311)
partition factory {
offset = 4608K # 0x480000
size = 2M # 0x200000
}
# FIP partition - BL31 + U-Boot (sectors 13312-17407)
partition fip {
# partition-type = 0x83 # Linux filesystem
image = "fip.bin"
offset = 13312s
size = 4096s
}
partition aux {
partition-uuid = D4EF35A0-0652-45A1-B3DE-D63339C82035
image = "aux.ext4"
}
partition primary {
partition-type-uuid = 0FC63DAF-8483-4772-8E79-3D69D8477DE4
bootable = true
size = 250M
image = "rootfs.squashfs"
}
partition secondary {
partition-type-uuid = 0FC63DAF-8483-4772-8E79-3D69D8477DE4
bootable = true
size = 250M
image = "rootfs.squashfs"
}
partition cfg {
partition-uuid = 7aa497f0-73b5-47e5-b2ab-8752d8a48105
image = "cfg.ext4"
}
partition var {
partition-uuid = 8046A06A-E45A-4A14-A6AD-6684704A393F
image = "var.ext4"
}
}
@@ -1,344 +0,0 @@
{
"ieee802-dot1ab-lldp:lldp": {
"infix-lldp:enabled": true
},
"ietf-hardware:hardware": {
"component": [
{
"name": "USB",
"class": "infix-hardware:usb",
"state": {
"admin-state": "unlocked"
}
},
{
"class": "infix-hardware:usb",
"name": "USB2",
"state": {
"admin-state": "unlocked"
}
}
]
},
"ietf-interfaces:interfaces": {
"interface": [
{
"name": "br0",
"type": "infix-if-type:bridge",
"ietf-ip:ipv4": {
"address": [
{
"ip": "192.168.0.1",
"prefix-length": 24
}
]
}
},
{
"name": "lan1",
"type": "infix-if-type:ethernet",
"ietf-ip:ipv6": {},
"infix-interfaces:bridge-port": {
"bridge": "br0"
}
},
{
"name": "lan2",
"type": "infix-if-type:ethernet",
"ietf-ip:ipv6": {},
"infix-interfaces:bridge-port": {
"bridge": "br0"
}
},
{
"name": "lan3",
"type": "infix-if-type:ethernet",
"ietf-ip:ipv6": {},
"infix-interfaces:bridge-port": {
"bridge": "br0"
}
},
{
"name": "lan4",
"type": "infix-if-type:ethernet",
"ietf-ip:ipv6": {},
"infix-interfaces:bridge-port": {
"bridge": "br0"
}
},
{
"name": "lo",
"type": "infix-if-type:loopback",
"ietf-ip:ipv4": {
"address": [
{
"ip": "127.0.0.1",
"prefix-length": 8
}
]
},
"ietf-ip:ipv6": {
"address": [
{
"ip": "::1",
"prefix-length": 128
}
]
}
},
{
"name": "sfp1",
"type": "infix-if-type:ethernet",
"ietf-ip:ipv6": {}
},
{
"name": "sfp2",
"type": "infix-if-type:ethernet",
"ietf-ip:ipv6": {}
},
{
"name": "wan",
"type": "infix-if-type:ethernet",
"ietf-ip:ipv4": {
"infix-dhcp-client:dhcp": {
"option": [
{"id": "ntp-server"},
{"id": "broadcast"},
{"id": "domain"},
{"id": "hostname"},
{"id": "dns-server"},
{"id": "router"},
{"id": "netmask"},
{"id": "vendor-class", "value": "Banana Pi BPI-R3"}
]
}
},
"ietf-ip:ipv6": {
"infix-dhcpv6-client:dhcp": {
"option": [
{"id": "ntp-server"},
{"id": "client-fqdn"},
{"id": "domain-search"},
{"id": "dns-server"}
]
}
}
},
{
"name": "wifi0",
"type": "infix-if-type:wifi"
},
{
"name": "wifi1",
"type": "infix-if-type:wifi"
}
]
},
"ietf-keystore:keystore": {
"asymmetric-keys": {
"asymmetric-key": [
{
"name": "genkey",
"public-key-format": "infix-crypto-types:ssh-public-key-format",
"public-key": "",
"private-key-format": "infix-crypto-types:rsa-private-key-format",
"cleartext-private-key": "",
"certificates": {}
}
]
}
},
"ietf-netconf-acm:nacm": {
"enable-nacm": true,
"groups": {
"group": [
{
"name": "admin",
"user-name": [
"admin"
]
}
]
},
"rule-list": [
{
"name": "admin-acl",
"group": [
"admin"
],
"rule": [
{
"name": "permit-all",
"module-name": "*",
"access-operations": "*",
"action": "permit",
"comment": "Allow 'admin' group complete access to all operations and data."
}
]
},
{
"name": "default-deny-all",
"group": [
"*"
],
"rule": [
{
"name": "deny-password-read",
"module-name": "ietf-system",
"path": "/ietf-system:system/authentication/user/password",
"access-operations": "*",
"action": "deny"
}
]
}
]
},
"ietf-netconf-server:netconf-server": {
"listen": {
"endpoints": {
"endpoint": [
{
"name": "default-ssh",
"ssh": {
"tcp-server-parameters": {
"local-address": "::"
},
"ssh-server-parameters": {
"server-identity": {
"host-key": [
{
"name": "default-key",
"public-key": {
"central-keystore-reference": "genkey"
}
}
]
}
}
}
}
]
}
}
},
"ietf-system:system": {
"hostname": "bpi-%m",
"ntp": {
"server": [
{
"name": "default",
"udp": {
"address": "pool.ntp.org"
}
}
]
},
"authentication": {
"user": [
{
"name": "admin",
"password": "$factory$",
"infix-system:shell": "bash"
}
]
},
"infix-system:motd-banner": "Li0tLS0tLS0uCnwgIC4gLiAgfCBJbmZpeCBPUyDigJQgSW1tdXRhYmxlLkZyaWVuZGx5LlNlY3VyZQp8LS4gdiAuLXwgaHR0cHM6Ly9rZXJuZWxraXQub3JnCictJy0tLSctJwo="
},
"infix-dhcp-server:dhcp-server": {
"option": [
{
"id": "ntp-server",
"address": "auto"
},
{
"id": "dns-server",
"address": "auto"
},
{
"id": "router",
"address": "auto"
}
],
"subnet": [
{
"subnet": "192.168.0.0/24",
"pool": {
"start-address": "192.168.0.100",
"end-address": "192.168.0.250"
}
}
]
},
"infix-firewall:firewall": {
"default": "wan",
"zone": [
{
"name": "lan",
"action": "accept",
"interface": [
"br0"
]
},
{
"name": "wan",
"action": "drop",
"interface": [
"wan"
],
"service": [
"dhcpv6-client"
]
}
],
"policy": [
{
"name": "lan-to-wan",
"action": "accept",
"ingress": [
"lan"
],
"egress": [
"wan"
],
"masquerade": true
}
]
},
"infix-meta:meta": {
"version": "1.6"
},
"infix-services:mdns": {
"enabled": true
},
"infix-services:ssh": {
"enabled": true,
"hostkey": [
"genkey"
],
"listen": [
{
"name": "ipv4",
"address": "0.0.0.0",
"port": 22
},
{
"name": "ipv6",
"address": "::",
"port": 22
}
]
},
"infix-services:web": {
"enabled": true,
"console": {
"enabled": true
},
"netbrowse": {
"enabled": true
},
"restconf": {
"enabled": true
}
}
}
@@ -1,3 +0,0 @@
#!/bin/sh
udevadm control --reload-rules
udevadm trigger --subsystem-match=net --action=add
@@ -1 +0,0 @@
ACTION=="add", SUBSYSTEM=="net", DEVPATH=="/devices/platform/soc/15100000.ethernet/net/eth1", NAME="sfp1"
@@ -1,3 +0,0 @@
CONFIG_DEVICE_TREE_INCLUDES="infix-env.dtsi infix-key.dtsi mt7986-emmc-env.dtsi"
BR2_TARGET_ARM_TRUSTED_FIRMWARE_ADDITIONAL_VARIABLES="BOOT_DEVICE=emmc DRAM_USE_DDR4=1 USE_MKIMAGE=1 MKIMAGE=$(HOST_DIR)/bin/mkimage"
CONFIG_SUPPORT_EMMC_BOOT=y
@@ -1,33 +0,0 @@
CONFIG_AUTOBOOT=y
CONFIG_BOOTDELAY=2
# CONFIG_MMC_PCI is not set
CONFIG_ENV_IS_NOWHERE=y
# CONFIG_ENV_IS_IN_MMC is not set
CONFIG_USB=y
CONFIG_USB_XHCI_HCD=y
CONFIG_USB_XHCI_MTK=y
CONFIG_USB_MTU3=y
CONFIG_PHY=y
CONFIG_PHY_MTK_TPHY=y
CONFIG_MTK_SPIM=y
CONFIG_SPI=y
CONFIG_DM_SPI=y
CONFIG_SPI_FLASH=y
CONFIG_DM_SPI_FLASH=y
CONFIG_SPI_FLASH_MTD=y
CONFIG_SPI_FLASH_MACRONIX=y
CONFIG_SPI_FLASH_WINBOND=y
CONFIG_SPI_FLASH_GIGADEVICE=y
CONFIG_MTD=y
CONFIG_DM_MTD=y
CONFIG_MTD_PARTITIONS=y
CONFIG_MTD_SPI_NAND=y
CONFIG_MTK_SPIM=y
CONFIG_MTK_SNOR=y
CONFIG_CMD_SF=y
CONFIG_CMD_USB=y
CONFIG_CMD_MTD=y
CONFIG_CMD_MTDPARTS=y
CONFIG_CMD_DM=y
@@ -1,5 +0,0 @@
#include <mt7986-env.dtsi>
&env {
fdtfile = "mediatek/mt7986a-bananapi-bpi-r3-emmc.dtb";
};
@@ -1,25 +0,0 @@
/ {
config {
env: environment {
/* After the MMC driver has enabled bus power,
* the controller seems to sometimes detect a
* card removal state , which causes it to
* disable power again. This hack re-enables the
* bus power in those cases.
*/
bootcmd = "run ixboot";
boot_targets = "mmc0";
ethprime = "eth0";
fdt_addr_r = "0x43f00000";
kernel_addr_r = "0x44000000";
scriptaddr = "0x48000000";
ramdisk_addr_r = "0x4A000000";
/* This is a development platform, keep
* developer mode statically enabled.
*/
ixbtn-devmode = "setenv dev_mode yes; echo Enabled";
ixbtn-factory = "echo \"No button available, use bootmenu\"";
};
};
};
@@ -1,5 +0,0 @@
#include <mt7986-env.dtsi>
&env {
fdtfile = "mediatek/mt7986a-bananapi-bpi-r3-sd.dtb";
};
@@ -1 +0,0 @@
CONFIG_DEVICE_TREE_INCLUDES="infix-env.dtsi infix-key.dtsi mt7986-sd-env.dtsi"
+7 -1
View File
@@ -1,4 +1,3 @@
include $(sort $(wildcard $(BR2_EXTERNAL_INFIX_PATH)/board/aarch64/*/*.mk))
.PHONY: board-enable-qemu-uboot
board-enable-qemu-uboot:
@@ -20,6 +19,13 @@ board-enable-qemu-uboot:
'$$(BR2_EXTERNAL_INFIX_PATH)/board/common/uboot/extras.config' \
--enable TARGET_UBOOT_FORMAT_DTB
.PHONY: board-enable-sparx-fit
board-enable-sparx-fit:
@$(call IXMSG,"Enabling SparX-5i compatible FIT options")
@BR2_PREFIX= ./utils/config --file $(BR2_CONFIG) \
--enable FIT_IMAGE \
--set-str FIT_KERNEL_LOAD_ADDR "0x7 0x00000000"
.PHONY: board-sparx-flash-uboot
board-sparx-flash-uboot: $(BINARIES_DIR)/u-boot.bin
@grep -q 'BR2_TARGET_UBOOT_BOARD_DEFCONFIG="mscc_fireant_pcb135_emmc"' $(BR2_CONFIG) || \
@@ -5,7 +5,7 @@
*/
/dts-v1/;
#include <arm64/microchip/sparx5_pcb135_emmc.dts>
#include "microchip/sparx5_pcb135_emmc.dts"
&cpu0 {
enable-method = "spin-table";
@@ -1,6 +0,0 @@
config BR2_PACKAGE_FREESCALE_IMX8MP_EVK
bool "NXP i.MX8MP EVK"
depends on BR2_aarch64
help
NXP i.MX8MP EVK
@@ -1,13 +0,0 @@
Copyright (c) 2024 The KernelKit Authors
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
@@ -1 +0,0 @@
dtb-y += freescale/imx8mp-evk.dtb
@@ -1,113 +0,0 @@
#include <arm64/freescale/imx8mp-evk.dts>
#include <dt-bindings/usb/pd.h>
&usb3_phy0 {
status = "okay";
};
&iomuxc {
pinctrl_typec_mux: typec1muxgrp {
fsl,pins = <
MX8MP_IOMUXC_SAI1_MCLK__GPIO4_IO20 0x16
>;
};
pinctrl_typec: typec1grp {
fsl,pins = <
MX8MP_IOMUXC_SAI1_TXD7__GPIO4_IO19 0x1c4
>;
};
};
&i2c2 {
ptn5110: tcpc@50 {
compatible = "nxp,ptn5110";
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_typec>;
reg = <0x50>;
interrupt-parent = <&gpio4>;
interrupts = <19 8>;
port {
typec_dr_sw: endpoint {
remote-endpoint = <&usb3_drd_sw>;
};
};
usb_con: connector {
compatible = "usb-c-connector";
label = "USB-C";
power-role = "dual";
data-role = "dual";
try-power-role = "sink";
source-pdos = <PDO_FIXED(5000, 3000, PDO_FIXED_USB_COMM)>;
sink-pdos = <PDO_FIXED(5000, 3000, PDO_FIXED_USB_COMM)
PDO_VAR(5000, 20000, 3000)>;
op-sink-microwatt = <15000000>;
self-powered;
ports {
#address-cells = <1>;
#size-cells = <0>;
port@1 {
reg = <1>;
typec_con_ss: endpoint {
remote-endpoint = <&usb3_data_ss>;
};
};
};
};
};
};
&usb3_phy0 {
fsl,phy-tx-vref-tune = <0xe>;
fsl,phy-tx-preemp-amp-tune = <3>;
fsl,phy-tx-vboost-level = <5>;
fsl,phy-comp-dis-tune = <7>;
fsl,pcs-tx-deemph-3p5db = <0x21>;
fsl,phy-pcs-tx-swing-full = <0x7f>;
status = "okay";
};
&usb3_0 {
status = "okay";
};
&usb_dwc3_0 {
dr_mode = "otg";
hnp-disable;
srp-disable;
adp-disable;
usb-role-switch;
role-switch-default-mode = "none";
snps,dis-u1-entry-quirk;
snps,dis-u2-entry-quirk;
status = "okay";
port {
usb3_drd_sw: endpoint {
remote-endpoint = <&typec_dr_sw>;
};
};
};
/ {
gpio-sbu-mux {
compatible = "gpio-sbu-mux";
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_typec_mux>;
switch-gpios = <&gpio4 20 GPIO_ACTIVE_LOW>;
orientation-switch;
port {
usb3_data_ss: endpoint {
remote-endpoint = <&typec_con_ss>;
};
};
};
chosen {
infix {
/* "admin" */
factory-password-hash = "$5$mI/zpOAqZYKLC2WU$i7iPzZiIjOjrBF3NyftS9CCq8dfYwHwrmUK097Jca9A";
};
};
};
@@ -1,46 +0,0 @@
define FREESCALE_IMX8MP_EVK_LINUX_CONFIG_FIXUPS
$(call KCONFIG_ENABLE_OPT,CONFIG_ARCH_NXP)
$(call KCONFIG_ENABLE_OPT,CONFIG_ARCH_MXC)
$(call KCONFIG_ENABLE_OPT,CONFIG_FEC)
$(call KCONFIG_ENABLE_OPT,CONFIG_NET_VENDOR_STMICRO)
$(call KCONFIG_ENABLE_OPT,CONFIG_STMMAC_ETH)
$(call KCONFIG_ENABLE_OPT,CONFIG_DWMAC_IMX8)
$(call KCONFIG_ENABLE_OPT,CONFIG_SERIAL_IMX)
$(call KCONFIG_ENABLE_OPT,CONFIG_SERIAL_IMX_CONSOLE)
$(call KCONFIG_ENABLE_OPT,CONFIG_I2C_IMX)
$(call KCONFIG_ENABLE_OPT,CONFIG_SPI_IMX)
$(call KCONFIG_ENABLE_OPT,CONFIG_PINCTRL_IMX8MP)
$(call KCONFIG_ENABLE_OPT,CONFIG_GPIO_MXC)
$(call KCONFIG_ENABLE_OPT,CONFIG_IMX2_WDT)
$(call KCONFIG_ENABLE_OPT,CONFIG_MMC_SDHCI_OF_ESDHC)
$(call KCONFIG_ENABLE_OPT,CONFIG_MMC_SDHCI_ESDHC_IMX)
$(call KCONFIG_ENABLE_OPT,CONFIG_CLK_IMX8MP)
$(call KCONFIG_ENABLE_OPT,CONFIG_NVMEM_IMX_OCOTP)
$(call KCONFIG_ENABLE_OPT,CONFIG_INTERCONNECT)
$(call KCONFIG_ENABLE_OPT,CONFIG_INTERCONNECT_IMX)
$(call KCONFIG_ENABLE_OPT,CONFIG_INTERCONNECT_IMX8MP)
$(call KCONFIG_ENABLE_OPT,CONFIG_REALTEK_PHY)
# For X
$(call KCONFIG_ENABLE_OPT,CONFIG_DRM)
$(call KCONFIG_ENABLE_OPT,CONFIG_DRM_ETNAVIV)
$(call KCONFIG_ENABLE_OPT,CONFIG_DRM_IMX8MP_DW_HDMI_BRIDGE)
$(call KCONFIG_ENABLE_OPT,CONFIG_PHY_FSL_SAMSUNG_HDMI_PHY)
$(call KCONFIG_ENABLE_OPT,CONFIG_DRM_IMX8MP_HDMI_PVI)
$(call KCONFIG_ENABLE_OPT,CONFIG_DRM_IMX_LCDIF)
$(call KCONFIG_ENABLE_OPT,CONFIG_INPUT_MOUSE)
$(call KCONFIG_ENABLE_OPT,CONFIG_INPUT_MOUSEDEV)
$(call KCONFIG_ENABLE_OPT,CONFIG_HID_GENERIC)
# For USB
$(call KCONFIG_DISABLE_OPT,CONFIG_USB)
$(call KCONFIG_ENABLE_OPT,CONFIG_USB)
$(call KCONFIG_ENABLE_OPT,CONFIG_USB_DWC3)
$(call KCONFIG_DISABLE_OPT,CONFIG_USB_DWC3_GADGET)
$(call KCONFIG_ENABLE_OPT,CONFIG_USB_DWC3_HOST)
$(call KCONFIG_ENABLE_OPT,CONFIG_ARM_IMX_BUS_DEVFREQ)
$(call KCONFIG_ENABLE_OPT,CONFIG_TYPEC_TCPCI)
$(call KCONFIG_ENABLE_OPT,CONFIG_TYPEC_SWITCH_GPIO)
endef
$(eval $(ix-board))
$(eval $(generic-package))
@@ -1,8 +0,0 @@
{
"eth0": {
"phy-detached-when-down": true
},
"eth1": {
"broken-mqprio": true
}
}
@@ -1,9 +0,0 @@
config BR2_PACKAGE_FRIENDLYARM_NANOPI_R2S
bool "FriendlyElec NanoPi R2S"
depends on BR2_aarch64
select SDCARD_AUX
select BR2_PACKAGE_INPUT_EVENT_DAEMON
select BR2_PACKAGE_LINUX_FIRMWARE_RTL_815X
help
FriendlyElec NanoPi R2S is a compact router board based on
the Rockchip RK3328 SoC with dual Gigabit Ethernet ports.
@@ -1,13 +0,0 @@
Copyright (c) 2025 The KernelKit Authors
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
@@ -1,172 +0,0 @@
FriendlyELC NanoPi R2S
======================
The [NanoPi R2S][1] is a very low-cost 64-bit ARM min router, powered by
the Rockchip RK3328, quad-core Cortex-A53.
The R2S does not have any onboard eMMC, so the only way to boot Infix on
it is using and SD card.
LEDs
----
The front system LEDs work as follows in Infix:
| **Stage** | **SYS** | **LAN** | **WAN** |
|----------------|---------|---------|---------|
| Power-on | dimmed | off | off |
| Factory reset | on | on | on |
| Linux loading | on | off | off |
| System loading | 1 Hz | off | off |
| System up | off | on | off |
| WAN address | off | on | on |
| Locate | 1 Hz | 1 Hz | 1 Hz |
| Fail safe | 5 Hz | off | off |
| Panic | 5 Hz | 5 Hz | 5 Hz |
Powering on the device the SYS LED is turned on faintly (dimmed). It
remains dimmed while U-Boot loads the kernel, and turns bright red when
the kernel starts. It remains steady on until the system has started
the LED daemon, `iitod`, which sets it blinking at 1 Hz while the rest
of the system starts up. When the system has come up successfully, the
SYS LED is turned off and the green LAN LED turns on. The WAN LED will
turn on (green) when the WAN interface is up and has an IP address.
> Compared to the `x86_64` Qemu target, it takes a while to parse all
> YANG models and load `startup-config`, but the whole process should
> not take more than 60 seconds, and usually a lot less.
If a "find my device" function exists, it will blink all LEDs at 1 Hz.
If `startup-config` fails to load Ínfix reverts to `failure-config`,
putting the device in fail safe (or fail secure) mode. Indicated by
the SYS LED blinking at 5 Hz instead of turning off.
If Infix for some reason also fails to load `failure-config`, then all
LEDs will blink at 5 Hz to clearly indicate something is very wrong.
In all error cases the console shows the problem.
Factory Reset
-------------
The reset button on the side can be used not only to safely reboot the
device, but can also be used to trigger a factory reset at power on.
At power-on, keep the reset button pressed for 10 seconds. The system
LEDs (SYS, WAN, LAN) will all blink at 1 Hz, to help you count down the
seconds. When the 10 seconds have passed all LEDs are turned off before
loading Linux.
When Linux boots up it confirms the factory reset by lighting up the
LEDs again, no blinking this time. The LEDs stay on until all files and
directories on read/writable partitions (`/cfg` and `/var`) have been
safely erased.
The system then continues loading, turning off all LEDs except SYS,
which blinks calmly at 1 Hz as usual until the system has completed
loading, this time with a `startup-config` freshly restored from the
device's `factory-config`.
How to Build
------------
```
$ make r2s_defconfig
$ make
```
Once the build has finished you will have `output/images/sdcard.img`
which you can flash to an SD card.
```
$ sudo dd if=output/images/sdcard.img of=/dev/mmcblk0 bs=1M status=progress oflag=direct
```
> **WARNING:** ensure `/dev/mmcblk0` really is the correct device for
> your SD card, and not used by the system!
Booting the Board
-----------------
1. Connect a TTL cable to three UART pins, GND is closest to the edge
2. Insert the flashed SD card
3. Power-up the board using an USB-C cable (ensure good power source!)
Worth noting, unlike many other boards, the Rockchip family of chipsets
runs the UART at 1500000 bps (1.5 Mbps) 8N1.
Console Port
------------
Unlike many other boards, the NanoPi R2S console, and in fact all
Rockchip family chipsets, runs at 1500000 bps (1.5 Mbps) 8N1.
Secure Boot
-----------
Like other Infix builds, the R2S enjoys secure boot. Please note,
however that the default signing keys are the public!
Also, default builds allow modifying and saving the U-Boot environment
(see below), which you may want to disable to secure the device. The
device also runs in *developer mode*, allowing full U-Boot shell access,
which you may also want to disable in a full production setting.
Caveat
------
Most (all?) of these boards do not have any Vital Product Data (VPD)
EEPROM mounted. This means they do not come with unique MAC addresses
allocated to the two Ethernet ports.
The bootloader (U-Boot) default environment for the board is usually
what provides a default, the same default MAC addresses to Linux:
- 4a:dc:d8:20:0d:84
- 4a:dc:d8:20:0d:85
This is important in case you want to run multiple R2S devices on the
same LAN. Meaning you either have to change the MAC address in the
U-Boot environment (below), or use the `custom-phys-address` setting in
Infix for the interface(s).
Break into U-Boot using Ctrl-C at power-on, preferably when the text
`Press Ctrl-C NOW to enter boot menu` is displayed. Exit the menu to
get to the prompt:
```
(r2s) printenv
...
eth1addr=4a:dc:d8:20:0d:84
ethact=ethernet@ff540000
ethaddr=4a:dc:d8:20:0d:85
ethprime=eth0
...
```
Here we change both addresses, using the *Locally Administered* bit:
```
(r2s) setenv eth1addr 02:00:c0:ff:ee:01
(r2s) setenv ethaddr 02:00:c0:ff:ee:00
(r2s) saveenv
```
Boot the system, log into Linux, and inspect the MAC addresses:
```
admin@infix-00-00-00:~$ ip -br l
lo UP 00:00:00:00:00:00 <LOOPBACK,UP,LOWER_UP>
eth0 UP 02:00:c0:ff:ee:00 <BROADCAST,MULTICAST,UP,LOWER_UP>
eth1 UP 02:00:c0:ff:ee:01 <BROADCAST,MULTICAST,UP,LOWER_UP>
```
[1]: https://wiki.friendlyelec.com/wiki/index.php/NanoPi_R2S

Some files were not shown because too many files have changed in this diff Show More