Hello everyone. Please excuse the newbocity of my post, but I've been actively perusing this site as well as osdever.net and I can't figure out what is wrong. I have a bootsect.asm, which loads GDT's, IDT's, Protected Mode, enables A20 and jumps to my main kernel, which is written in C. So far all my code does is print a welcome message, and loops while waiting for keyboard input. Everything works just great, except, when my main kernel (plus the misc. functions, like in,out,print, etc) gets to be bigger than 1KB (2 sectors), it just crashes and reboots endlessly. Can someone help me?
(Currently it is at exactly 1KB, and it works like a charm. I will post code if it's necessary.)
Thanks
Kernel crashes if code extends beyond 2 sectors
Re:Kernel crashes if code extends beyond 2 sectors
Sounds like the boot loader is fouling up but without any more detail, who knows why.
Re:Kernel crashes if code extends beyond 2 sectors
Here is the first half of my bootloader code: (I know some assembly, but this is strictly a copy-paste job...)
Code: Select all
[BITS 16] ; We need 16-bit intructions for Real mode
[ORG 0x7C00] ; The BIOS loads the boot sector into memory location 0x7C00
origin equ 0x7C00
GLOBAL entry
entry:
reset_drive:
mov ah, 0 ; RESET-command
int 13h ; Call interrupt 13h
or ah, ah ; Check for error code
jnz reset_drive ; Try again if ah != 0
mov ax, 0
mov es, ax
mov bx, 0x1000 ; Destination address = 0000:1000
mov ah, 02h ; READ SECTOR-command
mov al, 02h ; Number of sectors to read = 1
mov ch, 0 ; Cylinder = 0
mov cl, 02h ; Sector = 2
mov dh, 0 ; Head = 0
int 13h ; Call interrupt 13h
or ah, ah ; Check for error code
jnz reset_drive ; Try again if ah != 0
cli ; Disable interrupts, we want to be alone
xor ax, ax
mov ds, ax ; Set DS-register to 0 - used by lgdt
lgdt [gdt_desc] ; Load the GDT descriptor
mov eax, cr0 ; Copy the contents of CR0 into EAX
or eax, 1 ; Set bit 0
mov cr0, eax ; Copy the contents of EAX into CR0
jmp 08h:clear_pipe ; Jump to code segment, offset clear_pipe
[BITS 32] ; We now need 32-bit instructions
clear_pipe:
mov ax, 10h ; Save data segment identifyer
mov ds, ax ; Move a valid data segment into the data segment register
mov ss, ax ; Move a valid data segment into the stack segment register
mov esp, 090000h ; Move the stack pointer to 090000h
;Set up IDT tables..
lidt [idt_pointer]
call read_kbd
call enable_A20
call read_kbd
jmp 08h:01000h ; Jump to section 08h (code), offset 01000h
Re:Kernel crashes if code extends beyond 2 sectors
The 2nd half:
Code: Select all
;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Random code bits
;;;;;;;;;;;;;;;;;;;;;;;;;;
read_kbd:
in al,64h ; read status byte
and al,01h ; wait for OBF==1
jz read_kbd
in al,60h ; read scancode byte
ret
printchar:
mov ah,0x0E ; This number is the number of the function in the BIOS to run.
mov bh,0x00 ; Page number (I'm not 100% sure of this myself but it is best
mov bl,0x07 ; Text attribute (Controls the background and foreground colour
mov al,65
int 0x10 ; Call the BIOS video interrupt.
ret
;;;;;;;;;;;;;;;;;;;;;;;;;;
;; End random code bits
;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Enable A20
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
enable_A20:
cli
call a20wait
mov al,0xAD
out 0x64,al
call a20wait
mov al,0xD0
out 0x64,al
call a20wait2
in al,0x60
push eax
call a20wait
mov al,0xD1
out 0x64,al
call a20wait
pop eax
or al,2
out 0x60,al
call a20wait
mov al,0xAE
out 0x64,al
call a20wait
;sti
ret
a20wait:
.l0: mov ecx,65536
.l1: in al,0x64
test al,2
jz .l2
loop .l1
jmp .l0
.l2: ret
a20wait2:
.l0: mov ecx,65536
.l1: in al,0x64
test al,1
jnz .l2
loop .l1
jmp .l0
.l2: ret
start_of_idt:
;interrupt 0
dw isr1
dw 0x10
dw 0x8E00
dw (origin >> 16)
;interrupt 1
dw isr1
dw 0x10
dw 0x8E00
dw (origin >> 16)
end_of_idt:
idt_pointer:
dw end_of_idt - start_of_idt - 1
dd start_of_idt
;;;;;;;;;;;;;;;;;;;;;;;;;
;; ISRs
;;;;;;;;;;;;;;;;;;;;;;;;;
isr1:
pusha
push gs
push fs
push es
push ds
;call
;jmp printchar
mov word [0xB8000],'D '
pop ds
pop es
pop fs
pop gs
popa
iret
gdt: ; Address for the GDT
gdt_null: ; Null Segment
dd 0
dd 0
gdt_code: ; Code segment, read/execute, nonconforming
dw 0FFFFh
dw 0
db 0
db 10011010b
db 11001111b
db 0
gdt_data: ; Data segment, read/write, expand down
dw 0FFFFh
dw 0
db 0
db 10010010b
db 11001111b
db 0
gdt_end: ; Used to calculate the size of the GDT
gdt_desc: ; The GDT descriptor
dw gdt_end - gdt - 1 ; Limit (size)
dd gdt ; Address of the GDT
times 510-($-$$) db 0 ; Fill up the file with zeros
dw 0AA55h ; Boot sector identifyer
- Pype.Clicker
- Member
- Posts: 5964
- Joined: Wed Oct 18, 2006 2:31 am
- Location: In a galaxy, far, far away
- Contact:
Re:Kernel crashes if code extends beyond 2 sectors
i'm not surprised it doesn't load kernels bigger than 1K since it only reads 2 sectors ...
e.g. look at your "loading" code: you have hard-coded "mov al,2" thus you'll always try to load 2 sectors... That's one of the reason why GRUB is so nice to use.
I'm not yet using it and it means i need to use ad-hock ASM-code patching tools (sue me) to tell the bootloader how much sectors it should read and from where ...
Oh, also ... You should know that INT13 will probably not allow more than 18 sectors to be read at once (actually, no more than one track at once), so when you'll have something like >9K, expect more weirdnesses to occur
Welcome to the real mode (err... i mean world)
e.g. look at your "loading" code: you have hard-coded "mov al,2" thus you'll always try to load 2 sectors... That's one of the reason why GRUB is so nice to use.
I'm not yet using it and it means i need to use ad-hock ASM-code patching tools (sue me) to tell the bootloader how much sectors it should read and from where ...
Oh, also ... You should know that INT13 will probably not allow more than 18 sectors to be read at once (actually, no more than one track at once), so when you'll have something like >9K, expect more weirdnesses to occur
Welcome to the real mode (err... i mean world)
-
- Member
- Posts: 1600
- Joined: Wed Oct 18, 2006 11:59 am
- Location: Vienna/Austria
- Contact:
Re:Kernel crashes if code extends beyond 2 sectors
me neither: the poor cpu, working so brave just to be thrown into silicium nirvana. No wonder it says *sigh, I don't want anymore ... ?rks*
... the osdever formerly known as beyond infinity ...
BlueillusionOS iso image
BlueillusionOS iso image
Re:Kernel crashes if code extends beyond 2 sectors
Ah great thanks. I was looking through my bootloader last night and I noticed this.
While I'm here, I have another question. What is the option to have the strings in my code be written to the end of the binary file? I vaguely remember reading about that somewhere. Would that be a reason why I am unable to print literal strings? (i.e. print("Hello, world!");)
Thanks again
While I'm here, I have another question. What is the option to have the strings in my code be written to the end of the binary file? I vaguely remember reading about that somewhere. Would that be a reason why I am unable to print literal strings? (i.e. print("Hello, world!");)
Thanks again