levinboot suspend Fun with Pinebook Pro

WARNING! DO THIS AT YOUR OWN RISK! POSSIBLE BRICKING OF PINEBOOK PRO!

UPDATE 2024-07-24: honestly…. just throw this piece of crap out. 😂 after years of trying to make this thing something that was even worth anything at all it fails miserably. you are better off finding an ancient 2010s macbook pro and installing linux on that.

UPDATE 2022-06-13: had a hiccup on my first day using suspend. seems like samba+winbind+pam+nss did not like coming off the AD network when i started it back up. it wasn’t a complete loss i just had to get back to lightdm and log back in using cached credentials. i am searching for a fix for this now but this is a bit difficult to test without coming off the network then figuring out a way to get back into the state i was in. otherwise, suspend has been a massive improvement on battery life if you are constantly closing and opening the pbp.

anybody who has a pinebook pro has probably lost their mind because suspend doesn’t work. this makes having an arm based laptop rather moot. i learned that using levinboot instead of u-boot with the lts linux kernel allows for actual legitimate suspend to ram to work. it still eats up around 2%/hr of battery life but that is still way better than s2idle or just leaving it on. it also means carrying a charger around isn’t as important. sorry but nvme still has its issues. so if you have one, you either have to pull it out or just not do this. i had to yank mine out. serial cable is super duper ridiculously highly recommended.

this was done with manjaro (running xfce) which is what i use day to day on the pbp on emmc. you first have to install linux-lts over linux. this is because there are bugs in the more recent manjaro kernels that prevent it from working. lts is decent and still works (5.15.x). first edit /etc/mkinitcpio.conf and you will see this line…

MODULES=(rtc_rk808 rockchipdrm panel_edp pwm_bl)

change panel_edp to panel_simple so the line looks like this…

MODULES=(rtc_rk808 rockchipdrm panel_simple pwm_bl)

one you do this replace whatever kernel you have with the lts kernel with…

# pacman -S linux-lts linux-lts-headers

it will ask you to remove linux (and linux-headers) for whatever kernel you are running and it will replace them. after you do this you should completely power down and power back up again. this is just to ensure the kernel is functional. you should see something like…

# uname -a
Linux hostname 5.15.43-1-MANJARO-ARM-LTS #1 SMP PREEMPT Wed May 25 13:20:50 UTC 2022 aarch64 GNU/Linux

the reason you reboot is to ensure u-boot still works. using levinboot essentially stops you from using u-boot. it is important to know this because it means that you either need to write u-boot back to emmc or you need to get an img that is made using a levinboot payload.

levinboot uses a partition that you write raw to. unlike u-boot which requires you write two files to /dev/mmcblk2 (or 1 for sd), levinboot just needs one write to the actual device. you then write a payload raw to a partition using a special guuid. to use an analogy related to u-boot: it would be like writing idbloader.img but then writing u-boot to a partition instead of the main device. i probably didn’t explain that properly but you’ll understand once you start doing it.

we want to ensure u-boot can still be brought back to life if necessary. there may be a lot of reasons you may want to do this (mostly because u-boot has active development and cross arch universal appeal). so we are going to ensure that /boot with all the u-boot bits still exists. i accomplished this by moving /boot (which in manjaro has its own partition on mmcblk2p1) to /boot unmounted on /dev/mmcblk2p2. essentially stopping it from having its own partition. in order to do this you need to..

# cd /mnt
# mkdir tmp
# umount /dev/mmcblk2p1
# mount /dev/mmcblk2p1 /mnt/tmp
# cd /mnt/tmp/
# cp -Rvp * /boot
# cd /boot
# umount /dev/mmcblk2p1

you have essentially copied anything u-boot needs to the larger partition on the emmc. now edit /etc/fstab and remove any references to /boot that you see. afterwards edit /boot/extlinux/extlinux.conf and change any references to dirs you see there to /boot/… it will look something like this…

LABEL Manjaro ARM
KERNEL /boot/Image
FDT /boot/dtbs/rockchip/rk3399-pinebook-pro.dtb
APPEND initrd=/boot/initramfs-linux.img console=ttyS2,1500000n8 … other options…

shut it down and start it back up again to ensure u-boot can still function. login and make sure /dev/mmcblk2p1 did not mount under boot. this can be checked quickly with df -h.

next you will need this awesome package created by Venom668 who packaged levinboot and it can be loaded side by side with u-boot.

save the file somewhere and go to the dir it is in and use pacman to install it…

# pacman -U levinboot-0.8.6.1-aarch64.pkg.tar.zst

he was nice enough to add instructions. just a warning. once you write levinboot-sd.img to emmc you have essentially ‘gotten rid of’ u-boot. you can no longer boot u-boot based sds. so this is really something you only do if you only want a functional laptop and do not want to use it as a playground. before doing the writing though you should take a look at cmdline.txt.

# cd /boot/levinboot
# nano -w cmdline.txt

ok. so the easiest way i found to modify the cmdline.txt was to just take the append portion of u-boot extlinux.conf, remove the initrd=linux… portion… and take the remainder and toss it into cmdline.txt. so your cmdline.txt should look SOMETHING similar to this (NOTE: NOT EXACTLY… COPY AND PASTE YOUR OWN PARTUUID FOR root=. I totally screwed myself doing this the first time out). pay close attention to this one and don’t rush it… this is all one line…

console=ttyS2,1500000n8 earlycon=uart8250,mmio32,0xff1a0000 ignore_loglevel no_console_suspend keep_bootcon root=PARTUUID=<YOUR PARTUUID!!> rw rootwait audit=0 plymouth.ignore-serial-consoles ipv6.disable=1

some of the stuff i have there you may not need but this is what i use. like i said. just take whatever is in your extlinux.conf and paste it in other than the initrd=thisstuff portion. after you are done doing this in the /boot/levinboot dir there is a script to update the payload.img. run the script from /boot/levinboot.

# ./update-payload.sh

this script will create a new payload.img that you will write raw to the /dev/mmcblk2p1 partition. now you have to move onto fdisk…

tl;dr…

# fdisk /dev/mmcblk2

> t
> 1
> e5ab07a0-8e5e-46f6-9ce8-41a518929b7c
> x
> A
> 2
> w

just a rundown of this black box stuff… t changes a partition tag, 1 is the partition you are choosing (mmcblk2p1), e5ab07a0-8e5e-46f6-9ce8-41a518929b7c is a special guuid that levinboot uses to know this is the partition that it has a payload on, x swaps you to expert mode, A sets a boot flag to partition, 2 so you can boot u-boot later if you really have to. i am not sure if u-boot needs the boot flag to be set but better safe than sorry. it won’t hurt anything anyways, w write to disk and exit. i did this while everything was mounted because you’re really just toying with the partition table and not doing much by way of resizing partitions.

so at this point your emmc should be good to write levinboot to your emmc and partition. from /boot/levinboot…

# dd if=levinboot-sd.img of=/dev/mmcblk2
# dd if=payload.img of=/dev/mmcblk2p1

for safe measure but probably not necessary…
# sync

you can also add conv=fsync if you are paranoid. it’s a pinebook… just saying. at this point you SHOULD be able to power down. cross your fingers. power it back up. and boot.

if you managed to make the alchemy work then you should see a rather quick booting into manjaro. the real test is making sure suspend to ram works. what you should do first is just hold alt+ctrl and press F2 in order to swing over to a console login (if you have a ui based one like lightdm or gdm running). login as root or as a user who can sudo -s. then sudo -s and become root and do this…

# cat /sys/power/mem_sleep

you should see [deep]. this means that the pinebook pro is set to suspend to ram. if it is not then something is wrong. you can force it but i doubt it would help later when you try to suspend it…

# echo deep > /sys/power/mem_sleep

before the final testing you may want to edit a couple of things…

EDIT: /etc/systemd/login.conf
HandlePowerKey=ignore

EDIT: /etc/systemd/sleep.conf
AllowSuspend=yes
SuspendState=mem

once that’s done your pinebook pro should be sort of all set for sleep mode. you may want to reboot one more time just to ensure these settings are in effect. the first edit is because once you press the power button to turn it back on then once it comes out of sleep mode it will turn off.

once you are set. you are booting levinboot. your /sys/power/mem_sleep says [deep]. you can run this…

# echo mem > /sys/power/state

the second you hit enter your pinebook pro SHOULD go to suspend to ram. it would be easier to confirm this with a serial cable but another easy way is to wait around 20-30s and press the power button on the keyboard for about 2-3s to wake it up. if it comes back to life you are successful and can finally use it how it should be used. i am not sure about other desktop environments (like gnome or kde) but i think they all call systemd in order to control sleep mode so you should be able to set all the settings that you normally do in order to do things like closing the lid to put it to sleep. at least for me in xfce this all seems to function properly. suspend key works and closing the lid puts it to sleep and opening it again wakes it up.

good luck. if you got it to work you can bask in the glory of finally having an arm based laptop that doesn’t get charged like an x64.