{{ImportantMessage|text=For the sake of simplicity, this document does not address the reliability of the partitioning schemes described. This matter is beyond the scope of this document and should take into account several factors such as the intrinsic reliability of NOR/NAND flashes, the estimated usage in terms of read/write operations, etc. For more information related to this subject, please contact [mailto:support-bora@dave.eu the technical support].}}
== History ==
!Version
!Date
!BXELK version
!Hardware Part Nr
!Notes
|-
|1.0.0
|December 2016
|[[BELK/BXELK_software_components#BELK_3Initial release|-|2.0.1_.2F_BXELK_10|March 2019|Added use case #2|-|2.0.01|March 2019|BXELK Added warning about realiability<br>Added images of case #1's partitioning scheme|-|{{oldid|9151|2.0.0]]2}}|June 2019|DBXF4110D2RFixed definition of <code>nandboot2</code> variable<br />EVBBX0000C0R|Fixed dump related to the download of the bitstream file
|-
|3.0.0
|Jan 2020
|Update for BELK/BXELK 4.1.0
|}
<section begin=BELK/>== Standalone boot==This document shows some examples related to configuring Bora/BoraX/BoraLite for standalone operativity. We'll explain how to program and configure a [[BORA Xpress SOM|BORA Xpress]]-based system to boot in standalone mode, without the need of a system microSD card or an NFS server. Only the flash memories available on the SoM itself will be used to store persistently all the software required. The examples here documented are valid for [[BORA SOM|BORA]] and for [[BORA Lite SOM|BORA Lite]] as well. {{ImportantMessage|text=It is worth remembering that the examples shown in this article don't make use of any image script. This technique is used by the bootable microSD card delivered along with the kit, instead. For more details, please refer to [[Working_with_the_Yocto_build_system#bootscript|this section]].}} ===Use case #1======= Introduction ====This configuration makes use of one of the most common partitioning schemes, that is:*The NOR flash acts as boot memory; as such, it contains**bootrom header and FSBL (or header+U-Boot SPL)**U-Boot**U-Boot redundant environment**Even though these images are not strictly required to boot the system, the NOR flash also contains:***The Linux kernel image***The Linux Device Tree Blob (DTB)***The bitstream file for the Programmable Logic (PL).*The NAND flash contains a partition devoted to a read/write UBIFS root filesystem. The resulting flash memory layout is illustrated in the following pictures. [[File:BELK-NOR-flash-partitioning-case1.png|thumb|center|600px|NOR flash partitioning scheme]] [[File:BELK-NAND-flash-partitioning-case1.png|thumb|center|600px|NAND flash partitioning scheme]]
This document has been written and tested with the software/hardware combination described in the history table above. However it contains general concept that can be adapted on any DAVE Embedded Systems' Linux platform.
We'll explain how to program and configure a [[Category:BoraX|BoraX]] to boot in standalone modeIn essence, without the need of a system microSD card or a NFS server, with two optionsbootstrap sequence looks like this:* booting with NOR + NAND** U-Boot will fetch fetches and program programs the PL bitstream and then fetch *Then it fetches the Linux kernel binary images (kernel + device treeand DTB) from the on-board NOR flash memory*Once started, while later the OS will Linux kernel mount the root file system filesystem from a NAND partition.
==Use case ===Testbed=====This configuration was tested with the following testbed:*SOM: DBXF4110D2R*carrier board: EVBBX0000C0R*software: [[BELK/BXELK_software_components#BELK_3.0.1_.2F_BXELK_1.0.0|BXELK 1==.0.0]]
==== Program the root file system filesystem in NAND flash ====
This is a common step for both booting options.
* Boot the system via SD or NFS as described into the [[System_boot_and_recovery_via_microSD_card_(BORA_SOM/BELK-L/Development/BXELK)How_to_create_a_bootable_microSD_card|System boot and recovery via microSD card]] and [[Booting_the_system_via_NFS_(BORA_SOM/BELK-L/General/BXELK)Booting_from_NFS|Booting the system via NFS]]
* By default, the NAND is already partitioned to allow booting from NAND-only (see next section) and, thus, some partitions are reserved for FSBL, U-boot and kernel images. Here we won't modify this default configuration. The [[Memory Tecnology Device (MTD)|MTD]] partitions can be dumped with <code>/proc/mtd</code> (the partition's name should be self-explanatory)
{{ImportantMessage|text=Please note that MTD partition index may change depending of on flash device availability, flash device size, u-boot environment variables or kernel device driver load order. Always take care of looking inside <code>/proc/mtd</code> to match your specific layout}}
* Format and initialize ''nand-ubi'' partition, which in our case is <code>mtd7</code>, using [[Memory Tecnology Device (MTD)#UBI|UBI]] with:
<preclass="board-terminal">
ubiformat /dev/mtd7
ubiattach -m 7
<pre class="board-terminal">
root@bora:~# ubiformat /dev/mtd7
ubiformat /dev/mtd7ubiformat: mtd7 (nand), size 526385152 1056964608 bytes (5021008.0 MiB), 4016 8064 eraseblocks of 131072 bytes (128.0 KiB), min. I/O size 2048 byteslibscan: scanning eraseblock 4015 8063 -- 100 % completeubiformat: 4016 8060 eraseblocks have valid erase counter, mean value is 21ubiformat: 4 bad eraseblocks found, numbers: 8060, 8061, 8062, 8063ubiformat: formatting eraseblock 4015 8063 -- 100 % complete
root@bora:~# ubiattach -m 7
[ 95 275.732434247791] UBIubi0: attaching mtd7 to ubi0[ 100280.930047486952] UBIubi0: scanning is finished[ 100280.954932520370] UBIubi0: attached mtd7 (name "nand-rootfsubi", size 502 1008 MiB) to ubi0[ 100280.961772526302] UBIubi0: PEB size: 131072 bytes (128 KiB), LEB size: 126976 129024 bytes[ 100280.968534533222] UBIubi0: min./max. I/O unit sizes: 2048/2048, sub-page size 2048512[ 100280.975248539860] UBIubi0: VID header offset: 2048 512 (aligned 2048512), data offset: 40962048[ 100280.982129546610] UBIubi0: good PEBs: 40168060, bad PEBs: 04, corrupted PEBs: 0[ 100280.988100552720] UBIubi0: user volume: 0, internal volumes: 1, max. volumes count: 128[ 100280.995271559908] UBIubi0: max/mean erase counter: 43/32, WL threshold: 4096, image sequence number: 1955579947857573235[ 101280.004308568946] UBIubi0: available PEBs: 38527900, total reserved PEBs: 164160, PEBs reserved for bad PEB handling: 160156[ 101280.013959578486] UBIubi0: background thread "ubi_bgt0d" started, PID 913983UBI device number 0, total 4016 8060 LEBs (509935616 1039933440 bytes, 486991.3 8 MiB), available 3852 7900 LEBs (489111552 1019289600 bytes, 466972.5 1 MiB), LEB size 126976 129024 bytes (124126.0 KiB)
root@bora:~# ubimkvol /dev/ubi0 -N rootfs -m
Set volume size to 4891115521019289600Volume ID 0, size 3852 7900 LEBs (489111552 1019289600 bytes, 466972.5 1 MiB), LEB size 126976 129024 bytes (124126.0 KiB), dynamic, name "rootfs", alignment 1root@bora:~#
</pre>
* Now mount the UBI volume using [[Memory Tecnology Device (MTD)#UBIFS|UBIFS]] in a temporary directory
[ 387424.671411230219] UBIubi0: detaching mtd7 from ubi0[ 387424.677554238132] UBIubi0: mtd7 is detached from ubi0
root@bora:~#
</pre>
You can now safely reboot or turn off the system.
==== Program the boot images in NOR flash====It is assumed that the following U-Boot's environment variables are defined:
<pre class="board-terminal">fdt_base=0x00780000fpga_base=0x00180000kernel_base= NOR flash ====We assume that the following environment variables are present in u-boot:<pre>0x00800000
==== Program the root filesystem in NAND flash ====
This step can be followed in the same way as described [[BORA_SOM/BELK-L/Deployment/Standalone_boot#Program_the_root_filesystem_in_NAND_flash | before]]
==== Program the boot images in NAND flash from U-Boot ====
It is assumed that the following U-Boot's environment variables are defined:
* Update the <code>bootfile</code>, <code>fdtfile</code> and <code>fpgafile</code> environment variables to fit the filename as found inside the TFTP server.
* Program kernel and device tree on NAND flash with the following U-Boot command
<pre class="board-terminal">
Bora> run loadfpga nand_updatefpga loadk nand_updatek loadfdt nand_updatefdt
</pre>
E.g.:
<pre class="board-terminal">
Bora> run loadfpga nand_updatefpga loadk nand_updatek loadfdt nand_updatefdt
Using ethernet@e000b000 device
TFTP from server 192.168.0.13; our IP address is 192.168.0.90
-rw-r--r-- 1 root root 10073 Mar 5 2021 belk-4.1.0_bora.dtb
-rw-r--r-- 1 root root 4045564 Mar 5 2021 belk-4.1.0_bora_BASE_fpga.bin
-rw-r--r-- 1 root root 3796168 Mar 5 2021 belk-4.1.0_uImage
root@bora:~#
</pre>
* now the binary images have been retrieved form the ''tftp'' server (like the U-Boot tftp download)
* check the mtd partitioning for identifying the proper <code>/dev/mtdX</code> device
<pre class="board-terminal">
root@bora:~# cat /proc/mtd
dev: size erasesize name
mtd0: 00040000 00020000 "nand-SPL"
mtd1: 000c0000 00020000 "nand-uboot"
mtd2: 00040000 00020000 "nand-uboot-env1"
mtd3: 00040000 00020000 "nand-uboot-env2"
mtd4: 00600000 00020000 "nand-bitstream"
mtd5: 00080000 00020000 "nand-device-tree"
mtd6: 00800000 00020000 "nand-linux"
mtd7: 1f000000 00020000 "nand-rootfs"
root@bora:~#
</pre>
It is possible to see the mtd partition for the NAND flash: i.e. <code>mtd4</code> for the fpga bitstream, <code>mtd5</code> for the device tree and <code>mtd6</code> for the kernel
* using the mtd partitioning, program the binary images in the proper <code>/dev/mtdX</code> device
* the <code>mtd-utils</code> commands <code>flash_erase</code> and <code>nandwrite</code> can be used for this purposes: see [https://bootlin.com/blog/managing-flash-storage-with-linux here] for more information
## Booting kernel from Legacy Image at 02080000 ...
Image Name: Linux-4.9.0-belk-4.1.0-xilinx
Image Type: ARM Linux Kernel Image (uncompressed)
Data Size: 3796104 Bytes = 3.6 MiB
Load Address: 00008000
Entry Point: 00008000
Verifying Checksum ... OK
## Flattened Device Tree blob at 02000000
Booting using the fdt blob at 0x2000000
Loading Kernel Image ... OK
Loading Device Tree to 1effa000, end 1efff758 ... OK
Switching to NAND storage before starting Linux
Starting kernel ...
Uncompressing Linux... done, booting the kernel.
[ 0.000000] Booting Linux on physical CPU 0x0
[ 0.000000] Linux version 4.9.0-belk-4.1.0-xilinx (jenkins@linuxserver2) (gcc version 6.2.1 20161016 (Linaro GCC 6.2-2016.11) ) #1 SMP PREEMPT Tue Dec 24 11:34:28 CET 2019
## Booting kernel from Legacy Image at 02080000 ...
Image Name: Linux-4.9.0-belk-4.1.0-xilinx
Image Type: ARM Linux Kernel Image (uncompressed)
Data Size: 3796104 Bytes = 3.6 MiB
Load Address: 00008000
Entry Point: 00008000
Verifying Checksum ... OK
## Flattened Device Tree blob at 02000000
Booting using the fdt blob at 0x2000000
Loading Kernel Image ... OK
Loading Device Tree to 1effa000, end 1efff758 ... OK
Switching to NAND storage before starting Linux
Starting kernel ...
Uncompressing Linux... done, booting the kernel.
[ 0.000000] Booting Linux on physical CPU 0x0
[ 0.000000] Linux version 4.9.0-belk-4.1.0-xilinx (jenkins@linuxserver2) (gcc version 6.2.1 20161016 (Linaro GCC 6.2-2016.11) ) #1 SMP PREEMPT Tue Dec 24 11:34:28 CET 2019
In this case, the NOR flash is only used to store U-Boot and its environment. All the other images are stored onto the NAND flash. Specifically, the NAND flash has four partitions that are used to store respectively:
*The <code>uImage</code> binary image, which, in turn, consists of the Linux kernel and a [http://www.linuxfromscratch.org/blfs/view/svn/postlfs/initramfs.html <code>initramfs</code> image], as per [[BELK-TN-006:_Using_PetaLinux_to_Build_BELK/BXELK_Software_Components|PetaLinux]]'s default configuration.
**This partition is associated with the device file <code>/dev/mtd0</code>
*The PL bitstream
**This partition is associated with the device file <code>/dev/mtd1</code>
*The Device Tree Blob
**This partition is associated with the device file <code>/dev/mtd2</code>
*An auxiliary read/write filesystem used by the user-space applications for several purposes such as data logging
**This partition is associated with the device file <code>/dev/mtd3</code>.
The resulting bootstrap sequence is like the following:
#U-Boot is retrieved from the NOR flash and copied into the SDRAM memory
#U-boot, in turn, reads from the NAND memory the <code>uImage</code>, the bitstream, the DTB, and copies them into the SDRAM memory
#U-Boot starts the Linux kernel
#Finally, the Linux kernel mounts the root filesystem from the SDRAM memory and starts user-space applications and daemons.
It is worth remembering that <code>mtd0</code>,<code>mtd1</code>, and <code>mtd2</code> are used as raw partitions while <code>mtd3</code> is associated with a block device in order to mount a filesystem, specifically ''UBIFS''. To handle such filesystem, the Linux kernel must be built with the UBI/UBIFS support enabled and the root filesystem must include the <code>mtd-utils-ubifs</code> package (see the following image).
[[File:PetaLinux-mtd-utils-ubifs.png|thumb|center|600px|Selecting the <code>mtd-utils-ubifs</code> package in PataLinux root filesystem configuration]]
To setup the desired standalone configuration, several operations need to be carried out. They are detailed in the following sections. It is assumed that the SOM can boot from the NOR flash. If not, please see [[BORA_SOM/BELK-L/Deployment/Restoring_U-Boot_on_NOR_flash|this page]].
=====Testbed=====
The testbed used to test this configuration consists of the following boards:
*SOM: DBXD4110S2R
*Carrier board: EVBBX0000C0R
*Software: BXELK 4.0.0 + PetaLinux 2017.1
====Storing the images onto the raw partitions of the NAND memory====
Before storing the images into the NAND flash, the bitstream must be converted. For more details, please refer to [[BELK-AN-008: Programming the FPGA Bitstream with U-Boot|this page]]:
Once the U-Boot console is available, the binary files to be stored into the NAND flash can be downloaded via TFTP. The size of the partitions illustrated in the previous image determine the offsets to use with the <code>nand erase/write</code> commands. The following box shows the full procedure.
The first file to be stored is <code>uImage</code>:
<pre class="board-terminal">
Bora> nand info
options 0x 0
bbt options 0x 20000
Bora> tftpboot ${loadaddr} borax/uImage
Using ethernet@e000b000 device
TFTP from server 192.168.0.13; our IP address is 192.168.0.81
Bora> nand write ${loadaddr} 0 ${filesize} NAND write: device 0 offset 0x0, size 0x972038 9904184 bytes written: OKBora><INTERRUPT/pre> Downloading and flashing of the bitstream file:<pre class="board-terminal">Bora> print tftpboot ${loadaddr} borax/bitstream.binUsing ethernet@e000b000 deviceTFTP from server 192.168.0.13; our IP address is 192.168.0.81Filename 'borax/bitstream.bin'.Load address: 0x2080000Loading: ################################################################# ################################################################# ################################################################# ################################################################# ################################################################# ################################################################# ################################################################# ################################################################# ################################################################# ################################################################# ################################################################# ################################################################# ################################################################# ################################################################# ################################################################# ################################################################# ################################################################# ############################################################### 2.5 MiB/sdoneBytes transferred = 5979916 (5b3f0c hex)Bora> nand erase 3000000 f00000 NAND erase: device 0 offset 0x3000000, size 0xf00000Erasing at 0x3ee0000 -- 100% complete.OKBora> nand write ${loadaddr} 3000000 ${filesize} NAND write: device 0 offset 0x3000000, size 0x5b3f75 5980021 bytes written: OK</pre> Downloading and flashing of the DTB:<pre class="board-terminal">Bora> tftpboot ${loadaddr} borax/bora.dtbUsing ethernet@e000b000 deviceTFTP from server 192.168.0.13; our IP address is 192.168.0.81Filename 'borax/bora.dtb'.Load address: 0x2080000Loading: ## Error# 746.1 KiB/sdoneBytes transferred = 15280 (3bb0 hex)Bora> nand erase 3f00000 100000 NAND erase: device 0 offset 0x3f00000, size 0x100000Erasing at 0x3fe0000 -- 100% complete.OKBora> nand write ${loadaddr} 3f00000 ${filesize} NAND write: device 0 offset 0x3f00000, size 0x3bb0 15280 bytes written: OK</pre> ===Setting up the U-Boot environment===In order to boot the system as desired, the U-Boot environment must be configured properly. The most important variable is <code>nandboot2</code> that can be created as follows:<pre class="board-terminal">Bora> setenv nandboot2 'run program_fpga2 loadunand loadfdtnand nandargs2 addip addcons addmisc; run configid_fixupfdt; bootm ${loadaddr} - ${fdtaddr}'Bora> saveeSaving Environment to SPI Flash...SF: Detected s25fl128s_64k with page size 256 Bytes, erase size 64 KiB, total 32 MiBErasing SPI flash...Writing to SPI flash...doneValid environment: 1</pre> Another important variable that needs to be changed is <code>mtdparts</code>. It must be set like this in order to tell the kernel how the NAND flash is partitioned:<pre class="board-terminal">mtdparts=mtdparts=pl35x-nand:48M(data0),15M(data1),1M(data2),-(data3)</pre> Similarly, other variables need to be created such as <code>loadunand</code> and <code>loadfdtnand</code>. The resulting environment should look like this:<pre class="8fc790board-terminal" not defined>
Please note that the variable <code>bootcmd</code> is set to run the desired boot sequence (<code>nandboot2</code>).
====Formatting the fourth partition of the NAND memory (<code>mtd3</code>)====
After setting up the U-Boot environment, it is possible to start a full bootstrap sequence by issuing the <code>boot</code> command. Please refer to [[#Full bootstrap procedure|this section]] to see the dump of the serial console during the full bootstrap sequence.
Once the system has completed the bootstrap procedure, it is possible to format the <code>mtd3</code> partition in order to store a ''UBIFS'' filesystem.
First of all, check that the NAND's partitions are defined properly:<preclass="board-terminal">root@bora-ubi:~# cat /proc/mtd
dev: size erasesize name
mtd0: 03000000 00020000 "data0"
mtd2: 00100000 00020000 "data2"
mtd3: 3c000000 00020000 "data3"
</pre> To format the partition and to mount the newly created filesystem, issue the following commands:<pre class="board-terminal">root@bora-ubi:~# ubiformat /dev/mtd3
ubiformat: mtd3 (nand), size 1006632960 bytes (960.0 MiB), 7680 eraseblocks of 131072 bytes (128.0 KiB), min. I/O size 2048 bytes
root@bora:~# ls -la /mnt/total 16drwxr-xr-x 4 root root 4096 Mar 19 2018 .drwxrwxr-x 16 541 502 4096 Jul 9 21:11 ..drwxr-xr-x 2 root root 4096 Mar 19 2018 tftpvideodrwxr-xr-x 2 root root 4096 Mar 19 2018 ubifsroot@boraubi:~# mkdir -p /mnt/data3root@bora-ubi:~# mount -t ubifs ubi0_0 /mnt/data3[ 12386634.777228342953] UBIFS (ubi0:0): default file-system created[ 12386634.783887349787] UBIFS (ubi0:0): background thread "ubifs_bgt0_0" started, PID 8781473[ 12386634.913347536639] UBIFS (ubi0:0): UBIFS: mounted UBI device 0, volume 0, name "data3"[ 12386634.920577543901] UBIFS (ubi0:0): LEB size: 129024 bytes (126 KiB), min./max. I/O unit sizes: 2048 bytes/2048 bytes[ 12386634.930509553858] UBIFS (ubi0:0): FS size: 967421952 bytes (922 MiB, 7498 LEBs), journal size 33546240 bytes (31 MiB, 260 LEBs)[ 12386634.941440564767] UBIFS (ubi0:0): reserved for root: 4952683 bytes (4836 KiB)[ 12386634.948006571363] UBIFS (ubi0:0): media format: w4/r0 (latest is w4/r0), UUID B4CA7F108B1F86F2-B2AEF2C3-4C894292-B2E1845F-59B38879E56477D3BF3E212A, small LPT model</pre> It is now possible to verify that the filesystem was mounted properly:<pre class="board-terminal">root@bora-ubi:~# mount192.168.0.13:/opt/nfsroot/bora/belk-4.0.0 rootfs on / type nfs rootfs (rw,relatime,vers=2,rsize=4096,wsize=4096,namlen=255,hard,nolock,proto=tcp,timeo=600,retrans=2,sec=sys,mountaddr=192.168.0.13,mountvers=1,mountproto=tcp,local_lock=all,addr=192.168.0.13)devtmpfs on /dev type devtmpfs (rw,relatime,size=506608k,nr_inodes=126652,mode=755)
proc on /proc type proc (rw,relatime)
sysfs on /sys type sysfs (rw,relatime)
debugfs on /sys/kernel/debug type debugfs (rw,relatime)
devtmpfs on /dev type devtmpfs (rw,relatime,size=503536k,nr_inodes=125884,mode=755)
tmpfs on /run type tmpfs (rw,nosuid,nodev,mode=755)
tmpfs on /var/volatile type tmpfs (rw,relatime)
devpts on /dev/pts type devpts (rw,relatime,gid=5,mode=620,ptmxmode=000)
ubi0_0 on /mnt/data3 type ubifs (rw,relatime)
</pre> As expected, the available space on the <code>ubi0_0</code> is less than the raw size of the partition:<pre class="board-terminal">root@bora-ubi:~# df
Filesystem 1K-blocks Used Available Use% Mounted on
FDT: property som_configid FDT: override 'som_configid' with '00000005'
FDT: override 'som_uniqueid' with '3a11013a:40b52447'
FDT: override 'cb_uniqueid' with '00000000:00000000'
## Booting kernel from Legacy Image at 02080000 ...
Image Name: Linux-4.9.0-belk-4.0.0-xilinx
Image Type: ARM Linux Kernel Image (uncompressed)
Data Size: 9904120 Bytes = 9.4 MiB
Load Address: 00008000
Entry Point: 00008000
Verifying Checksum ... OK
## Flattened Device Tree blob at 01f00000
Booting using the fdt blob at 0x1f00000
Loading Kernel Image ... OK
Loading Device Tree to 1effa000, end 1efff996 ... OK
Switching to NAND storage before starting Linux
Starting kernel ...
Uncompressing Linux... done, booting the kernel.
[ 0.000000] Booting Linux on physical CPU 0x0
[ 0.000000] Linux version 4.9.0-belk-4.0.0-xilinx (dvdk@osboxes) (gcc version 6.2.1 20161016 (Linaro GCC 6.2-2016.11) ) #4 SMP PREEMPT Tue Mar 5 10:27:41 CET 2019
*<code>mtd0</code>, <code>mtd1</code>, and <code>mtd2</code> are significantly larger than the files they store used in this example. This allows having a spare room to store larger images. For the sake of simplicity, U-Boot was configured to read the whole partitions (see how the <code>loadunand</code>, <code>loadfdtnand</code>, and <code>loadfpga2</code> variables are defined). Obviously, this affect the overall boot time negatively. To optimize it, these variables have to be changed in order to read just the required amount of data according to the size of the actual stored files.
*As stated previously, the root filesystem is <code>initramfs</code> and thus not persistent. Consequently, every time the system boots, the directory <code>/mnt/data3</code> must be created before mounting the ''UBIFS'' file system stored in the NAND flash.