uenvcmd in uEnv.txt can not be executed automatically - linux-kernel

I am using an arm board using TFTP and NFS but it got stuck at kernel loading as shown in the screenshot and I have to input the run uenvcmd then the process will keep going and everything is OK.
Below is my uEnv.txt:
# This uEnv.txt file can contain additional environment settings that you
# want to set in U-Boot at boot time. This can be simple variables such
# as the serverip or custom variables. The format of this file is:
# variable=value
# NOTE: This file will be evaluated after the bootcmd is run and the
# bootcmd must be set to load this file if it exists (this is the
# default on all newer U-Boot images. This also means that some
# variables such as bootdelay cannot be changed by this file since
# it is not evaluated until the bootcmd is run.
autoload=no
ipaddr=192.168.1.100
serverip=192.168.1.13
gatewayip=192.168.1.1
staticip=${ipaddr}:${serverip}:${gatewayip}:255.255.255.0:::off
bootpath=/tftpboot
rootfspath=/opt/ti-processor-sdk-linux-rt-am57xx-evm-03.00.00.04/targetNFS
#setting for kernel loading
kernel_addr=0x82000000
fdt_addr=0x88000000
nfs_args=setenv bootargs console=ttyO0,115200n8 root=/dev/nfs rw nfsroot=${serverip}:${rootfspath} ip=${staticip}
load_zimage=tftp ${kernel_addr} ${bootpath}/zImage
loadfdt=tftp ${fdt_addr} ${bootpath}/am572x-idk.dtb
boot_zimage=bootz ${kernel_addr} - ${fdt_addr}
uenvcmd=run load_zimage; run loadfdt; run nfs_args; run boot_zimage
these is a strange file called uboot.env beside the uEnv.txt, too long to paste here, uboot.env

Problem solved: Just delete the file uboot.env
This should be a bug of SDK. I will report this to TI. Thanks #Notlikethat

Related

Access u-boot env variables set by fw_setenv from boot.scr

I'm experimenting with nanopi board with ubuntu OS and u-boot bootloader.
When booted into system, I set u-boot environment variable with fw_setenv:
$ fw_setenv foo bar
On the following reboot I'd like to access this foo variable from the /boot/boot.scr script:
if [ -z "${foo}" ]; then
echo "Fail"
else
echo "Ok"
fi
I get Fail, so foo is inaccessible.
I've no experience with u-boot but I read that it has two sets of environment variables: one read-only (fixed as a part of U-boot image), and another read/write (user environment). So it looks like user environment is not accessible from boot.scr script? Is it true? How can I make my foo variable visible at the moment when boot.scr is executed?
Upd: My /etc/fw_env.config file:
# Block device
/dev/mmcblk1 0xc0000 0x20000
U-boot version: 2020.01
The problem is found. U-boot constants CONFIG_SYS_MMC_ENV_DEV, CONFIG_ENV_OFFSET, and CONFIG_ENV_SIZE did not match those in /etc/fw_env.config.
Solved the problem by changing these constants to
#define CONFIG_SYS_MMC_ENV_DEV 1
#define CONFIG_ENV_OFFSET 0x3f8000
#define CONFIG_ENV_SIZE 0x20000
recompiling u-boot and updating fw_env.config accordingly:
/dev/mmcblk1 0x3f8000 0x20000

bitbake not producing a zImage file

I've been running a Yocto build in bitbake for a few days, but I've noticed it sometimes stops producing the zImage file of my kernel. Most of the changes I'm making are to the kernel config, and the machine.conf file. when this happens, I still get updated tar.gz files with each build, but the zImage stops being updated. Running the do_clean, do_cleanall and do_cleansstate tasks do not help, and neither does deleting the old zImage file from build/tmp/deploy. The only thing that helps is deleting the entire pocky/build/tmp directory and rebuilding the entire project from scratch. Here is my current machine.conf file:
##TYPE: Machine
##Name: EMAC, Inc. SoM-9G45M Module
##DESCRIPTION: Machine.inc configuration for the SoM-9G45M board with a at91sam9g45 processor
TARGET_ARCH = "arm"
PREFERRED_PROVIDER_virtual/kernel = "linux-2.6.30-at91-emac"
PREFERRED_PROVIDER_xserver = "xserver-kdrive"
KERNEL_IMAGETYPE = "zImage"
KERNEL_EXTRA_ARGS = "LOADADDR=0x74000000"
#don't try to access tty1
USE_VT = "0"
MACHINE_FEATURES = "kernel26 apm alsa ext2 usbhost usbgadget"
KERNEL_DEVICETREE = "at91som9g45.dtb"
# used by sysvinit_2
#SERIAL_CONSOLE = "115200 ttyS1"
SERIAL_CONSOLE = "115200 ttyS0"
#SERIAL_CONSOLES = "115200;ttyS0 115200;ttyS1"
#SYSLINUX_DEFAULT_CONSOLE = "console=ttyS0"
#SYSLINUX_SERIAL = "0 115200"
#SYSLINUX_SERIAL_TTY = "console=ttyS0,115200"
#EXTRA_IMAGECMD_jffs2 = "--pad=0xA00000 --little-endian --eraseblock=0x20000"
# NAND
MKUBIFS_ARGS = " -e 129024 -c 2047 -m 2048 -x lzo"
UBINIZE_ARGS = " -m 2048 -p 128KiB -s 512"
UBI_VOLNAME = "rootfs"
UBOOT_MACHINE = "${MACHINE}_nandflash_config"
UBOOT_ENTRYPOINT = "0x74000000"
UBOOT_LOADADDRESS = "0x74000000"
require include/at91sam9.inc
What can cause a bitbake build to stop producing the specified kernel image, and how do I fix it?
The answer ended up having two parts.
First, running bitbake -c do_cleansstate linux-at91 and then bitbake core-image-sato successfully regenerated the zImage file.
Second, linux-2.6.30-at91-emac was incorrect since my kerenl was just called linux-at91. So my kernel build was likely only being run when I ran builds for other machines.
So my full image build wasn't rebuilding the kernel because I had referenced a different kernel. Once I fixed that, the kernel build would start running again. I'm not sure how I got a zImage in the first place, or why bitbake never threw an error after being told to build a kernel that didn't exist.

How to set system variables in start-up scripts

I'm controlling 8 servos using the PWM outputs on the BeagleBone. On start-up the names of the PWMs are dynamically assigned so they vary from boot to boot, so to know which pin matches which PWM I've written this script:
#!/bin/sh
# match BeagleBone PWMCHIP{n} with available pwm controllers
for i in $(/bin/ls /sys/class/pwm); do
link=$(/bin/readlink /sys/class/pwm/$i)
case "$link" in
*48300100*) BBPWM0=$i;;
*48300200*) BBPWM1=$i;;
*48302200*) BBPWM2=$i;;
*48304100*) BBPWM3=$i;;
*48304200*) BBPWM4=$i;;
esac
done
export BBPWM0
export BBPWM1
export BBPWM2
export BBPWM3
export BBPWM4
echo "PWM0 = $BBPWM0" > /home/ormund/servo.log
/home/ormund/servo-server
The system works when I start it from the command line, the servo-server listens on a network port and moves the servos correctly in response to remote commands, but if I start this from systemd at boot, it fails, the BBPWM0 is a null string and the server cant start. What am I doing wrong?

U-boot. BeagleBone Black. Micro SD card

I have a series of questions on how U-boot works on the BeagleBone Black. Everything started with this tutorial on how to use a micro SD card(uSD) as extra storage.
uSD as extra storage on BBB.
Currently my setup looks like this.
$ fdisk -l
Disk /dev/mmcblk0: 7948 MB, 7948206080 bytes #uSD
Device Boot Start End Blocks Id System
/dev/mmcblk0p1 2048 198655 98304 e W95 FAT16 (LBA)
/dev/mmcblk0p2 198656 15523839 7662592 83 Linux
Disk /dev/mmcbk1: 3867 MB, 3867148288 bytes #eMMC
Device Boot Start End Blocks Id System
/dev/mmcblk1p1 * 2048 198655 98304 e W95 FAT16 (LBA)
/dev/mmcblk1p2 198656 7553023 3677184 83 Linux
So if I havent had it wrong this is what happends.
Boot sequence.
1.The BBB is powered.
2.The U-boot is loaded from the eMMC(/dev/mmcblk1p1)
3.The U-boot searches for uEnv.txt file within the uSD(/dev/mmcblk0p1) and loads it.
...... We will retake from here.
In /dev/mmcblk0p1 i have a uEnv.txt file that looks like this.
mmcdev=1
bootpart=1:2
mmcroot=/dev/mmcblk1p2 ro
optargs=quiet
In /dev/mmcblk1p1 i have the default uEnv.txt file that at some point have this lines.
loadkernel=load mmc ${mmcdev}:${mmcpart} ${loadaddr} ${kernel_file}
loadinitrd=load mmc ${mmcdev}:${mmcpart} ${initrd_addr} ${initrd_file}; setenv initrd_size ${filesize}
.......
mmcargs=setenv bootargs console=tty0 console=${console} ${optargs} ${kms_force_mode} root=${mmcroot} rootfstype=${mmcrootfstype} ${systemd}
We can see how ${mmcdev}, ${mmcroot}, ${optargs} are used although they arent defined in the file, they are defined uSD uEnv.txt.
Question 1.
¿Does this mean that both uEnv.txt files are loaded?
Retaking the boot sequence.
Boot sequence.
4.The U-boot searches for uEnv.txt file within the eMMC(/dev/mmcblk1p1) and loads it.
5.The Linux kernel is loaded.
When there is no uSD the ${mmcdev}, ${mmcroot}, ${optargs} arguments aren't defined, not in the uEnv.txt at least.
Question 2.
¿Where do the default values come?
Now the part that really bothers me. On another board a have a eMMC uEnv.txt file that looks like this.
optargs=quiet drm.debug=7 capemgr.enable_partno=BB-UART2,BB-UART1
The board boots fine without uSD.
Question 3.
How is that even posible?
The answer to the question should be in your board configuration file. Specifically the definition of 'CONFIG_EXTRA_ENV_SETTINGS'- "Define this to contain any number of null terminated strings (variable = value pairs) that will be part of the default environment compiled into the boot image." (from u-boot README file)

Getting U-boot's Version from Userspace

Does anyone know of a way to get U-boot version installed from userspace? There is the fw_printenv command that provides access to U-boot's environment variables, but not the version.
If U-boot is located in mtd0, you can get version info as follows:
root#SUPERWIFI:/proc# strings /dev/mtd0 | grep U-Boot
U-Boot 1.1.4-g1c8343c8-dirty (Feb 28 2014 - 13:56:54)
U-Boot
Now running in RAM - U-Boot at: %08lx
Just an update for this.
In our version of U-Boot we changed the code for main_loop() in main.c to this:
#ifdef CONFIG_VERSION_VARIABLE
char *oldver=getenv("ver");
if(oldver==0 ||strcmp(oldver,version_string))
{
setenv("ver", version_string); /* set version variable */
saveenv();
}
#endif /* CONFIG_VERSION_VARIABLE */
So setenv/saveenv is only called, if needed by an update.
In our firmware we added
/sbin/fw_printenv -n ver > /var/config/u-boot.ver
to make the u-boot version public available.
There's no defined way to do this. Once Linux boots, u-boot is no longer running and it's RAM is reclaimed for Linux's use. Linux doesn't even know about u-boot. Nor does it have to have been booted by u-boot.
If you really want to do this, the only way to do it is to add the u-boot version to the kernel's command line, write code to scan the u-boot image in flash for it's version, or something even nastier.
An alternative solution is to read the version directly from the u-boot binary file (can be even embedded in an image file containing other binaries as well like e.g. the first stage bootloader) with e.g. mmcblk0boot0 as partition (of device mmcblk0) the bootloader resides in:
sudo grep -a --null-data U-Boot /dev/mmcblk0boot0
Site note: Does work not only for Arch Linux but e.g. Ubuntu as well.
In my devices UBoot automatically creates a "ver" environment variable containing its version:
U-Boot > printenv
baudrate=115200
ethact=FEC ETHERNET
ethaddr=24-db-ad-00-00-08
bootdelay=3
bootcmd=bootm fc080000 - fc060000
bootargs=console=ttyCPM0,115200n8 rdinit=/sbin/init
stdin=serial
stdout=serial
stderr=serial
ver=U-Boot 2009.03-svn9684 (Mar 08 2010 - 17:08:32)
Environment size: 253/131068 bytes
U-Boot >
I don't use fw_printenv, but I would imagine that this variable gets passed along as well. Maybe you already have something similar in your system?
UPDATE (5/23/2012):
I added fw_printenv to my linux image and can confirm that I do see the "ver" variable:
[root#ST600 /]# fw_printenv
baudrate=115200
ethact=FEC ETHERNET
ethaddr=24-db-ad-00-00-08
stdin=serial
stdout=serial
stderr=serial
ver=U-Boot 2009.03-svn9684 (Mar 11 2010 - 09:43:08)
bootcmd=bootm fc080000 - fc060000
bootdelay=3
bootargs=console=ttyCPM0,115200n8 rdinit=/sbin/init panic=10 mem=32m
[root#ST600 /]#
Try to read uboot version this way:
Find uboot partition, eg. for MTD device:
cat /proc/mtd
For /dev/mtd5:
cat /dev/mtd5 | hexdump -C -n 64
You can't rely on fw_printenv if you want to know u-boot version.
fw_printenv just looks for the printenv partition and dumps its data. So it's OK for normal variables, but it's not OK for the "ver" variable, which is dynamic, and whose value is initialized by u-boot when it boots. The value of this variable doesn't remain after u-boot exit, except if you manually save it to environment.
For example, on my board, if I print the "ver" variable from u-boot prompt:
U-Boot > printenv ver
ver=U-Boot 2009.11-00393-g5ca9497-dirty (Nov 26 2012 - 11:08:44)
This is the real version of u-boot, coming from u-boot itself.
Now, if I boot my board and use fw_printenv:
el#board # fw_printenv | grep ver=
ver=U-Boot 2009.11-00323-gbcc6e0e (Sep 21 2012 - 11:07:19)
As you can see, it's different. Because it happens that I have a "ver" variable defined in my environment. And it doesn't match the real u-boot version.
Of course, I could go back to u-boot, use "saveenv" to update the "ver" value in the environment. Then the two values would match. But then, I should always update the environment after changing u-boot.
So, my conclusion is that using fw_printenv to get u-boot version is definitely not a good idea.
If u-boot is residing in an MTD partition then this will work:
U_BOOT_VER=$(for part in `grep u-boot-[01] /proc/mtd | cut -f 1 -d ':'`; do strings /dev/${part} | grep "^U-Boot.*("; break; done)

Resources