tech-embed archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
Re: Where to start...?
The attached mini_init.c works for me. (Note that this is a stripped
down version of an init that did a bit more stuff that is specific to
our system).
Compile with "cc -Wall -Werror -static -o init mini_init.c".
/Erik
Rose, Brian wrote:
From: Erik Anggard <erik.anggard%packetfront.com@localhost>
List: tech-embed
Well, if you want to get really minimalistic all you'll need is:
- A kernel (comment out all options and devices you don't need, in the
config file before compiling it to reduce the size of the kernel).
- A root device: if you don't have a hardrive you can use a memory disk
beded in the kernel (like in the installation-kernel) or NFS.
- Your own statically linked /sbin/init on the root device. This is the
only userland process started by the kernel so if your system only need
to run one program call it init and place it in /sbin. (Your program
might have to do some of the things that the original init does, e.g. if
your program wants do console io you will need a /dev/console and your
init will have to open that device and dup2 fd's 0, 1 and 2 to that fd).
You can of course use the standard init and instead creat your own
/etc/rc.
Has anyone created a minimal init that just sets up the console? I've tried
looking through the init code, but I'm not seeing where it sets this up.
I'm currently looking through all the glibc functions to find outhow to do
this. Is there a simple code snippet somewhere that shows how to set up the
console and operate a simple C program (aka Hello World!)?
Thanks for the help.
Brian Rose
Brian dot Rose at icn dot siemens dot com
407-942-6934
If you hold a Unix shell to your ear, do you hear the C?
/* $Id: asrbl.c,v 1.48 2002/03/05 10:34:09 eriang Exp $ */
/*
* File: mini_init.c
* By: Erik Anggard, PacketFront Sweden AB
* Created: 2001-10-02
*
* Minimal init process.
*
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <fcntl.h>
#include <unistd.h>
#include <signal.h>
#include <sys/ioctl.h>
#include <sys/param.h>
#include <sys/reboot.h>
#include <sys/mount.h>
#include <ufs/ufs/ufsmount.h>
#include <sys/cdefs.h>
#include <sys/socket.h>
#include <stddef.h>
#include <syslog.h>
/*
* Defines
*/
#define DEFAULT_ROOTUID -2
#define PATH_CONSOLE "/dev/console"
#define MAXCMD 128
/*
* Prototypes
*/
static void reboot_system(void);
static void critical(char *msg);
static int setup_tty(char *name, int redirect);
void badsig_handler(int sig);
static int setup_signals(void);
/*
* Globals
*/
int single = 0;
/*
* main
*/
int
main(int argc, char *argv[])
{
struct ufs_args args;
char cmdstr[MAXCMD+1], *s, *s2;
int done;
if (argc == 2 && !strcmp(argv[1], "-s"))
single = 1;
if (single) {
openlog("init", LOG_CONS|LOG_ODELAY, LOG_AUTH);
/* remount root fs in read-write */
bzero(&args, sizeof(struct ufs_args));
args.export.ex_root = DEFAULT_ROOTUID;
if (mount(MOUNT_FFS, "/", MNT_UPDATE, &args) == -1)
syslog(LOG_ALERT, "init: failed to remount root files "
"system read-write\n");
setup_signals();
setup_tty(PATH_CONSOLE, 1);
}
done = 0;
while (!done) {
/* Display simple prompt. */
printf("# ");
if ((s = fgets(cmdstr, MAXCMD, stdin)) != NULL) {
/* strip white space */
while (isspace(*s)) s++;
s2 = s;
while (*s2 != '\0') s2++;
s2--;
while (isspace(*s2) && s2 > s) s2--;
s2[1] = '\0';
if (*s == '\0')
continue;
/* Handle commands. */
if (!strcmp(s, "reboot")) {
done = 1;
} else if (!strcmp(s, "test")) {
printf("test!\n");
} else {
printf("unkown command: %s\n", s);
}
}
}
if (single)
reboot_system();
return (0);
}
/*
* reboot
*/
static void
reboot_system(void)
{
if (reboot(RB_AUTOBOOT, NULL) == -1)
perror("reboot");
for (;;);
}
/*
* critical
*/
static void
critical(char *msg)
{
syslog(LOG_EMERG, "%s", msg);
reboot_system();
}
/* Setup the console for output/input/whatever. Much of this is
* taken from the NetBSD init and libs.
*/
static int
setup_tty(char *name, int redirect)
{
int fd;
revoke(name);
sleep(2); /* NetBSD does this. */
if((fd = open(name, O_RDWR)) == -1)
critical("Unable to open tty");
/* Taken from login_tty */
setsid();
if(ioctl(fd, TIOCSCTTY, NULL) == -1)
critical("Unable to set controlling tty");
if (redirect) {
dup2(fd, 0);
dup2(fd, 1);
dup2(fd, 2);
}
if (fd > 2)
close(fd);
return 0;
}
/*
* badsig_handler
*/
void
badsig_handler(int sig)
{
char text[64];
snprintf(text, 64, "Received signal %d", sig);
critical(text);
}
/* Signal choices taken from NetBSD init. */
static int
setup_signals(void)
{
struct sigaction sa;
sigset_t mask;
sigemptyset(&sa.sa_mask);
sa.sa_flags = 0;
sa.sa_handler = badsig_handler;
sigaction(SIGSYS, &sa, NULL);
sigaction(SIGABRT, &sa, NULL);
sigaction(SIGFPE, &sa, NULL);
sigaction(SIGILL, &sa, NULL);
sigaction(SIGSEGV, &sa, NULL);
sigaction(SIGBUS, &sa, NULL);
sigaction(SIGXCPU, &sa, NULL);
sigaction(SIGXFSZ, &sa, NULL);
sigaction(SIGTERM, &sa, NULL);
sigemptyset(&sa.sa_mask);
sa.sa_flags = 0;
sa.sa_handler = (void *)reboot_system;
sigaction(SIGUSR1, &sa, NULL);
sa.sa_flags = SA_NOCLDSTOP | SA_RESTART;
sa.sa_handler = badsig_handler;
sigaction(SIGCHLD, &sa, NULL);
sigfillset(&mask);
sigdelset(&mask, SIGABRT);
sigdelset(&mask, SIGFPE);
sigdelset(&mask, SIGILL);
sigdelset(&mask, SIGSEGV);
sigdelset(&mask, SIGBUS);
sigdelset(&mask, SIGSYS);
sigdelset(&mask, SIGXCPU);
sigdelset(&mask, SIGXFSZ);
sigdelset(&mask, SIGHUP);
sigdelset(&mask, SIGTERM);
sigdelset(&mask, SIGUSR1);
sigprocmask(SIG_SETMASK, &mask, NULL);
sigemptyset(&sa.sa_mask);
return 0;
}
Home |
Main Index |
Thread Index |
Old Index