Page 1 of 2
Working on bochs but not on real PC
Posted: Thu Jan 24, 2008 7:27 am
by AlfaOmega08
Why does my OS work on bochs, but on real PC it doesn't?
On a real PC it reboots immediately after the bootstrap
On Virtual PC 2007 after the bootstrap, the virtual machine crashes...
Maybe is the boot code?
Posted: Thu Jan 24, 2008 8:01 am
by ucosty
VM's typically zero all the memory. A real computer may have random values scattered throughout ram. You can't rely on uninitialised variables containing 0.
VM's also dont accurately simulate the timings of devices and as a result IO operations can work fine in VMs but not on real machines. The solution is to add wait states around appropriate io port operations.
Thats all I can think of at the moment.
Posted: Thu Jan 24, 2008 8:16 am
by AlfaOmega08
So.. according to you, I should initialize each variable with 0. And add a wait after each I/O operation, like that:
Code: Select all
outportb(xxx, xxx);
for (i = 0; i < 500; i++);
[/code]
Posted: Thu Jan 24, 2008 8:24 am
by AJ
Hi,
Most likely it's the first option - something is assuming zeroed memory. For example, if you are paging, you should really zero each new page table / directory before using them and as ucosty mentioned, do not use any variable uninitialised.
The wait for I/O will depend on what device you are talking to. Some devices may need no wait at all, some may requre several ms. Some devices, you will have to do a sleep manually, some provide busy flags, so that you can keep polling the status register until the busy flag is clear.
Cheers,
Adam
Posted: Thu Jan 24, 2008 8:40 am
by AlfaOmega08
I'm not currently using paging...
For the I/O i'm handling only the keyboard. I know I've to test the bit1 of the port 0x64 before write. But in my case, it seems the problem is before the initialization of the drivers.
The problem is immediately after the boot code. The first thing my kernel does is a ClearScreen. And it crashes before that
Posted: Thu Jan 24, 2008 8:47 am
by ucosty
What boot code are you using?
Posted: Thu Jan 24, 2008 8:51 am
by AJ
Suggestion: Run it on VPC and have COM1 output to a text file. Write a really basic serial driver which does not use your normal driver interface (just have it compiled directly in, with a com_putc() function which can be called from anywhere in your kernel) and at certain points just output 'A', 'B', 'C', etc...
This will really quickly enable you to establish the site of the crash. I have always found it useful in my test kernels to automatically echo all console output to a COM port by default.
Cheers,
Adam
Posted: Thu Jan 24, 2008 9:22 am
by ucosty
AJ wrote:This will really quickly enable you to establish the site of the crash. I have always found it useful in my test kernels to automatically echo all console output to a COM port by default.
My OS does that and it works nicely. I still have no idea, however, how I got it in my head that it would be a good idea to test the serial output by printing it to the console though.
Posted: Thu Jan 24, 2008 9:35 am
by Solar
One such problem I heard about is that Bochs emulated floppy never fails, while a "real" floppy drive can fail numerous times before getting it right.
I never got to the point of floppy access, perhaps one of the others could pitch in details.
Posted: Thu Jan 24, 2008 9:43 am
by AlfaOmega08
I've writed my boot code by myself. It loads a KERNEL_SIZE number of sectors in the memory at 0x10000, disable ints, enable A20, load gdt, switch to PMode and jmp to 0x10000
Code: Select all
KERNEL_SIZE EQU 50
[BITS 16]
[ORG 7C00h]
XOR AX, AX
MOV SP, 7C00h
MOV BP, 7C00h
MOV SI, KERNEL_SIZE
XOR BX, BX
MOV AX, 1000h
MOV ES, AX
MOV CX, 2
XOR DX, DX
Again:
MOV AH, 2
MOV AL, 1
INT 13h
JC Error
PUSH AX
PUSH BX
MOV AH, 0Eh
MOV AL, '.'
MOV BX, 7
INT 10h
POP BX
POP AX
MOV AX, ES
ADD AX, 32
MOV ES, AX
DEC SI
JZ Readed
INC CX
CMP CL, 18
JBE Again
MOV CL, 1
INC DH
CMP DH, 2
JNE Again
MOV DH, 0
INC CH
JMP Again
Error:
MOV AH, 0Eh
MOV AL, 'E'
MOV BX, 7
INT 10h
XOR AX, AX
INT 16h
INT 19h
Readed:
MOV DX, 3F2h
MOV AL, 0Ch
OUT DX, AL
CLI
MOV AL, 8Dh
OUT 70h, AL
IN AL, 71h
Wait1:
IN AL, 64h
TEST AL, 2
JNZ Wait1
MOV AL, 0D1h
OUT 64h, AL
Wait2:
IN AL, 64h
TEST AL, 2
JNZ Wait2
MOV AL, 0DFh
OUT 60h, AL
LGDT [GDTR]
MOV EAX, CR0
OR AL, 1
MOV CR0, EAX
JMP 08h:Main32
Main32:
[BITS 32]
MOV EAX, 10H
MOV DS, AX
MOV ES, AX
MOV FS, AX
MOV GS, AX
MOV SS, AX
MOV ESP, 900000h
PUSH DWORD 2
POPFD
MOV EAX, 10000h
JMP EAX
CLI
HLT
[BITS 16]
GDT:
NullSegment:
DD 0
DD 0
CodeSegment:
DW 0FFFFh
DW 0
DB 0
DB 9Ah
DB 0CFh
DB 0
DataSegment:
DW 0FFFFH
DW 0
DB 0
DB 92h
DB 0CFh
DB 0
GDTEnd:
GDTR:
DW GDTEnd - GDT - 1
DD GDT
[BITS 32]
times (510 - ($ - $$)) DB 0
DW 0AA55h
Posted: Wed Feb 06, 2008 12:50 pm
by AlfaOmega08
I've tried to rewrite my bootloader (now with FAT12 support
), and I forgot to put the code to enable the A20 Gate. It has worked wonderful...
As I have put the A20 Gate enabling, it has started crash.
I can say that the bootloader crashes on the jump to the kernel, because commenting that line, it does not crash any more.
I enable A20 with this code:
Code: Select all
CALL Empty8042
MOV AL, 0D1h
OUT 64h, AL
CALL Empty8042
MOV AL, 0DFh
OUT 60h, AL
CALL Empty8042
Where "Empty8042" is:
Code: Select all
Empty8042:
IN AL, 64h
TEST AL, 2
JNZ Empty8042
RET
And this is my PMode entry point:
Code: Select all
[BITS 32]
Main32:
MOV AX, 10h
MOV DS, AX
MOV ES, AX
MOV FS, AX
MOV GS, AX
MOV SS, AX
MOV ESP, 90000h
MOV EAX, 100000h
JMP EAX ;If I comment this, it doesn't crash
CLI
HLT
Posted: Thu Feb 07, 2008 9:29 am
by AlfaOmega08
Can anyone help me?
Posted: Thu Feb 07, 2008 9:39 am
by Combuster
For starters, use brendan's bios and configure it to fill memory with garbage. Hopefully that will make the error appear in bochs as well.
Posted: Thu Feb 07, 2008 1:51 pm
by AlfaOmega08
I've not found brendan's bios, neither on google...
Anytime, now the problem is on VPC not on bochs...
I've modified my code for the A20 Gate according to the brokenthorn one. The routine to enable the A20 returns -1. As whe cannot enable A20 with keyboard.
This explain why it doesn't jump... the address is over 1 MB!
Can I starts my kernel in real mode, write routines in C for loading GDT, enabling A20 (trying with keyboard, then INT 15, ...), and switch to PMode? Does gcc support real mode?
Posted: Thu Feb 07, 2008 4:46 pm
by Masterkiller
You could try to enable A20 trough the system control port A (port 0x92). It is faster and easier (you don't have to wait).
The other thing that you could do is to write handle for 'double fault' exception to display somthing on screen. That will explain much
The code you posted does not change the DS and SS register in real-mode. LGDT format gets the address from the DS:immediate. Try to debug on bochs to see where system restarts and is the GDT is properly loaded.