Skip to content

Commit 332a98c

Browse files
committed
nextthing/chip: init
1 parent 2d4b471 commit 332a98c

10 files changed

Lines changed: 465 additions & 0 deletions

File tree

README.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -404,6 +404,8 @@ See code for all available configurations.
404404
| [Minisforum V3](minisforum/v3) | `<nixos-hardware/minisforum/v3>` | `minisforum-v3` |
405405
| [MNT Reform with RK3588 module](mnt/reform/rk3588) | `<nixos-hardware/mnt/reform/rk3588` | `mnt-reform-rk3588` |
406406
| [MECHREVO Yilong15Pro](mechrevo/GM5HG0A) | `<nixos-hardware/mechrevo/GM5HG0A>` | `mechrevo-gm5hg0a` |
407+
| [NextThing C.H.I.P](nextthing/chip) | `<nixos-hardware/nextthing/chip>` | `nextthing-chip` |
408+
| [NextThing PocketCHIP](nextthing/chip/pocketchip) | `<nixos-hardware/nextthing/chip/pocketchip>` | `nextthing-chip-pocketchip` |
407409
| [NXP iMX8 MPlus Evaluation Kit](nxp/imx8mp-evk) | `<nixos-hardware/nxp/imx8mp-evk>` | `nxp-imx8mp-evk` |
408410
| [NXP iMX8 MQuad Evaluation Kit](nxp/imx8mq-evk) | `<nixos-hardware/nxp/imx8mq-evk>` | `nxp-imx8mq-evk` |
409411
| [Hardkernel Odroid HC4](hardkernel/odroid-hc4/default.nix) | `<nixos-hardware/hardkernel/odroid-hc4>` | `hardkernel-odroid-hc4` |

flake.nix

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -375,6 +375,8 @@
375375
msi-gs60 = import ./msi/gs60;
376376
msi-gl62 = import ./msi/gl62;
377377
msi-gl65-10SDR-492 = import ./msi/gl65/10SDR-492;
378+
nextthing-chip = import ./nextthing/chip;
379+
nextthing-chip-pocketchip = import ./nextthing/chip/pocketchip;
378380
nxp-imx8mp-evk = import ./nxp/imx8mp-evk;
379381
nxp-imx8mq-evk = import ./nxp/imx8mq-evk;
380382
nxp-imx8qm-mek = import ./nxp/imx8qm-mek;

nextthing/chip/README.md

Lines changed: 190 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,190 @@
1+
# NextThingCo C.H.I.P / PocketCHIP
2+
3+
```nix
4+
{
5+
inputs.nixpkgs.url = "https://nixos.org/channels/nixos-25.11/nixexprs.tar.xz";
6+
inputs.nixos-hardware.url = "github:NixOS/nixos-hardware";
7+
outputs = { nixpkgs, nixos-hardware, ... }: {
8+
nixosConfigurations.ntcchip = nixpkgs.lib.nixosSystem {
9+
modules = [
10+
# If you are using C.H.I.P without PocketCHIP
11+
# nixos-hardware.nixosModules.nextthing-chip
12+
13+
# If you are using PocketCHIP
14+
nixos-hardware.nixosModules.nextthing-chip-pocketchip
15+
16+
{
17+
# Cross compilation build architecture
18+
nixpkgs.buildPlatform.system = "x86_64-linux";
19+
20+
# Don't lock yourself out!
21+
services.openssh.enable = true;
22+
users.users.root = {
23+
initialPassword = "INSECURE CHANGE ME LATER";
24+
openssh.authorizedKeys.keys = [ "..." ];
25+
};
26+
networking.wireless.enable = true;
27+
}
28+
];
29+
};
30+
};
31+
}
32+
```
33+
34+
## Try NixOS without wiping the stock OS
35+
36+
Build the image, then flash it to a USB thumbdrive:
37+
38+
```shellsession
39+
$ nix build .#nixosConfigurations.ntcchip.config.system.build.sdImage -o result-image -vL
40+
$ zstdcat ./result-image/sd-image/*.img.zst | sudo dd of=/dev/sdb status=progress
41+
```
42+
43+
(It's called `sdImage` but we are not going to flash it to an SD card, just utilizing the `sdImage` infrastructure to build a flashable image.)
44+
45+
Plug the thumbdrive to your CHIP. Now we need to enter the "FEL mode". This can be achieved by connecting a jumper wire between the "FEL" pin and "GND" before boot, or pressing the `Reboot to FEL mode` button on the stock OS.
46+
47+
Now we can build our version of the bootloader and boot from it:
48+
49+
```shellsession
50+
$ nix build .#nixosConfigurations.ntcchip.config.system.build.uboot -o result-uboot -vL
51+
$ nix-shell -p sunxi-tools
52+
[nix-shell]$ sudo sunxi-fel uboot ./result-uboot/u-boot-sunxi-with-spl.bin
53+
```
54+
55+
The `sunxi-fel` command can fail complaining `ERROR: Allwinner USB FEL device not found!`. Simply try rerunning the command a few times more.
56+
57+
## Install U-Boot to NAND
58+
59+
The Allwinner R8 SoC itself can boot from NAND or SD cards (on PF or PC pins). However, this device does not have an SD card slot. In theory you could [add an SD card slot](https://byteporter.com/ntc-chip-micro-sd-slot/), but that's on the PE pins and the SoC cannot boot from it.
60+
61+
To make it boot without the help of a computer, we must install our bootloader to NAND. (WARNING: THIS WILL WIPE YOUR STOCK OS!)
62+
63+
Connect a USB-to-UART dongle to your CHIP (TXD->RXD, RXD->TXD, GND->GND), then run:
64+
65+
```shellsession
66+
$ nix-shell -p picocom
67+
[nix-shell]$ picocom -b 115200 /dev/ttyUSB0
68+
69+
Type [C-a] [C-h] to see available commands
70+
Terminal ready
71+
```
72+
73+
Short "FEL" to "GND", boot your CHIP. Open another shell session, run: (again these commands may fail, repeat the command when it fails)
74+
75+
```shellsession
76+
$ nix-shell -p sunxi-tools
77+
[nix-shell]$ sudo sunxi-fel spl result-uboot/sunxi-spl.bin
78+
[nix-shell]$ sudo sunxi-fel write 0x4a000000 result-uboot/u-boot-dtb.bin
79+
[nix-shell]$ sudo sunxi-fel write 0x43000000 result-uboot/sunxi-spl-with-ecc.bin
80+
[nix-shell]$ sudo sunxi-fel exe 0x4a000000
81+
```
82+
83+
Back to the `picocom` shell session, you should see this:
84+
85+
```shellsession
86+
U-Boot SPL 2025.10 (Oct 06 2025 - 19:13:09 +0000)
87+
DRAM: 512 MiB
88+
CPU: 1008000000Hz, AXI/AHB/APB: 3/2/2
89+
Trying to boot from FEL
90+
91+
92+
U-Boot 2025.10 (Oct 06 2025 - 19:13:09 +0000) Allwinner Technology
93+
94+
CPU: Allwinner A13 (SUN5I)
95+
Model: NextThing C.H.I.P.
96+
DRAM: 512 MiB
97+
Core: 62 devices, 20 uclasses, devicetree: separate
98+
WDT: Not starting watchdog@1c20c90
99+
NAND: 0 MiB
100+
Loading Environment from nowhere... OK
101+
DDC: timeout reading EDID
102+
DDC: timeout reading EDID
103+
DDC: timeout reading EDID
104+
Setting up a 480x272 lcd console (overscan 0x0)
105+
In: serial,usbkbd
106+
Out: serial,vidconsole
107+
Err: serial,vidconsole
108+
Allwinner mUSB OTG (Peripheral)
109+
Net: using musb-hdrc, OUT ep1out IN ep1in STATUS ep2in
110+
MAC de:ad:be:ef:00:01
111+
HOST MAC de:ad:be:ef:00:00
112+
RNDIS ready
113+
eth0: usb_ether
114+
115+
starting USB...
116+
USB EHCI 1.00
117+
USB OHCI 1.0
118+
Bus usb@1c14000: 2 USB Device(s) found
119+
Bus usb@1c14400: 1 USB Device(s) found
120+
scanning usb for storage devices... 1 Storage Device(s) found
121+
Hit any key to stop autoboot: 2
122+
```
123+
124+
Hit any key before it counts to 0 and you'll enter the U-Boot shell. Run:
125+
126+
```shellsession
127+
=> nand erase.chip
128+
129+
NAND erase.chip: device 0 whole chip
130+
Skipping bad block at 0x14800000
131+
Skipping bad block at 0x15800000
132+
Skipping bad block at 0xd7c00000
133+
Skipping bbt reserved at 0xff000000
134+
Skipping bbt reserved at 0xff400000
135+
Skipping bbt reserved at 0xff800000
136+
Skipping bbt reserved at 0xffc00000
137+
138+
OK
139+
=> nand write.raw.noverify 0x43000000 0 40
140+
141+
NAND write: 1130496 bytes written: OK
142+
=> nand write.raw.noverify 0x43000000 0x400000 40
143+
144+
NAND write: 1130496 bytes written: OK
145+
=> nand write 0x4a000000 0x800000 0xc0000
146+
147+
NAND write: device 0 offset 0x800000, size 0xc0000
148+
786432 bytes written: OK
149+
=> reset
150+
resetting ...
151+
```
152+
153+
## Install rootfs to NAND
154+
155+
This is not yet implemented, primarily due to the poor MLC NAND support on mainline Linux. In theory we could use SLC emulation mode to workaround this, like what [@macromorgan did with Debian 11](https://www.reddit.com/r/ChipCommunity/comments/pwhf37/mainline_debian_working_off_nand/). However, SLC emulation reduces usable storage by half (2 GiB), while a minimal NixOS install takes around 2.6 GiB.
156+
157+
## PocketCHIP Keyboard
158+
159+
[`pocketchip.nix`](./pocketchip.nix) adds an XKB keyboard layout for PocketCHIP. It should be automatically available under Xorg and Linux console. For Wayland composers, you have to configure it manually:
160+
161+
### Sway
162+
163+
```
164+
input "1:1:tca8418" {
165+
xkb_layout us+pocketchip
166+
}
167+
```
168+
169+
### Niri
170+
171+
```kdl
172+
input {
173+
keyboard {
174+
xkb {
175+
layout "us+pocketchip"
176+
}
177+
}
178+
}
179+
```
180+
181+
The Home/Power button sends `XF86PowerOff`. You can `disable-power-key-handling`, then bind it to something else:
182+
183+
```kdl
184+
input {
185+
disable-power-key-handling
186+
}
187+
binds {
188+
XF86PowerOff repeat=false { toggle-overview; }
189+
}
190+
```

nextthing/chip/bluetooth.nix

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
{ lib, ... }:
2+
3+
{
4+
# RTl8723BS Bluetooth
5+
boot.kernelPatches = [
6+
{
7+
name = "bt-hciuart-rtl";
8+
patch = null;
9+
structuredExtraConfig.BT_HCIUART_RTL = lib.kernel.yes;
10+
}
11+
];
12+
13+
# Load WiFi driver earlier to prevent race-conditions with Bluetooth driver
14+
boot.initrd.availableKernelModules = [
15+
"r8723bs"
16+
"libarc4"
17+
"cfg80211"
18+
];
19+
}

nextthing/chip/common.nix

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
{ pkgs, lib, ... }:
2+
3+
{
4+
nixpkgs.hostPlatform.system = "armv7l-linux";
5+
6+
boot.loader.grub.enable = lib.mkDefault false;
7+
boot.loader.generic-extlinux-compatible.enable = lib.mkDefault true;
8+
9+
hardware.deviceTree.name = lib.mkDefault "sun5i-r8-chip.dtb";
10+
11+
# PMIC driver is required for the USB PHY to function. Critical for USB boot
12+
# platform 1c14000.usb: deferred probe pending: platform: supplier 1c13400.phy not ready
13+
boot.initrd.availableKernelModules = [
14+
# CONFIG_AXP20X_ADC=m
15+
"axp20x_adc"
16+
"axp20x_usb_power"
17+
"axp20x_battery"
18+
"axp20x_ac_power"
19+
];
20+
21+
# Workaround random freezes
22+
powerManagement.cpuFreqGovernor = lib.mkDefault "performance";
23+
24+
# Using overlays here so we can modularly override it in nand.nix and pocketchip.nix
25+
nixpkgs.overlays = [
26+
(final: _prev: {
27+
ubootCHIP = final.buildUBoot {
28+
defconfig = "CHIP_defconfig";
29+
extraMeta.platforms = [ "armv7l-linux" ];
30+
filesToInstall = [
31+
"u-boot-sunxi-with-spl.bin"
32+
];
33+
};
34+
})
35+
];
36+
system.build.uboot = lib.mkDefault pkgs.ubootCHIP;
37+
38+
# Mali 400 GPU
39+
hardware.graphics.enable = lib.mkDefault true;
40+
}

nextthing/chip/default.nix

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
{
2+
imports = [
3+
./common.nix
4+
./bluetooth.nix
5+
./image.nix
6+
./nand.nix
7+
];
8+
}

nextthing/chip/image.nix

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
# We are not going to flash it to an SD card, just utilizing the sdImage infrastructure to build a flashable image
2+
3+
{ config, modulesPath, ... }:
4+
5+
{
6+
imports = [
7+
"${modulesPath}/installer/sd-card/sd-image.nix"
8+
];
9+
10+
sdImage = {
11+
populateRootCommands = ''
12+
mkdir -p ./files/boot
13+
${config.boot.loader.generic-extlinux-compatible.populateCmd} -c ${config.system.build.toplevel} -d ./files/boot
14+
'';
15+
populateFirmwareCommands = "";
16+
};
17+
}

nextthing/chip/nand.nix

Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
{ pkgs, ... }:
2+
3+
let
4+
dtsText = ''
5+
&nfc {
6+
pinctrl-names = "default";
7+
pinctrl-0 = <&nand_pins &nand_cs0_pin &nand_rb0_pin>;
8+
status = "okay";
9+
#address-cells = <1>;
10+
#size-cells = <0>;
11+
nand@0 {
12+
reg = <0>;
13+
allwinner,rb = <0>;
14+
nand-ecc-mode = "hw";
15+
nand-ecc-maximize;
16+
nand-on-flash-bbt;
17+
};
18+
};
19+
'';
20+
dtsiFile = pkgs.writeText "enable-nand.dtsi" dtsText;
21+
22+
mtdparts = "4m(spl),4m(spl-backup),4m(uboot),4m(env),-(UBI)";
23+
in
24+
25+
{
26+
nixpkgs.overlays = [
27+
(_final: prev: {
28+
ubootCHIP = prev.ubootCHIP.override (old: {
29+
filesToInstall = old.filesToInstall ++ [
30+
"spl/sunxi-spl-with-ecc.bin"
31+
"u-boot-dtb.bin"
32+
"spl/sunxi-spl.bin"
33+
];
34+
extraConfig = (old.extraConfig or "") + ''
35+
CONFIG_CMD_MTD=y
36+
CONFIG_CMD_MTDPARTS=y
37+
CONFIG_MTDIDS_DEFAULT="nand0=sunxi-nand.0"
38+
CONFIG_MTDPARTS_DEFAULT="mtdparts=sunxi-nand.0:${mtdparts}"
39+
40+
CONFIG_MTD=y
41+
CONFIG_DM_MTD=y
42+
CONFIG_MTD_RAW_NAND=y
43+
CONFIG_SYS_NAND_USE_FLASH_BBT=y
44+
CONFIG_SYS_NAND_BLOCK_SIZE=0x400000
45+
CONFIG_SYS_NAND_PAGE_SIZE=0x4000
46+
CONFIG_SYS_NAND_OOBSIZE=0x500
47+
'';
48+
prePatch = (old.prePatch or "") + ''
49+
cat ${dtsiFile} >> ./dts/upstream/src/arm/allwinner/sun5i-r8-chip.dts
50+
'';
51+
});
52+
})
53+
];
54+
55+
hardware.deviceTree.overlays = [
56+
{
57+
name = "enable-nand";
58+
dtsText = ''
59+
/dts-v1/;
60+
/plugin/;
61+
/ {
62+
compatible = "nextthing,chip";
63+
};
64+
${dtsText}
65+
'';
66+
}
67+
];
68+
69+
boot.kernelParams = [
70+
"mtdparts=1c03000.nand-controller:${mtdparts}"
71+
];
72+
73+
environment.systemPackages = [
74+
pkgs.mtdutils
75+
];
76+
}

0 commit comments

Comments
 (0)