"Yeoj" <
joeyt...@gmail.com> wrote in message
news:a3d89b1a-ef8d-4df6...@googlegroups.com...
> I can't figure out why my OS is not booting to the MB mark
> in memory. I have researched all I can and I am stuck.
> I am calling an assembly kernel.
>
Ok.
> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
> ; Yeoj Bootloader Version 1.0
> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
>
> %define version '1.0'
>
> [BITS 16]
> [ORG 0x7C00]
>
Ok.
The brackets aren't needed. You might also want a "SECTION .text"
etc.
>
> main:
> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;
> ; main = whole program
> ; Move the location into DS
> ; Move Welcome String
> ; call Print to execute it
> ; JMP to Kernel to get there
> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;
> cli
> mov ax,0x7C00 ; Setup the Data Segment register
> ; Location of data is DS:Offset
> mov ds,ax ; Now I know where I'm at
> mov ds, ax
> mov fs, ax
> mov es, ax
> mov gs, ax
>
You've set all the segments to 0x7C00. You probably wanted
0x07C0. The segment is multiplied by 16 or shifted 4 bits then
added to the offset in real mode (RM), i.e., CS<<4+IP or CS*16+IP.
Correcting that still might not do what you want. Most BIOSes set
CS=0x0 and IP=0x7C00. If yours does that, then your code will
work with your BIOS. However, some BIOSes some set CS=0x07C0 and
IP=0x0. Your code might need to be adjusted to work for both
combinations of CS and IP. Actually, it probably needs to be
rewritten for any combination of values that satisfy CS<<4+IP or
CS*16+IP. You might want to set CS explicitly via a far jump to
the following instruction.
> mov ax, 0x0000 ; set the stack
> mov ss, ax
> mov sp, 0xFFFF
> mov bp, 0xFFFF
> sti
SP and BP likely need to be word aligned (two bytes), i.e.,
0xFFFE. POP instructions increment SP, so if you have a POP
before any PUSHes to the stack then SP will overflow or wrap to
0x0 where your BIOS IDT is... You might want a smaller value for
SP and BP, e.g., 0x7C00 or 0x7000 or 0x600 etc.
I can't confirm if the print routine works by reading it.
> Kernel:
> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
> ;Kernel = Set up for the Kernel
> ;Sets up A20, GDT, IDT
> ;jumps to Kernel
> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
>
> A20:
> ;;;;;;;
> ; A20 ;
> ;;;;;;;
>
> mov ax,0x2401 ;enable A20
> int 15
> cmp ax,0x86 ; Checks for Campatablity
> je Fail
> mov si, A20Load ; Bring in A20 Text
This may be a problem. BIOS support for enabling A20 is erratic
and problematic . There are two common alternate methods:
keyboard controller A20 method and the PS/2 A20 method. PS/2
method works on most modern machines. Some older machines require
keyboard controller method. There are a number of pages on the
alt.os.development FAQ website managed by James Harris discussing
various A20 issues. You can find other pages on A20 via Google or
Yahoo, or on the OSDev.org forums, or I can provide more links if
needed. The last link below shows a sampling of the BIOS support
of the A20 functions.
http://aodfaq.wikispaces.com/a20
http://aodfaq.wikispaces.com/mc-a20-timing
http://aodfaq.wikispaces.com/boot
http://aodfaq.wikispaces.com/machine+characteristics
> Call Print
> jmp GDT
>
>
> ;;;;;;;;;;;;;;;
> ; GDT and IDT ;
> ;;;;;;;;;;;;;;;
>
>
> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
> ; Global Descriptor Table (GDT) ;
> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
>
> gdt:
> dw 0,0,0,0 ; Null
>
> dw 0x07FF ; 8Mb - limit=2047
Most people set this to 0xFFFF for either 1MB or 4GB.
> dw 0x0000 ; base address=0
> dw 0x9A00 ; code read/exec
> dw 0x00C0 ; granularity=4096, 386
>
Most people use CF instead of C0.
> .data:
> dw 0x07FF ; 8Mb - limit=2047
Most people set this to 0xFFFF for either 1MB or 4GB.
> dw 0x0000 ; base address=0
> dw 0x9200 ; data read/write
> dw 0x00C0 ; granularity=4096, 386
>
Most people use CF instead of C0.
> idt_48:
> dw 0 ; idt limit=0
> dw 0,0 ; idt base=0L
>
> gdt_48:
> dw 0x800 ; gdt limit=2048, 256 GDT entries
> dw gdt,0x0 ; gdt base = 0x0xxx
Isn't gdt_48 supposed to be 8 bytes?
Usually, most people set two labels "gdt" and "gdt_end" around the
GDT entries, then they subtract to get the entries for gdt_48.
gdt_48:
dw gdt_end - gdt - 1
dd 0
dw 0
The two zero's comprise the physical address of the gdt. They're
unset. Most code computes the address of the gdt label and fills
in the physical address in gdt_48 before issuing an LGDT
instruction. I don't see that in your code below ...
> GDT:
> cli
> lgdt[gdt_48] ;
> sti
> mov si, GDTLoad ; Bring in GDT Text
> call Print ; Print it
>
There might be a problem here. See comment above.
> mov ax, 0 ;
> int 0x16 ;Wait for Keystroke to Load Kernel
>
> mov si, dotall
> Call Print
>
> xor ax, ax
> add ax, 1 ; Clear Carry Bit
>
> mov si, DAPS ; Load DAPS Struct to SI
> mov ah, 0x42 ; Read Functions
> mov dl, 0x80 ; Active Boot Drive
> int 0x13
>
> jc Fail ; If something goes wrong...
>
> gotoPMoDe:
> cli
>
I can't confirm if this routine works by reading it.
> mov eax, cr0
> or eax, 1
> mov cr0, eax
>
Ok.
> jmp 0x1000:0x0 ; Jump to Kernel
>
That'll work if you know your code is at 0x10000 (64KB). For 1MB,
you probably want 0xFFF0 instead of 0x1000. Usually, a RETF or a
JMP FAR is used, instead of absolute segment:offset values.
They're used because the value to jump to can be computed and
saved in memory for a JMP FAR or pushed onto the stack for a RETF.
> Fail:
> mov si, Failure
> Call Print
> jmp $
>
> ;;;;;;;;;;;;;;;;
> ; Data ;
> ;;;;;;;;;;;;;;;;
>
> Welcome db
> 'YOS',13,10,version,13,10,'',13,10,'Boot-Successful',13,10,0 ;
> Data Red Dwarf Version and Boot Success
> GDTLoad db 'GDT Loading ...',13,10,0 ; GDT Message
> A20Load db 'A20 Loading ...',13,10,0 ; A20 Message
> PMDLoad db 'PMD Loading ...',13,10,0 ; PMD Message
> dotall db '.',13,10,0
> Failure db 'Failure',13,10,0
> ;;;;;;;;;;;;;;;;;;
> ; Jump To Kernel ;
> ;;;;;;;;;;;;;;;;;;
>
Ok.
> ;;;;;;;;
> ; DAPS ;
> ;;;;;;;;
>
> DAPS: db 0x10 ; Size of Structure (16 bytes)
> db 0 ; Always 0
> db 1 ; Number of Sectors to Read (1x512)
> db 0 ; Always 0
> dd 0x10000 ; Target Location for Reading To
> dw 0 ; Page Table (0, Disabled)
> dd 1 ; Read from Second Block
> dd 0 ; Large LBAs, ignore
>
> ;;;;;;;;;;;;;;;;;
> ; Fill and Sign ;
> ;;;;;;;;;;;;;;;;;
>
I'm not familiar with this.
> times 510-($-$$) db 0 ; Fill the rest with zeros
> dw 0xAA55 ; Boot loader signature
Ok.
Rod Pemberton