From 098b0dd7bf6600ed6b904cd531a55a6415996900 Mon Sep 17 00:00:00 2001 From: John Tsiombikas Date: Sun, 8 Apr 2018 08:11:47 +0300 Subject: [PATCH] hacking the 1st stage loader --- gdbnotes | 10 ++++ pcboot.ld | 14 +++++- src/boot/boot.s | 147 ++++++++++++++++++++++++++++++++++++++++++++---------- src/boot/boot2.s | 36 +++++++++++++ 4 files changed, 178 insertions(+), 29 deletions(-) create mode 100644 gdbnotes create mode 100644 src/boot/boot2.s diff --git a/gdbnotes b/gdbnotes new file mode 100644 index 0000000..e03261f --- /dev/null +++ b/gdbnotes @@ -0,0 +1,10 @@ +$ qemu-system-i386 -fda test.bin -s -S +$ gdb +target remote localhost:1234 +set architecture i8086 +display/i $pc +b *0x7c00 + +examine register with: i r eax + +$ objdump -D test diff --git a/pcboot.ld b/pcboot.ld index f629124..28fb7e6 100644 --- a/pcboot.ld +++ b/pcboot.ld @@ -1,10 +1,20 @@ OUTPUT_ARCH(i386) SECTIONS { - /* BIOS will load us at 0x7c000h */ - . = 0x7c000; + /* BIOS loads the boot code at 0000:7c00 */ + . = 0x7c00; .boot : { * (.boot); } + + /* second stage boot loader */ + .boot2 : { * (.boot2); } + _boot2_size = SIZEOF(.boot2); + + /* main program will be loaded at 1MB by the second stage + * boot loader + */ + . = 1M; + .startup : { * (.startup); } .text : { * (.text); } .rodata : { * (.rodata); } diff --git a/src/boot/boot.s b/src/boot/boot.s index e3fd206..ffd1408 100644 --- a/src/boot/boot.s +++ b/src/boot/boot.s @@ -1,37 +1,130 @@ .code16 .section .boot,"a" - mov $0x13, %ax - int $0x10 - - mov $1, %al - mov $0x3c8, %dx - outb %al, %dx - mov $0x3c9, %dx - mov $63, %al - outb %al, %dx - xor %al, %al - outb %al, %dx - outb %al, %dx - - mov $200, %ebx - mov $0x00000101, %eax - pushl $0xa000 - popl %es - xor %di, %di -fill: - mov %ebx, %ecx - and $1, %ecx - jnz 0f - rol $16, %eax -0: mov $80, %ecx - rep stosl - dec %ebx - jnz fill + cli + cld + # move stack to the top of 512k + mov $0x7000, %ax + mov %ax, %ss + xor %sp, %sp + # use the code segment for data access + mov %cs, %ax + mov %ax, %ds + mov %ax, %es + + call clearscr + + mov $_boot2_size, %eax + call print_num + + # load the second stage boot loader and jump to it + mov $_boot2_size, %eax + mov %eax, %ebx + shr $9, %eax + and $0x1ff, %ebx + jz 0f + inc %eax +0: pushw %ax + pushw $1 + # set es to the start of the destination buffer to allow reading in + # full 64k chunks + mov $boot2_addr, %bx + shr $4, %bx + mov %bx, %es + xor %bx, %bx + call readsect + jmp boot2_addr cli hlt + .set SECT_PER_TRACK, 18 + + .set ARG_NSECT, 6 + .set ARG_SIDX, 4 + .set VAR_NTRACKS, -2 + +# readsect(first, num) +readsect: + push %bp + mov %sp, %bp + sub $2, %sp + + # calculate how many tracks to read + mov ARG_NSECT(%bp), %ax + xor %dx, %dx + mov $SECT_PER_TRACK, %cx + div %cx + cmp $0, %dx + jz 0f + inc %ax +0: mov %ax, VAR_NTRACKS(%bp) + + xor %cx, %cx +0: cmp VAR_NTRACKS(%bp), %cx + jz 0f + push %cx + call read_track + pop %cx + jmp 0b +0: + # TODO cont. + pop %bp + ret + +read_track: + ret + +clearscr: + push %es + pushw $0xb800 + pop %es + xor %eax, %eax + xor %di, %di + movl $500, %ecx + rep stosl + pop %es + ret + +print_num: + # save es + push %es + + xor %cx, %cx + movw $numbuf, %si + mov $10, %ebx + +0: xor %edx, %edx + div %ebx + add $48, %dl + mov %dl, (%si) + inc %si + inc %cx + cmp $0, %eax + jnz 0b + + # print the backwards string + pushw $0xb800 + pop %es + xor %di, %di + +0: dec %si + mov (%si), %al + movb %al, %es:(%di) + inc %di + mov $7, %al + movb %al, %es:(%di) + inc %di + dec %cx + jnz 0b + + # restore es + pop %es + ret + +numbuf: .space 10 .org 510 .byte 0x55 .byte 0xaa + +boot2_addr: diff --git a/src/boot/boot2.s b/src/boot/boot2.s new file mode 100644 index 0000000..47121ee --- /dev/null +++ b/src/boot/boot2.s @@ -0,0 +1,36 @@ +# this is the second-stage boot loader + .code16 + .section .boot2,"a" + + mov $0x13, %ax + int $0x10 + + pushw $63 + pushw $63 + pushw $0 + pushw $0xff + call set_palette + add $8, %sp + + pushw $0xa000 + pop %es + xor %di, %di + mov $16000, %ecx + mov $0xffffffff, %eax + rep stosl + + hlt + +set_palette: + mov %sp, %bp + mov $0x3c8, %dx + movw 2(%bp), %ax + outb %al, %dx + inc %dx + movw 4(%bp), %ax + outb %al, %dx + movw 6(%bp), %ax + outb %al, %dx + movw 8(%bp), %ax + outb %al, %dx + ret -- 1.7.10.4