In 012. Debian on the Lenovo 300e 2nd-gen arm64 Chromebook I bought a laptop I thought was this one and in 012a. Installing Debian on the Lenovo 300e 2nd-gen Chromebook (Intel) I made it normal. Now I have a celeron laptop for some reason.
Well, the reason is that Lenovo makes three identical laptops, as listed by Chromium OS > Developer Information for Chrome OS Devices[orig. arch.]:
- Release
- 27 February 2019
- 1 March 2019
- 28 February 2020
- OEM
- Lenovo
- Lenovo
- Lenovo
- Model
- Lenovo 300e Chromebook 2nd Gen (MTK)
- Lenovo 300e Chromebook 2nd Gen (Intel)
- Lenovo 300e Chromebook 2nd Gen AMD
- Code name
- Sycamore360
- Phaser360
- Treeya360
- Board name(s)
- hana
- Octopus
- Grunt
- Base board
- oak
- octopus
- User ABI
- arm
- x86_64
- x86_64
- Kernel
- 3.18
- 4.14
- 4.14
- Kernel ABI
- aarch64
- x86_64
- x86_64
- Platform
- MT8173
- Gemini Lake
- Stoney Ridge
- Form Factor
- Chromebook
- Convertible
- Convertible
- First Release
- R72
- R72
- R80
compare this to what Lenovo product pages call them:
- Branding
- 300e Chromebook 2nd Gen (11.6") Laptop
- 300e Chromebook 2nd Gen (11.6") Laptop
- 300e Chromebook 2nd Gen (11.6”, AMD)
- Google summary and "product not available" popup
- Lenovo 300e Chromebook (2nd Gen, MTK)
- 300e Chromebook 2nd Gen (11.6") Laptop
- New Lenovo Chromebook 300e
- Processor
- MediaTek™ 8173C (2.10GHz)
- Intel® Celeron® N4020 Processor (…)
- 7th Generation AMD A4-9120C APU (…)
and to what the bottom stickers and the "Product Specification References" (the PDFs you get in Tech Specs, More Information) call them:
- Sticker
- Lenovo 300e Chromebook 2nd Gen MTK
- Lenovo 300e Chromebook 2nd Gen
- Lenovo 300e Chromebook 2nd Gen AST
- PSRef
- Lenovo 300e Chromebook 2nd Gen MTK
- Lenovo 300e Chromebook 2nd Gen
- Lenovo 300e Chromebook 2nd Gen AST
This has to be actively-malicious behaviour on Lenovo's part. I bought my Intel (sorry, my ) 300e thinking it were the MTK one becuase it was listed thusly. The sticker didn't specify any variant, but it's the first from the series so that added up. The seller had listed it as that because the only Google result for "Lenovo 300e Chromebook 2nd Gen" is the MTK-variant product page, there's no way she could've known. The variant appears to be absolute search engine poison. Or deduplicated away. Or whatever.
Also, I don't know where the ChromiumOS page got the parens around the variant designator from, or the "Intel", but they were crucial in fooling me, personally.
In an obverse vein, the "Acer Chromebook R13" (which was also under consideration this time) is a real product that the ChromiumOS page also knows about, and Acer seems to entirely and wholly deny having ever produced it – there is no mention of it on acer.com, and Google returns second-hand re-sellers exclusively.
Regardless, the search space is thus narrowed considerably, because any listing that doesn't show a clear, in-focus, readable, un-painted-over view of the bottom sticker, at least enough to make out "MTK", is right out. This means I may've missed out on some deals, but at time of writing there's all of 5 working arm64 Chromebooks in Poland for a reasonable price (defined as a hard ≤200zł (≤46€) filter).
On 2024-01-11 I bought the titular laptop for 149+10.95zł (70+22zł for one with a busted-ass screen; resp. 36.78€ and 21.15€; resp. 18.5kg and 10.6kg of kefir) for the same reason as in 012. Debian on the Lenovo 300e 2nd-gen arm64 Chromebook – as an arm64-with-CRC32 testbed.
This continues to be primarily precipitated by the chrultrabook talk, and naturally it continues to be impossible to install Debian traditionally on ARM Chromebooks. Like InstallingDebianOn/Samsung/ARMChromebook and Samsung Chromebook 2, this is "running debian on the chromebook from the μsd card, and also you can »install« by properly arranging and copying to the internal flash", even though both of them do say they're "installing" on the device when they aren't. Which is why 012a. Installing Debian on the Lenovo 300e 2nd-gen Chromebook (Intel) had "install" in the title and this doesn't.
Hopefully, instead of using unprecedented-in-the-text shell programs and methodologies that definitely make sense to the authors at the time to construct the images, I can demonstrate the final state itself (god forbid!) as well as the basis for the steps taken with no leaps of logic, so this can serve as more useful documentation.
Here we can see some obvious physical differences between these supposedly-identical laptops (barring the warranty/service seals glued to the screen): on the english keyboard, ⟵ is actually labelled backspace, ⇥ – tab, and ⇧ – shift.
Most importantly, however: there's no nose cam. What's the point of a laptop, then, honestly.
And this demonstrates a significant consumer-affecting difference, in that the holes are just different:
So this full-size computer somehow has only as much I/O as my palmtop?
The label does agree with the listing that it's MTK:
Incredible pog moment.
It appears that I'm pre-
because it booted to the developer mode warning screen that took 400 words last time –
– where two things stand out: the serial number is one triplet shorter (the Intel one had 7), and it says "Model: HANA".
One may recall from 012. Debian on the Lenovo 300e 2nd-gen arm64 Chromebook and from the tables quoted at the top of this page that the Intel-processor laptop said "Model: PHASER360". At the time I'd been expecting "Sycamore360", but due to the nomenclature scam "Phaser360" made sense.
Chrultrabook says this should be the board name, and lists Phaser360 as the board name for the 2nd-gen Intel 300e, which disagrees with the ChromiumOS-branded documentation but is internally consistent. Google-official Chromebook Help, Recover your Chromebook, Recovery option 2: Use USB drive, Step 2: Download a new copy of the OS says
- Click Select a model from a list, or type in the model number of the Chromebook you want to recover. To find this number, look at the bottom of the error message on your Chromebook screen.
and "model number" per se doesn't appear anywhere else. So everything is, as usual, at odds.
The "hana" board name appears to be shared between 9 identical devices
(the "telesu" ASUS one uses a "hana" "Base board",
all others use "oak". these appear to be unrelated hanas)
released between 2017-03-17 and 2019-12-27, which includes 300e
(first-gen), 300e 2nd Gen
, and 100e 2nd Gen
Lenovos.
There appears to be no first-generation ARM 100e variant (the Intel and AMD ones are in full swing).
This is your brain on products.
This is all the more weird because the listing proclaims it used, ✅Bios - Ok
(? shit don't got one, brother)
and ŚLADY UŻYTKOWANIA
,
but doesn't mention anything that would imply it's in developer mode.
Maybe this was done as a reset step, but there are easier and better-documented ways to do this.
Especially since the only thing attached to the laptop in the box, beside the seals,
was a long
Any modifications to the software or hardware, including attempted service, void your right to a return!
spiel, which wouldn't go well for me if I were to return it in such an overtly-"modified" state probably.
It also tries to spin
✅Bateria trzyma minimalnie 1h
as
baterie sprawdzamy pod obciążeniem
but one has to wonder how this could be done to a machine in freshly-triggered developer mode.
So with the innards appearing to be some ARM board, and a manually-confirmed boot 🙄 the magical OOBE control doesn't appear to've been clicked, and clicking through it and through the root passphrase popup was so mindless and indistinguishable from the last time I forgot to shoot jpegs. Except that the throbbers appear to be embedded videos instead of animations, but.
Beside the similarly-decroted kernel version, note how this doesn't actually say what the CPU… is? Like its self-branding? Apparently this information doesn't exist in the CPU, or exists only to the extent of the same two integers that /proc/cpuinfo shows –
– and you (or lscpu
) can look them up in a table.
The best approximation of a CPU/device ID I found in /proc/device-tree/compatible, which listed google,hana-rev{6,5,4,3,2,1}, google,hana, and mediatek,mt8173. Note the lack of Lenovo's C after the model. I haven't found it attested anywhere in proc/sysfs.
The only product-level branding I found in /sys/firmware/vpd/ro/
(Vital/Vendor Product Data
[orig. arch.] – yes, the documentation can't decide)
as model_name:
"Lenovo 300e Chromebook 2nd Gen MTK" (which miraculously agrees with Lenovo's marketing and the outside!),
and customization_id matching the ChromiumOS "Code name" with "OEM1-SYCAMORE360".
There's also 64 bytes of hex in a stable_device_secret_DO_NOT_SHARE in there. idk why. funny, though
Another model difference is that on the Intel platform the μSD card slot showed up as SCSI (undoubtedly through a USB adapter) and on this one it's an MMC device, as it ought to be. Oh and the tactiles of plugging the SD card are so ass I thought it was broken before looking at the hotplugs in the dmesg.
I'd complained that no Home/End is agony, and it is, but I must not've tried 🔍 and ˂ or ˃, which does just that.
Following the instruxions from /etc/issue:
If you are having trouble booting a self-signed kernel, you may need to enable USB booting. To do so, un the following as root: enable_dev_usb_boot
yielded
localhost ~ # enable_dev_usb_boot
SUCCESS: Booting any self-signed kernel from SSD/USB/SDCard slot is enabled.
Insert bootable media into USB / SDCard slot and press Ctrl-U in developer
screen to boot your self-signed image.
and it do b honkin
which one has to assume is good, given the lack of priors in this domain.
To validate this suspicion, I consulted /sys/firmware/log which identifies itself ас "coreboot-81de43c Mon Mar 19 23:11:07 UTC 2018 bootblock starting...", and previously the sexion headed by "Starting depthcharge on hana..." had
VbAudioOpen() - note count 5
VbBootDeveloper() - user pressed Ctrl+D; skip delay
VbBootDeveloper() - trying fixed disk
VbTryLoadKernel() start, get_info_flags=0x2
VbTryLoadKernel() found 1 disks
VbTryLoadKernel() trying disk 0
GptNextKernelEntry looking at new prio partition 2
GptNextKernelEntry s1 t0 p2
GptNextKernelEntry looking at new prio partition 4
GptNextKernelEntry s1 t0 p1
GptNextKernelEntry looking at new prio partition 6
GptNextKernelEntry s0 t15 p0
GptNextKernelEntry likes partition 2
Found kernel entry at 20480 size 32768
Checking key block signature...
- sig_size=512, expecting 512 for algorithm 8
In RSAVerify(): Padding check failed!
In RSAVerify(): Hash check failed!
Invalid key block signature.
whereas now it saw the prefix of
VbAudioOpen() - note count 5
VbBootDeveloper() - user pressed Ctrl+U; try USB
vboot_draw_screen: screen=0x0 locale=3
VbTryLoadKernel() start, get_info_flags=0x1
VbTryLoadKernel() found 1 disks
VbTryLoadKernel() trying disk 0
Primary GPT header is invalid
Secondary GPT header is invalid
Unable to read GPT data
VbTryLoadKernel() LoadKernel() = 65551
VbSetRecoveryRequest(91)
VbBootDeveloper() - no kernel found on USB
rt5645_device_init completed, codec = 5650
VbSetRecoveryRequest(0)
vboot_draw_screen: screen=0x101 locale=3
VbBootDeveloper() - user pressed Ctrl+D; skip delay
and presumably the screen being 0 is why it flashes black.
I can't seem to find, like, first-party documentation about what a "valid" header would be.
Well, about what this bootloader looks for, in any way whatever.
It's either upstream's
Note: Only CrOS formatted images will boot via USB. Other Linux distros will not work.
[orig. arch.]
(abject lie as proven by the guides)
or the guides which are "do this".
Though, actually, it does seem like, for that laptop exclusively, Chromium OS > Developer Information for Chrome OS Devices > Samsung ARM Chromebook, Firmware, Boot Sequence[orig. arch.] reads:
- power on
- the CPU will execute u-boot from the read-only on-board SPI flash
- u-boot will look at the GPT layout on the 16 GiB SSD (connected via eMMC)
- search for the firmware partition marked active and try to boot the u-boot that lives there
- u-boot will look at the GPT layout
- search for the Linux kernel partition marked active and try to boot the kernel that lives there
- Linux kernel boots from its corresponding rootfs partition
- profit!
Out of the 30 internal links from the device table[orig. arch.] (discounting those that don't work or redirect),
Before you start fiddling with your own builds it is strongly recommend to(sic!) (mentions ChromiumOS images exclusively)
unique requirements for entering recovery mode!, so it's the most different one
and
Cr-48 Chrome Notebook Developer Information[orig. arch.]
is the oldest, so it actually has an itemised guide called How to boot your own (non-Chromium OS) image from USB which nonetheless starts with
(Note: This part is outdated: make_developer_script_runner.sh does not exist anymore)
.
Even then, a sub-Create a USB disk that will boot another operating system-sexion consists exclusively of
TODO: This should be possible for someone skilled in the art of Linux. The above instructions tell you how to run any arbitrary Linux program, and (with root access) you should be able to do pretty much anything you want. It would be nice to get some good instructions here, though.
which actually makes sense, since the "How to" sexion doesn't actually appear to do anything?
except download a "mario_recovery_kernel"(‽) from a Google CDN,
prepare an exec sh
"developer script", and combine them it into a ChromeOS-equivalent image?
which sure as hell doesn't look like non-Chromium OS
.
Naturally two different ways to make an actual ChromiumOS image are outlined, in spite of the page linking to the developer documentation constantly.
Even out of our lucky trio, the
Samsung ARM Chromebook[orig. arch.]
is the only one with the bullet list.
Even then, how are you supposed to interpret it?
How can a partition be marked "active"?
Is the "Linux kernel partition" actually "ChromeOS kernel" (FE3A2A5D-4F32-41A7-B725-ACCC3285A309),
the only kernel
-matching UUID bookworm fdisk knows about?
Assuming the image has to support the Linux boot protocol, what parameters does it pass?
Are there any other restrixions?
The SD card I put in to test was actually MBR-formatted, so this probably explains why "{Primary,Secondary} GPT header is invalid". Indeed, re-making it as GPT (with the only partition being a VFAT "Linux filesystem" (0FC63DAF-8483-4772-8E79-3D69D8477DE4) to copy logs to), I got:
VbBootDeveloper() - user pressed Ctrl+U; try USB
VbTryLoadKernel() trying disk 0
GptNextKernelEntry no more kernels
VbTryLoadKernel() LoadKernel() = 65551
VbSetRecoveryRequest(91)
VbBootDeveloper() - no kernel found on USB
Amazing, incredible, it enumerated no kernels this time. Emboldened by this, I made two kernel partitions, one with the flag it hints at (it's wrong of course, "active partitions" are an MBR thing), accd'g to fdisk:
Device Size Type Name Attrs
/dev/mmcblk1p1 200M Linux filesystem
/dev/mmcblk1p2 30M ChromeOS kernel
/dev/mmcblk1p3 30M ChromeOS kernel LegacyBIOSBootable
and rebooting
VbTryLoadKernel() trying disk 0
GptNextKernelEntry looking at new prio partition 2
GptNextKernelEntry s0 t0 p0
GptNextKernelEntry looking at new prio partition 3
GptNextKernelEntry s0 t0 p0
GptNextKernelEntry no more kernels
VbTryLoadKernel() LoadKernel() = 65551
and the flag doesn't appear to change anything, neither the iteration order nor the solaris-disk-lookin-ass statussies. (rember that it "likes" internal mmc partition 2 with "s1 t0 p2")
Just copying an arm64 kernel doesn't work. Not altogether unexpected, given that mmcblk0p2 starts with
000000 43 48 52 4f 4d 45 4f 53 02 00 00 00 01 00 00 00 >CHROMEOS........<
(with an obvious 64k initial block boundary) and binwalk finds an LZ4 blob at 0x100C8 which decompresses to a kernel image.
This puts the "search for the Linux kernel" paragraph at an 0/2 – the legacy-bootable flag doesn't do anything, and the partition contains a ChromeOS boot bundle, not a kernel.
Not altogether helpful, except I can grep out the full branding string –
Linux version 4.19.272-14690-gda0c1392f4b0 (chrome-bot@chromeos-release-builder-us-central1-b-x32-59-cvr8) (Chromium OS 16.0_pre475826_p20230103-r7 clang version 16.0.0 (/var/tmp/portage/sys-devel/llvm-16.0_pre475826_p20230103-r7/work/llvm-16.0_pre475826_p20230103/clang 11897708c0229c92802e747564e7c34b722f045f)) #1 SMP PREEMPT Sun Apr 16 19:38:55 PDT 2023
Which is somehow 2023-04 on this 2019 laptop? And a ChromiumOS prelease? Maybe this is why it was in developer mode.
Device Start Sectors Size Type Name Attrs
mmcblk0p11 64 16384 8M unknown RWFW Type-UUID=CAB6E88E-ABF3-4102-A07A-D4BB9BE3C1D3
mmcblk0p6 16448 1 512B ChromeOS kernel KERN-C GUID:52,53,54,55
mmcblk0p7 16449 1 512B ChromeOS root fs ROOT-C
mmcblk0p9 16450 1 512B ChromeOS reserved reserved
mmcblk0p10 16451 1 512B ChromeOS reserved reserved
mmcblk0p2 20480 32768 16M ChromeOS kernel KERN-A GUID:49,56
mmcblk0p4 53248 32768 16M ChromeOS kernel KERN-B GUID:48,56
mmcblk0p8 86016 32768 16M Microsoft basic data OEM
mmcblk0p12 249856 65536 32M EFI System EFI-SYSTEM LegacyBIOSBootable
mmcblk0p5 315392 4194304 2G ChromeOS root fs ROOT-B
mmcblk0p3 4509696 4194304 2G ChromeOS root fs ROOT-A
mmcblk0p1 8704000 52359120 25G Microsoft basic data STATEmmcblk0p1 8704000 52359120 25G Microsoft basic data STATE
mmcblk0p2 20480 32768 16M ChromeOS kernel KERN-A GUID:49,56
mmcblk0p3 4509696 4194304 2G ChromeOS root fs ROOT-A
mmcblk0p4 53248 32768 16M ChromeOS kernel KERN-B GUID:48,56
mmcblk0p5 315392 4194304 2G ChromeOS root fs ROOT-B
mmcblk0p6 16448 1 512B ChromeOS kernel KERN-C GUID:52,53,54,55
mmcblk0p7 16449 1 512B ChromeOS root fs ROOT-C
mmcblk0p8 86016 32768 16M Microsoft basic data OEM
mmcblk0p9 16450 1 512B ChromeOS reserved reserved
mmcblk0p10 16451 1 512B ChromeOS reserved reserved
mmcblk0p11 64 16384 8M unknown RWFW Type-UUID=CAB6E88E-ABF3-4102-A07A-D4BB9BE3C1D3
mmcblk0p12 249856 65536 32M EFI System EFI-SYSTEM LegacyBIOSBootable
This is how the internal flash is partitioned, Shockingly, this just about matches the layout I saw in 012a. Installing Debian on the Lenovo 300e 2nd-gen Chromebook (Intel), but notice how the logical partitions are in, effectively, random order.
A few things jump out here: the four 1-sector parts are all zero-filled. Why aren't they simply Not There? who knows.
Partition 8 (OEM
) is a completely empty ext4, mounted on /usr/share/oem under ChromeOS.
The purpose of this is similarly unclear.
Partition 11 is of a type unknown to the fdisk distributed with the system.
The only non-forum non-code Google result
(note also how it's to-a-commit instead of main which reads, to me, like "no public links to this at all")
for the UUID calls it ChromeOS firmware
.
I've taken the liberty
to teach fdisk about this
(made significantly more annoying by the userland being fucking armhf; admittedly they do say
, but the "arm" ABI is hard-dead, so).
This would presumably be where the second U-Boot is chainloaded from (RWFW
– read/writeable firmware?).
But's also zero-filled, so the first 10M of the flash is zeroes.
Partition 12 (EFI-SYSTEM
) isn't actually,
but it is a 6M-used FAT with
a 110B u-boot/boot.scr.uimg identified as "u-boot legacy uImage" whose semantic content appears to be
setenv kernelpart 2
, setenv rootpart 3
and a vmlinuz.uimg.A which is a device tree – nice, but we already have a device tree in procfs. Are they any different?
Yeah. This device tree has a kernel inside. Not as a joke, but as
/dts-v1/;
/ {
timestamp = <0x5cc03b66>;
description = "Chrome OS kernel image with one or more FDT blobs";
#address-cells = <0x01>;
images {
kernel@1 {
data = <0x4224d18 0x6470b909 0x841600c1 0x4d5a0091 …
type = "kernel_noload";
arch = "arm64";
os = "linux";
compression = "lz4";
load = <0x00>;
entry = <0x00>;
};
with 1448960 integers, for a total of 5660KiB. There's also a few description = "mt8173-oak-rev5.dtb";-style fdt@N entries but they all add up to 350k. And they're all SHA1-checksummed but the kernel isn't. The branding for this one is
Linux version 3.18.0-12341-g91e1dfd (chrome-bot@chromeos-factory-us-central1-b-x32-31-497v) (gcc version 4.9.x 20150123 (prerelease) (4.9.2_cos_gg_2d511e9_4.9.2-r122) ) #1 SMP PREEMPT Wed Apr 24 03:31:08 PDT 2019
which matches the shipped version documented in the big table; conversely, KERN-B is
Linux version 4.19.272-14688-g23c63bd32a8a (chrome-bot@chromeos-release-builder-us-central1-c-x32-90-i5ts) (Chromium OS 16.0_pre475826_p20230103-r7 clang version 16.0.0 (/var/tmp/portage/sys-devel/llvm-16.0_pre475826_p20230103-r7/work/llvm-16.0_pre475826_p20230103/clang 11897708c0229c92802e747564e7c34b722f045f)) #1 SMP PREEMPT Wed Apr 5 00:00:28 PDT 2023
which is 2 commits/11 days behind the KERN-A from the previous sexion, suggesting that this full 2023 ChromiumOS pre-release image(?) randomly includes a completely unrelated 2019 kernel.
This system's /proc/device-tree/compatible precisely matches conf@9
's compatible
string,
pointing to fdt@9
, described as mt8173-elm-hana.dtb
[decompiled].
Regardless of how odd the partitioning scheme is, it high-lights type-specific bits set in the boot bundle partitions
– just copying the boot bundle to a ChromeOS kernel
partition on the SD card behaved identically to copying the raw kernel (s0 t0 p0, unchecked) –
so by exhaustively testing all the combinations, I arrived at the following table with a "fake" boot bundle (/sys/firmware/log outlined).
GptNextKernelEntry looking at new prio partition 2
GptNextKernelEntry s0 t0 p2
GptNextKernelEntry no more kernels
VbTryLoadKernel() LoadKernel() = 65551
VbSetRecoveryRequest(91)
VbBootDeveloper() - no kernel found on USB
GptNextKernelEntry looking at new prio partition 2
GptNextKernelEntry s1 t0 p0
GptNextKernelEntry no more kernels
GptNextKernelEntry looking at new prio partition 2
GptNextKernelEntry s1 t0 p2
GptNextKernelEntry likes partition 2
Found kernel entry at 411648 size 81920
Checking key block signature...
- sig_size=512, expecting 512 for algorithm 8
In RSAVerify(): Padding check failed!
In RSAVerify(): Hash check failed!
Invalid key block signature.
Verifying key block signature failed.
Checking key block hash only...
- sig_size=256, expecting 256 for algorithm 4
Kernel preamble is good.
Key block valid: 0
Combined version: 65538
- sig_size=256, expecting 256 for algorithm 4
In RSAVerify(): Hash check failed!
Kernel data verification failed.
Marking kernel as invalid.
GptNextKernelEntry looking at new prio partition 2
GptNextKernelEntry s1 t0 p2
GptNextKernelEntry no more kernels
GptNextKernelEntry looking at new prio partition 2
GptNextKernelEntry s1 t0 p1
GptNextKernelEntry likes partition 2
…
GptNextKernelEntry looking at new prio partition 2
GptNextKernelEntry s1 t0 p1
GptNextKernelEntry no more kernels
If bundles copied verbatim from /dev/mmcblk0p2 are "real",
then I made "fake" by replacing the kernel with an LZ4ed Debian one
({ head -c 0x100C8 mmcblk0p2; lz4 -9 < vmlinuz-6.6.11-arm64; } > mmcblk0p2.fake
).
Booting fakes with a measurable-but-recoverable behaviour is crucial because real bundles hard-hang the system in the black screen.
According to
ChromiumOS Docs - Debug Button Shortcuts, Devices With Keyboards
there are at least a few combos that may've been able to trigger a warm re-boot, but they all start with alt+🔊
which is treated as the Magic SysRq key
– off by default, enable it yourself –
so no logs from that one.
I'm assuming it either doesn't get a rootfs or gets a bogus one, and thus panicks instantly. No log in the firmware survives the reboot, it doesn't initialise the display, and the resistors that are in stock and would let me construct the CCD cable that may show the serial console have been "in packing" for most of this week, so. idk.
Please ignore that I've now twice referenced the
Partition attributes table in the
GUID Partition Table Wikipedia article,
and the type-specific bits for ChromeOS kernel
partitions are in the ChromeOS kernel partition attributes table on the next screen down.
Still no active
marker tho.
Looks like I'd retroactively buried the lede – KERN-A and KERN-B are also in the device-tree-with-embedded-LZ4ed-kernel format.
It was very ඞ that the LZ4 blob started at 0x100C8 instead of 0x10000.
But there doesn't appear to be a rootfs designator in the device tree, or embedded into the image – not that one would be expected, given the
root=PARTUUID=uuid/PARTNROFF=1
in /proc/cmdline, and especially given the U-Boot setenv
s of {kernel,root}part
in the script.
If we are to accept booting a one-has-to-assume-backdoored kernel, and with ROOT-A and ROOT-B having no flags to distinguish them, three possibilities of picking the rootfs when USB-🙄-booting spring to mind:
ChromeOS root fs,
CHROMEOSpreamble contains the partition number,
CHROMEOSpreamble contains the partition UUID,
A quick head -c 0x10000 mmcblk0p[24] | od -tx1 | grep -wC1 cc | grep -w fe
confirms the UUID isn't there, at least not in plain.
03 and 05 also don't appear swapped at the same offsets, but who knows.
So, using the "real" boot bundle and the worst rootfs in existence (dpkg-deb -R libc6_2.38-5_arm64.deb faux-root; dpkg-deb -R dash_0.5.12-6_arm64.deb faux-root; ln faux-root/{bin/sh,sbin/init}; mkfs.ext2 -d faux-root faux-root.10M 10M) I observed a significant behavioural change: ctrl+u now goes black for precisely 5 seconds and then reboots! (Still no console so idk why it reboots, and it reboots so no log, but it's definitely doing something.) The same happens regardless of partition number, which strongly hints at option a).
(Later, further testing revealed that the rootfs is always root=PARTUUID=kernel-partition-uuid/PARTNROFF=1 – the partition one after the kernel. The partition type-UUID doesn't matter. What I was observing was either some type of kernel panic, or the bootloader picking the kernel with a partition after it. A quick check also shows that this is a kernel-only (mount(8) doesn't understand it) syntax, naturally authored by an @chromium.org address specifically for this use-case.
So: secret, fourth thing.
One could say that, knowing this, Linux kernel boots from its corresponding rootfs partition
makes sense.
But without that knowledge it means nothing at all — ½/3.)
Emboldened, I copied over the 2G ROOT-A instead at an incredible pace of 3.3M/s. (During this I discovered that if you pause the small looped MP4 of an animation on the OOBE screen, chrome goes from two processes at >80% CPU each to just one at 10%.) This yields a black screen for the same 5s,
for 3-10s, and only then a reboot, after which my accessibility settings were globally reset.
Some fiddling with that rootfs yielded
diff --no-dereference -ru {orig,new}/sbin/chromeos-boot-alert
--- orig/sbin/chromeos-boot-alert 2024-01-20 03:18:41.000000000 +0100
+++ new/sbin/chromeos-boot-alert 2024-01-20 03:22:26.000000000 +0100
@@ -151,6 +151,9 @@
# Prints message before starting to rebuild a corrupted stateful partition.
mode_self_repair() {
show_assets_message "self_repair"
+ id >> "$TTY"
+ bash < "$TTY" >> "$TTY" 2>&1 &
+ sleep 4
}
# Prints a message telling the user that developer mode has been disabled for
which was slow as shit (on the order of 2cps max input speed) and still rebooted after a few seconds, but.
The real break-through was
Only in orig/etc/init: boot-splash.conf
diff '--color=auto' --no-dereference -ru {orig,new}/etc/init/startup.conf
--- orig/etc/init/startup.conf 2023-04-17 06:31:09.000000000 +0200
+++ new/etc/init/startup.conf 2024-01-20 03:31:08.000000000 +0100
@@ -10,4 +10,5 @@
start on stopped pre-startup
-exec chromeos_startup
+#exec chromeos_startup
+exec frecon --enable-gfx --enable-vt1 --enable-vts
diff '--color=auto' --no-dereference -ru {orig,new}/etc/init/ui.conf
--- orig/etc/init/ui.conf 2023-04-17 06:26:19.000000000 +0200
+++ new/etc/init/ui.conf 2024-01-20 03:06:54.000000000 +0100
@@ -35,7 +35,7 @@
kill timeout 20 # In seconds.
# Uncomment line below to output to VT02
-#console output
+console output
# Directory where session manager logs are written and prefix of files there.
env UI_LOG_DIR=/var/log/ui
Only in new/sbin: init.new
(The ui.conf diff doesn't do anything.
The boot-splash.conf deletion may be exchanged for a startup.conf deletion instead, since it also runs frecon.
Naturally, the way to show the "ChromeOS" fade-in is by passing a tty emulator 70 PNGs, in developer mode, and keeping it running afterward.)
chromeos_startup is what triggers the self-repair message
(rendered is by pango-view
ing the background, the localised text, and the throbber to a PNG and giving those to frecon).
This yields
This high-lights the biggest issue with this system: there is no console.
This lede is buried in /proc/cmdline in the HFBITLAND sexion –
console= is provided as the first parameter.
Opening /dev/console fails with ENODEV
.
There are no framebuffers (and no loadable fbdev modules), there are no VTs.
frecon, which is what provides the pseudo-VTs, draws the teletypes (and the PNGs) by talking to the GPU directly.
As in it has /dev/dri/card2 open.
This is why the tty says it's /dev/pts/0 – it's an xterm, but drop the x.
So to answer the first question from 012a. Installing Debian on the Lenovo 300e 2nd-gen Chromebook (Intel) – TERM=xterm
because it is.
It's also horrendous and the ptys it gives you barely work (libreadline masks this in bash)
– i.a. backspace sends ^H and it's configured for the usual ^?.
One syscall to fix, too hard for this trillion-dollar startup.
This also explains why you can press ctrl+alt+←/→ (not the arrow keys)
to open "VT" 1/2, even though ←/→ are XF86Back
/XF86Forward
and not F1/F2.
Not even serial? Not even serial. My resistors'd got here and I assembled a hdctools: Chrome OS Hardware Debug & Control Tools, Closed Case Debug (CCD), Communicating with Google Security Chip(GSC), SuzyQ / SuzyQable (no, even they don't know what it is) accd'g to the instruxions in Making your own SuzyQ (though mind the referenced 22k 1% resistor not being real and the breakout they spec seemingly being american-only) more on mastussy.
Device Support says
The “Closed Case Debugging” column in the Chrome OS device list indicates whether CCD is supported. If the device is ARM, the CPU/AP UART works by default in dev mode (you should see a login prompt). x86 devices disable it[…]
which implies to me that there's some sort of activity.
And the login prompt
really smells like "you get console=ttyS0" or at least a getty thereon
(this is substantiated by opening ttyS0 working and ttyS[123] EIO
ing).
Indeed, I can debug the Intel-chipped 300e (shows the ttyUSBs, talks on all of them),
but not this one.
Why?
The device list they link to is another version of the big table cited at the top of this page.
Indeed, both agree with regards to the column I omitted – Closed Case Debugging.
The Intel 300e has a Yes
in that column. This Mediatek – nothing. No data.
So another difference between these nominally-identical laptops is that you can debug one but not the other. This one is either a black screen or you've magically done something right and you have a gterm. Of course, I tried to actually run Xorg out of a Debian chroot since there's a GPU exposed, and the best you get is
…
(==) ModulePath set to "/usr/lib/xorg/modules"
(II) The server relies on udev to provide the list of input devices.
If no devices become available, reconfigure udev or disable AutoAddDevices.
(II) Loader magic: 0x5c61bffef0
(II) Module ABI versions:
X.Org ANSI C Emulation: 0.4
X.Org Video Driver: 25.2
X.Org XInput driver : 24.4
X.Org Server Extension : 10.0
(EE) dbus-core: error connecting to system bus: org.freedesktop.DBus.Error.FileNotFound (Failed to connect to socket /run/dbus/system_bus_socket: No such file or directory)
(II) xfree86: Adding drm device (/dev/dri/card1)
(II) Platform probe for /sys/devices/platform/soc/13000000.mfgsys-gpu/drm/card1
(II) xfree86: Adding drm device (/dev/dri/card2)
(II) Platform probe for /sys/devices/platform/soc/14000000.clock-controller/drm/card2
(II) xfree86: Adding drm device (/dev/dri/card0)
(II) Platform probe for /sys/devices/platform/vgem/drm/card0
(II) no primary bus or device found
falling back to /sys/devices/platform/soc/13000000.mfgsys-gpu/drm/card1
(II) LoadModule: "glx"
(II) Loading /usr/lib/xorg/modules/extensions/libglx.so
(II) Module glx: vendor="X.Org Foundation"
compiled for 1.21.1.11, module version = 1.0.0
ABI class: X.Org Server Extension, version 10.0
(II) LoadModule: "modesetting"
(II) Loading /usr/lib/xorg/modules/drivers/modesetting_drv.so
(II) Module modesetting: vendor="X.Org Foundation"
compiled for 1.21.1.11, module version = 1.21.1
Module class: X.Org Video Driver
ABI class: X.Org Video Driver, version 25.2
(II) modesetting: Driver for Modesetting Kernel Drivers: kms
(WW) Falling back to old probe method for modesetting
(WW) Falling back to old probe method for modesetting
(II) modeset(G0): using drv /dev/dri/card2
(EE) No devices detected.
(EE)
Fatal server error:
(EE) no screens found(EE)
(EE)
Please consult the The X.Org Foundation support
at http://wiki.x.org
for help.
(EE) Please also check the log file at "/var/log/Xorg.0.log" for additional information.
(EE)
(EE) Server terminated with error (1). Closing log file.
and no, plugging in an HDMI doesn't work, it just doesn't understand the GPU or whatever. I'm no eXorgpert.
Given that neither guide mentions anything remotely close to this, one has to assume that on the "Samsung ARM Chromebook" this is simply not the case, and that it pre-dates this no-console no-framebuffer model.
This is close to as far as I can get with first-principles debugging since there just isn't really a way to do anything unless everything fully works. If only there were
like when you're bisecting rootfs bootability requirements and you find the cmdline listed in /sys/fs/pstore/console-ramoops-0 (and dmesg-ramoops-0 sometimes(?) but they're equivalent) which contains the entire console output.
(If you know what you're looking for, this is obvious – /proc/consoles consists of
pstore-1 -W- (E p a)
but It is all obvious when it is explained to you.
.)
Which is great, but only works reliably for real co-operated reboots. When you use the hard-reboot alt+⟳ combo (which Debug Button Shortcuts calls
).
you get something to the effect of (cat -A
-reformatted):
[ 0. 00000] ^Booting Linuh on physicad CPU 0x0000000000 Y0p410fd032]$
^[ 0.000000] Hifux versin. 4.!9.272-14690-gd! c13(2f4b0 (chrome-bot@chr.mdos)be,easE-bdilder^Mus%central1-b%x32-59-cvp8) (C(romIum OS 16.0_pre47^U826_p"0230^Q03-r7 clang verSHON 12.0^N0 (/va2/tmp/`ortagd/sys-deve,/l,vi)1^V.0Wpr%474826_p20230103-^R7/uorc/dLVm^M16*0_pre475826_p2023^P103/chanc 1189'708c0229c9280^RE74^W564`7c3^Pb722f045f)) "1 SMP PREEMPT Sun Apr 16 19:38:55 PDT 2023$
[ 0.000000] Machine model: COocld Hafa$
[ ^@ 0.000000L Malboried early^@optiOn 'Cnnsole'$
[ 0.0^P0000M ReSerred memory8 createD @MA memmry pool at 0x00000000b7^P0000 $ qaze 5 MiB$
[ 0&000^P00] GF*^@beserved mem: ini4ha,IzeD nOde 6pu_dma_Mem_begio.@"70000 0, compatible id shared-dma,pool$
[ ^@^@ 0*000000] pqci: probing for ck*duit method from DT.$
S ^@ 0.0000 0] psci:^@PSCIv1.0 d%tected in firMw!2e.$
[ 0,000000] psba: Usin^G standard PSAH v0.2 functioj IDr$
K 0.000000^] `sci: MIFRATE_INFO_TIPE not supported*$
[ 0.000^P00] psc!: SMC CAllinG^@Confeltion V1.1$
S ^@ 0. 00000] percpu: Embedded 24 pages/cpu R41080 r81(2 D^R9032 u98304$
[ 0.0 0000Y @etected V^IPT ^I-ca#`e .n C@^E0$
[ .000000] CPU features* en`bling workapnunD fob A^RM errata 826319, 827319, 824069^H[ 0,000000] CPU fe`turEs: enabline^@workaround fop ABM erratul 843419$
[ 0* 00000] APU feaTureS: enAbling sorkaroqnd foR ARM erratui ^X^T%719$
[^@ 0,000 00] Built 1 z/n%lists, m/bhLity^@group)nc on. Todal pages^Z^@1030656$
[ ^@ 0.000000U KernEl #/mmand^@line: crOs_seaure con^Sole5 log,Evel=7 inht=/sbin/ijit cros_recure dbM.tr!ce=0x00^V rogt=PARTUUID=fd012a^P$-54ac-dd4'-b773-73df13281aa7/PABTNROFF<0 rootvait rw dm_vdridh^N%rror_beharior=3 dm_Verity,maxZbios=-1 Dm_FerItY.dev_wAit=0 dm="1 vrokt none ro 1$0 40774^V8 veridy pay,maD=ROOT]DDV (ashtrde=#_DEV hashstart=4076468 alg=sha054 r'ot_hexdifest=59&5ac90'd@5cfa3f6fd%f15b166c94025a41ef4abfd0d)c6^Xdb6Ef4a2f62a48 salt=05e2c9a8dc172bc%efe0B899182b436bb89^V09a04^TeAbaaeb5ec07441cf2!122" nohnidrd vt.gdmbalWcqrSor_ddfault=0^@kern_guid=fd012a04-^U4ac%dd47,b573,77df1^Q381aa7 cpuidle.governor=tEo $
which, given that the power LED goes off for 573ms during this time, one has to assume is DRAM bit-rot.
As cool as observing a theoretical phenomenon everyone knows about but I never expected to see is in the home shop, it's less-than-helpful for trying to ascertain precise messages.
Debug Button Shortcuts also says
Notes:
Functionality Shortcut Warm AP reset Alt + Volume-Up + R Restart Chrome Alt + Volume-Up + X * Kernel panic/reboot Alt + Volume-Up + X + X * Reboot EC but don't boot AP Alt + Volume-Up + Down-Arrow Force EC hibernate Alt + Volume-Up + H
- AP = Application Processor; EC = Embedded Controller.
- Alt + Volume-Up is treated as the Magic SysRq key. When in Developer mode, you can enable SysRq key combinations as documented in the Linux kernel docs.
and, naturally, I'd tried to apply this for a long time, with alt, the volume up button on the side, and a magick, and it never worked.
It is only much later that it'd occurred to me that by Volume-Up
they may mean the 🔊 on the keyboard.
That does work! and as long as the ChromiumOS kernel is running,
alt+🔊+b reboots
and preserves the pstore log in tact,
while alt+🔊+c crashes and preserves the pstore log in tact.
But alt+🔊+r also reboots with pstore ok,
and not only is that not a useful SysRq (Turns off keyboard raw mode
),
but it works regardless of a kernel running or said kernel having any hardware.
So this is documented as a SysRq but just isn't, and is another, more warmer, reboot.
[…]
It's no actual interactive console, but it's a way to reliably probe whatever the fuck was happening in the black box. Real green-field shit.
Given the above, it is tempting to boot a Debian rootfs with KERN-A – previously just a black screen – and see what falls out. Don't – you will first get
[ 1.95725] ChbomIuM OS LSM: sb_mou.t ddv=sysf3 type=s)Qfs flAgs-xe
!.9047)8\ systemd[1]: F@i,ed to mount sysfs (4ypa sysfs) on /sYs (MC_NOSUID|MS_NODEV|MS_NOEXEC ""(: Too eany levels of symbklic links
[ 1.94304] Chromi5m OR HSM: sb_moent MotNt path sith syml)nks prohibHded obj="/syr/kErned/secqrity" pid=1 cMdline=.sbin/init cros_secure"
[ 1.91301] CHROlium OS LSM: 3b_mound dev=#EcuRityfs tyPa<Securityfs blacs0xe
1.957065M systeed[]* FrEezing exea%tiOn.[ 31.19(945] bl_dix`d: `ira"ling
wherein "Chromium OS LSM: Mount path with symlinks prohibited" appears to be from the eponymous module which prevents mounting on paths which were resolved via symlinks, and after you strace systemd pid1 you will find out that it does
mount("proc", "/proc", "proc", ...)
but
open("/sys", O_NOFOLLOW) = 0
mount("sysfs", "/proc/self/fd/0", "sysfs", ...)
and
open("/sys/kernel/security", O_NOFOLLOW) = 0
mount("securityfs", "/proc/self/fd/0", "securityfs", ...)
as its own symlink mitigation,
which makes the latter two ELOOP
, as seen in the log.
Given that it does not remount these one may then be tempted to simply gift them. So after you
#!/bin/sh
echo dupa dupa dupa dupa dupa dupa dupa > /dev/kmsg
/bin/mount -t sysfs sysfs /sys > /dev/kmsg 2>&1
/bin/mount -t securityfs securityfs /sys/kernel/security > /dev/kmsg 2>&1
/bin/mount -t proc proc /proc > /dev/kmsg 2>&1
/bin/mount -t tmpfs tmpfs /tmp > /dev/kmsg 2>&1
/bin/mount -t tmpfs tmpfs /run > /dev/kmsg 2>&1
mkdir /run/lock >/dev/kmsg 2>&1
/bin/mount -t tmpfs tmpfs /run/lock > /dev/kmsg 2>&1
/bin/mount -t devtmpfs -o mode=0755 devtmpfs /dev > /dev/kmsg 2>&1
mkdir /dev/pts > /dev/kmsg 2>&1
mkdir /dev/shm > /dev/kmsg 2>&1
/bin/mount -t tmpfs -o mode=01777 tmpfs /dev/shm > /dev/kmsg 2>&1
mnt() {
/bin/mount -t "$@" >/dev/kmsg 2>&1
}
mnt cgroup2 -o nsdelegate,memory_recursiveprot cgroup2 /sys/fs/cgroup ||
mnt cgroup2 -o nsdelegate cgroup2 /sys/fs/cgroup ||
mnt cgroup2 cgroup2 /sys/fs/cgroup ||
mnt tmpfs tmpfs /sys/fs/cgroup
mnt devpts -o mode=0620,gid=5 devpts /dev/pts
mnt cgroup2 -o nsdelegate cgroup2 /sys/fs/cgroup/unified ||
mnt cgroup2 cgroup2 /sys/fs/cgroup/unified
mnt cgroup -o none,name=systemd,xattr cgroup /sys/fs/cgroup/systemd ||
mnt cgroup -o none,name=systemd cgroup /sys/fs/cgroup/systemd
mnt pstore pstore /sys/fs/pstore
mnt bpf -o mode=0700 bpf /sys/fs/bpf
#/bin/sed s/^/'verbose debug'/ /proc/cmdline > /etc/cmdline
#mount --bind /etc/cmdline /proc/cmdline
#echo zqpa zqpa zqpa zqpa zqpa zqpa zqpa > /dev/kmsg
#exec /usr/lib/systemd/systemd --log-level=debug
#/bin/mount -t proc proc /media
#while :; do /bin/cp /media/self/mounts /dev/kmsg; done &
#( strace -fp 1 -o /dev/kmsg & ) &
#sleep 0.5
exec /lib/systemd/systemd --log-level=debug "$@"
(sleep 3 && sync /) >/dev/kmsg 2>&1 &
exec /bin/strace -DDD -o /strace /lib/systemd/systemd --log-level=debug "$@"
you will continue to see a black screen and on reset the pstore will contain
So this kernel is just fundamentally incompatible with systemd (at least as-configured). woulda bin an easy short-cut, but alas
This, and the ChromiumOS kernels not supporting kexecing, means that we need to find
first (naturally, this ticks off the "backdoored kernel" issue as well).
The frecon /etc/issue says something about booting a self-signed kernel
,
so this ought to be viable;
luckily, crossystem output includes
fw_vboot2 = 1 # [RO/int] 1 if firmware was selected by vboot2 or 0 otherwise
so by applying my incredible monkey brain (
root@chwast:~# apt search vboot2
Sorting... Done
Full Text Search... Done
root@chwast:~# apt search vboot
Sorting... Done
Full Text Search... Done
boot-kernel-utils/unstable,now 0~R106-15054.B-1 arm64
Chrome OS verified boot utils required to sign kernels
boot-utils/unstable,now 0~R106-15054.B-1 arm64
Chrome OS verified u-boot utilities
) and rembering that i last saw this toolchain in InstallingDebianOn/Samsung/ARMChromebook as
# Declare the kernel flags: cat > ${MNT}/boot/kernel.flags <<EOF console=tty1 printk.time=1 nosplash rootwait root=${DEV}p3 rw rootfstype=ext4 lsm.module_locking=0 EOF # Sign the kernel: cat > ${MNT}/boot/sign-kernel.sh <<EOF vbutil_kernel --repack /boot/vmlinuz.signed --keyblock \ /usr/share/vboot/devkeys/kernel.keyblock --version 1 \ --signprivate /usr/share/vboot/devkeys/kernel_data_key.vbprivk \ --config /boot/kernel.flags --oldblob /boot/oldblob EOF
this can be trivially reproduced (after installing boot-kernel-utils, which suffers from recommending 50M of javascript via a -docs package) by re-packing KERN-A:
vbutil_kernel --repack orig.repacked \
--keyblock /usr/share/vboot/devkeys/kernel.keyblock \
--signprivate /usr/share/vboot/devkeys/kernel_data_key.vbprivk \
--config cmdline \
--oldblob /dev/mmcblk0p2
cp orig.repacked /dev/mmcblk1p9
which does boot as expected and uses the cmdline from cmdline. binwalk didn't find this, but the boot bundles, after the device tree payload, end with a string sexion containing the cmdline:
54372340 >sion.load.entry.algo.kernel.fdt.< 54372400 >compatible.timestamp.value......< 54372440 >................................< * 54400000 >console= loglevel=7 init=/sbin/i< 54400040 >nit cros_secure drm.trace=0x106 < 54400100 >root=PARTUUID=%U/PARTNROFF=1 roo< 54400140 >twait rw dm_verity.error_behavio< 54400200 >r=3 dm_verity.max_bios=-1 dm_ver< 54400240 >ity.dev_wait=0 dm="1 vroot none < 54400300 >ro 1,0 4077568 verity payload=RO< 54400340 >OT_DEV hashtree=HASH_DEV hashsta< 54400400 >rt=4077568 alg=sha256 root_hexdi< 54400440 >gest=[…54400640…]" noinitrd vt.global_< 54400700 >cursor_default=0 kern_guid=%U cp< 54400740 >uidle.governor=teo ............< 54401000 >................................< * 100000000
with the %U
s being replaced with the boot bundle's partition's UUID by the boot-loader.
A cute scheme, which does work and does boot, so the tool-chain works.
Even if I don't know why you'd want to sign with those particular parts of some key; doesn't really matter.
So, by plumbing the depths of the vbutil_kernel usage string
(or its equivalent 🙄 manual)
we can observe that,
given vbutil_kernel --get-vmlinuz /dev/mmcblk0p2 --vmlinuz-out orig
,
orig contains the whole device tree with the embedded kernel &c.
Why do they call it a vmlinuz
then? doesn't matter, I s'pose.
And by filling out the non-re-packing, I got to
printf '\0' > bootloader
vbutil_kernel --pack /dev/mmcblk1p9 \
--keyblock /usr/share/vboot/devkeys/kernel.keyblock \
--signprivate /usr/share/vboot/devkeys/kernel_data_key.vbprivk \
--version 1 \
--vmlinuz orig \
--bootloader bootloader \
--config cmdline \
--arch arm64
wherein it's similarly unclear to me what the version's supposed to be or mean. I copied 1 from InstallingDebianOn/Samsung/ARMChromebook because it's required for --pack. The architecture defaults to "x86" regardless of the host.
As inferrable from above, the bootloader bit is null in the shipped kernel, but you can't spec an empty file, so a file with a zero is minimal. This doesn't appear to be used by our bootloader, but it lives in a block after the cmdline.
So, near as I can tell, the boot bundle consists of:
CHROMEOSparameter(?) block
vmlinuz
(Even if you replace the kernel carefully without re-signing the bundle, you get honked at and /sys/firmware/log has the same "In RSAVerify(): Padding check failed!" error as the first time.)
Now we just need to get an appropriate kernel to stuff into 2.. The Debian kernel is unsuitable as-shipped because it's fully modular and we don't get an initrd.
Naturally, fixing this means apt sourceing the latest kernel (6.6.11-1),
copying /boot/config-6.6.11-arm64 to .config,
and either dealing with all the Kconfig UIs actively fighting you when you try to build in a component with modularised dependencies
(why can't the computer also build them in instead of just complaining that they're modular and doing nothing? unsolvable problem)
or just (sed -i s/=m$/=y/ .config
) building every module into the kernel image.
Unfortunately, if you do the latter,
not only does make -j25 ARCH=arm64 LLVM=1 Image take eons (like an hour),
it produces an intermediate 1.7G-sized vmlinux,
and the output arch/arm64/boot/Image (which according to make ARCH=arm64 help is the Uncompressed kernel image
) is 154M (86M LZ4ed).
This would be perfect if it were bootable; alas, it honks with
This unfortunately means manually enabling every Mediatek-specific feature ('/\(MEDIATEK\|MTK\).*=m/s/m$/y/'
),
all framebuffers,
all the blockdev drivers ('/BLOCK.*=m/s/m$/y/'
) and ext4 ('s/CONFIG_EXT4_FS=m/CONFIG_EXT4_FS=y/'
).
This is mind-numbing. A final .config (and a diff from the Debian one) are at the end.
Here's the high-lights.
There's a Platform selection menu at the top.
I unselected everything sans MediaTek SoC Family
.
There's a whole-ass Platform support for Chrome hardware sexion, with most of it turned off or modularised in the Debian config.
Drivers for ChromeOS systems are disguised as "CHROMEOS", "CROS", and "GOOGLE". A significant proportion of these depend on X86.
In the File systems, Miscellaneous filesystems sexion there's Persistent store support
(CONFIG_PSTORE).
This is crucial, since this is what provides the logs in /sys/fs/pstore.
I cranked that shit.
CONFIG_CHROMEOS_PSTORE depends on X86. This is rather surprising, and proves how mind-numbing of an activity this is because I have it in my notes twice. ARM chromebooks appear to use some standard pstore method which is covered by a generic driver.
This yields a much more realistic 31M Image.
There's probably a, uh, right way to pack it into the device tree.
Alas, as demonstrated in the how is pointar formed kernal loaded? sexion, device trees can be decompiled
(though not unambiguously, since this time the kernel blob was formatted as data = [04 22
):
[…] 74 00];
$ tail -c +$(( 0x10000 + 1)) mmcblk0p2 | dtc -I dtb -O dts > mmcblk0p2.dts
$ csplit mmcblk0p2.dts '/data =/' '/type =/'
161
26119768
7957930
$ head xx00 xx02
==> xx00 <==
/dts-v1/;
/ {
timestamp = <0x643cb38f>;
description = "Chrome OS kernel image with one or more FDT blobs";
#address-cells = <0x01>;
images {
kernel@1 {
==> xx02 <==
type = "kernel_noload";
arch = "arm64";
os = "linux";
compression = "lz4";
load = <0x00>;
entry = <0x00>;
};
fdt@1 {
description = "mt2712-evb.dtb";
$ { cat xx00;
printf 'data = ['; lz4 < .../Image | od -An -tx1 -v | tr -d '\n'; printf '];\n';
cat xx02; } > new
$ dtc -I dts -O dtb < new > new.dtb
(This is hopefully rather clear: splitting the file before and after the first data = line – the kernel's – then pasting it back together with said line replaced with a hex dump from the LZ4ed image. The first two steps don't need to be repeated and the latter two can be trivially pipelined together.)
So, after several identical signing rounds (with orig replaced with new.dtb), rebooting to a black screen, letting it rip for a bit, then ⟳+power-buttoning:
It is now that I discovered that alt+🔊+r works, so full log. It's rather inconsequential, but the interesting bits are
[ 0.000000] Linux version 6.6.11 (nabijaczleweli@tarta) (Debian clang version 18.0.0 (++20231231112334+c7c912cff945-1~exp1~20231231112352.433), Debian LLD 18.0.0) #8 SMP Mon Jan 22 03:42:58 CET 2024
[ 0.000000] KASLR disabled due to lack of seed
[ 0.000000] Machine model: Google Hana
[ 0.000000] efi: UEFI not found.
[ 0.000000] Reserved memory: created DMA memory pool at 0x00000000b7000000, size 5 MiB
[ 0.000000] OF: reserved mem: initialized node vpu_dma_mem_region@b7000000, compatible id shared-dma-pool
[ 0.000000] OF: reserved mem: 0x00000000b7000000..0x00000000b74fffff (5120 KiB) nomap non-reusable vpu_dma_mem_region@b7000000
[ 0.000000] NUMA: No NUMA configuration found
[ 0.000000] Initmem setup node 0 [mem 0x0000000040000000-0x000000013fffffff]
[ 0.011840] smp: Brought up 1 node, 4 CPUs
[ 0.011902] SMP: Total of 4 processors activated.
[ 0.011910] CPU features: detected: 32-bit EL0 Support
[ 0.011917] CPU features: detected: 32-bit EL1 Support
[ 0.011925] CPU features: detected: CRC32 instructions
[ 0.012042] CPU: All CPU(s) started at EL2
[ 0.044906] Serial: AMBA PL011 UART driver
[ 0.045354] pstore: Using crash dump compression: deflate
[ 0.045368] printk: console [ramoops-1] enabled
[ 0.045780] pstore: Registered ramoops as persistent store backend
[ 0.045791] ramoops: using 0x100000@0xb1f00000, ecc: 0
– 4G of RAM, 4 CPUs, clang trunk works, pstore works, so the device tree also works.
It does, however, end with a litany of expired time-outs for like every device –
[ 10.976470] mtk-scpsys 10006000.scpsys: vdec: clk unavailable [ 10.976747] mt6577-uart 11002000.serial: Can't get uart clock [ 10.978161] mediatek-hdmi-ddc 11012000.i2c: get ddc_clk failed: fffffffffffffdfb , [ 10.978447] mediatek-cec 10013000.cec: Failed to get cec clock: -517 [ 10.979634] mtk_vpu 10020000.vpu: get vpu clock failed [ 10.979742] mtk-cpufreq mtk-cpufreq: failed to initialize dvfs info for cpu0 [ 10.982016] platform 10212000.mailbox: deferred probe pending [ 10.982039] platform 11290000.usb-phy: deferred probe pending [ 10.982055] platform 10209100.hdmi-phy: deferred probe pending [ 10.982069] platform 1401e000.pwm: deferred probe pending [ 10.982083] platform backlight: deferred probe pending [ 10.982097] platform 1000d000.pwrap: deferred probe pending
Unclear to me what "deferred probe pending" means (do I need to buy a driver?); this is the hard part.
Actually the hard part turned out to be "getting Hifux to execute an init from an embedded »early userspace« initramfs"
(apparently it wants /init (rdinit=
) instead of /sbin/init (init=
)
and only runs it if it exists and silently ignores everything if not;
I only got to this with significant debugging),
since How to troubleshoot deferred probe issues in Linux
notes commit d090b70ede02: driver core: add deferring probe reason to devices_deferred property,
which 6.6
includes, puts the reason into /sys/kernel/debug/devices_deferred
– while we aren't at a real interactive userland yet
(and can't embed one due to the Linux image limit, and the "bootloader" block doesn't appear to be forwarded as an initrd),
a minimal "cp /s/k/d/d_d /dev/kmsg
"-style cpio is 1.7M zstded –
dash, mount, libc6, libblkid1, libmount1, libpcre2, libselinux1 debs, a Makefile
.ONESHELL:
_:
mkdir -p root/dev root/proc root/sys root/dev
for f in *.deb; do
dpkg-deb -R $$f root/
rm -r root/DEBIAN
done
rm -r root/usr/share root/usr/lib/aarch64-linux-gnu/gconv
chmod u-s root/usr/bin/*
ln -f init root/
a simple init script to log the file every second
#!/bin/sh -x
mount -t devtmpfs devtmpfs /dev
exec > /dev/console < /dev/console 2>&1
#exec > /dev/kmsg 2>&1
mount -t proc proc /proc
mount -t sysfs sysfs /sys
mount -t debugfs debugfs /sys/kernel/debug
printf '%s\n' /sys/kernel/debug/*
cat() (
set +x
while IFS= read -r l; do
printf '%s\n' "$l"
done < "$1"
)
cat /proc/uptime > /dev/kmsg
set +x
u=0
one() {
while :; do
IFS=. read -r u2 rest < /proc/uptime
[ $u2 -eq $u ] && continue
u=$u2
echo $u.$rest > /dev/kmsg
cat /sys/kernel/debug/devices_deferred > /dev/kmsg
break
done
}
one; one; one; one; one; one; one; one; one; one
and
CONFIG_INITRAMFS_SOURCE="[…]/faux/root",
with a little ergonomic panic=1 yields
[ 23.083931] Run /init as init process [ 23.145830] 23.14 69.15 [ 23.181712] mtk-cpufreq [ 23.209648] backlight platform: supplier fixedregulator2 not ready [ 23.284973] 11230000.mmc platform: wait for supplier /soc/pwrap@1000d000/mt6397/mt6397regulator/buck_vio18 [ 23.387265] 11240000.mmc platform: wait for supplier /soc/pwrap@1000d000/mt6397/mt6397regulator/ldo_vmc [ 23.501618] 1401d000.dpi mediatek-dpi: Failed to get bridge [ 23.572462] 11260000.mmc platform: wait for supplier /soc/pwrap@1000d000/mt6397/mt6397regulator/ldo_vgp3 [ 23.681601] 1401b000.dsi platform: wait for supplier /soc/i2c@11007000/edp-bridge@8/ports/port@0/endpoint [ 23.794384] 14025000.hdmi [ 23.837822] panel platform: wait for supplier /soc/i2c@11007000/edp-bridge@8/ports/port@1/endpoint … [ 32.777145] Kernel panic - not syncing: Attempted to kill init! exitcode=0x00000000
which naturally points to CONFIG_REGULATOR_MT6397
.
Re-building, re-signing, re-rebooting again shows
[ 24.315189] mtk-cpufreq [ 24.342813] backlight platform: supplier fixedregulator2 not ready [ 24.412245] 1401d000.dpi mediatek-dpi: Failed to get bridge [ 24.473247] 11260000.mmc platform: supplier fixedregulator0 not ready [ 24.559623] 1401b000.dsi platform: wait for supplier /soc/i2c@11007000/edp-bridge@8/ports/port@0/endpoint [ 24.665648] 14025000.hdmi [ 24.708081] panel platform: wait for supplier /soc/i2c@11007000/edp-bridge@8/ports/port@1/endpoint
which is already quite good, with both MMCs showing up
[ 17.525454] mmcblk0: mmc0:e624 SU08G 7.40 GiB [ 17.688381] mmcblk0: p1 p5 p6 p9 p10 p15 [ 18.167701] mmc1: new HS400 MMC card at address 0001 [ 18.269237] mmcblk1: mmc1:0001 DA4032 29.1 GiB [ 18.379454] GPT:partition_entry_array_crc32 values don't match: 0x9d2a6879 != 0xef8dd269 [ 18.499823] GPT:Primary header thinks Alt. header is not at the end of the disk. [ 18.648561] GPT:61063167 != 61071359 [ 18.648566] GPT:Alternate GPT header not at the end of the disk. [ 18.648569] GPT:61063167 != 61071359 [ 18.735943] GPT: Use GNU Parted to correct GPT errors. [ 18.735978] mmcblk1: p1 p2 p3 p4 p5 p6 p7 p8 p9 p10 p11 p12 [ 18.853013] mmcblk1boot0: mmc1:0001 DA4032 4.00 MiB [ 18.963993] mmcblk1boot1: mmc1:0001 DA4032 4.00 MiB [ 19.088099] mmcblk1rpmb: mmc1:0001 DA4032 16.0 MiB, chardev (238:0)
(though note the now-randomised MMC order, and the explicit-by-name parted call-out. more like GNU Partition Table!) but they still want, uh
$ grep -A1 fixedregulator mt8173-elm-hana.dts fixedregulator0 { compatible = "regulator-fixed"; $ grep -r regulator-fixed | grep c: drivers/regulator/fixed.c: .compatible = "regulator-fixed", $ grep fixed drivers/regulator/Makefile obj-$(CONFIG_REGULATOR_FIXED_VOLTAGE) += fixed.o
CONFIG_REGULATOR_FIXED_VOLTAGE:
[ 24.483011] mtk-cpufreq [ 24.522681] 1401d000.dpi mediatek-dpi: Failed to get bridge [ 24.587404] 1401b000.dsi platform: wait for supplier /soc/i2c@11007000/edp-bridge@8/ports/port@0/endpoint [ 24.696106] 14025000.hdmi [ 24.739520] panel platform: wait for supplier /soc/i2c@11007000/edp-bridge@8/ports/port@1/endpoint
so
$ grep -A1 edp-bridge mt8173-elm-hana.dts edp-bridge@8 { compatible = "parade,ps8640"; $ grep -r parade,ps8640 drivers/gpu/drm/bridge/parade-ps8640.c: { .compatible = "parade,ps8640" }, $ grep ps8640 drivers/gpu/drm/bridge/Makefile obj-$(CONFIG_DRM_PARADE_PS8640) += parade-ps8640.o $ grep DRM_PARADE_PS8640 .config CONFIG_DRM_PARADE_PS8640=y
hm
$ grep -m1 -A1 11007000 mt8173-elm-hana.dts i2c@11007000 { compatible = "mediatek,mt8173-i2c"; $ grep -r mediatek,mt8173-i2c | grep c: drivers/i2c/busses/i2c-mt65xx.c: { .compatible = "mediatek,mt8173-i2c", .data = &mt8173_compat }, $ grep i2c-mt65xx drivers/i2c/busses/Makefile obj-$(CONFIG_I2C_MT65XX) += i2c-mt65xx.o $ grep CONFIG_I2C_MT65XX .config CONFIG_I2C_MT65XX=m
which still doesn't actually get us the screen due to the unchanging bridge issues, but
But only after disabling CONFIG_INITRAMFS_SOURCE because if there is an initramfs embedded,
even if you don't unpack it (noinitrd
),
the rootfs mount willl ENOENT
regardless,
which means you can get a panic with a blockdev dump listing available partition UUIDs when root= already contains one of them:
[ 24.530570] VFS: Cannot open root device "PARTLABEL=chwast-root" or unknown-block(179,778): error -2
(or "PARTUUID=b8c64d3b-7752-4132-a244-5a85fc14157a")
(or "0b3:0030a")
[ 24.639808] Please append a correct "root=" boot option; here are the available partitions:
[ 24.739687] b300 30535680 mmcblk2
[ 24.739696] driver: mmcblk
[ 24.820866] b301 26179560 mmcblk2p1 d8331ad0-ed78-f442-87f4-78df0130895a
…
[ 26.001792] b30c 32768 mmcblk2p12 bcf61070-764a-004f-8abd-590a44996a91
[ 26.001798]
[ 26.110005] 0b3:00100 4096 mmcblk2boot0
[ 26.110012] (driver?)
[ 26.191177] 0b3:00200 4096 mmcblk2boot1
[ 26.191183] (driver?)
[ 26.272335] 0b3:00300 7761920 mmcblk1
[ 26.272342] driver: mmcblk
[ 26.353498] 0b3:00301 204800 mmcblk1p1 1aa8056f-1357-6c45-a2f2-cb8bb98338e6
[ 26.460663] 0b3:00305 16384 mmcblk1p5 8865bf3d-d8ea-574a-9c55-3aabefc1e84d
[ 26.567834] 0b3:00306 2097152 mmcblk1p6 a0464221-9912-f146-ac7b-c6f489c25176
[ 26.675000] 0b3:00309 102400 mmcblk1p9 1e061a8c-6159-4486-add1-988e88a06acf
[ 26.782169] 0b3:0030a 1046872 mmcblk1p10 b8c64d3b-7752-4132-a244-5a85fc14157a
[ 26.890374] 0b3:0030f 10240 mmcblk1p15 b6bbcc50-e420-4032-a2d2-ea69fce9cb53
[ 26.890381]
[ 26.998582] List of all bdev filesystems:
[ 27.046449] ext3
[ 27.046453] ext2
[ 27.069350] ext4
[ 27.092248] fuseblk
[ 27.115147]
[ 27.158861] Kernel panic - not syncing: VFS: Unable to mount root fs on unknown-block(179,778)
and since it says unknown-block(179,778) (rather than "0,0") it knows what it is! but just can't.
But rebuilding without, enabling serial-getty@ttyUSB0.service, plugging in a USB/serial adapter, and building and installing modules, we are greeted with
at a blazing 9600 bits per second. You know it's a modern system because that speed was achieved over USB 3.
This kinda mostly works, vaguely; since the other end is a real RS232, the maximum speed is 115200 baud and oh boy is 11k/s (8k/s for binary data) fucking horrendous in year of the hog 2024!
Wi-Fi backtraces with a warning and doesn't work even after loading firmware (mrvl/sd8897_uapsta.bin from firmware-libertas). Neither does the screen in any meaningful way, even with firmware-misc-nonfree mediatek/mt8173/vpu_p.bin.
Concept proven: Debian new+
But no matter what I do or what combination of seemingly-relevant configs I flip, shit don't work.
This either means booting normally to the rootfs, or freezing completely with an inocuous log or one that doesn't stand out at all.
This is exemplified by the latter happening when turning on CONFIG_DRM_FBDEV_EMULATION
.
Post factum I know for a fact this isn't the issue,
but at one point it became obvious that this is some proxy-interactive behaviour with no way to validate it.
If only someone had a validated-funxional config to test or diff against!
google hana chromebook linux - Google Search
running linux mainline on arm chromebooks - for example
lenovo chromebook n23 - hana; acer chromebook r13 - elm; lenovo chromebook ... https://support.google.com/chrome/a/answer/9139543?hl=en · https://chromium ...
→
running linux mainline on arm chromebooks
supported devices and linux distributions
- chromebook oak:
- lenovo chromebook 300e (mt8173 version) - hana
- https://github.com/hexdump0815/imagebuilder/blob/main/systems/chromebook_oak/readme.md
→
imagebuilder/systems/chromebook_oak/readme.md at main · hexdump0815/imagebuilder
chromebook oak
tested systems - working
- lenovo chromebook 300e (mt8173 version) - hana
kernel build notes
in many ways it's a program that builds it, making it the best type of notes, so →
# patches for mt8173/oak for i in /compile/doc/stable-mt/misc.cbm/patches/v6.6/mt8173*.patch; do echo === $i patch -p1 < $i done[…]scripts/kconfig/merge_config.sh -m arch/arm64/configs/defconfig /compile/doc/kernel-config-options/chromebooks-aarch64.cfg /compile/doc/kernel-config-options/mediatek.cfg /compile/doc/kernel-config-options/docker-options.cfg /compile/doc/kernel-config-options/options-to-remove-generic.cfg /compile/doc/stable-mt/misc.cbm/options/options-to-remove-special.cfg /compile/doc/kernel-config-options/additional-options-generic.cfg /compile/doc/kernel-config-options/additional-options-aarch64.cfg /compile/doc/stable-mt/misc.cbm/options/additional-options-special.cfg
The patches are superficially worrying, but they all just touch the device tree –
remove even more high speed mmc stuff to get it working stable
– whereas the same cannot be said for the MT8183 patches, but thankfully none of them are relevant here. It is of interest to evaluate these against the mt8173-elm-hana.dtb [decompiled] device tree distributed by ChromiumOS
sd-uhs-sdr{50,104}
tags therefrom,
upstream doesn't do this.raise temps for elm a bit) with no further commentary; upstream, they were added in commit 689b937bedde (
arm64: dts: mediatek: add mt8173 elm and hana board>already as 60/65; giving it another 10° here probably isn't gonna super fuck it up, but it'd've been nice to see some reasoning and maybe measurements and potentially a list of considerations given :v
Merging the configs per the crusty-ass spec works and produces a boot bundle that doesn't work.
But given that the blob in EFI-SYSTEM
also contains a different set of device trees paired with its older kernel
(indeed, a set so different it doesn't even include mt8173-elm-hana.dtb
and the only description
that's vaguely similar is "mt8173-hana-rev0.dtb"
),
a quick re-pack after the prescribed make dtbs
$ csplit -fbb mmcblk0p2.dts '/data =/' '/type =/' '/mt8173-elm-hana.dtb/' '/data =/'
161
26119768
334465
40
7623425
$ # bb00 bb02 start the same as xx00 xx02
$ tail -n2 bb02
fdt@9 {
description = "mt8173-elm-hana.dtb";
$ head -n8 bb04
type = "flat_dt";
arch = "arm64";
compression = "none";
hash@1 {
value = <0xd0eb38a9 0xad297279 0x5b014030 0x1027dbfe 0x3361c4a4>;
algo = "sha1";
};
$ { cat bb00;
printf 'data = ['; lz4 < .../Image | od -An -tx1 -v | tr -d '\n'; printf '];\n';
cat bb02;
printf 'data = ['; < .../arch/arm64/boot/dts/mediatek/mt8173-elm-hana.dtb od -An -tx1 -v | tr -d '\n'; printf '];\n';
cat bb04; } |
dtc -I dts -O dtb > stb+dtb.dtb
— you may notice or rember the DTB is SHA1ed. This doesn't do jack shit, not even as a logged diagnostic. I even forgor 💀 at the time — shows
That's an okay start, but as exemplified by the penguins this is a vajazzled defconfig instead of the reasonable Debian config, so Wi-Fi still doesn't work (though that may just be the way iwd drives it and it may work with another userland), and mounting EXT4s throws warnings (final lines), so beside the screen working it's not a great kernel.
One would hope that just repacking the best kernel to date with the new device tree would work (it doesn't). Or that applying the same set of diffs to /boot/config-6.6.11-arm64 would (also no).
Why? well,
And that is a very literal "straight" – given this final ls -rtlh *.dtb
of my newkernel directory
(also browsable and downloadable with corresponing configs, modules, and logs):
21M 01-22 03:44 new+pstored+sysrq.dtb
20M 01-23 05:40 debian.dtb
21M 01-23 06:04 new+pstored+sysrq+clock.dtb
21M 01-23 07:07 new+pstored+sysrq+clock-uvesa.dtb
22M 01-23 16:01 new+pstored+sysrq+clock-uvesa+clk.dtb
22M 01-23 19:02 new+pstored+sysrq+clock-uvesa+clk+initrd.dtb
22M 01-23 20:16 new+pstored+sysrq+clock-uvesa+clk+mmc.dtb
24M 01-24 02:29 new+pstored+sysrq+clock-uvesa+clk+mmc+devices_deferred.dtb
24M 01-24 02:36 new+pstored+sysrq+clock-uvesa+clk+mmc+devices_deferred2.dtb
24M 01-24 02:47 new+pstored+sysrq+clock-uvesa+clk+mmc+devices_deferred2+rtc.dtb
24M 01-24 20:42 new+pstored+sysrq+clock-uvesa+clk+mmc+devices_deferred2+rtc+6397.dtb
24M 01-24 22:47 new+pstored+sysrq+clock-uvesa+clk+mmc+devices_deferred2+rtc+6397+fixed.dtb
24M 01-25 00:13 new+pstored+sysrq+clock-uvesa+clk+mmc+devices_deferred2+rtc+6397+fixed+i2c.dtb
24M 01-25 01:06 new+pstored+sysrq+clock-uvesa+clk+mmc+devices_deferred2+rtc+6397+fixed+i2c@mount.dtb
23M 01-25 03:24 new+pstored+sysrq+clock-uvesa+clk+mmc+devices_deferred2+rtc+6397+fixed+i2c-initrd.dtb
23M 01-25 08:18 new+pstored+sysrq+clock-uvesa+clk+mmc+devices_deferred2+rtc+6397+fixed+i2c+usbsh2.dtb
# ^ first serial-interactive session
23M 01-25 21:02 new+pstored+sysrq+clock-uvesa+clk+mmc+devices_deferred2+rtc+6397+fixed+i2c+usbsh2+legacy.dtb
22M 01-26 02:38 new+pstored+sysrq+clock-uvesa+clk+mmc+devices_deferred2+rtc+6397+fixed+i2c+usbsh2+legacy-legacy.dtb
18M 01-26 07:27 stb+dtb.dtb
# ^ the 🐧🐧🐧🐧 config
22M 01-26 21:37 new+pstored+sysrq+clock-uvesa+clk+mmc+devices_deferred2+rtc+6397+fixed+i2c+usbsh2+legacy-legacy+dtb+dma.dtb
22M 01-26 22:17 new+pstored+sysrq+clock-uvesa+clk+mmc+devices_deferred2+rtc+6397+fixed+i2c+usbsh2+legacy-legacy+dtb+dma+simple.dtb
we are currently here.
This followed:
17M 01-26 23:54 deb+options-to-remove-special.cfg+mediatek.cfg+additional-options-special.cfg.dtb
18M 01-27 00:30 deb+options-to-remove-special.cfg+mediatek.cfg+additional-options-special.cfg+full.dtb
18M 01-27 01:19 deb+options-to-remove-special.cfg+mediatek.cfg+additional-options-special.cfg+full+all.dtb
17M 01-27 01:46 deb+options-to-remove-special.cfg+mediatek.cfg+additional-options-special.cfg+full+all+gen.dtb
17M 01-27 02:29 deb2+1.dtb
18M 01-27 02:44 deb2+2.dtb
18M 01-27 02:56 deb2+3.dtb
18M 01-27 03:08 deb2+4.dtb
18M 01-27 03:13 deb2+5.dtb
18M 01-27 03:20 deb2+6.dtb
18M 01-27 03:25 deb2+7.dtb
18M 01-27 03:30 deb2+8.dtb
18M 01-27 03:34 deb2+9.dtb
18M 01-27 03:37 deb2+11.dtb
18M 01-27 03:37 deb2+10.dtb
18M 01-27 03:46 deb2+12.dtb
# ^ ./tools/testing/ktest/config-bisect.pl 1 (jack shit)
22M 01-27 04:35 new+pstored+sysrq+clock-uvesa+clk+mmc+devices_deferred2+rtc+6397+fixed+i2c+usbsh2+legacy-legacy+dtb+dma+simple+bi.dtb
# ^ bisexion diff applied to the previous one (still jack shit)
15M 01-27 04:51 bis.dtb
17M 01-27 05:02 bis+2.dtb
17M 01-27 05:48 bis+3.dtb
17M 01-27 06:57 bis+4.dtb
18M 01-27 08:05 bis+5.dtb
18M 01-27 08:51 bis+6.dtb
18M 01-27 08:55 bis+7.dtb
18M 01-27 09:13 bis+8.dtb
18M 01-27 09:17 bis+9.dtb
18M 01-27 09:37 bis+10.dtb
18M 01-27 09:40 bis+11.dtb
# ^ ./tools/testing/ktest/config-bisect.pl 2 (also jack shit, and different variable)
And this is where the first issue that made applying the diffs not work finally became apparent: they set, for example
CONFIG_DRM_MEDIATEK_HDMI=y CONFIG_DRM_MEDIATEK_DP=y CONFIG_DRM_MEDIATEK=y
but make oldconfig
(or olddefconfig
, or any *config
, or any build job),
which updates the existing .config to match both the current kernel and its invariants updates it to
CONFIG_DRM_MEDIATEK=m CONFIG_DRM_MEDIATEK_DP=m CONFIG_DRM_MEDIATEK_HDMI=m
because CONFIG_DRM_MEDIATEK
depends on CONFIG_DRM
, which is also built as a module.
So instead of transitively updating the dependency tree to comply with the "build this in" spec, it just silently downgrades them all to be modules. Observant readers may note that this is the second time this mentality manifests within this post.
17M 01-27 16:57 hm+p.dtb
23M 01-27 18:54 new+pstored+sysrq+clock-uvesa+clk+mmc+devices_deferred2+rtc+6397+fixed+i2c+usbsh2+legacy-legacy+dtb+dma+simple+merged.dtb
# ^ {chromebooks-aarch64,mediatek,additional-options-aarch64,additional-options-special}.cfg applied mechanically
# and the other cfgs applied manually
23M 01-27 19:22 new+pstored+sysrq+clock-uvesa+clk+mmc+devices_deferred2+rtc+6397+fixed+i2c+usbsh2+legacy-legacy+dtb+dma+simple+merged-svs.dtb
22M 01-27 19:31 new+pstored+sysrq+clock-uvesa+clk+mmc+devices_deferred2+rtc+6397+fixed+i2c+usbsh2+legacy-legacy+dtb+dma+simple+merged-svs+fb.dtb
22M 01-27 19:50 new+pstored+sysrq+clock-uvesa+clk+mmc+devices_deferred2+rtc+6397+fixed+i2c+usbsh2+legacy-legacy+dtb+dma+simple+merged-svs+fb+df.dtb
21M 01-27 20:13 new+pstored+sysrq+clock-uvesa+clk+mmc+devices_deferred2+rtc+6397+fixed+i2c+usbsh2+legacy-legacy+dtb+dma+simple+merged-svs+fb+df+drm.dtb
22M 01-27 20:36 new+pstored+sysrq+clock-uvesa+clk+mmc+devices_deferred2+rtc+6397+fixed+i2c+usbsh2+legacy-legacy+dtb+dma+simple+merged-svs+fb+df+drm+more.dtb
22M 01-27 20:48 new+pstored+sysrq+clock-uvesa+clk+mmc+devices_deferred2+rtc+6397+fixed+i2c+usbsh2+legacy-legacy+dtb+dma+simple+merged-svs+fb+df+drm+more+nogoog.dtb
finally yielded
This marks the first Debian-derived, and thus meaningfully diffable, config. (You can't really pick the interesting bits out of the relentless torrent of defconfig diff.)
The key?
Turning off GOOGLE_FRAMEBUFFER_COREBOOT
!
With it you see
[ 0.386886] simple-framebuffer simple-framebuffer.0: simplefb: cannot reserve video memory at [mem 0x00000000-0x00400fff] [ 0.386911] simple-framebuffer simple-framebuffer.0: framebuffer at 0x0, 0x401000 bytes [ 0.386919] simple-framebuffer simple-framebuffer.0: format=a8r8g8b8, mode=1366x768x32, linelength=5464
at the end of the dmesg and then it hangs. The "cannot reserve video memory" is just a warning that it can't lock it exclusively, and it then, presumably, initialises the range [0, 0x400FFF], razing the interrupt table that's probably unmoved from 0.
Without it it just boots and logs
[ 1.098264] [drm] Initialized mediatek 1.0.0 20150513 for mediatek-drm.12.auto on minor 0 [ 1.303268] Console: switching to colour frame buffer device 170x48 [ 1.334367] mediatek-drm mediatek-drm.12.auto: [drm] fb0: mediatekdrmfb frame buffer device
as it ought to.
The Debian config is such that this automatically turns on/off when toggling CONFIG_FB_SIMPLE
(or whatever); the defconfig isn't.
This is not obvious because the warning looks like an error,
and there are like seven different drivers that log as "simple-framebuffer",
and approximately twenty "simple framebuffer"s.
Not to mention the spoopy axion at a distance with the actual driver – framebuffer-coreboot – not logging as itself.
Naturally, one wants to enable all the GOOGLE/CROS configs, and you should; just not this one.
22M 01-27 23:17 new+pstored+sysrq+clock-uvesa+clk+mmc+devices_deferred2+rtc+6397+fixed+i2c+usbsh2+legacy-legacy+dtb+dma+simple+merged-svs+fb+df+drm+more+nogoog+somegoog.dtb
22M 01-28 01:38 new+pstored+sysrq+clock-uvesa+clk+mmc+devices_deferred2+rtc+6397+fixed+i2c+usbsh2+legacy-legacy+dtb+dma+simple+nogoog.dtb
22M 01-28 01:51 new+pstored+sysrq+clock-uvesa+clk+mmc+devices_deferred2+rtc+6397+fixed+i2c+usbsh2+legacy-legacy+dtb+dma+simple+nogoog+emul.dtb
23M 01-28 02:24 new+pstored+sysrq+clock-uvesa+clk+mmc+devices_deferred2+rtc+6397+fixed+i2c+usbsh2+legacy-legacy+dtb+dma+simple+nogoog+emul+paneldrm.dtb
23M 01-28 02:40 new+pstored+sysrq+clock-uvesa+clk+mmc+devices_deferred2+rtc+6397+fixed+i2c+usbsh2+legacy-legacy+dtb+dma+simple+nogoog+emul+paneldrm+spi.dtb
22M 01-28 03:31 new+pstored+sysrq+clock-uvesa+clk+mmc+devices_deferred2+rtc+6397+fixed+i2c+usbsh2+legacy-legacy+dtb+dma+simple+nogoog+emul+paneldrm+spi+pins+regulator.dtb
22M 01-28 04:22 new+pstored+sysrq+clock-uvesa+clk+mmc+devices_deferred2+rtc+6397+fixed+i2c+usbsh2+legacy-legacy+dtb+dma+simple+nogoog+emul+paneldrm+spi+pins+regulator+noemul+emul.dtb
18M 01-28 17:57 mandeb.dtb
20M 01-28 18:35 mandeb+initrd.dtb
20M 01-28 18:46 mandeb+initrd+1.dtb
20M 01-28 19:03 mandeb+initrd+1+tabs.dtb
20M 01-28 19:09 mandeb+initrd+1+tabs1.dtb
20M 01-28 19:28 mandeb+initrd+1+tabs2+reg.dtb
20M 01-28 19:51 mandeb+initrd+1+tabs2+reg+drm.dtb
20M 01-28 20:03 mandeb+initrd+1+tabs2+reg+drm+adc.dtb
This was my limit for the
useless /sys/kernel/debug/devices_deferred dumps,
and where finally instead of thinking "if only there were a way to have a config contain what's in my device tree"
I found and applied scripts/dtc/dt_to_config.
Of course, it wants to be in a git checkout
(which I have, but is annoying –
you could probably replace the
with git grep
grep -rI
with the same effect of not looking into artifacts),
but even beside that it produces a brain destroyer format:
-dD----H----- : /backlight : pwm-backlight : arch/arm/mach-s3c/mach-crag6410.c : no_config : none -dDc---H----- : /backlight : pwm-backlight : drivers/video/backlight/pwm_bl.c : CONFIG_BACKLIGHT_PWM : none -dDc--------- : /connector : hdmi-connector : drivers/gpu/drm/bridge/display-connector.c : CONFIG_DRM_DISPLAY_CONNECTOR : none -dDc--------- : /connector : hdmi-connector : drivers/gpu/drm/bridge/lontium-lt8912b.c : CONFIG_DRM_LONTIUM_LT8912B : none -dDc----x---- : /connector : hdmi-connector : drivers/gpu/drm/mediatek/mtk_hdmi.c : mediatek-drm-hdmi-objs : none -dDc----x---- : /connector : hdmi-connector : drivers/gpu/drm/sun4i/sun4i_drv.c : sun4i-drm-y : none ------------- : /cpus/cpu@0 : arm,cortex-a53 : no_driver : no_config : none ------------- : /cpus/cpu@1 : arm,cortex-a53 : no_driver : no_makefile : none -d-c----x---- : /cpus/cpu@100 : arm,cortex-a72 : drivers/soc/bcm/brcmstb/biuctrl.c : obj-y : none -d-c----x---- : /cpus/cpu@101 : arm,cortex-a72 : drivers/soc/bcm/brcmstb/biuctrl.c : obj-y : none
Thankfully this can be avoided with --config-format
which is less arcane –
# -dD----H----- : /backlight : pwm-backlight : arch/arm/mach-s3c/mach-crag6410.c : no_config : none # no_config # -dDc---H----- : /backlight : pwm-backlight : drivers/video/backlight/pwm_bl.c : CONFIG_BACKLIGHT_PWM : none # CONFIG_BACKLIGHT_PWM is not set # CONFIG_BACKLIGHT_PWM=y # -dDc--------- : /connector : hdmi-connector : drivers/gpu/drm/bridge/display-connector.c : CONFIG_DRM_DISPLAY_CONNECTOR : none # CONFIG_DRM_DISPLAY_CONNECTOR is not set # CONFIG_DRM_DISPLAY_CONNECTOR=y # -dDc--------- : /connector : hdmi-connector : drivers/gpu/drm/bridge/lontium-lt8912b.c : CONFIG_DRM_LONTIUM_LT8912B : none # CONFIG_DRM_LONTIUM_LT8912B is not set # CONFIG_DRM_LONTIUM_LT8912B=y # -dDc----x---- : /connector : hdmi-connector : drivers/gpu/drm/mediatek/mtk_hdmi.c : mediatek-drm-hdmi-objs : none # mediatek-drm-hdmi-objs # -dDc----x---- : /connector : hdmi-connector : drivers/gpu/drm/sun4i/sun4i_drv.c : sun4i-drm-y : none # sun4i-drm-y
and can be quite trivially analysed against the current-best with something like
$ grep '^# C' dt_to_config.config | grep =y | sed 's/# //' | cut -d= -f1 |
sort -u | grep -v ^CONFIG_MACH |
while read -r c; do grep ^$c= .config || echo NO $c; done |
grep m$
CONFIG_ARM_MEDIATEK_CPUFREQ=m
CONFIG_ARM_SMC_WATCHDOG=m
CONFIG_BACKLIGHT_PWM=m
CONFIG_BATTERY_SBS=m
CONFIG_BT_MRVL_SDIO=m
CONFIG_CPUFREQ_DT=m
CONFIG_DRM_DISPLAY_CONNECTOR=m
CONFIG_I2C_HID_OF=m
CONFIG_I2C_MT65XX=m
CONFIG_KEYBOARD_GPIO=m
CONFIG_MFD_ROHM_BD718XX=m
CONFIG_PHY_MTK_TPHY=m
CONFIG_SCSI_UFSHCD_PLATFORM=m
CONFIG_SND_SOC_MT8173=m
CONFIG_SND_SOC_MT8173_RT5650=m
CONFIG_SND_SOC_RT5645=m
CONFIG_TCG_TIS_I2C_INFINEON=m
CONFIG_TOUCHSCREEN_ELAN=m
to then upgrade
CONFIG_{ARM_MEDIATEK_CPUFREQ{,_HW},
and enable
I2C_HID_OF_{ELAN,GOODIX}
,
yielding
20M 01-28 20:37 mandeb+initrd+1+tabs2+reg+drm+adc+d_t_c.dtb
18M 01-28 20:43 mandeb+initrd+1+tabs2+reg+drm+adc+d_t_c-initrd.dtb
i.e.
which, with no missing devices and, well, showing up on the screen, bodes very well! and
which may be one of this generation's yippeeest moments.
(The ENODEV
s at the top are from a lack of modules on this first boot.)
(Also note how modprobe@efi_pstore.service succeeds.
I don't really know how or why, given that this system lacks EFI (and ACPI for that matter) and they're both configured away completely.)
And after a quick module installation, I've achieved
(I'm even in the clip!) All these bundles listed above accumulate to 74 and I lost at most like 4 images, so a few sequence numbers were spent on QEMU pre-testing.
Even X.Org works!
But there's three obvious issues:
input: mtk-rt5650 Headset Jack as /devices/platform/sound/sound/card0/input8 input: mtk-rt5650 HDMI Jack as /devices/platform/sound/sound/card0/input9in the dmesg but pipewire doesn't see them
3. is the most pressing for both usability reasons (it's bound to be slow, but not that slow) and because sometimes I/O will just, like, effectively hang, with kilobyte-sized mmaps taking seconds, and the dmesg complaining that the card is "stuck busy", all with a blatant culprit – mt8173-fix-mmc1-speed.patch. The SD card was solid under KERN-A which has all the full-speed stuff this patch disables.
By performing a speed-running trick called "forwarding to the list while modules were building four days ago", I already have a prospective patch for 2., so I can be oh-so-brave (with only a quick glance at if it'd be catastrophic!) and update the module while at it – re-building dtbs modules with just mt8173-higher-temps.patch and the diff from the mail yields
18M 01-31 00:00 mandeb+initrd+1+tabs2+reg+drm+adc+d_t_c-initrd&mwifiex+mmc1.dtb
and while the Wi-Fi warning goes away, the SD card rootfs experience is as shit as ever.
But this may well be because my SD card is not fast enough to qualify for any of the speed boosts – the two internal ones are
new HS400 MMC card
and new ultra high speed SDR104 SDIO card
but this one is just new high speed SDHC card
;
maybe we need to actually install Debian because this is horrendous.
This may be fixable with an SD card worth as much as the laptop instead of my drawer special,
but that still kinda defeats the purpose of a laptop with an internal diskrectangle.
Testing with such a card on the 4.19 ChromiumOS kernel,
I could reproduce the "instability" with a simple test (b2sum /dev/mmcblk1
),
presenting itself as a kernel segfault
and likewise on the 6.6.11 kernel.
Applying the patch fixes it (and runs the card at "high speed").
The MMC ordering appears to already be stable, so while it was random with the original device tree,
that one's for 4.19, so it may just be and old-device-tree issue?
The patch itself blames back to
commit 01101e3 (promising experiments based on apline linux-elm apk
)
as misc.cbm/patches/alpine/fix-mmc-order.patch.
Not that "identical device enumeration order" is a sensible goal unto itself in a.d. 2020 regardless.
rt5650 Playback: ASoC: no backend DAIs enabled for rt5650 Playback, possibly missing ALSA mixer-based routing or UCM profile
is the lead for issue 1.
A quick search for files matching *rt5650*
in sid
shows an unbounded amount of linuxes but starts with firmware-sof-signed
and /lib/firmware/intel/sof-tplg/sof-adl-rt5650.tplg,
whose description says it
Provides the Intel SOF audio firmware and topology needed for audio functionality on some Intel system.
,
which this isn't, so it's not it (not that I didn't try).
Searching locally instead via dpkg -S rt5650 actually reveals alsa-ucm-conf, with
which sure looks like it'd match what the driver complains about not having! but has.
This kinda smells like the bluetooth situation where you need libspa-0.2-bluetooth to have bluetooth audio.
Indeed, apt search pipewire
reveals
pipewire-alsa/unstable 1.0.1-2 arm64
Pipewire ALSA plugin
but this is actually a plugin for ALSA to output to pipewire. Not that you'd know this from the package description. I know it from the damn arch wiki. Reported as Bug#1062262: pipewire-alsa: adversarial description.
Further apt search alsa
ing shows
alsa-tools/unstable 1.2.5-3 arm64
Console based ALSA utilities for specific hardware
alsa-utils/unstable 1.2.10-1.1 arm64
Utilities for configuring and using ALSA
can you guess which one is a sussy baka amongus and which one is the chad taskpilled crewmatecel? The latter lists
Included tools: - alsaucm: alsa use case manager
so if you voted for the latter you will not be ejected.
Amazingly, during the emergency meeting aplay -l
and arecord -l
corroborated mtkrt5650 venting:
**** List of PLAYBACK Hardware Devices ****
card 0: mtkrt5650 [mtk-rt5650], device 0: rt5650 Playback (*) []
Subdevices: 1/1
Subdevice #0: subdevice #0
card 0: mtkrt5650 [mtk-rt5650], device 2: HDMI PCM (*) []
Subdevices: 1/1
Subdevice #0: subdevice #0
**** List of CAPTURE Hardware Devices ****
card 0: mtkrt5650 [mtk-rt5650], device 1: rt5650 Capture (*) []
Subdevices: 1/1
Subdevice #0: subdevice #0
but aplay
doesn't and arecord
records all zeroes.
alsaucm
is one of those programs that definitely make sense to the authors.
But by clicking around –
running everything, in order, from alsaucm(1)
(only real science on da blog):
# alsaucm
# alsaucm listcards
0: hw:0
mtk-rt5650
# alsaucm open 0
ALSA lib main.c:1554:(snd_use_case_mgr_open) error: failed to import 0 use case configuration -2
alsaucm: error failed to open sound card 0: No such file or directory
# alsaucm open hw:0
# alsaucm list _verbs
0: HiFi
Default
# alsaucm list _devices
alsaucm: error failed to get list _devices: No such file or directory
# alsaucm list _devices/HiFi
0: Speaker
Speaker
1: Headphones
Headphones
2: Mic
Internal Microphone
3: Headset
Headset Microphone
4: HDMI
HDMI Audio
# alsaucm list _modifiers
alsaucm: error failed to get list _modifiers: No such file or directory
# alsaucm list _modifiers/HiFi
list is empty
# alsaucm get _verb
alsaucm: error failed to get _verb: No such file or directory
# alsaucm set _verb HiFi
# alsaucm get _verb
alsaucm: error failed to get _verb: No such file or directory
(why the fuck does it all have underscores?
why is "HiFi" a verb?
why is the "verb" denoted as optional after _devices
and _modifiers
but isn't?
why can I not know what the current "verb" is?
what would doing the verb even do?)
and unloading and inserting every sound module (or rebooting! presumably the "verb" gets persisted somewhere up them guts)
now replaced "Dummy Output" in wpctl status
with
Audio
├─ Sinks:
│ 56. Built-in Audio HDMI Audio [vol: 0.40]
│ * 57. Built-in Audio Headphones + Speaker [vol: 1.00]
│
└─ Sources:
* 58. Built-in Audio Headset Microphone + Internal Microphone [vol: 0.63]
Settings
└─ Default Configured Node Names:
0. Audio/Sink alsa_output.platform-sound.HiFi__hw_mtkrt5650_0__sink
1. Audio/Source alsa_input.platform-sound.HiFi__hw_mtkrt5650_1__source
(why are they grouped and not split?) and neither aplay
nor pw-play
do anything.
But at this time I noticed the tab expansion list for a has an alsamixer
which has drip –
– but more importantly has a Headphon output with green OO and a Speaker one is MM, which is, respectively, not muted and muted, apparently. Plugging in headphones actually plays to the headphones. Amazing! But recording gets just noise (it's possible the mic is shot on the headphones but that the internal one is as well? no way). And unmuting the Speaker output doesn't make it go.
The only solution to this is multivariable bisexion, defined as "going to the end of the like eight pages of increasingly-cryptically-named outputs, unmuting a few, then playing again". This is how I know that unmuting the Ext Spk output lets the internal speakers go. It's also how I know that when you're expecting a tinny voice to say "The HINFO.network." (which you should join!) but get a square wave and a mild whiff of burning lacquer that shit's fucking terrifying mang. It's also also how I know that expecting the same and getting a 600Hz whine also is. At least I was ready on the reset that time.
Naturally, the mixer settings are persisted across reboots, so fuck knows which ones of the other 10 outputs I toggled made it be a daemon, or whether just flipping Ext Spk will make it output cleanly to the speakers. Or if some of those outputs start driving the speakers with a DC offset regardless of whether there's audio playing. I know I'm not trynna find out at 2am again.
A quick purge of the ALSA state from /var/lib/alsa/asound.state thankfully reverted this, and also contained
control.31 {
iface MIXER
name 'Ext Spk Switch'
value false
comment {
access 'read write'
type BOOLEAN
count 1
}
}
control.32 {
iface MIXER
name 'Int Mic Switch'
value true
comment {
access 'read write'
type BOOLEAN
count 1
}
}
which amixer
lists as
Simple mixer control 'Ext Spk',0
Capabilities: pswitch pswitch-joined
Playback channels: Mono
Mono: Playback [on]
Simple mixer control 'Int Mic',0
Capabilities: pswitch pswitch-joined
Playback channels: Mono
Mono: Playback [on]
and either pressing m on it in alsamixer
or running amixer sset 'Ext Spk',0 on
(or off
)
made sound play from the speakers, with the counter-intuitive muted/off ⇒ headphones and unmuted/on ⇒ speakers.
If only there were a way to make this happen automatically like normal!
A quick peep with amixer events
yields
event value: numid=24,iface=CARD,name='Headphone Jack'
event value: numid=24,iface=CARD,name='Headphone Jack'
event value: numid=24,iface=CARD,name='Headphone Jack'
event value: numid=25,iface=CARD,name='Headset Mic Jack'
with the first two corresponding to plugging/unplugging a TRS jack, and the latter two corresponding to plugging a TRRS jack.
amixer contents
, then:
numid=24,iface=CARD,name='Headphone Jack'
; type=BOOLEAN,access=r-------,values=1
: values=on
numid=25,iface=CARD,name='Headset Mic Jack'
; type=BOOLEAN,access=r-------,values=1
: values=on
(note that it does also have Headphone Switch
and Headphone Playback Switch
(and the same for Speaker) as double-bools
but they appear to be only readable as part of a full dump – reading/writing via cget
/cset
just hangs).
Unfortunately amixer monitor
doesn't include the new data and the on/off is inverted hence the crusty-ass xor, but it's nevertheless a trivial program:
stdbuf -oL amixer events |
while read -r event value id; do
[ "$event $value" = "event value:" ] || continue
case "$id" in
*"'Headphone Jack'" ) ctl='Ext Spk'; inv=on ;;
*"'Headset Mic Jack'") ctl='Headset Mic'; inv=off ;;
* ) continue ;;
esac
amixer cget "$id" |
while IFS="$IFS=" read -r tp k v; do
[ "$tp $k" = ": values" ] || continue
case "$v$inv" in
onon|offoff) v=off ;;
onoff|offon) v=on ;;
esac
exec amixer sset "'$ctl'" "$v"
done
done
Further testing shows that if the Headset Mic
control is set to off it expectedly cuts out the TRRS microphone,
and this yields an all-zero recording – I haven't managed to get any input from the internal microphone, but this isn't really a big feature loss for me personally.
It's rather quite likely something like this is possible within the ALSA config itself.
I left both Headphon and Speaker at 33/59 (-12dB/0dB)
but dropped down the second Speaker (full name Speaker ClassD
) down from 92 (+1.58dB) to 72 (0dB).
There's a whole lot of dynamic range in the pipewire volume control.
And with all this we can
Further testing (triggered by wireplumber restarts causing Speaker
and Ext Spk
to mute again)
reveals you need to select
from the default
in the pavucontrol Output Devices panel and it works.
The HiFi "verb" appears to be
and selecting "Off" showed just dummy devices, and "Pro Audio" – two real devices that don't do anything.
The former does not appear to correspond to anything visible via pipewire (nor do I see it in the ALSA state), These settings are persistent (at last) but do not automatically switch when headphones are plugged in. Still no mic though.
All that's left is
because running off an SD card still sucks ass and continues to defeat the purpose.
Thankfully, we've already analysed bootloader discovery and the lay-out of the internal flash in
how is pointar formed kernal loaded?,
but out of the
many shortcuts the developer menu understands
not one of them is "boot kernel b actually",
which makes the ideal "add debian kernel and rootfs as default priority, keep KERN-A&ROOT-A with a downgraded priority as a recovery system"
configuration unworkable.
Indeed, if
ChromiumOS Docs - Disk Format, Selecting the kernel
is to be trusted, the entire "ChromeOS Kernel"-partition flag mechanism is used exclusively for effectively-one-time boot bundle verification after an update
and latches on the good kernel afterward.
This means two possibilities remain:
and the choice is obvious, since we already have that recovery image, and the path presents itself rather overtly:
Initial state
# fdisk /dev/mmcblk0
Welcome to fdisk (util-linux 2.39.3).
Changes will remain in memory only, until you decide to write them.
Be careful before using the write command.
GPT PMBR size mismatch (61063167 != 61071359) will be corrected by write.
The backup GPT table is not on the end of the device. This problem will be corrected by write.
Command (m for help): d
Partition number (1-12, default 12): 6
Partition 6 has been deleted.
Command (m for help): d
Partition number (1-5,7-12, default 12): 7
Partition 7 has been deleted.
Command (m for help): d
Partition number (1-5,8-12, default 12): 9
Partition 9 has been deleted.
Command (m for help): d
Partition number (1-5,8,10-12, default 12): 10
Partition 10 has been deleted.
Command (m for help): p
Disk /dev/mmcblk0: 29.12 GiB, 31268536320 bytes, 61071360 sectors
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disklabel type: gpt
Disk identifier: 8648551F-D8FC-AC44-AA00-C0CA32C4A9BC
Device Start End Sectors Size Type
/dev/mmcblk0p1 8704000 61063119 52359120 25G Microsoft basic data
/dev/mmcblk0p2 20480 53247 32768 16M ChromeOS kernel
/dev/mmcblk0p3 4509696 8703999 4194304 2G ChromeOS root fs
/dev/mmcblk0p4 53248 86015 32768 16M ChromeOS kernel
/dev/mmcblk0p5 315392 4509695 4194304 2G ChromeOS root fs
/dev/mmcblk0p8 86016 118783 32768 16M Microsoft basic data
/dev/mmcblk0p11 64 16447 16384 8M ChromeOS firmware
/dev/mmcblk0p12 249856 315391 65536 32M EFI System
Partition table entries are not in disk order.
Command (m for help): w
The partition table has been altered.
Calling ioctl() to re-read partition table.
Syncing disks.
(these are all cruft)
Command (m for help): d
Partition number (1-5,8,11,12, default 12): 8
Partition 8 has been deleted.
Command (m for help): d
Partition number (1-5,11,12, default 12):
Partition 12 has been deleted.
Command (m for help): p
Device Start End Sectors Size Type
/dev/mmcblk0p1 8704000 61063119 52359120 25G Microsoft basic data
/dev/mmcblk0p2 20480 53247 32768 16M ChromeOS kernel
/dev/mmcblk0p3 4509696 8703999 4194304 2G ChromeOS root fs
/dev/mmcblk0p4 53248 86015 32768 16M ChromeOS kernel
/dev/mmcblk0p5 315392 4509695 4194304 2G ChromeOS root fs
/dev/mmcblk0p11 64 16447 16384 8M ChromeOS firmware
(neither of these have anything of interest; I did make a backup of EFI-SYSTEM for completeness' sake)
Command (m for help): d
Partition number (1-5,11, default 11): 4
Partition 4 has been deleted.
Command (m for help): d
Partition number (1-3,5,11, default 11): 5
Partition 5 has been deleted.
Command (m for help): p
Device Start End Sectors Size Type
/dev/mmcblk0p1 8704000 61063119 52359120 25G Microsoft basic data
/dev/mmcblk0p2 20480 53247 32768 16M ChromeOS kernel
/dev/mmcblk0p3 4509696 8703999 4194304 2G ChromeOS root fs
/dev/mmcblk0p11 64 16447 16384 8M ChromeOS firmware
(of course, kill KERN-A/ROOT-A instead if KERN-B is the winner on your machine)
localhost# df -Th
Filesystem Type Size Used Avail Use% Mounted on
/dev/root ext2 2.0G 1.6G 418M 79% /
/dev/mmcblk0p1 ext4 25G 659M 23G 2% /mnt/stateful_partition
/dev/mapper/encstateful ext4 7.2G 145M 7.0G 2% /mnt/stateful_partition/encrypted
localhost# lsblk
NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINTS
loop1 7:1 0 7.3G 0 loop
`-encstateful 254:1 0 7.3G 0 dm /home/chronos
/var
/mnt/stateful_partition/encrypted
mmcblk0 179:0 0 29.1G 0 disk
|-mmcblk0p1 179:1 0 25G 0 part /var/cache/dlc-images
| /usr/local
| /home
| /mnt/stateful_partition
`-mmcblk0p3 179:3 0 2G 0 part /
localhost# du -haxd1 /mnt/stateful_partition
28K /mnt/stateful_partition/etc
4.0K /mnt/stateful_partition/dev_image
12K /mnt/stateful_partition/shutdown_umount_failure.log
4.0K /mnt/stateful_partition/encrypted.key
40K /mnt/stateful_partition/home
33M /mnt/stateful_partition/unencrypted
12K /mnt/stateful_partition/var_overlay
0 /mnt/stateful_partition/.developer_mode
4.0K /mnt/stateful_partition/umount-encrypted.log
16K /mnt/stateful_partition/lost+found
8.0K /mnt/stateful_partition/reboot_vault
489M /mnt/stateful_partition/encrypted.block
522M /mnt/stateful_partition
localhost# dmsetup table
encstateful: 0 15355208 crypt aes-cbc-essiv:sha256 :32:logon:dmcrypt:656e63737461746566756c 0 7:1 0 1 allow_discards
localhost# fstrim -v /mnt/stateful_partition/encrypted
/mnt/stateful_partition/encrypted: 7 GiB (7480754176 bytes) trimmed
localhost# du -h /mnt/stateful_partition/encrypted.block
323M /mnt/stateful_partition/encrypted.block
localhost# df -Th
Filesystem Type Size Used Avail Use% Mounted on
/dev/mmcblk0p1 ext4 25G 355M 23G 2% /mnt/stateful_partition
chwast# e2fsck -f /dev/disk/by-partlabel/ROOT-A
e2fsck 1.47.0 (5-Feb-2023)
Filesystem did not have a UUID; generating one.
ROOT-A: 11702/32000 files (9.7% non-contiguous), 402764/509696 blocks
chwast# resize2fs /dev/disk/by-partlabel/ROOT-A 1.7G
resize2fs 1.47.0 (5-Feb-2023)
resize2fs: Invalid new size: 1.7G
chwast# resize2fs /dev/disk/by-partlabel/ROOT-A 1704M
resize2fs 1.47.0 (5-Feb-2023)
The filesystem on /dev/disk/by-partlabel/ROOT-A is now 445440 (4k) blocks long.
chwast# e2fsck -f /dev/disk/by-partlabel/STATE
Pass 1: Checking inodes, blocks, and sizes
Inode 14 extent tree (at level 2) could be narrower. Optimize<y>? no
/dev/disk/by-partlabel/STATE: 152/1638400 files (2.0% non-contiguous), 238667/6544890 blocks
chwast# resize2fs /dev/disk/by-partlabel/STATE 384M
resize2fs: New size smaller than minimum (239160)
That's 940M! df and du agree on 355M used but e2fsck's block count also resolves to 932M! This means almost tripled usage of space vs the data inside; no fiddling around got me anywhere. How? What's in those 577M?
chwast# resize2fs /dev/disk/by-partlabel/STATE 960M
The filesystem on /dev/disk/by-partlabel/STATE is now 245760 (4k) blocks long.
chwast# mount /dev/disk/by-partlabel/STATE /mnt
chwast# fstrim -v /mnt
/mnt/: 400.5 MiB (419946496 bytes) trimmed.
chwast# umount /dev/disk/by-partlabel/STATE /mnt
chwast# e2fsck -fy /dev/disk/by-partlabel/STATE
/dev/mmcblk0p1: 152/65536 files (1.3% non-contiguous), 129018/245760 blocks
And that's 503M. Where did 437M go? Mysterium tytsei.
chwast# resize2fs /dev/disk/by-partlabel/STATE 512M -fz /tmp/undo
Overwriting existing filesystem; this can be undone using the command:
e2undo /tmp/undo /dev/disk/by-partlabel/STATE
The filesystem on /dev/disk/by-partlabel/STATE is now 131072 (4k) blocks long.
chwast# e2fsck -fyz /tmp/undo2 /dev/disk/by-partlabel/STATE
/dev/mmcblk0p1: 152/32768 files (2.6% non-contiguous), 124912/131072 blocks
chwast# resize2fs /dev/disk/by-partlabel/STATE 480M -fz /tmp/undo3
Overwriting existing filesystem; this can be undone using the command:
e2undo /tmp/undo3 /dev/disk/by-partlabel/STATE
Resizing the filesystem on /dev/disk/by-partlabel/STATE to 122880 (4k) blocks.
resize2fs: No space left on device while trying to resize /dev/disk/by-partlabel/STATE
Please run 'e2fsck -fy /dev/disk/by-partlabel/STATE' to fix the filesystem
after the aborted resize operation.
chwast# e2undo /tmp/undo3 /dev/disk/by-partlabel/STATE && rm /tmp/undo3
chwast# mount -r /dev/disk/by-partlabel/STATE /mnt
chwast# df -h /mnt
Filesystem Size Used Avail Use% Mounted on
/dev/mmcblk0p1 364M 340M 0 100% /mnt
Usually this would be a slightly more involved process because we'd want to keep it all on disk, but in this case they all easily fit in RAM, even all at once.
chwast:/tmp# cp /dev/disk/by-partlabel/KERN-A .
chwast:/tmp# cmp /dev/disk/by-partlabel/KERN-A KERN-A
chwast:/tmp# fdisk /dev/mmcblk0
Command (m for help): p
Device Start End Sectors Size Type
/dev/mmcblk0p1 8704000 61063119 52359120 25G Microsoft basic data
/dev/mmcblk0p2 20480 53247 32768 16M ChromeOS kernel
/dev/mmcblk0p3 4509696 8703999 4194304 2G ChromeOS root fs
/dev/mmcblk0p11 64 16447 16384 8M ChromeOS firmware
Command (m for help): x
Expert command (m for help): p
Device Start End Sectors Type-UUID UUID Name Attrs
/dev/mmcblk0p1 8704000 61063119 52359120 EBD0A0A2-B9E5-4433-87C0-68B6B72699C7 D8331AD0-ED78-F442-87F4-78DF0130895A STATE
/dev/mmcblk0p2 20480 53247 32768 FE3A2A5D-4F32-41A7-B725-ACCC3285A309 CCFE5BD8-BBE4-A840-9C0B-BBA6427B6309 KERN-A GUID:49,56
/dev/mmcblk0p3 4509696 8703999 4194304 3CB8E202-3B7E-47DD-8A3C-7FF2A13CFCEC E71F6E02-1BC3-9D43-9EDD-2C7CA20D512A ROOT-A
/dev/mmcblk0p11 64 16447 16384 CAB6E88E-ABF3-4102-A07A-D4BB9BE3C1D3 530A6C46-BDFA-7C40-A446-FC05001BDA82 RWFW
Expert command (m for help): r
Command (m for help): d
Partition number (1-3,11, default 11): 2
Partition 2 has been deleted.
Command (m for help): n
Partition number (2,4-10,12-128, default 2): 2
First sector (16448-61071326, default 18432): 16448 # doesn't need to be aligned
Last sector, +/-sectors or +/-size{K,M,G,T,P} (16448-4509695, default 4509695): +32767
# 32768 − 1 for fdisk +-based arithmetic
Created a new partition 2 of type 'Linux filesystem' and of size 16 MiB.
Command (m for help): t
Partition number (1-3,11, default 11): 2
Partition type or alias (type L to list all): 180
Changed type of partition 'Linux filesystem' to 'ChromeOS kernel'.
Command (m for help): x
Expert command (m for help): n
Partition number (1-3,11, default 11): 2
New name: KERN-A
Partition name changed from '' to 'KERN-A'.
Expert command (m for help): S
Partition number (1-3,11, default 11): 2
Enter GUID specific bit (48-63, default 48): 49
The GUID specific bit 49 on partition 2 is enabled now.
Expert command (m for help): S
Partition number (1-3,11, default 11): 2
Enter GUID specific bit (48-63, default 48): 56
The GUID specific bit 56 on partition 2 is enabled now.
Expert command (m for help): p
Device Start End Sectors Type-UUID UUID Name Attrs
/dev/mmcblk0p2 16448 49215 32768 FE3A2A5D-4F32-41A7-B725-ACCC3285A309 B9393B88-B27F-438D-BF88-93BE6E66E4A9 KERN-A GUID:49,56
Expert command (m for help): r
Command (m for help): p
Device Start End Sectors Size Type
/dev/mmcblk0p2 16448 49215 32768 16M ChromeOS kernel
Command (m for help): w
The partition table has been altered.
Calling ioctl() to re-read partition table.
Syncing disks.
chwast:/tmp# cp KERN-A /dev/disk/by-partlabel/KERN-A
chwast:/tmp# cmp KERN-A /dev/disk/by-partlabel/KERN-A
chwast:/tmp# e2image -rap /dev/disk/by-partlabel/ROOT-A ROOT-A
Copied 402500 / 402503 blocks (100%) in 00:00:08 at 196.53 MB/s
chwast:/tmp# ls -lh ROOT-A
-rw------- 1 root root 1.7G Feb 3 16:12 ROOT-A
chwast:/tmp# du -h ROOT-A
1.6G ROOT-A
chwast:/tmp# mount -r ROOT-A /mnt
chwast:/tmp# ls /mnt
bin dev etc home lib lost+found media mnt opt postinst proc root run sbin sys tmp usr var
chwast:/tmp# df -h /mnt/
Filesystem Size Used Avail Use% Mounted on
/dev/mmcblk0p3 1.7G 1.6G 168M 91% /mnt
chwast:/tmp# # all good!
chwast:/tmp# umount /mnt/
chwast:/tmp# fdisk /dev/mmcblk0
Command (m for help): d
Partition number (1-3,11, default 11): 3
Partition 3 has been deleted.
Command (m for help): n
Partition number (3-10,12-128, default 3): 3
First sector (49216-61071326, default 51200): # does need to be aligned
Last sector, +/-sectors or +/-size{K,M,G,T,P} (51200-8703999, default 8703999): +3563519
# resize2fs said "445440 (4k) blocks long" – 445440*4096/512 − 1
Created a new partition 3 of type 'Linux filesystem' and of size 1.7 GiB.
Command (m for help): t
Partition number (1-3,11, default 11): 3
Partition type or alias (type L to list all): 181
Changed type of partition 'Linux filesystem' to 'ChromeOS root fs'.
Command (m for help): x
Expert command (m for help): n
Partition number (1-3,11, default 11): 3
New name: ROOT-A
Partition name changed from '' to 'ROOT-A'.
Expert command (m for help): p
Device Start End Sectors Type-UUID UUID Name Attrs
/dev/mmcblk0p3 51200 3614719 3563520 3CB8E202-3B7E-47DD-8A3C-7FF2A13CFCEC ACB76082-35D1-46F0-A8E9-97006C40B632 ROOT-A
Expert command (m for help): r
Command (m for help): p
Device Start End Sectors Size Type
/dev/mmcblk0p3 51200 3614719 3563520 1.7G ChromeOS root fs
Command (m for help): w
chwast:/tmp# wc -c ROOT-A /dev/disk/by-partlabel/ROOT-A
1824522240 ROOT-A
1824522240 /dev/disk/by-partlabel/ROOT-A
chwast:/tmp# cp ROOT-A /dev/disk/by-partlabel/ROOT-A
chwast:/tmp# cmp ROOT-A /dev/disk/by-partlabel/ROOT-A
chwast:/tmp# mount -r /dev/disk/by-partlabel/ROOT-A /mnt
chwast:/tmp# ls /mnt
bin dev etc home lib lost+found media mnt opt postinst proc root run sbin sys tmp usr var
chwast:/tmp# df -h /mnt/
Filesystem Size Used Avail Use% Mounted on
/dev/mmcblk0p1 364M 340M 0 100% /mnt
chwast:/tmp# e2image -rap /dev/disk/by-partlabel/STATE STATE
Copied 122867 / 122871 blocks (100%) in 00:00:02 at 239.97 MB/s
chwast:/tmp# ls -lh STATE
-rw------- 1 root root 512M Feb 3 16:19 STATE
chwast:/tmp# du -h STATE
355M STATE
chwast:/tmp# mount -r STATE /mnt
chwast:/tmp# ls /mnt
dev_image encrypted encrypted.block encrypted.key etc home lost+found reboot_vault shutdown_umount_failure.log umount-encrypted.log unencrypted var_overlay
chwast:/tmp# df -h /mnt/
Filesystem Size Used Avail Use% Mounted on
/dev/loop0 364M 340M 0 100% /mnt
chwast:/tmp# # likewise!
chwast:/tmp# umount /mnt/
chwast:/tmp# fdisk /dev/mmcblk0
Command (m for help): d
Partition number (1-3,11, default 11): 1
Partition 1 has been deleted.
Command (m for help): n
Partition number (1,4-10,12-128, default 1): 1
First sector (34-61071326, default 3614720):
Last sector, +/-sectors or +/-size{K,M,G,T,P} (3614720-61071326, default 61069311): +1048575
# resize2fs: "131072" – 131072*4096/512 − 1
Created a new partition 1 of type 'Linux filesystem' and of size 512 MiB.
Command (m for help): t
Partition number (1-3,11, default 11): 1
Partition type or alias (type L to list all): 11
Changed type of partition 'Linux filesystem' to 'Microsoft basic data'.
Command (m for help): x
Expert command (m for help): n
Partition number (1-3,11, default 11): 1
New name: STATE
Partition name changed from '' to 'STATE'.
Expert command (m for help): p
Device Start End Sectors Type-UUID UUID Name Attrs
/dev/mmcblk0p1 3614720 4663295 1048576 EBD0A0A2-B9E5-4433-87C0-68B6B72699C7 DE9260C7-B796-4681-82E1-6BF5E1DDC405 STATE
/dev/mmcblk0p2 16448 49215 32768 FE3A2A5D-4F32-41A7-B725-ACCC3285A309 B9393B88-B27F-438D-BF88-93BE6E66E4A9 KERN-A GUID:49,56
/dev/mmcblk0p3 51200 3614719 3563520 3CB8E202-3B7E-47DD-8A3C-7FF2A13CFCEC ACB76082-35D1-46F0-A8E9-97006C40B632 ROOT-A
/dev/mmcblk0p11 64 16447 16384 CAB6E88E-ABF3-4102-A07A-D4BB9BE3C1D3 530A6C46-BDFA-7C40-A446-FC05001BDA82 RWFW
Expert command (m for help): r
Command (m for help): p
Device Start End Sectors Size Type
/dev/mmcblk0p1 3614720 4663295 1048576 512M Microsoft basic data
/dev/mmcblk0p2 16448 49215 32768 16M ChromeOS kernel
/dev/mmcblk0p3 51200 3614719 3563520 1.7G ChromeOS root fs
/dev/mmcblk0p11 64 16447 16384 8M ChromeOS firmware
Command (m for help): w
chwast:/tmp# cp STATE /dev/disk/by-partlabel/STATE
chwast:/tmp# cmp STATE /dev/disk/by-partlabel/STATE
And at this point booting to ChromeOS with ctrl+d still works! Amazing.
Rename the SD card – now recovery – rootfs so it doesn't get picked up for booting later.
localhost# fdisk /dev/mmcblk1
Command (m for help): p
Disk /dev/mmcblk1: 7.4 GiB, 7948206080 bytes, 15523840 sectors
Device Start End Sectors Size Type
/dev/mmcblk1p1 4864000 5839843 975844 476.5M Microsoft basic data
/dev/mmcblk1p5 411648 444415 32768 16M Linux filesystem
/dev/mmcblk1p6 444416 4638719 4194304 2G ChromeOS root fs
/dev/mmcblk1p9 4638720 4843519 204800 100M ChromeOS kernel
/dev/mmcblk1p10 11329502 15521791 4192290 2G Linux root (ARM-64)
/dev/mmcblk1p15 4843520 4863999 20480 10M Solaris alternate sector
Command (m for help): x
Expert command (m for help): p
Device Start End Sectors Type-UUID UUID Name Attrs
/dev/mmcblk1p1 4864000 5839843 975844 EBD0A0A2-B9E5-4433-87C0-68B6B72699C7 90330FF3-B8B8-124F-8285-416E7A627F64
/dev/mmcblk1p5 411648 444415 32768 0FC63DAF-8483-4772-8E79-3D69D8477DE4 8865BF3D-D8EA-574A-9C55-3AABEFC1E84D GUID:49,56
/dev/mmcblk1p6 444416 4638719 4194304 3CB8E202-3B7E-47DD-8A3C-7FF2A13CFCEC A0464221-9912-F146-AC7B-C6F489C25176
/dev/mmcblk1p9 4638720 4843519 204800 FE3A2A5D-4F32-41A7-B725-ACCC3285A309 1E061A8C-6159-4486-ADD1-988E88A06ACF GUID:49,56
/dev/mmcblk1p10 11329502 15521791 4192290 B921B045-1DF0-41C3-AF44-4C6F280D3FAE 525C4783-84CA-B249-ABC8-4635B19103BF chwast-root
/dev/mmcblk1p15 4843520 4863999 20480 6A9283A5-1DD2-11B2-99A6-080020736631 D733780B-EC52-3B4A-B568-FEB45F3C4903
Expert command (m for help): n
Partition number (1,5,6,9,10,15, default 15): 10
New name: chwast-recovery-root
Partition name changed from 'chwast-root' to 'chwast-recovery-root'.
Expert command (m for help): r
Command (m for help): w
and install – by copying – to the eMMC:
localhost# fdisk /dev/mmcblk0
Command (m for help): n
Partition number (4-10,12-128, default 4): 100
First sector (4663296-61071326, default 4663296):
Last sector, +/-sectors or +/-size{K,M,G,T,P} (4663296-61071326, default 61069311): +24M
Created a new partition 100 of type 'Linux filesystem' and of size 24 MiB.
Command (m for help): t
Partition number (1-3,11,100, default 100):
Partition type or alias (type L to list all): 174
Changed type of partition 'Linux filesystem' to 'ChromeOS kernel'.
Command (m for help): x
Expert command (m for help): n
Partition number (1-3,11,100, default 100):
New name: chwast-kernel
Expert command (m for help): S
Partition number (1-3,11,100, default 100):
Enter GUID specific bit (48-63, default 48): 49
The GUID specific bit 49 on partition 100 is enabled now.
Expert command (m for help): S
Partition number (1-3,11,100, default 100):
Enter GUID specific bit (48-63, default 48): 56
The GUID specific bit 56 on partition 100 is enabled now.
Expert command (m for help): p
Device Start End Sectors Type-UUID UUID Name Attrs
/dev/mmcblk0p100 4663296 4712447 49152 FE3A2A5D-4F32-41A7-B725-ACCC3285A309 B404D487-BF0B-A842-B93F-742DFB050BA5 chwast-kernel GUID:49,56
Expert command (m for help): r
Command (m for help): p
Device Start End Sectors Size Type
/dev/mmcblk0p100 4663296 4712447 49152 24M ChromeOS kernel
Command (m for help): n
Partition number (4-10,12-99,101-128, default 4): 101
First sector (4712448-61071326, default 4712448):
Last sector, +/-sectors or +/-size{K,M,G,T,P} (4712448-61071326, default 61069311): -4G
Created a new partition 101 of type 'Linux filesystem' and of size 22.9 GiB.
Command (m for help): t
Partition number (1-3,11,100,101, default 101):
Partition type or alias (type L to list all): 27
Changed type of partition 'Linux filesystem' to 'Linux root (ARM-64)'.
Command (m for help): x
Expert command (m for help): n
Partition number (1-3,11,100,101, default 101):
New name: chwast-root
Partition name changed from '' to 'chwast-root'.
Expert command (m for help): p
Device Start End Sectors Type-UUID UUID Name Attrs
/dev/mmcblk0p101 4712448 52682751 47970304 B921B045-1DF0-41C3-AF44-4C6F280D3FAE A1A44681-9DB6-5640-81F7-F469F51EAA7B chwast-root
Expert command (m for help): r
Command (m for help): p
Device Start End Sectors Size Type
/dev/mmcblk0p101 4712448 52682751 47970304 22.9G Linux root (ARM-64)
Command (m for help): n
Partition number (4-10,12-99,102-128, default 4): 102
First sector (52682752-61071326, default 52682752):
Last sector, +/-sectors or +/-size{K,M,G,T,P} (52682752-61071326, default 61069311):
Created a new partition 102 of type 'Linux filesystem' and of size 4 GiB.
Command (m for help): t
Partition number (1-3,11,100-102, default 102):
Partition type or alias (type L to list all): swap
Changed type of partition 'Linux filesystem' to 'Linux swap'.
Command (m for help): x
Expert command (m for help): n
Partition number (1-3,11,100-102, default 102):
New name: chwast-swap
Partition name changed from '' to 'chwast-swap'.
Expert command (m for help): p
Device Start End Sectors Type-UUID UUID Name Attrs
/dev/mmcblk0p1 3614720 4663295 1048576 EBD0A0A2-B9E5-4433-87C0-68B6B72699C7 DE9260C7-B796-4681-82E1-6BF5E1DDC405 STATE
/dev/mmcblk0p2 16448 49215 32768 FE3A2A5D-4F32-41A7-B725-ACCC3285A309 B9393B88-B27F-438D-BF88-93BE6E66E4A9 KERN-A GUID:48,56
/dev/mmcblk0p3 51200 3614719 3563520 3CB8E202-3B7E-47DD-8A3C-7FF2A13CFCEC ACB76082-35D1-46F0-A8E9-97006C40B632 ROOT-A
/dev/mmcblk0p11 64 16447 16384 CAB6E88E-ABF3-4102-A07A-D4BB9BE3C1D3 530A6C46-BDFA-7C40-A446-FC05001BDA82 RWFW
/dev/mmcblk0p100 4663296 4712447 49152 FE3A2A5D-4F32-41A7-B725-ACCC3285A309 B404D487-BF0B-A842-B93F-742DFB050BA5 chwast-kernel GUID:49,56
/dev/mmcblk0p101 4712448 52682751 47970304 B921B045-1DF0-41C3-AF44-4C6F280D3FAE A1A44681-9DB6-5640-81F7-F469F51EAA7B chwast-root
/dev/mmcblk0p102 52682752 61069311 8386560 0657FD6D-A4AB-43C4-84E5-0933C84B4F4F 0AAF87E8-B293-964A-8073-605103B71460 chwast-swap
Expert command (m for help): r
Command (m for help): p
Device Start End Sectors Size Type
/dev/mmcblk0p1 3614720 4663295 1048576 512M Microsoft basic data
/dev/mmcblk0p2 16448 49215 32768 16M ChromeOS kernel
/dev/mmcblk0p3 51200 3614719 3563520 1.7G ChromeOS root fs
/dev/mmcblk0p11 64 16447 16384 8M ChromeOS firmware
/dev/mmcblk0p100 4663296 4712447 49152 24M ChromeOS kernel
/dev/mmcblk0p101 4712448 52682751 47970304 22.9G Linux root (ARM-64)
/dev/mmcblk0p102 52682752 61069311 8386560 4G Linux swap
Command (m for help): w
localhost# cp /dev/mmcblk1p9 /dev/disk/by-partlabel/chwast-kernel
cp: error writing '/dev/disk/by-partlabel/chwast-kernel': No space left on device
# benign: overprovisioned at 100M, the actual bundle is <20M
localhost# blkdiscard /dev/disk/by-partlabel/chwast-root
localhost# e2image -rap /dev/mmcblk1p10 /dev/disk/by-partlabel/chwast-root
e2image 1.46.5 (30-Dec-2021)
Scanning inodes...
Copied 1852984 / 1852984 blocks (100%) in 00:01:56 at 15.60 MB/s s
localhost# mkswap -L chwast-swap /dev/disk/by-partlabel/chwast-swap
Setting up swapspace version 1, size = 4 GiB (4293914624 bytes)
LABEL=chwast-swap, UUID=d88296c6-5438-41f2-866a-e1e9e01b77b3
chwast-kernel on partition 100 has priority 2 (49=1, 48=0 ⇔ 0b10) with its Successful Boot Flag
set,
and will thus be chosen over KERN-A
(partition 2) with priority 1.
chwast# resize2fs /dev/dev/disk/by-partlabel/chwast-root
resize2fs 1.47.0 (5-Feb-2023)
Filesystem at /dev/disk/by-partlabel/chwast-root is mounted on /; on-line resizing required
old_desc_blocks = 8, new_desc_blocks = 92
The filesystem on /dev/dev/disk/by-partlabel/chwast-root is now 5926272 (4k) blocks long.
chwast# df -h
Filesystem Size Used Avail Use% Mounted on
/dev/mmcblk0p100 22G 1.7G 19G 8% /
has a propensity to shuffle the priorities, but it's nothing major.
Disable the successful boot flag on the Debian kernel:
chwast# fdisk /dev/mmcblk0
Command (m for help): x
Expert command (m for help): p
Device Start End Sectors Type-UUID UUID Name Attrs
/dev/mmcblk0p2 16448 49215 32768 FE3A2A5D-4F32-41A7-B725-ACCC3285A309 B9393B88-B27F-438D-BF88-93BE6E66E4A9 KERN-A GUID:48,56
/dev/mmcblk0p100 4663296 4712447 49152 FE3A2A5D-4F32-41A7-B725-ACCC3285A309 B404D487-BF0B-A842-B93F-742DFB050BA5 chwast-kernel GUID:49,56
Expert command (m for help): S
Partition number (1-3,11,100-102, default 102): 100
Enter GUID specific bit (48-63, default 48): 56
The GUID specific bit 56 on partition 100 is disabled now.
chwast# reboot
After rebooting, now to ChromeOS, note how the priorities were automatically inverted.
localhost# fdisk /dev/mmcblk0
Command (m for help): x
Expert command (m for help): p
Device Start End Sectors Type-UUID UUID Name Attrs
/dev/mmcblk0p2 16448 49215 32768 FE3A2A5D-4F32-41A7-B725-ACCC3285A309 B9393B88-B27F-438D-BF88-93BE6E66E4A9 KERN-A GUID:49,56
/dev/mmcblk0p100 4663296 4712447 49152 FE3A2A5D-4F32-41A7-B725-ACCC3285A309 B404D487-BF0B-A842-B93F-742DFB050BA5 chwast-kernel GUID:48
Expert command (m for help): S
Partition number (1-3,11,100-102, default 102): 100
Enter GUID specific bit (48-63, default 48): 56
The GUID specific bit 56 on partition 100 is enabled now.
Expert command (m for help): S
Partition number (1-3,11,100-102, default 102): 2
Enter GUID specific bit (48-63, default 48): 49
The GUID specific bit 49 on partition 2 is disabled now.
localhost# reboot
And with
the re-boot chooses the Debian kernel again. For a subsequent recovery run, toggling KERN-A's bit 49 would also work.
In pointed contrast to
012a. Installing Debian on the Lenovo 300e 2nd-gen Chromebook (Intel), Post Install, General QOL Fixes, Run the cros-keyboard-map script[…].
Escape
F1
F2
F3
F4
F5
F6
F7
F8
F9
F10
XF86Sleep
(🔒 is the Suspend Key and handled by logind by default.) Caps Lock is replaced with
Super_L
esc, 🔒, and 🔍 are the same as on the Intel 300e. All the other ones aren't, and this is for the best – you can switch VTs normally! You almost wouldn't notice the keyboard's fucked! sans the usual omissions of Home/End/Delete of course.
The clicky buttons on the side –
XF86AudioRaiseVolume
XF86AudioLowerVolume
– are distinguished from 🔉/🔊 this time! Imagine!
For these same inputs keyd yields
device added: 0000:0000 cros_ec (/dev/input/event0) device added: 06cb:1a10 hid-over-i2c 06CB:1A10 (/dev/input/event1) device added: 04f3:009f Elan Touchpad (/dev/input/event3) cros_ec 0000:0000 esc down cros_ec 0000:0000 f1 down cros_ec 0000:0000 f2 down cros_ec 0000:0000 f3 down cros_ec 0000:0000 f4 down cros_ec 0000:0000 f5 down cros_ec 0000:0000 f6 down cros_ec 0000:0000 f7 down cros_ec 0000:0000 f8 down cros_ec 0000:0000 f9 down cros_ec 0000:0000 f10 down cros_ec 0000:0000 sleep down cros_ec 0000:0000 leftmeta down
– note that the side buttons don't generate any input event! But this agrees with our other findings, and thus, for the same mapping as last time, a simple /etc/keyd/cros_ec.conf of
[ids]
0000:0000
[alt]
left = home
right = end
up = pageup
down = pagedown
[main]
# Don't mangle these (https://github.com/rvaiya/keyd/issues/618)
rightcontrol = rightcontrol
rightshift = rightshift
# 🔒
sleep = delete
# 🔍 remains as leftmeta
[meta]
# ←
f1 = back
# →
f2 = forward
# ⟳
f3 = refresh
# tableau
f4 = print
# fast rectangle
f5 = scale
# small ☀️
f6 = brightnessdown
# ☀️
f7 = brightnessup
# 🔇
f8 = mute
# 🔉
f9 = volumedown
# 🔊
f10 = volumeup
sleep = sleep
suffices.
Yeah so the touchpad has one button.
This by itself is baffling, but since the "Tapping" mode basically a necessity for the modern user anyway (the methodology in 012a. Installing Debian on the Lenovo 300e 2nd-gen Chromebook (Intel), Installing Linux, /etc/X11/xorg.conf.d/touchpad.conf applies) it's only an issue for the first 10min because clicking touchpads sucks on a good day so the
mapping thus enabled is all-'round better than only having two buttons would've been. Plus, there's already a 75-big pad for clicking just above.
Doesn't work.
But it does work under ChromeOS, with dmesg | grep -i hdmi
yielding
[ 0.130803] mediatek-hdmi-phy 10209100.hdmi-phy: Using default TX DRV impedance: 4.2k/36
[ 0.131789] mediatek-drm-hdmi 14025000.hdmi: Waiting for external bridge
[ 0.133463] gpio-display-mux hdmi_mux: GPIO lookup for consumer detect
[ 0.133468] gpio-display-mux hdmi_mux: using device tree for GPIO lookup
[ 0.133485] of_get_named_gpiod_flags: parsed 'detect-gpios' property of node '/hdmi_mux[0]' - status (0)
[ 0.133519] gpio-display-mux hdmi_mux: Waiting for external bridge anx7688
[ 0.960402] mediatek-drm-hdmi 14025000.hdmi: Waiting for external bridge
[ 0.960636] gpio-display-mux hdmi_mux: GPIO lookup for consumer detect
[ 0.960638] gpio-display-mux hdmi_mux: using device tree for GPIO lookup
[ 0.960645] of_get_named_gpiod_flags: parsed 'detect-gpios' property of node '/hdmi_mux[0]' - status (0)
[ 0.967421] [drm] hdmi-audio-codec driver bound to HDMI
[ 0.968986] mtk-rt5650 sound: snd-soc-dummy-dai <-> HDMI mapping ok
[ 0.969679] mtk-rt5650 sound: i2s-hifi <-> HDMIO mapping ok
[ 1.025253] input: mtk-rt5650 HDMI Jack as /devices/platform/sound/sound/card0/input6
[ 1.025521] mediatek-dpi 1401d000.dpi: Found bridge node: /soc/hdmi@14025000
[ 11.742614] udevd[2142]: Process '/usr/sbin/hdcp_pass_key.sh /devices/platform/soc/14025000.hdmi' failed with exit code 1.
[ 11.895324] udevd[2145]: Process '/usr/sbin/hdcp_pass_key.sh /devices/platform/soc/14025000.hdmi/hdmi-audio-codec.11.auto' failed with exit code 1.
whereas the same under 6.6.11 #137 is only
[ 18:20:17] platform 14025000.hdmi: Fixed dependency cycle(s) with /soc/dpi@1401d000/port/endpoint
[ 18:20:17] platform connector: Fixed dependency cycle(s) with /soc/hdmi@14025000/ports/port@1/endpoint
[ 18:20:17] mediatek-hdmi-phy 10209100.hdmi-phy: Using default TX DRV impedance: 4.2k/36
[ 18:20:17] [drm] hdmi-audio-codec driver bound to HDMI
[ 18:20:17] mediatek-dpi 1401d000.dpi: Found bridge node: /soc/hdmi@14025000
[ 18:20:20] input: mtk-rt5650 HDMI Jack as /devices/platform/sound/sound/card0/input9
(matching lines lowlighted). So only the audio goop is common.
Fortuitously, while a grep for of_get_named_gpiod_flags
was uneventful,
a grep for gpio-display-mux
yielded nothing – not one single reult – in the 6.6.11 tree.
Well then!
gpio-display-mux
figures in the
ChromeOS device tree as
and not at all in the 6.6.11 one; the first google result is [v3,4/5] dt-bindings: display: bridge: Add GPIO display mux binding, part of the [PATCH v3 0/5] Add generic-display-mux driver and bindings, series from 2023-02-18. (Attentive readers may remember this is a 2019 device.) All great, except this series is dropped because it doesn't do something-or-other cromulently enough for the DRM subsystem. If only you could've arrived at this before you shipped hundreds of thousands of units!
The series from patchwork applies with minimal fuzz; this also references the analogix,anx7688 device –
spi@1100a000 {
ec@0 {
i2c-tunnel@1 {
compatible = "google,cros-ec-i2c-tunnel";
google,remote-bus = <0x01>;
#address-cells = <0x01>;
#size-cells = <0x00>;
anx7688@2c {
compatible = "analogix,anx7688";
status = "okay";
reg = <0x2c>;
– also not present (incl. the tunnel) in the 6.6.11 device tree, also with no compatible module. There's an extrmely crusty patch for it (targetting the PinePhone) from this Thursday; it also applies with no fuzz.
$ make -j25 ARCH=arm64 LLVM=1 oldconfig Generic GPIO-controlled mux (DRM_GENERIC_GPIO_MUX) [N/m/y/?] (NEW) y Analogix ANX7688 Type-C DRP Port controller and mux driver (TYPEC_ANX7688) [N/m/y/?] (NEW) y
and it builds fine as well. Neither of them change the device tree, however, so I carefully grafted both devices thereinto, yielding
18M 02-04 19:44 mandeb+initrd+1+tabs2+reg+drm+adc+d_t_c-initrd&mwifiex+mmc1+gpio-display-mux.dtb
18M 02-04 19:53 mandeb+initrd+1+tabs2+reg+drm+adc+d_t_c-initrd&mwifiex+mmc1+gpio-display-mux2.dtb
18M 02-04 20:09 mandeb+initrd+1+tabs2+reg+drm+adc+d_t_c-initrd&mwifiex+mmc1+gpio-display-mux3.dtb
18M 02-04 20:29 mandeb+initrd+1+tabs2+reg+drm+adc+d_t_c-initrd&mwifiex+mmc1+gpio-display-mux3+anx.dtb
which boots to black screen, neither alt+🔊+r nor ⟳+power button leave anything in the pstore.
Heretofore the device trees to sign/bundle and boot were a bastardised version of the ChromeOS boot bundle's device tree.
This works, but is both plain odd and existentially problematic –
what is the boot bundles contain device trees without the right compatible = stanza like in EFI-SYSTEM
?
Given that the bootloader coughs up to Starting depthcharge on hana...
,
a quick "site:manpages.debian.org depthcharge" search yields
mkdepthcharge(1)
(as part of depthcharge-tools,
which also includes kernel/initrd hooks,
pulls in a tremendous amount of dependencies,
and ships a service to massage the partition table on boot
– absolutely not happening, sorry),
pointing at mkimage(1) (u-boot-tools),
and mkimage -l mandeb+initrd+1+tabs2+reg+drm+adc+d_t_c-initrd\&mwifiex+mmc1-sdr.dtb
starts with
Image contains unit addresses @, this will break signing
FIT description: Chrome OS kernel image with one or more FDT blobs
Created: Mon Apr 17 04:48:47 2023
Image 0 (kernel@1)
Description: unavailable
Created: Mon Apr 17 04:48:47 2023
Type: Kernel Image (no loading done)
Compression: lz4 compressed
Data Size: 15550846 Bytes = 15186.37 KiB = 14.83 MiB
Image 1 (fdt@1)
Description: mt2712-evb.dtb
Created: Mon Apr 17 04:48:47 2023
Type: Flat Device Tree
Compression: uncompressed
Data Size: 8174 Bytes = 7.98 KiB = 0.01 MiB
Architecture: AArch64
Hash algo: sha1
Hash value: 2cb3b42d319ed9579540b17d7c2c68863329e8fe
…
Configuration 0 (conf@1)
Description: unavailable
Kernel: kernel@1
FDT: fdt@1
– certainly promising.
By adapting an example from the manual, mkimage -f auto -A arm64 -T kernel -C lz4 -d Image.lz4 -b mt8173-elm-hana.dtb Image.dtb (naturally, here the architecture defaults to PowerPC; the kernel must already be pre-LZ4ed and not a pipe) produces Image.dtb, which, after decompilation, looks like
/dts-v1/;
/ {
timestamp = <0x65c03b5b>;
description = "Kernel Image image with one or more FDT blobs";
creator = "U-Boot mkimage 2023.01";
#address-cells = <0x01>;
images {
kernel-1 {
description = [00];
type = "kernel";
arch = "arm64";
os = "linux";
compression = "lz4";
load = <0x00>;
entry = <0x00>;
data = [04 22 4d 18 …];
hash-1 {
value = <0x9e4dfdd9>;
algo = "crc32";
};
};
fdt-1 {
description = "mt8173-elm-hana";
data = [d0 0d fe ed …];
type = "flat_dt";
arch = "arm64";
compression = "none";
hash-1 {
value = <0xae9f8591>;
algo = "crc32";
};
};
};
configurations {
default = "conf-1";
conf-1 {
description = "mt8173-elm-hana";
kernel = "kernel-1";
loadables = "kernel-1";
fdt = "fdt-1";
};
};
};
(note the differences from ChromeOS's –
both are hashed, but with CRC32;
IDs delimited with -es instead of @s).
The type is kernel rather than kernel_noload (Kernel Image (no loading done)
)
because if you use kernel_noload then it doesn't boot because it calls the node kernel_noload-1.
You could decompile/re-tag to type = "kernel_noload"/recompile to match ChromeOS, which works,
and mkdepthcharge appears convinced is required,
but it doesn't appear to change anything,
and -T kernel just works.
This makes the final kernel installation look like
$ lz4 -9 < .../arch/arm64/boot/Image > Image.lz4
$ mkimage -f auto -A arm64 \
-T kernel -C lz4 -d Image.lz4 \
-b .../arch/arm64/boot/dts/mediatek/mt8173-elm-hana.dtb \
Image.dtb
FIT description: Kernel Image image with one or more FDT blobs
Created: Mon Feb 5 01:17:41 2024
Image 0 (kernel-1)
Description:
Created: Mon Feb 5 01:17:41 2024
Type: Kernel Image
Compression: lz4 compressed
Data Size: 12611929 Bytes = 12316.34 KiB = 12.03 MiB
Architecture: AArch64
OS: Linux
Load Address: 0x00000000
Entry Point: 0x00000000
Hash algo: crc32
Hash value: 03808745
Image 1 (fdt-1)
Description: mt8173-elm-hana
Created: Mon Feb 5 01:17:41 2024
Type: Flat Device Tree
Compression: uncompressed
Data Size: 43853 Bytes = 42.83 KiB = 0.04 MiB
Architecture: AArch64
Hash algo: crc32
Hash value: ae9f8591
Default Configuration: 'conf-1'
Configuration 0 (conf-1)
Description: mt8173-elm-hana
Kernel: kernel-1
FDT: fdt-1
Loadables: kernel-1
$ printf '\0' > bootloader
$ echo root=PARTLABEL=chwast-root rootwait console=pstore-1 console=tty1 > cmdline
# vbutil_kernel --pack /dev/disk/by-partlabel/chwast-root \
--keyblock /usr/share/vboot/devkeys/kernel.keyblock \
--signprivate /usr/share/vboot/devkeys/kernel_data_key.vbprivk \
--version 1 \
--vmlinuz Image.dtb \
--bootloader bootloader \
--config cmdline \
--arch arm64
which provides for a roughly-normal /boot and a simple installation script,
18M 02-04 21:36 mandeb+initrd+1+tabs2+reg+drm+adc+d_t_c-initrd&mwifiex+mmc1-sdr.dtb
13M 02-05 04:24 6.6.11.bundle
The firmware, which logged
Boot policy: Match for type 0 with cmdline 1
Modified kernel command line: cros_secure console= loglevel=7 init=/sbin/init cros_secure drm.trace=0x106 root=PARTUUID=ccfe5bd8-bbe4-a840-9c0b-bba6427b6309/PARTNROFF=1 rootwait rw dm_verity.error_behavior=3 dm_verity.max_bios=-1 dm_verity.dev_wait=0 dm="1 vroot none ro 1,0 4077568 verity payload=ROOT_DEV hashtree=#_DEV hashstart=4077568 alg=sha256 root_hexdigest=59f5ac907dd5cfa3f6fdef15b166c94065a41ef4abfd0d9c68db6ef4a2f62a68 salt=05e2c9a8dc172bc5efe0c899186b436bb89609a064eabcaeb5ec07441cf2a122" noinitrd vt.global_cursor_default=0 kern_guid=ccfe5bd8-bbe4-a840-9c0b-bba6427b6309 cpuidle.governor=teo
Loading FIT.
Image fdt@54 has 61778 bytes.
…
Image fdt@1 has 8174 bytes.
Image kernel@1 has 8706585 bytes.
Compat preference: google,hana-rev5
Config conf@54, kernel kernel@1, fdt fdt@54, compat google,willow-sku1 google,willow mediatek,mt8183
…
Config conf@9, kernel kernel@1, fdt fdt@9, compat google,hana-rev6 google,hana-rev5 (match) google,hana-rev4 google,hana-rev3 google,hana-rev2 google,hana-rev1 google,hana mediatek,mt8173
…
Config conf@1, kernel kernel@1, fdt fdt@1, compat mediatek,mt2712-evb mediatek,mt2712
Choosing best match conf@9.
Shutting down all USB controllers.
Exiting depthcharge with code 4 at timestamp: 5889734
Decompressing LZ4 kernel to 0x40080000
jumping to kernel
now logs
Boot policy: Match for type 0 with cmdline 1
Modified kernel command line: cros_secure root=PARTLABEL=chwast-root rootwait console=pstore-1 console=tty1
Loading FIT.
Image fdt-1 has 43853 bytes.
Image kernel-1 has 12611929 bytes.
Compat preference: google,hana-rev5
Config conf-1 (default), kernel kernel-1, fdt fdt-1, compat google,hana-rev6 google,hana-rev5 (match) google,hana-rev4 google,hana-rev3 google,hana mediatek,mt8173
Choosing best match conf-1.
Shutting down all USB controllers.
Exiting depthcharge with code 4 at timestamp: 2759765
Decompressing LZ4 kernel to 0x40000000
jumping to kernel
"sbs-%s"
) reports time-to-empty and time-to-full in seconds.
The APM driver ("BAT%d"
, commonly used on x86) reports them in minutes.
As the only manifestation of the amd64 monoculture I really encountered,
userspace software may not expect this,
and i3status reports 974 hours to drain and 1032:15 to charge.the Magic SysRq keyat all.
CONFIG_XFS=y
or whatever in the config below); mount on /mntapt source linux
cp /boot/config-6.6.11-arm64 .config
; paths per debian/rules.gen):
debian/bin/kconfig.py .config debian/config/config debian/config/arm64/config
make ARCH=arm64 olddefconfig
scripts/kconfig/merge_config.sh -m .config config-6.6.11.diff-m
patch -p1 < mwifiex.patch # warning backtrace; from Dmitry Antipov, though the patch in the mail is damaged
patch -p1 < mt8173-fix-mmc1-speed.patch # oops when using SDR104 cards; from mt8173-fix-mmc1-speed.patch
patch -p1 < mt8173-higher-temps.patch # raise temps for elm a bit
; from mt8173-higher-temps.patch
make ARCH=arm64 Image modules dtbs
make ARCH=arm64 modules_install INSTALL_MOD_PATH=/mnt INSTALL_MOD_STRIP=1
lz4 -9 < arch/arm64/boot/Image > /mnt/boot/Image-6.6.11.lz4
(or whatever the version)cp arch/arm64/boot/dts/mediatek/mt8173-elm-hana.dtb /mnt/boot/mt8173-elm-hana-6.6.11.dtb
echo console=pstore-1 console=tty1 rootwait root=as appropriate for the rootfs > cmdline
&c../bundle 6.6.11 > /dev/the-kernel-partition
sbs_6_000b-i2c-6-0b Adapter: cros-ec-i2c-tunnel in0: 11.37 V temp: +22.6°C curr1: -386.00 mA (avg = -0.38 A) cpu_thermal-virtual-0 Adapter: Virtual device temp1: +45.6°C CROS_USBPD_CHARGER0-isa-0000 Adapter: ISA adapter in0: 0.00 V curr1: N/A (max = +0.00 A)
A successful non-invasive reversible methodology to install Debian on a presently-still-novel ARM64 Chromebook platform, all possible because the MT8173 platform is well-supported by Linux and because the elm/hana platform is reasonably-supported by Linux (sans the HDMI thing).
A top-down and bottom-up analysis of the Chromebook bootloader stack with effectively no a priori knowledge, and attempts at replication of various documentation showing mostly negative results.
1.94W idle (at a reasonable indoor backlight brightess) is the lowest power consumption I've seen on a computer. This is maintained at around 2.3W during static web browsing, and extends to >12h projected times-to-empty at around 70% battery capacity (~23h at ~100%).. There are no hardware accelerators that Firefox understands; there's no OpenGL; fullscreen glxgears (llvmpipe) gets 57FPS, half-screen gets 140FPS, both at around 7W.
Issues identified (chronological order):
13M 02-06 19:18 6.6.15.bundle
25 straight days well spent on
commit 9628372: Add hardware-accellerated crc32c() for ARM64.
Buy my album buy my stickers.
Nit-pick? Correction? Improvement? Annoying? Cute? Anything?
Mail,
post, or open!