| TIP: Click on subject to list as thread! | ANSI |
| echo: | |
|---|---|
| to: | |
| from: | |
| date: | |
| subject: | Re: [C] Gating |
Hi CHARLES! :-)
CA> Note: No listing of new C programs are posted here _ever_. ;-)
linuxrc program to boot a Linux system off a CD-ROM / filesystem (written
by me, but let's say I'm putting this into the public domain). This needs a
few more ingredients besides the C program to work, though. Something
similar to this is used by Knoppix and others, but I wrote mine from
scratch.
This can be compiled with
gcc -static -Os -march=i386 linuxrc.c -o linuxrc
strip linuxrc
and then it needs to be put onto a filesystem image as /linuxrc together
with an empty /mnt directory and a /dev directory containing /dev/console,
/dev/hda through /dev/hdt, and /dev/scd0 through /dev/scd9. This filesystem
image can then be compressed with gzip and passed to a linux kernel as an
initial ramdisk image. On boot, the kernel will unpack the image and run
the /linuxrc program. The program then locates the CD-ROM devices in the
system and tries each of them in turn to find a disc with the file
/etc/rc.d/rc.sysinit (system initialization script) on it. If it is found,
it is made the new / filesystem and /sbin/init is executed from it.
----- linuxrc.c begins -----
#include
#include
#include
#include
#include
#include
#include
#include
#include
int pivot_root(const char *new_root, const char *put_old);
#define KLOG_GET_MESSAGES 3
#define KLOG_SET_LOGLEVEL 8
#define BUFSIZE 65536
#define DEVNAMEMAX 16
#define UNIQUEFILE "/mnt/etc/rc.d/rc.sysinit"
void halt_system(void)
{
while (1)
;
}
void check_okay(int res, const char *errmsg)
{
if (res < 0) {
printf("Error: %s\n", errmsg);
halt_system();
}
}
int correct_medium(const char *devname)
{
int res;
struct stat buf;
res = mount(devname, "/mnt", "iso9660", (0xC0ED
<< 16) | MS_RDONLY, 0);
if (res == -1) {
printf("No suitable medium on %s\n", devname);
return 0;
}
res = stat(UNIQUEFILE, &buf);
if (res == -1) {
umount("/mnt");
printf("Unrelated filesystem on %s\n", devname);
return 0;
}
printf("Root filesystem found on %s\n", devname);
return 1;
}
void change_root(void)
{
int res;
res = chdir("/mnt");
check_okay(res, "could not cd into CD-ROM root filesystem");
res = pivot_root("/mnt", "/mnt/initrd");
check_okay(res, "could not change / to CD-ROM root filesystem");
execl("/sbin/init", "/sbin/init");
check_okay(-1, "could not execute /sbin/init");
}
int main(int argc, char **argv)
{
char buf[BUFSIZE];
char devname[DEVNAMEMAX];
char *work, *line, *sub;
int res, found = 0;
puts("Attempting to locate CD-ROM device");
klogctl(KLOG_SET_LOGLEVEL, NULL, 1);
memset(buf, 0, BUFSIZE);
res = klogctl(KLOG_GET_MESSAGES, buf, BUFSIZE);
check_okay(res, "could not read kernel messages");
work = buf;
while (work) {
line = strsep(&work, "\n");
sub = strstr(line, "ATAPI CD/DVD-ROM drive");
if (sub) {
memset(devname, 0, DEVNAMEMAX);
strcpy(devname, "/dev/");
memcpy(devname+5, line+3, 3);
printf("ATAPI CD-ROM at: %s\n", devname);
if (correct_medium(devname))
change_root();
found = 1;
}
sub = strstr(line, "Attached scsi CD-ROM sr");
if (sub) {
memset(devname, 0, DEVNAMEMAX);
strcpy(devname, "/dev/scd");
memcpy(devname+8, line+26, 1);
printf("SCSI CD-ROM at: %s\n", devname);
if (correct_medium(devname))
change_root();
found = 1;
}
}
if (!found)
puts("No CD-ROM device found");
else
puts("Root filesystem not found on CD-ROM device(s)");
halt_system();
/* NOT REACHED */
return 0;
}
----- linuxrc.c ends -----
Ciao
Pascal
--- Msged/LNX 6.1.1
* Origin: The Nine have left Minas Morgul. (1:153/401.2)SEEN-BY: 633/267 270 @PATH: 153/401 307 140/1 106/2000 633/267 |
|
| SOURCE: echomail via fidonet.ozzmosis.com | |
Email questions or comments to sysop@ipingthereforeiam.com
All parts of this website painstakingly hand-crafted in the U.S.A.!
IPTIA BBS/MUD/Terminal/Game Server List, © 2025 IPTIA Consulting™.