Home | Projects | Notes > Embedded Linux > Writing uEnv.txt File from Scratch
[!] Note: Instead of booting from eMMC completed from the previous steps (Debian image; where there's only one partition, and boot/
folder does not contain uImage), I've used microSD card (which contains Angstrom image) to boot and follow the lecture.
boot
U-boot command will load the Linux kernel and execute it. boot
simply runs the environment variable bootcmd
. So, if you want to change the behavior of boot
, you have to modify the commands stored in the environment variable bootcmd
.
U-boot always try to read the uEnv.txt from the boot source. If uEnv.txt is not found, it will use the default values of the enve variables.
If you don't want U-boot to use default values, you need to enforce new values using uEnv.txt.
U-boot's "load from memory device" commands:
fatload
- Loads a binary file from FAT based file system into memory.
load
- Loads a binary file from any file system.
Examples:
xxxxxxxxxx
31fatload usb 0:1 0x82000000 uImage
2fatload mmc 0:1 0x88000000 initramfs
3load mmc 0:1 0x88000000 uImage
1st arg - Interface (e.g., USB, MMC, etc.)
2nd arg - Device#:Partition# (Device# can be checked by running something like
mmc list
.)When the Linux image is properly flashed onto eMMC, eMMC partitions would look like:
Our goal is to write our own uEnv.txt file from scratch and update the bootcmd
so that when we run boot
command from the U-boot prompt, it will refer to our custom uEnv.txt file while booting.
Let's load the Linux binary image "uImage" from the second partition of the SD card into the DDR memory.
xxxxxxxxxx
21=> load mmc 0:2 0x82000000 /boot/uImage
24002080 bytes read in 300 ms (12.7 MiB/s)
/boot/uImage
since uImage file is located inside the directoryboot/
in the 2nd partition of SD card.
Now, let's boot the Linux kernel image using bootm
command (boot application image from memory).
This boot fails because the Linux Bootstrap Loader couldn't find the DTB. (This is why the Bootstrap Loader complains about the "Unrecognized machine ID ...".
xxxxxxxxxx
301=> bootm 0x82000000
2## Booting kernel from Legacy Image at 82000000 ...
3 Image Name: Angstrom/3.8.10/beaglebone
4 Created: 2013-04-29 19:56:00 UTC
5 Image Type: ARM Linux Kernel Image (uncompressed)
6 Data Size: 4002016 Bytes = 3.8 MiB
7 Load Address: 80008000
8 Entry Point: 80008000
9 Verifying Checksum ... OK
10 Loading Kernel Image ... OK
11
12Starting kernel ...
13
14Uncompressing Linux... done, booting the kernel.
15
16Error: unrecognized/unsupported machine ID (r1 = 0x00000e05).
17
18Available machine support:
19
20ID (hex) NAME
21ffffffff Generic OMAP4 (Flattened Device Tree)
22ffffffff Generic AM33XX (Flattened Device Tree)
23ffffffff Generic OMAP3-GP (Flattened Device Tree)
24ffffffff Generic OMAP3 (Flattened Device Tree)
250000060a OMAP3 Beagle Board
2600000a9d IGEP OMAP3 module
2700000928 IGEP v2 board
2800000ae7 OMAP4 Panda board
29
30Please check your kernel config and/or bootloader.
L13: The very last message from the U-boot. From this point on, the control is on the Linux Bootstrap Loader.
To boot successfully, we need to first load DTB to somewhere in memory and let the Bootstrap Loader know where the correct DTB file is located.
Boot BBB to U-boot prompt and load uImage (kernel image) and DTB file into DDR memory by running the following commands:
xxxxxxxxxx
41=> load mmc 0:2 0x82000000 /boot/uImage
24002080 bytes read in 296 ms (12.9 MiB/s)
3=> load mmc 0:2 0x88000000 /boot/am335x-boneblack.dtb
423334 bytes read in 18 ms (1.2 MiB/s)
Now, run bootm
by specifying both of those addresses:
xxxxxxxxxx
171=> bootm 0x82000000 - 0x88000000
2## Booting kernel from Legacy Image at 82000000 ...
3 Image Name: Angstrom/3.8.10/beaglebone
4 Created: 2013-04-29 19:56:00 UTC
5 Image Type: ARM Linux Kernel Image (uncompressed)
6 Data Size: 4002016 Bytes = 3.8 MiB
7 Load Address: 80008000
8 Entry Point: 80008000
9 Verifying Checksum ... OK
10## Flattened Device Tree blob at 88000000
11 Booting using the fdt blob at 0x88000000
12 Loading Kernel Image ... OK
13 Loading Device Tree to 8fff7000, end 8ffffb25 ... OK
14
15Starting kernel ...
16
17Uncompressing Linux... done, booting the kernel.
Looks like there is no crash, but Linux is not sending any boot logs. So, we can't see the progress.
This is because when the Linux kernel takes over the control, it has no idea which serial port of the board is used for sending the boot logs. The BBB uses UART0 as the serial debug terminal, which is enumerated as /dev/ttyO0
by the serial driver. You need to tell the kernel where to send this information to by using the boot arguments.
Along with this information, many other pieces of information need to be passed to the kernel using the boot arguments.
bootargs
Next step is to send bootargs to the Linux kernel from U-boot.
Use the U-boot standard environment variable bootargs
to send the boot arguments to the Linux kernel. If not already defined, go ahead and define one.
xxxxxxxxxx
51=> printenv bootargs
2## Error: "bootargs" not defined
3=> setenv bootargs console=ttyO0,115200
4=> printenv bootargs
5bootargs=console=ttyO0,115200
Tell the Linux kernel that our console is
ttyO0
.
Run bootm
by specifying both of those addresses:
xxxxxxxxxx
11=> bootm 0x82000000 - 0x88000000
Now, the boot message will show up on our console. But, boot again will fail at some point because the Linux kernel has no idea where it should mount the file system.
So, you have to send the location and type of file system using bootargs
.
Let's mount the file system which is present at the partition 2 of the microSD card.
xxxxxxxxxx
11=> setenv bootargs console=ttyO0,115200 root=/dev/mmcblk0p2 rw
root=/dev/mmcblk0p2 rw
is added to the previously defined environmental variablebootargs
.It is basically telling which root file system (RFS) to mount during the booting process and is giving read/write permission.
Now, if you repeat the previous steps all over again, you will be able to boot the Linux kernel successfully.
In summary:
xxxxxxxxxx
61=> setenv bootargs
2=> load mmc 0:2 0x82000000 /boot/uImage
34002080 bytes read in 296 ms (12.9 MiB/s)
4=> load mmc 0:2 0x88000000 /boot/am335x-boneblack.dtb
523334 bytes read in 18 ms (1.2 MiB/s)
6=> bootm 0x82000000 - 0x88000000
xxxxxxxxxx
361## Booting kernel from Legacy Image at 82000000 ...
2 Image Name: Angstrom/3.8.10/beaglebone
3 Created: 2013-04-29 19:56:00 UTC
4 Image Type: ARM Linux Kernel Image (uncompressed)
5 Data Size: 4002016 Bytes = 3.8 MiB
6 Load Address: 80008000
7 Entry Point: 80008000
8 Verifying Checksum ... OK
9## Flattened Device Tree blob at 88000000
10 Booting using the fdt blob at 0x88000000
11 Loading Kernel Image ... OK
12 Loading Device Tree to 8fff7000, end 8ffffb25 ... OK
13
14Starting kernel ...
15
16Uncompressing Linux... done, booting the kernel.
17[ 0.000000] Booting Linux on physical CPU 0x0
18
19...
20...
21...
22
23.---O---.
24| | .-. o o
25| | |-----.-----.-----.| | .----..-----.-----.
26| | | __ | ---'| '--.| .-'| | |
27| | | | | |--- || --'| | | ' | | | |
28'---'---'--'--'--. |-----''----''--' '-----'-'-'-'
29 -' |
30 '---'
31
32The Angstrom Distribution beagleboard ttyO0
33
34Angstrom v2012.12 - Kernel 3.8.10
35
36beagleboard login:
Booting the Linux kernel using the U-boot commands success!!!
uEnv.txt file helps us to group all these step-by-step processes together in one file so that they can get carried out automatically during the boot process.
Create a simple "uEnv.txt" file.
xxxxxxxxxx
21mypcip=setenv serverip 193.168.1.2
2
You first need to declare a custom environment variable and assign the command to it.
"uEnv.txt" file must contain the very last EMPTY line.
Transfer the "uEnv.txt" file from host to BBB borad using serial port transfer protocols like xmodem or ymodem which are supported by minicom.
U-boot also supports serial port transfer protocol commands:
loadx
- Send/receive file using xmodem protocol
loady
- Send/receive file using ymodem protocol
loadz
- Send/receive file using zmodem protocol
On minicom,
loady
command.
Ctrl+A
S
(this will show the serial port transfer protocols available) ymodem
.
Transferring uEnv.txt file to the target does not mean that the environment variable is accessible from the target. You need to IMPORT the file!
xxxxxxxxxx
61=> env import -t 0x82000000 38
2=> printenv mypcip
3mypcip=setenv serverip 192.168.1.2
4=> run mypcip
5=> printen serverip
6serverip=192.168.1.2
L1: The address to pass must be taken from the result of the previous step.
Now, the value 192.168.1.2
is successfully stored in serverip
.
Updated uEnv.txt
xxxxxxxxxx
51mypcip=setenv serverip 192.168.1.2
2ipaddr=192.168.27.1
3bootargs=console=ttyO0,115200 root=/dev/mmcblk0p2 rw
4bootcmd=echo"********** Booting from memory **********";load mmc 0:2 0x82000000 /boot/uImage;load mmc 0:2 0x88000000 /boot/am335x-boneblack.dtb;bootm 0x82000000 - 0x88000000
5
Import
xxxxxxxxxx
31=> env import -t 0x82000000 284
2=> printenv bootargs
3bootargs=console=ttyO0,115200 root=/dev/mmcblk0p2 rw
L2: To check if important has been successful.
Now, finally, boot
!
xxxxxxxxxx
411=> boot
2Unknown command 'echo********** Booting from memory **********' - try 'help'
34002080 bytes read in 305 ms (12.5 MiB/s)
423334 bytes read in 21 ms (1.1 MiB/s)
5## Booting kernel from Legacy Image at 82000000 ...
6 Image Name: Angstrom/3.8.10/beaglebone
7 Created: 2013-04-29 19:56:00 UTC
8 Image Type: ARM Linux Kernel Image (uncompressed)
9 Data Size: 4002016 Bytes = 3.8 MiB
10 Load Address: 80008000
11 Entry Point: 80008000
12 Verifying Checksum ... OK
13## Flattened Device Tree blob at 88000000
14 Booting using the fdt blob at 0x88000000
15 Loading Kernel Image ... OK
16 Loading Device Tree to 8fff7000, end 8ffffb25 ... OK
17
18Starting kernel ...
19
20Uncompressing Linux... done, booting the kernel.
21[ 0.000000] Booting Linux on physical CPU 0x0
22[ 0.000000] Initializing cgroup subsys cpu
23
24...
25...
26...
27
28.---O---.
29| | .-. o o
30| | |-----.-----.-----.| | .----..-----.-----.
31| | | __ | ---'| '--.| .-'| | |
32| | | | | |--- || --'| | | ' | | | |
33'---'---'--'--'--. |-----''----''--' '-----'-'-'-'
34 -' |
35 '---'
36
37The Angstrom Distribution beagleboard ttyO0
38
39Angstrom v2012.12 - Kernel 3.8.10
40
41beagleboard login:
L2: This message is what we put in the uEnv.txt file.
What would you need to change in uEnv.txt to be able to boot from the eMMC instead of microSD card?
load mmc
command should be adjusted! (microSD card
Also, you must check where the Linux kernel image is located in what format. Arguments of load mmc
must reflect this information correctly!
Nayak, K. (2022). Embedded Linux Step by Step Using Beaglebone Black [Video file]. Retrieved from https://www.udemy.com/course/embedded-linux-step-by-step-using-beaglebone/