I’ve now updated the documentation and uploaded the latest version which includes all the changes mentioned here to date. Let me know if you spot any problems or bad links.
Latest Version Uploaded
June 14th, 2009First Real Program!
June 13th, 2009I’ve now implemented the first useful program – a very simple version of “ls”. It’s not much, but it’s a start!
Interesting how many bugs come to light when doing something like this. A particularly nasty one was the situation when a memory allocation was called for with a requested size of zero (of course this should never happen, so a few more checks are needed). The result was that the first memory entry in the list was used (even though it was already allocated elsewhere) and susequently deallocated, with unpredictable results. That was quite a tough one to track down as it didn’t show up immediately. As always, without SimNow I don’t know how I’d ever have found it.
When I have the energy I’ll try to document this latest version and upload it to the web site as I think it represents a significant step.
Semaphores
May 31st, 2009Whilst modifying the memory allocation routines to include the Pid of the task that owns the memory it occurred to me that I had made the most elementary oversight by not accounting for the possibility of multiple tasks trying to allocate memory at the same time. In the wrong circumstances this could cause havoc by completely wrecking the linked lists of memory allocation. The answer is trivial – I have now implemented a system of semaphors so that only one task can access the memory allocation/deallocation routines at a time.
This is almost trivial on the x86_64 processors by using the CMPXCHG instruction. This tests and, if required, sets a memory location as an atomic instruction; in other words, it is guaranteed that the instruction will complete without being interrupted. If the semaphore can’t be set (i.e. if another task has already set it) a task switch is done and the operation will be retried next time the task runs.
At the start of the memory allocation/deallocation routines a semaphore is now set, and it is cleared at the end of these routines. This should guard against the possibility of some particulary obscure bugs at a future time.
Resource Allocation/Deallocation
May 28th, 2009The more I work on the system the more obvious it is that I’m going to have to be a little more clever when allocating and, particularly, deallocating memory. I’m most concerned with deallocating memory when a task ends. User heap memory is no problem, as it is part of a memory map that gets discarded and (I think) kernel heap allocation doesn’t occur in user tasks. However there is still shared memory to worry about. Currently it’s up to the task to make sure that it deallocates everything – but that’s really not good enough; it should happen automatically.
I’m thinking at the moment of adding an additional field to each allocated block of memory to record the task of the PID that it belongs to. A separate task could then clean up resources once a task ends (and perhaps periodically sweep the system looking for zombie resources). It doesn’t sound too difficut to implement.
Actually, I’m not totally convinced that the use of shared memory is a good thing (except where absolutely necessary) - there are obvious security implications. It’s needed to pass information between tasks (other than the limited amount of data that can be passed directly in a message), but there must be an alternative way of doing this. I must look carefully at where shared memory is used and whether it is necessary.
There’s also the separate problem of keeping track of which task an FCB belongs to so that the filesystem can deallocate it when it is no longer needed.
SimNow and Fedora 11
May 23rd, 2009I bought a new laptop the other day and installed Fedora 11 on it, only to discover that SimNow didn’t work. I’ve now installed Fedora 10, and things work fine. I don’t know whether it’s a problem with the latest kernels or libraries, but it’s worth bearing in mind. I’m guessing this problem may affect the cutting-edge versions of other distributions.
File System Nearly Finished
May 15th, 2009Work on this is now pretty much complete for the time being. It turned out to be much easier than I anticipated. Write access now works; directory structure and time stamps don’t. I’m not too bothered about a directory structure right now, as the root directory can hold 512 entries – in any case I don’t intend FAT to be the long-term file system, so I don’t want to do more than the necessary minimum of work on it. Time stamping would be of little use until some form of time-of-day clock is implemented (shouldn’t be too difficult). I’ll now work on documenting and publishing this latest version.
What next? Current work has shown up a problem when running under QEMU; sometimes it needs two or three attempts before the system runs. These problems don’t occur under SimNow, so I’m guessing it’s a question of uninitialized variables. Other than that, I think that I’ll look at implementing a few simple commands – cat, ls, cp, that sort of thing. Another thing that I think I may look at is changing the memory map to give more available memory to the various parts of the system.
Disk Journalling
May 13th, 2009Work on adding write ability to the filesystem is progressing nicely, but I was momentarily disconcerted by a little detail of SimNow. By default, all disk writes are journalled; this means that, unless you disable this feature or manually commit changes, changes won’t be saved to the disk image. I wondered why my disk writing routines seemed to be working when looked at under the debugger but weren’t saving anything permanently to the disk! Have a look at the manual to find details of this feature (which I can see is actually very useful when you are experimenting).
By the way, there’s a new version of SimNow out that allows you to add and delete devices from the virtual machine that you are using. It also seems slightly faster to me, but that could well be a combination of my imagination and changes that I have made to IanOS.
Timers
May 11th, 2009Whilst working on the filesystem code I realized that the timer code definitely need improving. As presented the system only has a single timer; this obviously causes problems if more than one task calls sys_Sleep(). I hadn’t really thought about how to implement multiple timers, but it suddenly occurred to me (whilst I was out walking the dog on the South Downs) that it was really simple. By adding another field to the task structure to hold a timer count, the job is practically done! During the timer interrupt it’s just a question of checking which tasks are waiting on a timer, decrementing the timer field in the task structure and, if it’s reached zero, unblocking the task. Really simple! Things sometimes work that way.
Now, back to the filesystem.
File System
May 11th, 2009Time to enhance the file system, I think. Currently it can only read from the disk, and doesn’t know about subdirectories. First step will be to add write access. The IDE part of this should be fairly straightforward, but the FAT part is possibly a little more complicated. We need to be able to create directory entries and manage the FAT itself.
This is going to mean accessing the FAT itself quite a bit, so it’s going to be necessary to buffer it; memory accesses are obviously preferable to a lot of disk accesses. One possibility is just to keep the whole FAT in memory as an array; this does seem a little wasteful on memory, and makes it more difficult to ascertain which sectors of the FAT need to be rewritten to disk when changes are made (easy if the FAT is rewritten for each change, but more difficult is we want to do these updates in batches). Another possibility is to have an array of pointers to structures containing each sector of the FAT and information about whether the sector has changed since it was read from disk. This would be much more efficient memory-wise, as it would only be necessary to create structures for FAT sectors that have been read, but complicates access to the FAT slightly. I’m not quite sure which is more important – memory space or efficient access. But I do prefer the ellegance of the sparse-memory approach (the second possibility). Also, it’s a little more complicated to program – but as the whole point of this exercise is to have fun, that’s an advantage not a disadvantage!
Latest Version
April 29th, 2009I’ve now uploaded, and documented, the current version. Let me know if there are any problems with the code or the site.