What’s that, you will ask? Well, that was TEH BUG which made all buffered dos operations (the ones done through FGetC, FGetS, FPutC, FPutS, Printf and many more) unusable on x86_64 target. What does this line? Well, it should set the highest bit to one and clear all other ones. This tiny line of code works perfectly… Better than enyone expected in the old times, where C’s long was 32-bit…
The struct FileHandle of dos.library contains a tiny buffer used to speed up file operations. The buffer could be therefore in both READ and WRITE modes. In order to set it into write mode, the FHF_WRITE on the filehandle’s flags has to be set. The fh_Flags field is of type ULONG – it is a 32-bit unsigned number.
The FHF_WRITE was defined as ~0UL/2+1. Fine. On x86, where the type long is 32-bit, the FHF_WRITE equalled 0x80000000. On x86_64 however the type long is 64-bit wide. The FHF_WRITE flags was therefore 0x8000000000000000. And this value does not fit into ULONG variable……
I have redefined the FHF_WRITE variable a bit and suddenly the buffered operations do work, as you may see on the screenshot (yes, the whole shell uses buffered operations :-))). Finally, after one month of useless fight I continue on the x86_64 port. Sweeet.
A lot of things and commits have happened since my last blog entry. There was so much to do, that I have forgotten (and actually didn’t have had any time to) to blog here 🙂
There are already filesystems in the AROS64 which may be used to boot the system – the cdvdfs is a good example. As practically everything – it has had some issues visible on 64-bit architectures only, but everything is fixable, of course 🙂 The standard keyboard and PS/2 are supported together with vesa and vga video drivers.
I have added one long awaited “feature” to the AROS64 – partial MMU support. The kernel is partially protected (the .text and .rodata sections) against accidental writes caused by buggy applications. Moreover, the address range 0 – 0x0fff is excluded completely in both user and supervisor modes. Every write and almost every read to/from address in this range will cause immediate page fault. *Almost*? Yes, the page fault handler looks at the instruction which caused the fault. If it is a 64-bit read from address 4UL into any of the registers, then the SysBase value is saved into the requested register and the faulty instruction is omitted. It is a very simplistic emulation of legacy SysBase. Nevertheless, one should use this feature with care – it’s significantly slower.
What will be next? The Zune/Wanderer fixes in order to make this pair completely usable. Then the rest of the standard AROS tree – most programs have not yet been checked in AROS64. Fixing it all will take some time, of course, but it will not take long. Apart from this fixes, I will try to move as much architecture dependences into kernel.resource as possible. Once this target is achieved, it will be possible to replace the kernel and it’s userland interface – the kernel.resource, with something completely different… 🙂
Stay tuned for more news from the new virgin 64-bit AROS-land 🙂
It has been a very very long time since I wrote anything last time. I Hope you still visit this site 🙂
Since I was very busy with my work at Uni, I have abandoned idea of writing new kernel by myself, only. Sure it would be nice to do something like that alone, but I’m afraid I would end up with a half-ready kernel, a patchwork which would be big enough to let exec.library work. Nothing less, nothing more.
The plans have changed. I will make a quicker amd64 port – a slightly modified x86 version for amd64 cpu. The old concept reborn. The huge disadvantage is (yes, you will be disappointed now) that the new kernel will offer almost nothing more than the x86 one. That means – all applications will still run in one huge address space common to all processes. It’s still the fastest possible approach on x86_64 architecture – some 2 MiB pages covering the very first 4 GiB address space – all of them in translation look-aside buffer (TLB) of the CPU. The SysBase pointer is still at absolute address 4, but it’s use is deprecated. One should access the CPU-local SysBase variable at address %GS:8.
What are the advantages, will you ask? Well, have a look at the screenshot. The core libraries are already there. The scheduler should work, at least in theory :). Many libraries and modules may be already compiled thanks to the enormous effort of Henning Kiel, who fights with badly written sources and let them compile. Once irq.hidd and timer.device are done, I should have AROS working on amd64. Neato, huh? Apart from that, I have avoided assembler code as much as possible. Even interrupt and exception handlers are pure C called by very small context-saving asm stub.
As soon as the x86_64 port of AROS will be ready (and bounty will be satisfied), I will start project aiming at creation of new kernel for our OS. I promise.
Stay tuned. Some interesting news are coming….
I have wasted my whole weekend on hunting for a not existing bug. A x86-64 kernel was not going to boot, hanging somewhere around the initialization of few classes. After a long and stressful investigation I have found out, that the code compiled with -mcmodel=medium flag was totally wrong (I have to use this memory model, since the kernel is located at address 0x0f8000000000). The gcc documentation said:
Generate code for the medium model: The program is linked in the
lower 2 GB of the address space but symbols can be located
anywhere in the address space.
According to this information, my code has to work! But it didn’t. And then, suddenly, after considering two other possibilities (kernel placed either in lowest 2GB or the highest 2GB of address space) I have found the solution:
When `-mcmodel=medium’ is specified, the data greater than
THRESHOLD are placed in large data section. This value must be the
same across all object linked into the binary and defaults to
Adding the “-mmlarge-data-threshold=1″ solved all my issues caused by change from gcc 4.0 to 4.1… Oh well… 😉