Hi,
Thanks for testing - these are the types of bugs I'm looking for

. First, the easy one (the 486 cpu dx2 laptop) then the hard one...
NANOSLEEP
The "ISA Plug & Play" detection code uses a lot of little time delays, which add up to a total of 2408 mS (plus a little overhead) on any computer. These time delays use my "nanosleep" function, which (for short delays on computers without a local APIC or RDTSC) uses PIT channel 2 for timing.
I was configuring this PIT channel to generate a 596.59 KHz square wave (PIT mode 3) and then monitoring the output of the timer using IO port 0x61 bit 5. When I wrote the code I made sure the time delays were accurate on a Pentium IV, and checked that it worked on an 80486DX2-66, but never actually checked that it was accurate on the 486

. On this 486 the ISA Plug & Play detection was taking 4 seconds and I had assumed it was just a slower CPU - I was wrong!
The 596.59 KHz square wave made the timer output change state every 838 nS, which was too fast for the CPU/chipset to keep up with. This resulted in my code skipping timer output state changes, causing longer than intended delays. Depending on the exact timing of the delay code (and how long your chipset makes the CPU wait for an "in al,0x61" instruction) each time delay could have been anything on older computers.
I rewrote/optimized the delay code so that it takes a little less time between sampling the timer output state. Then I tested various timer frequencies with my 80486DX2-66 to find that frequencies higher than 298.295 KHz are unreliable. Based on this I've estimated that a 16 MHz 80486 (the slowest 80486) should handle frequencies lower than 149.1477 KHz and then halved it just to make sure, resulting in a final frequency of 74.573 KHz. IMHO this should be a very conservative setting, as the majority of time is spent within the "in al,0x61" instructions, which would depend on the speed of the chipset rather than the speed of the CPU (and all 80486 chipsets should be relatively similar).
KERNEL RE-ENTRANCY DEADLOCK
This is a strange one. The error itself is generated when the kernel detects that a re-entrancy lock is already locked when a thread is trying to acquire it. For a multi-CPU kernel this is normal and the CPU will wait for another CPU to release the lock before acquiring it. On a single-CPU kernel it's impossible for another CPU to release the lock, so the kernel generates this error (as the lock can't be freed when the CPU is waiting for it).
The re-entrancy lock in question is used to protect the "sleep queue", which is a list of threads that are sleeping. When a thread calls the "sleep" function, interrupts are disabled, the lock is acquired, the thread is inserted into the queue, then the lock is freed and interrupts are restored.
The handler for IRQ 8 (which is started by an interrupt gate - interrupts disabled) calls a routine that checks the sleep queue for threads that should be woken. The routine that wakes threads starts with interrupts disabled, acquires the re-entrancy lock, enables interrupts, removes any threads from the sleep queue, then frees the lock. The lock allows other IRQ handlers to interrupt but prevents thread switches. None of the other IRQ handlers (and none of the routines called by other IRQ handlers) uses the sleep queue lock.
Based on all of that, I can't find any way for the sleep queue lock to be locked twice (either through some quirk of timing, or something failing to release it). It's also (supposed to be) impossible for the scheduler to do a thread switch while the lock is acquired, so the kernel's idle thread shouldn't have been able to run (and even if thread switches were possible, the idle thread is a much lower priority than any thread that could've called the sleep function).
Therefore, the only explanation I can think of at the moment is that some code somewhere is overwriting the memory that contains the re-entrancy lock, and that's why the kernel thinks the re-entrancy lock is locked. Considering that I haven't been able to reproduce this problem, the "overwritten memory" idea doesn't sound too likely to me either (it's more likely I've overlooked some timing/synchronization related bug).
In an attempt to shed more light, I've improved the re-entrancy locking so that it will return an error code (containing the lock state and thread ID for who-ever locked it last), and added code to detect lock corruption. I've also tightened things up within the code that wakes sleeping threads and the code that stops running threads (used when they go to sleep, etc). If it is lock corruption it'll say so, if it's timing/synchronization I might have (hopefully) fixed it or I might have changed the exact timing so that the bug doesn't surface (hopefully not).
[EDIT: I've updated the web site's download page so the old link goes to the new version -
http://bcos.hopt.org/dl.html 
]
Thanks again,
Brendan