KEE.SYS
"KEE" is the "kernel execution environment", a set of functions like kernel mutexes and the like that you will need when you write a multi-core compliant device driver.
This API is also referred as the OS/2 Aurora KEE32 API.
Overview
KEE gives a 32-bit (flat model) device driver the kernel services it would otherwise get from the 16-bit DevHelp interface: locking, blocking and waking threads, memory allocation and locking, copying to and from user space, file access, Unicode conversion and tracing. It also provides calls to switch a thread's stack between 16-bit and 32-bit so that a 32-bit driver can still be called by, and call, 16-bit drivers.
A driver uses KEE by including bsekee.h (IBM DDK 1998; the Unicode calls are declared in unikern.h) and linking kee.lib. That library is only an import library: every call is imported by ordinal from a module named KEE, and the kernel resolves the imports when the driver is loaded.
Export ordinals
Taken from the import library kee.lib in the IBM DDK (47 entries, module name KEE). The numbers are grouped in tens:
| Ordinals | Group | Entries |
|---|---|---|
| 10-13 | Spinlocks | KernAllocSpinLock (10), KernFreeSpinLock (11), KernAcquireSpinLock (12), KernReleaseSpinLock (13) |
| 20-27 | Mutexes | KernAllocMutexLock (20), KernFreeMutexLock (21), KernRequestSharedMutex (22), KernReleaseSharedMutex (23), KernTryRequestSharedMutex (24), KernRequestExclusiveMutex (25), KernReleaseExclusiveMutex (26), KernTryRequestExclusiveMutex (27) |
| 30-31 | Block/wakeup | KernBlock (30), KernWakeup (31) |
| 40-45 | 16/32-bit and hooks | KernThunkStackTo16 (40), KernThunkStackTo32 (41), KernSerialize16BitDD (42), KernUnserialize16BitDD (43), KernArmHook (44), KernAllocateContextHook (45) |
| 50-51 | User/system copy | KernCopyIn (50), KernCopyOut (51) |
| 60-66 | Memory | KernVMAlloc (60), KernVMFree (61), KernVMLock (62), KernVMUnlock (63), KernLinToPageList (64), KernVMSetMem (65), KernSelToFlat (66) |
| 70 | Dynamic API | KernDynamicAPI |
| 80-81 | Trace | KernRASSysTrace (80), KernPerfSysTrace (81) |
| 90-94 | Data symbols | _KernSISData (90), _KernLISData (91), _KernInterruptLevel (92), _KernTKSSBase (93), _KernKEEVersion (94) |
| 100-106 | Files | KernLockFile (100), KernUnLockFile (101), KernGetFileSize (102), KernTestFileCache (103), KernReadFileAt (104), KernReadFileAtCache (105), KernReturnFileCache (106) |
| 120-122 | Unicode | KernCreateUconvObject (120), KernStrFromUcs (121), KernStrToUcs (122) |
The functions listed below as undocumented (KernYield, KernOpen, KernClose, KernRead) are not in the DDK import library.
Using KEE instead of DevHelp
The Drv32 kit's conversion notes (David Azarewicz) list these replacements when a 16-bit driver is ported to 32-bit:
| 16-bit DevHelp call | 32-bit replacement |
|---|---|
| DevHelp_ProcBlock | KernBlock |
| DevHelp_ProcRun | KernWakeup |
| DevHelp_VMLock / DevHelp_VMUnLock | KernVMLock / KernVMUnlock |
| DevHelp_VMAlloc | KernVMAlloc (or the Drv32 helpers D32VMAlloc / D32AllocMem, which call it) |
| DevHelp_RAS | KernRASSysTrace |
| DevHelp_VirtToLin | Far16ToFlat (a Drv32 helper, not part of KEE) |
Some DevHelp calls have no KEE equivalent and the Drv32 kit supplies its own wrappers (Dev32Help_*). One caveat from the Drv32 header: for stack variables, use the kit's D32ThunkStackTo32() rather than KernThunkStackTo32(), otherwise FlatToFar16() will not work on them.
Blocking and waking
KernBlock(id, timeout in ms, flags, lock, data) combines "release this lock" with "go to sleep", so a thread can block on an event without a race. The flags are:
- 0x01 uninterruptible
- 0x02 release the spinlock before blocking
- 0x04 release the exclusive mutex before blocking
- 0x08 release the shared mutex before blocking
- 0x10 do not re-acquire the lock after waking
KernWakeup(id, flags, count, data) wakes the threads blocked on an id: 0x01 wakes at most one thread, 0x04 boosts the priority of the woken threads, 0x08 passes a data word to them (returned through KernBlock's data pointer). It returns the number of threads woken.
Memory locking
KernVMLock accepts the flags 0x01 (do not block if the pages are not immediately available) and 0x02 (the pages must be physically contiguous, for drivers about to do contiguous DMA).
Where it is used
- The 32-bit disk manager of the DDK (OS2DASD) takes its internal lock/unlock operations from KEE spinlocks and links against
kee.lib. - The Drv32 kit links its sample drivers against
kee.lib, and its library implements physical-to-linear mapping on top ofKernVMAlloc(whole 4 KB pages are mapped). - The 32-bit TCP/IP sockets layer SOCKETSK.SYS.
Functions
- KernThunkStackTo16
- KernThunkStackTo32
- KernSerialize16BitDD
- KernUnserialize16BitDD
- KernCopyIn
- KernCopyOut
- KernVMAlloc
- KernVMFree
- KernVMLock
- KernVMUnlock
- KernLinToPageList
- KernVMSetMem
- KernSelToFlat
- KernDynamicAPI
- KernRASSysTrace
- KernPerfSysTrace
Hooks
Thread locking
Spin lock
Mutex lock
Exclusive mutex lock
File management
- KernLockFile
- KernUnLockFile
- KernGetFileSize
- KernTestFileCache
- KernReadFileAt
- KernReadFileAtCache
- KernReturnFileCache