flat assembler
Message board for the users of flat assembler.

Index > OS Construction > Cannot load GDT and go 32Bits

Author
Thread Post new topic Reply to topic
antoniovazquezblanco



Joined: 02 Dec 2010
Posts: 9
antoniovazquezblanco 02 Dec 2010, 21:38
I've started to write my own OS.

First of all my code is hosted on GitHub: https://github.com/firebirdysc/Firebird-OS

I've written a bootsector that loads a bootloader. My problem is that my bootloader can't load the GDT. If I use the same code in a separated file declaring ORG 7C00 it runs properly so I deduce that the problem resides in the value of the reisters but I'm lost. Can anybody review this code?

Thanks!
Post 02 Dec 2010, 21:38
View user's profile Send private message Visit poster's website Reply with quote
Tyler



Joined: 19 Nov 2009
Posts: 1216
Location: NC, USA
Tyler 03 Dec 2010, 00:31
Next time, post the code you want people to look at. It's not fun trying to track down a bug in someone else's code.(ei narrow ir down and post as little as is needed)

Why are you loading to 9ef00? I'm pretty sure that's not a good idea. IIRC, memory in that area is usually marked reserved. Why not make use the gap between the IVT and 7c00?

The structure goes
Code:
;====================================================================;
; Firebird OS Bootsector ;
; ;
; Simple bootsector written in assembler for Firebird OS ;
;====================================================================;

BITS 16
ORG 0

jmp bootsect_start ;Jump to the main code
nop

;-----------------------------------------------;
; DISK DESCRIPTION TABLE ;
;-----------------------------------------------;

OEM_ID db "FIREBIRD"
BytesPerSector dw 0x0200
SectorsPerCluster db 0x01
ReservedSectors dw 0x0001
TotalFATs db 0x02
MaxRootEntries dw 0x00E0
TotalSectorsSmall dw 0x0B40
MediaDescriptor db 0xF0
SectorsPerFAT dw 0x0009
SectorsPerTrack dw 0x0012
NumHeads dw 0x0002
HiddenSectors dd 0x00000000
TotalSectorsLarge dd 0x00000000
DriveNumber db 0x00
Flags db 0x00
Signature db 0x29
VolumeID dd 0xFFFFFFFF
VolumeLabel db "FIREBIRD OS"
SystemID db "FAT12 "


;-----------------------------------------------;
; MAIN CODE ;
;-----------------------------------------------;

bootsect_start:

mov ax, cs
mov ds, ax ;Set data segment to where we're loaded
mov es, ax

mov byte [bootdev], dl ;Save boot device number
;NOTE: A few early BIOSes are reported to improperly set DL

mov eax, 0 ;Needed for some older BIOSes

.read
mov ax, 9FE0h ;ES:BX = 9FE0:0000
mov es, ax ;
mov bx, 0 ;

mov ah, 2 ;Load disk data to ES:BX
mov al, 1 ;Load 1 sectors
mov ch, 0 ;Cylinder=0
mov cl, 2 ;Sector=2
mov dh, 0 ;Head=0
mov dl, [bootdev] ;Drive=bootdev

int 13h ;Read!
jnc .read_done ;Read went ok => continue

call reset_floppy ;ERROR => reset floppy
jnc .read ;Floppy reset OK => try again

mov si, disk_error
call print_string
jmp reboot ;Floppy reset error => reboot

.read_done
jmp 9FE0h:0000 ;Jump to the program


;-----------------------------------------------;
; DATA ;
;-----------------------------------------------;

disk_error db "[!] Bootsector: Error: Floppy error!", 0Dh, 0Ah, 0
reboot_str db "[+] Press any key to reboot...", 0Dh, 0Ah, 0
bootdev db 0 ;Boot device number


;-----------------------------------------------;
; FUNCTIONS ;
;-----------------------------------------------;

reboot: ;Reboots the machine
mov si, reboot_str
call print_string
mov ax, 0
int 16h ;Waits for keystroke
mov ax, 0
int 19h ;Reboot the system

print_string: ;Output string in SI to screen
pusha
mov ah, 0Eh ;int 10h teletype function
.repeat:
lodsb ;Get char from string
cmp al, 0
je .done ;If char is zero, end of string
int 10h ;Otherwise, print it
jmp short .repeat
.done:
popa
ret

reset_floppy: ;IN: [bootdev] = boot device; OUT: carry set on error
push ax
push dx
mov ax, 0
mov dl, byte [bootdev]
stc
int 13h
pop dx
pop ax
ret

;-----------------------------------------------;
; END OF FILE ;
;-----------------------------------------------;

times 510-($-$$) db 0 ;Pad remainder of boot sector with zeros
dw 0AA55h ;Boot signature
    

b/c bioses that check for jmp+nop usually expect the jmp to jump to the byte exactly after the disc description.
Post 03 Dec 2010, 00:31
View user's profile Send private message Reply with quote
antoniovazquezblanco



Joined: 02 Dec 2010
Posts: 9
antoniovazquezblanco 03 Dec 2010, 07:57
Humm I didn't really knew where to load my code. Where would you load it? In my repo there is a docs folder. This is a memory map. What errors did I commit?

Code:
Starting address    Ending address    Content
00000                 003FF               Interrupt Vector Table
00400                 004FF               BIOS Data Area
00500                 07BFF               FREE MEMORY!
07C00                 07DFF               Boot Sector
07E00                 9FBFF               FREE MEMORY!
9FC00                 9FDFF               Kernel
9FE00                 9FFFF                Boot Loader
A0000                 BFFFF               Video Memory
C0000                 C7FFF               Video BIOS
C8000                 EFFFF               BIOS Shadow Area
F0000                 FFFFF               System BIOS
    
Post 03 Dec 2010, 07:57
View user's profile Send private message Visit poster's website Reply with quote
edfed



Joined: 20 Feb 2006
Posts: 4353
Location: Now
edfed 03 Dec 2010, 16:53
you can simplify with this equation:
bootloader = bootsector
kernel = 1000h:0
Post 03 Dec 2010, 16:53
View user's profile Send private message Visit poster's website Reply with quote
antoniovazquezblanco



Joined: 02 Dec 2010
Posts: 9
antoniovazquezblanco 03 Dec 2010, 18:27
edfed wrote:
you can simplify with this equation:
bootloader = bootsector
kernel = 1000h:0


Bootloader + Bootsector > 512B... Too big to have a decent check system...
Post 03 Dec 2010, 18:27
View user's profile Send private message Visit poster's website Reply with quote
edfed



Joined: 20 Feb 2006
Posts: 4353
Location: Now
edfed 03 Dec 2010, 18:30
no need to check, if it happen to don't work, it just means there is a problem, and check for problems will not solve it not help to solve it.

for example, if your checker says, problem, unable to load kernel, it just means that you should first do a good loader, tested, and tested again, ones it works, it works.

you just have to load kernel sectors to a location and jump to (or call) it.
Post 03 Dec 2010, 18:30
View user's profile Send private message Visit poster's website Reply with quote
antoniovazquezblanco



Joined: 02 Dec 2010
Posts: 9
antoniovazquezblanco 03 Dec 2010, 19:05
edfed wrote:
no need to check, if it happen to don't work, it just means there is a problem, and check for problems will not solve it not help to solve it.

for example, if your checker says, problem, unable to load kernel, it just means that you should first do a good loader, tested, and tested again, ones it works, it works.

you just have to load kernel sectors to a location and jump to (or call) it.


Hummm. I can do everithing on the kernel Smile. Thanks, I'll start now!
Post 03 Dec 2010, 19:05
View user's profile Send private message Visit poster's website Reply with quote
antoniovazquezblanco



Joined: 02 Dec 2010
Posts: 9
antoniovazquezblanco 03 Dec 2010, 19:54
Still crashing...

Bootloader loads kernel in 1000h:0. Kernel starts and enables A20 gate. GDT is loaded but I can't switch to PM...

Please can anybody check kernel/kernel.asm file? Thanks!
Post 03 Dec 2010, 19:54
View user's profile Send private message Visit poster's website Reply with quote
ManOfSteel



Joined: 02 Feb 2005
Posts: 1154
ManOfSteel 03 Dec 2010, 20:28
For starters the GDT size (line 161) is wrong. It should be gdt_end-gdt-1. And by the way, the comment is wrong as your GDT has 3 descriptors, i.e. 24d/0x18 bytes.
Post 03 Dec 2010, 20:28
View user's profile Send private message Reply with quote
antoniovazquezblanco



Joined: 02 Dec 2010
Posts: 9
antoniovazquezblanco 03 Dec 2010, 21:48
ManOfSteel wrote:
For starters the GDT size (line 161) is wrong. It should be gdt_end-gdt-1. And by the way, the comment is wrong as your GDT has 3 descriptors, i.e. 24d/0x18 bytes.


Done. It doesn't work... do you see anything else? By the way, I cant understand your correction in my comment...
Post 03 Dec 2010, 21:48
View user's profile Send private message Visit poster's website Reply with quote
ManOfSteel



Joined: 02 Feb 2005
Posts: 1154
ManOfSteel 03 Dec 2010, 22:39
Okay, I took a longer look at your code. The problem is simple: the real-mode addressing is completely wrong.

First, load your kernel at a slightly lower address (0x9c0 for instance) so that the full offset is smaller than a word/64KB or else it won't even assemble the jump in the kernel at line 139.
Then, make sure you copy the GDT using valid addressing.
Now you can notice the protected mode works because it prints the green "S" at the top left corner.
I also set the GDT base at 0x500 like your comment at line 119 says.
Take a look at the diffs (bootsect.asm and kernel.asm respectively):
Code:
100c100
<       mov ax, 0x9c0       ;ES:BX = 1000:0000
---
>       mov ax, 1000h       ;ES:BX = 1000:0000
122c122
<       jmp 0x9c0:0000      ;Jump to the program
---
>       jmp 1000h:0000      ;Jump to the program
    

Code:
118,120c118,120
<       mov si, gdt+0x9c0*16                    ;start of GDT table into SI register
<       mov di, 0x500   ;locate GDT at 500h in memory
<       mov cx, gdt_end-gdt     ;size of the GDT (defined my fancy footwork)
---
>       mov si, gdt                     ;start of GDT table into SI register
>       mov di, [gdtbse]        ;locate GDT at 500h in memory
>       mov cx, [gdtsze]        ;size of the GDT (defined my fancy footwork)
139c139
<       jmp 08h:protected_mode+0x9c0*16
---
>       jmp 08h:protected_mode
151c151
<       mov word [0xb8000],'S '
---
> 
162c162
< gdtbse dd 0x500               ;where GDT is located at (bootloader_end+gdt)
---
> gdtbse dd 0xA0000 + gdt       ;where GDT is located at (bootloader_end+gdt)
    


~~~~

antoniovazquezblanco wrote:
By the way, I cant understand your correction in my comment...

Just look at your code. How long is a segment descriptor? dd*2 or dw*2+db*4 = 8 bytes, not 64. It ensues that, having 3 descriptors, your GDT is merely 8*3=24 bytes long, not 192.
Post 03 Dec 2010, 22:39
View user's profile Send private message Reply with quote
antoniovazquezblanco



Joined: 02 Dec 2010
Posts: 9
antoniovazquezblanco 03 Dec 2010, 23:03
Em... Feel so stupid.... emm THANKS! ^^. You're really cool! I really feel very pleased Smile. WORKED!
Post 03 Dec 2010, 23:03
View user's profile Send private message Visit poster's website Reply with quote
antoniovazquezblanco



Joined: 02 Dec 2010
Posts: 9
antoniovazquezblanco 05 Dec 2010, 17:45
As I followed your suggestions I consider the next question should be here.

I've created a function:
Code:
kernel_main()
{
}
    


In C that prints a string.

I've compiled both files with .o elf files as the result. I now want to link both. Can I link them or do I need to create a new bin file and call it?

Thanks!
Post 05 Dec 2010, 17:45
View user's profile Send private message Visit poster's website Reply with quote
Coty



Joined: 17 May 2010
Posts: 553
Location: &#9216;
Coty 05 Dec 2010, 18:05
You can link them... Here is a tut on how to link FASM and TCC...

Are you trying to link both and get a raw BINARY file? Is this even possible?

I hope you are not trying to link your boot sector and kernel together Shocked

_________________
http://codercat.org/
Post 05 Dec 2010, 18:05
View user's profile Send private message Send e-mail Visit poster's website Reply with quote
antoniovazquezblanco



Joined: 02 Dec 2010
Posts: 9
antoniovazquezblanco 05 Dec 2010, 19:27
Not bootsector +kernel but almost. Bootsector only loads a file that enables A20 and set GDT and jumps 32bits. That is 16Bit code wich I want to link to 32Bit code + 32Bit C code... Can I? Xd don't think that is possible, but you told me not to use a 2 stage bootloader so maybe I'm not right... xD
Post 05 Dec 2010, 19:27
View user's profile Send private message Visit poster's website Reply with quote
Display posts from previous:
Post new topic Reply to topic

Jump to:  


< Last Thread | Next Thread >
Forum Rules:
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum
You cannot attach files in this forum
You can download files in this forum


Copyright © 1999-2025, Tomasz Grysztar. Also on GitHub, YouTube.

Website powered by rwasa.