Page 1 of 2

Errors while entering protected mode

Posted: Tue Oct 08, 2013 7:12 am
by yee1
Hey,
I have many problems while entering protected mode.
Here is code i wanted to enter protected mode:

Code: Select all

[BITS 16]           
[ORG 0x8000]     
CLI     
lgdt [GDTP]         
Mov eax,CR0           
Or eax,000000001h     
Mov CR0,eax   
Jmp 08h:CLEAR
[BITS 32]           
CLEAR:           
Mov ax,010h       
Mov ds,ax 

makelooping:
jmp makelooping

GDT: 
dq 00000000000000000h 
dw 0FFFFh 
dw 00000h
db 00h   
db 010011010b
db 011001111b
db 00h   
dw 0FFFFh 
dw 00000h
db 00h   
db 010010010b
db 011001111b
db 00h   
GDTP:                           
dw GDTP-GDT-1       
dd GDT
My bootloader loads kernel's sectors to memory starting by 0x8000, so 0x8000 is beging of kernel code.

Above code seems to be fine, but Bochs prints error like:

00014092315e[CPU0 ] fetch_raw_descriptor: GDT: index (f) 1 > limit (0)

What does it mean ? Why it can not enter protected mode ?

I am using nasm.

As you can see below (part cut from below's log) my GDT seems to be not loaded into, old segments are in:
00014092315i[CPU0 ] | SEG selector base limit G D
00014092315i[CPU0 ] | SEG sltr(index|ti|rpl) base limit G D
00014092315i[CPU0 ] | CS:0800( 0004| 0| 0) 00008000 0000ffff 0 0
00014092315i[CPU0 ] | DS:0800( 0005| 0| 0) 00008000 0000ffff 0 0
00014092315i[CPU0 ] | SS:0000( 0005| 0| 0) 00000000 0000ffff 0 0
00014092315i[CPU0 ] | ES:0800( 0005| 0| 0) 00008000 0000ffff 0 0
00014092315i[CPU0 ] | FS:0000( 0005| 0| 0) 00000000 0000ffff 0 0
00014092315i[CPU0 ] | GS:0000( 0005| 0| 0) 00000000 0000ffff 0 0
Below bochs output:
========================================================================
Bochs x86 Emulator 2.4.5
Build from CVS snapshot, on April 25, 2010
========================================================================
00000000000i[ ] reading configuration from bochsrc
00000000000i[ ] Ignoring magic break points
00000000000i[ ] installing x module as the Bochs GUI
00000000000i[ ] Bochs x86 Emulator 2.4.5
00000000000i[ ] Build from CVS snapshot, on April 25, 2010
00000000000i[ ] System configuration
00000000000i[ ] processors: 1 (cores=1, HT threads=1)
00000000000i[ ] A20 line support: yes
00000000000i[ ] CPU configuration
00000000000i[ ] level: 6
00000000000i[ ] SMP support: no
00000000000i[ ] APIC support: yes
00000000000i[ ] FPU support: yes
00000000000i[ ] MMX support: yes
00000000000i[ ] 3dnow! support: no
00000000000i[ ] SEP support: yes
00000000000i[ ] SSE support: sse2
00000000000i[ ] XSAVE support: no
00000000000i[ ] AES support: no
00000000000i[ ] MOVBE support: no
00000000000i[ ] x86-64 support: no
00000000000i[ ] MWAIT support: no
00000000000i[ ] VMX support: no
00000000000i[ ] Optimization configuration
00000000000i[ ] RepeatSpeedups support: no
00000000000i[ ] Trace cache support: no
00000000000i[ ] Fast function calls: no
00000000000i[ ] Devices configuration
00000000000i[ ] ACPI support: no
00000000000i[ ] NE2000 support: no
00000000000i[ ] PCI support: no, enabled=no
00000000000i[ ] SB16 support: no
00000000000i[ ] USB support: no
00000000000i[ ] VGA extension support: vbe
00000000000i[MEM0 ] allocated memory at 0x7f5e6afd0010. after alignment, vector=0x7f5e6afd1000
00000000000i[MEM0 ] 32.00MB
00000000000i[MEM0 ] mem block size = 0x00100000, blocks=32
00000000000i[MEM0 ] rom at 0xfffe0000/131072 ('/usr/local/share/bochs/BIOS-bochs-latest')
00000000000i[MEM0 ] rom at 0xc0000/40448 ('/usr/local/share/bochs/VGABIOS-lgpl-latest')
00000000000i[CMOS ] Using local time for initial clock
00000000000i[CMOS ] Setting initial clock to: Tue Oct 8 15:06:27 2013 (time0=1381237587)
00000000000i[DMA ] channel 4 used by cascade
00000000000i[DMA ] channel 2 used by Floppy Drive
00000000000i[FDD ] tried to open 'im.IMA' read/write: Permission denied
00000000000i[FDD ] fd0: 'im.IMA' ro=1, h=2,t=80,spt=18
00000000000i[VGA ] interval=50000
00000000000i[MEM0 ] Register memory access handlers: 0x000a0000 - 0x000bffff
00000000000i[XGUI ] test_alloc_colors: 16 colors available out of 16 colors tried
00000000000i[XGUI ] font 8 wide x 16 high, display depth = 24

(.:4925): Gtk-CRITICAL **: IA__gtk_widget_show: assertion `GTK_IS_WIDGET (widget)' failed
00000000000i[MEM0 ] Register memory access handlers: 0xe0000000 - 0xe0ffffff
00000000000i[VGA ] VBE Bochs Display Extension Enabled
00000000000i[ ] init_dev of 'unmapped' plugin device by virtual method
00000000000i[ ] init_dev of 'biosdev' plugin device by virtual method
00000000000i[ ] init_dev of 'speaker' plugin device by virtual method
00000000000i[SPEAK] Failed to open /dev/console: No such file or directory
00000000000i[SPEAK] Deactivating beep on console
00000000000i[ ] init_dev of 'extfpuirq' plugin device by virtual method
00000000000i[ ] init_dev of 'iodebug' plugin device by virtual method
00000000000i[ ] init_dev of 'ioapic' plugin device by virtual method
00000000000i[IOAP ] initializing I/O APIC
00000000000i[MEM0 ] Register memory access handlers: 0xfec00000 - 0xfec00fff
00000000000i[ ] init_dev of 'keyboard' plugin device by virtual method
00000000000i[KBD ] will paste characters every 1000 keyboard ticks
00000000000i[ ] init_dev of 'harddrv' plugin device by virtual method
00000000000i[HD ] Using boot sequence floppy, none, none
00000000000i[HD ] Floppy boot signature check is enabled
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 0x0378 irq 7
00000000000i[ ] register state of 'unmapped' plugin device by virtual method
00000000000i[ ] register state of 'biosdev' plugin device by virtual method
00000000000i[ ] register state of 'speaker' plugin device by virtual method
00000000000i[ ] register state of 'extfpuirq' plugin device by virtual method
00000000000i[ ] register state of 'iodebug' plugin device by virtual method
00000000000i[ ] register state of 'ioapic' plugin device by virtual method
00000000000i[ ] register state of 'keyboard' plugin device by virtual method
00000000000i[ ] register state of 'harddrv' plugin device by virtual method
00000000000i[ ] register state of 'serial' plugin device by virtual method
00000000000i[ ] register state of 'parallel' plugin device by virtual method
00000000000i[SYS ] bx_pc_system_c::Reset(HARDWARE) called
00000000000i[CPU0 ] cpu hardware reset
00000000000i[APIC0] allocate APIC id=0 (MMIO enabled) to 0xfee00000
00000000000i[CPU0 ] CPUID[0x00000000]: 00000003 756e6547 6c65746e 49656e69
00000000000i[CPU0 ] CPUID[0x00000001]: 00000f00 00000800 00000000 078bfbff
00000000000i[CPU0 ] CPUID[0x00000002]: 00410601 00000000 00000000 00000000
00000000000i[CPU0 ] CPUID[0x00000003]: 00000000 00000000 00000000 00000000
00000000000i[CPU0 ] CPUID[0x00000004]: 00000000 00000000 00000000 00000000
00000000000i[CPU0 ] CPUID[0x80000000]: 80000004 00000000 00000000 00000000
00000000000i[CPU0 ] CPUID[0x80000001]: 00000000 00000000 00000000 00000000
00000000000i[CPU0 ] CPUID[0x80000002]: 20202020 20202020 20202020 6e492020
00000000000i[CPU0 ] CPUID[0x80000003]: 286c6574 50202952 69746e65 52286d75
00000000000i[CPU0 ] CPUID[0x80000004]: 20342029 20555043 20202020 00202020
00000000000i[ ] reset of 'unmapped' plugin device by virtual method
00000000000i[ ] reset of 'biosdev' plugin device by virtual method
00000000000i[ ] reset of 'speaker' plugin device by virtual method
00000000000i[ ] reset of 'extfpuirq' plugin device by virtual method
00000000000i[ ] reset of 'iodebug' plugin device by virtual method
00000000000i[ ] reset of 'ioapic' plugin device by virtual method
00000000000i[ ] reset of 'keyboard' plugin device by virtual method
00000000000i[ ] reset of 'harddrv' plugin device by virtual method
00000000000i[ ] reset of 'serial' plugin device by virtual method
00000000000i[ ] reset of 'parallel' plugin device by virtual method
00000000000i[XGUI ] [x] Mouse off
00000003305i[BIOS ] $Revision: 1.247 $ $Date: 2010/04/04 19:33:50 $
00000318057i[KBD ] reset-disable command received
00000444815i[VBIOS] VGABios $Id: vgabios.c,v 1.69 2009/04/07 18:18:20 vruppert Exp $
00000444886i[VGA ] VBE known Display Interface b0c0
00000444918i[VGA ] VBE known Display Interface b0c5
00000447843i[VBIOS] VBE Bios $Id: vbe.c,v 1.62 2009/01/25 15:46:25 vruppert Exp $
00000600000i[XGUI ] charmap update. Font Height is 16
00000760532i[BIOS ] Starting rombios32
00000761029i[BIOS ] Shutdown flag 0
00000761710i[BIOS ] ram_size=0x02000000
00000762188i[BIOS ] ram_end=32MB
00000802748i[BIOS ] Found 1 cpu(s)
00000822017i[BIOS ] bios_table_addr: 0x000fbc18 end=0x000fcc00
00000834694i[BIOS ] bios_table_cur_addr: 0x000fbc18
00012943038i[BIOS ] Booting from 0000:7c00
00014092315e[CPU0 ] fetch_raw_descriptor: GDT: index (f) 1 > limit (0)
00014092315e[CPU0 ] interrupt(): gate descriptor is not valid sys seg (vector=0x0d)
00014092315e[CPU0 ] interrupt(): gate descriptor is not valid sys seg (vector=0x08)
00014092315i[CPU0 ] CPU is in protected mode (active)
00014092315i[CPU0 ] CS.d_b = 16 bit
00014092315i[CPU0 ] SS.d_b = 16 bit
00014092315i[CPU0 ] | EAX=60000011 EBX=00000007 ECX=00000000 EDX=00000022
00014092315i[CPU0 ] | ESP=0000ffd4 EBP=00000000 ESI=000e013f EDI=0000009b
00014092315i[CPU0 ] | IOPL=0 id vip vif ac vm RF nt of df if tf sf zf af PF cf
00014092315i[CPU0 ] | SEG selector base limit G D
00014092315i[CPU0 ] | SEG sltr(index|ti|rpl) base limit G D
00014092315i[CPU0 ] | CS:0800( 0004| 0| 0) 00008000 0000ffff 0 0
00014092315i[CPU0 ] | DS:0800( 0005| 0| 0) 00008000 0000ffff 0 0
00014092315i[CPU0 ] | SS:0000( 0005| 0| 0) 00000000 0000ffff 0 0
00014092315i[CPU0 ] | ES:0800( 0005| 0| 0) 00008000 0000ffff 0 0
00014092315i[CPU0 ] | FS:0000( 0005| 0| 0) 00000000 0000ffff 0 0
00014092315i[CPU0 ] | GS:0000( 0005| 0| 0) 00000000 0000ffff 0 0
00014092315i[CPU0 ] | EIP=00000014 (00000014)
00014092315i[CPU0 ] | CR0=0x60000011 CR2=0x00000000
00014092315i[CPU0 ] | CR3=0x00000000 CR4=0x00000000
00014092315e[CPU0 ] exception(): 3rd (13) exception with no resolution, shutdown status is 00h, resetting
00014092315i[SYS ] bx_pc_system_c::Reset(HARDWARE) called
00014092315i[CPU0 ] cpu hardware reset
00014092315i[APIC0] allocate APIC id=0 (MMIO enabled) to 0xfee00000
00014092315i[CPU0 ] CPUID[0x00000000]: 00000003 756e6547 6c65746e 49656e69
00014092315i[CPU0 ] CPUID[0x00000001]: 00000f00 00000800 00000000 078bfbff
00014092315i[CPU0 ] CPUID[0x00000002]: 00410601 00000000 00000000 00000000
00014092315i[CPU0 ] CPUID[0x00000003]: 00000000 00000000 00000000 00000000
00014092315i[CPU0 ] CPUID[0x00000004]: 00000000 00000000 00000000 00000000
00014092315i[CPU0 ] CPUID[0x80000000]: 80000004 00000000 00000000 00000000
00014092315i[CPU0 ] CPUID[0x80000001]: 00000000 00000000 00000000 00000000
00014092315i[CPU0 ] CPUID[0x80000002]: 20202020 20202020 20202020 6e492020
00014092315i[CPU0 ] CPUID[0x80000003]: 286c6574 50202952 69746e65 52286d75
00014092315i[CPU0 ] CPUID[0x80000004]: 20342029 20555043 20202020 00202020
00014092315i[ ] reset of 'unmapped' plugin device by virtual method
00014092315i[ ] reset of 'biosdev' plugin device by virtual method
00014092315i[ ] reset of 'speaker' plugin device by virtual method
00014092315i[ ] reset of 'extfpuirq' plugin device by virtual method
00014092315i[ ] reset of 'iodebug' plugin device by virtual method
00014092315i[ ] reset of 'ioapic' plugin device by virtual method
00014092315i[ ] reset of 'keyboard' plugin device by virtual method
00014092315i[ ] reset of 'harddrv' plugin device by virtual method
00014092315i[ ] reset of 'serial' plugin device by virtual method
00014092315i[ ] reset of 'parallel' plugin device by virtual method

Re: Errors while entering protected mode

Posted: Tue Oct 08, 2013 7:28 am
by bigbob
Your GDT looks good. It's not easy to find the bug. For example I can't see your stack.
It would be much faster to check the Brokenthorn os-tutorials:
http://www.brokenthorn.com/Resources/OSDevIndex.html

I followed that and I have never had problems with entering PM.
Its code is well organized, easy to understand.

Re: Errors while entering protected mode

Posted: Tue Oct 08, 2013 7:50 am
by yee1
bigbob wrote:Your GDT looks good. It's not easy to find the bug. For example I can't see your stack.
It would be much faster to check the Brokenthorn os-tutorials:
http://www.brokenthorn.com/Resources/OSDevIndex.html

I followed that and I have never had problems with entering PM.
Its code is well organized, easy to understand.
Well I have just tested code sample from here http://www.brokenthorn.com/Resources/OSDev8.html

Code: Select all

;*************************************************
;	Gdt.inc
;		-GDT Routines
;
;	OS Development Series
;*************************************************
 
%ifndef __GDT_INC_67343546FDCC56AAB872_INCLUDED__
%define __GDT_INC_67343546FDCC56AAB872_INCLUDED__
 
bits	16
 
;*******************************************
; InstallGDT()
;	- Install our GDT
;*******************************************
 
InstallGDT:
 
	cli				; clear interrupts
	pusha				; save registers
	lgdt 	[toc]			; load GDT into GDTR
	sti				; enable interrupts
	popa				; restore registers
	ret				; All done!
 
;*******************************************
; Global Descriptor Table (GDT)
;*******************************************
 
gdt_data: 
	dd 0 				; null descriptor
	dd 0 
 
; gdt code:				; code descriptor
	dw 0FFFFh 			; limit low
	dw 0 				; base low
	db 0 				; base middle
	db 10011010b 			; access
	db 11001111b 			; granularity
	db 0 				; base high
 
; gdt data:				; data descriptor
	dw 0FFFFh 			; limit low (Same as code)
	dw 0 				; base low
	db 0 				; base middle
	db 10010010b 			; access
	db 11001111b 			; granularity
	db 0				; base high
 
end_of_gdt:
toc: 
	dw end_of_gdt - gdt_data - 1 	; limit (Size of GDT)
	dd gdt_data 			; base of GDT
 
 
%endif ;__GDT_INC_67343546FDCC56AAB872_INCLUDED__
And it's same like mine code for gdt.
Added far jmp for 8h selector and still not working.

Could you posibble to test these codes with your bochs configuration ? My config is default so i really dont know what may be wrong. I am using 2.4.5 version. Thank you.
I have already wasted ~2 weeks for it and it's still now working, tested codes found at internet and at books, well all of them are mostly the same, well there should be no magic in entering PM but its not working at mine.

Re: Errors while entering protected mode

Posted: Tue Oct 08, 2013 8:05 am
by bigbob
It's the same as mine. The problem is somewhere else. It makes no sense to test it :)
My OS is here:
https://sites.google.com/site/forthoperatingsystem/
The Bochs-config can be found in the zip.
The GDT-related code is in gdt.inc and in loader.asm gdt_init gets called and we enter PM at EnterStage3.
In kernel.asm if you throw out the FORTH-related stuff (from "Coldstart: call forth_init" or even before that), then you will have a working BrokenThorn(BT)-tutorial. The kernel will be copied to 0x100000 (1Mb).
Of course, you will have the same result if you follow the BrokenThorn tutorial step-by step.

EDIT: the loop that reads the Keys is in the Forth-related code. That you can get from the BT-tutorials.

Re: Errors while entering protected mode

Posted: Tue Oct 08, 2013 12:46 pm
by jnc100
There is a discrepancy between the address your code is linked at and that which it is run from.

According to the bochs output, CS, DS and ES are 0x0800 at the time of the error (pointing to a segment starting at address 0x8000), and IP starts at 0 (i.e. I presume you do something like jmp 0x800:0 to get here in your bootloader). Contrast this with the fact that the kernel expects to be running with IP starting at 0x8000 (the ORG line). This will be fine as long as you only use relative addresses but when you start using absolute ones then you run into issues.

You probably want to jmp to 0:0x8000 (and set DS and ES to 0) in your bootloader instead.

By the way, this is a problem that can be easily investigated further with the bochs integrated debugger - set a breakpoint at physical address 0x8000 and single step through, inspecting your gdt to ensure it is what you expect it to be.

Regards,
John.

Re: Errors while entering protected mode

Posted: Tue Oct 08, 2013 2:18 pm
by yee1
jnc100 wrote:There is a discrepancy between the address your code is linked at and that which it is run from.

According to the bochs output, CS, DS and ES are 0x0800 at the time of the error (pointing to a segment starting at address 0x8000), and IP starts at 0 (i.e. I presume you do something like jmp 0x800:0 to get here in your bootloader). Contrast this with the fact that the kernel expects to be running with IP starting at 0x8000 (the ORG line). This will be fine as long as you only use relative addresses but when you start using absolute ones then you run into issues.

You probably want to jmp to 0:0x8000 (and set DS and ES to 0) in your bootloader instead.

By the way, this is a problem that can be easily investigated further with the bochs integrated debugger - set a breakpoint at physical address 0x8000 and single step through, inspecting your gdt to ensure it is what you expect it to be.

Regards,
John.
Lawl... bootloader was a bug you were right i was doing far jmp to 0x800:0, thank you.

One more question about your post:
You probably want to jmp to 0:0x8000 (and set DS and ES to 0) in your bootloader instead.
Why to set DS=ES=0 ?

After jumping to 0x8000 i set

Code: Select all

[bits 16]
[org 0x8000]

mov ax, cs
mov ds, ax
...
and its working (still in real mode when doing it).


So why ?

Re: Errors while entering protected mode

Posted: Tue Oct 08, 2013 2:39 pm
by jnc100
yee1 wrote:Why to set DS=ES=0 ?
Whilst its not essential for the code you've posted, if you are using the tiny memory mode (which you are as your data and code are expecting to be within the same segment) then CS should equal DS and ES as some memory load/store instructions imply DS/ES as the segments used - my advice was simply to avoid problems should you expand this kernel somewhat.
After jumping to 0x8000 i set

Code: Select all

[bits 16]
[org 0x8000]

mov ax, cs
mov ds, ax
...
This does set DS to 0 as it you do a jmp 0:0x8000 before this and therefore CS will be 0.

Regards,
John.

Re: Errors while entering protected mode

Posted: Tue Oct 08, 2013 2:49 pm
by jnc100
yee1 wrote:

Code: Select all

; *******************************************
; InstallGDT()
;	- Install our GDT
;*******************************************
 
InstallGDT:
 
	cli				; clear interrupts
	pusha				; save registers
	lgdt 	[toc]			; load GDT into GDTR
	sti				; enable interrupts
	popa				; restore registers
	ret				; All done!
 
Incidentally, this code from the BrokenThorn tutorials is, well, broken. It runs the risk of enabling interrupts when there is not a valid IDT present. I think the idea behind it was to attempt to restore the interrupt flag (IF) to whatever it was at the start of the function, so the code could be called from real mode when preparing to enter protected mode but also from within protected mode if someone wished to move the GDT (e.g. from that setup by a second stage bootloader to the actual kernel one or moving to a higher half kernel etc). A better implementation would be:

Code: Select all

InstallGDT:
    pushf
    cli
    lgdt [toc]
    popf
    ret
and anyway, you should call cli right at the start of your kernel until you're ready to handle interrupts.

Regards,
John.

Re: Errors while entering protected mode

Posted: Tue Oct 08, 2013 5:09 pm
by yee1
jnc100 wrote:
yee1 wrote:Why to set DS=ES=0 ?
Whilst its not essential for the code you've posted, if you are using the tiny memory mode (which you are as your data and code are expecting to be within the same segment) then CS should equal DS and ES as some memory load/store instructions imply DS/ES as the segments used - my advice was simply to avoid problems should you expand this kernel somewhat.
After jumping to 0x8000 i set

Code: Select all

[bits 16]
[org 0x8000]

mov ax, cs
mov ds, ax
...
This does set DS to 0 as it you do a jmp 0:0x8000 before this and therefore CS will be 0.

Regards,
John.
Ok, thank you. I have one more misunderstand about GDT, hope you will help me ;)
So...
Segment size is 20 bits value. When G=1 (in my case) then it's 4 kB, so max memory is 4GB.
My kernel is loaded at 0x8000 and it takes let's say 6kB, so my segment size needs to be at least
0x8000 = 32 768 B / 1024 = 32kB
32 + 6 = 38 kB
So my segment size needs to be at least (i know atm its tiny model for 4gb, but its as example) 38 and 38 should be put into gdt's descriptor record. Is it correct ?


Another question :D
What about 8000h address ? As far as i have read it's used to write at screen (video memory, right ?) but I have already used memory space that begins at 8000h for my kernel. How is it working ? How to deal with it ?


Really thank you for your help!

Re: Errors while entering protected mode

Posted: Tue Oct 08, 2013 6:10 pm
by kfreezen
Really, if you're entering protected mode, the best would be to set the segment descriptors' bases to 0x00000 and the limits to 0xFFFFF. That way you have complete access to the entire 4GB of your address space without having to swap segments around. I believe, however, if you do it that way, you'll need an [org 0x8000] directive in your assembly file so that when you switch to protected mode and do a far jump to your 32-bit code, your data and code will all point to the correct addresses.

Also, it isn't address 0x8000 that is used for video, it is address 0xB8000.

Re: Errors while entering protected mode

Posted: Wed Oct 09, 2013 1:37 pm
by yee1
kfreezen wrote:Really, if you're entering protected mode, the best would be to set the segment descriptors' bases to 0x00000 and the limits to 0xFFFFF. That way you have complete access to the entire 4GB of your address space without having to swap segments around. I believe, however, if you do it that way, you'll need an [org 0x8000] directive in your assembly file so that when you switch to protected mode and do a far jump to your 32-bit code, your data and code will all point to the correct addresses.

Also, it isn't address 0x8000 that is used for video, it is address 0xB8000.

So memory space beginning from 0xB8000 isn't useable for my kernel neither I want to print characters ?

What if I want to load many tasks and it will reach 0xB8000 address and further like 0xb8001 and so on ? I will print some characters at screen, right ? But what about my tasks (TSS) ?

Are there any other memory space address ranges like 0xb8000 that I should "take care? ?

You said to keep tiny model of memory (one 4 gb segment) and what about memory protection of tasks and privilage levels ?

Re: Errors while entering protected mode

Posted: Wed Oct 09, 2013 7:45 pm
by kfreezen
One 4GB segment is not "tiny" memory model, but "flat" memory model. I would think you're better off having a stub that reloads the 32-bit code to 0x100000 (1 MB) or some other arbitrary address above what real mode can access. That way you wouldn't have the danger of running into your video memory in the event that your kernel is ever over 606KiB (0x97C00 bytes) in size.

To your worrying about running into 0xB8000 with many tasks: If you have a Memory management system and Paging implemented, you can just identity map everything under 0x100000 as well as everything in your kernel when you initialize your memory manager. Then you won't have to worry about accidentally writing something to 0xB8000 and overwriting your video memory (unless, of course, you have a rogue function).

When you load tasks, you would be able to allocate some free physical pages to an arbitrary address in either your kernel page directory or a new page directory. Be aware that if you want to run tasks in your kernel address space (i.e. to run drivers), you will have to build each task for a different address and load it there, or you could implement some sort of relocation (see http://wiki.osdev.org/ELF#Relocation).

EDIT: Changed 0xB0000 to 0x97C00 and various other things.

Re: Errors while entering protected mode

Posted: Thu Oct 10, 2013 1:27 am
by bigbob
I am not sure, if you asked about this but I copied it from BrokenThorn tutorial 7:

x86 Real Mode Memory Map
General x86 Real Mode Memory Map:

0x00000000 - 0x000003FF - Real Mode Interrupt Vector Table
0x00000400 - 0x000004FF - BIOS Data Area
0x00000500 - 0x00007BFF - Unused
0x00007C00 - 0x00007DFF - Our Bootloader
0x00007E00 - 0x0009FFFF - Unused
0x000A0000 - 0x000BFFFF - Video RAM (VRAM) Memory
0x000B0000 - 0x000B7777 - Monochrome Video Memory
0x000B8000 - 0x000BFFFF - Color Video Memory
0x000C0000 - 0x000C7FFF - Video ROM BIOS
0x000C8000 - 0x000EFFFF - BIOS Shadow Area
0x000F0000 - 0x000FFFFF - System BIOS

You can for sure use the "Unused" memory which is 640Kb.

Here you can see that there is a 1Mb "hole" at 15Mb(when in protected mode) (Memory Map, osdev-wiki):
http://wiki.osdev.org/Memory_Map_(x86)

How to detect memory is also a good read:
http://wiki.osdev.org/Detecting_Memory_%28x86%29

Re: Errors while entering protected mode

Posted: Thu Oct 10, 2013 8:23 am
by Combuster
0x00007E00 - 0x0009FFFF - Unused
should be 07E00 - 7FFFF - unused; the EBDA starts somewhere in the space after which makes this part not guaranteed safe..

Re: Errors while entering protected mode

Posted: Thu Oct 10, 2013 12:45 pm
by yee1
I don't understand some things... why only 1 MB ? I want to run tasks in protected mode (of course) where 4 GB of memory available. How linux/windows is working in 1 MB, well I am sure it's not so how is linux/windows possible to have 4 GB of memory and me only 1 MB ? :P Please explain me it, thank you.

All of you were saying about real mode. I want to have my OS running in protected mode where as far as I know there is also 0xB8000 address available for video memory, right ?