In Linux initrd image, ethernet fails to work - linux

I am working on SABRE SD Development board, which uses i.Mx6 Quad core processor. I have developed a initrd image for this board. The kernel boots up and the initrd images is mounted successfully. Even the fec ethernet drivers are loaded properly.
But during the init process the dhcp fails to designate an ip for the ethernet device.
on analysis using the strace utility on the 'dhcp' command the following log was obtained:
In the log a select system call Timeouts causing the error. A selective portion of the log is given bellow.
socket(PF_INET, SOCK_RAW, IPPROTO_RAW) = 6
ioctl(6, SIOCGIFINDEX, {ifr_name="eth0", ifr_index=2}) = 0
ioctl(6, SIOCGIFHWADDR, {ifr_name="eth0", ifr_hwaddr=00:04:9f:02:b3:81}) = 0
close(6) = 0
clock_gettime(CLOCK_MONOTONIC, {53, 815520338}) = 0
write(1, "Sending discover...\n", 20Sending discover...
) = 20
socket(PF_PACKET, SOCK_DGRAM, 8) = 6
bind(6, {sa_family=AF_PACKET, proto=0x800, if2, pkttype=PACKET_HOST, addr(6)={0,
ffffffffffff}, 20) = 0
sendto(6, "E\0\0014\0\0\0\0#\21y\272\0\0\0\0\377\377\377\377\0D\0C\1 ,h\1\1\6\0"..., 308, 0, {sa_family=AF_PACKET, proto=0x800, if2, pkttype=PACKET_HOST, add8
close(6) = 0
fcntl64(5, F_SETFD, FD_CLOEXEC) = 0
clock_gettime(CLOCK_MONOTONIC, {53, 990583005}) = 0
select(6, [3 5], NULL, NULL, {3, 0}) = 0 (Timeout)
But when the same rootfs used in initrd image is used with SD card boot the dhcp command does not fail.
Can any one help me with some clues?
with regards,
Vivek

Related

EADDRNOTAVAIL even after using IP_FREEBIND?

I was under the impression that under Linux you could bind to a non-local address as long as you set the IP_FREEBIND socket option, but that's not the behavior I'm seeing:
$ sudo strace -e 'trace=%network' ...
...
socket(AF_INET, SOCK_RAW, IPPROTO_UDP) = 5
setsockopt(5, SOL_SOCKET, SO_REUSEADDR, [1], 4) = 0
setsockopt(5, SOL_SOCKET, SO_NO_CHECK, [1], 4) = 0
setsockopt(5, SOL_IP, IP_HDRINCL, [1], 4) = 0
setsockopt(5, SOL_IP, IP_FREEBIND, [1], 4) = 0
bind(5, {sa_family=AF_INET, sin_port=htons(abcd), sin_addr=inet_addr("w.x.y.z")}, 16) = -1 EADDRNOTAVAIL (Cannot assign requested address)
...
I also set the ip_nonlocal_bind setting, just to be certain, and I get the same results.
$ sysctl net.ipv4.ip_nonlocal_bind
net.ipv4.ip_nonlocal_bind = 1
Unfortunately, it seems that it is not possible to bind a raw IP socket to a non-local, non-broadcast and non-multicast address, regardless of IP_FREEBIND. Since I see inet_addr("w.x.y.z") in your strace output, I assume that this is exactly what you're trying to do and w.x.y.z is a non-local unicast address, thus your bind syscall fails.
This seems in accordance with man 7 raw:
A raw socket can be bound to a specific local address using the
bind(2) call. If it isn't bound, all packets with the specified
IP protocol are received. In addition, a raw socket can be bound
to a specific network device using SO_BINDTODEVICE; see socket(7).
Indeed, looking at the kernel source code, in raw_bind() we can see the following check:
ret = -EADDRNOTAVAIL;
if (addr->sin_addr.s_addr && chk_addr_ret != RTN_LOCAL &&
chk_addr_ret != RTN_MULTICAST && chk_addr_ret != RTN_BROADCAST)
goto out;
Also, note that .sin_port must be 0. The .sin_port field for raw sockets is used to select a sending/receiving IP protocol (not a port, since we are at level 3 and ports do not exist). As the manual states, from Linux 2.2 onwards you cannot select a sending protocol through .sin_port anymore, the sending protocol is the one set when creating the socket.

ubiformat in barebox giving timeout

I have a custom iMX 6UL board with Barebox (partially) functional. I have on board a Semper s25hs512t Flash being detected (after adding the necessary device id indrivers/mtd/spi-nor/spi-nor.c)
The problem - My board does not have ethernet or removable SD. I need to burn the boot loader/ flash on the s25hs512. I need to format the flash accordingly and copy the files on it.
my dtsi has
&qspi {
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_qspi>;
status = "okay";
flash0: s25hs512t#0 {
#address-cells = <1>;
#size-cells = <1>;
compatible = "spansion,s25hs512t", "jedec,spi-nor";
spi-max-frequency = <40000000>;
spi-rx-bus-width = <4>;
spi-tx-bus-width = <4>;
reg = <0>;
spi-mode = <0>;
m25p,fast-read;
status = "okay";
partition#0 {
label = "barebox";
reg = <0x00000000 0x00100000>;
};
partition#1 {
label = "barebox-env";
reg = <0x00100000 0x00040000>;
};
partition#2 {
label = "barebox-of";
reg = <0x00140000 0x00040000>;
};
partition#3 {
label = "kernel";
reg = <0x00180000 0x00800000>;
};
partition#4 {
label = "root";
reg = <0x00980000 0x03640000>;
};
};
};
on boot barebox detects the flash
Board: Freescale i.MX6 UltraLite Caisteal Board
detected i.MX6 UltraLite revision 1.0
i.MX6 UltraLite unique ID: 241e09d4e317402a
m25p80 s25hs512t#00: s25hs512t (65536 Kbytes). <=====
imx-esdhc 2194000.mmc#2194000.of: registered as mmc1
rng_self_test: RNG software self-test passed
caam 2140000.crypto#2140000.of: Instantiated RNG4 SH0
caam 2140000.crypto#2140000.of: Instantiated RNG4 SH1
malloc space: 0x8eefcf80 -> 0x9ddf9eff (size 239 MiB)
barebox-environment chosen:environment.of: probe failed: No such file or directory
devinfo shows
`-- 21e0000.spi#21e0000.of
`-- s25hs512t#00
`-- m25p0
`-- 0x00000000-0x03ffffff ( 64 MiB): /dev/m25p0
`-- m25p0.barebox
`-- 0x00000000-0x000fffff ( 1 MiB): /dev/m25p0.barebox
`-- m25p0.barebox-env
`-- 0x00000000-0x0003ffff ( 256 KiB): /dev/m25p0.barebox-env
`-- m25p0.barebox-of
`-- 0x00000000-0x0003ffff ( 256 KiB): /dev/m25p0.barebox-of
`-- m25p0.kernel
`-- 0x00000000-0x007fffff ( 8 MiB): /dev/m25p0.kernel
`-- m25p0.root
`-- 0x00000000-0x0363ffff ( 54.3 MiB): /dev/m25p0.root
but when I run ubiformat, I am oddly getting this
barebox#Freescale i.MX6 UltraLite Caisteal Board:/ ubiformat /dev/m25p0.barebox -y
ubiformat: m25p0.barebox (nor), size 1048576 bytes (1 MiB), 4 eraseblocks of 262144 bytes (256 KiB), min. I/O size 1 bytes
libscan: scanning eraseblock 3 -- 100 % complete
ubiformat: 1 eraseblocks are supposedly empty
ubiformat: warning!: 3 of 4 eraseblocks contain non-ubifs data
ubiformat: warning!: only 0 of 4 eraseblocks have valid erase counter
ubiformat: erase counter 0 will be used for all eraseblocks
ubiformat: note, arbitrary erase counter value may be specified using -e option
ubiformat: use erase counter 0 for all eraseblocks
ubiformat: formatting eraseblock 3 -- 100 % complete
ERROR: m25p80 s25hs512t#00: flash operation timed out
ERROR: m25p0.barebox: error -110 while writing 262144 bytes to PEB 0:0, written 0 bytes
libubigen: error!: cannot write 262144 bytes
ubiformat: error!: cannot write layout volume
ubiformat: Operation not permitted
Any way ahead from this?
PS : Update
Thanks for help from #TrentP - I am focusing only on formatting the larger partitions so that I can write the kernel and root partition. but I have not been able to mount the ubi partition. I get the following issue (Readonly filesystem)
barebox#Freescale i.MX6 UltraLite Caisteal Board:/ erase /dev/m25p0.kernel
barebox#Freescale i.MX6 UltraLite Caisteal Board:/ ubiattach /dev/m25p0.kernel
NOTICE: ubi0: scanning is finished
NOTICE: ubi0: empty MTD device detected
NOTICE: ubi0: registering /dev/m25p0.kernel.ubi
NOTICE: ubi0: attached mtd0 (name "m25p0.kernel", size 8 MiB) to ubi0
NOTICE: ubi0: PEB size: 262144 bytes (256 KiB), LEB size: 262016 bytes
NOTICE: ubi0: min./max. I/O unit sizes: 1/256, sub-page size 1
NOTICE: ubi0: VID header offset: 64 (aligned 64), data offset: 128
NOTICE: ubi0: good PEBs: 32, bad PEBs: 0, corrupted PEBs: 0
NOTICE: ubi0: user volume: 0, internal volumes: 1, max. volumes count: 128
NOTICE: ubi0: max/mean erase counter: 1/0, WL threshold: 65536, image sequence number: 1700878141
NOTICE: ubi0: available PEBs: 28, total reserved PEBs: 4, PEBs reserved for bad PEB handling: 0
barebox#Freescale i.MX6 UltraLite Caisteal Board:/ ubimkvol /dev/m25p0.kernel.ubi kernel 0
NOTICE: ubi0: registering kernel as /dev/m25p0.kernel.ubi.kernel
barebox#Freescale i.MX6 UltraLite Caisteal Board:/ mount -t ubifs /dev/m25p0.kernel.ubi.kernel /mnt/kernel/
ERROR: UBIFS error (ubi0:0): 9de5a2d5: can't format empty UBI volume: read-only mount
ERROR: ubifs ubifs0: probe failed: Read-only file system
mount: Invalid argument
If I use ubiformat I get this
barebox#Freescale i.MX6 UltraLite Caisteal Board:/ ubiformat /dev/m25p0.kernel -y
ubiformat: m25p0.kernel (nor), size 8388608 bytes (8 MiB), 32 eraseblocks of 262144 bytes (256 KiB), min. I/O size 1 bytes
libscan: scanning eraseblock 31 -- 100 % complete
ubiformat: warning!: 32 of 32 eraseblocks contain non-ubifs data
ubiformat: warning!: only 0 of 32 eraseblocks have valid erase counter
ubiformat: erase counter 0 will be used for all eraseblocks
ubiformat: note, arbitrary erase counter value may be specified using -e option
ubiformat: use erase counter 0 for all eraseblocks
ubiformat: formatting eraseblock 31 -- 100 % complete
barebox#Freescale i.MX6 UltraLite Caisteal Board:/ ubiattach /dev/m25p0.kernel
NOTICE: ubi0: scanning is finished
ERROR: ubi0 error: ubi_read_volume_table: the layout volume was not found
ERROR: ubi0 error: ubi_attach_mtd_dev: failed to attach mtd0, error -22
failed to attach: Invalid argument
devinfo
Parent: m25p0.kernel
Parameters:
available_pebs: 0 (type: uint32)
bad_peb_count: 0 (type: uint32)
good_peb_count: 32 (type: uint32)
leb_size: 262016 (type: uint32)
max_erase_counter: 2 (type: uint32)
mean_erase_counter: 0 (type: uint32)
min_io_size: 1 (type: uint32)
peb_size: 262144 (type: uint32)
reserved_pebs: 32 (type: uint32) <=== why all PEBs are reserved?
sub_page_size: 1 (type: uint32)
vid_header_offset: 64 (type: uint32)
Any suggestions on what I am doing wrong. I know its something ridiculously simple. just unknown to me
You aren't supposed to use ubiformat on the barebox partition. It's too small. That's why it fails.
UBI is a Linux layer for putting UBI filesystems into NAND or NOR flash. The iMX6UL CPU boot ROM does not understand UBI. It can't boot something in a UBI formatted partition. It's for the root filesystem in the root partition.
Read section 8 of the iMX6UL reference manual, especially §8.6 about QuadSPI booting. This will tell you what you must put into flash to make it bootable.
Also look at the barebox_update command, which can be used to flash the bootloader from Barebox. The board needs to support it and I don't know about your board. The code is in various imx6_bbu_* functions. I'm not sure if qspi is supported, as I only see eMMC/SD,eMMC boot, NAND, and I2C/SPI. The qspi interface isn't the same as a serial EEPROM on one of the eCSPI controllers (again, see RM §8!). But perhaps it would work with an appropriate header already on the image.

FileStream behaves differently on Linux

(DotNet Core 2.1) I am using FileStream to write bytes to a file. Developing on Windows and Targeting Yocto Linux on a ARM 32 Bit processor.
When running on Windows I get the correct resulting file.
Same code running on Linux, produces an incorrect file.
Putting both files on the Linux system and checking them with the "file" command yields different results:
$ file pc.iso # <-- GOOD
pc.iso: data
$ file linux.iso # <-- BAD
linux.iso: DOS/MBR boot sector, code offset 0x58+2, OEM-ID "mkfs.fat",
sectors/cluster 64, reserved sectors 64, Media descriptor 0xf8, sectors/track
63, heads 255, sectors 100000000 (volumes > 32 MB), FAT (32 bit), sectors/FAT
12224, reserved 0x1, serial number 0x53ab8ba2, unlabeled
Sample of the code:
using (var stream = new FileStream(path, FileMode.Open, FileAccess.Write, FileShare.None, 4096, FileOptions.WriteThrough ))
{
stream.Seek(start, SeekOrigin.Begin);
for (int i = 0; i < amount; i++)
{
var bytes = GetBytes(i);
stream.Write(bytes, 0, bytes.Length);
}
}
Why would something like this produce different results on Linux? And/or how can I prevent it from somehow producing a FAT32 image?

Process killed by SIGHUP after read returns ERESTARTSYS

We have some application which calls a PHP script which connects to an Oracle DB to do certain things. :) This does not work out well sometimes.
We are now running the PHP part via strace from the beginning.
This is how it looks when everything works ok (everything works out, the DB connection is built, the query executed, the DB is again disconnected, etc.):
10:30:17.935486 connect(8, {sa_family=AF_INET, sin_port=htons(1521), sin_addr=inet_addr("10.1.1.55")}, 16) = -1 EINPROGRESS (Operation now in progress)
10:30:17.935546 times(NULL) = 2908590046
10:30:17.935569 brk(0xda4000) = 0xda4000
10:30:17.935594 poll([{fd=8, events=POLLOUT}], 1, 60000) = 1 ([{fd=8, revents=POLLOUT}])
10:30:17.940338 getsockopt(8, SOL_SOCKET, SO_ERROR, [519270883345301504], [4]) = 0
10:30:17.940368 fcntl(8, F_GETFL) = 0x802 (flags O_RDWR|O_NONBLOCK)
10:30:17.940388 fcntl(8, F_SETFL, O_RDWR) = 0
10:30:17.940408 getsockname(8, {sa_family=AF_INET, sin_port=htons(62498), sin_addr=inet_addr("192.168.22.30")}, [16]) = 0
10:30:17.940437 getsockopt(8, SOL_SOCKET, SO_SNDBUF, [-4193870156763480064], [4]) = 0
10:30:17.940458 getsockopt(8, SOL_SOCKET, SO_RCVBUF, [-4193870156763409068], [4]) = 0
10:30:17.940483 setsockopt(8, SOL_TCP, TCP_NODELAY, [1], 4) = 0
10:30:17.940506 fcntl(8, F_SETFD, FD_CLOEXEC) = 0
10:30:17.940652 rt_sigaction(SIGPIPE, {0x1, ~[ILL ABRT BUS FPE SEGV USR2 TERM XCPU XFSZ SYS RTMIN RT_1], SA_RESTORER|SA_RESTART|SA_SIGINFO, 0x7f7198b2b920}, {0x1, [PIPE], SA_RESTORER|SA_RESTART, 0x7f7198b2b920}, 8) = 0
10:30:17.940725 write(8, "\x00\xe8\x00\x00\x01\x00\x00\x00\x01\x3b\x01\x2c\x0c\x41\x20\x00\xff\xff\x7f\x08\x00\x00\x01\x00\x00\xa2\x00\x46\x00\x00\x08\x00"..., 232) = 232
10:30:17.940781 read(8, "\x00\x08\x00\x00\x0b\x00\x00\x00", 8208) = 8
10:30:17.974177 write(8, "\x00\xe8\x00\x00\x01\x00\x00\x00\x01\x3b\x01\x2c\x0c\x41\x20\x00\xff\xff\x7f\x08\x00\x00\x01\x00\x00\xa2\x00\x46\x00\x00\x08\x00"..., 232) = 232
10:30:17.974247 read(8, "\x00\x29\x00\x00\x02\x00\x00\x00\x01\x3b\x0c\x41\x00\x00\x00\x00\x01\x00\x00\x00\x00\x29\x51\x41\x00\x00\x00\x00\x00\x00\x00\x00"..., 8208) = 41
10:30:17.976465 write(8, "\x00\x00\x00\xa4\x06\x20\x00\x00\x00\x00\xde\xad\xbe\xef\x00\x9a\x00\x00\x00\x00\x00\x04\x00\x00\x04\x00\x03\x00\x00\x00\x00\x00"..., 164) = 164
....
This is how it looks when everything does not work ok:
10:23:24.888170 connect(8, {sa_family=AF_INET, sin_port=htons(1521), sin_addr=inet_addr("10.1.1.55")}, 16) = -1 EINPROGRESS (Operation now in progress)
10:23:24.888241 times(NULL) = 2908548738
10:23:24.888263 brk(0xda4000) = 0xda4000
10:23:24.888287 poll([{fd=8, events=POLLOUT}], 1, 60000) = 1 ([{fd=8, revents=POLLOUT}])
10:23:24.889769 getsockopt(8, SOL_SOCKET, SO_ERROR, [519270883345301504], [4]) = 0
10:23:24.889807 fcntl(8, F_GETFL) = 0x802 (flags O_RDWR|O_NONBLOCK)
10:23:24.889827 fcntl(8, F_SETFL, O_RDWR) = 0
10:23:24.889845 getsockname(8, {sa_family=AF_INET, sin_port=htons(62473), sin_addr=inet_addr("192.168.22.30")}, [16]) = 0
10:23:24.889873 getsockopt(8, SOL_SOCKET, SO_SNDBUF, [-8374476973480591360], [4]) = 0
10:23:24.889892 getsockopt(8, SOL_SOCKET, SO_RCVBUF, [-8374476973480520364], [4]) = 0
10:23:24.889915 setsockopt(8, SOL_TCP, TCP_NODELAY, [1], 4) = 0
10:23:24.889936 fcntl(8, F_SETFD, FD_CLOEXEC) = 0
10:23:24.890062 rt_sigaction(SIGPIPE, {0x1, ~[ILL ABRT BUS FPE SEGV USR2 TERM XCPU XFSZ SYS RTMIN RT_1], SA_RESTORER|SA_RESTART|SA_SIGINFO, 0x7f2ee24b4920}, {0x1, [PIPE], SA_
RESTORER|SA_RESTART, 0x7f2ee24b4920}, 8) = 0
10:23:24.890129 write(8, "\x00\xe8\x00\x00\x01\x00\x00\x00\x01\x3b\x01\x2c\x0c\x41\x20\x00\xff\xff\x7f\x08\x00\x00\x01\x00\x00\xa2\x00\x46\x00\x00\x08\x00"..., 232) = 232
10:23:24.890186 read(8, 0xd705a6, 8208) = ? ERESTARTSYS (To be restarted)
10:23:24.907853 --- SIGHUP (Hangup) # 0 (0) ---
10:23:24.908708 +++ killed by SIGHUP +++
This happens sometimes and the application (or at least the PHP script and the connection to the DB) just gets killed. That's bad.
What do you make of the above straces?
Can we tell who is killed by who?
Why would read() return ERESTARTSYS?
What does SIGHUP (Hangup) # 0 (0) tell us exactly?
Your process got sent a SIGHUP, which caused the normal action of exiting.
Can't tell who did it. Try a newer version of strace. From what I can tell, going all the way back to version 4.6 from 2011 it should display more information. The version of strace you are using is from prior to 2011 and the # 0 (0) supplies the PC of the process when the signal was received and the address associated with the signal from siginfo_t. Neither will tell you anything about this problem.
A newer version will supply something like this:
--- SIGHUP {si_signo=SIGHUP, si_code=SI_USER, si_pid=25064, si_uid=1000} ---
--- SIGHUP {si_signo=SIGHUP, si_code=SI_KERNEL} ---
This first is another process sending the SIGHUP. The second is one sent automatically because of certain events.
The latter can happen when the controlling terminal of the process closes or when the session leader exits because its terminal closed. If you determine it's the kernel sending the signal, then I'd look at your process while it's running and examine the "sid" and "tty" columns in the ps output. That will tell you the session leader and terminal responsible for causing the SIGHUP to be sent. Maybe sometimes your script has a controlling terminal and sometimes not?
The session leader would usually be the parent process that started your script, or the parent of that process, or the parent of that, etc. Looking at ps output and "sid" will tell you. If that leader process exits and has a controlling terminal, everything under it gets a SIGHUP. The way to solve this would be either have the leader not exit until the PHP process is finished, or at some point detach from that session or terminal. Usually a daemon or server process should not associated with a terminal. See daemon() and setsid().

Turn off power to a USB port

I'm looking for a way to turn power off (and back on) for a USB port. Solution can be in C, bash, etc. I'm using a BeagleBone running 32-bit Ubuntu 16.04 for armhf.
> uname -srvm
Linux 4.4.6-ti-r15 #1 SMP Tue Apr 5 12:32:22 UTC 2016 armv7l
I've tried many things discussed on StackOverflow and AskUbuntu, including:
#include <linux/usbdevice_fs.h>
int main(void)
{
int fd = open( "/dev/bus/usb/001/002", O_WRONLY );
if (fd < 0) return 1;
int rc = ioctl( fd, USBDEVFS_RESET, 0 );
if (rc < 0) return 2;
close( fd );
return 0;
}
The USB device I need to turn off (and eventually back on) is a Champtek FS310 barcode reader which shows up as a magnetic card strip reader when I run lsusb:
> lsusb
Bus 001 Device 002: ID 040b:6543 Weltrend Semiconductor Manhattan Magnetic Card Strip Reader
Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
> lsusb -t
/: Bus 01.Port 1: Dev 1, Class=root_hub, Driver=musb-hdrc/1p, 480M
|__ Port 1: Dev 2, If 0, Class=Human Interface Device, Driver=usbhid, 1.5M
|__ Port 1: Dev 2, If 1, Class=Human Interface Device, Driver=usbhid, 1.5M
I've found that running these two commands results in the device turning off:
echo "1-1" > /sys/bus/usb/drivers/usb/unbind
echo "1-1" > /sys/bus/usb/drivers/usb/bind
Strangely enough, it only turns off during "bind", not "unbind". But once it turns off this way, the only way I've found to turn it back on is to reboot the computer, which is not a usable solution.
Indeed, that other question did have a technique that worked for what I was trying to do. Note this isn't a generic Linux answer, it will only work on BeagleBone Black and similar devices. (I tested on a BeagleBone Green.) Working backwards from the devmem2 example, this block of C++ code turns the USB power off, then back on:
const size_t page_size_in_bytes = getpagesize();
const size_t address_gpio3_13 = 0x47401c60; // see comment below
const size_t address_start = address_gpio3_13 / page_size_in_bytes * page_size_in_bytes;
const size_t address_offset = address_gpio3_13 - address_start;
int fd = open("/dev/mem", O_RDWR);
void *addr = mmap( 0, page_size_in_bytes, PROT_READ | PROT_WRITE, MAP_SHARED, fd, address_start );
uint8_t *byte_ptr = reinterpret_cast<uint8_t*>(addr);
byte_ptr[address_offset] = 0x00; // turn off USB
std::this_thread::sleep_for( std::chrono::milliseconds(500) );
byte_ptr[address_offset] = 0x01; // turn on USB
munmap( addr, page_size_in_bytes );
close(fd);
(Error handling not included.)
The magic number 0x47401c60 really is a magic number. According to some posts, it looks like a NDA needs to be signed to get access to some of the USB-related documentation. In the ARM335X Technical Reference Manual, the only mention of the 0x47401Cxx address space is the following on page 156:
Block Name Start Address End Address
USB1 Core 0x4740_1C00 0x4740_1FFF

Resources