Changes between Version 16 and Version 17 of venice/boot


Ignore:
Timestamp:
04/18/2024 12:41:15 AM (3 weeks ago)
Author:
Tim Harvey
Comment:

removed booting from NVMe section as U-Boot now supports NVMe

Legend:

Unmodified
Added
Removed
Modified
  • venice/boot

    v16 v17  
    5858|| 0x01000000 -            ||        || Disk Partitions || used by the OS ||
    5959
    60 == Booting from NVMe
    61 
    62 You can't access NVMe devices from u-boot because IMX8M PCI is not supported in U-Boot and NVMe uses the PCI bus.
    63 
    64 What is possible, is that you can load a kernel that has PCI/NVMe support from eMMC/USB/microSD and thus run your OS off NVMe.
    65 
    66 NVMe support has existed in our '''kernels''' for a long time. It works exactly like putting your root filesystem on any block storage device such that you tell the kernel what device is root via 'root=<device> rootwait'.
    67 
    68 The IMX8 BOOT ROM does not support booting from PCI/NVMe so it will always boot its boot firmware from something it does support (NAND/SDIO/MMC/SD/SPI/USB/QSPI) and in this case that is eMMC. So the boot firmware will always exist on eMMC.
    69 
    70 If U-Boot doesn't support your the device or filesystem , then the need to put the kernel/bootscript/fdt on something it does support (ie a 'bootfs' or raw mmc using fixed offfsets/sizes) and just feed it the 'root=' parameter that is eventually wanted. This is not at all a new or foriegn concept.
    71 
    72 Note that in order to mount a rootfs in Linux not only do you need the valid 'root=' arguments (and supporting args like 'rootwait' for slower devs) you also would need to have 'static' support for the device and filesystem you wish to use otherwise you need to use a ramdisk that loads modules to support them mount the rootfs and pivot to it. NVMe and UMS was set to be static in the Venice kernel at this commit: [https://github.com/Gateworks/linux-venice/commit/4158a0890a8498fc6de18a5b4e3dbd22adfd93b0]
    73 
    74 If you have an NVMe in one of our boards you will see:
    75 {{{
    76 root@jammy-venice:~# lspci
    77 00:00.0 PCI bridge: Synopsys, Inc. DWC_usb3 / PCIe bridge (rev 01)
    78 01:00.0 PCI bridge: Pericom Semiconductor PI7C9X2G608GP PCIe2 6-Port/8-Lane Packet Switch
    79 02:01.0 PCI bridge: Pericom Semiconductor PI7C9X2G608GP PCIe2 6-Port/8-Lane Packet Switch
    80 02:02.0 PCI bridge: Pericom Semiconductor PI7C9X2G608GP PCIe2 6-Port/8-Lane Packet Switch
    81 02:03.0 PCI bridge: Pericom Semiconductor PI7C9X2G608GP PCIe2 6-Port/8-Lane Packet Switch
    82 02:04.0 PCI bridge: Pericom Semiconductor PI7C9X2G608GP PCIe2 6-Port/8-Lane Packet Switch
    83 03:00.0 Non-Volatile memory controller: Realtek Semiconductor Co., Ltd. Device 5765 (rev 01)
    84 c0:00.0 Ethernet controller: Marvell Technology Group Ltd. 88E8057 PCI-E Gigabit Ethernet Controller
    85 root@jammy-venice:~# ls /sys/class/nvme
    86 nvme0
    87 root@jammy-venice:~# ls /dev/nvme0
    88 /dev/nvme0
    89 root@jammy-venice:~# ls /dev/nvme0n1
    90 /dev/nvme0n1
    91 root@jammy-venice:~# dmesg | grep nvme
    92 [    7.052622] nvme nvme0: pci function 0000:03:00.0
    93 [    7.052665] nvme 0000:03:00.0: enabling device (0000 -> 0002)
    94 [    7.275312] nvme nvme0: allocated 64 MiB host memory buffer.
    95 [    7.340566] nvme nvme0: 4/0/0 default/read/poll queues
    96 [    7.353019] nvme nvme0: Ignoring bogus Namespace Identifiers
    97 [    7.366645]  nvme0n1: p1
    98 }}}
    99 
    100 Notes
    101 - Kernel must have CONFIG_BLK_DEV_NVME enabled (and obviously PCI) (and static unless relying on a ramdisk to load modules)
    102 - The /dev/nvme0 is the controller (0 being the first one)
    103 - The /dev/nvme0n1 is the device and you would partition this and use this just like a /dev/mmcblk2 or a /dev/sda
    104 - If partitions are found they will be available as p1, p2 etc
    105 - The kernel can use this for root just like any block storage device via 'root=/dev/nvme0n1p1 rootwait'
    106 
    107 Recall that our default bootloaders use a U-Boot convention called 'generic distro boot' where the bootcmd runs distro_bootcmd which works by searching a list of bootable devices for bootable partitions that contain a boot script matching a list. If found it runs that bootscript and the bootscript uses the device and interface that it was located on to know what root device to tell the kernel to use. Because U-Boot and Linux differ in naming conventions between block storage device (U-Boot doesn't know that 'mmc 2:1' may refer to /dev/mmcblk2p1 on Linux) it uses the UUID of that particular filesystem and adds a 'root=PARTUUID=<uuid>' to boot. We use uuid because that standard is the same across uboot and Linux but device naming and numbering is not a standard. So if you put our standard rootfs on any block storage device that U-Boot supports it just works without modification.
    108 
    109 One can do the following steps under Linux on a host or target. For example these steps work on our board:
    110 
    111 Prepare the nvme device by copying our compressed disk image to it
    112 {{{
    113 DEV=/dev/nvme0n1 # /dev/sda for first usb mass storage device
    114 cd /tmp
    115 wget https://dev.gateworks.com/venice/images/jammy-venice.img.gz
    116 [ -b $DEV ] || { echo ERROR NVMe device $DEV does not exist; exit 1; }
    117 zcat jammy-venice.img.gz | dd of=$DEV
    118 rm jammy-venice.img.gz
    119 }}}
    120 
    121 Creating a 'bootfs' disk image:
    122 {{{
    123 # set some vars that can easily be adjusted
    124 P1_MB=60 # 60M should be enough for kernel/fdt/bootscript
    125 P1_OFFSET_MB=1 # we typically start disk partitions at 1M
    126 # fetch our kernel tarball and extract the contents of ./boot to a boot directory
    127 wget https://dev.gateworks.com/venice/kernel/linux-venice-6.6.8.tar.xz
    128 mkdir boot
    129 tar -C boot/ --strip-components=2 -xvf linux-venice-6.6.8.tar.xz ./boot
    130 # create a 'bootfs' filesystem
    131 truncate -s ${P1_MB}M bootfs.ext
    132 mkfs.ext4 bootfs.ext
    133 # use e2cp/e2mkdir from e2tools package to create/copy files to ext without having to mount it
    134 apt update && apt install -y e2tools
    135 e2mkdir bootfs.ext:boot
    136 for i in $(ls boot); do e2cp boot/$i bootfs.ext:boot/; done
    137 # create a bootscript using out default one with one modification
    138 wget https://raw.githubusercontent.com/Gateworks/bsp-venice/master/boot.scr
    139 # change the root=PARTUUID=${uuid} argument to what we want (I use sed here to do it but they can just edit and replace however they wish)
    140 sed -i 's;root=PARTUUID=${uuid};root=/dev/nvme0n1p1;' boot.scr
    141 # create bootscript using mkimage from u-boot-tools package
    142 apt update && apt install -y u-boot-tools
    143 mkimage -A arm64 -T script -C none -d boot.scr boot.scr.uimage
    144 # copy the bootscript to filesystem
    145 e2cp boot.scr.uimage bootfs.ext:boot/boot.scr
    146 # create a disk image (partition table, partitions)
    147 truncate -s $(($P1_MB+$P1_OFFSET_MB))M bootfs.img
    148 # add a partition table
    149 apt update && apt install -y fdisk
    150 printf "$(($P1_OFFSET_MB*2*1024)),$(($P1_MB*2*1024)),L,*" | sfdisk -uS bootfs.img
    151 # copy filesystem into image
    152 dd if=bootfs.ext of=bootfs.img bs=1M seek=$P1_OFFSET_MB
    153 # compress image
    154 gzip bootfs.img
    155 # bootfs.img.gz is what you are going to flash to the eMMC via 'update_all' or manually via 'gzwrite'
    156 #^^^ Note there are lots of possible variations on the above... filesystem type doesn't have to be ext4... partition sizes formats can change etc... you just need to do something uboot supports
    157 }}}
    158 
    159 If you are doing the above on our board booted to emmc then you can't write to the emmc while its mounted (unpredictable results) so you would have to have done this from a ramdisk, or you could move that bootfs.img.gz out of /tmp to save it to the existing file system then reboot to uboot and load/flash it from U-Boot mmc:
    160 {{{
    161 mv bootfs.img.gz /
    162 sync && reboot
    163 u-boot=> load mmc 2:1 $loadaddr /bootfs.img.gz && gzwrite mmc $dev $loadaddr $filesize
    164 }}}
    165 
    166 If you copy bootfs.img.gz to a tftp server for example you can install just like any other compressed disk image:
    167 {{{
    168 u-boot=> setenv image venice/bootfs.img.gz; run update_all
    169 }}}
    170 
    171 Now you can reset/power-cycle
    172 
    173 If you inspect you can see your changes:
    174 {{{
    175 u-boot=> part list mmc 2
    176 
    177 Partition Map for MMC device 2  --   Partition Type: DOS
    178 
    179 Part    Start Sector    Num Sectors     UUID            Type
    180   1     2048            122880          d1a37fad-01     83 Boot
    181 #^^^ emmc partition 1 is a bootable Linux partition of 122880 blocks (122880*512=60M)
    182 
    183 u-boot=> ls mmc 2:1
    184 <DIR>       4096 .
    185 <DIR>       4096 ..
    186 <DIR>      16384 lost+found
    187 <DIR>       4096 boot
    188 #^^^ only the boot dir exists
    189 
    190 u-boot=> ls mmc 2:1 boot
    191 <DIR>       4096 .
    192 <DIR>       4096 ..
    193 <DIR>      16384 lost+found
    194 <DIR>       4096 boot
    195 u-boot=> ls mmc 2:1 boot
    196 <DIR>       4096 .
    197 <DIR>       4096 ..
    198         31275520 Image
    199            37426 imx8mm-venice-gw71xx-0x.dtb
    200            51885 imx8mm-venice-gw72xx-0x-gw16157.dtb
    201             2157 imx8mm-venice-gw72xx-0x-gw16157.dtbo
    202            51547 imx8mm-venice-gw72xx-0x-imx219.dtb
    203             2293 imx8mm-venice-gw72xx-0x-imx219.dtbo
    204            51648 imx8mm-venice-gw72xx-0x-rpidsi.dtb
    205             1989 imx8mm-venice-gw72xx-0x-rpidsi.dtbo
    206            51069 imx8mm-venice-gw72xx-0x-rs232-rts.dtb
    207             1241 imx8mm-venice-gw72xx-0x-rs232-rts.dtbo
    208            51156 imx8mm-venice-gw72xx-0x-rs422.dtb
    209             1292 imx8mm-venice-gw72xx-0x-rs422.dtbo
    210            51145 imx8mm-venice-gw72xx-0x-rs485.dtb
    211             1281 imx8mm-venice-gw72xx-0x-rs485.dtbo
    212            50843 imx8mm-venice-gw72xx-0x.dtb
    213            52878 imx8mm-venice-gw73xx-0x-gw16157.dtb
    214             2157 imx8mm-venice-gw73xx-0x-gw16157.dtbo
    215            52540 imx8mm-venice-gw73xx-0x-imx219.dtb
    216             2293 imx8mm-venice-gw73xx-0x-imx219.dtbo
    217            52641 imx8mm-venice-gw73xx-0x-rpidsi.dtb
    218             1989 imx8mm-venice-gw73xx-0x-rpidsi.dtbo
    219            52042 imx8mm-venice-gw73xx-0x-rs232-rts.dtb
    220             1241 imx8mm-venice-gw73xx-0x-rs232-rts.dtbo
    221            52139 imx8mm-venice-gw73xx-0x-rs422.dtb
    222             1292 imx8mm-venice-gw73xx-0x-rs422.dtbo
    223            52128 imx8mm-venice-gw73xx-0x-rs485.dtb
    224             1281 imx8mm-venice-gw73xx-0x-rs485.dtbo
    225            51836 imx8mm-venice-gw73xx-0x.dtb
    226            38309 imx8mm-venice-gw75xx-0x.dtb
    227            44288 imx8mm-venice-gw7901.dtb
    228            42563 imx8mm-venice-gw7902.dtb
    229            39682 imx8mm-venice-gw7903.dtb
    230            40046 imx8mm-venice-gw7904.dtb
    231            38039 imx8mn-venice-gw7902.dtb
    232            46598 imx8mp-venice-gw71xx-2x.dtb
    233            49113 imx8mp-venice-gw72xx-2x.dtb
    234            49684 imx8mp-venice-gw73xx-2x.dtb
    235            68290 imx8mp-venice-gw74xx-imx219.dtb
    236             2094 imx8mp-venice-gw74xx-imx219.dtbo
    237            68430 imx8mp-venice-gw74xx-rpidsi.dtb
    238             2025 imx8mp-venice-gw74xx-rpidsi.dtbo
    239            67594 imx8mp-venice-gw74xx.dtb
    240            47398 imx8mp-venice-gw75xx-2x.dtb
    241         11300992 kernel.itb
    242             2242 boot.scr
    243 #^^^ and it contains our kernel/dtbs/script
    244 }}}
    245 
    246 
    247 
    248 Note that NVMe support in U-Boot for imx8m mini is likely coming soon; NVMe has been supported in U-Boot for a while now, but PCIe for IMX8M has not been. IMX8MP PCI support landed upstream just a few weeks ago (and we've tested/enabled it (PCI/NVME) upstream for imx8mp-venice). imxmm support is hopefully coming soon.
    24960
    25061[=#u-boot]