I ran out of steam writing library routines and imported two
BSD-licensed libc routines: sscanf() and getopt().
I will most likely rewrite them sooner or later. For now
I just wanted to see figlet running.
We now make three VirtualConsoles at boot: tty0, tty1, and tty2.
We launch an instance of /bin/sh in each one.
You switch between them with Alt+1/2/3
How very very cool :^)
- sys$readlink + readlink()
- Add a /proc/PID/exe symlink to the process's executable.
- Print symlink contents in ls output.
- Some work on plumbing options into VFS::open().
This is pretty inefficient for ext2fs. We walk the entire block group
containing the inode, searching through every directory for an entry
referencing this inode.
It might be a good idea to cache this information somehow. I'm not sure
how often we'll be searching for it.
Obviously there are multiple caching layers missing in the file system.
This took me a couple hours. :^)
The ELF loading code now allocates a single region for the entire
file and creates virtual memory mappings for the sections as needed.
Very nice!
I also added a generator cache to FileHandle. This way, multiple
reads to a generated file (i.e in a synthfs) can transparently
handle multiple calls to read() without the contents changing
between calls.
The cache is discarded at EOF (or when the FileHandle is destroyed.)
FileHandle gets a hasDataAvailableForRead() getter.
If this returns true in sys$read(), the task will block(BlockedRead) + yield.
The fd blocked on is stored in Task::m_fdBlockedOnRead.
The scheduler then looks at the state of that fd during the unblock phase.
This makes "sh" restful. :^)
There's still some problem with the kernel not surviving the colonel task
getting scheduled. I need to figure that out and fix it.
It's implemented as a separate process. How cute is that.
Tasks now have a current working directory. Spawned tasks inherit their
parent task's working directory.
Currently everyone just uses "/" as there's no way to chdir().
I added a dead-simple malloc that only allows allocations < 4096 bytes.
It just forwards the request to mmap() every time.
I also added simplified versions of opendir() and readdir().
- Turn Keyboard into a CharacterDevice (85,1) at /dev/keyboard.
- Implement MM::unmapRegionsForTask() and MM::unmapRegion()
- Save SS correctly on interrupt.
- Add a simple Spawn syscall for launching another process.
- Move a bunch of IO syscall debug output behind DEBUG_IO.
- Have ASSERT do a "cli" immediately when failing.
This makes the output look proper every time.
- Implement a bunch of syscalls in LibC.
- Add a simple shell ("sh"). All it can do now is read a line
of text from /dev/keyboard and then try launching the specified
executable by calling spawn().
There are definitely bugs in here, but we're moving on forward.
- More work on funneling console output through Console.
- init() now breaks off into a separate task ASAP.
- ..this leaves the "colonel" task as a simple hlt idle loop.
- Mask all IRQs on startup (except IRQ2 for slave passthru)
- Fix underallocation bug in Task::allocateRegion().
- Remember how many times each Task has been scheduled.
The panel and scheduling banner are disabled until I get things
working nicely in the (brave) new Console world.