1 Introduction ============== This document lists all the needed tools and compilers to build the lxapi32 OS/2 device driver. It also tries to give some informations about the architecture of the driver and explain some technical details. 2 Required tools ================ - Watcom C/C++ version 11.0c - ALP 4.x (IBM assembler; comes with ddk) - IBM OS/2 DDK (http://service.boulder.ibm.com/ddk/) - Base header/libraries/tools (combase.zip) - MMPM/2 base (mmpmdd.zip) - PDD & MMPM/2 driver reference 3 Recommended tools for debugging ================================= - ICAT debugger (follow link from IBM DDK page) - OS/2 Debug kernel 4 Building the driver ===================== You need some environment variables for build: DDK should point to the DDK directory LXAPI32DEV should point to the directory, where LXAPI32 source files are installed WATCOM should point to the Watcom directories You can build the driver from the main directory by executing: build.cmd This will create the debug version of the driver. Parameters to build.cmd: clean Clean up all directories release Make release version (without debug) debug Make debug version (default) all Rebuild all files 5 LXAPI32 driver architecture ============================= LXAPI32 contains a lot of Linux function calls. At initialization time a driver should attach to LXAPI32 and get all function entry points via IDC calls. After this, all functions can be called directly. The SKELETON directory contains a simple skeleton driver that shows you how to attach to LXAPI32 and get the function entry points. There are some differences between linux and LXAPI32: timer ------- LXAPI32 registers a timer handler at init time. While processing a timer interrupt LXAPI32 calls every timer. Also schedules() are solved with a timer interrupt. A thread that calls schedule() will block. In the timer interrupt handler all (scheduled) blocked threads will be unblocked. The timer interrupt handler also manages all registered threads (see below). threads -------- It is impossible to provide kernel threads in OS/2. Threads in LXAPI32 are implemented with timer interrupts. At every timer tick LXAPI32 calls the function that was registered with the kernel_thread() function. This function should not block or stay in an endless loop. Instead it should be redesigned to give up (return) as needed. An Example: // Original thread code: static int stopThread=0; int myThread(void *data) { while(stopThread==0) { // Do something schedule(); // Do something different schedule(); } } // Modified thread code: static int stopThread=0; static int loopMode; int myThread(void *data) { switch(loopMode) { case 0: // Do something loopMode=1; break; case 1: // Do something different loopMode=0; break; } if(stopThread) return 1; else return 0; } As you can see it is necessary to provide an extra variable to save the thread's current state. This is used in a switch/case to decide which function to call. Resource requests ----------------------- Calls to request_irq() and and all request_* functions as defined in sched.h needs as an extra parameter a pointer to a struct lxrm_resource. This pointer is needed to support OS2 Resource Manager. 6 SKELETON sample driver ======================== In the directory SKELETON you'll find a sample device driver. If you plan to write an own driver based on LXAPI32.SYS you can use this sample as a template.