Skip to content

Commit b2405d1

Browse files
committed
nextthing/chip: init
1 parent f4c4c2c commit b2405d1

10 files changed

Lines changed: 466 additions & 0 deletions

File tree

README.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -410,6 +410,8 @@ See code for all available configurations.
410410
| [Minisforum V3](minisforum/v3) | `<nixos-hardware/minisforum/v3>` | `minisforum-v3` |
411411
| [MNT Reform with RK3588 module](mnt/reform/rk3588) | `<nixos-hardware/mnt/reform/rk3588` | `mnt-reform-rk3588` |
412412
| [MECHREVO Yilong15Pro](mechrevo/GM5HG0A) | `<nixos-hardware/mechrevo/GM5HG0A>` | `mechrevo-gm5hg0a` |
413+
| [NextThing C.H.I.P](nextthing/chip) | `<nixos-hardware/nextthing/chip>` | `nextthing-chip` |
414+
| [NextThing PocketCHIP](nextthing/chip/pocketchip) | `<nixos-hardware/nextthing/chip/pocketchip>` | `nextthing-chip-pocketchip` |
413415
| [NXP iMX8 MPlus Evaluation Kit](nxp/imx8mp-evk) | `<nixos-hardware/nxp/imx8mp-evk>` | `nxp-imx8mp-evk` |
414416
| [NXP iMX8 MQuad Evaluation Kit](nxp/imx8mq-evk) | `<nixos-hardware/nxp/imx8mq-evk>` | `nxp-imx8mq-evk` |
415417
| [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
@@ -381,6 +381,8 @@
381381
msi-gl62 = import ./msi/gl62;
382382
msi-gl65-10SDR-492 = import ./msi/gl65/10SDR-492;
383383
msi-prestige-15-a10sc = import ./msi/prestige/15-a10sc;
384+
nextthing-chip = import ./nextthing/chip;
385+
nextthing-chip-pocketchip = import ./nextthing/chip/pocketchip;
384386
nxp-imx8mp-evk = import ./nxp/imx8mp-evk;
385387
nxp-imx8mq-evk = import ./nxp/imx8mq-evk;
386388
nxp-imx8qm-mek = import ./nxp/imx8qm-mek;

nextthing/chip/README.md

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

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/default.nix
25+
nixpkgs.overlays = lib.mkBefore [
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: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
{
2+
imports = [
3+
./common.nix
4+
./bluetooth.nix
5+
./nand.nix
6+
];
7+
}

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)