OSDev.org

The Place to Start for Operating System Developers
It is currently Sun Sep 22, 2019 8:39 pm

All times are UTC - 6 hours




Post new topic Reply to topic  [ 2 posts ] 
Author Message
 Post subject: triple fault on compiling and linking kernel and bootloader
PostPosted: Sat Feb 16, 2019 12:27 pm 
Offline

Joined: Sat Feb 16, 2019 12:02 pm
Posts: 2
I am new to operating system development. I am trying to load my kernel from my 2 stage bootloader, but I immediately get a triple fault. I have narrowed it down to most likely being in the compiling and linking. I think this because I load and call my 2nd stage bootloader in the same way that I load and call the kernel. But just in case it something else I will also post my bootloader.

Here is the linker.ld:
Code:
OUTPUT_FORMAT(elf32-i386)
ENTRY(main)

SECTIONS
{
  . = 0x9000;
  .text : { *(.text.start) *(.text)}
  .data : { *(.data) }
  .bss  : { *(.bss) *(COMMON) }
}

here is my build.sh:
Code:
nasm -f bin -o boot.bin boot.asm

nasm -f elf32 -o stage2.o stage2.asm
ld -melf_i386 -Ttext=0x1000 -nostdlib --nmagic -o stage2.elf stage2.o
objcopy -O binary stage2.elf stage2.bin

gcc -g -m32 -c -ffreestanding -o kernel.o kernel.c -lgcc
ld -melf_i386 -Tlinker.ld -nostdlib --nmagic -o kernel.elf kernel.o
objcopy -O binary kernel.elf kernel.bin

dd if=/dev/zero of=corn.img bs=512 count=2880
dd if=boot.bin of=corn.img bs=512 conv=notrunc
dd if=stage2.bin of=corn.img bs=512 conv=notrunc
dd if=kernel.bin of=corn.img bs=512 seek=1 conv=notrunc

and here is my kernel.c
Code:
__asm__ (".pushsection .text.start\r\n" \
         "jmp main\r\n" \
         ".popsection\r\n"
         );

int main(){
  while(1){}
  return 0;
}

Here is my stage 1 of bootloader(boot.asm):
Code:
bits 16
org 0x7c00

offset equ 0x1000

xor ax, ax
mov ds, ax
mov es, ax
mov ss, ax
mov sp, 0x7c00
mov bp, sp
mov [BOOT_DRIVE], dl

cld

mov bx, msg
call print

load_stage2:
  mov bx, offset
  mov dh, 2
  mov dl, [BOOT_DRIVE]
  call load_disk

  mov bx, 0x9000
  mov dh, 17
  mov dl, [BOOT_DRIVE]
  call load_disk

  jmp 0x0000:offset

  jmp $

%include "load_disk.asm"
%include "print.asm"
%include "print_hex.asm"
BOOT_DRIVE db 0
msg db "Booting cornOS", 0

times 510 - ($-$$) db 0
dw 0xaa55

here is stage 2(stage2.asm):
Code:
bits 16
stage2:
  mov ax, cs
  mov ds, ax
  mov es, ax
  mov bx, stage2_called
  call print

  call enable_a20
  call switch_to_pm

%include "a20.asm"
%include "switch_to_pm.asm"
%include "gdt.asm"

bits 32
BEGIN_PM:
  mov ebx, pmode_msg
  call print_pm
  jmp CODE_SEG:0x9000
  jmp $
%include "print32.asm"
stage2_called db "Stage two successfully called!", 0
pmode_msg db "Sucessfully entered protected mode", 0

Here is stuff I don't believe is relevant but just in case is will post it here:

gdt.asm
Code:
gdt_start:
  dd 0x0
  dd 0x0

gdt_code:
  dw 0xffff
  dw 0x0
  db 0x0
  db 10011010b
  db 11001111b
  db 0x0

gdt_data:
  dw 0xffff
  dw 0x0
  db 0x0
  db 10010010b
  db 11001111b
  db 0x0

gdt_end:

gdt_desc:
  dw gdt_end - gdt_start - 1
  dd gdt_start
CODE_SEG equ gdt_code - gdt_start
DATA_SEG equ gdt_data - gdt_start

switch_to_pm.asm:
Code:
bits 16
switch_to_pm:
  cli
  lgdt [gdt_desc]
  mov eax, cr0
  or al, 1
  mov cr0, eax
  jmp CODE_SEG:init_pm
bits 32
init_pm:
  mov ax, DATA_SEG
  mov ds, ax
  mov ss, ax
  mov es, ax
  mov fs, ax
  mov gs, ax

  mov ebp, 0x90000
  mov esp, ebp

  call BEGIN_PM

load_disk.asm:
Code:
load_disk:
  pusha
  push dx

  mov ah, 0x02
  mov al, dh
  mov ch, 0x00
  mov cl, 0x02
  mov dh, 0x00

  int 0x13
  jc disk_error

  pop dx
  cmp al, dh
  jne sectors_error
  mov bx, read_disk_success
  call print
  popa
  ret

disk_error:
  mov bx, read_disk_failed
  call print
  mov dh, ah
  call print_hex
  jmp $

sectors_error:
  mov bx, incorrect_sectors
  call print
  jmp $
read_disk_success db "Successfully read disk!", 0
read_disk_failed db "Failed to read disk", 0
incorrect_sectors db "Incorrect number of sectors read", 0

and finally a20.asm:
Code:
bits 16

a20_success db "A20 gate sucessfully enabled!", 0
a20_failed db "A20 gate enable failed", 0
%include "print.asm"

check_a20:
    pushf
    push ds
    push es
    push di
    push si

    cli

    xor ax, ax
    mov es, ax

    not ax
    mov ds, ax

    mov di, 0x0500
    mov si, 0x0510

    mov al, byte [es:di]
    push ax

    mov al, byte [ds:si]
    push ax

    mov byte [es:di], 0x00
    mov byte [ds:si], 0xFF

    cmp byte [es:di], 0xFF

    pop ax
    mov byte [ds:si], al

    pop ax
    mov byte [es:di], al

    mov ax, 0
    je check_a20__exit

    mov ax, 1

check_a20__exit:
    pop si
    pop di
    pop es
    pop ds
    popf

    ret
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
      call check_a20
      cmp ax, 0
      jne a20_success_enable
      mov bx, a20_failed
      call print
      ret
a20_success_enable:
  mov bx, a20_success
  call print
  ret
a20wait:
      in      al,0x64
      test    al,2
      jnz     a20wait
      ret


a20wait2:
      in      al,0x64
      test    al,1
      jz      a20wait2
      ret

I'm really stuck and cant find any tutorials on 2 stage bootloaders :? , thanks in advance to anyone who helps! :D


Top
 Profile  
 
 Post subject: Re: triple fault on compiling and linking kernel and bootloa
PostPosted: Sat Feb 16, 2019 6:15 pm 
Offline
Member
Member

Joined: Fri Aug 26, 2016 1:41 pm
Posts: 482
For the future please use a service like Gitlab or Githib or some place that can store your kernel so that we can easily gain access to it with minimal hassles.

There is no reason to have 2 stages here, but to fix it so what you are trying to do works will require a change to the way load_disk.asm works. It was originally designed with fixed cylinders heads and sectors. Since you really want to use it to load more than one place from disk the code needs to be modified so all the drive parameters are passed into the load_disk function. Modify load_disk.asm to look like:
Code:
pusha
  push ax                       ; Save original # of sectors to read (AL)

  mov ah, 0x02
  int 0x13
  jc disk_error

  pop dx                        ; Restore the number of sectors to read into DL
  cmp al, dl
  jne sectors_error
  mov bx, read_disk_success
  call print
  popa
  ret

disk_error:
  mov bx, read_disk_failed
  call print
  mov dh, ah
  call print_hex
  jmp $

sectors_error:
  mov bx, incorrect_sectors
  call print
  jmp $
read_disk_success db "Successfully read disk!", 0
read_disk_failed db "Failed to read disk", 0
incorrect_sectors db "Incorrect number of sectors read", 0
. You ill need to modify boot.asm to properly set up the call to load_disk with the CHS and sectors to read.It can be modified to be:
Code:
bits 16
org 0x7c00

offset equ 0x1000

xor ax, ax
mov ds, ax
mov es, ax
mov ss, ax
mov sp, 0x7c00
mov bp, sp
mov [BOOT_DRIVE], dl

cld

mov bx, msg
call print

load_stage2:
  mov bx, offset                ; ES:BX=0x0000:0x1000
  mov dl, [BOOT_DRIVE]
  mov al, 1                     ; Read 1 sector
  mov ch, 0x00                  ; From cylinder 0
  mov cl, 0x02                  ;      sector 2
  mov dh, 0x00                  ;      head 0

  call load_disk

  mov dl, [BOOT_DRIVE]
  mov al, 16                    ; Read 16 sectors
  mov ch, 0x00                  ; From cylinder 0
  mov cl, 0x03                  ;      sector 3
  mov dh, 0x00                  ;      head 0
  mov bx, 0x9000                ; ES:BX=0x0000:0x9000
  call load_disk

  jmp 0x0000:offset

  jmp $

%include "load_disk.asm"
%include "print.asm"
%include "print_hex.asm"
BOOT_DRIVE db 0
msg db "Booting cornOS", 0

times 510 - ($-$$) db 0
dw 0xaa55
There is a bug in your buil.sh file. You place stage2.bin ontop of boot.bin in the disk image. You need use SEE with DD to seek to the proper place. Change it to be:
Code:
nasm -f bin -o boot.bin boot.asm

nasm -f elf32 -o stage2.o stage2.asm
ld -melf_i386 -Ttext=0x1000 -nostdlib --nmagic -o stage2.elf stage2.o
objcopy -O binary stage2.elf stage2.bin

gcc -g -m32 -c -ffreestanding -o kernel.o kernel.c -lgcc
ld -melf_i386 -Tlinker.ld -nostdlib --nmagic -o kernel.elf kernel.o
objcopy -O binary kernel.elf kernel.bin

dd if=/dev/zero of=corn.img bs=512 count=2880
dd if=boot.bin of=corn.img bs=512 conv=notrunc
dd if=stage2.bin of=corn.img bs=512 seek=1 conv=notrunc
dd if=kernel.bin of=corn.img bs=512 seek=2 conv=notrunc


Top
 Profile  
 
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 2 posts ] 

All times are UTC - 6 hours


Who is online

Users browsing this forum: Google [Bot] and 10 guests


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 post attachments in this forum

Search for:
Jump to:  
cron
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group