I am building a Linux system from the bottom for a Beagle Bone board. I have compiled the vanilla kernel and built a basic root file system with busybox. The system is booted with U-boot, while the rootfs is located on a Linux PC and exported through NFS:
/path/to/rootfs 10.42.0.17(rw,wdelay,no_root_squash,no_subtree_check,sec=sys,rw,secure,no_root_squash,no_all_squash)
The U-boot bootargs are:
bootargs console=ttyO0,115200n8 root=/dev/nfs rw nfsroot=${serverip}:/path/to/rootfs,v3,tcp ip=dhcp
I've encountered a problem when trying to get su working for non-root users. In order to work around the problem people over internet are suggesting to set the suid bit for the busybox binary.
After doing so:
$ sudo chmod u+s busybox
and verifying:
$ ls -la
...
-rwsr-xr-x 1 myuser myuser 1882976 Jan 13 21:47 busybox
...
$ stat -c "%a %n" busybox
4755 busybox
Something went wrong. The kernel is booting and all of the usual messages are displayed, but it is getting stuck at the end, and no login line is displayed. Here are last few lines of the booting sequence:
[ 3.776185] IP-Config: Complete:
[ 3.779656] device=eth0, hwaddr=c8:a0:30:c5:80:e9, ipaddr=10.42.0.17, mask=255.255.255.0, gw=10.42.0.1
[ 3.789877] host=10.42.0.17, domain=, nis-domain=(none)
[ 3.795822] bootserver=10.42.0.1, rootserver=10.42.0.1, rootpath=
[ 3.802492] nameserver0=10.42.0.1
[ 3.871575] VFS: Mounted root (nfs filesystem) on device 0:15.
[ 3.879903] devtmpfs: mounted
[ 3.883713] Freeing unused kernel memory: 380K (c07ef000 - c084e000)
If removing the flag, the things are returning to normal:
....
[ 3.862291] Freeing unused kernel memory: 380K (c07ef000 - c084e000)
10.42.0.17 login:
If setting the flag from within the running shell on the Beagle Bone board itself, the shell is stopping responding right after the chmod is performed.
I suspect it is something to do with the way the NFS is exporting the rootfs, but it's only a guess, so qualified explanation and possible solution would be helpful.
After some research I will answer my question myself. The answer is very simple. In order the above to work, the busybox binary should be owned by root:root. The simplest solution is just to change the ownership.
Related
I have an embedded ARM system with processor AT91SAM9G45.
System consists of two components:
Linux kernel (4.14.79)
Busybox 1.29.3 as initramfs image.
I connect to the device using putty and connecting to serial port.
When kernel starts, everything goes fine. Kernel unpacks initramfs image, all files are found and listed (I see it by debug messages). But when it starts /init, log messages are:
Freeing unused kernel memory: 384K
This architecture does not have kernel memory protection.
run_init_process BEFORE /init
run_init_process AFTER /init, result = 0
Kernel panic - not syncing: Attempted to kill init! exitcode=0x00000004
/init is symlink to /bin/busybox. I tried to replace /init with /sbin/init, /bin/busybox, /linuxrc, but results are the same.
/etc/inittab file:
# Begin /etc/inittab
id::initdefault:
si::sysinit:/etc/init.d/rc S
#l0::wait:/etc/rc.d/init.d/rc 0
#l1::wait:/etc/rc.d/init.d/rc 1
#l2::wait:/etc/rc.d/init.d/rc 2
#l3::wait:/etc/rc.d/init.d/rc 3
#l4::wait:/etc/rc.d/init.d/rc 4
#l5::wait:/etc/rc.d/init.d/rc 5
#l6::wait:/etc/rc.d/init.d/rc 6
ca::ctrlaltdel:/sbin/shutdown -t1 -a -r now
su::once:/sbin/sulogin
1::respawn:/sbin/getty ttyS1 115200
2::respawn:/sbin/getty ttyS2 115200
3::respawn:/sbin/getty ttyS3 115200
4::respawn:/sbin/getty ttyS4 115200
5::respawn:/sbin/getty ttyS5 115200
6::respawn:/sbin/getty ttyS6 115200
# End /etc/inittab
/etc/init.d/rcS file (this file is allowed to execute):
#!/bin/busybox sh
echo "Hello world!"
I don't know if even /init process starts parsing /etc/inittab or it falls before getting /etc/inittab by some reasons I cannot find out. Maybe there are
some mistakes in my /etc/inittab and /etc/init.d/rcS files. Maybe there are some errors with terminal (/etc/init.d/rcS cannot write to stdout cause it's blocked, suspended, being used by another process and so on).
How to definitely get sured, that /etc/inittab is started?
Welcome to StackOverflow.
I see there is space between rc and S
si::sysinit:/etc/init.d/rc S
change it to
si::sysinit:/etc/init.d/rcS
let me know if it works.
/init is symlink to /bin/busybox.
The typical /init file in an initramfs built by Buildroot that incorporates Busybox is a script of seven lines:
#!/bin/sh
# devtmpfs does not get automounted for initramfs
/bin/mount -t devtmpfs devtmpfs /dev
exec 0</dev/console
exec 1>/dev/console
exec 2>/dev/console
exec /sbin/init $*
Note the comment ("devtmpfs does not get automounted for initramfs") and the mount command for /dev.
It's /sbin/init (rather than /init) that is linked to /bin/busybox.
IOW without the proper setup of the /dev directory, userland has no I/O capabilty.
Only after devtmpfs has been mounted should the init program in Busybox be executed, which will then access /etc/inittab.
See Is there a way to get Linux to treat an initramfs as the final root filesystem?
and
Make CONFIG_DEVTMPFS_MOUNT apply to initramfs/initmpfs
I'm working on an embedded ARM device running Linux (kernel 3.10), with NAND memory for storage. I'm trying to build a minimal linux which will reside on its own partition and carry out updates of the main firmware.
The kernel uses a very minimal root fs which is stored in a ramfs. However, I can't get it to boot. I get the following error:
[ 0.794113] List of all partitions:
[ 0.797600] 1f00 128 mtdblock0 (driver?)
[ 0.802669] 1f01 1280 mtdblock1 (driver?)
[ 0.807697] 1f02 1280 mtdblock2 (driver?)
[ 0.812735] 1f03 8192 mtdblock3 (driver?)
[ 0.817761] 1f04 8192 mtdblock4 (driver?)
[ 0.822794] 1f05 8192 mtdblock5 (driver?)
[ 0.827820] 1f06 82944 mtdblock6 (driver?)
[ 0.832850] 1f07 82944 mtdblock7 (driver?)
[ 0.837876] 1f08 12288 mtdblock8 (driver?)
[ 0.842906] 1f09 49152 mtdblock9 (driver?)
[ 0.847928] No filesystem could mount root, tried: squashfs
[ 0.853569] Kernel panic - not syncing: VFS: Unable to mount root fs on unknown-block(1,0)
[ 0.861806] CPU: 0 PID: 1 Comm: swapper Not tainted 3.10.73 #11
[ 0.867732] [<800133ec>] (unwind_backtrace+0x0/0x12c) from [<80011a50>] (show_stack+0x10/0x14)
(...etc)
The root fs is built by the build process, using the following (simplified for clarity):
# [Copy some things to $(ROOTFS_OUT_DIR)/mini_rootfs]
cd $(ROOTFS_OUT_DIR)/mini_rootfs && find . | cpio --quiet -o -H newc > $(ROOTFS_OUT_DIR)/backup.cpio
gzip -f -9 $(ROOTFS_OUT_DIR)/backup.cpio
This creates $(ROOTFS_OUT_DIR)/backup.cpio.gz
The kernel is then built like this:
#$(MAKE) -C $(LINUX_SRC_DIR) O=$(LINUX_OUT_DIR) \
CONFIG_INITRAMFS_SOURCE="$(ROOTFS_OUT_DIR)/backup.cpio.gz" \
CONFIG_INITRAMFS_ROOT_UID=0 CONFIG_INITRAMFS_ROOT_GID=0
I think this means it uses the same config as the main firmware (built elsewhere), but supplies the minimal ramfs image using CONFIG_INITRAMFS_SOURCE.
From Kernel.Org, the ramfs is always built anyway, and CONFIG_INITRAMFS_SOURCE is all that is needed to specify a pre-made root fs to use. There are no build errors to indicate that there is a problem creating the ramfs, and the size of the resulting kernel looks about right. backup.cpio.gz is about 3.6 MB; the final zImage is 6.1 MB; the image is written to a partition which is 8 MB in size.
To use this image, I set some flags used by the (custom) boot loader which tell it to boot from the minimal partition, and also set a different command line for the kernel. Here is the command line used to boot:
console=ttyS0 rootfs=ramfs root=/dev/ram rw rdinit=/linuxrc mem=220M
Note that the nimimal root fs contains "/linuxrc", which is actually a link to /bin/busybox:
lrwxrwxrwx 1 root root 11 Nov 5 2015 linuxrc -> bin/busybox
Why doesn't this boot? Why is it trying "squashfs" filesystem, and is this wrong?
SOLVED! It turned out that a file name used by the (custom) build system had changed as part of an update, and so it was not putting the correct kernel image into the firmware package. I was actually trying to boot the wrong kernel with the "rootfs=ramfs" parameter, one which didn't have a ramfs.
So, for future reference, this error occurs if you specify "rootfs=ramfs" but your kernel wasn't built with any rootfs built in (CONFIG_INITRAMFS_SOURCE=... NOT specified)
I've just tried Bash on my Windows 10 PC, and it works fine. However, I found that there is no such thing as loop devices by ls /dev/, and modprobe loop gives an error output.
Does it mean this Bash doesn't support loop devices at all or is there a solution for mounting an image as a loop device?
Windows Subsystem for Linux 1 (WSL, formerly known as Bash on Ubuntu on Windows) did not support loop devices. There was a feature request and an issue about it on Microsoft's Git repo.
WSL 2, however, does support loop devices.
$ uname -a
Linux Blade 5.10.102.1-microsoft-standard-WSL2 #1 SMP Wed Mar 2 00:30:59 UTC 2022 x86_64 x86_64 x86_64 GNU/Linux
$ fallocate -l 1G test.img
$ mkfs.ext3 test.img
mke2fs 1.45.5 (07-Jan-2020)
Discarding device blocks: done
Creating filesystem with 262144 4k blocks and 65536 inodes
Filesystem UUID: 549cca4d-a65f-4f4f-8428-e324feaed3d0
Superblock backups stored on blocks:
32768, 98304, 163840, 229376
Allocating group tables: done
Writing inode tables: done
Creating journal (8192 blocks): done
Writing superblocks and filesystem accounting information: done
$ sudo mount -o loop test.img /media/
$ ls /media/
lost+found
Do you know that Bash is just a shell (something that reads your commands, executes them, pipes between them and permits you to write scripts) and is not an operating system?
Loop devices are part of the Linux kernel, and they simply don't exist in the Windows kernel.
I recently tried to install php5-gd package on my debian vmware server and it failed at libc6 - i386.
Afterwards every command other than CD caused a Segmentation fault and the server would no long boot, showing the following error
[ 4.808086] init[1]: segfault at 0 ip (null) sp bff4645c error 14 in init[8048000+8000]
[ 4.808372] Kernel panic - not syncing: Attempted to kill init!
[ 4.808442] Pid: 1, comm: init Not tainted 3.2.0-4-686-pae #1 Debian 3.2.65-1
[ 4.808512] Call Trace:
(Trace continued in this image
)
I am at a complete loss on what to do at this moment. Any help or direction would be appreciated
Edit: I've since uploaded debian-live-8.3.0-i386-standard to the vmware store and booted the broken vm with the live cd.
Now I am in the live cd terminal but not sure what to do next. I did a lsblk and noted that the broken vm's boot partition is sda > sda2 and that's all I have done so far. Do I need to mount this somewhere now?
Edit2: I've now mounted the broken partition into the live cd, however when I tried to chroot, I get Segmentation Fault:
# mkdir -p /mnt/tcs1/boot
# mount /dev/tcs1/root /mnt/tcs1
# mount /dev/sda1 /mnt/tcs1/boot
# mount -t proc none /mnt/tcs1/proc
# mount -o bind /dev /mnt/tcs1/dev
# mount -o bind /run /mnt/tcs1/run
# mount -o bind /sys /mnt/tcs1/sys
# chroot /mnt/tcs1 /bin/bash
# Segmentation fault
Solved:
I relinked ld-linux.so.2 to /lib/i386-linux-gnu/ld-2.19.so from a rescue CD and managed to chroot in
One of the books on advanced linux programming states:
The /proc/filesystems entry displays the file system types known to the kernel. Note that this list isn't very useful because it is not complete: File systems can be loaded and unloaded dynamically as kernel modules.The contents of /proc/filesystems list only file system types that either are statically linked into the kernel or are currently loaded. Other file system types may be available on the system as modules but might not be loaded yet.
Now, I have:
➜ ~ ps -C sshfs
PID TTY TIME CMD
8123 ? 00:00:00 sshfs
➜ ~ mount | grep sshfs
root#ss1: on /home/wani/tmp type fuse.sshfs (rw,nosuid,nodev,relatime,user_id=0,group_id=0)
➜ ~
But ...
➜ ~ cat /proc/filesystems | grep sshfs
➜ ~
sshfs is implemented in userspace using the FUSE infrastructure. Userspace filesystems are not known to the kernel as a separate entity. The FUSE kernel-side infrastructure itself, however, is known to the kernel. On my system:
$ cat /proc/filesystems
nodev sysfs
nodev rootfs
nodev ramfs
...
ext4
cramfs
...
nodev fuse
nodev fusectl
...
Note the last two lines; the kernel is aware of a fuse filesystem, which is essentially an adapter interface that lets filesystem services to be provided by userspace processes.