That's it for summer I guess.
Daylight savings just finished here - and it's already throwing me out. After plugging away at the computer all afternoon I thought it must've been 10 or something as it seemed to have been dark for so long, but it was only 7:30 ... Good time to call it a day I guess.
Yesterday I got a whole lot of work out of the way on the retaining wall, I should've done more today but I was too lazy. The weather was too nice too - although then I just spent most of the day inside instead of taking advantage of it. Once I sit down to hack it's pretty well game over ... Probably should've made the effort though - looks like weather is turning wet soon, and I need to get some of the stuff done whilst it's still try. Maybe an hour or two over the next two days might do it.
Well that's Easter done, back to work tomorrow.
Was up pretty late hacking away on some WoofƆs stuff, and then continued it for most of today. For the most part it's just re-arranging stuff I already have from puppybits, or my previous x86 hacking. Pretty time consuming though, trying to tie it all together. It also needed quite a bit of re-thinking and re-jigging along the way.
I've got it all building, and it currently launches two tasks, one which immediately goes to sleep waiting for work to do, and the idle task which blinks the led. But that isn't really any more than I already have in puppybits, so I need to start testing the other stuff - per-process virtual memory, message passing, and so on. These things are a bit hard to play with in isolation since so much support is needed first. Hmm, I really need to get timers and timer interrupts working too, but I can test that in isolation.
The architecture which i've thought about so far does seem to be holding together at least - no big surprises have come along ... yet. Although that assumes the stuff i've written actually works too. So far I have a 'memserver' which is tightly bound to the kernel - it is basically a kernel thread since it accesses the kernel memory directly. It is used to create all in-kernel objects - directly adding them to the kernel in some cases, or where necessary through lightweight system calls to register the new resource. This lets me avoid any dynamic memory in the kernel itself, and by using the right data structures or the occasional lightweight system call I don't have to worry about serialisation either (well, once i've got it right).
I had been thinking about all sort of exotic data structures like trees or hash tables to locate resources based on an object id - but these all have various issues. Execution time, serialisation, and so on (I have implementations that use no dynamic memory, so that wasn't an issue). So in the end I settled for a simple array for many of the objects - it probably uses less memory anyway, and certainly needs less code. It also allows me to update and access it atomically from multiple threads of execution without trouble.
The whole 'kernel' is only 10 system calls so far - and although I still need a few more for interrupts, it shouldn't be many ... I think. Of course most of the work is in the servers, and the kernel is just passing data around. Even in those 10 I already have some 'helper' syscalls too - they aren't strictly necessary but combine a couple of system calls into one, there is probably scope for some more of those.
I had a little chicken and egg problem with message allocating - you need to send a message to the memory server to allocate new messages before they can be sent via the kernel. I think I have worked out a solution - part of the process start-up will be to send a system message to the new process. This message can then be used to ask for more, or just as a general purpose message container. Still, I might need some other more direct mechanism since message ownership passes every time they are forwarded, and it is possible for them to get `lost'.
I might have to look into a mailbox mechanism I guess, although I don't want to have too many options for IPC. After I'd written the basic message allocation system I thought it would be a bit bulky to do too often - well the point is not to in the first place, but it seemed a bit heavy. I looked into a simpler mechanism of message passing using limited registered arguments. But it just didn't seem that useful - because you can only pass primitive non-pointer types. As soon as you want to pass buffers around the mechanism falls down, and you need even more complex support code (like 'far' copies), which then needs to perform extra security checks, and so on. One `freebie' of the message passing mechanism as i've envisioned it so far is it sort of self-checks. Nothing the kernel deals with needs checking in detail because any addresses are from trusted sources or have already been verified, or just integer representations of virtual addresses it never looks at. And servers can perform fairly cheap checking since all data must fit in a fixed bound.
Might sit on all that for a while now.