Page 2 of 4

Re: PCnet / FAST III

Posted: Tue Dec 02, 2014 4:17 pm
by ronaldlees
andymc wrote:That would be cool, if you could figure out how to single-step Visopsys from a VM :ugeek:

Visopsys chain-loads, exactly the same as Windows (but unlike Linux). You just load the first sector of the Visopsys partition into the memory location 0x00007c00 and jump to it. More or less.

Unlike the boot sector 0, the OS loader (/vloader) does do some fairly Visopsys-specific stuff: gathering info from the real-mode BIOS, setting the video mode, setting up basic memory paging, switching to protected mode, passing arguments to the kernel, etc. Not so easy to swap that out :lol:
Yes, after I thought about it, I realized that vloader was doing a lot more than just setting things up to hit the kernel's entry point. You're right though - it would be a pretty cool thing to do. GxEmul is a nice little emulator with capabilities to emulate different hardware based on i386, ARM, mips, etc. I've had some success stepping hobby kernels on it. It is similar to QEMU, except that you can specify an entry point. Being able to do so, is of course of limited benefit if too much has to be done by the loader. I don't know much about Visopsys, and have only taken a few looks at the code. Does the kernel call the loader back, like in RiscOS?

I guess I'll settle for working on a full -hda image of Visopsys/QEMU for now, just to see what there is to see. My first foray into that resulted in some kind of RTC problem, trying to install Visopsys into a QEMU .hda image.

- Ron

Re: PCnet / FAST III

Posted: Tue Dec 02, 2014 4:51 pm
by ronaldlees
I tried to install Visopsys to a QEMU image:

Code: Select all

qemu-img create -f raw visopsys.img 1G

Code: Select all

qemu-system-i386 -hda visopsys.img -cdrom visopsys-2014-11-14.iso -boot d
When the QEMU window appeared, it displayed the initial loading of Visopsys, and stopped with:

Code: Select all

Detecting hardware: real-time clock (RTC) Error::kernelRtcDriver.c:waitReady(58)
RTC not ready
Detecting hardware: real-time clock (RTC) Error::kernelRtcDriver.c:waitReady(58)
RTC not ready
etc, etc
It's probably something brain dead simple I'm not doing.

Re: PCnet / FAST III

Posted: Tue Dec 02, 2014 5:37 pm
by andymc
ronaldlees wrote:I don't know much about Visopsys, and have only taken a few looks at the code. Does the kernel call the loader back, like in RiscOS?
No, once the loader hands off parameters to the kernel via its stack, the loader becomes free memory. It sets up a flat-memory, protected mode environment for the kernel to run in, and then the kernel is on its own.
ronaldlees wrote:When the QEMU window appeared, it displayed the initial loading of Visopsys, and stopped with:

Code: Select all

Detecting hardware: real-time clock (RTC) Error::kernelRtcDriver.c:waitReady(58)
RTC not ready
Detecting hardware: real-time clock (RTC) Error::kernelRtcDriver.c:waitReady(58)
RTC not ready
etc, etc
It's probably something brain dead simple I'm not doing.
It's probably a problem with the RTC code, in fact. I've recently tweaked it a bit for the next release - I was seeing similar error messages in VirtualBox (never on real machines, but these emulators can introduce weird factors) and it's working now. Here's the patch, if you wouldn't mind giving it a try?

Code: Select all

Index: src/kernel/kernelRtcDriver.c
===================================================================
RCS file: /home/andymc/Prog/cvs/visopsys/src/kernel/kernelRtcDriver.c,v
retrieving revision 1.25
diff -u -r1.25 kernelRtcDriver.c
--- src/kernel/kernelRtcDriver.c	29 Jun 2014 15:35:08 -0000	1.25
+++ src/kernel/kernelRtcDriver.c	30 Oct 2014 23:56:43 -0000
@@ -49,10 +49,16 @@
 	unsigned char data = 0x80;
 	int count;
 
-	kernelProcessorOutPort8(0x70, 0x0A);
-	for (count = 0; ((count < 10000) && (data & 0x80)); count ++)
+	for (count = 0; count < 10000; count ++)
+	{
+		kernelProcessorOutPort8(0x70, 0x0A);
+		kernelProcessorDelay();
 		kernelProcessorInPort8(0x71, data);
 
+		if (!(data & 0x80))
+			break;
+	}
+
 	if (data & 0x80)
 	{
 		kernelError(kernel_error, "RTC not ready");

Re: PCnet / FAST III

Posted: Tue Dec 02, 2014 5:44 pm
by ronaldlees
Here's the patch, if you wouldn't mind giving it a try?

Code: Select all

Index: src/kernel/kernelRtcDriver.c
===================================================================
RCS file: /home/andymc/Prog/cvs/visopsys/src/kernel/kernelRtcDriver.c,v
retrieving revision 1.25
diff -u -r1.25 kernelRtcDriver.c
--- src/kernel/kernelRtcDriver.c	29 Jun 2014 15:35:08 -0000	1.25
+++ src/kernel/kernelRtcDriver.c	30 Oct 2014 23:56:43 -0000
@@ -49,10 +49,16 @@
 	unsigned char data = 0x80;
 	int count;
 
-	kernelProcessorOutPort8(0x70, 0x0A);
-	for (count = 0; ((count < 10000) && (data & 0x80)); count ++)
+	for (count = 0; count < 10000; count ++)
+	{
+		kernelProcessorOutPort8(0x70, 0x0A);
+		kernelProcessorDelay();
 		kernelProcessorInPort8(0x71, data);
 
+		if (!(data & 0x80))
+			break;
+	}
+
 	if (data & 0x80)
 	{
 		kernelError(kernel_error, "RTC not ready");
Sure. I'll slap it on right after I get back from my (daily) five mile run (gotta keep MY old hardware running :-) )

- Ron

Re: PCnet / FAST III

Posted: Tue Dec 02, 2014 7:40 pm
by ronaldlees
Andy:

I got back, walked the dogs, and did the patch.

Good news - the patch allows the installation onto the QEMU virtual drive to continue further. The less good news, is that as the installation continues, it shows messages about having problems detecting the virtual drive.

Maybe I'm not on the same page with the other QEMU users of Visopsys. Just to be certain, I'll check the Qemu version. I'm using:

Code: Select all

qemu -version

QEMU emulator version 1.1.2 (Debian 1.1.2+dfsg-6a+deb7u5), Copyright (c) 2003-2008 Fabrice Bellard
Is that the same version that works for everybody else?

Re: PCnet / FAST III

Posted: Tue Dec 02, 2014 9:36 pm
by ronaldlees
Well, I did get what I wanted, and was able to single step the visopsys kernel with QEMU and gdb.

First, I set QEMU to start with "stopped" option:

Code: Select all

qemu-system-i386 -hda ./visopsys1.img -cdrom ./visopsys-2014-12-02.iso -boot d -s -serial stdio -S
Then, in separate terminal, I started gdb:

Code: Select all

gdb ./visopsys
          (loading debug symbols)

(gdb) target remote localhost:1234
(gdb) b identify
   (Breakpoint 1 at 0xc0047a45: file kernelIdeDriver.c, line 1081.)
(gdb) cont
      (Continuing.)

Breakpoint 1, identify (diskNum=diskNum@entry=0, 
    buffer=buffer@entry=0xc00d841c) at kernelIdeDriver.c:1081
1081	{
(gdb) si
I tried to pick a series of good breakpoints, so that I might isolate the issue quicker, which is that the device was not identified. The following is a small snippet of the debugging session. I guess I should study the code to select some good breakpoints for this issue...

Code: Select all

0xc004631b	367							kernelProcessorInPort8(DISK_CHAN(diskNum).ports.altComStat,
369				if (statReg & ATA_STAT_ERR)
0xc0046321	369				if (statReg & ATA_STAT_ERR)
376				if (kernelSysTimerRead() > (startTime + timeout))
kernelSysTimerRead () at kernelSysTimer.c:136
136		if (systemTimer == NULL)
0xc002cf3d	136		if (systemTimer == NULL)
141		if (ops->driverRead == NULL)
0xc002cf49	141		if (ops->driverRead == NULL)
148		timer = ops->driverRead();
0xc0053cc5 in driverRead () at kernelSysTimerDriver.c:71
71	}
driverSetupTimer (counter=-1073454261, mode=-1073257218, count=0)
    at kernelSysTimerDriver.c:115
115	{
0xc0053ccc in driverSetupTimer (counter=-1073257218, mode=0, count=37)
    at kernelSysTimerDriver.c:115
115	{
0xc0053ccd in driverSetupTimer (counter=0, mode=20, count=-1072856236)
    at kernelSysTimerDriver.c:115
115	{
0xc004634b in waitOperationComplete (diskNum=diskNum@entry=0, 
    yield=yield@entry=0, dataWait=dataWait@entry=1, ack=0, timeout=20)
    at kernelIdeDriver.c:376
376				if (kernelSysTimerRead() > (startTime + timeout))
0xc004634e	376				if (kernelSysTimerRead() > (startTime + timeout))
346			if (yield && !DISK_CHAN(diskNum).gotInterrupt)
0xc0046296	346			if (yield && !DISK_CHAN(diskNum).gotInterrupt)
355			if (DISK_CHAN(diskNum).gotInterrupt)
0xc00462bf	355			if (DISK_CHAN(diskNum).gotInterrupt)
367				kernelProcessorInPort8(DISK_CHAN(diskNum).ports.altComStat,
0xc004631c	367				kernelProcessorInPort8(DISK_CHAN(diskNum).ports.altComStat,
369				if (statReg & ATA_STAT_ERR)
0xc0046321	369				if (statReg & ATA_STAT_ERR)
376				if (kernelSysTimerRead() > (startTime + timeout))
kernelSysTimerRead () at kernelSysTimer.c:136
136		if (systemTimer == NULL)
0xc002cf3d	136		if (systemTimer == NULL)
141		if (ops->driverRead == NULL)
0xc002cf44	141		if (ops->driverRead == NULL)
148		timer = ops->driverRead();
0xc0053cc5 in driverRead () at kernelSysTimerDriver.c:71
71	}
driverSetupTimer (counter=-1073454261, mode=-1073257218, count=0)
    at kernelSysTimerDriver.c:115
115	{
0xc0053ccc in driverSetupTimer (counter=-1073257218, mode=0, count=37)
    at kernelSysTimerDriver.c:115
115	{
0xc0053ccd in driverSetupTimer (counter=0, mode=20, count=-1072856236)
    at kernelSysTimerDriver.c:115
115	{
0xc004634b in waitOperationComplete (diskNum=diskNum@entry=0, 
    yield=yield@entry=0, dataWait=dataWait@entry=1, ack=0, timeout=20)
    at kernelIdeDriver.c:376
376				if (kernelSysTimerRead() > (startTime + timeout))
0xc004634e	376				if (kernelSysTimerRead() > (startTime + timeout))
346			if (yield && !DISK_CHAN(diskNum).gotInterrupt)
0xc0046296	346			if (yield && !DISK_CHAN(diskNum).gotInterrupt)
355			if (DISK_CHAN(diskNum).gotInterrupt)
0xc00462bf	355			if (DISK_CHAN(diskNum).gotInterrupt)
367				kernelProcessorInPort8(DISK_CHAN(diskNum).ports.altComStat,
0xc004631c	367				kernelProcessorInPort8(DISK_CHAN(diskNum).ports.altComStat,
369				if (statReg & ATA_STAT_ERR)
0xc0046321	369				if (statReg & ATA_STAT_ERR)
376				if (kernelSysTimerRead() > (startTime + timeout))
kernelSysTimerRead () at kernelSysTimer.c:136
136		if (systemTimer == NULL)
(gdb) quit
A debugging session is active.

Obviously I really need to find some decent breakpoints. Stepping with "n" commands directly in GDB results in ugly output. I'd do better with an IDE here (emacs). But, I'm feeling like I might learn something about your kernel!

Re: PCnet / FAST III

Posted: Tue Dec 02, 2014 11:56 pm
by andymc
Man, that's so cool. I've never considered doing this stuff. I'm not much of a debugger-user anyway, but sometimes they're the right tool for a tricky problem. I need to try this.

These lines

Code: Select all

driverSetupTimer (counter=-1073454261, mode=-1073257218, count=0)
    at kernelSysTimerDriver.c:115
look screwy, but I think it's just a debugger hiccup. That function is not called when reading the timer. Basically, the code is looping, waiting for an IDE interrupt.

Is this a debug build? (make debug) Do you see any messages like

Code: Select all

		// Just a timeout
		kernelDebugError("Disk %02x no interrupt received - timeout",
			 diskNum);
? You'd only see those in a debug build.

I suspect that the real problem here is the new APIC interrupt controller code, introduced in the most recent release (0.75). Nextvolume posted about problems with the APIC in Qemu http://visopsys.org/forums/viewtopic.php?f=3&t=250. I'm currently trying to debug it in VirtualBox (gah!) and when I get that sorted, I was planning to test in Qemu...

If you want to disable the APIC code and test that, just stick a "return 0;" at the top of the driverDetect() function in kernelApicDriver.c. Then it will fall back to using the old PIC code.

Re: PCnet / FAST III

Posted: Wed Dec 03, 2014 1:13 am
by ronaldlees
andymc wrote: Is this a debug build? (make debug) Do you see any messages like

Code: Select all

		// Just a timeout
		kernelDebugError("Disk %02x no interrupt received - timeout",
			 diskNum);
? You'd only see those in a debug build.
Yes, kernelDebugError() lines were scrolling by all the time. The snippet I selected was pretty random.
andymc wrote: I suspect that the real problem here is the new APIC interrupt controller code, introduced in the most recent release (0.75). Nextvolume posted about problems with the APIC in Qemu http://visopsys.org/forums/viewtopic.php?f=3&t=250. I'm currently trying to debug it in VirtualBox (gah!) and when I get that sorted, I was planning to test in Qemu...

If you want to disable the APIC code and test that, just stick a "return 0;" at the top of the driverDetect() function in kernelApicDriver.c. Then it will fall back to using the old PIC code.
Yes, I'll give your suggestion to drop back to old PIC a go. Probably in the morning tho ...

I just spent about an hour trying to get all of this to run with Eclipse, but so far there seems to be some muckup in the remote debug configuration.

Edit: (twenty minutes later)

- I couldn't stand the suspense, so I made the change you suggested to drop back to "old PIC" mode and recompiled, and now it works. So we can end the day on a high note (other than for the APIC needing something)

Re: PCnet / FAST III

Posted: Wed Dec 03, 2014 2:02 am
by andymc
That's good news - thanks for the update. My task is clearly marked out for me in that case.

With the APIC, on VirtualBox, it's a tricky one. I've spent 2 evenings trying to debug it. Identified some tweaks, but no answer yet. Hopefully, whatever the issue is, it'll be the same for Qemu. Ideally I'd be trying Qemu in parallel to compare results, but I had some difficulty getting it installed in my Ubuntu. Perhaps I should try again.

Re: PCnet / FAST III

Posted: Thu Dec 04, 2014 3:44 am
by andymc
Hi Ron,

Could you possibly try dropping this version of the APIC driver into your source tree, and see whether it solves the problems you've been seeing with missing interrupts, etc., in Qemu?

I seem to have solved it in VirtualBox, and the error messages were so similar to Qemu, but I've had trouble setting up Qemu on my dev machine. If you and nextvolume think the APIC code is working in Qemu, then I'll feel more confident that I've fixed it.