Wednesday, August 25, 2004

Build 1: Hello World!

I defined my abstract display, but couldn't write the driver because too many details are fuzzy. I need more of the underlying stuff to be figured out first, which brings me to Build 1, Hello World! The idea here is to write a Hello World program in Java, then write all the supporting classes with only required methods implemented. I've already done this, leading to the System, String, PrintStream, FilterOutputStream, and OutputStream classes (in Java) and the following Atlas OS classes: atlas.boot.IA32 (the loader), and in atlas.dev, we have Device, PortRange, and Console. That's about all we need to run Hello World, except the platform dependent crap-- the boot loader, the JVM interpreter, and the PortRange implementation. In order to meet my goal sooner than later, I'm opting for total inefficiency and lack of security. After it actually does something, I'll see about the rest.

Hello World!

Monday, August 23, 2004

...or Defining an Abstract Display Driver

OK, so the ATI miniport driver thing ended when I started reading about windows display driver architecture. Modern video card programming is probably my biggest weak point, which is why I chose to hit that first. Anyway, it turns out that Windoze uses a layered driver approach with GDI, a display driver, a miniport driver, and a port driver. I've been vaguely aware of this, but didn't realize the details until trying to reverse the ATI driver. GDI is responsible for abstracting the details for user applications; it issues commands to the display driver and the miniport driver. The display driver has the job of actually rendering graphics, while the miniport driver handles configuration and mode setting type IO requests. The port driver is provided by Windoze and handles the bus interface (PCI, ISA, AGP, etc.). I'm happy to ignore the bus interface for now, but instead of simply copying Microsoft, I need to define my driver model. They have a pretty good reason for layering it the way they do, but this needs to look a little different within the Java framework.

Java already has a few GDI-esque libraries: Graphics2D being the most obvious. However, it is not derived from the device hierarchy and is not exactly what I'm looking for. So, I think the appropriate approach would be to design an AbstractDisplay class which offers functions like path stroking and filling, bit-blitting, color settings, etc. Then I can extend the abstract class to the equivalent of a MS display driver. Most display cards transfer data by mapping video memory onto system memory in a "linear frame buffer". All rendering operations will be alike for cards that support a LFB, so maybe one extension would be a LFBDisplay. Other cards have hardware accelerators, so maybe an AcceleratedDisplay. Then for specific card families, these devices can be further extended to support the nitty-gritty configuration details. Perhaps my ATI card would be an AtiRageMobiliyDisplay, which extends LFBDisplay, which extends AbstractDisplay. Then packages like Graphics2D can lookup the default AbstractDisplay, and perform all rendering functions to it. This is my idea given what I know so far-- it is likely to change as I go, and I'm learning to accept that.

So in the interest of both simplicity and genericism, I'm dropping the ATI project in favor of first implementing a generic VGA driver, after I define the abstract display class, of course. Mmmm, tasty details.

Friday, August 20, 2004

Reverse Engineering an ATI Miniport Driver

OK, I decided to hold off on the Intel drivers, and instead go straight for the hard part. If I can do this then the Intel stuff will be easy, and I'll be well on my way to getting something started. So I downloaded a miniport driver for my Rage P/M Mobility AGP 2x card. I have disassembled the 70kb file and am wading through all of the defined miniport interfaces to examine how the device works. I'm trying to approximately rewrite the thing in Java as I go, but it's pretty messy-- there are at least 267 functions. It's just complex enough to be a total pain, but barely easy enough for me to attempt it. On the plus side, the driver I got appears to support many ATI display cards, so the end product might actually be useful to someone else.

Thursday, August 19, 2004

Device Scan Successful

I scanned my WinBook which I will use for initial testing, and it gave me the following list:

Intel 440BX/ZX AGPset Host Bridge [82443BX/ZX]
Intel 440BX/ZX AGPset PCI-to-PCI bridge [82443BX/ZX]
ESS Technology Solo-1 PCI AudioDrive family [ES1938/41/46]
Agere Systems LT Winmodem 56K [1456VQH19R-1(INT)]
Intel PIIX4/4E/4M ISA Bridge [82371AB/EB/MB]
Intel PIIX4/4E/4M IDE Controller [82371AB/EB/MB]
Intel PIIX4/4E/4M USB Interface [82371AB/EB/MB]
Intel PIIX4/4E/4M Power Management Controller [82371AB/EB/MB]
O2Micro CardBus Controller [OZ6832/3]
O2Micro CardBus Controller [OZ6832/3]
ATI Technologies Rage P/M Mobility AGP 2x [01541014]

 
I think I'll write the intel drivers first since they hook up to core services.

Here is the source code for reference:

bits 16
org 7C00h

pci_scan
mov ax,cs
mov ds,ax
mov ax,0B800h
mov es,ax
xor di,di

mov dx,0CF8h
mov eax,80000000h
mov ebx,eax
out dx,eax
in eax,dx
cmp eax,ebx
jne .error

.again mov eax,ebx
out dx,eax
add dx,4
in eax,dx
sub dx,4

cmp eax,-1
je .no_dev
call print_dev
.no_dev
test ebx,700h
jnz .next

mov eax,ebx
mov al,0Ch
out dx,eax
add dx,6
in al,dx
sub dx,6
test al,80h
jnz .next

add ebx,800h
.fin cmp ebx,80080000h
je .done

jmp short .again

.next add ebx,100h
jmp short .fin

.done mov si,.dn_msg
mov cx,(.dn_msg_end-.dn_msg) / 2
rep movsw
jmp short .halt

.error mov si,.err_msg
mov cx,(.err_msg_end-.err_msg) / 2
rep movsw
.halt jmp short .halt

.dn_msg db 'D',7,'O',7,'N',7,'E',7
.dn_msg_end
.err_msg db 'N',7,'O',7,' ',7,'P',7,'C',7,'I',7
.err_msg_end

print_dev
mov ecx,eax
mov eax,ebx
bswap eax
mov al,ah
call print_al
mov ax,073Ah
stosw
shr eax,16
push ax
shr al,3
call print_al
mov ax,073Ah
stosw
pop ax
and al,7
call print_al
mov ax,072Dh
stosw
mov eax,ecx
xchg al,ah
call print_al
mov al,ah
call print_al
mov ax,073Ah
stosw
shr eax,16
xchg al,ah
call print_al
mov al,ah
call print_al
add edi,160-18*2
ret

print_al push ax
push ax
shr al,4
add al,90h
daa
adc al,40h
daa
mov ah,7
stosw
pop ax
and al,0Fh
add al,90h
daa
adc al,40h
daa
mov ah,7
stosw
pop ax
ret

times $$+510-$ db 0
dw 0AA55h


First Step: Drivers

My first step will be to write device drivers for my system, and try to organize them hierarchically as I go, providing abstract implementations for many vendor specific devices.

The nitty-gritty: I'm going to write a short assembly language program that I can fit in a floppy boot sector and which will scan the PCI bus and print out a list of all devices found. Then I will look those devices up in a PCI vendor/device database, and try to find existing drivers/documentation that I can use to create my own drivers.

So far, I think that the basic hardware-independant functions that need to be supported for building device drivers is: IRQ mapping, I/O port access, memory-mapped I/O access, and maybe DMA but that might work best as a separate device. In writing my Java device drivers, I will use the following methods that I assume are supported natively:

class Device {
void addInterruptListener(InterruptListener l);
void removeInterruptListener(InterruptListener l);
IORange getPortRange(long base, int len);
IORange getMemoryRange(long base, int len);
}
interface InterruptListener {
void interruptOccurred();
}
class IORange {
int readByte(int offset);
int readShort(int offset);
int readInt(int offset);
void writeByte(int offset, int data);
void writeShort(int offset, int data);
void writeInt(int offset, int data);
}

Strategy: Write it in Java

My strategy for achieving tenet 2 is to do all programming in Java. The underlying machine-level kernel will cache an optimized compilation of each class during installation. This will then allow the code to run at native speed in exchange for a one-time delay during installation in most cases. In order to have mass appeal, a mechanism for validating other executable formats and converting them to Java bytecode will exist. There is a problem when code uses unsafe procedures, like pointer arithmetic, but we can wrap these and through exceptions when they misbehave.

As for low-level machine programming, boot code will be architecture specific, and a certain base level functionality will be provided by a machine specific kernel. I have in mind to implement the java.lang package and an OS specific device driver package natively.

Ideally, all drivers would be written in Java and linked to some sort of Device base class, but there must also be a mechanism for using drivers written for other OS's.

Wednesday, August 18, 2004

Tenet 3: For Dummies

The success of Windows has been largely because of this factor. If I am to gain the general favor of the world population, then it must be usable by dummies. This means: automatic configuration of drivers, intuitive interfaces, and verbose explanations. All features will be fully customizable through wizards or expert interfaces. Also, there will be no obscure config files as in Linux. No system info will be accessible via the file system. All applications will be installed as a package rather than a big collection of files, etc., etc.

Tenet 2: Any Software, Any Hardware

That's right. It follows from tenet 1, that any terminal on the network must be able to run software from any other terminal. In the simplest case, this implies homogeneous hardware and software. More robustly, we could write the OS in a way that allows translation from one platform to another. This appeals to my sense of adventure, and also to the one-world-order that I am attempting. The ideal here is to end up with one OS which renders all others totally obsolete.

Tenet 1: The Network is The Computer

This is straight from Sun Microsystems, and it is good. Future computer users will expect to turn on their machine and command the world's resources. Extending this assumption a bit further than Sun has thus far, we see an OS which does not distinguish unnecessarily between local and remote resources. Users can log into any PC that is connected to the network identically to any other terminal, except for where locality specific features make sense, such as identifying the default printer. Also, this implies load balancing over network nodes, enabling very large scale distributed applications.

Introduction

My wife and I made a pact recently--actually it's more of a competition--in which I have to take over the world and she has to become a fitness instructor. It's a little lopsided maybe, but we set our own goals and we've agreed to them. "Taking over the world" in this case implies developing an operating system that will replace Windows, Linux, MacOS, etc. That's right. Welcome to the next, next level. You may follow the thought process that goes into the development of such an OS if you dare.

This page is powered by Blogger. Isn't yours?