Compare commits

...

67 Commits
emmc ... master

Author SHA1 Message Date
Takumi Sueda
3fb1dea6f1 Merge pull request #59 from brain-hackers/ci-bump-debian
Brainux: bump up Debian version to Trixie
2026-03-25 02:39:49 +09:00
Takumi Sueda
98a42ab772 Add docs for coding agents 2026-03-22 22:28:46 +09:00
Takumi Sueda
c7e05fb77b Add isc-dhcp-client for dhclient 2026-03-20 02:49:31 +09:00
Takumi Sueda
f3f5eee21b Use NCM instead of RNDIS for USB ethernet gadget 2026-03-20 02:49:31 +09:00
Takumi Sueda
805f0daebd linux-brain: add UVC and NCM 2026-03-19 22:42:11 +09:00
Takumi Sueda
8f3a42adc4 linux-brain: fix config and lradc 2026-03-19 01:09:51 +09:00
Takumi Sueda
7669040ae2 Unmount special directories before making an image 2026-03-13 15:26:56 +09:00
Takumi Sueda
a7e1b1aa1a Split brainux-clean into clean and umount-special 2026-03-13 15:26:27 +09:00
Takumi Sueda
8d5f28e712 linux-brain: fix dts 2026-03-13 14:20:42 +09:00
Takumi Sueda
f3ddab408a Generage and upload listconfig early 2026-03-13 02:52:39 +09:00
Takumi Sueda
a8527d9098 Write brainux_version with a proper permission 2026-03-13 02:50:15 +09:00
Takumi Sueda
cd1bba1f0a Mount and umount sys and proc 2026-03-13 02:49:55 +09:00
b8635dbf7b Builder image bump up to ubuntu-24.04 2026-03-11 13:42:42 +09:00
Takumi Sueda
e8ba23fdfa Update linux-brain: bump to 6.1 2026-03-11 13:42:00 +09:00
Takumi Sueda
ef5ab8903f Replace deprecated set-output / save the brainux version into the vfat partition 2026-03-11 02:05:21 +09:00
Takumi Sueda
6e16db7177 Remove unnecessary sudo 2026-03-11 01:59:10 +09:00
Takumi Sueda
f1af5e77cb Enable fake-hwclock's new targets 2026-03-11 01:58:54 +09:00
Takumi Sueda
b1a3b834dd Drop midori and replace neofetch with fastfetch 2026-03-11 01:58:38 +09:00
Takumi Sueda
e13a1ea846 Change the Debian version to trixie 2026-03-11 01:57:58 +09:00
Takumi Sueda
818644a433 Change the mirror to riken 2026-03-11 01:55:46 +09:00
Takumi Sueda
140ba3ff38 aptcache: accept root directory config 2026-03-11 01:55:12 +09:00
Takumi Sueda
cf7cc41efe Merge pull request #58 from brain-hackers/ci-enable-serial
Enable USB UART converter drivers
2024-12-23 20:19:19 +09:00
Takumi Sueda
17c4c8b5a7 Specify the version of setuptools
to avoid failing installing listconfig due to the old Python
2024-12-23 19:13:03 +09:00
Takumi Sueda
924216b934 Update linux-brain: enable USB UART converter 2024-12-23 18:42:49 +09:00
Takumi Sueda
0c7861189b Merge pull request #57 from brain-hackers/ci-next
Upgrade submodules etc.
2024-02-03 23:26:06 -08:00
Takumi Sueda
4257f2465a Workaround workaround 2024-02-04 16:13:11 +09:00
Takumi Sueda
24e5428c62 Build U-Boot specially made for PW-A7400 2024-02-04 16:13:11 +09:00
Takumi Sueda
086c5b08f5 Add x11-ico-dvd, remove weston and xwayland 2024-02-04 16:13:11 +09:00
Takumi Sueda
9d65cf08dd Update linux-brain, u-boot-brain, and brainlilo 2024-02-04 16:13:08 +09:00
Takumi Sueda
68e6e1091e Merge pull request #56 from brain-hackers/buildroot-experiment
Enhance buildroot rootfs
2023-07-31 22:24:07 +09:00
Takumi Sueda
ce8d780b33 Enhance blink.sh 2023-07-31 22:09:11 +09:00
Takumi Sueda
b561fdaec9 buildroot: specify an override directory to add files into the buildroot rootfs 2023-07-31 18:34:50 +09:00
Takumi Sueda
611706771f Merge pull request #55 from brain-hackers/readme
Update README
2023-07-29 01:36:35 +09:00
Takumi Sueda
2fa3904480 Update README 2023-07-29 01:35:28 +09:00
Takumi Sueda
3479812f91 Merge pull request #54 from brain-hackers/ci-buildroot
Add buildroot rootfs target and SD image target
2023-07-29 01:17:07 +09:00
Takumi Sueda
94d37b1b76 Add buildroot w/ Brain board definition 2023-07-29 00:24:37 +09:00
Takumi Sueda
d6719fd49f Enhance build scripts to generate a buildroot SD image 2023-07-29 00:24:37 +09:00
Takumi Sueda
1de1747fbb Add buildroot submodule 2023-07-29 00:24:37 +09:00
Takumi Sueda
d885ca6bc1 Merge pull request #53 from brain-hackers/ci-fix
Fix CI and integrate additional systemd units
2023-07-29 00:23:32 +09:00
Takumi Sueda
b242f06d78 Copy systemd units before setup 2023-07-28 21:40:02 +09:00
Takumi Sueda
d534aa7416 Call daemon-reload before enabling boot.mount 2023-07-24 17:40:55 +09:00
Takumi Sueda
870363a92e Use the latest checkout action 2023-07-24 17:39:08 +09:00
Takumi Sueda
8ca8a3ab12 Merge pull request #52 from brain-hackers/misc
Misc. addition
2023-03-27 20:01:31 +09:00
Takumi Sueda
33e3afbf13 Enable RNDIS gadget automatically 2023-03-27 19:55:11 +09:00
Takumi Sueda
bc2c108d77 Mount /boot automatically 2023-03-21 18:01:11 +09:00
Takumi Sueda
ee93757ff1 Merge pull request #51 from brain-hackers/ci-ly-fix
Switch ly repository to freeze the source code
2023-01-18 04:25:37 +09:00
Takumi Sueda
9f41a0bbd2 Switch ly repository to freeze the source code 2023-01-10 19:14:57 +09:00
Takumi Sueda
9671252f5d Merge pull request #50 from brain-hackers/ci-bullseye
Change the base rootfs to bullseye
2022-12-21 13:11:01 +09:00
Takumi Sueda
935363d6ac Change the base rootfs to bullseye
It is unintentionally reverted back to buster
2022-12-21 13:09:18 +09:00
Takumi Sueda
25668a72e3 Merge pull request #49 from brain-hackers/bump
Update linux-brain: update keyboard driver & maximize brightness
2022-12-08 01:03:01 +09:00
Takumi Sueda
d7da4a6e44 Update linux-brain: update keyboard driver & maximize brightness 2022-12-08 01:02:34 +09:00
Takumi Sueda
8f3f63be44 Merge pull request #48 from brain-hackers/ci-timesyncd
Add systemd-timesyncd & revert back issue and os-release
2022-11-24 00:23:56 +09:00
Takumi Sueda
a4350f303c Fix sudoers 2022-11-23 23:28:22 +09:00
Takumi Sueda
f7a20f61b7 Revert back issue and os-release 2022-11-23 23:20:09 +09:00
Takumi Sueda
2ecec60001 Add systemd-timesyncd 2022-11-23 23:14:38 +09:00
Takumi Sueda
eaa027db98 Merge pull request #47 from brain-hackers/sudoer
Show asterisks in sudo
2022-11-23 23:07:09 +09:00
Takumi Sueda
53e39a8bb6 Show asterisks in sudo 2022-11-23 23:00:06 +09:00
Takumi Sueda
453fe8d60f Merge pull request #46 from brain-hackers/ci-update
Bump versions
2022-11-23 02:06:05 +08:00
Takumi Sueda
e7d3c4629a G5300 -> A7200 2022-11-23 01:23:39 +09:00
Takumi Sueda
57c5052909 Update BrainLILO: support 1G
1G is supported by no one else though
2022-11-23 00:14:58 +09:00
Takumi Sueda
84960b1471 Update u-boot-brain: unify 2G, update env 2022-11-23 00:12:11 +09:00
Takumi Sueda
515aff62be Update linux-brain: unify 2G, enable UAC 2022-11-23 00:11:29 +09:00
Takumi Sueda
6cf0f749d4 Merge pull request #44 from brain-hackers/fix
Fix
2022-11-13 20:35:42 +08:00
Takumi Sueda
7ca8ed3cc1 Install ly service 2022-11-13 21:35:03 +09:00
Takumi Sueda
f444f68a3b Install ca-certificates 2022-11-13 11:48:38 +09:00
Takumi Sueda
f503ef87ef Merge pull request #43 from brain-hackers/license
Add exeopener license agreement
2022-11-04 10:36:54 +09:00
Takumi Sueda
3f4afedf45 Add exeopener license agreement
as per the body approved by the original author
2022-11-03 00:39:09 +09:00
34 changed files with 1491 additions and 104 deletions

View File

@@ -12,7 +12,7 @@ jobs:
outputs:
upload_url: ${{ steps.create_release.outputs.upload_url }}
steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v3
with:
fetch-depth: 0
submodules: false
@@ -38,22 +38,33 @@ jobs:
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 python3-pip
- name: Upgrade pip and setuptools
run: pip3 install -U pip 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
@@ -75,27 +86,15 @@ jobs:
asset_path: release.zip
asset_name: ${{ steps.archive_name.outputs.name }}.zip
asset_content_type: application/zip
- 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
build-linux-x1:
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-gnueabihf libssl-dev lzop qemu-user-static debootstrap
- name: Configure for Linux
@@ -123,14 +122,17 @@ jobs:
asset_content_type: application/zip
build-uboot:
runs-on: ubuntu-20.04
runs-on: ubuntu-24.04
needs: [create_release]
strategy:
matrix:
include:
- model: g5300
- 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
@@ -154,11 +156,11 @@ jobs:
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
@@ -192,7 +194,7 @@ jobs:
asset_content_type: application/zip
build-uboot-x1:
runs-on: ubuntu-20.04
runs-on: ubuntu-24.04
needs: [create_release]
strategy:
matrix:
@@ -200,11 +202,11 @@ jobs:
- 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
@@ -231,10 +233,10 @@ jobs:
asset_content_type: application/zip
build-sd:
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: Make /opt writable
@@ -245,7 +247,7 @@ jobs:
unzip -q cegcc.zip
cp -r cegcc /opt/
- 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 kpartx build-essential bison flex libncurses5-dev gcc-arm-linux-gnueabi qemu-user-static debootstrap
- name: Configure for Linux
@@ -253,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
@@ -274,14 +280,14 @@ jobs:
asset_content_type: application/zip
build-sd-x1:
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 kpartx build-essential bison flex libncurses5-dev gcc-arm-linux-gnueabihf libssl-dev lzop qemu-user-static debootstrap
- name: Upgrade pip and setuptools
@@ -299,7 +305,7 @@ jobs:
- name: Build Linux
run: make lbuild
- name: Build Debian Root
run: make brainux
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\//}

3
.gitmodules vendored
View File

@@ -13,3 +13,6 @@
[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
View 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.

View File

@@ -135,30 +135,52 @@ lilobuild:
liloclean:
make -C ./brainlilo clean
brainux:
@if [ "$(shell uname)" != "Linux" ]; then \
echo "Debootstrap is only available in Linux!"; \
exit 1; \
fi
sudo mkdir -p brainux
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=$(ROOTFS_CROSS) --foreign buster brainux/; \
sudo debootstrap --arch=$(ROOTFS_CROSS) --foreign trixie brainux/; \
else \
sudo debootstrap --arch=$(ROOTFS_CROSS) --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
./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:
@@ -167,7 +189,7 @@ 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:

View File

@@ -94,8 +94,8 @@ Build Linux
1. Confirm that `linux-brain/arch/arm/boot/zImage` exists.
Bootstrap Debian 11 (bullseye)
------------------------------
Build a Debian rootfs
---------------------
1. Run `make ldefconfig lbuild`.
@@ -107,9 +107,23 @@ Bootstrap Debian 11 (bullseye)
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 using gcc 10 for host compiler, `make ubuild` may fail.
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

1
buildroot Submodule

Submodule buildroot added at cf3ea90108

View 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.

View 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.

Binary file not shown.

View 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.

Binary file not shown.

View 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.

Binary file not shown.

15
docs/knowledge/AGENTS.md Normal file
View 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".

View 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
View 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.

View File

@@ -5,13 +5,16 @@ 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 "g5300" "sh1" "sh2" "sh3" "sh4" "sh5" "sh6" "sh7"; do
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
@@ -19,9 +22,11 @@ for i in "g5300" "sh1" "sh2" "sh3" "sh4" "sh5" "sh6" "sh7"; do
${REPO}/nkbin_maker/bsd-ce ${REPO}/u-boot-brain/u-boot.bin
case $i in
"g5300")
"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;;
@@ -34,7 +39,7 @@ for i in "g5300" "sh1" "sh2" "sh3" "sh4" "sh5" "sh6" "sh7"; do
esac
done
dd if=/dev/zero of=${IMG} bs=1M count=3072
dd if=/dev/zero of=${IMG} bs=1M count=${SIZE_M}
START1=2048
SECTORS1=$((1024 * 1024 * 64 / 512))
@@ -49,7 +54,7 @@ sfdisk ${IMG} < ${WORK}/part.sfdisk
sudo kpartx -av ${IMG}
LOOPDEV=$(losetup -l | grep sd.img | grep -o 'loop.' | tail -n 1)
LOOPDEV=$(losetup -l | grep ${IMG_NAME} | grep -o 'loop.' | tail -n 1)
sudo mkfs.fat -n boot -F32 -v -I /dev/mapper/${LOOPDEV}p1
sudo mkfs.ext4 -L rootfs /dev/mapper/${LOOPDEV}p2
@@ -58,6 +63,8 @@ mkdir -p ${WORK}/p1 ${WORK}/p2
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-pw*.dtb ${WORK}/p1/
sudo mkdir -p ${WORK}/p1/nk
@@ -71,13 +78,13 @@ 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 -d ${REPO}/image/exeopener.exe.gz
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}/brainux/* ${WORK}/p2/
sudo cp -ra ${REPO}/${ROOTFS}/* ${WORK}/p2/
sudo umount ${WORK}/p1 ${WORK}/p2
sudo kpartx -d ${IMG}

10
os-brainux/override-pre.sh Executable file
View 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

View File

@@ -5,10 +5,8 @@ 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

View File

@@ -1,2 +0,0 @@
Brainux GNU/Linux 10 \n \l

View File

@@ -1 +0,0 @@
Brainux GNU/Linux 10

View 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

View File

@@ -0,0 +1,10 @@
[Unit]
Description=Mount boot partition
[Mount]
What=/dev/mmcblk1p1
Where=/boot
Options=ro
[Install]
WantedBy=multi-user.target

View File

@@ -0,0 +1,9 @@
[Unit]
Description=Enable Ethernet USB Gadget
[Service]
Type=oneshot
ExecStart=/usr/bin/enable_ethernet_gadget
[Install]
WantedBy=multi-user.target

View 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

View File

@@ -1,9 +0,0 @@
PRETTY_NAME="Brainux GNU/Linux 11 (bullseye)"
NAME="Brainux GNU/Linux"
VERSION_ID="11"
VERSION="11 (bullseye)"
VERSION_CODENAME=bullseye
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"

View File

@@ -20,12 +20,12 @@ else
fi
cat <<EOF > /etc/apt/sources.list
deb http://${REPO}/debian bullseye main contrib non-free
deb-src http://${REPO}/debian bullseye main contrib non-free
deb http://${REPO}/debian bullseye-updates main contrib non-free
deb-src http://${REPO}/debian bullseye-updates main contrib non-free
deb http://${REPO_SECURITY}/debian-security bullseye-security/updates main contrib non-free
deb-src http://${REPO_SECURITY}/debian-security bullseye-security/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
@@ -55,10 +55,10 @@ echo "brain" > /etc/hostname
# Install packagecloud repository
# Reference: https://packagecloud.io/brainhackers/brainux/install
# curl: downloads the GPG key from packagecloud
# curl, ca-certificates: downloads the GPG key from packagecloud
# gnupg, debian-archive-keyring: packagecloud verification dependency
DEBIAN_FRONTEND=noninteractive \
apt install -y curl gnupg debian-archive-keyring
apt install -y curl ca-certificates gnupg debian-archive-keyring
# apt-transport-https can be installed after debian-archive-keyring being installed
DEBIAN_FRONTEND=noninteractive \
@@ -80,31 +80,31 @@ 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 xserver-xorg-input-evdev xinput-calibrator xorg-dev x11-apps xinit \
xserver-xorg xserver-xorg-video-fbdev xserver-xorg-dev xserver-xorg-input-evdev xinput-calibrator xorg-dev x11-apps x11-ico-dvd xinit \
jwm \
weston xwayland \
bash tmux vim htop \
midori pcmanfm lxterminal xterm gnome-terminal fbterm uim-fep uim-anthy fonts-noto-cjk \
dbus udev alsa-utils usbutils iw fake-hwclock\
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 wget git \
network-manager zip neofetch sl python3-numpy ipython3 netsurf-gtk fcitx-anthy
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
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 https://github.com/nullgemm/ly.git
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
@@ -113,7 +113,7 @@ systemctl enable ly
install -m 0777 -d /etc/X11/xorg.conf.d
# Fix Midori launch failure
sudo update-mime-database /usr/share/mime
update-mime-database /usr/share/mime
# Setup users
adduser --gecos "" --disabled-password --home /home/user user
@@ -135,13 +135,19 @@ 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 bullseye main contrib non-free
deb-src http://deb.debian.org/debian bullseye main contrib non-free
deb http://deb.debian.org/debian bullseye-updates main contrib non-free
deb-src http://deb.debian.org/debian bullseye-updates main contrib non-free
deb http://deb.debian.org/debian-security bullseye-security/updates main contrib non-free
deb-src http://deb.debian.org/debian-security bullseye-security/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

View 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

View File

@@ -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.