Episode: 2971
Title: HPR2971: World of Commodore 2019 Episode 2: Hacking GeckOS
Source: https://hub.hackerpublicradio.org/ccdn.php?filename=/eps/hpr2971/hpr2971.mp3
Transcribed: 2025-10-24 14:05:59

---

This is HPR episode 2,971 for Monday the 23rd of December 2019.
Today's show is entitled, World of Commodore 2019 Episode 2, Hacking Geckos,
and as part of the series, Hobby Electronics, it is hosted by Paul Quirk,
and is about 49 minutes long, and carries a clean flag. The summer is. Glenn Holner explains
how he got Linux running on a Commodore 64.
This episode of HPR is brought to you by Ananasthos.com. Get 15% discount on all shared hosting
with the offer code HPR15, that's HPR15.
Better web hosting that's honest and fair, at Ananasthos.com.
Hello, good people of Hacker Public Radio. This is Paul Quirk, and I've returned with my
second episode of my World of Commodore mini-series. This episode features a presentation by Glenn
Holmer, a retired Java programmer in Linux Amin, who lives in Milwaukee, Wisconsin, USA.
He has a web page at lionlabs.org, and on December 7th, 2019, he was at World of Commodore
to tell us how he got Linux running on a Commodore 64. Pictures of this presentation
are available at my non-commercial, personal website at peakwork.com. This presentation
included visuals that are not available in this audio podcast. If you'd like to see
and hear this and other World of Commodore presentations, I recommend you go to the Toronto
Pet Users Group YouTube page. That's Toronto Pet Users Group, spelt as one word without
spaces, and the word users is plural. A link to this YouTube channel will be available
in the show notes. And so, with no further ado, I present you Hacking Gecko S by Glenn
Holmer. Hi, all. I'm Glenn, and I'm going to talk about Gecko S, which is the Unix
like operating system for Commodore 64, and a couple of the other Commodore machines. I'm
a 64 guy, and my interest is programming languages and operating systems. I've got a
good collection, a lot of it's on my website there. And I've talked a lot of the Commodore
shorts. I talk every year at DCF Midwest, and I've spoken at the Las Vegas, one of
Las Vegas shows, the old C4 show. And of course, I've spoken at the premier Commodore
conference, which is of course World of Commodore here in Toronto. Although I do have to say,
Father, forgive me, it has been five years since my last World of Commodore. So I don't
know how many Hail Jack Travelles, I'll have to say for that. And most of the talks
I've given have been about programming languages. Although I've talked a couple of times about
operating systems, but it's always been GS. So I said to myself, you know, there are other
operating systems out there for the Commodore 64, and I should probably learn one and share
some knowledge about it. And so I looked through my collection and I decided I was going
to talk about GACO-S, which turned out to be a really good choice because of course this
year is the 50th anniversary of Unix, which of course is like Annis rich and Gantan
Thompson, the party hats on. And nice machine, PDP 11 Model 20. It's a pretty big honking machine
there even for the early versions of Unix, right? So if you look at that, and then you
think to yourself, if Unix on a Commodore 64, well, you might be forgiven if you had a reaction
like this. But let's stop and think about it. Is it really that crazy? Let's, you know,
you're not, you're, let's face, you're not going to get salirous or linux or BSD or anything
like that running out of Commodore 64. But you might get something like the earlier Unix
is that weren't quite as large as the modern ones are. So let's look at the machines that
the early versions of Unix ran out. And by the way, these numbers come from Brian
Kernahan's new book on the history of Unix, and Betty Redden had. Yeah, if you haven't
read it, go out and get it. It's a great book. But the first version of Unix was written
on a PDP 7. I think it's 16 kilobytes of memory. Now that's not exactly the exact number
because the machine had 18 bit words and so forth. But I didn't think about that for a
second, right? And then about a year later, they ported it to C-Langwoods and they ran
it on that big conkin PDP 11 you just saw was 24 K. Good Lord. Wow. On a Commodore 64, we have,
well, 64 K. Yeah, okay. We're covered in the memory department, right? How about processor speed?
Well, that's a little harder to compare because the machines are really very different than
there's, it's, you can't really make an Apple's to Apple's comparisons. But from the research I
did, I got the impression that they really are comparable in speed between a Commodore 64 and
PDP 11, but somebody by contradicting online, I'm sure, but at least it's in the ballpark, right? So
memory, processor speed? Yeah, not that far away. However, the CPU itself, that's where the comparison
kind of falls down because there are three big differences between the PDP 11 and a 6510.
First of all, the PDP 11 had a user mode and a kernel mode. So there was some protection when
the kernel was running that user programs couldn't stop all over it. And of course, there's nothing
like that on a 65 or two. We don't have, you know, ring zero or ring three or anything like that.
And second of all, the PDP 11 had eight 16-bit general registers.
Okay, what do we got on a 65 or two? We have these three little tiny 8-bit registers, right?
A cumulative X index, Y index, and those are not general registers. They all answered
the different instructions, right? So yeah, the code is going to be difficult. And the third thing
of course is the stack. PDP 11 had a register that said where the stack is. Which is what you
need for multitasking because of course, that three program has to have its own stack.
So it's a simple matter to change the value in that register and say, oh, well, now the stack is
over here. Let's go over and run this program, right? Nothing like that on the 65 or two. Of course,
where the stack is always at 0100 and there's no way to change it. So the coding is going to be
a lot more complicated. But as far as resources are concerned, it's not that crazy. It's not that
crazy an idea. So let's talk a little bit about the ECHO-S starting with this history. How many
people here know who Andre Fushat is? He's the guy who wrote ECHO-S. I see a few pants going up.
I would expect more. But Andre of course is known particularly as an expert on the older
machines like the pets and so forth. And I would expect that at the Toronto pet users group,
there would be people to know who he is. But anyway, Andre works for IBM over in Germany.
And he originally wrote ECHO-S to run on a machine that he built himself. He built a 65 or two
machine. And that machine had a memory management unit and supported up to a megabyte of memory.
So it didn't have quite the restrictions that you would see on, for example, a Commodore 64.
But he did later port it to run on some of the Commodore machines. It'll run on a pet,
even a 32k pet. It'll run on an 82.96, which of course is the most beautiful machine ever created.
And it'll run on a Commodore 64, which is what I'm going to talk about. So as I talk about the
details of this, just bear in mind that they might be slightly different from one version to another.
Now, development on ECHO-S is extremely actively, especially within the last month or so.
And I think it might be partly my fault that this happened because as I was studying ECHO-S and
learning it and preparing for the first presentation I gave at BCF Midwest in Chicago, I was corresponding
with Andre. And I was asking questions and stuff. And every so often he'd say, well, I really
should get back into ECHO-S. Well, he has. And everything is changing really fast. If you look at
the commits on GitHub, there's just this long list of the things that have been changed and improved
and added. So the source is GPL. It's freely available. It's on GitHub. The other coordinates
on it is repo. So if you want, you can check out the latest branch or the latest stable release
and build it yourself and run it on your own machine. It's trivially easy to build,
well, the serving Linux it is, but it's really not hard to build it at all. In fact, when I do my
demo, I'm going to do a clean and build with the entire operating system before and you won't
believe what fast it is. So let's, oh yes, I have one more picture here. This is one version of
the machine that Gekos originally was written to run on. Wouldn't you love that or something
that looked like that? I love that picture. And this is the one with the MMU and supporting
megabyte of memory. Anyway, let's now talk about the features of Gekos. Now, looking at all the
stuff on this list, again, you might be forgiven. If your mind goes back to that other slide and you
start thinking, are you crazy? But honestly, God, it's got all these things and I'll be
demoing most of them in just a minute. First of all, Gekos is a preemptively multi-passing operating
system. It really is. It's not a, you know, it's not some trick or anything. It's really
preemptively multi-passing. It's got a scheduler that runs at interrupt time based on a timer interrupt.
In fact, not only is it multi-tasking, preemptively multi-tasking, but it's got task priorities.
The kernel has a nice API so that you can drop your priority and let somebody else run more.
It's even got multi-threading. It's a, by default, every thread, every process, every task that is
has one active thread, but you can start other threads, or you can just fork into tasks.
It's got virtual consoles. Now, Linux users are probably familiar with this. On Linux, if you
were to control all DEF1, it drops you down to a full-screen console and you can go control all DEF2 and
so on. Linux users usually ships with a half a dozen consoles. There are four on Gekos and you
can just tap F1 to cycle between it. It's got signals. One process can send a signal to another
process. It's got semaphores, which are very important in Gekos because of the lack of hardware
protection. So you'd have semaphores that are defined by the operating system that refer to,
for example, a certain area of memory, or a certain device, or the serial lesson general. A lot
of the kernel APIs require you to lock a certain semaphore first before you call an API so that nobody
gets, nobody else gets in there and does something you shouldn't do. Again, that's because there's
just no protection against this kind of thing on the 65-2. The shell has both background and
redirection. I'll be showing those. It's got piping. Piping as far as I can tell was broke for a long
time and I'm really just submitted some patches to get it to work again, but that was like literally
within the past couple days and I think it still has an issue with certain programs, so I won't
be showing that, but I'm sure it'll get fixed within the next few days. It's got environmental
variables. I'm not going to show that either, but there's a single environment on the commoner 64
version as opposed to an environment per task. And then it has a relocatable file format, which is
something that Audrey came up with. And of course, that's very important in a multitasking operating
system because you don't know where your program is going to load. Your program might load here
here today and tomorrow there might be something else running there and it loads over here.
So you can't have any absolute addresses and you're executable. What happens is when the system
loads a program into memory before it runs it, it does an address fix up based on the load address
so that all the addresses match up. So that's very important and that'll come up again later in the
discussion. So having set all this wonderful stuff and brag about all the stuff that Gedguis can do,
I guess I better put my money where my mom is to do a demo. So I hope you don't mind,
I'm going to do the demo using rice, but Leap and I worked it out so that we're going to have a
describe sound. So it's going to be close, but not a real machine. The thing is if you're doing
operating system work on a commoner 64, you're pretty well going to have to use cross-evolvement
tools and amulators any week because it's just too unvealed the other ways. I'm normally very
disapproving of that sort of thing but you know all bets are off of the operating system.
So here's what I'm going to be showing and like I say this is a very recent build of Gedguis,
it's not the most recent build because I had to cut it off. I think Monday or so
because things were changing so fast I could just need this. I needed to know what version I was
going to be running. Yeah and here's all this stuff I'm going to be showing. The highlight is going
to be most of this stuff has been in Gedguis for years now, but the highlight is going to be the
new PS and kill commands and I'll show how those were developed and how they weren't about that.
So let's go over here and I've got vice running. So I'm going to actually
know I said I was going to build it from scratch didn't I? So let's do this and then let's do this.
I've got a little script I use and I'm going to do a complete clean and build of the operating
system and then bring it up in the vice monitor. That should take a long time, right?
Or not. That was it. Now when you start get OS there's a basic loader that loads a large
kernel image and then it loads a little tiny machine language like you're like this. Then it loads
a little tiny machine language stuff and passes control to it and that little stub disperses the
kernel image into upper memory above below the IO layer and then it starts it up and the magic
begins. Here we go. There is our boot screen so now we have a real a for really real
unique slight operating system running on a pretend Commodore 64. Notice when it starts up that
there are five things starting. There is init. There are two file system device drivers. There's
one that controls the devices and one that's specific with the IEC bus and then there are two
shelves. The one says shell and the second one says LSH which stands for library shell because it's
as a standard library. That older shell is considered more or less obsolete and it's not really
supported anymore but it still has for a tad until the features that weren't in the new shell
which is the one that we're looking at now. So that stuff is gradually being ported over to
the new shell and I think at some point that over one is going to be deprecated. But where is
that older shell? We're only seeing one of course. I don't remember I said it has virtual
consoles right so if I tap F1 there it is. There's the other shell. That's the old one. Nothing
on three, nothing on four so let's go back to one. And then older shell they're both loaded
at boot time and that older shell actually includes a built-in machine language. You can imagine
that it's using a lot of memory. So that's not a small piece of code name.
But let's go back to that first shell and I want to show you that GECOS has a lot of the things
you would expect in a Linux-like operating system starting with a real and of course you can do
something like this. And there you go. The file sizes of course are actual number of bytes used
on the disk, not the file size itself. It's a number of sectors used times 256. And you know it even
has, I'm not sure I'm going to device this would be applicable but it's got you can put more
else on it and get a display with more stuff. And this is kind of like the full-mod
version of LS and we'll see if yeah. I'm a 1540 watercolor so this doesn't even apply.
So you can also do something like for example this does what you would expect.
Okay, so those are going to be missing my cat. He's the best cat a boy ever had. He's never ever
known. And remember I said it has a redirectional whistleboard.
Okay, you hear the disk drive running because it's ready to file out. Nothing came out on
standard output. And of course if we want to see where the output went we can count that file.
And the output wouldn't exactly where we would expect it to go. So you know you can look through
the directory and play around with some of the other things it's got. As of very recently we
like the past few weeks it's now got a more command. It's got a WC command word count. So there's
a lot of other stuff. But I'd like to show some demo programs that I wrote for Gekos that are
showing the more internal features of it that I was described before. And there are three little
demos all of which involve two programs. The first program is going to fork a second program
when it starts and then there's going to be some interaction between those two programs.
So the first one demonstrates forking and multitasking. So I have these two programs.
This program when it starts up is going to fork a second program and then second program being
forked. It's going to start flashing the border slowly. Well you see the first program is still running.
Eventually the first program ends, second program is still running and eventually the second
program ends. So you can see that the multitasking is very smooth. We had a constant pulsing of the
border when it was changing colors and everything. So everything the multitasking works extremely well.
Second demo is signal passing, sending a signal from one process to another.
So this first program, the two programs are six send and six receive. The first program
works the second program and when the second program starts, he's going to register a signal hand
alert. It says setting mask there and it just goes off the top. But the first program mean title
printed a message saying hit a key when you want me to send a signal. And then that second program
he's just going in the timer loop waiting for that signal to be sent. So if I hit a key,
that first program sent sig user one and then ended and the second program received the signal.
So that has all kinds of interesting possibilities. There was a guy at the Chicago store who said,
I'm going to write a battleship, he uses signal passing to get to do the stuff.
Then there are the third demo is the semiforce and I talk about the importance of semiforce. So
here's an example of that. First program, when he starts up, he's going to lock an arbitrary
semiforce named sendem. Then he's going to report that second program called sem wait.
And of course, the first program says, by the way, hit a key when you want me to free it. But meanwhile,
he's got a lock on that semiforce. And the second program says, well, okay, I'm waiting because the
second program is trying to do the same thing. He's trying to lock that same semiforce. But of course,
he's going to get an error message saying, you know, that semiforce is in use. So when I hit a key,
the first program frees that semiforce and then ends. And when the second program comes up and gets
his slice and gets a chance to run again, he's going to try again. And this time he did acquire the
lock. And of course, when he's done, he's reased the semiforce and ends. So if you're writing programs
for gecoest that involves semiforce locking, make sure you release the semiforce afterwards. Otherwise,
there will be pain and suffering. So those are the demos that I wanted to show, except that there's
one more demo. That forking and multitasking demo, there's another version of that demo. Because
when I first got that running, I was so excited that I actually made a video of it. I posted a link
to the video at IRC and leaves all that video. And he said, well, it's all well and good. But
you really want to do his background, the whole demo, and then take a directory listing while it
was running, right? And my reaction was basically, you know, are you crazy? But I thought, you know,
what's the cap, and I should try it, right? And with gecoest, you'll see that it happened over
and over again. You might come up with some crazy idea, think, well, I wouldn't work, but you try
it, and it does work. It happens all the time. So I'm going to do a slightly different version of
what I call the schema demo. And instead of taking a directory listing, I'm going to ask for a
process list, which is a good segue into this new PS token that we have. So here's the forking
demo again. And this time, I'm going to background it. And when I get my cursor back,
I'm going to ask for a process list. So they're forking is running, the second program is flashing
the board, and we have a process listing, and then one by one, the other programs they have.
This guy's still running. All right, so we had, and I don't know what the error message is,
something that came up recently. It doesn't hurt anything right now, but I'll figure it out.
And anyway, look at this process list. This is a thing of beauty right here.
We have on the left-hand column, the PID, the process ID, and as it turns out, the process ID is
actually an index into the task table. So by looking at it, we can see that the task table has 12
by entries, because it goes up to 12 every time. And then in the second column, of course,
we have the name of the process, which you need to know. And then you have, and by the way,
that name is new that didn't used to be there, then there's the exact address, which is also new,
and you have to go to the exact address of the program to debug it. Because remember before,
I was talking about how you have relocatable programs, and you don't know what the addresses
of your routines are until the program gets loaded and relocated. So you might have, you know,
say you have a routine called, you know, my Groovy routine, and you want to put a break point on it.
And you assemble your program, and you look at the listing, and it says, well, my Groovy routine is
at 0100. Well, it's not at 0100. It's at offset 0100 from the beginning of the program.
So you have to take the loaded address of the program, add the offset, and that's where you
sit at break point. So you need to know the exact address. And again, that's something new.
Next column is a number of active threads. A number of body fault. I said that every cast has one
active thread. And then that next one is really interesting. I love that next column. It's
parent PID. So the first one in it, of course, is me, it was the primary processes. And he really
has no panic. He gets started up by the kernel in root time. So he's got a parent of FF.
And remember when we saw Gecko as starting, and there were five things that started up in it,
two file system device drivers and two shells. So we can see that those are the first five entries.
And those second four all have a parent of 0, which means they were started in turn by in it.
Now we see that 3-0 is the shell, the one we're looking at. And I started forking from the
command line. So forking has a parent of 3-0, which is the shell. And forking, forked, forked,
and forked therefore has a parent PID of 3 Charlie. That makes sense. And then when I got my cursor
I typed PS at the command line. So PS has a parent of 3, the shell, not 3-0. So that is very
interesting information to have. SM is the signal mask for passing signals. So it's what signals
of program is prepared to respond to. And SIG A is the signal handler address,
another is the address that gets jumped to when the signal was received. Those last four are
all the same because, and I just learned this, the standard library actually multiplexes those,
and they all go to the same place and the fans off from there. And then of course we have the input
output in there. So I'm going to talk the deck of the last part of this talk is how we got the name
and the executive address in there, which didn't used to be in there before. And I'm going to take
a one-slade detour to show you the kill program, which was in the old shell too, but it's got a
few more features now, and I know what I'm going to do before it. And I got it accepted into the
kernel, into the master branch, and I'm very excited about that. So what I'm going to do is,
I'm going to go over here, and I'm going to start up the second half of that signal passing
bell. This is the program that sits here waiting for somebody to send to the signal and just goes
on the loop going, I'm here, I'm here, I'm waiting, I'm waiting, let's go back here. Now who knows
what the kill command does? Yes sir, kills a process. And put in the dumps cap and go sit by the
principal's office, sir. Sends a signal exactly. Now by default it sends a signal that will probably
kill the process that's receiving the signal. It sends by default a signal. And that may not kill
the process, depending on if it's going wild, it may not kill it. So in that case you might want
to send a signal kill, which of course is signal number nine, which is where we get the expression kill
dash nine, which even little girls who go to Jurassic Park know how to use. So I, the original
version of kill in Gecko has just did a kill, and I changed it so that it could send any arbitrary
process. So let's go over here and look. Oh, yep, still waiting to go. So let's send him a signal,
but first we need to know what his PID is. So we'll take a process listening.
And we'll see that there is Sig received. He's had three Charlie. So I'm going to send
it. I'm going to set a sig break signal to process three Charlie.
Well, let's get over there and watch this happen. I think those consoles wonderful.
And we'll see that, in fact, he did receive a signal one zero, which happens to be sig break.
Great, work as expected. Now I'm going to start him up one more time.
And this time, and he's going to have the same PID. He'll get the same slot over again.
And now I'm going to send him a kill dash nine. Now, as it happens, nine is not the number for
sig kill in Gecko's. In fact, sig kill is not as implemented in Gecko's, but that's okay.
Kill dash nine is tradition, right? So yeah. If you send him a kill dash nine,
well, let's watch and see what happens.
Boom. He's got a fork and he never even prints a message saying I got a signal because he
didn't get a signal. We just got his head chopped off. So that's the new stuff that's in
Gecko's. This PS and kill man. And now comes the kind of heavy duty part of the talk where I
talked about how we got there, how we got those, those new fields. So to understand how the name
and the process, the name and the exact address were added, we have to understand first how the
PS command works in Gecko's. So here's the old one, first of all. This is from the old shell,
and this is an earlier build of Gecko SS 2.09 release that came out in 2013, I think.
What's wrong with this picture? Well, first of all, we don't have any names. Well, you have one
name, but what's at PID zero? I guarantee you it's a net. I guarantee you it's a net, right? It's
not, it's not the challenge in it. So there's something there that could be improved and we don't have
the start address of each process. Like I said, if you want to the start address,
you can't really do meaningful debugging. There are other ways around that, but they're a little
quite big. So let's talk first about how the PS command works. Now, all this information that
PS printed out comes from the kernel's task table, but it's really not appropriate for an end user
program like PS to go stickiness fingers in the task table. That's kind of forbidden fruit,
doesn't work. The kernel shouldn't, you know, you should, you shouldn't be sticking your fingers
in the kernel's data structure, basically. But on a 6502, there's no way to prevent that.
Your program could, by adding a right include files, figure out fairly easy where the task
table is, but you shouldn't do it. You can't prevent it, but you shouldn't do it. So what happens
is that there's a kernel API called GetInfo, and that's what PS calls. PS calls into the kernel,
and he calls GetInfo, and GetInfo says, okay, I'm going to look at my little task table here. He
grabs information and he builds a table someplace for PS to read. Well, that's part of the story.
The place he builds that table is called the program communication buffer or PC buff for short.
Remember what I said about semaphores? You could have other processes that are, that are making
kernel calls that use that PC buff at the same time. That would be a bad thing, right? So what
really happens is the first thing PS does, he locks the semaphore that refers to the PC buff.
Then he calls into the kernel, he calls GetInfo, the kernel looks in his task table,
builds a table in the PC buff, PS reads it, and prints the results for screen. So that's the way it
works. Now, how do we get the name and the start address from the task table into the PC buff?
Well, I looked at this, and I thought to myself, I bet I can call it that. You know what? I like to do
this, but I'm still pretty leery of the Gekos kernel, because it's quite complex. It's really
quite complex, and so I thought to myself, maybe I could add this stuff by just changing GetInfo
and the way it gets in forward, and not actually touching the rest of the kernel itself.
And that would make it easier, right? So if you've ever done any amount of program,
you know that that kind of thinking invariably ends up with something that's 10 times as complicated
as what you originally wanted to do. But that's what I did. So I thought to myself, okay, I've got
two classes of programs I want to get the name for. One is the standard library programs that are
started by the shell, and the one is those five programs that we saw started by the kernel
when it started up, the voice drivers, the shells, and the end. So for the standard library programs
I did little digging, and I found that in the task table, one of the entries is a pointer to another
table. It's a per-processed table that's used by the standard library, and it contains them on
other things the name of the program. So I'm like, God, wow, that was easy. I'm all free.
All you got to do is when you call Gekos, he follows that link to the standard library's table,
he pulls up the name, plops it in the new field, and the task table, and we're all good, right?
Well, not really, because just like user programs shouldn't be sticking their fingers in the
kernel's data structure, the kernel shouldn't be sticking to his fingers in the standard library's
data structure either. And that's one of the things about Gekos. It's written properly. Everything
is done right. You know, you could clutch your way around this like I was trying to do, but it's
not the right way to do it. The kernel, I mean there's a reason we call it the kernel, right? The
kernel means like the core, the seed of something, and it should be an entity unto itself and not
even care or even know about the standard library. It shouldn't even have to know there is a standard
library. So that's not a good idea. It works, but it's not the right way to do it. All right,
shot down on that one. Then we have, where we really went off the rails, we have in it,
and the device drivers and the stuff that gets started at boot time. Well, I had a look at how
the operating system starts. And the way it starts is that you have this big kernel image in
memory. And at the beginning, there's a header followed by one of these programs. Then there's
another header somewhere else followed by a program and another header somewhere else. And
they're in any arbitrary order. You can't control it order, they're in the end. But each one of
those headers points to the next one. It's a linked list, right? So I thought, well,
looking at those headers, I see that just what the name is in the header, FSDab, FSIEC,
and whatever. So I thought, well, if I walk through those tables, I can just grab the name out of
there and I'll be good, right? It doesn't work. It doesn't work. And the reason it doesn't work
is that the kernel has a, well, it works, but the kernel has a fairly complicated way of going
through things. The question is, how do you get the right one of these programs with the right
process ID? And the only way I could think of to do it was to walk through those tables in the same
order that the kernel does when it starts up. Now, one of the things in the header is a program type
byte, which is a bitmap, bitmap. And what the kernel does is it walks through there and it starts
certain programs in a certain order. I want to look, I want to start for a program that's of type
in it. I want to start a program that's of type file system, right? And it makes multiple
passes going through all these programs. So what you'd have to do is you'd have to go through
there the exact same order that the kernel start up does and make multiple passes, but if you do
it exactly the right order, the names you come up with will match up one to one with the process
ID. Oh, boy. Okay. At this point, I really off the rails because this is just not something
you should do. Andre looked at that code and he said, I can't look at that for quite some time
to figure out what you're even trying to do. So yeah, that works, but it's a filthy clutch.
Apart from which, if the way the kernel starts changes even slightly, that whole thing's
going to fall down on the space. So, okay, both types of programs that I was looking for the names
where I came up with solutions that actually worked or seemed to work, but it was just a completely
wrong way to go about it. And as it turns out, going about at the right way by making subtle changes
to the kernel, turns out to be much easier. And these are the patches that Andre did. And this is
what's in GeckoS right now. So, as it turns out, of course, every single process that starts on
GeckoS has to go through the kernel for API. Fork is what starts a new process. It allocates another
entry in the task table. It creates a stack. It does all this other kind of housekeeping and then
it passes control to the new process. And guess what? What are the parameters you passed a fork
among other things? A name and an executive rest. So, it's already there. The kernels already got it.
So, all the kernels got to do is plug that value into the new fields in the task table.
When it starts a program, right? Easy. It should be easy, right? No. And the reason that's not easy
is because standard library programs pull a little trick. They put a stream number in the first
bite of the file name field and the file name actually starts in the second place. So, if you let
that go, every standard library program would have an unpredictable character at the beginning of
the file name. But as it turns out, there's a very easy, and by the way, more on that
stream number, it's passing that way later. But as it turns out, there's a very easy fix to that
because the standard library was not using all the possible parameters that the fork routine takes
when you call it. And you could use one of those parameters to pass that stream number. So,
that works out okay. That was just all fairly straightforward. I looked at the code when it was
committed, and I was like, oh, why did I think of that? And then adding the ones for the kernel
programs, that's simple because they're already there, and they're already perfect. The only
exception being that in it originally actually went out of its way to put a null wipe in the
name field. But there's no reason to mention pipes in the world. Now, adding the exact address,
we've got the name thing solved. Adding the exact address, let's see. The exact address is also
passed to fork. So again, you could just plop it right in and it would work. All for the program
started by the kernel, that's true. But again, we have an issue with the standard library. Now,
this one's really crazy. Yes, the reason it doesn't, the reason it's not quite going to work with
the standard library is that the way the standard library starts a program is that it does the
little housekeeping stuff. It calls for it to create a new process. And then after that call,
it lobes the program from disk and path and relocates it and passes control to it.
What's wrong with that picture? How can it load and run the program if it's already called fork,
which starts the process? It hasn't even been loaded from disk yet. But here's how that's done.
Here's the code that in the standard library, which is set everything up and called fork. And as
a started address, he passes the code a little bit further out in the standard library, which does
the loading and the relocation. So he calls for fork sets up a new process and everything and then
passes control to it with the address given, but the address given is within the standard library,
which is the routine that does the loading and the relocating. But as far as the kernel is concerned,
the new process is already running except that it isn't because it's the standard library. But once
he loads the program, relocates it, now he knows the started address, he passes control to it,
boom, here we go. Oh, what this is great. How wonderful he went, he was some code, right at that point
when he's done loading and he's about to pass control because now he knows the started address.
Fine, plug it right into the pass table. No, the standard library mustn't stick his fingers into
the kernel's task table, right? Again, we have that problem. So the solution to that one turn out
to be that Andre added a new API to the kernel called setinfo. Now we have to get info and we have setinfo
and setinfo allows the active task to set its own started address in the task table.
And remember, the active process at that point was really not the process that's going to start.
It's still the standard library which is loading because it's called fork with its own address and fork
thinks the new process is starting and it gets this far, it knows the address, it plugs it in and then
it jumps to the program so it all works out anyways. I don't know if I explained that well or not but
this is pretty crazy stuff but this is the kind of stuff that you experience when you're when you're
dealing with something on the operating system. And even something like EchoS that runs on a fairly
small machine, there's a lot of complexity there but it was a lot of fun and there's the solution
we have a setinfo. So this is great stuff. This is wonderful stuff. And now that we have this PS
and kill, we can do almost anything because we can debug our programs beautifully. In fact,
it's a new goal to me into EchoS I think to call it because now all the things that have been on
a list can be moved forward. First of all, I think there's a little of anything that's still in
the old shell that's not in the new shell so it could probably be deprecated pretty soon. You just
have the new shell. You might still want to have two of them running, right? But you wouldn't have
to have that old shell with the machine language modern ability which by the way you can load from
disk even now. Another thing, what are some things we could do with EchoS? We could have better
support for CMD hard drive. So remember that long listing I showed you with the file timestamp
and everything? Well, CMD hard drive has a timestamp but get West doesn't know where to find it so
that would be interesting. The one that interests me most is imagine how many people are familiar with
the 50-41 ultimate? Two plus a lot of hands go on. Okay. That machine, as you know, has an ethernet port
and what might be a little less well known is that there is an API that you can call you,
you can push some registers and stuff and you can actually open a socket and talk to another
machine and you can write your own networking programs. Imagine a vice driver for the 50-41
ultimate networking capabilities within the EchoS. I don't know if I have the chops to do that
but I like to try. Another thing you may have noticed that the disk access is not particularly fast
in the EchoS. It doesn't of course have GIF you do have less but maybe there's a way to speed
that up and there are some other things involved to involve in buffering and those are known
issues that might get worked out later on. It's a big deal. And of course your project here,
what I found when I gave a talk on the EchoS in Chicago was that all these people can have
coming up to my table and say, oh wow, I could do that. You don't like the guy who said he wanted
around writing a battleship program. Imagine all the different stuff you could do.
So if you're interested in working with EchoS and writing your own programs for it,
if you know 65 or something, 65 or two assembly, it's not hard at all. If you look at those
demo programs I showed, all of the stuff that actually was happening in those like the forking
and the signal sending and the cell four locking and all that stuff, it's all just a few lines of
code and most of those programs are like waiting on a timer loop, printing stuff to the screen,
error hand learning all it's like 90% fluff and just a few lines of code. So it's really
easier write programs for GIF if you're interested. Have a look at it.
Here's the resources slide and I'm going to post these slides on my website right after you
back to my table. But the bottom one is interesting and that is the commentary that I wrote on the
internals of GIF which is not finished and will never be finished because there's so much to learn.
But this the name of course is a play on words from Professor Lyon's commentary on women's
right. So I wrote this commentary and it's a very detailed description of the internals of
GIF. Tell us about what happens when the operating system is started. It talks yeah I'll post this
on my site. It starts it talks about what happens when the operating system is started, how the
scheduler works, how programs get loaded by the shell and all those different stuff in
men's detail of file names are nine authors. So if you're interested in learning the internals
of GIFs, have a look at my commentary and that'll help you get a leg up and learn where wrongs
and probably go further back. Okay having said all that we come to a slide that says questions.
Does anybody have any questions about GIFs? Yes. Would it be even hypothetically possible to get
something like CC6502 building GIFs like relocatable images? Are you like the sea compiler?
You're talking about doing it in the sea. Yeah. The question was is it possible to write
programs in sea for GIFs using CC65? I guess all I can say is good luck with that.
It would require it would require CC65 to know how to generate an executable in that relocatable
format. That would be the main time. I guess it would. I don't know. The answer I gave
to Chicago. I got the same question to Chicago and the answer I gave is well real men quote me
somewhere. But yeah it's theoretically possible. Anybody else have a question?
What's the role of that? I see 128 portability there. Yeah that's another question that came up
and somebody asked about Atari and that and all this other stuff. Theoretically you could write
it for almost any 6502 program and if you look at the source code there's a directly called
ARCH. So there's ARCH C64 and ARCH PET and ARCH 8296 or whatever. There's also an ARCH
proto-sub directory that has basically like a clean slate version of what you would need to do
to port to a new architecture. But I don't want you to have any false hopes about that because
it would not be straightforward. It's certainly doable. But I have by the way complete
printout of the Ganko S source code back up my table heavily highlighted and penciled in with
markings and stuff like that. And if you have a look at that you'll see that it's just littered
with a lot of defines and if deaths and so on and so forth. So it's already fairly complicated
adding additional architectures while certainly possible. It would not be a small undertaking.
But yeah it's certainly possible. You could write a version for the 128 or whatever
machine is author. Anybody else? All right. In that case thank you very much for your kind of
tension ladies and gentlemen. I hope you enjoyed Glenn's presentation as much as I did.
Please tune in next week to hear Dr. Richard Emmer's presentation entitled Life After Commodore.
Until then, please drive safe and make sure to have fun.
You've been listening to Hecker Public Radio at Hecker Public Radio dot org.
We are a community podcast network that releases shows every weekday, Monday through Friday.
Today's show, like all our shows, was contributed by an HBR listener like yourself.
If you ever thought of recording a podcast then click on our contributing to find out
how easy it really is. Hecker Public Radio was founded by the digital dog pound and the
infonomican computer club and is part of the binary revolution at binwreff.com.
If you have comments on today's show, please email the host directly, leave a comment on the website
or record a follow-up episode yourself. Unless otherwise stated, today's show is released on
creative comments, attribution, share a light, 3.0 license.
