Switch to real mode int 0x13 problem
Switch to real mode int 0x13 problem
Hello everyone!
I write very simple OS in protected mode, loaded by grub.
I wanted to boot from pendrive so i started switching to real mode (for int 0x13).
I used Napalm's code which is very good, but I had some problems so I made it more simple
I don't change gdt (my GDT is the same like in asm), don't use stack (only 2 calls).
It works on all emulators and real single core machine.
On Athlon X2 switch to real mode makes a reset , if I try read HD it's OK, problem is on pendrive.
When I comment int 0x13 call it's OK, so switching protected/real works fine.
Maybe it's a problem with second core?
Thanks for help in advance
Tomek
I write very simple OS in protected mode, loaded by grub.
I wanted to boot from pendrive so i started switching to real mode (for int 0x13).
I used Napalm's code which is very good, but I had some problems so I made it more simple
I don't change gdt (my GDT is the same like in asm), don't use stack (only 2 calls).
It works on all emulators and real single core machine.
On Athlon X2 switch to real mode makes a reset , if I try read HD it's OK, problem is on pendrive.
When I comment int 0x13 call it's OK, so switching protected/real works fine.
Maybe it's a problem with second core?
Thanks for help in advance
Tomek
Re: Switch to real mode int 0x13 problem
And the code of int32:
There is a lot of "magic" because the fight is long .
When I don't change PIC it runs in VirtualBox, but hangs on real machines.
It must be interrupt problem - HD works fine (faster), pendrive is slower - needs interrupts.
Or second cpu, is there a simple method to disable cpu#2?
Code: Select all
[bits 32]
global int32, _int32
%define INT32_BASE 0x7C00
%define REBASE(x) (((x) - reloc) + INT32_BASE)
%define GDTENTRY(x) ((x) << 3)
%define CODE32 GDTENTRY(1) ; 0x8
%define DATA32 GDTENTRY(2) ; 0x10
%define CODE16 GDTENTRY(3) ; 0x18
%define DATA16 GDTENTRY(4) ; 0x20
%define STACK16 INT32_BASE - 0x100
section .text
int32: use32
_int32:
cli
mov al, 0x80
out 0x70, al ; disable NMI
mov esi, reloc
mov edi, INT32_BASE
mov ecx, (int32_end - reloc)
cld
rep movsb
jmp INT32_BASE
reloc: use32
mov [REBASE(stack32_ptr)], esp
sidt [REBASE(idt32_ptr)]
mov esp, STACK16
jmp word CODE16:REBASE(p_mode16)
p_mode16: use16
jmp $+2
mov ax, DATA16
mov ds, ax
mov es, ax
mov fs, ax
mov gs, ax
mov ss, ax
mov eax, cr0
and eax, 0x7ffffffe
mov cr0, eax
jmp word 0x0000:REBASE(r_mode16)
r_mode16: use16
jmp $+2
xor ax, ax
mov ds, ax
mov ss, ax
lidt [REBASE(idt16_ptr)]
mov bx, 0x0b71 ; orginal 0x0870
jmp $+2
call resetpic
jmp $+2
mov ax, 0
mov gs, ax
mov fs, ax
mov es, ax
mov ds, ax
mov si, 0x3900 ; DAP
mov al, [0x3950] ; registers
mov ah, [0x3951]
mov bl, [0x3952]
mov bh, [0x3953]
mov cl, [0x3954]
mov ch, [0x3955]
mov dl, [0x3956]
mov dh, [0x3957]
sti
jmp $+2
int 0x13
cli
mov [0x3950], al
mov [0x3951], ah
mov [0x3952], bl
mov [0x3953], bh
mov [0x3954], cl
mov [0x3955], ch
mov [0x3956], dl
mov [0x3957], dh
in al, 0x60
in al, 0x61
out 0x61, al
mov al, 0x20
out 0x20, al ;EOI
out 0xA0, al
call resetpic2
mov eax, cr0
or al,3
mov cr0, eax
jmp dword CODE32:REBASE(p_mode32)
p_mode32: use32
mov ax, DATA32
mov ds, ax
mov es, ax
mov fs, ax
mov ds, ax
mov gs, ax
mov ss, ax
lidt [REBASE(idt32_ptr)]
mov esp, [REBASE(stack32_ptr)]
mov al, 0
out 0x70, al ; enable NMI
sti
ret
resetpic:
mov al, 0x11
out 0x20, al
jmp $+2
out 0xA0, al
jmp $+2
mov al, bh
out 0x21, al
jmp $+2
mov al, bl
out 0xA1, al
jmp $+2
mov al, 0x04
out 0x21, al
jmp $+2
shr al, 1
out 0xA1, al
jmp $+2
shr al, 1
out 0x21, al
jmp $+2
out 0xA1, al
jmp $+2
ret
resetpic2:
mov al, 0x11
out 0x20, al
jmp $+2
out 0xA0, al
jmp $+2
mov al, 0x20
out 0x21, al
jmp $+2
mov al, 0x28
out 0xA1, al
jmp $+2
mov al, 0x04
out 0x21, al
jmp $+2
mov al, 0x02
out 0xA1, al
jmp $+2
mov al, 1
out 0x21, al
jmp $+2
out 0xA1, al
jmp $+2
mov al, 0xf8
out 0x21, al
jmp $+2
mov al, 0xff
out 0xA1, al
jmp $+2
in al, 0x21
jmp $+2
and al, 0xbb
out 0x21, al
jmp $+2
in al, 0xA1
jmp $+2
and al, 0x3f
out 0xA1, al
jmp $+2
ret
stack32_ptr:
dd 0x00000000
idt32_ptr:
dw 0x0000
dd 0x00000000
idt16_ptr:
dw 0x03FF
dd 0x00000000
int32_end:
When I don't change PIC it runs in VirtualBox, but hangs on real machines.
It must be interrupt problem - HD works fine (faster), pendrive is slower - needs interrupts.
Or second cpu, is there a simple method to disable cpu#2?
Re: Switch to real mode int 0x13 problem
cut the power to itis there a simple method to disable cpu#2?
Programming is 80% Math, 20% Grammar, and 10% Creativity <--- Do not make fun of my joke!
If you're new, check this out.
If you're new, check this out.
Re: Switch to real mode int 0x13 problem
Hi,
Note: If you have started/enabled other CPUs, then you probably want some sort of "if this CPU is not the boot CPU, send IPI to boot CPU and get it to do the actual BIOS function (instead of using BIOS function/s on this CPU)" logic. You'd also probably want a FIFO queue of requests for this (so that if several CPUs are asking the boot CPU to perform BIOS functions at the same time, the requests are queued and performed by the boot CPU when it can). Of course in this case IRQ handling becomes complicated, and it'd be a much smarter idea is to ask yourself why you're using the BIOS after boot in the first place
Cheers,
Brendan
When the computer is first started, the firmware leaves spare CPUs in a "wait for SIPI" state. Unless you've started/enabled the CPU it's already effectively disabled and you won't need to "re-disable" them.tomek32 wrote:Or second cpu, is there a simple method to disable cpu#2?
Note: If you have started/enabled other CPUs, then you probably want some sort of "if this CPU is not the boot CPU, send IPI to boot CPU and get it to do the actual BIOS function (instead of using BIOS function/s on this CPU)" logic. You'd also probably want a FIFO queue of requests for this (so that if several CPUs are asking the boot CPU to perform BIOS functions at the same time, the requests are queued and performed by the boot CPU when it can). Of course in this case IRQ handling becomes complicated, and it'd be a much smarter idea is to ask yourself why you're using the BIOS after boot in the first place
Cheers,
Brendan
For all things; perfection is, and will always remain, impossible to achieve in practice. However; by striving for perfection we create things that are as perfect as practically possible. Let the pursuit of perfection be our guide.
Re: Switch to real mode int 0x13 problem
Thanks,
I didn't started second cpu, I think that grub 0.97 also doesn't.
I was testing various PIC settings in real mode and always reset
On older pc nearly always OK.
Maybe I should restore IDT at 0:0? Maybe grub is changing it?
I cut power to cpu#2, but it didn't help
I didn't started second cpu, I think that grub 0.97 also doesn't.
I was testing various PIC settings in real mode and always reset
On older pc nearly always OK.
Maybe I should restore IDT at 0:0? Maybe grub is changing it?
I cut power to cpu#2, but it didn't help
Re: Switch to real mode int 0x13 problem
I have no more ideas for now:-(
I was trying to debug it through prodebug. It's an interesting protected mode debugger booting from floppy.
But after boot, floppy reads hangs.
I've linked my code into prodebug, but it's not so easy...
Do You know good debugger to debug kernel on real machine?
I was trying to debug it through prodebug. It's an interesting protected mode debugger booting from floppy.
But after boot, floppy reads hangs.
I've linked my code into prodebug, but it's not so easy...
Do You know good debugger to debug kernel on real machine?
-
- Member
- Posts: 283
- Joined: Mon Jan 03, 2011 6:58 pm
Re: Switch to real mode int 0x13 problem
Bochs w/internal debuggertomek32 wrote:I have no more ideas for now:-(
I was trying to debug it through prodebug. It's an interesting protected mode debugger booting from floppy.
But after boot, floppy reads hangs.
I've linked my code into prodebug, but it's not so easy...
Do You know good debugger to debug kernel on real machine?
- Monk
Re: Switch to real mode int 0x13 problem
But it runs under Bochs...
And VirtualBox debugger.
It must be something in BIOS, which I didn't turned off.
And VirtualBox debugger.
It must be something in BIOS, which I didn't turned off.
-
- Member
- Posts: 283
- Joined: Mon Jan 03, 2011 6:58 pm
Re: Switch to real mode int 0x13 problem
Single step your code, look up any instructions you don't understand, compare the debugger dis-assembly vs your assembly code, look for ANYTHING out of place. Let us know if you have specific questions about any disassembly, returns, etc.tomek32 wrote:But it runs under Bochs...
And VirtualBox debugger.
It must be something in BIOS, which I didn't turned off.
- Monk
P.S. You should have done all this before posting here... We help newbies to OS, not newbies to developers (And that means you can debug) Not saying its the case here, but it happens often enough. Help us, help you!
Re: Switch to real mode int 0x13 problem
I was debugging it 1000 times (before it started to work).
Mostly under VBox debugger and Bochs.
Now I need to debug it on real machnie...
Mostly under VBox debugger and Bochs.
Now I need to debug it on real machnie...
Re: Switch to real mode int 0x13 problem
I think you have to program debugging features into the os to debug on a real machine.
Programming is 80% Math, 20% Grammar, and 10% Creativity <--- Do not make fun of my joke!
If you're new, check this out.
If you're new, check this out.
Re: Switch to real mode int 0x13 problem
Try adding a simple trace facility. Poke a different character to 0xb800 at different points in the code and in the isr so you can look at what character is in the top left of the screen when the system looks up. This is a very basic form of debugging which can identify problems quite well if you are patient and have no other more advanced facilities to hand...
Note that if you are getting reboots you may also need to mix this method with hlt loops, so you can read your 'output' without it resetting.
Note that if you are getting reboots you may also need to mix this method with hlt loops, so you can read your 'output' without it resetting.
Re: Switch to real mode int 0x13 problem
It's better
It works on Core I3 notebook.
I moved STACK16 from 7B00 to 20000.
There was only 15k of stack (at 4000) was my disk buffer.
But 15k stack for BIOS is to small?? Maybe with usb?
It still resets on Athlon X2, but it was hanging on notebook..
It works on Core I3 notebook.
I moved STACK16 from 7B00 to 20000.
There was only 15k of stack (at 4000) was my disk buffer.
But 15k stack for BIOS is to small?? Maybe with usb?
It still resets on Athlon X2, but it was hanging on notebook..