flat assembler
Message board for the users of flat assembler.
Index
> OS Construction > Triple fault on far jump after setting pmode bit |
Author |
|
Daedalus 09 Mar 2008, 20:50
Oh, forgot to mention. Previous code works without doing anything to A20 gate. Intel doesn't even mention it in System Engineering 3A for switching to protected mode.
Here's the previous code: bootloader.asm Code: ;BOOTLOADER format binary as 'img' use16 org 0x7c00 include 'diskHeader.asm' bootcode: ;Creating stack, disabling interrupts to not be interrupted and triple fault the whole thing. cli mov ax, 0x9000 mov ss, ax mov ax, 0xFFFF mov sp, ax ;********** Setup a GDT & IDT ************************************ include 'gdtcreate.asm' pop di lidt [es:di] ;Let the CPU know where the IDT (pointer) is pop di lgdt [es:di] ;Let the CPU know where the GDT (pointer) is ;********** Set the first bit of CR0 to 1 ********** mov eax, cr0 or eax, 1 mov cr0, eax ;********** FAR JMP to protected mode ********** jmp 0x08:ProtectedMode ;Far jump to protected mode (0x08 referers to item 8 in the GDT, that's the CODE segment) include 'gdt.inc.asm' ProtectedMode: ;****************************** We are now in PMode ****************************** use32 mov ax, 8*2 ; item 2 in GDT is the DATA segment . . . mov ds, ax mov ax, 8*3 ; item 3 in GDT is the STACK segment . . . mov ss, ax mov ecx, 0x08000 mov edi, 0xB8000 .loop1: mov [ds:edi], byte 'A' inc edi dec ecx mov [ds:edi], byte 0x07 inc edi dec ecx jnz .loop1 .end: jmp .end times 510-($-$$) db 0 dw 0xAA55 gdtcreate.asm Code: ;Create GDT mov ax, 0x0000 mov es, ax mov di, 0x1000 ;Making a GDT POINTER: ; bx base low (word) ; dx base high (word) ; cx limit (word) push di mov bx, 0x1006 ;base low (word) mov dx, 0 ;base high (word) mov cx, 5*8-1 ;limit (word) = count(entries) * sizeof(entry) - 1 call gdtWritePointer ;Write GDT POINTER ;Making the GDT itself, first the dummy entry. mov bx, 0 ;base low mov dx, 0 ;base high mov cx, 0 ;limit mov al, 0 ;access mov ah, 0 ;gran call gdtWriteEntry mov bx, 0 ;base low (word) mov dx, 0 ;base high (word) mov cx, 0xFfFF ;limit low (word) mov ah, 0x0F + 16*1100b ;limit high (nibble) + gran (nibble) mov al, 0x9A ;access (byte) call gdtWriteEntry ;Write CODE segment (covers all memory) mov bx, 0 ;base low (word) mov dx, 0 ;base high (word) mov cx, 0xFFFF ;limit low (word) mov ah, 0x0F + 16*1100b ;limit high (nibble) + gran (nibble) mov al, 0x92 ;access (byte) call gdtWriteEntry ;Write DATA segment (covers all memory) mov bx, 0x0000 ;base low (word) base = 90000 mov dx, 0x0009 ;base high (word) mov cx, 0xFFFF ;limit low (word) limit = A0000 mov ah, 0x00 + 16*0100b ;limit high (nibble) + gran (nibble) mov al, 0x92 ;access (byte) call gdtWriteEntry ;Write STACK segment (0x9000:0 - 0x9000:0xFFFF) ;Making a IDT POINTER: ; bx base low (word) ; dx base high (word) ; cx limit (word) push di mov bx, di add bx, 6 ;BX = DX + 6, put the IDT directly after the IDTpointer mov dx, 0 ;base high (word) mov cx, 0 ;limit (word) = count(entries) * sizeof(entry) - 1 call idtWritePointer ;Write IDT POINTER gdt.inc.asm Code: ; Filename: gdt.inc.asm ; GDT functions ; gdtwriteentry Write GDT entry at es:di ; bx base low (word) ; dx base high (word) ; cx limit low (word) ; ah limit high (nibble) + gran (nibble) 0xLG l=limit g=gran ; al access (byte) gdtWriteEntry: mov [es:di], cx ;limit add di, 2 mov [es:di], bx ;base low add di, 2 mov [es:di], dl ;base middle inc di mov [es:di], al ;access inc di mov [es:di], ah ;gran inc di mov [es:di], dh;base high inc di .return: ret ; gdt/idtwritepointer Write GDT/IDT POINTER entry at es:di ; bx base low (word) ; dx base high (word) ; cx limit (word) gdtWritePointer: idtWritePointer: mov [es:di], cx ;limit add di, 2 mov [es:di], bx ;base low add di, 2 mov [es:di], dx ;base middle add di, 2 .return: ret Diskheader.asm Code: jmp bootcode ;Jump to bootcode ;The code below is based on the FAT16 definition. times 3-($-$$) db 0 DB "BosByte" ;Microsoft wants us to put "MSWIN4.1" in here... fuck them! times 11-($-$$) db 0 DW 512 ;Bytes per sector (do not change!) DB 1 ;Sectors per Cluster DW 1 ;Reserved sector count DB 0x02 ;Num FATs (is ALWAYS 0x02) DW 512 ;Root entry's count (Should be 512 for FAT16) DW 2880 ;Sector count (2880 for 1.44 MB floppy) DB 0xF0 ;Media (0xF0 is common) DW 9 ;FatSize DW 18 ;Sectors per Track (used by Interupt) DW 2 ;Heads count (should be 2 for 1.44 MB floppy) DD 0 ;Hidden sectors DD 0 ;Used by FAT32 ;Should be at offset 36 now . . . DB 0x00 ;Drivenum (0 = floppy1) DB 0 ;Reserved for windows NT, fuck windows! DB 0x29 ;Indicates that the following three fields are present DD 12345 ;VolumeID (just random shizzle) DB "w00t-OS" ;VolumeName (max 11 chars) times 54-($-$$) db " " ;Fill Volumename up to 11 chars DB "FAT16" ;FileSysType (max 8 chars) times 62-($-$$) db " " ;Fill FileSysType up to 8 chars ;End of FAT16 header mainOutput.inc.asm Code: ; Filename: mainOutput.inc.asm ; Main output functions ;initscreen(void) initscreen: mov ah, 0x00 mov al, 0x12 int 0x10 .return: ret ;putc (AL char) putc: mov bl, 0x07 call putcc .return: ret ;puts(SI string) puts: mov bl, 0x07 call putcs .return: ret ;putcc (AL char,BL color) putcc: mov ah, 0x0E mov bh, 0x00 int 0x10 .return: ret ;putcs (SI string,BL color) putcs: cld .nextchar: lodsb ;load char @ DS:SI, SI++ or al, al ;check for 0 jz .return ;if 0 call putcc jmp .nextchar .return: ret |
|||
09 Mar 2008, 20:50 |
|
edfed 09 Mar 2008, 20:56
it's normal, the IA manuals are not destined (sorry) to PC programming, but to the µP programming, then, they don't mention anything about the PC platforms, only windows and MSDOS appears in their documents.
the A20 gate is external, it is a simple and gate, with an input for the A20 line and another for A20 enable. the problem is that you set the IDTR with a null table, and enable interrupts. if you set the IDTR, you should set a minimal PM set for IDT, or clear the I flag, CLI. |
|||
09 Mar 2008, 20:56 |
|
Daedalus 09 Mar 2008, 20:59
I CLI right before LGDT.
EDIT: And I know it's a pain in the ass, but could you look why the other example does work without ever touching A20? Bochs perhaps? |
|||
09 Mar 2008, 20:59 |
|
edfed 09 Mar 2008, 21:33
no boch. but more an addressing problem, it is always a problem in addressing, a bad reference, a biased reference, or a bad pointer. org is not there to simplify the task.
your SP is bad. try SP=0 and set it elsewhere. |
|||
09 Mar 2008, 21:33 |
|
Daedalus 09 Mar 2008, 22:24
My SP is the same as in the other bootloader, and that works fine. Why would it be wrong now? SP = 0 doesn't work.
|
|||
09 Mar 2008, 22:24 |
|
edfed 09 Mar 2008, 22:43
please, vid, delete it.
Last edited by edfed on 09 Mar 2008, 23:51; edited 1 time in total |
|||
09 Mar 2008, 22:43 |
|
edfed 09 Mar 2008, 23:43
now, it works.
the problem was in the GDT, you didn't build it correctly. you reversed all parameters. if one day you cross a problem with jmp 0000:7Cxx, it is because you put use32 too soon. use32 shall be writen just before the first 32 bit instruction, just at the pmode label. Last edited by edfed on 10 Mar 2008, 08:21; edited 1 time in total |
|||
09 Mar 2008, 23:43 |
|
Daedalus 10 Mar 2008, 08:19
Yeeeeeeeeeeeeeeeeeeeeey. I saw a bunch of A's and really happy now. Thanks edfed, for pointing out the GDT errors, hahahaha.. Didn't see them. Changed that, worked like a charm. 170 bytes.
|
|||
10 Mar 2008, 08:19 |
|
< Last Thread | Next Thread > |
Forum Rules:
|
Copyright © 1999-2024, Tomasz Grysztar. Also on GitHub, YouTube.
Website powered by rwasa.