|< << 3 of 3 >> >|


The reason for not booting was simple - Clang, seeing that target is Pentium 4 and above, optimized some memmoves into SSE operations. Bochs didn't expect that.

Now everything boots up until exceptions, at which point I believe the __builtin_longjmp primitive fails. Debugging it.

Clanged now

Anyway, I've done doing the craziest port of recent times - at the same time GCC to Clang and from waf 1.5 to 1.6.

Quite a bit of quirks to work around.

waf has changed a lot internally, and from occasional backtraces I still see that I'm using compatibility mode somewhere. Oh well, one day when I'm bored…

Clang is also full of quirks. First, I had to build a cross-gcc for it anyway, because otherwise it totally refuses to link or assemble anything. Second, the freestanding standard C headers are not quite finished it seems - stdint.h for example spits out about 20-30 warnings about redefined macros, so I had to disable -Werror for now just to get it to compile. Third, the generated code, obviously, doesn't run. I got only first couple functions of kickstart bootloader to work in bochs, after that it just GPFs. Now if it keeps raining tomorrow like today, I'll certainly will go and look what happens there, otherwise it might have to wait until next weekend (actually, in two weeks).

Magic Ink

Magic Ink

Highly recommend this read to all programmers and designers. Very inspirational.

It intersects with Metta's ideas of supporting creativity freedom, and is written a lot better than I could ever dream to write myself.

Font rasterization theory and techniques

Font rasterization theory and techniques

Metta MMU module init

MMU initialisation

First off, we start by loading the needed modules - mmu_mod, frames_mod and heap_mod.

mmu_mod will allocate and map the first chunk of memory to use. It does so without knowing much about memory allocation - just takes a first fit chunk from the physical memory map, passed to us by the bootloader. Parts of this memory will be used by frames_mod and heap_mod as well, so we need a way to know how much memory they would need.

Read more →

A historical moment

OMAP3 beagleboard.org # mmcinit
OMAP3 beagleboard.org # fatload mmc 0 0x82000000 kernel.bin
reading kernel.bin
640 bytes read
OMAP3 beagleboard.org # go 0x8200024c
## Starting application at 0x8200024C ...
hello, world!
## Application terminated, rc = 0x0

Metta progress report one

I have cleaned up the booting mess more or less and now my loader is able to enter the root domain - the startup component, which initialises all other components in order and passes control on to userspace loader component, which is supposed to finish system initialisation by starting up all user interface services.

Now there are pretty many loaders here already - there's a first stage loader which is either GRUB or some other kind of boot loader, next there is second stage loader which understands boot protocol, be it multiboot or Linux-style boot or something else and converts all information to format understood by kernel startup, which in turn parses the info from bootinfo page and sets necessary flags, configures necessary platform hardware, prepares memory structures like IDT and GDT and then launches the root domain, which in turn loads all startup modules, initialises them and passes control on to userspace startup component. This is 5 startup stages in all.

Now the design decision in modular system with C++ implementation is separation of component architecture and OO implementation. In component system, nothing is known about component implementation outside of the component and C++ implementation details break at component interface boundary - we want to confine implementation details inside component and expose only a C++ representation of public interface.

Therefore, C++ implementation breaks down to 3 essential parts: C++ implementation, in whatever level of detail we want, from very simple to complex elaborate designs, this is invisible to client code. Second is a thin C-style component interface layer. It is so thin, that I do not want to mess with it manually and it is generated by the IDL stub compiler, meddler. It is also able to generate the third piece - C++ wrapper around C interface that can be used in appropriate way by C++ clients.

Since meddler is still in the works, I generated some C interfaces manually for testing and now implement the memory management components behind those interfaces. Seems to be fairly interesting, since in pre-component design the C++ interfaces were directly exposed to client code and it was fairly easy to change public interface by simply declaring new methods public or private. It was also fairly easy to screw things up, because C++ exposes way too much to clients by default. This is different in component world, you have to be careful with how much of API you expose to clients - what is exposed once remains with this version of interface and has to be supported. Thankfully, I have versioned interfaces and this liability is not forever. On the bright side, only what you exposed will be seen - this makes client interface much thinner and cleaner.

Now on to MMU, frame allocator and stretch allocator implementations.

To remain the web weavers

To remain the web’s weavers and not its ensnared victims, we must merge with our electronic exocortex, wiring greater memory, thought processing and communication abilities directly into our brains.

James Hughen

|< << 3 of 3 >> >|