Page 1 of 1

problem passing my code to a function.

Posted: Sun May 22, 2005 10:10 am
by hgb
I have made a macro for show more easy my case.

Code: Select all

%macro inlinePM 0
cli
   ; /* disable NMIs as well */
   in al, 0x70
   or al, 0x80
   out 0x70, al

   call setup_GDT
   call setup_IDT

   mov ax, cx
   mov [old_CS], ax
   mov ax, ds
   mov [old_DS], ax
   mov ax, ss
   mov [old_SS], ax
;   mov ax, sp
;   mov [old_SP], ax

   ; /* WOW!!! This switches us to PMode just setting up CR0.PM bit to 1 */
   invk read_cr0 ; ; return dx:ax
   or ax, 1
   invk write_cr0, eax

   ; /* loading segment registers with PMode selectors */
   invk update_cs, 0x8
   mov ax, 0x10
   mov ds, ax
   mov es, ax
   mov ax, 0x18
   mov ss, ax
%endmacro
Also I have added this macro "OFFSETHERE" and the argument is the next line without comas.. some like:
OFFSETHERE MOV SS AX...
mov ss,ax

Code: Select all

%macro OFFSETHERE 1
%%__here__
%assign _here_3455342 %%__here__ -$$
%error  [_here_3455342] %1
%endmacro

I have in my code some like (compact form I guess):

Code: Select all

jmp start2
......
......
%macro inlinePM 0
.......
%endmacro

setup_pmode:
     inlinePM
     ret
.......
start2:
   cli         ; please no interupts
   mov   ax,cs
   mov   ds,ax
   mov   es,ax      ; es same as ds

      mov   ax,09000h   ; segment for stack
   OFFSETHERE MOV SS AX...
   mov   ss,ax
   OFFSETHERE MOV SP 0XF800...
   mov   sp,0F800h   ; offset for stack

   sti         ; enable ints again
   push bp
   mov bp, sp

 inlinePM ;this work OK but if
 call setup_pmode ; I replace the anterior with this, dosent work.
.....
When assembled, the two calls to the macro OFFSETHERE print the following:
t1.asm:402: warning: (OFFSETHERE:3) [1535] MOV SS AX...
t1.asm:404: warning: (OFFSETHERE:3) [1537] MOV SP 0XF800...
I think above values will be of use for the next???

This is the error by bochs when I use the call setup_pmode:

Code: Select all

00000648900p[CPU  ] >>PANIC<< load_seg_reg: GDT: SS: index(1200*8+7) > limit(000027)
00000648900i[SYS  ] Last time is 1116777734
00000648900i[CPU  ] protected mode
00000648900i[CPU  ] CS.d_b = 16 bit
00000648900i[CPU  ] SS.d_b = 16 bit
00000648900i[CPU  ] | EAX=60009000  EBX=00000001  ECX=000b0001  EDX=00000000
00000648900i[CPU  ] | ESP=0000f7fe  EBP=0000f7fe  ESI=00000596  EDI=000000a0
00000648900i[CPU  ] | IOPL=0 NV UP DI PL NZ NA PE NC
00000648900i[CPU  ] | SEG selector     base    limit G D
00000648900i[CPU  ] | SEG sltr(index|ti|rpl)     base    limit G D
00000648900i[CPU  ] |  DS:0008( 0001| 0|  0) 00010000 0000ffff 0 0
00000648900i[CPU  ] |  ES:0008( 0001| 0|  0) 00010000 0000ffff 0 0
00000648900i[CPU  ] |  FS:0000( 0000| 0|  0) 00000000 0000ffff 0 0
00000648900i[CPU  ] |  GS:b800( 0000| 0|  0) 000b8000 0000ffff 0 0
00000648900i[CPU  ] |  SS:0018( 0003| 0|  0) 00010000 0000ffff 0 0
00000648900i[CPU  ] |  CS:0008( 0001| 0|  0) 00010000 0000ffff 0 0
00000648900i[CPU  ] | EIP=00000601 (000005ff)
00000648900i[CPU  ] | CR0=0x60000011 CR1=0x00000000 CR2=0x00000000
00000648900i[CPU  ] | CR3=0x00000000 CR4=0x00000000
00000648900i[     ] restoring default signal behavior
00000648900i[CTRL ] quit_sim called with exit code 1
Apart it work near to OK (not at all) if I move the last line of inlinePM macro (mov ss, ax) outside of the macro and I put it after call setup_pmode, some like

Code: Select all

call setup_pmode
mov ss, ax

Only a last question, in bochs... what mean
00000648900i[CPU ] | EIP=00000601 (000005ff)

Re:problem passing my code to a function.

Posted: Sun May 22, 2005 5:16 pm
by hgb
Tought I dont understand...

I have finded a way to handle this esceptional behaviour, perhaps explaining what I do will help you for exaplain it to me????????


I have changed only the line

Code: Select all

start2:
   cli         ; please no interupts
   mov   ax,cs
   mov   ds,ax
   mov   es,ax      ; es same as ds
   mov   ax,09000h   ; segment for stack THIS LINE
   mov   ss,ax
   mov   sp,0F800h   ; offset for stack
I have changed it to

Code: Select all

   mov   ax,01000h   ; segment for stack
   mov    ss, ax
And that handled the extrange behaviour of put or not put mov ss, ax inside or outside the function that setup protected mode....


Any toughts?? explanations???


By the way, the place for my stack is correct.. I will not overwrite something there???

Re:problem passing my code to a function.

Posted: Sun May 22, 2005 10:04 pm
by Brendan
Hi,

Code: Select all

 inlinePM ;this work OK but if
 call setup_pmode ; I replace the anterior with this, dosent work.
You can't call a function with a real mode stack and expect it to return correctly with a protected mode stack unless the real mode CS base is the same as the protected mode CS base, and you use a 16 bit protected mode segment for both CS and SS. In general it's rarely worth the hassle anyway, as it's unusual for this code to be called more than once (and often 32 bit protected mode is desired anyway). In your specific case, the function to enable protected mode is entered with SS base = 0x90000 and then it attempts a "ret" after SS base is changed to 0x10000, so it's won't find the correct address to return to.

In addition I would not recommend disabling NMI's (Non-Maskable Interrupts). Normally NMI's are used when there's a fatal hardware error (like faulty RAM) where the only sane option an OS has is to triple fault (unless a small error code can be displayed and the CPU halted, which isn't normally possible before protected mode exception handlers are ready). Disabling NMI's and forgetting to enable them again is even worse than disabling them for the switch to protected mode only. I guess what I'm saying is that Non-Maskable Interrupts should never be masked.

rea wrote:By the way, the place for my stack is correct.. I will not overwrite something there???
The real mode stack at 0x9000:0xF800 (or 0x0009f800) will overwrite the EBDA (Extended BIOS Data Area) on some computers, but using 0x10000:0x???? should be fine. You should also set also SP on entry (when you set SS) :).


Cheers,

Brendan

Re:problem passing my code to a function.

Posted: Mon May 23, 2005 8:57 am
by hgb
ok, I get it :).

The NMI is how they are used in the tutorial Im following. aparently in the next, they are enabled for Pmode... and the IRQ are remapped (If Im not wrong....).

Also I have collected some things about the BIOS. If you are able to check it.. because I dont know what is there :).

Re:problem passing my code to a function.

Posted: Mon May 23, 2005 10:07 am
by Brendan
Hi,
rea wrote:Also I have collected some things about the BIOS. If you are able to check it.. because I dont know what is there :).
Ok - if anyone else notices anything....


First, you won't find any 80386 or later computers with the "Possible Memory hole of 128 Kb" at 0x80000.

The "BIOS Extension" entry for 0x90000 is unlikely, and the size and location of the EBDA (listed from 0x9FC00 to 0x9FFFF) varies. I generally never use memory between 0x90000 and 0x9FFFF without asking the BIOS if there's anything there first - see Int 0x12 (http://www.ctyme.com/intr/rb-0598.htm). There's often more going on in a computer than any single person realizes, so it's best to be "safe". For example, long after you've switched to protected mode and you think the BIOS isn't being used, it might be doing all sorts of things behind your back using SMM (Laptops are the worst for this).

I'd recommend preserving the contents of the EBDA (if any) and the entire first 2 KB (or 4 KB as it's easier) of memory just in case you want to use virtual 8086, or APM to turn the computer off, or restore the BIOS/real mode to boot another OS after yours has finished, or anything else you might think of half way through writing the OS.

Also the ISA DMA controller channels 0 to 3 can happily transfer to/from memory below 16 MB (not 1 MB) - IBM added some DMA page registers when they added the second DMA controller and this 1 MB limit hasn't applied since then (would've been early 1980's). The 1 MB limit doesn't apply to any computer capable of 32 bit protected mode (but the 16 MB limit still does).

For memory above 1 MB the document doesn't mention anything about a possible memory hole at 16 MB - see your BIOS (often there's something to enable/disable this hole for "OS/2" compatibility). It also doesn't mention things like local APICs or IO APICs, PCI devices, video card LFBs, ACPI reserved areas, etc.

In general, for anything above 1 MB use int15 ax=0xe820, and if that doesn't work use int15 ax=0xe801, and if that doesn't work use int15 ah=0x88.

You can expect the area from 1 MB to 16 MB to contain valid/usable RAM if the computer has enough RAM installed, which makes it a good location to load kernels and things during boot :). For example, for my OS I specify that it requires a computer with at least 2 MB of RAM, and then use the area from 1 MB to 2 MB without doing any checks.


Cheers,

Brendan