Scheduled Maintenance: We are aware of an issue with Google, AOL, and Yahoo services as email providers which are blocking new registrations. We are trying to fix the issue and we have several internal and external support tickets in process to resolve the issue. Please see: viewtopic.php?t=158230

 

 

 

[SOL]Custom init process: open() function fails on /dev/tty.

If none of the specific sub-forums seem right for your thread, ask here.
Post Reply
Message
Author
User avatar
vanfanel
Posts: 7
Joined: 2013-06-23 17:31

[SOL]Custom init process: open() function fails on /dev/tty.

#1 Post by vanfanel »

Hi there!

I have to build a small system that only runs a program, no init system, service management.. Just a script that I run by passing init=myscript to the Linux kernel options.
Things work good with this small script:

Code: Select all

#!/bin/sh

mount -t sysfs sysfs /sys
mount -t proc proc /proc
mount -n -t tmpfs none /dev

# Manually create the tty console node
mknod -m 666 /dev/tty c 5 0 

/etc/init.d/udev start >> /dev/null

setupcon

# Run sh now
/bin/sh

/etc/init.d/udev stop
umount -a

reboot -f
As you can see this is, indeed, simple stuff.
However, callng the open() function on /dev/tty in my C programs just fail with ERRNO: "no such device or address"
For example, this fails:

Code: Select all

console_fd = open("/dev/tty", O_RDONLY);
I have also tried passing console=tty and console=tty1 to the kernel, with the same results.

I know there must me a piede missing in this puzzle: since I am directly running sh from the script, it seems to be running on a socket instead of a tty. Am I right?
But why can't open() open /dev/tty even if it exists?
So many questions I want to know.
What am I missing here, please?

NOTE: SOLVED.
It was a matter of creating the TTY nodes with the right numbers and permissions:

Code: Select all

mknod -m 666 /dev/tty c 5 0
mknod -m 660 /dev/tty1 c 4 1
And then sending sh to run on tty1 via setsid:

Code: Select all

exec setsid sh -c 'exec sh </dev/tty1 >/dev/tty1 2>&1'
There may be need for other /dev nodes to be created. Look at a running system and just copy their magic numbers and permissions and use mknod accordingly. For example, for graphics, audio and input on a Pi4 system:

Code: Select all

# Video nodes creation
mkdir -p /dev/dri
mknod -m 660 /dev/dri/card0 c 226 0
mknod -m 660 /dev/dri/card1 c 226 1
mknod -m 660 /dev/dri/renderD128 c 226 128

# Audio nodes creation
mkdir -p /dev/snd
mknod -m 660 /dev/snd/controlC0 c 116 0
mknod -m 660 /dev/snd/controlC1 c 116 32
mknod -m 660 /dev/snd/pcmC0D0p c 116 16
mknod -m 660 /dev/snd/pcmC1D0p c 116 48
mknod -m 660 /dev/snd/timer c 116 33

# Input nodes creation
mkdir -p /dev/input
mknod -m 660 /dev/input/mouse0 c 13 32
mknod -m 660 /dev/input/mice c 13 63
mknod -m 660 /dev/input/event0 c 13 64
mknod -m 660 /dev/input/event1 c 13 65
mknod -m 660 /dev/input/event4 c 13 68
mknod -m 660 /dev/input/js0 c 13 68
Remember that UDEV seems to load the necessary kernel modules for connected hw, but doesn't seem to create the /dev nodes unless it has rules set.

I HOPE IT HELPS OTHER PEOPLE BUILDING MINIMAL SYSTEMS IN THE FUTURE.

Post Reply