I'm also making a lot of behind-the-scenes changes (the terminal emulator is one of the smaller changes, in fact):
- For one, the flash device driver is nearly complete. I haven't tested it yet, but it should be able to read blocks from and write blocks to FlashROM, buffering the block data as needed and caching block numbers for faster lookup. This leads me to another point: I redesigned the filesystem and flash device layout...again. I decided to keep the separation of the FlashROM and the filesystem, if only for simplifying the filesystem code. The flash device driver is responsible for translating logical block numbers—which the filesystem sees—to the actual locations in FlashROM. It will store the 32-bit block number immediately preceding the 128-byte block data itself, but I reserve the right to change this so that the block number table is separate from the block data.
The block number will have one of the following values:
Value Meaning 0xFFFFFFFF Block is free, and all blocks following in this sector are also free 0x00000000 Block is dirty n Block is used, and the block number is n
The filesystem, as in previous designs, will use the upper 16 bits of the block number as the inode number and the lower 16 bits as the block number within the file. This gives the filesystem up to 65,534 inode numbers and 65,536 file block numbers (the filesystem uses file block number 0 as the inode header). Given that the FlashROM is only 2MB, each block is 128 bytes, and each inode header is 32 bytes, there can be at most 13,107 non-empty files in this filesystem. I still need to work on the filesystem at the moment.
- I've updated the process scheduler to better allocate processor time depending on recent CPU usage of each process. Hopefully this will result in a responsive system when multiple processes are running simultaneously.
- I've implemented signal handling a little more thoroughly. It's not complete, but it's enough to get the rest of the system working first.
- I've removed a lot of "dead" code, such as code that's from PedroM but commented out. For example, I reimplemented the KeyScan() and AddKey() routines in C and made some Punix-specific changes to them (which were easier to make in C than in 68k assembly), and then I removed the large commented-out version from entry.s. I also reimplemented the BattCheck() routine from PedroM in C and removed it from entry.s. Now Punix can monitor the battery level (this is kind of important on a real calculator!).
- I fixed the link character device driver so it will restart transmitting and receiving when the write queue has data and when the read queue has room for more data, respectively. I had overlooked this detail when I first wrote it. D:
- I added load average calculations. These are made once every 5 seconds to measure how many processes are in the "run" state. The load averages can't be queried yet, so I'll need to add a way for a user process to get that information.
- I wrote a basic memory allocator, finally! This allocator can allocate blocks of memory in multiples of 128 bytes. I chose 128 bytes because it is the block size in Punix, so most memory allocations (e.g., buffers) in the kernel will be 128 bytes. Since this allocator will also be available to userland processes, the plan is for applications to allocate a large block or blocks of memory and then use a finer-grained malloc() routine to allocate memory from this pool of memory. This is the way uCLinux works (generally).
At this time, there are about 12 kilobytes left in the first sector of FlashROM for more code in Punix. This is a good thing because I still need to implement the inode allocator and other little bits of the middle-level filesystem code, as well as the execv*() system calls. These should all take less than 12 kilobytes when they're done.