2024 π Daylatest newsbuy art
Love itself became the object of her love.Jonathan Safran Foercount sadnessesmore quotes
very clickable
data + munging

The Perl Journal

Volumes 1–6 (1996–2002)

Code tarballs available for issues 1–21.

I reformatted the CD-ROM contents. Some things may still be a little wonky — oh, why hello there <FONT> tag. Syntax highlighting is iffy. Please report any glaring issues.

The Perl Journal
#18
Summer 2000
vol 5
num 2
Simon Cozens (2000) Perlix, the Perl Operating System. The Perl Journal, vol 5(2), issue #18, Summer 2000.

Perlix, the Perl Operating System

Simon Cozens


URLs
Perlix..............................ftp://othersideofthe.earth.li/pub/perl
Perl Power Tools......................https://language.perl.com/ppt/
Perl Shell..............https://www.focusresearch.com/gregor/psh/

It started, as so many of these things do, with one of those interminable debates between programmers. You know what I mean. They usually end up with one party shouting something like "Well, fine, I don't care if it's impossible, I'm going to do it anyway!"

This time around, it was me, and the topic in question was an operating system user-space comprised of non-GNU components. An operating system consists of two components: the kernel, like Windows or Linux, which talks to the hardware and directs the action, and the user-space, which is all the programs that you see and use: a shell, Explorer, programs to list directories, move files, read your mail, play games, and so on.

On "free" operating systems, a sizeable proportion of the essential user-space — not the really high-level things like web browsers, but the basic stuff that gets the system up and running — comes from the GNU project, and it was these programs that I wanted to replace.

Don't get me wrong. This wasn't an anti-GNU jihad. But someone had told me it wasn't possible, which was precisely the incentive I needed to get stuck into an idea I'd had a while ago.

Any sensible person would use BSD code here -- the BSD project derived their utilities from de-commercialized sources of Unix, and evolved independently of GNU. But that would be easy. And it wouldn't be fun. If you're going to prove a point, do it with style. So I was going to do it with Perl.

Now, I assume you've heard of the Perl Power Tools; if you haven't, you really want to check them out! PPT is a set of Perl programs, masterminded by Tom Christiansen, that implement many standard Unix utilities. They're the first thing (other than Perl, of course) I'll install when I'm working on a non-Unix computer, and you can grab your copy from https://language.perl.com/ppt/.

Now, with these, a fair amount of the work was done for me -- a reasonable number of the utilities I wanted to replace had already been rewritten in Perl. So, I took an empty filesystem, picked the appropriate implementations and placed them in the appropriate directories. If the GNU project can get away with sitting atop a Linux kernel until they've finished writing their own, I think we can too. I don't have any plans to start a Perl kernel at present, but maybe after a few more arguments...

Next, I compiled a statically linked perl executable; since that was necessary for everything to work and responsible for providing the Perl language to all the other programs, I decided to put it in /lib/, just like the C library. (You might see a file like /lib/libc-2.1.so in a Unix system, which provides all the standard functions of the C language to most of the programs written in C.)

Of course, there doesn't need to be anything else in /lib/ -- after all, I haven't written a dynamic linker in Perl yet. At three meg when stripped, /lib/perl is smaller than its libc counterpart.

We need a shell, of course, so I used Gregor Purdy's Perl Shell, available from https://www.focusresearch.com/gregor/psh/ and hacked together a quick /sbin/init which did very little other than call it. init is the program the kernel calls when it starts to get the rest of the operating system going. Some day I should write a real init; it's boring being in single user mode all the time. [The Perl Shell is introduced later in this issue. -- Editor]

I would like to be able to say it all worked fine first time, but it didn't. It took me quite a few attempts to get the Perl Shell talking to the Term::ReadLine modules properly, and I made a mess of the initial Perl installation. But it certainly booted, and there was a complete set of basic utilities available. After four or five tries getting all the modules in place, I had it working.

At this point, it stopped being an attack of hubris, and I started to realize quite what I had here -- a basic operating system, completely Perl based. Amazingly portable: just replace one file and you can move to a different type of machine. Extremely lightweight: under twenty meg for a complete installation, which of course includes a full Perl install. And surprisingly fast; since everything depends on Perl, the Perl image stays in memory most of the time.

Of course, there are a few problems. The biggest thing at the moment is a lack of applications. You're limited to what's been done in Perl. There's no windowing system and no console graphics. At the moment, there's no networking and no sound support either. It can't regenerate itself -- when the C compiler's written in C you can recompile it and upgrade it, but since Perl isn't (yet) written in Perl, you have to upgrade it on a computer that has C available.

What's in the future for Perlix? Well, we need an init and some system configuration (rc) files -- all done in Perl, of course. The Bourne shell's nice and portable, I know, but a little inflexible and slow for this sort of system work. After that, my priorities are networking support and a login. These are the most operating-system-specific elements, and the most difficult to do; I've just finished a mount (Listing 1), which allows us to mount /proc and examine the process table. I'm taking the opportunity to work in support for configuration files in XML as well as traditional Unix-style flat text: mount can read either a standard /etc/fstab or an XML equivalent.

Then, I suppose, we can start getting a few applications together. telnet, ftp, and their friends are easily taken care of with the Net:: modules, and similar tactics can yield expect, gzip, and a few other Unix mainstays. This should allow us to get the CPAN module working as a standalone utility, allowing for much easier installation of other modules.

A text-mode web browser in the style of lynx or w3m would be extremely welcome, and we're in desperate need of some text editors to allow future development to proceed on Perlix itself.

Looking to the longer term, I'm about 10% of the way through a TeX distribution, although I'm not planning to provide METAFONT. We'll also need to think about password support and internationalization at some point.

But for the time being, it works! I'll be using Perlix as the primary distribution on my laptop in a few months, although I will have some C libraries handy just in case.

If this sounds like fun to you, please feel free to contribute. Download a copy of Perlix, and pick some applications to port. (Get in touch with me first to see if anyone else is doing the same thing, of course.) We also need some mind-bogglingly crazy people to consider writing a kernel; Claudio Clavelli has been working on a Linux filesystem written in Perl, which I hope to use eventually: you can find that at https://www.assurdo.com/perlfs.

If you don't want to be quite so extreme, consider helping out with -- or at the very least, downloading and trying out -- the Perl Power Tools project I mentioned above; there's a natural link between the two, and I hope we can produce some work of mutual benefit. Alternately, you might want to join the Perl Shell development effort over at https://www.sourceforge.com/.

Perlix is available for download from ftp://othersideofthe.earth.li/pub/perl.


Simon Cozens is a Perl programmer and author, and claims to be completely sane.

listing 1

Perlix, The Perl Operating System The Perl Journal, Summer 2000
Simon Cozens (2000) Perlix, the Perl Operating System. The Perl Journal, vol 5(2), issue #18, Summer 2000.
 
#!/lib/perl -w
use strict;      # This is an operating system, after all.
my $canxml; eval { use XML::Simple }; $canxml++ unless $@;
my $VERSION = "1.0";
use Data::Dumper;
use Getopt::Std; my %options;
getopts("t:ho:v",\%options);
defined $options{v} && do {print "Perlix mount version $VERSION\n"; exit};
defined $options{h} && exec("perldoc mount");
my $dev_or_point = shift || do {print "mtab support not here yet.\n";
		exit;};
my %fstab; open(FSTAB, "/etc/fstab") or die "$0: Can't open fstab: $!\n";
if (($_=<FSTAB>) =~/^<\?xml/) {
     die "XML support not installed.\n" unless $canxml;
     $fstab{$_->{directory}} =
          [ $_->{filesystem}, $_->{type}, join ",", keys %{$_->{options}} ]
     for (@{XMLin(join "", <FSTAB>)->{entry}}) ;
} else {
     do {
          next if /^#/;
          my ($device, $mpoint, $type, $options) = split;
          $fstab{$mpoint} = [$device, $type, $options];
     } while (defined ($_ = <FSTAB>));
}
print Dumper(\%fstab);
use constant MAGIC => 0xC0ED0000; # Kernel mount magic. (Linux specific!)
use constant MS_RDONLY  =>   0; use constant MS_NOSUID  => 1;
use constant MS_NODEV   =>   2; use constant MS_NOEXEC  => 3;
use constant MS_SYNC    =>   4; use constant MS_REMOUNT => 5;
my ($mount, $what, $where, $type);
if (exists $fstab{$dev_or_point}) {   # It's a mount point.
     $where =$dev_or_point;
     ($what,$type) = ($fstab{$where}->[0], $fstab{$where}->[1]);
     defined $options{t} && do {print "Can't change type here.\n"; exit};
     $options{o} ||= $fstab{$where}->[2],
     $mount = options($options{o})+(0+MAGIC);
} else { # It's a block device, you'd hope.
     $what = $dev_or_point;
     -b $what or die "$what isn't a block device.\n";
     $where = shift or die "You need to tell me where to mount $what\n";
     $mount = options($options{o}||"") + (0+MAGIC);
     $type=$options{t} or die "Don't know how to mount $what on $where\n";
}
my $data = "";
syscall(&SYS_mount, $what, $where, $type, $mount, $data);
die "Mounting $what on $where: $!\n" if $!;
sub options {
     my $options = shift;
     my $mode=chr(0); # I've got a bit vector and I'm not afraid to use it.
     for (split ",", $options) {
          last if $_ eq "defaults";
          ($_ eq "ro"	) && do	{ vec($mode,MS_RDONLY	,1)=1;	next};
          ($_ eq "rw"	) && do	{ vec($mode,MS_RDONLY	,1)=0;	next};
          ($_ eq "nosuid"	) && do	{ vec($mode,MS_NOSUID	,1)=1;	next};
          ($_ eq "nodev"	) && do	{ vec($mode,MS_NODEV 	,1)=1;	next};
          ($_ eq "noexec"	) && do	{ vec($mode,MS_NOEXEC	,1)=1;	next};
          ($_ eq "sync"	) && do	{ vec($mode,MS_SYNC 	,1)=1;	next};
          ($_ eq "remount"	) && do	{ vec($mode,MS_REMOUNT	,1)=1;	next};
          warn "Unrecognised option $_ ignored\n";
     }
     return ord($mode);
}
Martin Krzywinski | contact | Canada's Michael Smith Genome Sciences CentreBC Cancer Research CenterBC CancerPHSA
Google whack “vicissitudinal corporealization”
{ 10.9.234.152 }