Page 1 of 1

Switch to real mode int 0x13 problem

Posted: Sat Mar 23, 2013 3:11 am
by tomek32
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

Re: Switch to real mode int 0x13 problem

Posted: Sun Mar 24, 2013 4:03 am
by tomek32
And the code of int32:

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:                       
    
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?

Re: Switch to real mode int 0x13 problem

Posted: Sun Mar 24, 2013 7:30 pm
by Mikemk
is there a simple method to disable cpu#2?
cut the power to it

Re: Switch to real mode int 0x13 problem

Posted: Sun Mar 24, 2013 10:04 pm
by Brendan
Hi,
tomek32 wrote:Or second cpu, is there a simple method to disable cpu#2?
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.

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

Re: Switch to real mode int 0x13 problem

Posted: Mon Mar 25, 2013 2:05 pm
by tomek32
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 :-)

Re: Switch to real mode int 0x13 problem

Posted: Wed Mar 27, 2013 1:16 pm
by tomek32
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?

Re: Switch to real mode int 0x13 problem

Posted: Wed Mar 27, 2013 2:40 pm
by FallenAvatar
tomek32 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?
Bochs w/internal debugger

- Monk

Re: Switch to real mode int 0x13 problem

Posted: Wed Mar 27, 2013 3:08 pm
by tomek32
But it runs under Bochs...
And VirtualBox debugger.

It must be something in BIOS, which I didn't turned off.

Re: Switch to real mode int 0x13 problem

Posted: Wed Mar 27, 2013 8:14 pm
by FallenAvatar
tomek32 wrote:But it runs under Bochs...
And VirtualBox debugger.

It must be something in BIOS, which I didn't turned off.
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.

- 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

Posted: Thu Mar 28, 2013 4:06 am
by tomek32
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...

Re: Switch to real mode int 0x13 problem

Posted: Fri Mar 29, 2013 4:32 pm
by Mikemk
I think you have to program debugging features into the os to debug on a real machine.

Re: Switch to real mode int 0x13 problem

Posted: Fri Mar 29, 2013 9:39 pm
by brain
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.

Re: Switch to real mode int 0x13 problem

Posted: Sat Mar 30, 2013 11:24 am
by tomek32
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..