Getting into Protected Mode from GRUB

Question about which tools to use, bugs, the best way to implement a function, etc should go here. Don't forget to see if your question is answered in the wiki first! When in doubt post here.
Crazed123

Getting into Protected Mode from GRUB

Post by Crazed123 »

I've made a boot disk image and I'm attempting to load my OS in GRUB. However whenever I do I get the following output from Bochs.

Code: Select all

========================================================================
                       Bochs x86 Emulator 2.1.1
                           February 08, 2004
========================================================================
00000000000i[     ] reading configuration from .bochsrc
00000000000i[     ] .bochsrc: vga_update_interval seems awfully small!
00000000000i[     ] installing x module as the Bochs GUI
00000000000i[     ] Bochs x86 Emulator 2.1.1
00000000000i[     ]   February 08, 2004
00000000000i[     ] System configuration
00000000000i[     ]   processors: 1
00000000000i[     ]   A20 line support: yes
00000000000i[     ]   APIC support: no
00000000000i[     ] CPU configuration
00000000000i[     ]   level: 5
00000000000i[     ]   fpu support: yes
00000000000i[     ]   paging support: yes, tlb enabled: yes
00000000000i[     ]   mmx support: yes
00000000000i[     ]   sse support: no
00000000000i[     ]   v8086 mode support: yes
00000000000i[     ]   3dnow! support: no
00000000000i[     ]   PAE support: no
00000000000i[     ]   PGE support: no
00000000000i[     ]   PSE support: no
00000000000i[     ]   x86-64 support: no
00000000000i[     ]   SEP support: no
00000000000i[     ] Optimization configuration
00000000000i[     ]   Guest2HostTLB support: no
00000000000i[     ]   RepeatSpeedups support: no
00000000000i[     ]   Icache support: no
00000000000i[     ]   Host Asm support: yes
00000000000i[MEM0 ] allocated memory at 0xb78d0008. after alignment, vector=0xb78d1000
00000000000i[MEM0 ] 4.00MB
00000000000i[MEM0 ] rom at 0xf0000/65536 ('/usr/share/bochs/BIOS-bochs-latest')
00000000000i[MEM0 ] rom at 0xc0000/29664 ('/usr/share/bochs/VGABIOS-lgpl-latest')
00000000000i[CMOS ] Using local time for initial clock
00000000000i[CMOS ] Setting initial clock to: Fri Jan 28 22:36:53 2005 (time0=1106951813)
00000000000i[DMA  ] channel 4 used by cascade
00000000000i[DMA  ] channel 2 used by Floppy Drive
00000000000i[FDD  ] fd0: 'grub_disk.img' ro=0, h=2,t=80,spt=18
00000000000i[XGUI ] test_alloc_colors: 16 colors available out of 16 colors tried
00000000000i[XGUI ] font 8 wide x 16 high, display depth = 24
00000000000i[VGA  ] interval=30000
00000000000i[     ] init_mem of 'harddrv' plugin device by virtual method
00000000000i[     ] init_mem of 'keyboard' plugin device by virtual method
00000000000i[     ] init_mem of 'serial' plugin device by virtual method
00000000000i[     ] init_mem of 'parallel' plugin device by virtual method
00000000000i[     ] init_mem of 'extfpuirq' plugin device by virtual method
00000000000i[     ] init_dev of 'harddrv' plugin device by virtual method
00000000000i[HD   ] Boot device will be 'a'
00000000000i[HD   ] Floppy boot signature check is enabled
00000000000i[     ] init_dev of 'keyboard' plugin device by virtual method
00000000000i[KBD  ] will paste characters every 1000 keyboard ticks
00000000000i[     ] init_dev of 'serial' plugin device by virtual method
00000000000i[SER  ] com1 at 0x03f8 irq 4
00000000000i[     ] init_dev of 'parallel' plugin device by virtual method
00000000000i[PAR  ] parallel port 1 at 0x378 irq 7
00000000000i[     ] init_dev of 'extfpuirq' plugin device by virtual method
00000000000i[     ] reset of 'harddrv' plugin device by virtual method
00000000000i[     ] reset of 'keyboard' plugin device by virtual method
00000000000i[     ] reset of 'serial' plugin device by virtual method
00000000000i[     ] reset of 'parallel' plugin device by virtual method
00000000000i[     ] reset of 'extfpuirq' plugin device by virtual method
00000000000i[XGUI ] [x] Mouse off
00000004325i[BIOS ]  rombios.c,v 1.103.2.2 2004/02/02 22:39:22 cbothamy Exp $
00000015000e[VGA  ] character height = 1, skipping text update
00000030000e[VGA  ] character height = 1, skipping text update
00000045000e[VGA  ] character height = 1, skipping text update
00000060000e[VGA  ] character height = 1, skipping text update
00000075000e[VGA  ] character height = 1, skipping text update
00000090000e[VGA  ] character height = 1, skipping text update
00000105000e[VGA  ] character height = 1, skipping text update
00000120000e[VGA  ] character height = 1, skipping text update
00000135000e[VGA  ] character height = 1, skipping text update
00000150000e[VGA  ] character height = 1, skipping text update
00000165000e[VGA  ] character height = 1, skipping text update
00000180000e[VGA  ] character height = 1, skipping text update
00000195000e[VGA  ] character height = 1, skipping text update
00000210000e[VGA  ] character height = 1, skipping text update
Crazed123

Re:Getting into Protected Mode from GRUB

Post by Crazed123 »

Code: Select all

00000225000e[VGA  ] character height = 1, skipping text update
00000240000e[VGA  ] character height = 1, skipping text update
00000255000e[VGA  ] character height = 1, skipping text update
00000270000e[VGA  ] character height = 1, skipping text update
00000285000e[VGA  ] character height = 1, skipping text update
00000300000e[VGA  ] character height = 1, skipping text update
00000315000e[VGA  ] character height = 1, skipping text update
00000330000e[VGA  ] character height = 1, skipping text update
00000345000e[VGA  ] character height = 1, skipping text update
00000360000e[VGA  ] character height = 1, skipping text update
00000390000e[VGA  ] character height = 1, skipping text update
00000405000e[VGA  ] character height = 1, skipping text update
00000420000e[VGA  ] character height = 1, skipping text update
00000435000e[VGA  ] character height = 1, skipping text update
00000440061i[KBD  ] reset-disable command received
00000450000e[VGA  ] character height = 1, skipping text update
00000463354i[VBIOS] VGABios $Id: vgabios.c,v 1.38 2003/11/05 23:21:19 cbothamy Exp $
00000465000e[VGA  ] character height = 1, skipping text update
00000480000e[VGA  ] character height = 1, skipping text update
00000510000i[XGUI ] charmap update. Font Height is 16
00000525000i[XGUI ] charmap update. Font Height is 16
00000540000i[XGUI ] charmap update. Font Height is 16
00000555000i[XGUI ] charmap update. Font Height is 16
00000751525e[HD   ] device set to 0 which does not exist
00000751818e[HD   ] device set to 1 which does not exist
00001104914i[BIOS ] int15: Func 24h, subfunc 01h, A20 gate control not supported
00001110905i[BIOS ] int13_harddisk: function 41, unmapped device for DL=80
00001115403i[BIOS ] int13_harddisk: function 08, unmapped device for DL=80
00001119937i[BIOS ] *** int 15h function AX=00C0, BX=0000 not yet supported!
00001124417i[BIOS ] *** int 15h function AX=5300, BX=0000 not yet supported!
00001128832i[BIOS ] *** int 15h function AX=5304, BX=0000 not yet supported!
00032378855i[CPU  ] LOCK prefix unallowed (op1=0x53, attr=0x0, mod=0x0, nnn=0)
00032378855e[CPU  ] exception(): 3rd (13) exception with no resolution, shutdown status is 00h, resetting
And the virtual machine resets. It seems to have something to do with BIOS interrupts, but I don't know what to do about those because my own code doesn't call any! So either GRUB's calling bad interrupts and lock exceptions (whatever those are), or I'm making a bad jump to somewhere. Here's the code that starts my kernel:

Code: Select all

; startup
extern PASCALMAIN
global _start

KSTKSZ equ 16384

section .text
db 'ENGLISH',0
MBFLAGS equ 0x03
CHECKSUM equ -MBFLAGS-0x1BADB002

_mstart:
dd 0x1BADB002;//multiboot signature
dd MBFLAGS;//4kb page aligment for modules,memory info
dd CHECKSUM;//checksum=-(FLAGS+0x1BADB002)

_start:
        mov esp,_kernel_stack+KSTKSZ
        push eax
        push ebx
        call PASCALMAIN
        hlt
        
section .bss

_kernel_stack resb KSTKSZ
Can anyone tell me what I'm doing wrong? Thanks for the help!
AR

Re:Getting into Protected Mode from GRUB

Post by AR »

GRUB always fails those ints in Bochs. There is nothing particularly bad about those though.

LOCK is a prefix that locks the memory bus (to prevent other CPUs from accessing and changing memory until you're finished). I assume you haven't used it, the only way to execute a lock without having written some assembly using it is to jump to some place in memory filled with garbage. You might have linked it wrong or have a broken pointer somewhere.
Crazed123

Re:Getting into Protected Mode from GRUB

Post by Crazed123 »

So I've got a broken pointer somewhere? Thanks, come to think of it, it's probably the PASCALMAIN call. You're sure those interrupts aren't fatal?
AR

Re:Getting into Protected Mode from GRUB

Post by AR »

I've been booting my OS using GRUB for ages now, those 3 "not supported"s always occur, but GRUB works fine anyway.
Crazed123

Re:Getting into Protected Mode from GRUB

Post by Crazed123 »

Well, I don't think it's the PASCALMAIN pointer. The reason for the crasing seems to be that two of my variables are being treated as though they exist at NULL instead of actually being allocated. They exist in a unit that is in the main unit's uses clause, and I need to be able to set them. Why doesn't the compiler allocate them for me?

Code: Select all

neuro_main.o:     file format elf32-i386

Disassembly of section .text:

00000000 <PASCALMAIN>:
   0:   55                      push   %ebp
   1:   89 e5                   mov    %esp,%ebp
   3:   e8 fc ff ff ff          call   4 <PASCALMAIN+0x4>
   8:   c7 05 00 00 00 00 00    movl   $0x0,0x0
   f:   00 00 00 
  12:   c7 05 00 00 00 00 00    movl   $0x0,0x0
  19:   00 00 00 
  1c:   8f 05 00 00 00 00       popl   0x0
  22:   8f 05 00 00 00 00       popl   0x0
  28:   a1 00 00 00 00          mov    0x0,%eax
  2d:   3d 00 d2 ba 02          cmp    $0x2bad200,%eax
  32:   75 12                   jne    46 <PASCALMAIN+0x46>
  34:   eb 00                   jmp    36 <PASCALMAIN+0x36>
  36:   a1 00 00 00 00          mov    0x0,%eax
  3b:   e8 fc ff ff ff          call   3c <PASCALMAIN+0x3c>
  40:   84 c0                   test   %al,%al
  42:   74 02                   je     46 <PASCALMAIN+0x46>
  44:   eb 02                   jmp    48 <PASCALMAIN+0x48>
  46:   eb 0a                   jmp    52 <PASCALMAIN+0x52>
  48:   b8 70 00 00 00          mov    $0x70,%eax
  4d:   e8 fc ff ff ff          call   4e <PASCALMAIN+0x4e>
  52:   e8 fc ff ff ff          call   53 <PASCALMAIN+0x53>
  57:   c9                      leave  
  58:   c3                      ret    
  59:   8d 76 00                lea    0x0(%esi),%esi
I think the compiler is actually reading their current values, 0. Working on my assembly usage. How the hell do I get the thing to move to the address of the variable instead of treating the variable as a pointer?
Crazed123

Re:Getting into Protected Mode from GRUB

Post by Crazed123 »

Tested that theory, no idea what it is now. Anyone have any ideas as to what pointer is broken? Something seems to be jumping off or referencing high memory.
AR

Re:Getting into Protected Mode from GRUB

Post by AR »

Code: Select all

   3:  e8 fc ff ff ff          call  4 <PASCALMAIN+0x4>
  3b:  e8 fc ff ff ff          call  3c <PASCALMAIN+0x3c>
  4d:  e8 fc ff ff ff          call  4e <PASCALMAIN+0x4e>
  52:  e8 fc ff ff ff          call  53 <PASCALMAIN+0x53>
These lines look extremely weird. It's jumping into ITSELF. Notice how line 52 is calling 53, that would mean it's calling itself and executing 0xFC, I'm not sure what the binary representation of LOCK is but that could be what's causing it.

Try disassembling after linking to see how much of this sort of rubbish is in it.
Crazed123

Re:Getting into Protected Mode from GRUB

Post by Crazed123 »

Actually, most of that crap is gone after linking. Here's what is in there, starting from the entry point into the kernel.

Code: Select all

00100000 <.text>:
  100000:   45                      inc    %ebp
  100001:   4e                      dec    %esi
  100002:   47                      inc    %edi
  100003:   4c                      dec    %esp
  100004:   49                      dec    %ecx
  100005:   53                      push   %ebx
  100006:   48                      dec    %eax
  100007:   00 02                   add    %al,(%edx)
  100009:   b0 ad                   mov    $0xad,%al
  10000b:   1b 03                   sbb    (%ebx),%eax
  10000d:   00 00                   add    %al,(%eax)
  10000f:   00 fb                   add    %bh,%bl
  100011:   4f                      dec    %edi
  100012:   52                      push   %edx
  100013:   e4 bc                   in     $0xbc,%al
  100015:   98                      cwtl   
  100016:   ac                      lods   %ds:(%esi),%al
  100017:   11 00                   adc    %eax,(%eax)
  100019:   e8 f2 20 01 00          call   0x112110
  10001e:   f4                      hlt    
That last call instruction calls to this:

Code: Select all

112110:   55                      push   %ebp
  112111:   89 e5                   mov    %esp,%ebp
  112113:   e8 78 a6 ff ff          call   0x10c790
  112118:   89 1d 98 ac 11 00       mov    %ebx,0x11ac98
  11211e:   a3 9c ac 11 00          mov    %eax,0x11ac9c
  112123:   a1 9c ac 11 00          mov    0x11ac9c,%eax
  112128:   3d 02 b0 ad 2b          cmp    $0x2badb002,%eax
  11212d:   75 12                   jne    0x112141
  11212f:   eb 00                   jmp    0x112131
  112131:   a1 98 ac 11 00          mov    0x11ac98,%eax
  112136:   e8 e5 de fe ff          call   0x100020
  11213b:   84 c0                   test   %al,%al
  11213d:   74 02                   je     0x112141
  11213f:   eb 02                   jmp    0x112143
  112141:   eb 0a                   jmp    0x11214d
  112143:   b8 b4 53 11 00          mov    $0x1153b4,%eax
  112148:   e8 b7 e0 fe ff          call   0x100204
  11214d:   e8 ee a8 ff ff          call   0x10ca40
  112152:   c9                      leave  
  112153:   c3                      ret    
Which is quite recognisable as the beginning of my kernel code. And I think I found the bad pointer, I just don't know why it's bad. I checked and 0x100020 is the middle of an add instruction. I don't know why the call instruction goes there. The interactions of this compiler and assembler are really annoying me now.

And I've checked, the other call instructions are perfectly legitimate. Something's just wrong with this one.
AR

Re:Getting into Protected Mode from GRUB

Post by AR »

I don't know what that weird call is for or why it's there, you may have to check your link script and linker parameters. To be sure, I suggest that you use Bochs' Debugger to do a trace to see where it goes before exploding.
User avatar
Pype.Clicker
Member
Member
Posts: 5964
Joined: Wed Oct 18, 2006 2:31 am
Location: In a galaxy, far, far away
Contact:

Re:Getting into Protected Mode from GRUB

Post by Pype.Clicker »

Crazed123 wrote: So I've got a broken pointer somewhere? Thanks, come to think of it, it's probably the PASCALMAIN call. You're sure those interrupts aren't fatal?
According to Ralf Brown's Interrupt List

Int 15/AH=C0h - SYSTEM - GET CONFIGURATION (XT >1986/1/10,AT mdl 3x9,CONV,XT286,PS)
Int 15/AX=5300h - Advanced Power Management v1.0+ - INSTALLATION CHECK
Int 15/AX=5304h - Advanced Power Management v1.0+ - DISCONNECT INTERFACE

So i'd say they aren't fatal. GRUB is just checking which machine is there and BOCHS's BIOS warns you GRUB tries to make it do things that cannot be done (because they aren't there ;:)...
Crazed123

Re:Getting into Protected Mode from GRUB

Post by Crazed123 »

Alright, I've got a traced disassembly of everything that happens in Bochs once GRUB jumps into my kernel. The file's bit large, so I'm going to attach it to this post. There seems to be a lot of pointer manipulation which is then used to call more functions somehow. At the "final" level of recursion the program seems to do a "call edx" while the value of edx is 0x00000000. This leads it to the exception, which leads to triplefault.

I have no idea where all these functions have come from. I know I didn't code in recursing functions. Must be some obscure bug.
AR

Re:Getting into Protected Mode from GRUB

Post by AR »

You need to find the function at 0x10af18, "objdump --syms" should do it.

The function moves eax onto the stack, assumeably as a local variable, then moves it into eax...
It appears to be reading a global variable then calling it as a function pointer, the "objdump --syms" should also be able to tell you which variable is at 0x115530.

If you didn't write these functions then they may have been created by the compiler or were put in by the linker. Have you disabled the standard library(s) and are using a freestanding (or equivalent) environment?
Crazed123

Re:Getting into Protected Mode from GRUB

Post by Crazed123 »

I couldn't find 0x115530, but I did find the function at 0x10af18. It's some variant code, here's the listing.

Code: Select all

0010af18 g     F .text   00000016 SYSTEM_VARIANT_CLEAR$VARIANT
and

Code: Select all

0010af18 g     F .text   00000000 FPC_VARIANT_CLEAR
So I really just need to know how to turn variants off.
User avatar
Pype.Clicker
Member
Member
Posts: 5964
Joined: Wed Oct 18, 2006 2:31 am
Location: In a galaxy, far, far away
Contact:

Re:Getting into Protected Mode from GRUB

Post by Pype.Clicker »

imho, it looks like you're missing parts of the pascal runtime ...
Post Reply