Last active
October 19, 2015 16:29
-
-
Save elazarl/9f7d61dabeb6d899b64e to your computer and use it in GitHub Desktop.
Boot loader failure
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
* Copyright (C) 2013 Cloudius Systems, Ltd. | |
* | |
* This work is open source software, licensed under the terms of the | |
* BSD license as described in the LICENSE file in the top-level directory. | |
*/ | |
OUTPUT_FORMAT(binary) | |
MEMORY | |
{ | |
BOOTSECT : ORIGIN = 0, LENGTH = 0x10000 | |
} | |
SECTIONS | |
{ | |
.text 0x7c00 : { *(.text) } > BOOTSECT | |
} | |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# Copyright (C) 2013 Cloudius Systems, Ltd. | |
# | |
# This work is open source software, licensed under the terms of the | |
# BSD license as described in the LICENSE file in the top-level directory. | |
.code16 | |
tmp = 0x80000 | |
bootsect = 0x7c00 | |
cmdline = 0x7e00 | |
target = 0x1800000 | |
elf_entry_point_header_offset = 0x18 | |
lzentry = target+elf_entry_point_header_offset | |
loader = 0x200000 # OSV_KERNEL_BASE | |
entry = loader+elf_entry_point_header_offset | |
mb_info = 0x1000 | |
// OSv information lays in the end of this struct, which is 88 bytes in size. | |
mb_tsc1_lo = (mb_info + 88) | |
mb_tsc1_hi = (mb_info + 88 + 4) | |
mb_tsc_disk_lo = (mb_info + 88 + 8) | |
mb_tsc_disk_hi = (mb_info + 88 + 12) | |
mb_cmdline = (mb_info + 16) | |
mb_mmap_len = (mb_info + 44) | |
mb_mmap_addr = (mb_info + 48) | |
e820data = 0x2000 | |
.text | |
start: | |
ljmp $0, $init | |
# Be conservative, we should not be in the 10th byte so far, but better safe than sorry | |
.org 0x10 | |
# count32 will be overwritten by imgedit.py setsize <int>, | |
# to specify the exact loader size after it is compiled | |
count32: .short 4096 # in 32k units, 4096=128MB | |
int1342_struct: | |
.byte 0x10 | |
.byte 0 | |
.short 0x40 # 32k | |
.short 0 | |
.short tmp / 16 | |
lba: | |
.quad 128 | |
int1342_boot_struct: # for command line | |
.byte 0x10 | |
.byte 0 | |
.short 0x3f # 31.5k | |
.short cmdline | |
.short 0 | |
.quad 1 | |
xfer: .long target | |
gdt: | |
.short gdt_size - 1 | |
.short gdt | |
.long 0 | |
.quad 0x00cf9b000000ffff # 32-bit code segment | |
.quad 0x00cf93000000ffff # 32-bit data segment | |
.quad 0x00009b000000ffff # 16-bit code segment | |
.quad 0x000093000000ffff # 16-bit data segment | |
gdt_size = . - gdt | |
init: | |
rdtsc | |
mov %eax, mb_tsc1_lo | |
mov %edx, mb_tsc1_hi | |
xor %ax, %ax | |
mov %ax, %ds | |
mov %ax, %es | |
mov %ax, %ss | |
mov $0x7c00, %sp | |
mov $0x2401, %ax # enable a20 gate | |
int $0x15 | |
lea int1342_boot_struct, %si | |
mov $0x42, %ah | |
mov $0x80, %dl | |
int $0x13 | |
movl $cmdline, mb_cmdline | |
read_disk: | |
lea int1342_struct, %si | |
mov $0x42, %ah | |
mov $0x80, %dl | |
int $0x13 | |
jc done_disk # in case of errors, we don't really know what to do. | |
cli | |
lgdtw gdt | |
mov $0x11, %ax | |
lmsw %ax | |
ljmp $8, $1f | |
1: | |
.code32 | |
mov $0x10, %ax | |
mov %eax, %ds | |
mov %eax, %es | |
mov $tmp, %esi | |
mov xfer, %edi | |
mov $0x8000, %ecx | |
rep movsb | |
mov %edi, xfer | |
mov $0x20, %al | |
mov %eax, %ds | |
mov %eax, %es | |
ljmpw $0x18, $1f | |
1: | |
.code16 | |
mov $0x10, %eax | |
mov %eax, %cr0 | |
ljmpw $0, $1f | |
1: | |
xor %ax, %ax | |
mov %ax, %ds | |
mov %ax, %es | |
sti | |
addl $(0x8000 / 0x200), lba | |
decw count32 | |
jnz read_disk | |
done_disk: | |
rdtsc | |
mov %eax, mb_tsc_disk_lo | |
mov %edx, mb_tsc_disk_hi | |
mov $e820data, %edi | |
mov %edi, mb_mmap_addr | |
xor %ebx, %ebx | |
more_e820: | |
mov $100, %ecx | |
mov $0x534d4150, %edx | |
mov $0xe820, %ax | |
add $4, %edi | |
int $0x15 | |
jc done_e820 | |
mov %ecx, -4(%edi) | |
add %ecx, %edi | |
test %ebx, %ebx | |
jnz more_e820 | |
done_e820: | |
sub $e820data, %edi | |
mov %edi, mb_mmap_len | |
cli | |
mov $0x11, %ax | |
lmsw %ax | |
ljmp $8, $1f | |
1: | |
.code32 | |
mov $0x10, %ax | |
mov %eax, %ds | |
mov %eax, %es | |
mov %eax, %gs | |
mov %eax, %fs | |
mov %eax, %ss | |
call *lzentry | |
mov $loader, %eax | |
mov $mb_info, %ebx | |
call *entry | |
.org 0x1b8 | |
.byte 0x56, 0x53, 0x4F, 0, 0, 0 | |
.org 0x1be | |
.space 16, 0 | |
.org 0x1ce | |
.space 16, 0 | |
.org 0x1de | |
.space 16, 0 | |
.org 0x1ee | |
.space 16, 0 | |
.org 0x1fe | |
.byte 0x55, 0xaa |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/bin/bash | |
set -e | |
rm -rf out | |
[ -f .pid ] && (kill `cat .pid`; rm .pid) | |
make | |
qemu-system-x86_64 -snapshot -hda out/loader.img -serial file:/dev/stdout -pidfile .pid -s -S & | |
echo 'set arch i8086 | |
target remote localhost:1234 | |
hbr boot16.S:89 | |
commands | |
x/h count32 | |
c | |
end | |
hbr boot16.S:90 | |
commands 2 | |
i r eflags | |
end' >out/gdb.script | |
gdb out/boot16.elf -quiet -x out/gdb.script |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This is a demonstration of how INT 13, ah=42 fails after a while. | |
Run 'bash debug.sh`, then hit `c` a couple of times, you should | |
see that INT 13 returns with CF set, which means it had an error. | |
Why is it happening? The code is pretty simple, all it does is reading | |
a sector from the disk, and copying it to some place in the memory. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
quiet = $(if $V, $1, @echo " $2"; $1) | |
very-quiet = $(if $V, $1, @$1) | |
OUT=out | |
.PHONY: all | |
block=$(shell expr 512 \* 64) | |
image-size=$(shell expr 4 \* $(block) - 513 ) | |
all: $(OUT)/loader.img $(OUT)/boot16.elf | |
$(OUT)/boot16.elf: boot16.ld $(OUT)/boot16.o | |
$(call quiet, $(LD) $(OUT)/boot16.o boot16.ld -o $@, LD $@) | |
$(OUT)/boot16.bin: boot16.ld $(OUT)/boot16.o | |
$(call quiet, $(LD) -o $@ -T $^, LD $@) | |
$(OUT)/lzloader.elf: | |
$(call quiet, tr '\0' '\377' < /dev/zero | dd count=$(image-size) bs=1 of=$@) | |
$(OUT)/loader.img: $(OUT)/boot16.bin $(OUT)/lzloader.elf | |
$(call quiet, dd if=$(OUT)/boot16.bin of=$@ > /dev/null 2>&1, DD $@ boot16.bin) | |
$(call quiet, cat $(OUT)/lzloader.elf /dev/zero|dd count=`python -c 'print max(192, ($(image-size)-1)/512+1)'` of=$@ conv=notrunc seek=128 > /dev/null 2>&1, \ | |
DD $@ lzloader.elf) | |
$(call quiet, python setsize.py $@ $(OUT)/lzloader.elf, DD $@ boot16.bin) | |
makedir = $(call very-quiet, mkdir -p $(dir $@)) | |
build-s = $(CXX) $(CXXFLAGS) $(ASFLAGS) -g -c -o $@ $< | |
q-build-s = $(call quiet, $(build-s), AS $@) | |
$(OUT)/%.o: %.S | |
$(makedir) | |
$(q-build-s) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/python | |
import io | |
import os | |
import sys | |
if __name__ == '__main__': | |
img = sys.argv[1] | |
elf = sys.argv[2] | |
block_size = 32*1024 | |
elf_size_in_bytes = os.stat(elf).st_size | |
img_size = os.stat(img).st_size | |
# round up | |
elf_size_in_blocks = (elf_size_in_bytes-1)//block_size+1 | |
elf_data = bytearray(img_size) | |
with io.FileIO(img, 'r') as fp: | |
n = fp.readinto(elf_data) | |
elf_data = elf_data[:n] | |
elf_data[0x11] = (elf_size_in_blocks & 0xff00) >> 8 | |
elf_data[0x10] = elf_size_in_blocks & 0xff | |
with open(img, 'w') as fp: | |
fp.write(elf_data) | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment