From our investigations (Timo & I), there seems to be a memory
corruption when using a PXE boot on VBox.
You're committing a hack to workaround this memory corruption (which
replaces code which seems correct by some other code which is probably
correct), which lets you go a little bit further, where memory
corruption seems to strike again. And thus, this doesn't bring PXE boot
in better shape.
Furthermore, it appears that you're working around a bug which isn't in
ReactOS but in VBox. As a reminder, PXE boot works fine with Qemu, with
VMware. And when changing the ROM of VBox [1], then PXE boot works on
VBox as well.
Revert and report to VirtualBox instead. Our code is correct.
Thanks to Timo & Hervé for their help on digging into this issue.
[1]:
https://git.ipxe.org/ipxe.git/blob/HEAD:/src/config/vbox/README
On 10/01/2015 01:21, hbelusca(a)svn.reactos.org wrote:
Author: hbelusca
Date: Sat Jan 10 00:21:33 2015
New Revision: 66022
URL:
http://svn.reactos.org/svn/reactos?rev=66022&view=rev
Log:
[FREELDR]: Commit a temporary "hackfix" for (Pc)GetTime: on VBox when booting
with PXE, for some mysterious reason, Int386(0x1A) call with AH = 0x02 (Get CMOS Time)
*never ever* returns!! (however without PXE everything works). So... is it some kind of
stack overflow or whatever that makes the Int386 function stack messy? Or something else?
So in the meantime we use direct CMOS port reads. Timo, Hervé (and others), can you please
review? And in particular why does it happen only with PXE?
Modified:
trunk/reactos/boot/freeldr/freeldr/arch/i386/pcrtc.c
Modified: trunk/reactos/boot/freeldr/freeldr/arch/i386/pcrtc.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/boot/freeldr/freeldr/arch/…
==============================================================================
--- trunk/reactos/boot/freeldr/freeldr/arch/i386/pcrtc.c [iso-8859-1] (original)
+++ trunk/reactos/boot/freeldr/freeldr/arch/i386/pcrtc.c [iso-8859-1] Sat Jan 10 00:21:33
2015
@@ -20,10 +20,50 @@
#define BCD_INT(bcd) (((bcd & 0xf0) >> 4) * 10 + (bcd &0x0f))
+#ifndef INT386_WITH_INT_1A_AH_02_04__IS__FIXED
+
+/* CMOS Registers and Ports */
+#define CMOS_CONTROL_PORT (PUCHAR)0x70
+#define CMOS_DATA_PORT (PUCHAR)0x71
+
+#define RTC_REGISTER_A 0x0A
+#define RTC_REG_A_UIP 0x80
+
+static UCHAR
+HalpReadCmos(IN UCHAR Reg)
+{
+ /* Select the register */
+ WRITE_PORT_UCHAR(CMOS_CONTROL_PORT, Reg);
+
+ /* Query the value */
+ return READ_PORT_UCHAR(CMOS_DATA_PORT);
+}
+
+#endif
+
TIMEINFO*
PcGetTime(VOID)
{
static TIMEINFO TimeInfo;
+
+#ifndef INT386_WITH_INT_1A_AH_02_04__IS__FIXED
+
+ /* Loop while update is in progress */
+ while ((HalpReadCmos(RTC_REGISTER_A)) & RTC_REG_A_UIP);
+
+ /* Set the time data */
+ TimeInfo.Second = BCD_INT(HalpReadCmos(0));
+ TimeInfo.Minute = BCD_INT(HalpReadCmos(2));
+ TimeInfo.Hour = BCD_INT(HalpReadCmos(4));
+ TimeInfo.Day = BCD_INT(HalpReadCmos(7));
+ TimeInfo.Month = BCD_INT(HalpReadCmos(8));
+ TimeInfo.Year = BCD_INT(HalpReadCmos(9));
+
+ /* Compensate for the century field */
+ TimeInfo.Year += (TimeInfo.Year > 80) ? 1900: 2000;
+
+#else
+
REGS Regs;
for (;;)
@@ -86,6 +126,9 @@
break;
}
+
+#endif
+
return &TimeInfo;
}
--
Pierre Schweitzer <pierre at reactos.org>
System & Network Administrator
Senior Kernel Developer
ReactOS Deutschland e.V.