mirror of
https://github.com/brain-hackers/buildbrain
synced 2026-03-29 09:11:08 +09:00
Compare commits
163 Commits
2021-02-21
...
master
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
3fb1dea6f1 | ||
|
|
98a42ab772 | ||
|
|
c7e05fb77b | ||
|
|
f3f5eee21b | ||
|
|
805f0daebd | ||
|
|
8f3a42adc4 | ||
|
|
7669040ae2 | ||
|
|
a7e1b1aa1a | ||
|
|
8d5f28e712 | ||
|
|
f3ddab408a | ||
|
|
a8527d9098 | ||
|
|
cd1bba1f0a | ||
| b8635dbf7b | |||
|
|
e8ba23fdfa | ||
|
|
ef5ab8903f | ||
|
|
6e16db7177 | ||
|
|
f1af5e77cb | ||
|
|
b1a3b834dd | ||
|
|
e13a1ea846 | ||
|
|
818644a433 | ||
|
|
140ba3ff38 | ||
|
|
cf7cc41efe | ||
|
|
17c4c8b5a7 | ||
|
|
924216b934 | ||
|
|
0c7861189b | ||
|
|
4257f2465a | ||
|
|
24e5428c62 | ||
|
|
086c5b08f5 | ||
|
|
9d65cf08dd | ||
|
|
68e6e1091e | ||
|
|
ce8d780b33 | ||
|
|
b561fdaec9 | ||
|
|
611706771f | ||
|
|
2fa3904480 | ||
|
|
3479812f91 | ||
|
|
94d37b1b76 | ||
|
|
d6719fd49f | ||
|
|
1de1747fbb | ||
|
|
d885ca6bc1 | ||
|
|
b242f06d78 | ||
|
|
d534aa7416 | ||
|
|
870363a92e | ||
|
|
8ca8a3ab12 | ||
|
|
33e3afbf13 | ||
|
|
bc2c108d77 | ||
|
|
ee93757ff1 | ||
|
|
9f41a0bbd2 | ||
|
|
9671252f5d | ||
|
|
935363d6ac | ||
|
|
25668a72e3 | ||
|
|
d7da4a6e44 | ||
|
|
8f3f63be44 | ||
|
|
a4350f303c | ||
|
|
f7a20f61b7 | ||
|
|
2ecec60001 | ||
|
|
eaa027db98 | ||
|
|
53e39a8bb6 | ||
|
|
453fe8d60f | ||
|
|
e7d3c4629a | ||
|
|
57c5052909 | ||
|
|
84960b1471 | ||
|
|
515aff62be | ||
|
|
6cf0f749d4 | ||
|
|
7ca8ed3cc1 | ||
|
|
f444f68a3b | ||
|
|
f503ef87ef | ||
|
|
3f4afedf45 | ||
|
|
5e92df0600 | ||
|
|
e09c0ba017 | ||
|
|
d74ba8a70f | ||
|
|
ec695f99f0 | ||
|
|
22235e8cf0 | ||
|
|
9529327097 | ||
|
|
7e2b04ce18 | ||
|
|
8c7118f0b2 | ||
|
|
7a34055ef3 | ||
|
|
d64a316b1f | ||
|
|
d5ab036801 | ||
|
|
fe480d7b91 | ||
|
|
e15ce44891 | ||
|
|
0509bbbe6f | ||
|
|
a2295ecb55 | ||
|
|
07c32f712f | ||
|
|
89b4c120a2 | ||
|
|
1a4d1cd39a | ||
|
|
d8aa77a29f | ||
|
|
93de849023 | ||
|
|
0eb94960ca | ||
|
|
7299377004 | ||
|
|
b90386fbd2 | ||
|
|
f7e1dbeadf | ||
|
|
6bc1d44016 | ||
|
|
8bc1c15958 | ||
|
|
ffb3590060 | ||
|
|
45990eac88 | ||
|
|
b9b99be34a | ||
|
|
c3a5dbfe22 | ||
|
|
d30ec39b6b | ||
|
|
152854cd1d | ||
|
|
c8e7e32db5 | ||
|
|
32ba6d3825 | ||
|
|
0a39083d9e | ||
|
|
14275cdb60 | ||
| d5b86adc1c | |||
|
|
621a5e0b9a | ||
|
|
899aac01d9 | ||
|
|
627b8212ec | ||
|
|
e7f9e3f7a5 | ||
|
|
162f065148 | ||
|
|
0ecb9895ac | ||
|
|
2c89ef57d1 | ||
|
|
5689b3a04e | ||
|
|
12a69402c6 | ||
|
|
04987d3792 | ||
|
|
9c56c4175a | ||
|
|
23790bcf20 | ||
|
|
f82168e7b1 | ||
|
|
f77dc68e69 | ||
|
|
c59b6d7738 | ||
|
|
8ca448ad1f | ||
|
|
46100619b0 | ||
|
|
ccd54db033 | ||
|
|
ccd1d72e64 | ||
|
|
219d2ce3c0 | ||
|
|
d8c969cc7e | ||
|
|
682b8a44b4 | ||
|
|
9eee52eef1 | ||
|
|
6fa865562d | ||
|
|
0cb4e30ace | ||
|
|
882ebd83a1 | ||
|
|
07177b6a8e | ||
|
|
5ff900db79 | ||
|
|
0f934753d6 | ||
|
|
b8908199d5 | ||
|
|
0b2f80fe0b | ||
|
|
c133c10be3 | ||
|
|
7c9634349f | ||
|
|
48f1a6cb57 | ||
|
|
5e84e8719a | ||
|
|
177e60d3ce | ||
|
|
039a0f2868 | ||
|
|
2e0d446f9c | ||
|
|
7b96c4dfb4 | ||
|
|
9fe585f2e1 | ||
|
|
5a62bc1858 | ||
|
|
b5c7a41797 | ||
|
|
38bf49bd68 | ||
|
|
88ee1a04fc | ||
|
|
08e8a5a316 | ||
|
|
8930b5f3f3 | ||
|
|
da73a4f413 | ||
|
|
6120889990 | ||
|
|
52cb032a89 | ||
|
|
884623144f | ||
|
|
98505fbd1d | ||
|
|
d455d582b8 | ||
|
|
d25815ff52 | ||
|
|
3b26348a09 | ||
|
|
b1b57ed394 | ||
|
|
76838eb82a | ||
|
|
af6774678c | ||
|
|
e6e2d04a92 | ||
|
|
1ebd86c1a2 |
289
.gitchangelog.rc
Normal file
289
.gitchangelog.rc
Normal file
@@ -0,0 +1,289 @@
|
||||
# -*- coding: utf-8; mode: python -*-
|
||||
##
|
||||
## Format
|
||||
##
|
||||
## ACTION: [AUDIENCE:] COMMIT_MSG [!TAG ...]
|
||||
##
|
||||
## Description
|
||||
##
|
||||
## ACTION is one of 'chg', 'fix', 'new'
|
||||
##
|
||||
## Is WHAT the change is about.
|
||||
##
|
||||
## 'chg' is for refactor, small improvement, cosmetic changes...
|
||||
## 'fix' is for bug fixes
|
||||
## 'new' is for new features, big improvement
|
||||
##
|
||||
## AUDIENCE is optional and one of 'dev', 'usr', 'pkg', 'test', 'doc'
|
||||
##
|
||||
## Is WHO is concerned by the change.
|
||||
##
|
||||
## 'dev' is for developpers (API changes, refactors...)
|
||||
## 'usr' is for final users (UI changes)
|
||||
## 'pkg' is for packagers (packaging changes)
|
||||
## 'test' is for testers (test only related changes)
|
||||
## 'doc' is for doc guys (doc only changes)
|
||||
##
|
||||
## COMMIT_MSG is ... well ... the commit message itself.
|
||||
##
|
||||
## TAGs are additionnal adjective as 'refactor' 'minor' 'cosmetic'
|
||||
##
|
||||
## They are preceded with a '!' or a '@' (prefer the former, as the
|
||||
## latter is wrongly interpreted in github.) Commonly used tags are:
|
||||
##
|
||||
## 'refactor' is obviously for refactoring code only
|
||||
## 'minor' is for a very meaningless change (a typo, adding a comment)
|
||||
## 'cosmetic' is for cosmetic driven change (re-indentation, 80-col...)
|
||||
## 'wip' is for partial functionality but complete subfunctionality.
|
||||
##
|
||||
## Example:
|
||||
##
|
||||
## new: usr: support of bazaar implemented
|
||||
## chg: re-indentend some lines !cosmetic
|
||||
## new: dev: updated code to be compatible with last version of killer lib.
|
||||
## fix: pkg: updated year of licence coverage.
|
||||
## new: test: added a bunch of test around user usability of feature X.
|
||||
## fix: typo in spelling my name in comment. !minor
|
||||
##
|
||||
## Please note that multi-line commit message are supported, and only the
|
||||
## first line will be considered as the "summary" of the commit message. So
|
||||
## tags, and other rules only applies to the summary. The body of the commit
|
||||
## message will be displayed in the changelog without reformatting.
|
||||
|
||||
|
||||
##
|
||||
## ``ignore_regexps`` is a line of regexps
|
||||
##
|
||||
## Any commit having its full commit message matching any regexp listed here
|
||||
## will be ignored and won't be reported in the changelog.
|
||||
##
|
||||
ignore_regexps = [
|
||||
r'@minor', r'!minor',
|
||||
r'@cosmetic', r'!cosmetic',
|
||||
r'@refactor', r'!refactor',
|
||||
r'@wip', r'!wip',
|
||||
r'^([cC]hg|[fF]ix|[nN]ew)\s*:\s*[p|P]kg:',
|
||||
r'^([cC]hg|[fF]ix|[nN]ew)\s*:\s*[d|D]ev:',
|
||||
r'^(.{3,3}\s*:)?\s*[fF]irst commit.?\s*$',
|
||||
r'^$', ## ignore commits with empty messages
|
||||
]
|
||||
|
||||
|
||||
## ``section_regexps`` is a list of 2-tuples associating a string label and a
|
||||
## list of regexp
|
||||
##
|
||||
## Commit messages will be classified in sections thanks to this. Section
|
||||
## titles are the label, and a commit is classified under this section if any
|
||||
## of the regexps associated is matching.
|
||||
##
|
||||
## Please note that ``section_regexps`` will only classify commits and won't
|
||||
## make any changes to the contents. So you'll probably want to go check
|
||||
## ``subject_process`` (or ``body_process``) to do some changes to the subject,
|
||||
## whenever you are tweaking this variable.
|
||||
##
|
||||
section_regexps = [
|
||||
('New', [
|
||||
r'^[nN]ew\s*:\s*((dev|use?r|pkg|test|doc)\s*:\s*)?([^\n]*)$',
|
||||
]),
|
||||
('Changes', [
|
||||
r'^[cC]hg\s*:\s*((dev|use?r|pkg|test|doc)\s*:\s*)?([^\n]*)$',
|
||||
]),
|
||||
('Fix', [
|
||||
r'^[fF]ix\s*:\s*((dev|use?r|pkg|test|doc)\s*:\s*)?([^\n]*)$',
|
||||
]),
|
||||
|
||||
('Other', None ## Match all lines
|
||||
),
|
||||
|
||||
]
|
||||
|
||||
|
||||
## ``body_process`` is a callable
|
||||
##
|
||||
## This callable will be given the original body and result will
|
||||
## be used in the changelog.
|
||||
##
|
||||
## Available constructs are:
|
||||
##
|
||||
## - any python callable that take one txt argument and return txt argument.
|
||||
##
|
||||
## - ReSub(pattern, replacement): will apply regexp substitution.
|
||||
##
|
||||
## - Indent(chars=" "): will indent the text with the prefix
|
||||
## Please remember that template engines gets also to modify the text and
|
||||
## will usually indent themselves the text if needed.
|
||||
##
|
||||
## - Wrap(regexp=r"\n\n"): re-wrap text in separate paragraph to fill 80-Columns
|
||||
##
|
||||
## - noop: do nothing
|
||||
##
|
||||
## - ucfirst: ensure the first letter is uppercase.
|
||||
## (usually used in the ``subject_process`` pipeline)
|
||||
##
|
||||
## - final_dot: ensure text finishes with a dot
|
||||
## (usually used in the ``subject_process`` pipeline)
|
||||
##
|
||||
## - strip: remove any spaces before or after the content of the string
|
||||
##
|
||||
## - SetIfEmpty(msg="No commit message."): will set the text to
|
||||
## whatever given ``msg`` if the current text is empty.
|
||||
##
|
||||
## Additionally, you can `pipe` the provided filters, for instance:
|
||||
#body_process = Wrap(regexp=r'\n(?=\w+\s*:)') | Indent(chars=" ")
|
||||
#body_process = Wrap(regexp=r'\n(?=\w+\s*:)')
|
||||
#body_process = noop
|
||||
body_process = ReSub(r'((^|\n)[A-Z]\w+(-\w+)*: .*(\n\s+.*)*)+$', r'') | strip
|
||||
|
||||
|
||||
## ``subject_process`` is a callable
|
||||
##
|
||||
## This callable will be given the original subject and result will
|
||||
## be used in the changelog.
|
||||
##
|
||||
## Available constructs are those listed in ``body_process`` doc.
|
||||
subject_process = (strip |
|
||||
ReSub(r'^([cC]hg|[fF]ix|[nN]ew)\s*:\s*((dev|use?r|pkg|test|doc)\s*:\s*)?([^\n@]*)(@[a-z]+\s+)*$', r'\4') |
|
||||
SetIfEmpty("No commit message.") | ucfirst | final_dot)
|
||||
|
||||
|
||||
## ``tag_filter_regexp`` is a regexp
|
||||
##
|
||||
## Tags that will be used for the changelog must match this regexp.
|
||||
##
|
||||
tag_filter_regexp = r'^[0-9-]+$'
|
||||
|
||||
|
||||
## ``unreleased_version_label`` is a string or a callable that outputs a string
|
||||
##
|
||||
## This label will be used as the changelog Title of the last set of changes
|
||||
## between last valid tag and HEAD if any.
|
||||
unreleased_version_label = "(unreleased)"
|
||||
|
||||
|
||||
## ``output_engine`` is a callable
|
||||
##
|
||||
## This will change the output format of the generated changelog file
|
||||
##
|
||||
## Available choices are:
|
||||
##
|
||||
## - rest_py
|
||||
##
|
||||
## Legacy pure python engine, outputs ReSTructured text.
|
||||
## This is the default.
|
||||
##
|
||||
## - mustache(<template_name>)
|
||||
##
|
||||
## Template name could be any of the available templates in
|
||||
## ``templates/mustache/*.tpl``.
|
||||
## Requires python package ``pystache``.
|
||||
## Examples:
|
||||
## - mustache("markdown")
|
||||
## - mustache("restructuredtext")
|
||||
##
|
||||
## - makotemplate(<template_name>)
|
||||
##
|
||||
## Template name could be any of the available templates in
|
||||
## ``templates/mako/*.tpl``.
|
||||
## Requires python package ``mako``.
|
||||
## Examples:
|
||||
## - makotemplate("restructuredtext")
|
||||
##
|
||||
output_engine = rest_py
|
||||
#output_engine = mustache("restructuredtext")
|
||||
#output_engine = mustache("markdown")
|
||||
#output_engine = makotemplate("restructuredtext")
|
||||
|
||||
|
||||
## ``include_merge`` is a boolean
|
||||
##
|
||||
## This option tells git-log whether to include merge commits in the log.
|
||||
## The default is to include them.
|
||||
include_merge = True
|
||||
|
||||
|
||||
## ``log_encoding`` is a string identifier
|
||||
##
|
||||
## This option tells gitchangelog what encoding is outputed by ``git log``.
|
||||
## The default is to be clever about it: it checks ``git config`` for
|
||||
## ``i18n.logOutputEncoding``, and if not found will default to git's own
|
||||
## default: ``utf-8``.
|
||||
#log_encoding = 'utf-8'
|
||||
|
||||
|
||||
## ``publish`` is a callable
|
||||
##
|
||||
## Sets what ``gitchangelog`` should do with the output generated by
|
||||
## the output engine. ``publish`` is a callable taking one argument
|
||||
## that is an interator on lines from the output engine.
|
||||
##
|
||||
## Some helper callable are provided:
|
||||
##
|
||||
## Available choices are:
|
||||
##
|
||||
## - stdout
|
||||
##
|
||||
## Outputs directly to standard output
|
||||
## (This is the default)
|
||||
##
|
||||
## - FileInsertAtFirstRegexMatch(file, pattern, idx=lamda m: m.start())
|
||||
##
|
||||
## Creates a callable that will parse given file for the given
|
||||
## regex pattern and will insert the output in the file.
|
||||
## ``idx`` is a callable that receive the matching object and
|
||||
## must return a integer index point where to insert the
|
||||
## the output in the file. Default is to return the position of
|
||||
## the start of the matched string.
|
||||
##
|
||||
## - FileRegexSubst(file, pattern, replace, flags)
|
||||
##
|
||||
## Apply a replace inplace in the given file. Your regex pattern must
|
||||
## take care of everything and might be more complex. Check the README
|
||||
## for a complete copy-pastable example.
|
||||
##
|
||||
# publish = FileInsertIntoFirstRegexMatch(
|
||||
# "CHANGELOG.rst",
|
||||
# r'/(?P<rev>[0-9]+\.[0-9]+(\.[0-9]+)?)\s+\([0-9]+-[0-9]{2}-[0-9]{2}\)\n--+\n/',
|
||||
# idx=lambda m: m.start(1)
|
||||
# )
|
||||
#publish = stdout
|
||||
|
||||
|
||||
## ``revs`` is a list of callable or a list of string
|
||||
##
|
||||
## callable will be called to resolve as strings and allow dynamical
|
||||
## computation of these. The result will be used as revisions for
|
||||
## gitchangelog (as if directly stated on the command line). This allows
|
||||
## to filter exaclty which commits will be read by gitchangelog.
|
||||
##
|
||||
## To get a full documentation on the format of these strings, please
|
||||
## refer to the ``git rev-list`` arguments. There are many examples.
|
||||
##
|
||||
## Using callables is especially useful, for instance, if you
|
||||
## are using gitchangelog to generate incrementally your changelog.
|
||||
##
|
||||
## Some helpers are provided, you can use them::
|
||||
##
|
||||
## - FileFirstRegexMatch(file, pattern): will return a callable that will
|
||||
## return the first string match for the given pattern in the given file.
|
||||
## If you use named sub-patterns in your regex pattern, it'll output only
|
||||
## the string matching the regex pattern named "rev".
|
||||
##
|
||||
## - Caret(rev): will return the rev prefixed by a "^", which is a
|
||||
## way to remove the given revision and all its ancestor.
|
||||
##
|
||||
## Please note that if you provide a rev-list on the command line, it'll
|
||||
## replace this value (which will then be ignored).
|
||||
##
|
||||
## If empty, then ``gitchangelog`` will act as it had to generate a full
|
||||
## changelog.
|
||||
##
|
||||
## The default is to use all commits to make the changelog.
|
||||
#revs = ["^1.0.3", ]
|
||||
#revs = [
|
||||
# Caret(
|
||||
# FileFirstRegexMatch(
|
||||
# "CHANGELOG.rst",
|
||||
# r"(?P<rev>[0-9]+\.[0-9]+(\.[0-9]+)?)\s+\([0-9]+-[0-9]{2}-[0-9]{2}\)\n--+\n")),
|
||||
# "HEAD"
|
||||
#]
|
||||
revs = []
|
||||
200
.github/workflows/build.yml
vendored
200
.github/workflows/build.yml
vendored
@@ -12,36 +12,59 @@ jobs:
|
||||
outputs:
|
||||
upload_url: ${{ steps.create_release.outputs.upload_url }}
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
with:
|
||||
fetch-depth: 0
|
||||
submodules: false
|
||||
- name: Generate release name
|
||||
id: release_name
|
||||
# https://github.community/t/how-to-get-just-the-tag-name/16241/4
|
||||
run: echo ::set-output name=name::${GITHUB_REF/refs\/*s\//}
|
||||
- name: Generate changes file
|
||||
uses: sarnold/gitchangelog-action@master
|
||||
with:
|
||||
config_file: .gitchangelog.rc
|
||||
github_token: ${{ secrets.GITHUB_TOKEN }}
|
||||
- name: Create release
|
||||
id: create_release
|
||||
uses: actions/create-release@v1
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
with:
|
||||
tag_name: ${{ steps.release_name.outputs.name }}
|
||||
tag_name: ${{ steps.release_name.outputs.name }}-tag
|
||||
release_name: ${{ steps.release_name.outputs.name }}
|
||||
body: |
|
||||
Build ${{ steps.release_name.outputs.name }}
|
||||
body_path: CHANGES.md
|
||||
draft: false
|
||||
prerelease: true
|
||||
|
||||
build-linux:
|
||||
runs-on: ubuntu-20.04
|
||||
runs-on: ubuntu-24.04
|
||||
needs: [create_release]
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: actions/checkout@v3
|
||||
with:
|
||||
submodules: true
|
||||
- name: Workaround for apt update failure
|
||||
run: sudo rm /etc/apt/sources.list.d/github_git-lfs.*
|
||||
run: sudo rm -f /etc/apt/sources.list.d/github_git-lfs.*
|
||||
- name: Install deps
|
||||
run: sudo apt update && sudo apt install build-essential bison flex libncurses5-dev gcc-arm-linux-gnueabi qemu-user-static debootstrap
|
||||
run: sudo apt update && sudo apt install build-essential bison flex libncurses5-dev gcc-arm-linux-gnueabi qemu-user-static debootstrap python3-pip
|
||||
- name: Upgrade pip and setuptools
|
||||
run: pip3 install -U pip 'setuptools<71'
|
||||
- name: Install listconfig
|
||||
run: pip3 install listconfig
|
||||
- name: Configure for Linux
|
||||
run: make ldefconfig
|
||||
- name: Generate listconfig
|
||||
run: listconfig ./linux-brain/Kconfig ./linux-brain/.config > listconfig
|
||||
- name: Upload listconfig
|
||||
uses: actions/upload-release-asset@v1
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
with:
|
||||
upload_url: ${{ needs.create_release.outputs.upload_url }}
|
||||
asset_path: listconfig
|
||||
asset_name: listconfig
|
||||
asset_content_type: text/plain
|
||||
- name: Build Linux
|
||||
run: make lbuild
|
||||
- name: Setup releases
|
||||
@@ -63,32 +86,81 @@ jobs:
|
||||
asset_path: release.zip
|
||||
asset_name: ${{ steps.archive_name.outputs.name }}.zip
|
||||
asset_content_type: application/zip
|
||||
build-linux-x1:
|
||||
runs-on: ubuntu-24.04
|
||||
needs: [create_release]
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
with:
|
||||
submodules: true
|
||||
- name: Workaround for apt update failure
|
||||
run: sudo rm -f /etc/apt/sources.list.d/github_git-lfs.*
|
||||
- name: Install deps
|
||||
run: sudo apt update && sudo apt install build-essential bison flex libncurses5-dev gcc-arm-linux-gnueabihf libssl-dev lzop qemu-user-static debootstrap
|
||||
- name: Configure for Linux
|
||||
run: make ldefconfig-x1
|
||||
- name: Build Linux
|
||||
run: make lbuild
|
||||
- name: Setup releases
|
||||
id: release_name
|
||||
run: |
|
||||
mkdir release
|
||||
cp ./linux-brain/arch/arm/boot/dts/imx7ulp-pwh*.dtb release/
|
||||
cp ./linux-brain/arch/arm/boot/zImage release/zImage
|
||||
zip -r release.zip release/
|
||||
- name: Generate archive name
|
||||
id: archive_name
|
||||
run: echo ::set-output name=name::linux-x1-${GITHUB_REF/refs\/*s\//}
|
||||
- name: Upload release.zip
|
||||
uses: actions/upload-release-asset@v1
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
with:
|
||||
upload_url: ${{ needs.create_release.outputs.upload_url }}
|
||||
asset_path: release.zip
|
||||
asset_name: ${{ steps.archive_name.outputs.name }}.zip
|
||||
asset_content_type: application/zip
|
||||
|
||||
build-uboot:
|
||||
runs-on: ubuntu-20.04
|
||||
runs-on: ubuntu-24.04
|
||||
needs: [create_release]
|
||||
strategy:
|
||||
matrix:
|
||||
include:
|
||||
- model: a7200
|
||||
nk: edna3exe.bin
|
||||
lilo: gen2.bin
|
||||
- model: a7400
|
||||
nk: edna3exe.bin
|
||||
lilo: gen2_7400.bin
|
||||
- model: sh1
|
||||
nk: edsa1exe.bin
|
||||
lilo: gen3_1.bin
|
||||
- model: sh2
|
||||
nk: edsa2exe.bin
|
||||
lilo: gen3_2.bin
|
||||
- model: sh3
|
||||
nk: edsa3exe.bin
|
||||
lilo: gen3_3.bin
|
||||
- model: sh4
|
||||
nk: edsh4exe.bin
|
||||
lilo: gen3_4.bin
|
||||
- model: sh5
|
||||
nk: edsh5exe.bin
|
||||
lilo: gen3_5.bin
|
||||
- model: sh6
|
||||
nk: edsh6exe.bin
|
||||
lilo: gen3_6.bin
|
||||
- model: sh7
|
||||
nk: edsh7exe.bin
|
||||
lilo: gen3_7.bin
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: actions/checkout@v3
|
||||
with:
|
||||
submodules: true
|
||||
- name: Workaround for apt update failure
|
||||
run: sudo rm /etc/apt/sources.list.d/github_git-lfs.*
|
||||
run: sudo rm -f /etc/apt/sources.list.d/github_git-lfs.*
|
||||
- name: Install deps
|
||||
run: sudo apt update && sudo apt install build-essential bison flex libncurses5-dev gcc-arm-linux-gnueabi qemu-user-static debootstrap
|
||||
- name: Build nkbin-maker
|
||||
@@ -104,6 +176,7 @@ jobs:
|
||||
run: |
|
||||
mkdir release
|
||||
cp ./u-boot-brain/u-boot.bin release/u-boot.bin
|
||||
cp ./u-boot-brain/u-boot.bin release/${{ matrix.lilo }}
|
||||
cp ./u-boot-brain/u-boot.sb release/u-boot.sb
|
||||
cp ./nk.bin release/${{ matrix.nk }}
|
||||
zip -r release.zip release/
|
||||
@@ -120,15 +193,61 @@ jobs:
|
||||
asset_name: ${{ steps.archive_name.outputs.name }}.zip
|
||||
asset_content_type: application/zip
|
||||
|
||||
build-sd:
|
||||
runs-on: ubuntu-20.04
|
||||
build-uboot-x1:
|
||||
runs-on: ubuntu-24.04
|
||||
needs: [create_release]
|
||||
strategy:
|
||||
matrix:
|
||||
include:
|
||||
- model: h1
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: actions/checkout@v3
|
||||
with:
|
||||
submodules: true
|
||||
- name: Workaround for apt update failure
|
||||
run: sudo rm /etc/apt/sources.list.d/github_git-lfs.*
|
||||
run: sudo rm -f /etc/apt/sources.list.d/github_git-lfs.*
|
||||
- name: Install deps
|
||||
run: sudo apt update && sudo apt install build-essential bison flex libncurses5-dev gcc-arm-linux-gnueabihf libssl-dev lzop qemu-user-static debootstrap
|
||||
- name: Configure for U-Boot
|
||||
run: make udefconfig-${{ matrix.model }}
|
||||
- name: Build U-Boot
|
||||
run: make ubuild
|
||||
- name: Setup releases
|
||||
id: release_name
|
||||
run: |
|
||||
mkdir release
|
||||
cp ./u-boot-brain/u-boot.bin release/u-boot.bin
|
||||
zip -r release.zip release/
|
||||
- name: Generate archive name
|
||||
id: archive_name
|
||||
run: echo ::set-output name=name::uboot-${{ matrix.model }}-${GITHUB_REF/refs\/*s\//}
|
||||
- name: Upload release.zip
|
||||
uses: actions/upload-release-asset@v1
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
with:
|
||||
upload_url: ${{ needs.create_release.outputs.upload_url }}
|
||||
asset_path: release.zip
|
||||
asset_name: ${{ steps.archive_name.outputs.name }}.zip
|
||||
asset_content_type: application/zip
|
||||
|
||||
build-sd:
|
||||
runs-on: ubuntu-24.04
|
||||
needs: [create_release]
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
with:
|
||||
submodules: true
|
||||
- name: Make /opt writable
|
||||
run: sudo chown "$(whoami):$(whoami)" /opt
|
||||
- name: Install cegcc
|
||||
run: |
|
||||
wget -O cegcc.zip https://github.com/brain-hackers/cegcc-build/releases/download/2022-04-11-133546/cegcc-2022-04-11-133546.zip
|
||||
unzip -q cegcc.zip
|
||||
cp -r cegcc /opt/
|
||||
- name: Workaround for apt update failure
|
||||
run: sudo rm -f /etc/apt/sources.list.d/github_git-lfs.*
|
||||
- name: Install deps
|
||||
run: sudo apt update && sudo apt install kpartx build-essential bison flex libncurses5-dev gcc-arm-linux-gnueabi qemu-user-static debootstrap
|
||||
- name: Configure for Linux
|
||||
@@ -136,14 +255,18 @@ jobs:
|
||||
- name: Build Linux
|
||||
run: make lbuild
|
||||
- name: Build Debian Root
|
||||
run: make brainux
|
||||
run: make brainux brainux-umount-special
|
||||
- name: Build bsd-ce
|
||||
run: make -C nkbin_maker bsd-ce
|
||||
- name: Generate image name
|
||||
- name: Generate version string and image name
|
||||
id: image_name
|
||||
run: echo ::set-output name=name::sdimage-${GITHUB_REF/refs\/*s\//}
|
||||
run: |
|
||||
echo "name=sdimage-${GITHUB_REF/refs\/*s\//}" >> $GITHUB_OUTPUT
|
||||
echo "version=${GITHUB_REF/refs\/*s\//}" >> $GITHUB_OUTPUT
|
||||
- name: Build SD image
|
||||
run: make image/sd.img && mv image/sd.img ${{ steps.image_name.outputs.name }}.img
|
||||
env:
|
||||
BRAINUX_VERSION: ${{ steps.image_name.outputs.version }}
|
||||
- name: Compress
|
||||
run: zip ${{ steps.image_name.outputs.name }}.zip ${{ steps.image_name.outputs.name }}.img
|
||||
- name: Upload the image
|
||||
@@ -156,3 +279,46 @@ jobs:
|
||||
asset_name: ${{ steps.image_name.outputs.name }}.zip
|
||||
asset_content_type: application/zip
|
||||
|
||||
build-sd-x1:
|
||||
runs-on: ubuntu-24.04
|
||||
needs: [create_release]
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
with:
|
||||
submodules: true
|
||||
- name: Workaround for apt update failure
|
||||
run: sudo rm -f /etc/apt/sources.list.d/github_git-lfs.*
|
||||
- name: Install deps
|
||||
run: sudo apt update && sudo apt install kpartx build-essential bison flex libncurses5-dev gcc-arm-linux-gnueabihf libssl-dev lzop qemu-user-static debootstrap
|
||||
- name: Upgrade pip and setuptools
|
||||
run: pip3 install -U pip setuptools
|
||||
- name: Install pyelftools
|
||||
run: pip3 install pyelftools
|
||||
- name: Build Boot4u
|
||||
run: make boot4ubuild
|
||||
- name: Configure for U-Boot
|
||||
run: make udefconfig-h1
|
||||
- name: Build U-Boot
|
||||
run: make ubuild
|
||||
- name: Configure for Linux
|
||||
run: make ldefconfig-x1
|
||||
- name: Build Linux
|
||||
run: make lbuild
|
||||
- name: Build Debian Root
|
||||
run: make brainux brainux-umount-special
|
||||
- name: Generate image name
|
||||
id: image_name
|
||||
run: echo ::set-output name=name::sdimage-x1-${GITHUB_REF/refs\/*s\//}
|
||||
- name: Build SD image
|
||||
run: make image/sd_x1.img && mv image/sd_x1.img ${{ steps.image_name.outputs.name }}.img
|
||||
- name: Compress
|
||||
run: zip ${{ steps.image_name.outputs.name }}.zip ${{ steps.image_name.outputs.name }}.img
|
||||
- name: Upload the image
|
||||
uses: actions/upload-release-asset@v1
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
with:
|
||||
upload_url: ${{ needs.create_release.outputs.upload_url }}
|
||||
asset_path: ${{ steps.image_name.outputs.name }}.zip
|
||||
asset_name: ${{ steps.image_name.outputs.name }}.zip
|
||||
asset_content_type: application/zip
|
||||
|
||||
5
.gitignore
vendored
5
.gitignore
vendored
@@ -1,4 +1,7 @@
|
||||
env
|
||||
debian
|
||||
brainux
|
||||
cache/*
|
||||
!cache/.gitkeep
|
||||
nk.bin
|
||||
image/sd.img
|
||||
image/work
|
||||
|
||||
11
.gitmodules
vendored
11
.gitmodules
vendored
@@ -3,7 +3,16 @@
|
||||
url = https://github.com/brain-hackers/u-boot-brain.git
|
||||
[submodule "linux-brain"]
|
||||
path = linux-brain
|
||||
url = https://github.com/brain-hackers/linux-brain
|
||||
url = https://github.com/brain-hackers/linux-brain.git
|
||||
[submodule "nkbin_maker"]
|
||||
path = nkbin_maker
|
||||
url = https://github.com/brain-hackers/nkbin_maker.git
|
||||
[submodule "boot4u"]
|
||||
path = boot4u
|
||||
url = https://github.com/brain-hackers/boot4u.git
|
||||
[submodule "brainlilo"]
|
||||
path = brainlilo
|
||||
url = https://github.com/brain-hackers/brainlilo.git
|
||||
[submodule "buildroot"]
|
||||
path = buildroot
|
||||
url = https://github.com/brain-hackers/buildroot.git
|
||||
|
||||
148
AGENTS.md
Normal file
148
AGENTS.md
Normal file
@@ -0,0 +1,148 @@
|
||||
# AGENTS.md
|
||||
|
||||
## Purpose
|
||||
|
||||
This repository builds Brainux, a Debian-based Linux distribution and SD card image for SHARP Brain devices. The root repo is the orchestration layer: it wires together kernel, bootloader, rootfs, image-building scripts, CI, and several hardware-specific submodules.
|
||||
|
||||
Future agents should treat this file as project memory plus operating instructions for working in `buildbrain`.
|
||||
|
||||
## Repository map
|
||||
|
||||
- `linux-brain/`: Linux kernel submodule.
|
||||
- `u-boot-brain/`: U-Boot submodule.
|
||||
- `boot4u/`: chain-boot tool for newer models.
|
||||
- `brainlilo/`: chain-boot tool for older models.
|
||||
- `nkbin_maker/`: converts `u-boot.bin` into `nk.bin` for the Windows CE boot flow.
|
||||
- `buildroot/`: alternative lightweight rootfs build.
|
||||
- `os-brainux/`: Brainux rootfs customization scripts and overrides.
|
||||
- `os-buildroot/`: Buildroot-side overrides.
|
||||
- `image/`: SD image creation scripts.
|
||||
- `tools/`: helper scripts such as cross-prefix detection and APT cache tooling.
|
||||
- `docs/knowledge/`: hardware and boot-process knowledge for SHARP Brain devices. Prefer the Markdown files over PDFs for fast reading and search.
|
||||
|
||||
## Search strategy
|
||||
|
||||
Do not start with a repo-wide search from the root unless you actually need submodule results. This repo contains large submodules, and broad searches are noisy and slow.
|
||||
|
||||
Prefer scoped searches:
|
||||
|
||||
- Kernel work: search only under `linux-brain/`.
|
||||
- U-Boot work: search only under `u-boot-brain/`.
|
||||
- Rootfs and image work: search `os-brainux/`, `image/`, `tools/`, and the root `Makefile`.
|
||||
- Hardware/background research: read `docs/knowledge/*.md`.
|
||||
|
||||
## Important project knowledge
|
||||
|
||||
- Brainux development often happens in submodules, not in the root repo.
|
||||
- Typical kernel workflow:
|
||||
1. work inside `linux-brain/` on a branch based on `brain`
|
||||
2. return to the repo root
|
||||
3. run `make lclean ldefconfig lbuild` for a clean rebuild, or `make lbuild` for incremental rebuilds
|
||||
4. test on real hardware by copying `linux-brain/arch/arm/boot/zImage` and matching DTBs
|
||||
5. commit in `linux-brain/` using the surrounding kernel commit style
|
||||
- Typical U-Boot workflow is similar, but uses `u-boot-brain/` plus the `make udefconfig-*` and `make ubuild` targets.
|
||||
- Typical Brainux rootfs workflow edits files under `os-brainux/`, then runs `make brainux` or `make image/sd.img`.
|
||||
- Real-device testing is part of the normal loop. A local build passing is useful but not sufficient for hardware changes.
|
||||
|
||||
## Main build targets
|
||||
|
||||
The root `Makefile` is the main entry point.
|
||||
|
||||
- Setup:
|
||||
- `make setup`: initialize submodules.
|
||||
- `make setup-dev`: create `env/` and install `r3build`.
|
||||
- `make watch`: run the file watcher after `setup-dev`.
|
||||
- Linux:
|
||||
- `make ldefconfig`
|
||||
- `make ldefconfig-x1`
|
||||
- `make lbuild`
|
||||
- `make lclean`
|
||||
- U-Boot:
|
||||
- `make udefconfig-<model>` such as `udefconfig-sh1` or `udefconfig-h1`
|
||||
- `make ubuild`
|
||||
- `make uclean`
|
||||
- NK.bin:
|
||||
- `make nkbin-maker`
|
||||
- `make nk.bin`
|
||||
- Chain boot tools:
|
||||
- `make boot4ubuild`
|
||||
- `make lilobuild`
|
||||
- Rootfs and images:
|
||||
- `make brainux`
|
||||
- `make brainux-umount-special`
|
||||
- `make brainux-clean`
|
||||
- `make buildroot_rootfs`
|
||||
- `make image/sd.img`
|
||||
- `make image/sd_x1.img`
|
||||
- `make image/sd_buildroot.img`
|
||||
- Utilities:
|
||||
- `make aptcache`
|
||||
- `make uuu`
|
||||
|
||||
## Build behavior and constraints
|
||||
|
||||
- `make brainux` only works on Linux. It uses `debootstrap`, `qemu-arm-static`, `sudo`, chroot, and bind mounts.
|
||||
- Outside CI, `make brainux` expects the local APT cache from `make aptcache` and points debootstrap at `http://localhost:65432/debian/`.
|
||||
- `make brainux-umount-special` is the normal cleanup step after rootfs builds.
|
||||
- `make image/sd.img` and related image targets depend on a prepared rootfs and remove `image/work` via `make clean_work`.
|
||||
- `make ubuild` chooses the output format from the detected cross toolchain:
|
||||
- `arm-linux-gnueabi-` builds `u-boot.sb`
|
||||
- other configured prefixes build `u-boot.imx`
|
||||
|
||||
## CI reference
|
||||
|
||||
The authoritative automation is `.github/workflows/build.yml`.
|
||||
|
||||
CI currently does the following:
|
||||
|
||||
- Builds Linux artifacts for both the default family and the `x1` family.
|
||||
- Builds U-Boot artifacts for multiple models through a matrix.
|
||||
- Builds `nk.bin` for the older-model U-Boot jobs.
|
||||
- Builds full Debian-based SD images for the default family and for `x1`.
|
||||
|
||||
When changing build logic, keep the local Makefile workflow and CI workflow aligned.
|
||||
|
||||
## Files and outputs to know
|
||||
|
||||
- Linux outputs:
|
||||
- `linux-brain/arch/arm/boot/zImage`
|
||||
- DTBs under `linux-brain/arch/arm/boot/dts/`
|
||||
- U-Boot outputs:
|
||||
- `u-boot-brain/u-boot.bin`
|
||||
- `u-boot-brain/u-boot.sb` or `u-boot-brain/u-boot.imx`
|
||||
- Converted boot image:
|
||||
- `nk.bin`
|
||||
- SD images:
|
||||
- `image/sd.img`
|
||||
- `image/sd_x1.img`
|
||||
- `image/sd_buildroot.img`
|
||||
|
||||
## Guidance for edits
|
||||
|
||||
- If the task is about kernel or U-Boot source, make the change in the relevant submodule rather than trying to patch generated outputs or wrapper scripts in the root repo.
|
||||
- If the task is about Brainux package selection, startup behavior, or filesystem contents, inspect `os-brainux/` first.
|
||||
- If the task is about image layout or packaging, inspect `image/` and the root `Makefile`.
|
||||
- If the task is about cross-compile behavior, inspect `tools/getcross` and the relevant Makefile targets.
|
||||
- Avoid using interactive config editors such as `menuconfig` unless the user explicitly asks; prefer editing committed defconfig/config sources where practical.
|
||||
|
||||
## Validation expectations
|
||||
|
||||
Choose the lightest validation that matches the change:
|
||||
|
||||
- Makefile or CI edits: run the directly affected `make` target when feasible.
|
||||
- Kernel build plumbing: at least run the relevant `make ldefconfig*` or `make lbuild` path if the environment supports it.
|
||||
- U-Boot build plumbing: at least run the matching `make udefconfig-*` and `make ubuild` path if feasible.
|
||||
- Rootfs/image changes: prefer `make brainux brainux-umount-special`, and image targets when dependencies and privileges are available.
|
||||
|
||||
If a full build is not possible because of missing toolchains, root privileges, mounts, or long runtime, say that explicitly and leave the repo in a clean state.
|
||||
|
||||
## Knowledge docs
|
||||
|
||||
- Start with `docs/knowledge/*.md` when you need hardware, boot-sequence, suspend, or eMMC-install context.
|
||||
- `docs/knowledge/AGENTS.md` defines the rule for converting a knowledge PDF into Markdown. If asked to do such a conversion, preserve page positions with `# Page NN` headings, add an abstract, and write a concise text-first technical explanation rather than raw OCR.
|
||||
|
||||
## Commit and review notes
|
||||
|
||||
- Submodules have their own history and conventions. Kernel commits should follow the style already used in `linux-brain/`.
|
||||
- Root-repo changes should stay focused on orchestration, config, CI, docs, image assembly, and rootfs customization.
|
||||
- When a task spans both the root repo and a submodule, keep the responsibility split clear in the final report.
|
||||
107
Makefile
107
Makefile
@@ -1,7 +1,9 @@
|
||||
JOBS=$(shell grep -c '^processor' /proc/cpuinfo)
|
||||
|
||||
UBOOT_CROSS=$(shell ./tools/getcross u-boot)
|
||||
LINUX_CROSS=$(shell ./tools/getcross linux)
|
||||
ROOTFS_CROSS=$(shell ./tools/getcross rootfs)
|
||||
export ARCH=arm
|
||||
export CROSS_COMPILE=arm-linux-gnueabi-
|
||||
|
||||
.PHONY:
|
||||
setup:
|
||||
@@ -33,11 +35,11 @@ udefconfig-%:
|
||||
|
||||
.PHONY:
|
||||
usavedefconfig:
|
||||
make -C ./u-boot-brain savedefconfig
|
||||
make CROSS_COMPILE=$(UBOOT_CROSS) -C ./u-boot-brain savedefconfig
|
||||
|
||||
.PHONY:
|
||||
umenuconfig:
|
||||
make -C ./u-boot-brain menuconfig
|
||||
make CROSS_COMPILE=$(UBOOT_CROSS) -C ./u-boot-brain menuconfig
|
||||
|
||||
.PHONY:
|
||||
uclean:
|
||||
@@ -45,28 +47,65 @@ uclean:
|
||||
|
||||
.PHONY:
|
||||
ubuild:
|
||||
make -j$(JOBS) -C ./u-boot-brain u-boot.sb
|
||||
if [ "$(UBOOT_CROSS)" = "arm-linux-gnueabi-" ]; then \
|
||||
make CROSS_COMPILE=$(UBOOT_CROSS) -j$(JOBS) -C ./u-boot-brain u-boot.sb; \
|
||||
else \
|
||||
make CROSS_COMPILE=$(UBOOT_CROSS) -j$(JOBS) -C ./u-boot-brain u-boot.imx; \
|
||||
fi
|
||||
|
||||
.PHONY:
|
||||
ldefconfig:
|
||||
make -C ./linux-brain brain_defconfig
|
||||
|
||||
.PHONY:
|
||||
ldefconfig-x1:
|
||||
make -C ./linux-brain imx_v7_defconfig
|
||||
|
||||
.PHONY:
|
||||
lmenuconfig:
|
||||
make -C ./linux-brain menuconfig
|
||||
make CROSS_COMPILE=$(LINUX_CROSS) -C ./linux-brain menuconfig
|
||||
|
||||
.PHONY:
|
||||
lsavedefconfig:
|
||||
make -C ./linux-brain savedefconfig
|
||||
make CROSS_COMPILE=$(LINUX_CROSS) -C ./linux-brain savedefconfig
|
||||
mv ./linux-brain/defconfig ./linux-brain/arch/arm/configs/brain_defconfig
|
||||
|
||||
.PHONY:
|
||||
lsavedefconfig-x1:
|
||||
make CROSS_COMPILE=$(LINUX_CROSS) -C ./linux-brain savedefconfig
|
||||
mv ./linux-brain/defconfig ./linux-brain/arch/arm/configs/imx_v7_defconfig
|
||||
|
||||
.PHONY:
|
||||
lclean:
|
||||
make -C ./linux-brain distclean
|
||||
|
||||
.PHONY:
|
||||
lbuild:
|
||||
make -j$(JOBS) -C ./linux-brain
|
||||
make CROSS_COMPILE=$(LINUX_CROSS) -j$(JOBS) -C ./linux-brain
|
||||
|
||||
.PHONY:
|
||||
ldebpkg:
|
||||
$(MAKE) ldebpkg-build || $(MAKE) ldebpkg-clean
|
||||
mkdir -p debian
|
||||
mv linux-*.buildinfo debian/
|
||||
mv linux-*.changes debian/
|
||||
mv linux-*.diff.gz debian/
|
||||
mv linux-*.dsc debian/
|
||||
mv linux-*.orig.tar.gz debian/
|
||||
mv linux-*.deb debian/
|
||||
|
||||
.PHONY:
|
||||
ldebpkg-build:
|
||||
make -j$(JOBS) -C ./linux-brain deb-pkg
|
||||
|
||||
.PHONY:
|
||||
ldebpkg-clean:
|
||||
rm -f linux-*.buildinfo
|
||||
rm -f linux-*.changes
|
||||
rm -f linux-*.diff.gz
|
||||
rm -f linux-*.dsc
|
||||
rm -f linux-*.orig.tar.gz
|
||||
rm -f linux-*.deb
|
||||
|
||||
.PHONY:
|
||||
uuu:
|
||||
@@ -80,26 +119,68 @@ nkbin-maker:
|
||||
nk.bin:
|
||||
./nkbin_maker/bsd-ce ./u-boot-brain/u-boot.bin
|
||||
|
||||
.PHONY:
|
||||
boot4ubuild:
|
||||
make -C ./boot4u
|
||||
|
||||
.PHONY:
|
||||
boot4uclean:
|
||||
make -C ./boot4u clean
|
||||
|
||||
.PHONY:
|
||||
lilobuild:
|
||||
make -C ./brainlilo
|
||||
|
||||
.PHONY:
|
||||
liloclean:
|
||||
make -C ./brainlilo clean
|
||||
|
||||
brainux:
|
||||
@if [ "$(shell uname)" != "Linux" ]; then \
|
||||
echo "Debootstrap is only available in Linux!"; \
|
||||
exit 1; \
|
||||
fi
|
||||
mkdir -p brainux
|
||||
sudo mkdir -p brainux/proc brainux/sys
|
||||
sudo mount -t proc none $(shell pwd)/brainux/proc
|
||||
sudo mount --rbind /sys $(shell pwd)/brainux/sys
|
||||
|
||||
@if [ "$(CI)" = "true" ]; then \
|
||||
echo "I'm in CI and debootstrap without cache."; \
|
||||
sudo debootstrap --arch=armel --foreign buster brainux/; \
|
||||
sudo debootstrap --arch=$(ROOTFS_CROSS) --foreign trixie brainux/; \
|
||||
else \
|
||||
sudo debootstrap --arch=armel --foreign buster brainux/ http://localhost:65432/debian/; \
|
||||
sudo debootstrap --arch=$(ROOTFS_CROSS) --foreign trixie brainux/ http://localhost:65432/debian/; \
|
||||
fi
|
||||
sudo cp /usr/bin/qemu-arm-static brainux/usr/bin/
|
||||
sudo cp ./os-brainux/setup_brainux.sh brainux/
|
||||
sudo ./os-brainux/override-pre.sh ./os-brainux/override ./brainux
|
||||
sudo -E chroot brainux /setup_brainux.sh
|
||||
sudo rm brainux/setup_brainux.sh
|
||||
sudo ./os-brainux/override.sh ./os-brainux/override ./brainux
|
||||
|
||||
brainux-umount-special:
|
||||
sudo umount $(shell pwd)/brainux/proc || true
|
||||
sudo umount -l $(shell pwd)/brainux/sys || true
|
||||
sudo rm -rf brainux/proc brainux/sys
|
||||
|
||||
brainux-clean: brainux-umount-special
|
||||
sudo rm -rf brainux
|
||||
|
||||
buildroot_rootfs:
|
||||
make -C buildroot brain_imx28_defconfig
|
||||
make -C buildroot -j 12
|
||||
sudo mkdir -p buildroot_rootfs
|
||||
sudo tar -C ./buildroot_rootfs -xf buildroot/output/images/rootfs.tar
|
||||
|
||||
image/sd.img: clean_work
|
||||
./image/build_image.sh
|
||||
./image/build_image.sh brainux sd.img 3072
|
||||
|
||||
image/sd_x1.img: clean_work
|
||||
./image/build_image_x1.sh brainux sd_x1.img 3072
|
||||
|
||||
image/sd_buildroot.img: clean_work
|
||||
./image/build_image.sh buildroot_rootfs sd_buildroot.img 128
|
||||
|
||||
|
||||
.PHONY:
|
||||
clean_work:
|
||||
@@ -108,5 +189,9 @@ clean_work:
|
||||
.PHONY:
|
||||
aptcache:
|
||||
./tools/aptcache_linux_amd64 \
|
||||
-rule 'local=localhost:65432, remote=ftp.jaist.ac.jp' \
|
||||
-rule 'local=localhost:65432, remote=ftp.riken.jp, root=/Linux/debian' \
|
||||
-rule 'local=localhost:65433, remote=security.debian.org'
|
||||
|
||||
.PHONY:
|
||||
datetag:
|
||||
git tag $(shell ./tools/version)
|
||||
|
||||
74
README.md
74
README.md
@@ -3,7 +3,7 @@ buildbrain
|
||||
|
||||
This repository includes:
|
||||
|
||||
- linux-brain, u-boot-brain and nkbin_maker as submodules
|
||||
- linux-brain, u-boot-brain, nkbin_maker and boot4u as submodules
|
||||
- Useful build targets in Makefile
|
||||
- r3build.toml to watch changes that occur in submodules
|
||||
|
||||
@@ -12,6 +12,7 @@ Confirmed environments
|
||||
----------------------
|
||||
|
||||
- Debian 10 (buster) amd64
|
||||
- Debian 11 (bullseye) amd64
|
||||
|
||||
|
||||
Getting Started
|
||||
@@ -20,13 +21,13 @@ Getting Started
|
||||
1. Install dependencies.
|
||||
|
||||
```
|
||||
$ sudo apt install build-essential bison flex libncurses5-dev gcc-arm-linux-gnueabi
|
||||
$ sudo apt install build-essential bison flex libncurses5-dev gcc-arm-linux-gnueabi gcc-arm-linux-gnueabihf libssl-dev bc lzop qemu-user-static debootstrap kpartx libyaml-dev python3-pyelftools
|
||||
```
|
||||
|
||||
1. Clone this repository with recursive clone enabled.
|
||||
|
||||
```
|
||||
$ git clone --recursive git@github.com:puhitaku/buildbrain.git
|
||||
$ git clone --recursive git@github.com:brain-hackers/buildbrain.git
|
||||
```
|
||||
|
||||
- If you've cloned it without `--recursive`, run following command:
|
||||
@@ -41,32 +42,47 @@ Getting Started
|
||||
- Put `uuu` where the PATH executable points to.
|
||||
|
||||
|
||||
Build and inject U-Boot
|
||||
Build U-Boot
|
||||
-----------------------
|
||||
|
||||
1. Run `make udefconfig-sh*` to generate `.config`.
|
||||
|
||||
- For Sx1: `make udefconfig-sh1`
|
||||
- For Sx6: `make udefconfig-sh6`
|
||||
- For x1: `make udefconfig-h1`
|
||||
|
||||
2. Run `make ubuild` to build whole repository and generate `u-boot.sb`.
|
||||
2. Run `make ubuild` to build whole repository and generate `u-boot.sb` or `u-boot.bin`.
|
||||
|
||||
- i.MX283 loads a packed U-Boot executable called `u-boot.sb`.
|
||||
|
||||
3. To inject the executable into i.MX283 in recovery mode, run `make uuu`.
|
||||
|
||||
Inject U-Boot into i.MX283 in recovery mode
|
||||
-----------------------
|
||||
1. Follow `Build U-Boot` procedure to make U-Boot binary.
|
||||
|
||||
1. Run `make uuu`
|
||||
|
||||
Build and make NK.bin
|
||||
-----------------------
|
||||
|
||||
1. Run `make udefconfig` to generate `.config`.
|
||||
1. Follow `Build U-Boot` procedure to make U-Boot binary.
|
||||
|
||||
2. Run `make ubuild` to build whole repository and generate `u-boot.bin`.
|
||||
1. Run `make nkbin-maker`.
|
||||
|
||||
3. To make `nk.bin`, run `make nkbin`.
|
||||
1. To make `nk.bin`, run `make nk.bin`.
|
||||
|
||||
- nkbin_maker packs `u-boot.bin` into `nk.bin`.
|
||||
|
||||
Build and deploy boot4u
|
||||
-----------------------
|
||||
|
||||
1. Run `make boot4u`
|
||||
|
||||
1. Create index.din and copy AppMain.bin
|
||||
- `mkdir /path/to/your/sd/1st/partition/App/boot4u`
|
||||
- `touch /path/to/your/sd/1st/partition/App/boot4u/index.din`
|
||||
- `cp boot4u/AppMain.bin /path/to/your/sd/1st/partition/App/boot4u/`
|
||||
|
||||
|
||||
Build Linux
|
||||
-----------
|
||||
@@ -78,29 +94,38 @@ Build Linux
|
||||
1. Confirm that `linux-brain/arch/arm/boot/zImage` exists.
|
||||
|
||||
|
||||
Bootstrap Debian 10 (buster)
|
||||
----------------------------
|
||||
Build a Debian rootfs
|
||||
---------------------
|
||||
|
||||
1. Partition an SD card into two partitions.
|
||||
|
||||
- 1st: FAT32 (vfat), about 100MB
|
||||
- 2st: ext4, fill the remaining area
|
||||
|
||||
1. Build and copy the Linux kernel.
|
||||
|
||||
- Run `make ldefconfig lbuild`.
|
||||
- Copy `/linux-brain/arch/arm/boot/zImage` and `/linux-brain/arch/arm/boot/dts/imx28-evk.dtb` into the 1st partition.
|
||||
1. Run `make ldefconfig lbuild`.
|
||||
|
||||
1. Run APT cache in background (mandatory): `make aptcache`.
|
||||
|
||||
1. Run `make debian`.
|
||||
1. Run `make brainux`.
|
||||
|
||||
1. Copy all contents in `./debian` into the 2nd partition.
|
||||
1. Run `make image/sd.img`
|
||||
|
||||
- `sudo cp -ar ./debian/* /path/to/your/sd/2nd/partition/`
|
||||
- Please make sure that all attributes are preserved with `-a` flag.
|
||||
1. Confirm that `image/sd.img` is built and burn it to an SD card.
|
||||
|
||||
|
||||
Build a Buildroot rootfs
|
||||
------------------------
|
||||
|
||||
Buildroot rootfs aims to be the most lightweight rootfs for experimental use. `make buildroot_rootfs` runs the defconfig target for rootfs-only build and then builds the rootfs tarball and a CPIO archive for initramfs. `make image/sd_buildroot.img` makes a bootable SD image in `image` directory like the typical Brainux SD image.
|
||||
|
||||
If you want to customize the build of Buildroot, `cd` into `buildroot` and use the following targets:
|
||||
|
||||
- `make menuconfig` to change the configuration
|
||||
- `make` to build the rootfs (`-j` option might give you extra speed)
|
||||
|
||||
`image/sd_buildroot.img` target expects presence of the tarball at `buildroot/output/images/rootfs.tar`. You'll have to `clean` and rebuild every time you change the Buildroot's config before making the SD image.
|
||||
|
||||
|
||||
Known issues
|
||||
----------------------------------------
|
||||
If you use GCC 10 for the host compiler, `make ubuild` may fail.
|
||||
To complete build, open `/u-boot-brain/scripts/dtc/dtc-lexer.lex.c` or `/u-boot-brain/scripts/dtc/dtc-parser.tab.c` then comment out `YYLTYPE yylloc;`
|
||||
|
||||
Watch changes in submodules & auto-build
|
||||
----------------------------------------
|
||||
|
||||
@@ -116,4 +141,3 @@ What's r3build?
|
||||
---------------
|
||||
|
||||
[r3build](https://github.com/puhitaku/r3build) is a smart file watcher that aims to provide hot-reloading feature like Web frontend development.
|
||||
|
||||
|
||||
1
boot4u
Submodule
1
boot4u
Submodule
Submodule boot4u added at 3f916a0cf7
1
brainlilo
Submodule
1
brainlilo
Submodule
Submodule brainlilo added at 2ec8f7827e
1
buildroot
Submodule
1
buildroot
Submodule
Submodule buildroot added at cf3ea90108
368
docs/knowledge/202101_the_first_linux_porting_story_of_brain.md
Normal file
368
docs/knowledge/202101_the_first_linux_porting_story_of_brain.md
Normal file
@@ -0,0 +1,368 @@
|
||||
# Abstract
|
||||
This document details the initial journey of porting embedded Linux to the SHARP Brain electronic dictionary. It covers the hardware teardown, circuit analysis, compiling U-Boot, overcoming DRAM and microSD recognition issues, and finally reverse-engineering the undocumented LCD panel to successfully achieve a functional Linux boot.
|
||||
|
||||
# Page 01
|
||||
Title: Do Electronic Dictionaries Dream of Embedded Linux? (電子辞書は組み込み Linux の夢を見るか?)
|
||||
Author: Takumi Sueda @puhitaku
|
||||
Event: Bunka no Susume #6 (分解のススメ 第6回)
|
||||
Date: 2021/01/30
|
||||
Version: 2.0.0
|
||||
|
||||
# Page 02
|
||||
Self-introduction: Takumi Sueda (@puhitaku). A full-stack engineer with a preference for low-level layers. Freelance (formerly at NICT). First teardown was a PS2. Hobby: hacking including circuit analysis (e-dictionaries, routers), 3D printing, and tool development with Python/Go.
|
||||
|
||||
# Page 03
|
||||
Back in 2010, puhitaku (16 years old at the time) obtained an electronic dictionary at a textbook sale at Tsuyama National College of Technology.
|
||||
|
||||
# Page 04
|
||||
The model was SHARP Brain PW-GC610.
|
||||
|
||||
# Page 05
|
||||
Looking closely at the back of the device...
|
||||
|
||||
# Page 06
|
||||
A sticker reveals: "Windows® Embedded CE 6.0 Core".
|
||||
|
||||
# Page 07
|
||||
Close-up of the Windows CE sticker.
|
||||
|
||||
# Page 08
|
||||
Shocking discovery: "Windows CE is running on an electronic dictionary!?"
|
||||
|
||||
# Page 09
|
||||
Features of the SHARP Brain series:
|
||||
- Runs Windows CE.
|
||||
- Can run some CE apps or custom-developed ones.
|
||||
- A hacking community on 2ch already existed in 2010.
|
||||
Apps available at the time:
|
||||
- App launcher
|
||||
- Offline Wikipedia viewer
|
||||
- matplotlib
|
||||
- Ported visual novels, etc.
|
||||
|
||||
# Page 10
|
||||
The young puhitaku was deeply impressed.
|
||||
|
||||
# Page 11
|
||||
However, due to poor software and hardware, the community's activity rapidly declined.
|
||||
|
||||
# Page 12
|
||||
With limited technical skills at the time, puhitaku could only watch from the sidelines.
|
||||
|
||||
# Page 13
|
||||
Time passes to 2019...
|
||||
|
||||
# Page 14
|
||||
Looking at the Brain sleeping in a drawer, a question arose.
|
||||
|
||||
# Page 15
|
||||
"What kind of CPU does Brain have?"
|
||||
|
||||
# Page 16
|
||||
Googled it and was surprised!
|
||||
|
||||
# Page 17
|
||||
It was equipped with the i.MX series, synonymous with SoCs for embedded Linux!
|
||||
|
||||
# Page 18
|
||||
What is the i.MX series?
|
||||
- SoC by Freescale (now NXP).
|
||||
- A "living witness" of embedded Linux.
|
||||
- Source code for Linux and U-Boot (bootloader) is available on GitHub.
|
||||
- Datasheets and reference manuals are freely available.
|
||||
- Evaluation boards with the same SoC as Brain can be purchased.
|
||||
- puhitaku had used it extensively at work.
|
||||
Photo: i.MX 283 on SHARP Brain PW-SH1.
|
||||
|
||||
# Page 19
|
||||
The SoC was practically saying, "Please run Linux on me."
|
||||
|
||||
# Page 20
|
||||
Wondering: "Maybe Linux can run on Brain...?"
|
||||
|
||||
# Page 21
|
||||
Immediately bought one on Mercari.
|
||||
|
||||
# Page 22
|
||||
A grand journey of porting Linux to SHARP Brain began.
|
||||
|
||||
# Page 23
|
||||
Step 1: Disassemble and look inside.
|
||||
|
||||
# Page 24
|
||||
External view of SHARP Brain PW-SH1.
|
||||
|
||||
# Page 25
|
||||
Turning it over.
|
||||
|
||||
# Page 26
|
||||
Stickers hiding screws.
|
||||
|
||||
# Page 27
|
||||
Removing the stickers.
|
||||
|
||||
# Page 28
|
||||
Removing all stickers and screws.
|
||||
|
||||
# Page 29
|
||||
Removing the back of the hinge area.
|
||||
|
||||
# Page 30
|
||||
Prying up the hinge part.
|
||||
|
||||
# Page 31
|
||||
Progress of disassembly.
|
||||
|
||||
# Page 32
|
||||
Lifting the tabs with a card.
|
||||
|
||||
# Page 33
|
||||
Carefully lifting while watching out for the keyboard flexible cable.
|
||||
|
||||
# Page 34
|
||||
Close-up of the keyboard connector.
|
||||
|
||||
# Page 35
|
||||
Keyboard side separated.
|
||||
|
||||
# Page 36
|
||||
Removing the battery.
|
||||
|
||||
# Page 37
|
||||
Disconnecting the battery connector.
|
||||
|
||||
# Page 38
|
||||
Keyboard side disassembly complete.
|
||||
|
||||
# Page 39
|
||||
Back of the keyboard.
|
||||
|
||||
# Page 40
|
||||
Mainboard analysis.
|
||||
Components identified:
|
||||
- NXP i.MX283 (SoC)
|
||||
- Micron MT46H64M16LFBF-5 (RAM)
|
||||
- Samsung KLM8G1WE4A (eMMC)
|
||||
- Freescale MCQE16CLD (Power management?)
|
||||
- Yamaha YMU818B (Audio)
|
||||
- Magnetic sensor, Micro SD slot, Earphone jack.
|
||||
|
||||
# Page 41
|
||||
LCD side disassembly.
|
||||
|
||||
# Page 42
|
||||
Back of the LCD panel.
|
||||
|
||||
# Page 43
|
||||
Parts identified through disassembly. Moving towards Linux porting.
|
||||
|
||||
# Page 44
|
||||
The first barrier: "Circuitry" (回路).
|
||||
|
||||
# Page 45
|
||||
Cannot move forward without understanding all peripheral circuits.
|
||||
|
||||
# Page 46
|
||||
Using a heat gun...
|
||||
|
||||
# Page 47
|
||||
Removing the chips.
|
||||
|
||||
# Page 48
|
||||
Removing chips reveals the location of the "key" to inject the bootloader.
|
||||
|
||||
# Page 49
|
||||
Applying voltage to the PSWITCH pin (Row 1, Column 11) allows injecting the bootloader via USB from a PC.
|
||||
|
||||
# Page 50
|
||||
"Let's actually see it."
|
||||
|
||||
# Page 51
|
||||
Further probing SoC pins and peripheral circuits with a tester.
|
||||
|
||||
# Page 52
|
||||
Exhaustively investigating connections.
|
||||
|
||||
# Page 53
|
||||
Reverse engineering the FPC connector pins (LCD signals, backlight, touch panel, etc.).
|
||||
|
||||
# Page 54
|
||||
Electrical connections of the board are clarified. First step achieved.
|
||||
|
||||
# Page 55
|
||||
The second barrier: "Bootloader" (ブートローダ).
|
||||
|
||||
# Page 56
|
||||
U-Boot is on GitHub. There's a config for an evaluation board with the same SoC as Brain.
|
||||
Hypothesis: Compiling U-Boot for the evaluation board and injecting it into Brain might work.
|
||||
|
||||
# Page 57
|
||||
Compilation succeeded! Serial port connected! Running it...
|
||||
|
||||
# Page 58
|
||||
Output:
|
||||
HTLLCLLC
|
||||
Undefined Ins
|
||||
"What?"
|
||||
|
||||
# Page 59
|
||||
What is happening?
|
||||
- HTLLCLLC: Output from Boot ROM (Normal).
|
||||
- Undefined Ins: "Undefined Instruction".
|
||||
Forum search suggests: DRAM settings are wrong, preventing DRAM R/W.
|
||||
|
||||
# Page 60
|
||||
The third barrier: "DRAM".
|
||||
|
||||
# Page 61
|
||||
- Evaluation board uses DDR2 DRAM.
|
||||
- Brain uses LPDDR DRAM.
|
||||
U-Boot implementation for the evaluation board won't work with LPDDR.
|
||||
|
||||
# Page 62
|
||||
"Then just write an implementation for LPDDR."
|
||||
|
||||
# Page 63
|
||||
...It sounds easy, but...
|
||||
|
||||
# Page 64
|
||||
Snippet of DRAM control registers from the datasheet.
|
||||
|
||||
# Page 65
|
||||
There are about 200 DRAM-related registers.
|
||||
|
||||
# Page 66
|
||||
Analysis using:
|
||||
- Custom Python scripts.
|
||||
- Register dumps from the actual Brain hardware.
|
||||
- Mysterious code found on GitHub.
|
||||
After many trials and errors...
|
||||
|
||||
# Page 67
|
||||
It works! U-Boot logs show successful initialization of mx28 SDRAM controller and DRAM size detection (128 MiB).
|
||||
|
||||
# Page 68
|
||||
Now Linux can be booted from microSD!
|
||||
|
||||
# Page 69
|
||||
"Wait, let's load the Linux kernel from microSD... oh?"
|
||||
|
||||
# Page 70
|
||||
The fourth barrier: "microSD".
|
||||
|
||||
# Page 71
|
||||
U-Boot doesn't recognize the microSD. Oscilloscope shows no signals.
|
||||
|
||||
# Page 72
|
||||
It seemed trivial but was very difficult to solve.
|
||||
|
||||
# Page 73
|
||||
- Sniffing SD signals with an oscilloscope.
|
||||
- MOSFET control for power supply.
|
||||
- SoC I/O clock.
|
||||
- Reviewing I/O multiplexer.
|
||||
- Massive amount of printf debugging.
|
||||
After many trials and errors...
|
||||
|
||||
# Page 74
|
||||
Recognized! `mmc info` shows the SD card details.
|
||||
|
||||
# Page 75
|
||||
The fifth barrier: "Linux kernel and Debian".
|
||||
|
||||
# Page 76
|
||||
Conclusion: Linux worked with minor adjustments, and Debian 10 ran smoothly.
|
||||
|
||||
# Page 77
|
||||
Console output showing Debian 10, ARM926EJ-S (v5l) CPU, and Linux kernel 5.1.15.
|
||||
|
||||
# Page 78
|
||||
Linux is cleared! Porting is almost com...
|
||||
|
||||
# Page 79
|
||||
"Wait, the device's LCD isn't showing anything."
|
||||
|
||||
# Page 80
|
||||
Even if Linux boots, the screen stays dark.
|
||||
|
||||
# Page 81
|
||||
The sixth barrier: "LCD".
|
||||
|
||||
# Page 82
|
||||
- Uses a special standard that sends signals only when there's a change on the screen.
|
||||
- Official drivers in Linux cannot be used.
|
||||
- LCD model number is unknown, so data format is a mystery.
|
||||
Honestly, it was very tough.
|
||||
|
||||
# Page 83
|
||||
Found a miraculous line in the Windows boot log:
|
||||
`Initializing ILI9805 controller 16bit-2`
|
||||
|
||||
# Page 84
|
||||
"ILIxxxx" refers to ILITEK LCD drivers, used in SPI LCDs, etc.
|
||||
Searching revealed: No datasheet for ILI9805, but found ILI9806.
|
||||
|
||||
# Page 85
|
||||
External view of the ILI9805 chip on the FPC.
|
||||
|
||||
# Page 86
|
||||
Extracting all LCD signals and analyzing with a logic analyzer.
|
||||
|
||||
# Page 87
|
||||
Logic analyzer waveform showing the initialization sequence.
|
||||
|
||||
# Page 88
|
||||
Comparing logic analyzer captures with the ILI9806G datasheet (Rosetta Stone method). Identified the command set.
|
||||
|
||||
# Page 89
|
||||
Success! LCD initialization and pixel transfer in U-Boot. Showing the Tux logo.
|
||||
|
||||
# Page 90
|
||||
Linux implementation also succeeded! Full console output on the Brain screen.
|
||||
|
||||
# Page 91
|
||||
Close-up of the screen showing systemd boot logs.
|
||||
|
||||
# Page 92
|
||||
What is the next barrier?
|
||||
|
||||
# Page 93
|
||||
- Keyboard (Implementation in progress!)
|
||||
- Sound
|
||||
- Lid close detection
|
||||
- Battery management
|
||||
- Performance tuning
|
||||
- Stability improvements
|
||||
Still much more to enjoy.
|
||||
|
||||
# Page 94
|
||||
Recent progress.
|
||||
|
||||
# Page 95
|
||||
Formed the "Brain Hackers" community.
|
||||
|
||||
# Page 96
|
||||
About 70 members on Discord, mostly students. GitHub: https://github.com/brain-hackers
|
||||
|
||||
# Page 97
|
||||
Implementation status:
|
||||
- Boot Linux without disassembly (Done)
|
||||
- Boot Linux (U-Boot) from Windows (Done)
|
||||
- Kernel available via GitHub Actions (Done)
|
||||
- Keyboard driver implementation (In progress)
|
||||
- Information gathering on Wiki (In progress)
|
||||
|
||||
# Page 98
|
||||
Planning to provide a distribution that runs Linux just by flashing to an SD card, like Raspberry Pi.
|
||||
|
||||
# Page 99
|
||||
Started live hacking streams on YouTube/Twitter.
|
||||
|
||||
# Page 100
|
||||
Screenshot of a live stream showing code and the device.
|
||||
|
||||
# Page 101
|
||||
Look forward to more hacking from me and Brain Hackers!
|
||||
|
||||
# Page 102
|
||||
Brain Hackers logo.
|
||||
BIN
docs/knowledge/202101_the_first_linux_porting_story_of_brain.pdf
Normal file
BIN
docs/knowledge/202101_the_first_linux_porting_story_of_brain.pdf
Normal file
Binary file not shown.
154
docs/knowledge/202110_brain_boot_sequence.md
Normal file
154
docs/knowledge/202110_brain_boot_sequence.md
Normal file
@@ -0,0 +1,154 @@
|
||||
# Abstract
|
||||
This document provides a detailed technical breakdown of the SHARP Brain's boot sequence. It explains the process from the initial Boot ROM execution to the transition from the native Windows CE environment to Linux, detailing methods like using a custom application (BrainLILO) to chain-load U-Boot and exploring theoretical direct Boot ROM execution for deeper integration.
|
||||
|
||||
# Page 01
|
||||
Title: Detailed Explanation - Until Linux Boots on an Electronic Dictionary (詳解・電子辞書で Linux がブートするまで)
|
||||
Author: Takumi Sueda @puhitaku
|
||||
Event: Brain Hackers Meetup #1
|
||||
Date: 2021/10
|
||||
|
||||
# Page 02
|
||||
Self-introduction: Takumi Sueda (@puhitaku). Freelance developer. Announced Linux porting to SHARP Brain in September 2020, founded Brain Hackers in October. Likes: all layers of technology (especially low-level), reverse engineering, beef bowls, and music.
|
||||
|
||||
# Page 03
|
||||
Intro: A photograph of a disassembled SHARP Brain running Debian Linux, showing the console output on the built-in screen.
|
||||
|
||||
# Page 04
|
||||
Recap: What is SHARP Brain?
|
||||
- Electronic dictionary sold by SHARP running Windows CE.
|
||||
- Users can add apps built for CE (.exe PE files).
|
||||
Models:
|
||||
- Up to 2011: TOSHIBA TMPA910CRAXBG (armv4l) + 64 MiB DRAM, Windows CE.
|
||||
- 2012-2020: NXP i.MX28 (armv5tej) + 128 MiB DRAM, Windows CE.
|
||||
- 2021 onwards: NXP i.MX7ULP (armv7-a, armv7e-m) + 128 MiB DRAM, µITRON based RTOS.
|
||||
|
||||
# Page 05
|
||||
Recap: Linux Porting to Brain
|
||||
- puhitaku succeeded in booting Linux on PW-SH1.
|
||||
- Brain Hackers community expanded porting to all i.MX28 models.
|
||||
- Released "Brainux", a custom Debian-based distribution that makes running Linux on Brain as easy as on a Raspberry Pi.
|
||||
- Current work: Analysis and porting for the new PW-x1 (i.MX7ULP) models.
|
||||
|
||||
# Page 06
|
||||
Main Topic: The Boot Sequence.
|
||||
|
||||
# Page 07
|
||||
Windows → Linux: How it works. Diagram showing the transition from Windows CE to Linux.
|
||||
|
||||
# Page 08
|
||||
Before moving to Linux, let's understand how Windows CE boots. It all starts immediately after reset.
|
||||
|
||||
# Page 09
|
||||
1. Before Windows (Windows 以前).
|
||||
|
||||
# Page 10
|
||||
What does the ARM SoC execute immediately after power-on? Photo of the i.MX28 SoC on the board.
|
||||
|
||||
# Page 11
|
||||
A. Boot ROM.
|
||||
|
||||
# Page 12
|
||||
A. Boot ROM (For i.MX28: On-chip ROM).
|
||||
|
||||
# Page 13
|
||||
Peripheral Access: Immediately after power-on, the ARM core can only access things directly connected to the bus. eMMC, I2C, DRAM (requires init), and SPI are initially inaccessible.
|
||||
|
||||
# Page 14
|
||||
On-chip ROM and On-chip RAM (SRAM) are accessible immediately after reset. The first code is read from On-chip ROM, using On-chip RAM as the workspace.
|
||||
|
||||
# Page 15
|
||||
Boot Selection: The first bootloader in On-chip ROM selects the boot device, initializes peripherals, and loads the next bootloader. Options include USB slave (recovery), I2C, SPI, SSP (eMMC/SD), GPMI (NAND), and JTAG.
|
||||
|
||||
# Page 16
|
||||
On Brain, the One-Time-Programmable ROM is configured to "boot from eMMC". Some models might boot from I2C EEPROM first and then transition to eMMC.
|
||||
|
||||
# Page 17
|
||||
Program Image: The Boot ROM sequentially executes commands described in the "Program Image" located on the eMMC. These commands initialize the DRAM and load/jump to the next bootloader (EBOOT).
|
||||
|
||||
# Page 18
|
||||
EBOOT execution: EBOOT loads the "NK image" (the packaged Windows system) into the previously initialized DRAM and jumps to it.
|
||||
|
||||
# Page 19
|
||||
Result: Windows CE boots successfully.
|
||||
|
||||
# Page 20
|
||||
Summary of the flow before Windows: Reset -> Boot ROM -> Program Image -> EBOOT -> Windows CE.
|
||||
|
||||
# Page 21
|
||||
2. After Windows (Windows 以降).
|
||||
|
||||
# Page 22
|
||||
How to make Linux work "nicely".
|
||||
|
||||
# Page 23
|
||||
Recap: Brain runs Windows CE and allows adding custom .exe (PE) files.
|
||||
|
||||
# Page 24
|
||||
Chain-loading: Executing a mysterious app called "BrainLILO" placed in the "App" folder on the eMMC.
|
||||
|
||||
# Page 25
|
||||
BrainLILO loads the bootloader U-Boot (`u-boot.bin`) into DRAM.
|
||||
|
||||
# Page 26
|
||||
Preparation: BrainLILO disables the MMU (Memory Management Unit) and performs other low-level tasks.
|
||||
|
||||
# Page 27
|
||||
The Jump: Execution jumps to U-Boot. "Goodbye Windows..."
|
||||
|
||||
# Page 28
|
||||
Linux Boot: U-Boot re-initializes the hardware, loads the Linux Image into memory, and jumps to it.
|
||||
|
||||
# Page 29
|
||||
Result: Linux boots successfully.
|
||||
|
||||
# Page 30
|
||||
Summary of the flow after Windows: Windows CE -> BrainLILO -> U-Boot -> Linux.
|
||||
|
||||
# Page 31
|
||||
3. Various Linux Boot Methods (Linux ブートのさまざまな方法).
|
||||
|
||||
# Page 32
|
||||
Pathways to Linux: There isn't just one way to boot Linux. Diagram showing different paths from Boot ROM/Program Image/EBOOT.
|
||||
|
||||
# Page 33
|
||||
3.1. EBOOT → U-Boot.
|
||||
|
||||
# Page 34
|
||||
EBOOT log from PW-SH1: It shows EBOOT trying to open `EDSA1CFG.BIN`. Some models check the external SD for an NK image before reading from internal eMMC (likely for factory testing).
|
||||
|
||||
# Page 35
|
||||
EBOOT chain-boot: By placing a U-Boot image disguised as an NK image (`EDSA1EXE.BIN`) on an external SD card, EBOOT will load and run it.
|
||||
|
||||
# Page 36
|
||||
3.2. Boot ROM → Custom Program Image → U-Boot.
|
||||
|
||||
# Page 37
|
||||
Deep integration: Overwriting the "Program Image" area on the internal eMMC (where EBOOT normally resides) with a custom Program Image containing U-Boot SPL and U-Boot.
|
||||
|
||||
# Page 38
|
||||
Status: Currently, only the EBOOT chain-load and BrainLILO methods are implemented. Custom Program Image is yet to be tackled.
|
||||
|
||||
# Page 39
|
||||
4. Prospects for Custom Program Image (Program Image 自作の展望).
|
||||
|
||||
# Page 40
|
||||
Why do it?
|
||||
- Install Linux directly to internal eMMC (faster I/O than SD).
|
||||
- Use SD card purely as external storage.
|
||||
- Connect Wi-Fi dongles via SDIO (Linux has drivers for many modules).
|
||||
- Use data pins as general GPIO for custom circuits.
|
||||
- Essentially turns the Brain into a development board.
|
||||
|
||||
# Page 41
|
||||
5. Summary (まとめ).
|
||||
|
||||
# Page 42
|
||||
Summary:
|
||||
- Multiple ways to boot Linux on SHARP Brain.
|
||||
- From Windows via BrainLILO.
|
||||
- From EBOOT (Windows bootloader).
|
||||
- Directly from Boot ROM (Theoretical).
|
||||
- Successfully booting from Boot ROM will open up even more possibilities.
|
||||
|
||||
# Page 43
|
||||
Brain Hackers logo.
|
||||
BIN
docs/knowledge/202110_brain_boot_sequence.pdf
Normal file
BIN
docs/knowledge/202110_brain_boot_sequence.pdf
Normal file
Binary file not shown.
235
docs/knowledge/202208_install_linux_into_the_emmc.md
Normal file
235
docs/knowledge/202208_install_linux_into_the_emmc.md
Normal file
@@ -0,0 +1,235 @@
|
||||
# Abstract
|
||||
This document explains the process of analyzing the SHARP Brain's boot sequence to install and boot Linux directly from the internal eMMC. It details the reverse engineering of the i.MX28 Boot Mode selection via OTP ROM, extracting the I2C EEPROM configurations, and overwriting the eMMC's boot stream to replace Windows CE completely with U-Boot and Linux.
|
||||
|
||||
# Page 01
|
||||
Title: How to Erase the Identity of an Electronic Dictionary (電子辞書のアイデンティティを消す方法)
|
||||
Author: Takumi Sueda @puhitaku
|
||||
Event: 54th Information Science Young Researchers Workshop (#wakate2022)
|
||||
Date: 2022/08
|
||||
|
||||
# Page 02
|
||||
Self-introduction: Takumi Sueda (@puhitaku). Freelance developer. Developed for HOMMA Inc., etc. Likes: all layers of technology, reverse engineering, 3D printing, and music. Past event participation: 2020 Linux porting to Brain, 2021 TEPRA Lite BLE reverse engineering.
|
||||
|
||||
# Page 03
|
||||
Introduction.
|
||||
|
||||
# Page 04
|
||||
The electronic dictionary introduced today is...
|
||||
|
||||
# Page 05
|
||||
SHARP Brain. Photo of it running Debian Linux.
|
||||
|
||||
# Page 06
|
||||
Recap: Presented "Do Electronic Dictionaries Dream of Embedded Linux?" at the 53rd workshop in 2020.
|
||||
|
||||
# Page 07
|
||||
Slides and articles of previous presentations are available on the author's blog.
|
||||
|
||||
# Page 08
|
||||
What is SHARP Brain?
|
||||
|
||||
# Page 09
|
||||
Features:
|
||||
- Electronic dictionary brand launched by SHARP in 2008.
|
||||
- Equipped with Windows CE (until 2020 models).
|
||||
- Can run custom-compiled .exe files.
|
||||
- Hacking community established on 2ch shortly after launch.
|
||||
Apps: App launcher, Offline Wikipedia, matplotlib, visual novels, etc.
|
||||
|
||||
# Page 10
|
||||
Hardware:
|
||||
- CPU: NXP i.MX283 (ARM926EJ-S, armv5tej) at 454 MHz.
|
||||
- DRAM: LPDDR 128MB.
|
||||
- LCD: 800x480, etc.
|
||||
- SD: SDXC slot available.
|
||||
- eMMC: 8GB (internal, non-removable).
|
||||
- Others: Battery, touch panel, magnetic sensor (lid detection).
|
||||
Composition-wise, it's like a very old and simple first-generation Raspberry Pi with a keyboard, LCD, and battery.
|
||||
|
||||
# Page 11
|
||||
Recent Achievements:
|
||||
- Succeeded in booting Linux in 2020.
|
||||
- Founded "Brain Hackers" community, expanded support to more models.
|
||||
- Released "Brainux", a custom Debian-based distribution.
|
||||
- Just download the OS image and flash it to an SD card to run Linux.
|
||||
|
||||
# Page 12
|
||||
Even with porting success, many things remained to be done. One of them: "Overwriting Windows with Linux."
|
||||
|
||||
# Page 13
|
||||
SD vs eMMC: Booting from SD card was established, but installing directly to the internal 8GB eMMC was not yet achieved.
|
||||
|
||||
# Page 14
|
||||
Why install Linux to eMMC?
|
||||
- Better storage performance than SD.
|
||||
- Free up the SD slot for other uses.
|
||||
Example SD slot uses:
|
||||
- Connect Wi-Fi dongles via SDIO (Linux has mainline drivers for some modules).
|
||||
- Connect custom circuits via GPIO.
|
||||
- It becomes essentially a development board.
|
||||
|
||||
# Page 15
|
||||
Install Linux into the Brain itself and make it a pure Linux machine! "Good-bye, Windows!! Good-bye, Electronic Dictionary!!"
|
||||
|
||||
# Page 16
|
||||
What is needed to boot Linux from eMMC?
|
||||
|
||||
# Page 17
|
||||
A powered-on computer goes through a process called "Boot" to initialize hardware and prepare to run software.
|
||||
|
||||
# Page 18
|
||||
When Brain's power is turned on, several "bootloaders" perform the boot process, eventually starting Windows CE.
|
||||
|
||||
# Page 19
|
||||
The flow from the moment power is applied until the system finishes booting is called the "Boot Sequence."
|
||||
|
||||
# Page 20
|
||||
To achieve eMMC boot, one must trace the connection between the SoC behavior and bootloaders from power-on and appropriately overwrite that sequence.
|
||||
|
||||
# Page 21
|
||||
Explanation and Analysis of the Boot Sequence: Reset ~ Boot ROM.
|
||||
|
||||
# Page 22
|
||||
Photo of the i.MX28 SoC. What does it execute immediately after power-on?
|
||||
|
||||
# Page 23
|
||||
A. Boot ROM.
|
||||
|
||||
# Page 24
|
||||
A. Boot ROM (called On-chip ROM in i.MX28).
|
||||
|
||||
# Page 25
|
||||
Immediately after reset, external peripherals are uninitialized and unusable. The CPU can generally only access locations directly connected by the bus. eMMC, DRAM, I2C, and SPI are inaccessible.
|
||||
|
||||
# Page 26
|
||||
On-chip ROM and On-chip RAM (SRAM) are accessible via the bus immediately after reset. The CPU executes the instruction sequence in On-chip ROM using On-chip RAM as its workspace.
|
||||
|
||||
# Page 27
|
||||
The CPU uses the Boot ROM (the first bootloader) to select the boot device, initialize peripherals, and read the next bootloader. Devices include USB recovery, I2C, SPI, SSP (eMMC/SD), GPMI (NAND), and JTAG.
|
||||
|
||||
# Page 28
|
||||
The Boot ROM decides which external device to read the next bootloader from by looking at the "Boot Mode" written in the "One-Time Programmable (OTP) ROM".
|
||||
|
||||
# Page 29
|
||||
One-Time Programmable (OTP) ROM:
|
||||
- Non-erasable ROM implemented in the SoC's semiconductor, programmable only once.
|
||||
- The first area used to convey the developer's intent to the CPU.
|
||||
- Device-specific settings for boot devices are also written here.
|
||||
"Let's look inside the OTP to find the first boot device!"
|
||||
|
||||
# Page 30
|
||||
Analysis of the OTP settings.
|
||||
|
||||
# Page 31
|
||||
Recap: Brain allows running custom exe files.
|
||||
|
||||
# Page 32
|
||||
Using a "divine tool" called Scalpel that can see the entire memory space from Windows CE.
|
||||
|
||||
# Page 33
|
||||
According to the datasheet, the 8 MSB bits of the 32-bit value at address 0x8002C1A0 is the BOOT_MODE. Reading it with Scalpel results in 0x01 (0b00000001).
|
||||
|
||||
# Page 34
|
||||
Referring to the i.MX28 "Boot Mode Selection Map" table in the datasheet: BOOT_MODE 0bXXX00001 corresponds to I2C0 master, 3.3 V.
|
||||
|
||||
# Page 35
|
||||
Conclusion: The CPU is configured to read from an EEPROM connected via I2C first.
|
||||
|
||||
# Page 36
|
||||
Extracting and reading the EEPROM content.
|
||||
|
||||
# Page 37
|
||||
Question: "Where is the EEPROM on the Brain board?" (Photo of the mainboard).
|
||||
|
||||
# Page 38
|
||||
Answer: Located at U502 (highlighted in a pink box).
|
||||
|
||||
# Page 39
|
||||
Identifying the EEPROM: Probing pins with an oscilloscope while cycling power. Found 100kHz/400kHz clocks characteristic of I2C. Narrowed down the part number via Digi-Key footprint search: VSON package, 2mm x 3mm, 0.5mm thick (Rohm). Marking "4G3" identifies it as Rohm BR24G32 (4KB).
|
||||
|
||||
# Page 40
|
||||
Reading it: Soldered 0.2mm polyurethane wires under a stereomicroscope and read with a Saleae logic analyzer.
|
||||
|
||||
# Page 41
|
||||
EEPROM Content: Contains a "Boot Stream" (SB) structure. These are commands sequentially executed by the Boot ROM. Using `sbtoelf` tool from the Rockbox repository and Ghidra to disassemble the binary. Example commands: LOAD, FILL, CALL, MODE.
|
||||
|
||||
# Page 42
|
||||
Flow of binary deployment in SRAM after executing SB commands: CALL command -> Jump to entry point 0xE61C (Instructions armv5tej) -> Return.
|
||||
|
||||
# Page 43
|
||||
What the Boot ROM does after reading EEPROM:
|
||||
- Writes specific settings to eMMC peripherals.
|
||||
- Transitions to eMMC boot mode (MODE command to 0x09).
|
||||
- Once in eMMC boot mode, it parses the SB found on the eMMC (similar to the process with EEPROM).
|
||||
|
||||
# Page 44
|
||||
Summary: The CPU reads the I2C EEPROM to configure eMMC settings before transitioning to eMMC boot.
|
||||
|
||||
# Page 45
|
||||
Extracting and reading the eMMC content.
|
||||
|
||||
# Page 46
|
||||
Dumping eMMC is easy: Boot Linux from SD and use `dd` on `/dev/mmcblk0`. Looking at the Master Boot Record (MBR) for an entry with i.MX28 specific partition type 0x53. The beginning of that partition contains a pointer (sector number) to the SB.
|
||||
|
||||
# Page 47
|
||||
Structure of data related to boot on eMMC: Sector 0 (MBR) -> Sector 256 (SB) -> Sector 2304 (?) -> Sector 198912 (FAT32 partition with Windows CE). Flow: 1. Read MBR, 2. Read & run SB, 3. Run EBOOT.
|
||||
|
||||
# Page 48
|
||||
Summary: The CPU reads eMMC to execute EBOOT (Windows CE bootloader).
|
||||
|
||||
# Page 49
|
||||
Transition to Windows: EBOOT extracts the "NK image" (packaged Windows system) from eMMC to DRAM and jumps to it.
|
||||
|
||||
# Page 50
|
||||
The boot sequence from reset to Windows CE is completely clarified! Reset -> On-chip ROM -> I2C EEPROM -> eMMC -> Windows CE.
|
||||
|
||||
# Page 51
|
||||
Deciding which part of the boot sequence to overwrite.
|
||||
|
||||
# Page 52
|
||||
Where to put the custom binary to boot Linux?
|
||||
- I2C EEPROM SB: OS-independent (only does hardware adjustments).
|
||||
- eMMC SB: Contains Windows CE's EBOOT (OS-dependent).
|
||||
Strategy: Overwrite the content of eMMC with custom data.
|
||||
|
||||
# Page 53
|
||||
Experiment: Use USB boot mode to transition to eMMC boot and start Windows.
|
||||
|
||||
# Page 54
|
||||
"USB boot mode" allows booting from a PC without involving the EEPROM. If a PC-injected SB that merely transitions to eMMC boot succeeds in starting Windows CE, then the EEPROM content is confirmed to be OS-independent. (Using U-Boot's `mkimage` to generate SB).
|
||||
|
||||
# Page 55
|
||||
Forcing USB boot mode by shorting the pads (JP501) next to the eMMC while connecting USB.
|
||||
|
||||
# Page 56
|
||||
Result: Success. Decided to keep the EEPROM as is and overwrite the eMMC content.
|
||||
|
||||
# Page 57
|
||||
Creating an eMMC image containing the bootloader.
|
||||
|
||||
# Page 58
|
||||
Using U-Boot (Das U-Boot), commonly used in embedded Linux. Modified it to read from eMMC instead of SD. Modified the OS image generation script to include SB and U-Boot.
|
||||
|
||||
# Page 59
|
||||
Structure of the OS image for eMMC: MBR (Entry 0: FAT32, Entry 1: SB, Entry 2: Ext4) -> Sector 2048 (FAT32 partition with Tux logo) -> Sector 20800 (SB with U-Boot) -> Sector 24800 (Ext4 rootfs). Flow: 1. Read MBR, 2. Read & run SB, 3. Run U-Boot.
|
||||
|
||||
# Page 60
|
||||
Writing the eMMC image and booting.
|
||||
|
||||
# Page 61
|
||||
Flashing eMMC: Just use `dd` on the actual device using an eMMC image hidden on a Linux-bootable SD card. Don't forget backups! If flashing fails, it can be recovered via USB boot + serial (UART) if you can do fine soldering.
|
||||
|
||||
# Page 62
|
||||
Connecting UART (serial) to the development PC. Photo of the tiny wires soldered to test points and connected to a USB-Serial adapter.
|
||||
|
||||
# Page 63
|
||||
Success! Console output shows Linux 5.4.149 booting. `mount | grep mmcblk0` shows `/dev/mmcblk0p3` mounted as rootfs (ext4).
|
||||
|
||||
# Page 64
|
||||
SHARP Brain has stepped into its new life as a Linux machine, leaving its identity as an electronic dictionary behind.
|
||||
|
||||
# Page 65
|
||||
Summary.
|
||||
|
||||
# Page 66
|
||||
Summary: Even if implementation varies by SoC or architecture, the concept of bootloaders and boot sequences is common to all computers. If you want to fundamentally change the behavior of your hardware, grab a soldering iron and dig into the boot sequence.
|
||||
BIN
docs/knowledge/202208_install_linux_into_the_emmc.pdf
Normal file
BIN
docs/knowledge/202208_install_linux_into_the_emmc.pdf
Normal file
Binary file not shown.
141
docs/knowledge/202304_linux_suspend_on_brain.md
Normal file
141
docs/knowledge/202304_linux_suspend_on_brain.md
Normal file
@@ -0,0 +1,141 @@
|
||||
# Abstract
|
||||
This document provides a technical deep dive into Linux suspend mechanisms, focusing on the implementation of Suspend-to-RAM for the SHARP Brain electronic dictionary. It explains the transition and resume flows, the required power management and wakeup interrupt handler implementations, and the specific challenges faced, such as handling I2C-based key events and device tree configurations for power regulators.
|
||||
|
||||
# Page 01
|
||||
Title: Learning Linux Suspend with an Electronic Dictionary (電子辞書で学ぶ Linux のサスペンド)
|
||||
Author: Takumi Sueda aka @puhitaku
|
||||
Event: Information Science Young Researchers Workshop Spring Edition 2023 (#wakate2023s)
|
||||
Date: 2023/04
|
||||
|
||||
# Page 02
|
||||
Self-introduction: Takumi Sueda (@puhitaku). Freelance developer. Working for HOMMA Inc. Author, Security Camp instructor, OSS license consultant, etc. Likes: low-level technology, reverse engineering, 3D printing, music. Attending the workshop almost every year since 2014.
|
||||
|
||||
# Page 03
|
||||
Writing a series "Let's Run Linux on an Electronic Dictionary" for Nikkei Linux magazine. Part 3 will be in the May issue.
|
||||
|
||||
# Page 04
|
||||
The target device: SHARP Brain. Photo showing it running Debian Linux.
|
||||
|
||||
# Page 05
|
||||
Features of SHARP Brain:
|
||||
- Electronic dictionary brand launched in 2008.
|
||||
- Equipped with Windows CE (up to 2020 models).
|
||||
- Community established since launch.
|
||||
- Users can run custom exe files.
|
||||
|
||||
# Page 06
|
||||
Hardware:
|
||||
- CPU: NXP i.MX283 (ARM926EJ-S, 454MHz).
|
||||
- DRAM: LPDDR 128MB.
|
||||
- LCD: 800x480, etc.
|
||||
- SDXC slot.
|
||||
- eMMC: 8GB internal.
|
||||
- Battery, touch panel, magnetic sensor.
|
||||
Similar to a primitive Raspberry Pi with a keyboard, LCD, and battery.
|
||||
|
||||
# Page 07
|
||||
U-Boot and Linux porting:
|
||||
- Success in 2020.
|
||||
- Released "Brainux" distribution (bootable from SD card).
|
||||
Implemented drivers/features:
|
||||
- LCD (newly implemented).
|
||||
- Keyboard (newly implemented).
|
||||
- Touch panel.
|
||||
- SD / eMMC R/W.
|
||||
- Beep sounds via piezo element.
|
||||
|
||||
# Page 08
|
||||
Unimplemented features:
|
||||
- Power management (Sleep, cpufreq).
|
||||
- Sound.
|
||||
|
||||
# Page 09
|
||||
Focus of today's talk: Power management, specifically "Sleep".
|
||||
|
||||
# Page 10
|
||||
What is "Sleep"?
|
||||
|
||||
# Page 11
|
||||
There are several types of "Sleep" (system-wide sleep) in Linux:
|
||||
- Suspend-to-Idle.
|
||||
- Standby.
|
||||
- Suspend-to-RAM.
|
||||
- Hibernation.
|
||||
Generally, lower items consume less power.
|
||||
|
||||
# Page 12
|
||||
1. Suspend-to-Idle: Purely software-based sleep that just idles the CPU. Stops userspace, timekeeping, and I/O.
|
||||
2. Standby: Powers off unused CPUs during boot to save more power.
|
||||
3. Suspend-to-RAM: Saves CPU and device state to DRAM and powers off almost all hardware except DRAM and resume logic.
|
||||
4. Hibernation: Saves state to persistent storage and shuts down. Saves all hardware.
|
||||
|
||||
# Page 13
|
||||
For an electronic dictionary, Suspend-to-RAM is the target to balance power reduction and resume time.
|
||||
|
||||
# Page 14
|
||||
Flow of Suspend-to-RAM transition and resume.
|
||||
|
||||
# Page 15
|
||||
Flow of transitioning to Suspend-to-RAM:
|
||||
1. Notify the whole system, preparing kernel subsystems for sleep.
|
||||
2. Freeze tasks.
|
||||
3. Configure devices to not handle interrupts except those for suspend/resume.
|
||||
4. Stop non-boot CPUs (tasks/IRQs migrate to Boot CPU).
|
||||
5. Disable scheduler tick and stop context switching.
|
||||
6. Hand control to platform-specific firmware to transition to low-power state or cut power (except for RAM).
|
||||
7. Sleep until an interrupt from a resume device (e.g., keyboard) arrives.
|
||||
|
||||
# Page 16
|
||||
Flow of resuming from Suspend-to-RAM:
|
||||
1. Interrupt from a resume device arrives.
|
||||
2. CPU resumes and handles the interrupt (platform-dependent process).
|
||||
3. Control returns to the kernel.
|
||||
4. Resume kernel core, tick, and scheduling.
|
||||
5. Wake up non-boot CPUs.
|
||||
6. Wake up devices and restore IRQs.
|
||||
7. Thaw tasks.
|
||||
8. Send resume notifications to the whole system.
|
||||
|
||||
# Page 17
|
||||
What is needed to implement Suspend-to-RAM on new hardware?
|
||||
|
||||
# Page 18
|
||||
Two essential elements for Suspend-to-RAM:
|
||||
1. Power Management: Implement functions in the driver's `dev_pm_ops` structure to gracefully cut power upon suspend notification. Describe device-regulator (power) relationships in the Device Tree. (e.g., SoC internal regulators, MOSFETs for external hardware, SPI/I2C peripherals).
|
||||
2. Wakeup Interrupt Handler: Implement procedures in the Interrupt Service Routine (ISR) to instruct the Power Management Subsystem to resume when a valid wakeup input arrives. (e.g., magnetic sensor for lid, GPIO for power button).
|
||||
|
||||
# Page 19
|
||||
Side responsible for executing Suspend-to-RAM:
|
||||
- Call stack overview starting from writing to `/sys/power/state`.
|
||||
- Device Tree example: Describing the relationship between the LCD panel and its DVDD/AVDD power supplies. The kernel uses this info to toggle power.
|
||||
|
||||
# Page 20
|
||||
Communication between the wakeup ISR and the suspend execution code:
|
||||
1. Driver's ISR calls `pm_wakeup_event()` to increment a counter in the PM subsystem.
|
||||
2. `suspend_enter` checks the counter after the CPU PC returns. If incremented, it exits the loop; otherwise, it puts the CPU back to sleep.
|
||||
Conclusion: Interrupts unrelated to resume are ignored.
|
||||
|
||||
# Page 21
|
||||
Implementation status on SHARP Brain.
|
||||
|
||||
# Page 22
|
||||
Suspend-to-RAM is partially achieved but still a work in progress:
|
||||
- [Check] Execution of Suspend-to-RAM.
|
||||
- [Check] Resume via power button (on models where key matrix is directly read via GPIO).
|
||||
- [WIP] Resume via power button (on models where key events are read from MCU via I2C).
|
||||
- Problem: I2C peripheral-level interrupt wakes the device for any key press. Most peripherals are sleeping, so ISR capabilities are limited.
|
||||
- Might need reverse engineering of how Windows handles this.
|
||||
- [WIP] Power control for LCD, etc. (Describe GPIOs connected to FET gates/ENABLE pins as regulators in Device Tree).
|
||||
- [WIP] Verifying power consumption reduction.
|
||||
- [WIP] Release as OS image.
|
||||
|
||||
# Page 23
|
||||
Q&A Log:
|
||||
Q: In what order do kthread and userspace processes freeze?
|
||||
A: `suspend_prepare` -> `suspend_freeze_processes`. Userspace freezes first.
|
||||
Q: What is the difference in power saving between the 4 methods?
|
||||
A: Depends on the system. On Brain (small SoC), the difference between Suspend-to-Idle and Standby is small (115mA -> 86mA). Suspend-to-RAM's impact will be measured after implementing LCD power control.
|
||||
|
||||
# Page 24
|
||||
References: Bootlin Elixir (Linux source browser), Mainline Linux documentation (suspend-flows.rst, sleep-states.rst).
|
||||
Diagram showing the interaction between Brain and a development PC.
|
||||
BIN
docs/knowledge/202304_linux_suspend_on_brain.pdf
Normal file
BIN
docs/knowledge/202304_linux_suspend_on_brain.pdf
Normal file
Binary file not shown.
15
docs/knowledge/AGENTS.md
Normal file
15
docs/knowledge/AGENTS.md
Normal file
@@ -0,0 +1,15 @@
|
||||
This directory contains PDFs and texts that explains the inside of SHARP Brain, a series of e-dictionary sold by SHARP, for coding agents.
|
||||
|
||||
For text searching purpose, all PDFs are converted and explained into a corresponding Markdown with the same file name but the extension.
|
||||
|
||||
|
||||
# Converting PDF to md
|
||||
|
||||
If the user of a coding agent requests the agent to convert the PDF into text, the agent must follow the rule:
|
||||
|
||||
- The slide number and the position of the Markdown document must be preserved; to achieve this, the Markdown document must have first level headers with the page number like "# Page 01" .
|
||||
- The Markdown version is like a "text-only technical document version" of the PDF. Not only just converting texts in the PDF, agents must explain the topic based on the understanding of the visual slides.
|
||||
- Future session of coding agents will understand the thing by reading the Markdown. Make the text simple and not redundant.
|
||||
- Describe an abstract in the beginning of the Markdown.
|
||||
- The resulting output must have the same file name as the original PDF but the extension ".md".
|
||||
|
||||
55
docs/prompts/0000-introduce-coding-agents.md
Normal file
55
docs/prompts/0000-introduce-coding-agents.md
Normal file
@@ -0,0 +1,55 @@
|
||||
# Objective
|
||||
|
||||
This repository contains anything necessary to build an SD card image file of Brainux - a Debian-based Linux distribution for a series of e-dictionary "Brain" series sold by SHARP, a Japanese manufacturer - and now I'm going to add the root AGENTS.md for automated development.
|
||||
|
||||
Explore the repository to generate appropriate AGENTS.md that will help CC for future runs. AGENTS.md should contain project memory and instructions for CC.
|
||||
|
||||
|
||||
# Hints and instructions about the repo's structure
|
||||
|
||||
- Knowledge useful to understand the inside of SHARP Brain and its hacking scene will be contained in /docs/knowledge.
|
||||
- The definition of GitHub Actions workflow (/.github/workflows/build.yml) will be useful to understand how it enters into the build procedure.
|
||||
- The repo contains some submodules. File search or string search at the repo's root is not recommended.
|
||||
- Linux (linux-brain)
|
||||
- U-Boot (u-boot-brain)
|
||||
- BrainLILO (chain-boot tool specially made for specific older models)
|
||||
- boot4u (chain-boot tool specially made for specific newer models)
|
||||
- buildroot (to build an alternative lightweight rootfs, instead of the default Debian)
|
||||
- nkbin_maker (converter to turn U-Boot's ELF into an nk.bin that Windows CE's EBOOT bootloader understands)
|
||||
|
||||
|
||||
# My typical usage of buildbrain on the development of Brainux
|
||||
|
||||
|
||||
## Develop Linux kernel
|
||||
|
||||
1. `cd` into linux-brain
|
||||
2. Checkout an appropriate branch
|
||||
- The default branch is `brain`. When I edit the code, I make another branch from `brain`.
|
||||
3. Edit the code
|
||||
4. `cd ..` and go up into buildbrain
|
||||
5. `make lclean ldefconfig lbuild` to start a clean build
|
||||
- Run `make lmenuconfig` to edit the .config (which is not a suitable way for coding agents due to TUI)
|
||||
6. Copy the resulting kernel `/linux-brain/arch/arm/boot/zImage` and `/linux-brain/arch/arm/boot/dts/imx28-pw*.dtb` into an SD card and run it on a real machine
|
||||
6. Continue try-and-error loop; make another change to the code, `make lbuild`, and run it
|
||||
7. `cd linux-brain` and commit the change
|
||||
- Commit message must comply the kernel's convention; watch surrounding files and commits to infer the format
|
||||
8. File a PR and ask review
|
||||
9. Merge it
|
||||
|
||||
|
||||
## Develop U-Boot
|
||||
|
||||
It is mostly the same as Linux kernel.
|
||||
|
||||
|
||||
## Update Brainux's configuration script and file
|
||||
|
||||
1. Checkout an appropriate branch
|
||||
2. Edit scripts and files in os-brainux
|
||||
3. Run `make brainux` to build the root filesystem
|
||||
- ... or run `make image/sd.img` to create a complete SD image
|
||||
4. Copy the root filesystem to an SD card's second partition or write the entire image to an SD card
|
||||
5. Repeat 3 and 4
|
||||
6. Commit the change, file a PR, ask a review, and merge it
|
||||
|
||||
23
image/LICENSE
Normal file
23
image/LICENSE
Normal file
@@ -0,0 +1,23 @@
|
||||
*** exeopener ***
|
||||
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2022 Chiharu Shirasaka
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
@@ -5,27 +5,41 @@ JOBS=$(nproc)
|
||||
REPO=$(git rev-parse --show-toplevel)
|
||||
WORK=${REPO}/image/work
|
||||
LINUX=${REPO}/linux-brain
|
||||
IMG=${REPO}/image/sd.img
|
||||
ROOTFS=$1
|
||||
IMG_NAME=$2
|
||||
IMG=${REPO}/image/${IMG_NAME}
|
||||
SIZE_M=$3
|
||||
export CROSS_COMPILE=arm-linux-gnueabi-
|
||||
|
||||
mkdir -p ${WORK}
|
||||
mkdir -p ${WORK}/lilobin
|
||||
|
||||
for i in $(seq 1 6); do
|
||||
make -C ${REPO}/u-boot-brain pwsh${i}_defconfig
|
||||
for i in "a7200" "a7400" "sh1" "sh2" "sh3" "sh4" "sh5" "sh6" "sh7"; do
|
||||
NUM=$(echo $i | sed -E 's/sh//g')
|
||||
|
||||
make -C ${REPO}/u-boot-brain distclean pw${i}_defconfig
|
||||
make -j${JOBS} -C ${REPO}/u-boot-brain u-boot.bin
|
||||
${REPO}/nkbin_maker/bsd-ce ${REPO}/u-boot-brain/u-boot.bin
|
||||
|
||||
case $i in
|
||||
1|2|3)
|
||||
mv ${REPO}/nk.bin ${WORK}/edsa${i}exe.bin;;
|
||||
4|5|6)
|
||||
mv ${REPO}/nk.bin ${WORK}/edsh${i}exe.bin;;
|
||||
"a7200")
|
||||
mv ${REPO}/nk.bin ${WORK}/edna3exe.bin
|
||||
mv ${REPO}/u-boot-brain/u-boot.bin ${WORK}/lilobin/gen2.bin;;
|
||||
"a7400")
|
||||
mv ${REPO}/u-boot-brain/u-boot.bin ${WORK}/lilobin/gen2_7400.bin;;
|
||||
"sh1" | "sh2" | "sh3")
|
||||
mv ${REPO}/nk.bin ${WORK}/edsa${NUM}exe.bin
|
||||
mv ${REPO}/u-boot-brain/u-boot.bin ${WORK}/lilobin/gen3_${NUM}.bin;;
|
||||
"sh4" | "sh5" | "sh6" | "sh7")
|
||||
mv ${REPO}/nk.bin ${WORK}/edsh${NUM}exe.bin
|
||||
mv ${REPO}/u-boot-brain/u-boot.bin ${WORK}/lilobin/gen3_${NUM}.bin;;
|
||||
*)
|
||||
echo "WTF: $i"
|
||||
exit 1;;
|
||||
esac
|
||||
done
|
||||
|
||||
dd if=/dev/zero of=${IMG} bs=1M count=2048
|
||||
dd if=/dev/zero of=${IMG} bs=1M count=${SIZE_M}
|
||||
|
||||
START1=2048
|
||||
SECTORS1=$((1024 * 1024 * 64 / 512))
|
||||
@@ -40,20 +54,37 @@ sfdisk ${IMG} < ${WORK}/part.sfdisk
|
||||
|
||||
sudo kpartx -av ${IMG}
|
||||
|
||||
LOOPDEV=$(losetup -l | grep sd.img | grep -o 'loop.')
|
||||
LOOPDEV=$(losetup -l | grep ${IMG_NAME} | grep -o 'loop.' | tail -n 1)
|
||||
|
||||
sudo mkfs.fat -F32 -v -I /dev/mapper/${LOOPDEV}p1
|
||||
sudo mkfs.ext4 /dev/mapper/${LOOPDEV}p2
|
||||
sudo mkfs.fat -n boot -F32 -v -I /dev/mapper/${LOOPDEV}p1
|
||||
sudo mkfs.ext4 -L rootfs /dev/mapper/${LOOPDEV}p2
|
||||
|
||||
mkdir -p ${WORK}/p1 ${WORK}/p2
|
||||
sudo mount /dev/mapper/${LOOPDEV}p1 ${WORK}/p1
|
||||
sudo mount -o utf8=true /dev/mapper/${LOOPDEV}p1 ${WORK}/p1
|
||||
sudo mount /dev/mapper/${LOOPDEV}p2 ${WORK}/p2
|
||||
|
||||
echo ${BRAINUX_VERSION} > ${WORK}/brainux_version
|
||||
sudo cp ${WORK}/brainux_version ${WORK}/p1/
|
||||
sudo cp ${LINUX}/arch/arm/boot/zImage ${WORK}/p1/
|
||||
sudo cp ${LINUX}/arch/arm/boot/dts/imx28-pwsh*.dtb ${WORK}/p1/
|
||||
sudo cp ${WORK}/*.bin ${WORK}/p1/
|
||||
sudo cp ${LINUX}/arch/arm/boot/dts/imx28-pw*.dtb ${WORK}/p1/
|
||||
sudo mkdir -p ${WORK}/p1/nk
|
||||
sudo cp ${WORK}/*.bin ${WORK}/p1/nk/
|
||||
|
||||
sudo cp -ra ${REPO}/brainux/* ${WORK}/p2/
|
||||
make -C ${REPO}/brainlilo
|
||||
|
||||
LILO="${WORK}/p1/アプリ/Launch Linux"
|
||||
sudo mkdir -p "${LILO}"
|
||||
sudo touch "${LILO}/index.din"
|
||||
sudo touch "${LILO}/AppMain.cfg"
|
||||
sudo cp ${REPO}/brainlilo/*.dll "${LILO}/"
|
||||
sudo cp ${REPO}/brainlilo/BrainLILO.exe "${LILO}/AppMain_.exe"
|
||||
gzip -cd ${REPO}/image/exeopener.exe.gz > ${REPO}/image/exeopener.exe
|
||||
sudo cp ${REPO}/image/exeopener.exe "${LILO}/AppMain.exe"
|
||||
|
||||
sudo mkdir -p ${WORK}/p1/loader
|
||||
sudo cp ${WORK}/lilobin/*.bin ${WORK}/p1/loader/
|
||||
|
||||
sudo cp -ra ${REPO}/${ROOTFS}/* ${WORK}/p2/
|
||||
|
||||
sudo umount ${WORK}/p1 ${WORK}/p2
|
||||
sudo kpartx -d ${IMG}
|
||||
|
||||
52
image/build_image_x1.sh
Executable file
52
image/build_image_x1.sh
Executable file
@@ -0,0 +1,52 @@
|
||||
#!/bin/bash
|
||||
set -uex -o pipefail
|
||||
|
||||
JOBS=$(nproc)
|
||||
REPO=$(git rev-parse --show-toplevel)
|
||||
WORK=${REPO}/image/work
|
||||
LINUX=${REPO}/linux-brain
|
||||
IMG=${REPO}/image/sd_x1.img
|
||||
export CROSS_COMPILE=arm-linux-gnueabihf-
|
||||
|
||||
mkdir -p ${WORK}
|
||||
|
||||
dd if=/dev/zero of=${IMG} bs=1M count=3072
|
||||
|
||||
START1=2048
|
||||
SECTORS1=$((1024 * 1024 * 64 / 512))
|
||||
START2=$((2048 + ${SECTORS1}))
|
||||
|
||||
cat <<EOF > ${WORK}/part.sfdisk
|
||||
${IMG}1 : start=${START1}, size=${SECTORS1}, type=b
|
||||
${IMG}2 : start=${START2}, type=83
|
||||
EOF
|
||||
|
||||
sfdisk ${IMG} < ${WORK}/part.sfdisk
|
||||
|
||||
sudo kpartx -av ${IMG}
|
||||
|
||||
LOOPDEV=$(losetup -l | grep sd_x1.img | grep -o 'loop.')
|
||||
|
||||
sudo mkfs.fat -F32 -v -I /dev/mapper/${LOOPDEV}p1
|
||||
sudo mkfs.ext4 /dev/mapper/${LOOPDEV}p2
|
||||
|
||||
mkdir -p ${WORK}/p1 ${WORK}/p2
|
||||
sudo mount /dev/mapper/${LOOPDEV}p1 ${WORK}/p1
|
||||
sudo mount /dev/mapper/${LOOPDEV}p2 ${WORK}/p2
|
||||
|
||||
sudo cp ${LINUX}/arch/arm/boot/zImage ${WORK}/p1/
|
||||
sudo cp ${LINUX}/arch/arm/boot/dts/imx7ulp-pwh*.dtb ${WORK}/p1/
|
||||
|
||||
sudo cp ${REPO}/u-boot-brain/u-boot.bin ${WORK}/p1/
|
||||
|
||||
sudo mkdir -p ${WORK}/p1/App/boot4u
|
||||
sudo cp ${REPO}/boot4u/AppMain.bin ${WORK}/p1/App/boot4u/
|
||||
sudo touch ${WORK}/p1/App/boot4u/index.din
|
||||
|
||||
sudo cp -ra ${REPO}/brainux/* ${WORK}/p2/
|
||||
|
||||
sudo umount ${WORK}/p1 ${WORK}/p2
|
||||
sudo kpartx -d ${IMG}
|
||||
|
||||
rmdir ${WORK}/p1 ${WORK}/p2
|
||||
|
||||
BIN
image/exeopener.exe.gz
Normal file
BIN
image/exeopener.exe.gz
Normal file
Binary file not shown.
Submodule linux-brain updated: ce40e22b52...a9f534c7f5
10
os-brainux/override-pre.sh
Executable file
10
os-brainux/override-pre.sh
Executable file
@@ -0,0 +1,10 @@
|
||||
#!/bin/bash
|
||||
|
||||
set -uex -o pipefail
|
||||
|
||||
SRC=$1
|
||||
DST=$2
|
||||
|
||||
install -g root -o root -m 0644 $SRC/lib/systemd/system/boot.mount $DST/lib/systemd/system/boot.mount
|
||||
install -g root -o root -m 0644 $SRC/lib/systemd/system/ethernet_gadget.service $DST/lib/systemd/system/ethernet_gadget.service
|
||||
install -g root -o root -m 0755 $SRC/usr/bin/enable_ethernet_gadget $DST/usr/bin/enable_ethernet_gadget
|
||||
@@ -5,7 +5,17 @@ set -uex -o pipefail
|
||||
SRC=$1
|
||||
DST=$2
|
||||
|
||||
install -g root -o root -m 0644 $SRC/usr/lib/os-release $DST/usr/lib/os-release
|
||||
install -g root -o root -m 0644 $SRC/etc/issue $DST/etc/issue
|
||||
install -g root -o root -m 0644 $SRC/etc/issue.net $DST/etc/issue.net
|
||||
install -g root -o root -m 0644 $SRC/etc/motd $DST/etc/motd
|
||||
install -g root -o root -m 0440 $SRC/etc/sudoers $DST/etc/sudoers
|
||||
|
||||
install -g root -o root -m 0644 $SRC/etc/X11/xorg.conf $DST/etc/X11/xorg.conf
|
||||
install -g root -o root -m 0644 $SRC/etc/X11/Xsession.d/96calibrate $DST/etc/X11/Xsession.d/96calibrate
|
||||
|
||||
install -g root -o root -m 0644 -D $SRC/etc/xdg/weston/weston.ini $DST/etc/xdg/weston/weston.ini
|
||||
|
||||
install -g 1000 -o 1000 -m 0644 $SRC/home/user/.xprofile $DST/home/user/.xprofile
|
||||
sudo -u#1000 -g#1000 mkdir -p $DST/home/user/.config/fcitx
|
||||
install -g 1000 -o 1000 -m 0644 $SRC/home/user/.config/fcitx/profile $DST/home/user/.config/fcitx/profile
|
||||
sudo -u#1000 -g#1000 mkdir -p $DST/home/user/lxterminal
|
||||
install -g 1000 -o 1000 -m 0644 $SRC/home/user/lxterminal/lxterminal.conf $DST/home/user/lxterminal/lxterminal.conf
|
||||
install -g root -o root -m 0644 -D $SRC/etc/jwm/system.jwmrc $DST/etc/jwm/system.jwmrc
|
||||
|
||||
4
os-brainux/override/etc/X11/Xsession.d/96calibrate
Normal file
4
os-brainux/override/etc/X11/Xsession.d/96calibrate
Normal file
@@ -0,0 +1,4 @@
|
||||
if [ ! -e /etc/X11/xorg.conf.d/99-calibrator.conf ]; then
|
||||
xinput_calibrator --output-filename /etc/X11/xorg.conf.d/99-calibrator.conf
|
||||
fi
|
||||
|
||||
8
os-brainux/override/etc/X11/xorg.conf
Normal file
8
os-brainux/override/etc/X11/xorg.conf
Normal file
@@ -0,0 +1,8 @@
|
||||
Section "Device"
|
||||
Identifier "device"
|
||||
Driver "fbdev"
|
||||
EndSection
|
||||
Section "Screen"
|
||||
Identifier "screen"
|
||||
Device "device"
|
||||
EndSection
|
||||
@@ -1,2 +0,0 @@
|
||||
Brainux GNU/Linux 10 \n \l
|
||||
|
||||
@@ -1 +0,0 @@
|
||||
Brainux GNU/Linux 10
|
||||
216
os-brainux/override/etc/jwm/system.jwmrc
Normal file
216
os-brainux/override/etc/jwm/system.jwmrc
Normal file
@@ -0,0 +1,216 @@
|
||||
<?xml version="1.0"?>
|
||||
<JWM>
|
||||
|
||||
<!-- The root menu. -->
|
||||
<RootMenu onroot="12">
|
||||
<Include>/etc/jwm/debian-menu</Include>
|
||||
<Program icon="terminal.png" label="Terminal">lxterminal</Program>
|
||||
<Separator/>
|
||||
<Program icon="lock.png" label="Lock">
|
||||
xlock -mode blank
|
||||
</Program>
|
||||
<Separator/>
|
||||
<Restart label="Restart" icon="restart.png"/>
|
||||
<Exit label="Exit" confirm="true" icon="quit.png"/>
|
||||
</RootMenu>
|
||||
|
||||
<!-- Options for program groups. -->
|
||||
<Group>
|
||||
<Option>tiled</Option>
|
||||
<Option>aerosnap</Option>
|
||||
</Group>
|
||||
<Group>
|
||||
<Class>Pidgin</Class>
|
||||
<Option>sticky</Option>
|
||||
</Group>
|
||||
<Group>
|
||||
<Name>xterm</Name>
|
||||
<Option>vmax</Option>
|
||||
</Group>
|
||||
<Group>
|
||||
<Name>xclock</Name>
|
||||
<Option>drag</Option>
|
||||
<Option>notitle</Option>
|
||||
</Group>
|
||||
|
||||
<!-- Tray at the bottom. -->
|
||||
<Tray x="0" y="-1" height="20" autohide="off">
|
||||
|
||||
<TrayButton icon="/usr/share/jwm/jwm-red.svg">root:1</TrayButton>
|
||||
<Spacer width="2"/>
|
||||
|
||||
<Pager labeled="true"/>
|
||||
|
||||
<TaskList maxwidth="192"/>
|
||||
|
||||
<Dock/>
|
||||
<Clock format="%H:%M"><Button mask="123">exec:xclock</Button></Clock>
|
||||
|
||||
</Tray>
|
||||
|
||||
<!-- Visual Styles -->
|
||||
<WindowStyle>
|
||||
<Font>Sans-9:bold</Font>
|
||||
<Width>4</Width>
|
||||
<Height>21</Height>
|
||||
<Corner>3</Corner>
|
||||
<Foreground>#FFFFFF</Foreground>
|
||||
<Background>#555555</Background>
|
||||
<Outline>#777777</Outline>
|
||||
<Opacity>0.5</Opacity>
|
||||
<Active>
|
||||
<Foreground>#FFFFFF</Foreground>
|
||||
<Background>#0077CC</Background>
|
||||
<Outline>#1AA0FF</Outline>
|
||||
<Opacity>1.0</Opacity>
|
||||
</Active>
|
||||
</WindowStyle>
|
||||
<TrayStyle group="true" list="all">
|
||||
<Font>Sans-9</Font>
|
||||
<Background>#222222</Background>
|
||||
<Foreground>#FFFFFF</Foreground>
|
||||
<Outline>#222222</Outline>
|
||||
<Opacity>0.75</Opacity>
|
||||
</TrayStyle>
|
||||
<TaskListStyle>
|
||||
<Font>Sans-9</Font>
|
||||
<Active>
|
||||
<Foreground>#FFFFFF</Foreground>
|
||||
<Background>#333333</Background>
|
||||
</Active>
|
||||
<Foreground>#FFFFFF</Foreground>
|
||||
<Background>#222222</Background>
|
||||
</TaskListStyle>
|
||||
<PagerStyle>
|
||||
<Outline>#3B3B3B</Outline>
|
||||
<Foreground>#555555</Foreground>
|
||||
<Background>#333333</Background>
|
||||
<Text>#FFFFFF</Text>
|
||||
<Active>
|
||||
<Foreground>#0077CC</Foreground>
|
||||
<Background>#004488</Background>
|
||||
</Active>
|
||||
</PagerStyle>
|
||||
<MenuStyle>
|
||||
<Font>Sans-9</Font>
|
||||
<Foreground>#FFFFFF</Foreground>
|
||||
<Background>#333333</Background>
|
||||
<Outline>#000000</Outline>
|
||||
<Active>
|
||||
<Foreground>#FFFFFF</Foreground>
|
||||
<Background>#0077CC</Background>
|
||||
</Active>
|
||||
<Opacity>0.85</Opacity>
|
||||
</MenuStyle>
|
||||
<PopupStyle>
|
||||
<Font>Sans-9</Font>
|
||||
<Foreground>#000000</Foreground>
|
||||
<Background>#999999</Background>
|
||||
</PopupStyle>
|
||||
|
||||
<!-- Path where icons can be found.
|
||||
IconPath can be listed multiple times to allow searching
|
||||
for icons in multiple paths.
|
||||
-->
|
||||
<IconPath>/usr/share/icons/gnome/256x256/actions</IconPath>
|
||||
<IconPath>/usr/share/icons/gnome/256x256/apps</IconPath>
|
||||
<IconPath>/usr/share/icons/gnome/256x256/categories</IconPath>
|
||||
<IconPath>/usr/share/icons/gnome/256x256/devices</IconPath>
|
||||
<IconPath>/usr/share/icons/gnome/256x256/emblems</IconPath>
|
||||
<IconPath>/usr/share/icons/gnome/256x256/mimetypes</IconPath>
|
||||
<IconPath>/usr/share/icons/gnome/256x256/places</IconPath>
|
||||
<IconPath>/usr/share/icons/gnome/256x256/status</IconPath>
|
||||
<IconPath>/usr/share/icons/gnome/32x32/actions</IconPath>
|
||||
<IconPath>/usr/share/icons/gnome/32x32/animations</IconPath>
|
||||
<IconPath>/usr/share/icons/gnome/32x32/apps</IconPath>
|
||||
<IconPath>/usr/share/icons/gnome/32x32/categories</IconPath>
|
||||
<IconPath>/usr/share/icons/gnome/32x32/devices</IconPath>
|
||||
<IconPath>/usr/share/icons/gnome/32x32/emblems</IconPath>
|
||||
<IconPath>/usr/share/icons/gnome/32x32/mimetypes</IconPath>
|
||||
<IconPath>/usr/share/icons/gnome/32x32/places</IconPath>
|
||||
<IconPath>/usr/share/icons/gnome/32x32/status</IconPath>
|
||||
<IconPath>/usr/share/icons/gnome/scalable/actions</IconPath>
|
||||
<IconPath>/usr/share/icons/gnome/scalable/apps</IconPath>
|
||||
<IconPath>/usr/share/icons/gnome/scalable/categories</IconPath>
|
||||
<IconPath>/usr/share/icons/gnome/scalable/devices</IconPath>
|
||||
<IconPath>/usr/share/icons/gnome/scalable/emblems</IconPath>
|
||||
<IconPath>/usr/share/icons/gnome/scalable/mimetypes</IconPath>
|
||||
<IconPath>/usr/share/icons/gnome/scalable/places</IconPath>
|
||||
<IconPath>/usr/share/icons/gnome/scalable/status</IconPath>
|
||||
<IconPath>/usr/share/icons/hicolor/256x256/apps</IconPath>
|
||||
<IconPath>/usr/share/icons/hicolor/256x256/mimetypes</IconPath>
|
||||
<IconPath>/usr/share/icons/hicolor/32x32/actions</IconPath>
|
||||
<IconPath>/usr/share/icons/hicolor/32x32/apps</IconPath>
|
||||
<IconPath>/usr/share/icons/hicolor/32x32/categories</IconPath>
|
||||
<IconPath>/usr/share/icons/hicolor/32x32/devices</IconPath>
|
||||
<IconPath>/usr/share/icons/hicolor/32x32/emblems</IconPath>
|
||||
<IconPath>/usr/share/icons/hicolor/32x32/mimetypes</IconPath>
|
||||
<IconPath>/usr/share/icons/hicolor/32x32/status</IconPath>
|
||||
<IconPath>/usr/share/icons/hicolor/512x512/apps</IconPath>
|
||||
<IconPath>/usr/share/icons/hicolor/512x512/mimetypes</IconPath>
|
||||
<IconPath>/usr/share/icons/hicolor/scalable/actions</IconPath>
|
||||
<IconPath>/usr/share/icons/hicolor/scalable/apps</IconPath>
|
||||
<IconPath>/usr/share/icons/hicolor/scalable/categories</IconPath>
|
||||
<IconPath>/usr/share/icons/hicolor/scalable/devices</IconPath>
|
||||
<IconPath>/usr/share/icons/hicolor/scalable/emblems</IconPath>
|
||||
<IconPath>/usr/share/icons/hicolor/scalable/mimetypes</IconPath>
|
||||
<IconPath>/usr/share/icons/hicolor/scalable/places</IconPath>
|
||||
<IconPath>/usr/share/icons/hicolor/scalable/status</IconPath>
|
||||
<IconPath>/usr/share/icons</IconPath>
|
||||
<IconPath>/usr/share/pixmaps</IconPath>
|
||||
<IconPath>
|
||||
/usr/local/share/jwm
|
||||
</IconPath>
|
||||
|
||||
<!-- Virtual Desktops -->
|
||||
<!-- Desktop tags can be contained within Desktops for desktop names. -->
|
||||
<Desktops width="4" height="1">
|
||||
<!-- Default background. Note that a Background tag can be
|
||||
contained within a Desktop tag to give a specific background
|
||||
for that desktop.
|
||||
-->
|
||||
<Background type="solid">#111111</Background>
|
||||
</Desktops>
|
||||
|
||||
<!-- Double click speed (in milliseconds) -->
|
||||
<DoubleClickSpeed>400</DoubleClickSpeed>
|
||||
|
||||
<!-- Double click delta (in pixels) -->
|
||||
<DoubleClickDelta>2</DoubleClickDelta>
|
||||
|
||||
<!-- The focus model (sloppy or click) -->
|
||||
<FocusModel>sloppy</FocusModel>
|
||||
|
||||
<!-- The snap mode (none, screen, or border) -->
|
||||
<SnapMode distance="10">border</SnapMode>
|
||||
|
||||
<!-- The move mode (outline or opaque) -->
|
||||
<MoveMode>opaque</MoveMode>
|
||||
|
||||
<!-- The resize mode (outline or opaque) -->
|
||||
<ResizeMode>opaque</ResizeMode>
|
||||
|
||||
<!-- Key bindings -->
|
||||
<Key key="Up">up</Key>
|
||||
<Key key="Down">down</Key>
|
||||
<Key key="Right">right</Key>
|
||||
<Key key="Left">left</Key>
|
||||
<Key key="h">left</Key>
|
||||
<Key key="j">down</Key>
|
||||
<Key key="k">up</Key>
|
||||
<Key key="l">right</Key>
|
||||
<Key key="Return">select</Key>
|
||||
<Key key="Escape">escape</Key>
|
||||
|
||||
<Key mask="A" key="Tab">nextstacked</Key>
|
||||
<Key mask="A" key="F4">close</Key>
|
||||
<Key mask="A" key="#">desktop#</Key>
|
||||
<Key mask="A" key="F1">root:1</Key>
|
||||
<Key mask="A" key="F2">window</Key>
|
||||
<Key mask="A" key="F10">maximize</Key>
|
||||
<Key mask="A" key="Right">rdesktop</Key>
|
||||
<Key mask="A" key="Left">ldesktop</Key>
|
||||
<Key mask="A" key="Up">udesktop</Key>
|
||||
<Key mask="A" key="Down">ddesktop</Key>
|
||||
|
||||
</JWM>
|
||||
27
os-brainux/override/etc/sudoers
Normal file
27
os-brainux/override/etc/sudoers
Normal file
@@ -0,0 +1,27 @@
|
||||
#
|
||||
# This file MUST be edited with the 'visudo' command as root.
|
||||
#
|
||||
# Please consider adding local content in /etc/sudoers.d/ instead of
|
||||
# directly modifying this file.
|
||||
#
|
||||
# See the man page for details on how to write a sudoers file.
|
||||
#
|
||||
Defaults env_reset,pwfeedback
|
||||
Defaults mail_badpass
|
||||
Defaults secure_path="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
|
||||
|
||||
# Host alias specification
|
||||
|
||||
# User alias specification
|
||||
|
||||
# Cmnd alias specification
|
||||
|
||||
# User privilege specification
|
||||
root ALL=(ALL:ALL) ALL
|
||||
|
||||
# Allow members of group sudo to execute any command
|
||||
%sudo ALL=(ALL:ALL) ALL
|
||||
|
||||
# See sudoers(5) for more information on "@include" directives:
|
||||
|
||||
@includedir /etc/sudoers.d
|
||||
4
os-brainux/override/etc/xdg/weston/weston.ini
Normal file
4
os-brainux/override/etc/xdg/weston/weston.ini
Normal file
@@ -0,0 +1,4 @@
|
||||
[core]
|
||||
xwayland=true
|
||||
backend=fbdev-backend.so
|
||||
|
||||
22
os-brainux/override/home/user/.config/fcitx/profile
Normal file
22
os-brainux/override/home/user/.config/fcitx/profile
Normal file
File diff suppressed because one or more lines are too long
7
os-brainux/override/home/user/.xprofile
Normal file
7
os-brainux/override/home/user/.xprofile
Normal file
@@ -0,0 +1,7 @@
|
||||
export GTK_IM_MODULE=fcitx
|
||||
export QT_IM_MODULE=fcitx
|
||||
export XMODIFIERS=@im=fcitx
|
||||
|
||||
# Uncomment the following line to enable fcitx-mozc
|
||||
# fcitx-autostart &
|
||||
|
||||
53
os-brainux/override/home/user/lxterminal/lxterminal.conf
Normal file
53
os-brainux/override/home/user/lxterminal/lxterminal.conf
Normal file
@@ -0,0 +1,53 @@
|
||||
[general]
|
||||
fontname=Noto Sans Mono CJK JP 10
|
||||
selchars=-A-Za-z0-9,./?%&#:_
|
||||
scrollback=1000
|
||||
bgcolor=rgb(0,0,0)
|
||||
fgcolor=rgb(211,215,207)
|
||||
palette_color_0=rgb(0,0,0)
|
||||
palette_color_1=rgb(205,0,0)
|
||||
palette_color_2=rgb(78,154,6)
|
||||
palette_color_3=rgb(196,160,0)
|
||||
palette_color_4=rgb(52,101,164)
|
||||
palette_color_5=rgb(117,80,123)
|
||||
palette_color_6=rgb(6,152,154)
|
||||
palette_color_7=rgb(211,215,207)
|
||||
palette_color_8=rgb(85,87,83)
|
||||
palette_color_9=rgb(239,41,41)
|
||||
palette_color_10=rgb(138,226,52)
|
||||
palette_color_11=rgb(252,233,79)
|
||||
palette_color_12=rgb(114,159,207)
|
||||
palette_color_13=rgb(173,127,168)
|
||||
palette_color_14=rgb(52,226,226)
|
||||
palette_color_15=rgb(238,238,236)
|
||||
color_preset=Tango
|
||||
disallowbold=false
|
||||
cursorblinks=false
|
||||
cursorunderline=false
|
||||
audiblebell=false
|
||||
tabpos=top
|
||||
geometry_columns=80
|
||||
geometry_rows=24
|
||||
hidescrollbar=false
|
||||
hidemenubar=false
|
||||
hideclosebutton=false
|
||||
hidepointer=false
|
||||
disablef10=false
|
||||
disablealt=false
|
||||
disableconfirm=false
|
||||
|
||||
[shortcut]
|
||||
new_window_accel=<Primary><Shift>n
|
||||
new_tab_accel=<Primary><Shift>t
|
||||
close_tab_accel=<Primary><Shift>w
|
||||
close_window_accel=<Primary><Shift>q
|
||||
copy_accel=<Primary><Shift>c
|
||||
paste_accel=<Primary><Shift>v
|
||||
name_tab_accel=<Primary><Shift>i
|
||||
previous_tab_accel=<Primary>Page_Up
|
||||
next_tab_accel=<Primary>Page_Down
|
||||
move_tab_left_accel=<Primary><Shift>Page_Up
|
||||
move_tab_right_accel=<Primary><Shift>Page_Down
|
||||
zoom_in_accel=<Primary><Shift>plus
|
||||
zoom_out_accel=<Primary><Shift>underscore
|
||||
zoom_reset_accel=<Primary><Shift>parenright
|
||||
10
os-brainux/override/lib/systemd/system/boot.mount
Normal file
10
os-brainux/override/lib/systemd/system/boot.mount
Normal file
@@ -0,0 +1,10 @@
|
||||
[Unit]
|
||||
Description=Mount boot partition
|
||||
|
||||
[Mount]
|
||||
What=/dev/mmcblk1p1
|
||||
Where=/boot
|
||||
Options=ro
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
@@ -0,0 +1,9 @@
|
||||
[Unit]
|
||||
Description=Enable Ethernet USB Gadget
|
||||
|
||||
[Service]
|
||||
Type=oneshot
|
||||
ExecStart=/usr/bin/enable_ethernet_gadget
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
29
os-brainux/override/usr/bin/enable_ethernet_gadget
Executable file
29
os-brainux/override/usr/bin/enable_ethernet_gadget
Executable file
@@ -0,0 +1,29 @@
|
||||
#!/bin/sh
|
||||
|
||||
g=/sys/kernel/config/usb_gadget/eth
|
||||
|
||||
mkdir ${g}
|
||||
|
||||
echo "0x0200" > ${g}/bcdUSB
|
||||
echo "0x0200" > ${g}/bcdDevice
|
||||
|
||||
mkdir -p ${g}/strings/0x409
|
||||
echo "0123456789" > ${g}/strings/0x409/serialnumber
|
||||
echo "SHARP" > ${g}/strings/0x409/manufacturer
|
||||
echo "Brain" > ${g}/strings/0x409/product
|
||||
|
||||
mkdir -p ${g}/configs/c.1/strings/0x409
|
||||
echo "NCM Config" > ${g}/configs/c.1/strings/0x409/configuration
|
||||
echo 250 > ${g}/configs/c.1/MaxPower
|
||||
|
||||
mkdir ${g}/functions/ncm.usb0
|
||||
echo "8a:15:8b:44:3a:02" > ${g}/functions/ncm.usb0/dev_addr
|
||||
echo "8a:15:8b:44:3a:01" > ${g}/functions/ncm.usb0/host_addr
|
||||
|
||||
ln -s ${g}/functions/ncm.usb0 ${g}/configs/c.1/
|
||||
|
||||
echo "ci_hdrc.0" > ${g}/UDC
|
||||
|
||||
sleep 1
|
||||
ifconfig usb0 up
|
||||
dhclient
|
||||
@@ -1,9 +0,0 @@
|
||||
PRETTY_NAME="Brainux GNU/Linux 10 (buster)"
|
||||
NAME="Brainux GNU/Linux"
|
||||
VERSION_ID="10"
|
||||
VERSION="10 (buster)"
|
||||
VERSION_CODENAME=buster
|
||||
ID=debian
|
||||
HOME_URL="https://github.com/brain-hackers/README"
|
||||
SUPPORT_URL="https://github.com/brain-hackers/buildbrain"
|
||||
BUG_REPORT_URL="https://github.com/brain-hackers/buildbrain"
|
||||
@@ -1,6 +1,13 @@
|
||||
#!/bin/bash
|
||||
set -uex -o pipefail
|
||||
|
||||
TIMEZONE="Asia/Tokyo"
|
||||
if [ ! -v TIMEZONE ]; then
|
||||
TIMEZONE=Asia/Tokyo
|
||||
fi
|
||||
|
||||
if [ ! -v CI ]; then
|
||||
CI=false
|
||||
fi
|
||||
|
||||
/debootstrap/debootstrap --second-stage
|
||||
|
||||
@@ -13,12 +20,12 @@ else
|
||||
fi
|
||||
|
||||
cat <<EOF > /etc/apt/sources.list
|
||||
deb http://${REPO}/debian buster main contrib non-free
|
||||
deb-src http://${REPO}/debian buster main contrib non-free
|
||||
deb http://${REPO}/debian buster-updates main contrib non-free
|
||||
deb-src http://${REPO}/debian buster-updates main contrib non-free
|
||||
deb http://${REPO_SECURITY}/debian-security buster/updates main contrib non-free
|
||||
deb-src http://${REPO_SECURITY}/debian-security buster/updates main contrib non-free
|
||||
deb http://${REPO}/debian trixie main contrib non-free
|
||||
deb-src http://${REPO}/debian trixie main contrib non-free
|
||||
deb http://${REPO}/debian trixie-updates main contrib non-free
|
||||
deb-src http://${REPO}/debian trixie-updates main contrib non-free
|
||||
deb http://${REPO_SECURITY}/debian-security trixie-security/updates main contrib non-free
|
||||
deb-src http://${REPO_SECURITY}/debian-security trixie-security/updates main contrib non-free
|
||||
EOF
|
||||
|
||||
cat <<EOF > /etc/apt/apt.conf.d/90-norecommend
|
||||
@@ -26,45 +33,121 @@ APT::Install-Recommends "0";
|
||||
APT::Install-Suggests "0";
|
||||
EOF
|
||||
|
||||
# locales: locale has to be set before going any further
|
||||
apt update -y
|
||||
DEBIAN_FRONTEND=noninteractive \
|
||||
apt install -y locales
|
||||
|
||||
echo "$TIMEZONE" > /etc/timezone && \
|
||||
dpkg-reconfigure -f noninteractive tzdata && \
|
||||
sed -i -e 's/# en_US.UTF-8 UTF-8/en_us.UTF-8 UTF-8/' /etc/locale.gen && \
|
||||
sed -i -e 's/# en_US.UTF-8 UTF-8/en_US.UTF-8 UTF-8/' /etc/locale.gen && \
|
||||
echo 'LANG="en_US.UTF-8"' > /etc/default/locale && \
|
||||
dpkg-reconfigure -f noninteractive locales && \
|
||||
update-locale LANG=en_US.UTF-8
|
||||
|
||||
LANG=en_US.UTF-8
|
||||
|
||||
rm /etc/localtime
|
||||
ln -s /usr/share/zoneinfo/Asia/Tokyo /etc/localtime
|
||||
|
||||
echo "brain" > /etc/hostname
|
||||
|
||||
# Install packagecloud repository
|
||||
# Reference: https://packagecloud.io/brainhackers/brainux/install
|
||||
|
||||
echo root:root | chpasswd
|
||||
# curl, ca-certificates: downloads the GPG key from packagecloud
|
||||
# gnupg, debian-archive-keyring: packagecloud verification dependency
|
||||
DEBIAN_FRONTEND=noninteractive \
|
||||
apt install -y curl ca-certificates gnupg debian-archive-keyring
|
||||
|
||||
cat <<EOF >> /etc/securetty
|
||||
ttymxc0
|
||||
# apt-transport-https can be installed after debian-archive-keyring being installed
|
||||
DEBIAN_FRONTEND=noninteractive \
|
||||
apt install -y apt-transport-https
|
||||
|
||||
# Install GPG key and packagecloud repository config
|
||||
mkdir -p /etc/apt/keyrings
|
||||
curl -fsSL "https://packagecloud.io/brainhackers/brainux/gpgkey" \
|
||||
| gpg --dearmor > /etc/apt/keyrings/brainhackers_brainux-archive-keyring.gpg
|
||||
|
||||
cat <<EOF > /etc/apt/sources.list.d/packagecloud.list
|
||||
deb [signed-by=/etc/apt/keyrings/brainhackers_brainux-archive-keyring.gpg] https://packagecloud.io/brainhackers/brainux/any/ any main
|
||||
deb-src [signed-by=/etc/apt/keyrings/brainhackers_brainux-archive-keyring.gpg] https://packagecloud.io/brainhackers/brainux/any/ any main
|
||||
EOF
|
||||
|
||||
# Fetch packagecloud repository
|
||||
apt update -y
|
||||
|
||||
DEBIAN_FRONTEND=noninteractive \
|
||||
apt install -y dialog sudo \
|
||||
libjpeg-dev libfreetype6 libfreetype6-dev zlib1g-dev \
|
||||
xserver-xorg xserver-xorg-video-fbdev xserver-xorg-dev xorg-dev x11-apps \
|
||||
openbox obconf obmenu \
|
||||
weston xwayland \
|
||||
alsa-utils \
|
||||
xserver-xorg xserver-xorg-video-fbdev xserver-xorg-dev xserver-xorg-input-evdev xinput-calibrator xorg-dev x11-apps x11-ico-dvd xinit \
|
||||
jwm \
|
||||
bash tmux vim htop \
|
||||
midori pcmanfm lxterminal xterm gnome-terminal fonts-noto-cjk \
|
||||
dbus udev build-essential flex bison pkg-config autotools-dev libtool autoconf automake \
|
||||
pcmanfm lxterminal xterm gnome-terminal fbterm uim-fep uim-anthy fonts-noto-cjk \
|
||||
dbus udev alsa-utils usbutils iw fake-hwclock systemd-timesyncd\
|
||||
build-essential flex bison pkg-config autotools-dev libtool autoconf automake device-tree-compiler \
|
||||
python3 python3-dev python3-setuptools python3-wheel python3-pip python3-smbus \
|
||||
resolvconf net-tools ssh openssh-client avahi-daemon
|
||||
resolvconf net-tools isc-dhcp-client ssh openssh-client avahi-daemon wget git \
|
||||
network-manager zip fastfetch sl python3-numpy ipython3 netsurf-gtk fcitx-anthy
|
||||
|
||||
# Packages from packagecloud
|
||||
DEBIAN_FRONTEND=noninteractive \
|
||||
apt install -y --install-recommends brain-config
|
||||
|
||||
systemctl enable fake-hwclock-load fake-hwclock-save fake-hwclock-save.timer
|
||||
|
||||
# Ly
|
||||
DEBIAN_FRONTEND=noninteractive \
|
||||
apt install -y libpam0g-dev libxcb-xkb-dev
|
||||
cd /
|
||||
git clone --recurse-submodules -b master-24f017e https://github.com/brain-hackers/ly.git
|
||||
cd ly
|
||||
make
|
||||
make install
|
||||
make installsystemd
|
||||
cd /
|
||||
rm -r ly
|
||||
systemctl enable ly
|
||||
|
||||
# Create editable xorg.conf.d
|
||||
install -m 0777 -d /etc/X11/xorg.conf.d
|
||||
|
||||
# Fix Midori launch failure
|
||||
update-mime-database /usr/share/mime
|
||||
|
||||
# Setup users
|
||||
adduser --gecos "" --disabled-password --home /home/user user
|
||||
echo user:brain | chpasswd
|
||||
echo "user ALL=(ALL:ALL) ALL" > /etc/sudoers.d/user
|
||||
echo -e "127.0.1.1\tbrain" >> /etc/hosts
|
||||
|
||||
echo root:root | chpasswd
|
||||
|
||||
# Fix Xorg permission for non-root users
|
||||
# https://unix.stackexchange.com/questions/315169/how-can-i-run-usr-bin-xorg-without-sudo
|
||||
chown root:input /usr/lib/xorg/Xorg
|
||||
chmod g+s /usr/lib/xorg/Xorg
|
||||
usermod -a -G video user
|
||||
|
||||
# Allow root login via UART
|
||||
cat <<EOF >> /etc/securetty
|
||||
ttymxc0
|
||||
ttyLP0
|
||||
EOF
|
||||
|
||||
# Enable /boot mount
|
||||
systemctl enable boot.mount
|
||||
|
||||
# Enable RNDIS gadget
|
||||
systemctl enable ethernet_gadget
|
||||
|
||||
# Get wild
|
||||
cat <<EOF > /etc/apt/sources.list
|
||||
deb http://deb.debian.org/debian buster main contrib non-free
|
||||
deb-src http://deb.debian.org/debian buster main contrib non-free
|
||||
deb http://deb.debian.org/debian buster-updates main contrib non-free
|
||||
deb-src http://deb.debian.org/debian buster-updates main contrib non-free
|
||||
deb http://deb.debian.org/debian-security buster/updates main contrib non-free
|
||||
deb-src http://deb.debian.org/debian-security buster/updates main contrib non-free
|
||||
deb http://deb.debian.org/debian trixie main contrib non-free
|
||||
deb-src http://deb.debian.org/debian trixie main contrib non-free
|
||||
deb http://deb.debian.org/debian trixie-updates main contrib non-free
|
||||
deb-src http://deb.debian.org/debian trixie-updates main contrib non-free
|
||||
deb http://deb.debian.org/debian-security trixie-security/updates main contrib non-free
|
||||
deb-src http://deb.debian.org/debian-security trixie-security/updates main contrib non-free
|
||||
EOF
|
||||
|
||||
|
||||
112
os-buildroot/override/root/blink.sh
Executable file
112
os-buildroot/override/root/blink.sh
Executable file
@@ -0,0 +1,112 @@
|
||||
#!/bin/sh
|
||||
set -u
|
||||
|
||||
VERBOSE=0
|
||||
PIN=""
|
||||
SLEEP=1
|
||||
GPIOS=""
|
||||
|
||||
while getopts "hvr:p:s:" OPT; do
|
||||
case "$OPT" in
|
||||
h)
|
||||
echo "Usage: blink.sh [-hv] [-r PIN_RANGE_FROM-PIN_RANGE_TO] [-p PIN] [-s SLEEP_SEC]"
|
||||
echo "Example: blink.sh -r 0-10 -p 12"
|
||||
echo " (blink from GPIO 0 to 10 and 12)"
|
||||
exit 0
|
||||
;;
|
||||
v)
|
||||
VERBOSE=1
|
||||
;;
|
||||
r)
|
||||
RE='^([0-9]+)-([0-9]+)$'
|
||||
if echo $OPTARG | grep -qvE $RE; then
|
||||
echo "Error: invalid range: $OPTARG"
|
||||
exit 1
|
||||
fi
|
||||
FROM=$(echo $OPTARG | sed -E "s/$RE/\\1/")
|
||||
TO=$(echo $OPTARG | sed -E "s/$RE/\\2/")
|
||||
GPIOS="$GPIOS$(seq -s " " $FROM $TO) "
|
||||
;;
|
||||
p)
|
||||
if echo $OPTARG | grep -qvE "^[0-9]+$"; then
|
||||
echo "Error: invalid pin number: $OPTARG"
|
||||
exit 1
|
||||
fi
|
||||
GPIOS="$GPIOS$OPTARG "
|
||||
;;
|
||||
s)
|
||||
if echo $OPTARG | grep -qvE "^[0-9]+$"; then
|
||||
echo "Error: invalid sleep duration: $OPTARG"
|
||||
exit 1
|
||||
fi
|
||||
SLEEP=$OPTARG
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
if [ $VERBOSE -eq 1 ]; then
|
||||
echo "Pins to iterate over: $GPIOS"
|
||||
fi
|
||||
|
||||
if [ "$(id -u)" -ne "0" ]; then
|
||||
echo "Error: please run as root"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
AVAILABLE_GPIOS=""
|
||||
|
||||
export_gpio() {
|
||||
echo $1 > /sys/class/gpio/export
|
||||
}
|
||||
|
||||
set_direction() {
|
||||
echo out > /sys/class/gpio/gpio$1/direction
|
||||
}
|
||||
|
||||
set_value() {
|
||||
echo $2 > /sys/class/gpio/gpio$1/value
|
||||
}
|
||||
|
||||
for i in $GPIOS; do
|
||||
if [ ! -e "/sys/class/gpio/gpio$i" ]; then
|
||||
export_gpio $i 2>/dev/null
|
||||
if [ $? -ne 0 ]; then
|
||||
echo "Error: failed to export the pin $i"
|
||||
continue
|
||||
fi
|
||||
fi
|
||||
|
||||
set_direction $i 2>/dev/null
|
||||
if [ $? -ne 0 ]; then
|
||||
# Ignore the failure if the actual direction is out
|
||||
if grep -vq "out" /dsys/class/gpio/gpio$i/direction; then
|
||||
echo "Error: failed to set the direction of the pin $i to out"
|
||||
continue
|
||||
fi
|
||||
fi
|
||||
|
||||
AVAILABLE_GPIOS="$AVAILABLE_GPIOS$i "
|
||||
done
|
||||
|
||||
echo "Available GPIOs: $AVAILABLE_GPIOS"
|
||||
|
||||
while [ 1 ]; do
|
||||
for i in $AVAILABLE_GPIOS; do
|
||||
set_value $i 1 2>/dev/null
|
||||
if [ $? -ne 0 ]; then
|
||||
echo "Warning: failed to set the value of the pin $i to high"
|
||||
fi
|
||||
done
|
||||
|
||||
sleep $SLEEP
|
||||
|
||||
for i in $AVAILABLE_GPIOS; do
|
||||
set_value $i 0 2>/dev/null
|
||||
if [ $? -ne 0 ]; then
|
||||
echo "Warning: failed to set the value of the pin $i to low"
|
||||
fi
|
||||
done
|
||||
|
||||
sleep $SLEEP
|
||||
done
|
||||
|
||||
@@ -35,6 +35,7 @@ import (
|
||||
"net/http"
|
||||
"net/url"
|
||||
"os"
|
||||
"path"
|
||||
"path/filepath"
|
||||
"strconv"
|
||||
"strings"
|
||||
@@ -45,6 +46,7 @@ import (
|
||||
|
||||
type Proxy struct {
|
||||
remote string
|
||||
root string
|
||||
|
||||
cli *http.Client
|
||||
cache map[string]struct{}
|
||||
@@ -81,8 +83,9 @@ func NewProxy() (*Proxy, error) {
|
||||
return p, nil
|
||||
}
|
||||
|
||||
func (p *Proxy) Run(local, remote string) {
|
||||
func (p *Proxy) Run(local, remote, root string) {
|
||||
p.remote = remote
|
||||
p.root = root
|
||||
err := http.ListenAndServe(local, p)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
@@ -101,13 +104,13 @@ func (p *Proxy) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
||||
}
|
||||
|
||||
if nocache {
|
||||
fmt.Printf("GET (no cache): %s%s -> ", p.remote, r.URL.Path)
|
||||
fmt.Printf("GET (no cache): %s%s%s -> ", p.remote, p.root, r.URL.Path)
|
||||
err = p.fetchFromRemote(w, r, false)
|
||||
} else if _, ok := p.cache[encoded]; ok {
|
||||
fmt.Printf("GET (cache hit): %s%s -> ", p.remote, r.URL.Path)
|
||||
fmt.Printf("GET (cache hit): %s%s%s -> ", p.remote, p.root, r.URL.Path)
|
||||
err = p.fetchFromCache(w, r)
|
||||
} else {
|
||||
fmt.Printf("GET (cache miss): %s%s -> ", p.remote, r.URL.Path)
|
||||
fmt.Printf("GET (cache miss): %s%s%s -> ", p.remote, p.root, r.URL.Path)
|
||||
err = p.fetchFromRemote(w, r, true)
|
||||
}
|
||||
|
||||
@@ -133,6 +136,7 @@ func (p *Proxy) fetchFromRemote(w http.ResponseWriter, r *http.Request, cache bo
|
||||
}
|
||||
newURL.Scheme = "http"
|
||||
newURL.Host = p.remote
|
||||
newURL.Path = path.Join(p.root, newURL.Path)
|
||||
|
||||
req, err := http.NewRequest(http.MethodGet, newURL.String(), nil)
|
||||
if err != nil {
|
||||
@@ -219,7 +223,7 @@ func (w NullWriter) Close() error {
|
||||
}
|
||||
|
||||
type rule struct {
|
||||
Local, Remote string
|
||||
Local, Remote, Root string
|
||||
}
|
||||
|
||||
type rules []rule
|
||||
@@ -229,7 +233,7 @@ func (r *rules) String() string {
|
||||
}
|
||||
|
||||
func (r *rules) Set(raw string) error {
|
||||
var local, remote string
|
||||
var local, remote, root string
|
||||
|
||||
kvs := strings.Split(raw, ",")
|
||||
for _, kv := range kvs {
|
||||
@@ -243,6 +247,8 @@ func (r *rules) Set(raw string) error {
|
||||
local = tokens[1]
|
||||
case "remote":
|
||||
remote = tokens[1]
|
||||
case "root":
|
||||
root = tokens[1]
|
||||
default:
|
||||
return fmt.Errorf("rule has unknown key: '%s'", tokens[0])
|
||||
}
|
||||
@@ -252,7 +258,7 @@ func (r *rules) Set(raw string) error {
|
||||
return fmt.Errorf("rule lacks mendatory keys: 'local' and/or 'remote'")
|
||||
}
|
||||
|
||||
*r = append(*r, rule{Local: local, Remote: remote})
|
||||
*r = append(*r, rule{Local: local, Remote: remote, Root: root})
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -268,13 +274,13 @@ func main() {
|
||||
}
|
||||
|
||||
for i, rule := range rules {
|
||||
fmt.Printf("Proxy Rule %d: %s -> %s\n", i+1, rule.Local, rule.Remote)
|
||||
fmt.Printf("Proxy Rule %d: %s -> %s%s\n", i+1, rule.Local, rule.Remote, rule.Root)
|
||||
|
||||
p, err := NewProxy()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
go p.Run(rule.Local, rule.Remote)
|
||||
go p.Run(rule.Local, rule.Remote, rule.Root)
|
||||
}
|
||||
for {
|
||||
time.Sleep(9999999999)
|
||||
|
||||
Binary file not shown.
36
tools/getcross
Executable file
36
tools/getcross
Executable file
@@ -0,0 +1,36 @@
|
||||
#!/bin/sh
|
||||
set -e
|
||||
|
||||
uboot() {
|
||||
. ./u-boot-brain/.config
|
||||
case "${CONFIG_SYS_CPU}" in
|
||||
arm926ejs) echo -n "arm-linux-gnueabi-"; return;;
|
||||
armv7) echo -n "arm-linux-gnueabihf-"; return;;
|
||||
*) exit 1;;
|
||||
esac
|
||||
}
|
||||
|
||||
linux() {
|
||||
. ./linux-brain/.config
|
||||
case "${CONFIG_CPU_ARM926T}_${CONFIG_ARCH_MULTI_V7}" in
|
||||
y_) echo -n "arm-linux-gnueabi-"; return;;
|
||||
_y) echo -n "arm-linux-gnueabihf-"; return;;
|
||||
*) exit 1;;
|
||||
esac
|
||||
}
|
||||
|
||||
rootfs() {
|
||||
. ./linux-brain/.config
|
||||
case "${CONFIG_CPU_ARM926T}_${CONFIG_ARCH_MULTI_V7}" in
|
||||
y_) echo -n "armel"; return;;
|
||||
_y) echo -n "armhf"; return;;
|
||||
*) exit 1;;
|
||||
esac
|
||||
}
|
||||
|
||||
case "$1" in
|
||||
u-boot) uboot ;;
|
||||
linux) linux ;;
|
||||
rootfs) rootfs ;;
|
||||
*) exit 1; ;;
|
||||
esac
|
||||
3
tools/version
Executable file
3
tools/version
Executable file
@@ -0,0 +1,3 @@
|
||||
#!/bin/sh
|
||||
|
||||
date +"%Y-%m-%d-%H%M%S"
|
||||
Submodule u-boot-brain updated: 8f3049f7dc...e8fc0d0cf3
Reference in New Issue
Block a user