Use single partition to boot Linux on Phicomm N1All your data will be lost if you do something wrong. Don’t follow this post unless you’re ABSOLUTELY aware of what you’re doing.
Well, this idea has come to me for some time, but I didn’t want bother doing that until yesterday, when I upgraded my box to Linux 5.1.7.
ext4load
supports path (rather than file names only), so it’s possible to ask it to load files in /boot
.
Firstly I repartitioned my eMMC, create a single (large) partition starts at 100M, the script I used is posted below.
There are several caveats here, though:
- You may not create the partition from the beginning of the eMMC. Or you’ll be in trouble. (Those blocks are used by bootloader, etc., and are “reserved”.)
Feature 64bit
of ext4
must be turned off, since it’s not recognized by U-boot. (This took me some time to realize, thanks to a comment on StackOverflow.) You can find more discussions here. I kept metadata_csum
, as I didn’t see troubles with it (I’m still testing with it. I may turn out to be wrong.). This is also done by the script.
Several blocks may not be used by Linux, they’re marked as “bad block”s by the script.
The script also backup and restores the first 4M of /dev/mmcblk1
(except for partition table). I copied them from an earlier script. IIUC this is not strictly required, as the first sector should be not used by U-boot anyway. But I didn’t test that.
1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162 #/usr/bin/env bashset -e # So as to not overwrite U-boot, we backup the first 1M.dd if=/dev/mmcblk1 of=/tmp/boot-bak bs=1M count=4 # (Re-)initialize the eMMC and create a partition.## `bootloader` / `reserved` occupies [0, 100M). Since sector size is 512B, byte# offset would be 204800.parted -s /dev/mmcblk1 mklabel msdosparted -s /dev/mmcblk1 unit s mkpart primary ext4 204800 100% # Restore U-boot (except the first 442 bytes, where partition table is stored.)dd if=/tmp/boot-bak of=/dev/mmcblk1 conv=fsync bs=1 count=442dd if=/tmp/boot-bak of=/dev/mmcblk1 conv=fsync bs=512 skip=1 seek=1 # This method is used to convert byte offset in `/dev/mmcblk1` to block offset# in `/dev/mmcblk1p1`.as_block_number() { # Block numbers are offseted by 100M since `/dev/mmcblk1p1` starts at 100M # in `/dev/mmcblk1`. # # Because we're using 4K blocks, the byte offsets are divided by 4K. expr $((($1 - 100 * 1024 * 1024) / 4096))} # This method generates a sequence of block number in range [$1, $1 + $2).## It's used for marking several reserved regions as bad blocks below.gen_blocks() { seq $(as_block_number $1) $(($(as_block_number $(($1 + $2))) - 1))} # Mark reserved regions as bad block to prevent Linux from using them.## /dev/env: This "device" (present in Linux 3.x) uses 0x27400000 ~ +0x800000.# It seems that they're overwritten each time system boots if value# there is invalid. Therefore we must not touch these blocks.## /dev/logo: This "device" uses 0x28400000~ +0x800000. You may mark them as# bad blocks if you want to preserve or replace the boot logo.## All other "devices" (i.e., `recovery`, `rsv`, `tee`, `crypt`, `misc`, `boot`,# `system`, `data` should be safe to overwrite.)gen_blocks 0x27400000 0x800000 > /tmp/reservedblksecho "Marked blocks used by /dev/env as bad." # Let's see if a boot logo is to be installed.if [ -e /boot/n1-logo.img ]; then dd if=/boot/n1-logo.img of=/dev/mmcblk1 bs=1M seek=644 echo "Boot logo installed." gen_blocks 0x28400000 0x800000 >> /tmp/reservedblks echo "Marked blocks used by /dev/logo as bad."fi # Format the partition. Feature `64bit` of ext4 is disabled.mke2fs -F -q -O ^64bit -t ext4 -m 0 /dev/mmcblk1p1 -b 4096 -l /tmp/reservedblks # Flush changes (in case they were cached.).syncecho "Partition table (re-)initialized."
Then I needed to change start_emmc_autoscript
to load boot.ini
(this is my substitute for uEnv.ini
) from /boot
:
1 fw_setenv start_emmc_autoscript 'if ext4load mmc 1 ${env_addr} /boot/boot.ini; then env import -t ${env_addr} ${filesize}; if ext4load mmc 1 ${kernel_addr} ${image}; then if ext4load mmc 1 ${initrd_addr} ${initrd}; then if ext4load mmc 1 ${dtb_mem_addr} ${dtb}; then run boot_start;fi;fi;fi;fi;'
.. and change /boot/boot.ini
accordingly:
1234 image=/boot/vmlinuz-5.1.7initrd=/boot/uInitrddtb=/boot/meson-gxl-s905d-phicomm-n1.dtbbootargs=root=/dev/mmcblk1p1 rootflags=data=writeback rw console=ttyAML0,115200n8 console=tty0 no_console_suspend consoleblank=0 fsck.fix=yes fsck.repair=yes net.ifnames=0
/etc/fstab
need to be updated to reflect the change that /boot
is no longer a separate parition.
If you used UUIDs in specifying partitions / bootargs
, those UUIDs must also be updated.
This is how the system looks like now:
1234 [root@n1-box ~]# df -hFilesystem Size Used Avail Use% Mounted on/dev/mmcblk1p1 7.1G 1.0G 6.1G 16% /...
All your data will be lost if you do something wrong. Don’t follow this post unless you’re ABSOLUTELY aware of what you’re doing.
Well, this idea has come to me for some time, but I didn’t want bother doing that until yesterday, when I upgraded my box to Linux 5.1.7.
ext4load
supports path (rather than file names only), so it’s possible to ask it to load files in /boot
.
Firstly I repartitioned my eMMC, create a single (large) partition starts at 100M, the script I used is posted below.
There are several caveats here, though:
- You may not create the partition from the beginning of the eMMC. Or you’ll be in trouble. (Those blocks are used by bootloader, etc., and are “reserved”.)
Feature
64bit
ofext4
must be turned off, since it’s not recognized by U-boot. (This took me some time to realize, thanks to a comment on StackOverflow.) You can find more discussions here. I keptmetadata_csum
, as I didn’t see troubles with it (I’m still testing with it. I may turn out to be wrong.). This is also done by the script.Several blocks may not be used by Linux, they’re marked as “bad block”s by the script.
The script also backup and restores the first 4M of
/dev/mmcblk1
(except for partition table). I copied them from an earlier script. IIUC this is not strictly required, as the first sector should be not used by U-boot anyway. But I didn’t test that.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 | #/usr/bin/env bash set -e # So as to not overwrite U-boot, we backup the first 1M. dd if=/dev/mmcblk1 of=/tmp/boot-bak bs=1M count=4 # (Re-)initialize the eMMC and create a partition. # # `bootloader` / `reserved` occupies [0, 100M). Since sector size is 512B, byte # offset would be 204800. parted -s /dev/mmcblk1 mklabel msdos parted -s /dev/mmcblk1 unit s mkpart primary ext4 204800 100% # Restore U-boot (except the first 442 bytes, where partition table is stored.) dd if=/tmp/boot-bak of=/dev/mmcblk1 conv=fsync bs=1 count=442 dd if=/tmp/boot-bak of=/dev/mmcblk1 conv=fsync bs=512 skip=1 seek=1 # This method is used to convert byte offset in `/dev/mmcblk1` to block offset # in `/dev/mmcblk1p1`. as_block_number() { # Block numbers are offseted by 100M since `/dev/mmcblk1p1` starts at 100M # in `/dev/mmcblk1`. # # Because we're using 4K blocks, the byte offsets are divided by 4K. expr $((($1 - 100 * 1024 * 1024) / 4096)) } # This method generates a sequence of block number in range [$1, $1 + $2). # # It's used for marking several reserved regions as bad blocks below. gen_blocks() { seq $(as_block_number $1) $(($(as_block_number $(($1 + $2))) - 1)) } # Mark reserved regions as bad block to prevent Linux from using them. # # /dev/env: This "device" (present in Linux 3.x) uses 0x27400000 ~ +0x800000. # It seems that they're overwritten each time system boots if value # there is invalid. Therefore we must not touch these blocks. # # /dev/logo: This "device" uses 0x28400000~ +0x800000. You may mark them as # bad blocks if you want to preserve or replace the boot logo. # # All other "devices" (i.e., `recovery`, `rsv`, `tee`, `crypt`, `misc`, `boot`, # `system`, `data` should be safe to overwrite.) gen_blocks 0x27400000 0x800000 > /tmp/reservedblks echo "Marked blocks used by /dev/env as bad." # Let's see if a boot logo is to be installed. if [ -e /boot/n1-logo.img ]; then dd if=/boot/n1-logo.img of=/dev/mmcblk1 bs=1M seek=644 echo "Boot logo installed." gen_blocks 0x28400000 0x800000 >> /tmp/reservedblks echo "Marked blocks used by /dev/logo as bad." fi # Format the partition. Feature `64bit` of ext4 is disabled. mke2fs -F -q -O ^64bit -t ext4 -m 0 /dev/mmcblk1p1 -b 4096 -l /tmp/reservedblks # Flush changes (in case they were cached.). sync echo "Partition table (re-)initialized." |
Then I needed to change start_emmc_autoscript
to load boot.ini
(this is my substitute for uEnv.ini
) from /boot
:
1 | fw_setenv start_emmc_autoscript 'if ext4load mmc 1 ${env_addr} /boot/boot.ini; then env import -t ${env_addr} ${filesize}; if ext4load mmc 1 ${kernel_addr} ${image}; then if ext4load mmc 1 ${initrd_addr} ${initrd}; then if ext4load mmc 1 ${dtb_mem_addr} ${dtb}; then run boot_start;fi;fi;fi;fi;' |
.. and change /boot/boot.ini
accordingly:
1 2 3 4 | image=/boot/vmlinuz-5.1.7 initrd=/boot/uInitrd dtb=/boot/meson-gxl-s905d-phicomm-n1.dtb bootargs=root=/dev/mmcblk1p1 rootflags=data=writeback rw console=ttyAML0,115200n8 console=tty0 no_console_suspend consoleblank=0 fsck.fix=yes fsck.repair=yes net.ifnames=0 |
/etc/fstab
need to be updated to reflect the change that /boot
is no longer a separate parition.
If you used UUIDs in specifying partitions / bootargs
, those UUIDs must also be updated.
This is how the system looks like now:
1 2 3 4 | [root@n1-box ~]# df -h Filesystem Size Used Avail Use% Mounted on /dev/mmcblk1p1 7.1G 1.0G 6.1G 16% / ... |
how to upgraded N1 to Linux 5.1.7?
I compiled Linux 5.1.7 myself. Instructions of compiling Linux 4.20 were posted here, the same apply to Linux 5.x. Several patches are required for vanilla Linux 5.x to boot on Phicomm N1, they were posted here
thx~, and can u share ur kernel .config file ?
I’m not sure my .config suits your need, as I disabled several features (such as video / bluetooth / wireless networking) I don’t use. However, you may want to see Armbian’s (https://disk.yandex.ru/d/pHxaRAs-tZiei/5.88/s9xxx, in the first partition labeled “BOOT”), on which my .config is based. Their .config is intended for general use.
Ohmm,
I’m trying to setup also:
1, only-one-emmc root partition without vfat boot
2, with yandex’s netdisk 5.88
3, Armbian_5.88_Aml-s905_Ubuntu_bionic_default_5.1.0_20190607.img
4, change install.sh
And got some confusion about:
1, where the bootloader store in original mmc?
2, why bootloader occupy 100MiB ? from dmesg, mmcblk1boot0 only 4MiB
#
bootloader
/reserved
occupies [0, 100M). Since sector size is 512B, byte# offset would be 204800.
root@aml:/etc# dmesg|grep mmc
[ 3.041669] meson-gx-mmc d0072000.mmc: Got CD GPIO
[ 3.071952] meson-gx-mmc d0074000.mmc: allocated mmc-pwrseq
[ 3.205883] mmc1: new HS200 MMC card at address 0001
[ 3.210891] mmcblk1: mmc1:0001 NCard 7.28 GiB
[ 3.211539] mmcblk1boot0: mmc1:0001 NCard partition 1 4.00 MiB
[ 3.216304] mmcblk1boot1: mmc1:0001 NCard partition 2 4.00 MiB
[ 3.221716] mmcblk1rpmb: mmc1:0001 NCard partition 3 4.00 MiB, chardev (241:0)
3, What’s mean of below 3 x part?
mmcblk1boot0
mmcblk1boot1
mmcblk1rpmb
4, 20190607 version looks like ext4load cannot read /boot dir
5, about /etc/fw_env.config, how to test to get hardcoded 0x27400000? how to convert into fw_env.config?
https://isolated.site/2018/12/08/my-script-for-installing-armbian-5-67-into-phicomm-n1/
It seems that u-boot on Phicomm N1 hardcoded 0x27400000 for reading / storing its environment variables, and is overwritten with default values even when it’s invalid (from u-boot’s parser’s perspective).
6, could you publish your code to github then we can fork and customize some features? like remove logo option.
Thanks,
1/2. To my knowledge,
/dev/mmcblk1boot*
is physically separated from/dev/mmcblk1
, therefore their size have nothing to do with how much space should be reserved on/dev/mmcblk1
.Reserving the first 100M is only “sufficient”, but not “necessary”. I didn’t have a thorough test / analysis about how much space should be reserved. However, if my memory serves me well, overwriting blocks near the beginning of
/dev/mmcblk1
bricked my box, so I believe that they’re used for booting (at least in some later stage) or by bootloader.bootloader
/reserved
mentioned in the script referred to partitions in [N1’s partition table](https://isolated.site/2018/12/02/partition-table-format-of-phicomm-n1/), instead of the real “bootloader” (although the real bootloader is probably there, at least, bootloader for some stages.). The bootloader (the program) itself by no means should occupy 100MB.As for whether
/dev/mmcblk1boot*
is being used for booting, I saw several sources stating that they were not, but I couldn’t be sure if those sources applied to Amlogic. I haven’t tried overwriting/dev/mmcblk1
from the first byte, so I couldn’t confirm this.3. See https://www.digi.com/resources/documentation/digidocs/90001547/reference/bsp/v4-9_6ul/r_mmc-sd-sdio_6ul.htm. Note that the documentation is for ConnectCore 6UL SBC Pro, but the idea about eMMC remains the same.
4. I’m not aware that U-boot on N1 could be upgraded, as it seemed to be signed (RSA2048), and Phicomm and / or Amlogic did not provide a newer one for N1. Would you mind provide your source of newer version of U-boot on N1? Or are you using a device from other OEMs?
5. See [this post](https://isolated.site/2018/12/23/get-fw_printenv-working-on-phicomm-n1/). If you’re using a different device, a simple way would be
grep
-ing some variable in/dev/mmcblk1
.6. I haven’t prepared a GitHub account for N1 stuff, sorry about that. :/
Thank you Carrot for detail answer.
Could you provide a email and I can send some detail and discuss with you?
Or you can send ping to my email I guess you can see my email.
Comments are good way but it’s not efficiency and after i complete the comment but the Captcha expired time.
I searched lots of posts and finally got your professional technical blog posts from here.
And if we can discuss for more, I would like to contribute some code in github.
Thanks,
Echo
Had a hard time in setting up a fully functional IMAP/SMTP service for this site with no success.. Disabled captcha then. 🙂
https://github.com/laris/Phicomm-N1
I summarize some question in my github.
Thank your research.