Boot Phicomm N1 without emmc_autoscript / s905_autoscript

It’s recommended to backup your firmware environment variables before changing them.

If fw_printenv / fw_setenv does not work on your device, you might want to checkout this post to fix them.

emmc_autoscript / s905_autoscript is just a script run by start_emmc_autoscript:

In your case start_emmc_autoscript is likely using fatload instead ext4load as here. I changed the variable to use ext4 /boot partition before.

[root@n1-box ~]# fw_printenv start_emmc_autoscript
start_emmc_autoscript=if ext4load mmc 1 1020000 emmc_autoscript; then autoscr 1020000; fi;

If you got an error from executing this command, such as ## Error: "start_emmc_autoscript" not defined, it means that your device is not booting though the variable. You could fix this by:

fw_setenv start_autoscript 'if usb start; then run start_usb_autoscript; fi; run start_emmc_autoscript;'

Do not reboot your system now. start_emmc_autoscript has not been defined yet (see below).

Let’s get back to emmc_autoscript. The file in my case is:

This chould be different from your case, as I changed it so that kernel image name could by specified in /boot/uEnv.ini.

setenv env_addr "0x10400000"
setenv kernel_addr "0x11000000"
setenv initrd_addr "0x13000000"
setenv dtb_mem_addr "0x1000000"
setenv boot_start booti ${kernel_addr} ${initrd_addr} ${dtb_mem_addr}
if ext4load mmc 1 ${env_addr} uEnv.ini; then env import -t ${env_addr} ${filesize}; if ext4load mmc 1 ${kernel_addr} ${kernel_name}; then if ext4load mmc 1 ${initrd_addr} uInitrd; then if ext4load mmc 1 ${dtb_mem_addr} ${dtb_name}; then run boot_start;fi;fi;fi;fi;

It’s possible to bake the entire script into firmware variables, by executing the following commands:

The following commands also 1) change filename of /boot/uEnv.ini to /boot/boot.ini, 2) read dtb’s filename from /boot/boot.ini instead of hardcoding it, 3) and change the variable names of kernel_name, dtb_name in /boot/boot.ini to image, dtb, respectively. Feel free to revert these changes back if you want.

Actually I believe that with the help of rewritting start_emmc_autoscript (to import /boot/boot.ini using env import), emmc_autoscript could be written in /boot/boot.ini (in a slightly different format, though) in its entirety. However, I don’t see much sense in doing this, they do not change much anyway.

fw_setenv env_addr 0x10400000
fw_setenv kernel_addr 0x11000000
fw_setenv initrd_addr 0x13000000
fw_setenv dtb_mem_addr 0x1000000
fw_setenv boot_start 'booti ${kernel_addr} ${initrd_addr} ${dtb_mem_addr}'
fw_setenv start_emmc_autoscript 'if ext4load mmc 1 ${env_addr} 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 use /boot/boot.ini to specify the kernel, initrd, and dtb’s filename:

[root@n1-box ~]# cat /boot/boot.ini
image=vmlinuz-5.0.2
initrd=uInitrd
dtb=meson-gxl-s905d-phicomm-n1.dtb
bootargs=root=LABEL=ROOT_EMMC rootflags=data=writeback rw console=ttyAML0,115200n8 console=tty0 no_console_suspend consoleblank=0 fsck.fix=yes fsck.repair=yes net.ifnames=0

/boot/uEnv.ini, /boot/*_autoscript could all be removed now.

Now /boot/ should look like this way:

[root@n1-box ~]# find /boot/
/boot/
/boot/boot.ini
/boot/vmlinuz-5.0.2
/boot/meson-gxl-s905d-phicomm-n1.dtb
/boot/uInitrd

9 thoughts on “Boot Phicomm N1 without emmc_autoscript / s905_autoscript”

  1. thanks for the idea, i tried to load uboot directly with ext4load from start_emmc_autoscript, but it won’t boot, turns out there is bug in ext4load, but good news is that phicomm uboot has another 2 commands to avoid the bug: icache on ; dcache on

    so this is the final, now we can get rid of the scripts on /boot, and i can have single extlinux directory on boot.

    start_emmc_autoscript=icache on ; dcache on ; if ext4load mmc 1 0x1000000 uboot; then go 0x1000000; fi;

    do the same for start_usb_autoscript

    source:
    https://github.com/u-boot/u-boot/blob/master/cmd/cache.c
    https://github.com/archdemac/Phicomm-N1-info/blob/master/logs/uboot-help.log

  2. after successfully load mainline uboot from ext4 root partition, without the EMMC_AUTOSCRIPT / S905_AUTOSCRIPT. i try to move it further to put uboot in /boot/extlinux/uboot, and instruct start_emmc_autoscript to load uboot from “extlinux/uboot”, here is the result

    ext4load extlinux/uboot : failed to boot
    fatload extlinux/uboot : ok to boot.

    looks like there is another bug for ext4load.
    so, give up, now my /boot looks like this:

    config-linux-phicomm-n1
    dtbs
    extlinux
    initramfs-linux-phicomm-n1.img
    uboot
    vmlinuz-linux-phicomm-n1

    1. As far as I can understand it, I see no reason how enabling icache/dcache can address correctness issues.

      Sure its beneficial from performance perspective but that is unlikely to cause any difference in functionality.

      One thing that crossed my mind it that Cortex-A53 (among others ARM uarchs) does not keep icache coherent with dcache, so one needs to flush icache explicitly for self-modifying-code to run correctly.

      Difference between fatload and extload might be caused by different icache footprint, and fatload inadvertently (and “correctly”) evicted cache lines that should be flushed.

      Doing an `icache flush` before jumping to newly-loaded code might make a difference.

      But I no longer have an N1 at hand so all of the above are my speculation and probably wrong, do take them with a grain of salt.

    2. i don’t know which part did not work, but since “….fatload whatever/dir/uboot ; go 0xHEX” ALWAYS work, but ext4load + go always fail. i gave icache, dcache a try, and it happened to be working.

      let me try “icache flush” alone. and i’ll come back to you.

    3. icache flush or dcache flush or both does not make a difference.

      still can’t load uboot from another dir in ext4 root : ext4load uboot fine, ext4load [/]extlinux/uboot fail.

      i don’t have serial connection so i don’t know what actually happened.

  3. maybe it is related to how ext4 was formatted? here is the print

    sudo tune2fs -l /dev/mmcblk1p1
    tune2fs 1.46.5 (30-Dec-2021)
    Filesystem volume name:
    Last mounted on: /boot
    Filesystem UUID: 8632715c-4a22-4427-b9bf-e9c79682f1c2
    Filesystem magic number: 0xEF53
    Filesystem revision #: 1 (dynamic)
    Filesystem features: has_journal ext_attr resize_inode dir_index filetype needs_recovery extent 64bit flex_bg sparse_super large_file huge_file dir_nlink extra_isize metadata_csum
    Filesystem flags: unsigned_directory_hash
    Default mount options: user_xattr acl
    Filesystem state: clean
    Errors behavior: Continue
    Filesystem OS type: Linux
    Inode count: 32768
    Block count: 131072
    Reserved block count: 6553
    Overhead clusters: 6347
    Free blocks: 119674
    Free inodes: 32665
    First block: 0
    Block size: 4096
    Fragment size: 4096
    Group descriptor size: 64
    Reserved GDT blocks: 63
    Blocks per group: 32768
    Fragments per group: 32768
    Inodes per group: 8192
    Inode blocks per group: 512
    Flex block group size: 16
    Filesystem created: Sat Dec 24 08:55:29 2022
    Last mount time: Mon Dec 26 14:50:54 2022
    Last write time: Mon Dec 26 14:50:54 2022
    Mount count: 34
    Maximum mount count: -1
    Last checked: Sat Dec 24 08:55:29 2022
    Check interval: 0 ()
    Lifetime writes: 52 MB
    Reserved blocks uid: 0 (user root)
    Reserved blocks gid: 0 (group root)
    First inode: 11
    Inode size: 256
    Required extra isize: 32
    Desired extra isize: 32
    Journal inode: 8
    Default directory hash: half_md4
    Directory Hash Seed: 3083faf5-67a0-40cf-b488-7b1e3ac868ec
    Journal backup: inode blocks
    Checksum type: crc32c
    Checksum: 0x5f1c9f74

  4. i see your another post, say 64bit has to be turned off? in my case, i did not turn it off. what i did is just mkfs.ext4 /dev/mmcblk1p1/p2

    funny enough:

    # with emmc_autoscript
    start_emmc_autoscript=if ext4load mmc 1 1020000 emmc_autoscript; then autoscr 1020000; fi;
    in emmc_autoscript : if ext4load mmc 1 0x1000000 uboot; then go 0x1000000; fi; // work

    # without emmc_autoscript
    start_emmc_autoscript=if ext4load mmc 1 0x1000000 uboot; then go 0x1000000; fi; // fail, but fatload works.
    # without emmc_autoscript, add icache dcache
    start_emmc_autoscript=icache on; dcache on ; if ext4load mmc 1 0x1000000 uboot; then go 0x1000000; fi; // work, fatload works too.

    # without emmc_autoscript, add icache dcache, use one more level directory
    start_emmc_autoscript=icache on; dcache on ; if ext4load mmc 1 0x1000000 extlinux/uboot; then go 0x1000000; fi; // fail, but fatload works.

    # without emmc_autoscript, add icache dcache, use one more level directory, add a flush
    start_emmc_autoscript=icache on; dcache on ; icache flush ; dcache flush ; if ext4load mmc 1 0x1000000 extlinux/uboot; then go 0x1000000; fi; // fail

    1. I’m not sure if 64bit is still relevant here. I assume it was just a bug of certain versions of UBoot and should have been fixed.

Leave a Reply

Your email address will not be published. Required fields are marked *