Last active
September 21, 2018 07:02
-
-
Save knknkn1162/9ba537b49b10e77f39462a30b274689e to your computer and use it in GitHub Desktop.
Based on the course, https://pdos.csail.mit.edu/6.828/2018/ Load the HDD into memory at 0x00007c00~0x00007e00.
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
bootblock.o: file format elf32-i386 | |
Disassembly of section .text: | |
# Start the first CPU: switch to 32-bit protected mode, jump into C. | |
# The BIOS loads this code from the first sector of the hard disk into | |
# memory at physical address 0x7c00 and starts executing in real mode | |
# with %cs=0 %ip=7c00. | |
00007c00 <start>: | |
.code16 # Assemble for 16-bit mode | |
.globl start | |
# 0x7c00 ~ 0x7e00 | |
start: | |
# when xv6 is ready, it will re-enable interrupts | |
cli # BIOS enabled interrupts; disable | |
7c00: fa cli | |
# Zero data segment registers DS, ES, and SS. | |
# BIOS doesnot guarantee anything about the contents of %ds, %es, %ss. | |
xorw %ax,%ax # Set %ax to zero | |
7c01: 31 c0 xor %eax,%eax | |
movw %ax,%ds # -> Data Segment | |
7c03: 8e d8 mov %eax,%ds | |
movw %ax,%es # -> Extra Segment | |
7c05: 8e c0 mov %eax,%es | |
movw %ax,%ss # -> Stack Segment | |
7c07: 8e d0 mov %eax,%ss | |
00007c09 <seta20.1>: | |
# Physical address line A20 is tied to zero so that the first PCs | |
# with 2 MB would run software that assumed 1 MB. Undo that. | |
# The boot loader must enable the 21st address bit using I/O to the keyboard controller on ports 0x64 & 0x60 | |
seta20.1: | |
# read the status register form the keyboard controller via the port 0x64 | |
inb $0x64,%al # Wait for not busy | |
7c09: e4 64 in $0x64,%al | |
testb $0x2,%al | |
7c0b: a8 02 test $0x2,%al | |
# If input buffer is full(bit1 is set), repeat | |
jnz seta20.1 | |
7c0d: 75 fa jne 7c09 <seta20.1> | |
# the CPU writes to port 0x64, the byte is interpreted as a command byte. | |
# Write output port(P2) ..0xd1 | |
movb $0xd1,%al # 0xd1 -> port 0x64 | |
7c0f: b0 d1 mov $0xd1,%al | |
outb %al,$0x64 | |
7c11: e6 64 out %al,$0x64 | |
00007c13 <seta20.2>: | |
seta20.2: | |
inb $0x64,%al # Wait for not busy | |
7c13: e4 64 in $0x64,%al | |
testb $0x2,%al | |
7c15: a8 02 test $0x2,%al | |
jnz seta20.2 | |
7c17: 75 fa jne 7c13 <seta20.2> | |
# Command 0xdf: Enable A20 address line | |
movb $0xdf,%al # 0xdf -> port 0x60 | |
7c19: b0 df mov $0xdf,%al | |
# If the CPU writes to port 0x60, the byte is interpreted as a data byte. | |
# WHY? | |
# suppose that It can be read/written by writing 0x20/0x60 to port 0x64 and then reading/writing a data byte from/to port 0x60. | |
outb %al,$0x60 | |
7c1b: e6 60 out %al,$0x60 | |
# Switch from real to protected mode. Use a bootstrap GDT that makes | |
# virtual addresses map directly to physical addresses so that the | |
# effective memory map doesn't change during the transition. | |
lgdt gdtdesc | |
7c1d: 0f 01 16 lgdtl (%esi) | |
7c20: 78 7c js 7c9e <readsect+0xe> | |
movl %cr0, %eax | |
7c22: 0f 20 c0 mov %cr0,%eax | |
#define CR0_PE 0x00000001 // Protection Enable | |
orl $CR0_PE, %eax | |
7c25: 66 83 c8 01 or $0x1,%ax | |
movl %eax, %cr0 | |
7c29: 0f 22 c0 mov %eax,%cr0 | |
# translation, so that the mapping is still the identity mapping. | |
#define SEG_KCODE 1 // kernel code | |
# cannot modify %cs directly, so instead the code executes an ljmp instruction | |
# set %cs <- $(SEG_CODE<<3) = 0x08, which is at the 2nd GDT entry | |
ljmp $(SEG_KCODE<<3), $start32 | |
7c2c: ea .byte 0xea | |
# %cs:($0x007c31) | |
7c2d: 31 7c 08 00 xor %edi,0x0(%eax,%ecx,1) | |
00007c31 <start32>: | |
.code32 # Tell assembler to generate 32-bit code now. | |
start32: | |
# Set up the protected-mode data segment registers | |
#define SEG_KDATA 2 // kernel data+stack | |
movw $(SEG_KDATA<<3), %ax # Our data segment selector | |
7c31: 66 b8 10 00 mov $0x10,%ax | |
# %ds <- 0x10, which is the 3rd index GDT entry | |
movw %ax, %ds # -> DS: Data Segment | |
7c35: 8e d8 mov %eax,%ds | |
movw %ax, %es # -> ES: Extra Segment | |
7c37: 8e c0 mov %eax,%es | |
movw %ax, %ss # -> SS: Stack Segment | |
7c39: 8e d0 mov %eax,%ss | |
movw $0, %ax # Zero segments not ready for use | |
7c3b: 66 b8 00 00 mov $0x0,%ax | |
movw %ax, %fs # -> FS | |
7c3f: 8e e0 mov %eax,%fs | |
movw %ax, %gs # -> GS | |
7c41: 8e e8 mov %eax,%gs | |
# Set up the stack pointer and call into C. | |
movl $start, %esp | |
7c43: bc 00 7c 00 00 mov $0x7c00,%esp | |
call bootmain | |
7c48: e8 d5 00 00 00 call 7d22 <bootmain> | |
# If bootmain returns (it shouldn't), trigger a Bochs | |
# Bochs is a highly portable open source IA-32 (x86) PC emulator | |
# breakpoint if running under Bochs, then loop. | |
movw $0x8a00, %ax # 0x8a00 -> port 0x8a00 | |
7c4d: 66 b8 00 8a mov $0x8a00,%ax | |
movw %ax, %dx | |
7c51: 66 89 c2 mov %ax,%dx | |
outw %ax, %dx | |
7c54: 66 ef out %ax,(%dx) | |
# return the Bochs to the debugger prompt. Basically the same as doing CTRL+C. | |
movw $0x8ae0, %ax # 0x8ae0 -> port 0x8a00 | |
7c56: 66 b8 e0 8a mov $0x8ae0,%ax | |
outw %ax, %dx | |
7c5a: 66 ef out %ax,(%dx) | |
00007c5c <spin>: | |
spin: | |
jmp spin | |
7c5c: eb fe jmp 7c5c <spin> | |
7c5e: 66 90 xchg %ax,%ax | |
## Global Destriptor table(8byte*3entries) | |
00007c60 <gdt>: | |
## put the LGDT register(2+4byte) | |
00007c78 <gdtdesc>: | |
# bootmain.c | |
## bootmain() loads an ELF kernel image from the disk starting at | |
## sector 1 on the and then jumps to the kernel entry routine. | |
00007c7e <waitdisk>: | |
00007c90 <readsect>: | |
00007ce3 <readseg>: | |
00007d22 <bootmain>: | |
{ | |
00007d22 <bootmain>: | |
{ | |
7d22: 55 push %ebp | |
7d23: 89 e5 mov %esp,%ebp | |
7d25: 57 push %edi | |
7d26: 56 push %esi | |
7d27: 53 push %ebx | |
7d28: 83 ec 0c sub $0xc,%esp | |
readseg((uchar*)elf, 4096, 0); // 4096 = 0x1000 | |
7d2b: 6a 00 push $0x0 | |
7d2d: 68 00 10 00 00 push $0x1000 | |
// ELF binary places in-memory copy at address 0x10000 | |
// elf = (struct elfhdr*)0x10000; // scratch space | |
7d32: 68 00 00 01 00 push $0x10000 | |
7d37: e8 a7 ff ff ff call 7ce3 <readseg> | |
if(elf->magic != ELF_MAGIC) | |
7d3c: 83 c4 0c add $0xc,%esp | |
7d3f: 81 3d 00 00 01 00 7f cmpl $0x464c457f,0x10000 | |
7d46: 45 4c 46 | |
7d49: 75 50 jne 7d9b <bootmain+0x79> | |
ph = (struct proghdr*)((uchar*)elf + elf->phoff); | |
7d4b: a1 1c 00 01 00 mov 0x1001c,%eax | |
7d50: 8d 98 00 00 01 00 lea 0x10000(%eax),%ebx | |
eph = ph + elf->phnum; | |
7d56: 0f b7 35 2c 00 01 00 movzwl 0x1002c,%esi | |
7d5d: c1 e6 05 shl $0x5,%esi | |
7d60: 01 de add %ebx,%esi | |
for(; ph < eph; ph++){ | |
7d62: 39 f3 cmp %esi,%ebx | |
7d64: 73 2f jae 7d95 <bootmain+0x73> | |
pa = (uchar*)ph->paddr; | |
7d66: 8b 7b 0c mov 0xc(%ebx),%edi | |
readseg(pa, ph->filesz, ph->off); | |
7d69: ff 73 04 pushl 0x4(%ebx) | |
7d6c: ff 73 10 pushl 0x10(%ebx) | |
7d6f: 57 push %edi | |
7d70: e8 6e ff ff ff call 7ce3 <readseg> | |
if(ph->memsz > ph->filesz) | |
7d75: 8b 4b 14 mov 0x14(%ebx),%ecx | |
7d78: 8b 43 10 mov 0x10(%ebx),%eax | |
7d7b: 83 c4 0c add $0xc,%esp | |
7d7e: 39 c1 cmp %eax,%ecx | |
7d80: 76 0c jbe 7d8e <bootmain+0x6c> | |
stosb(pa + ph->filesz, 0, ph->memsz - ph->filesz); | |
entry(); | |
# Note that `elf = (struct elfhdr*)0x10000; // scratch space` | |
# And that (char*)elf->entry - (char*)elf = 0x18 | |
# so the address of the `entry` variable is 0x10000 + 0x18. | |
7d95: ff 15 18 00 01 00 call *0x10018 | |
} | |
7d9b: 8d 65 f4 lea -0xc(%ebp),%esp | |
7d9e: 5b pop %ebx | |
7d9f: 5e pop %esi | |
7da0: 5f pop %edi | |
7da1: 5d pop %ebp | |
7da2: c3 ret |
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
Memory Configuration | |
Name Origin Length Attributes | |
*default* 0x00000000 0xffffffff | |
Linker script and memory map | |
Address of section .text set to 0x7c00 | |
LOAD bootasm.o | |
LOAD bootmain.o | |
[!provide] PROVIDE (__executable_start = SEGMENT_START ("text-segment", 0x8048000)) | |
0x08048054 . = (SEGMENT_START ("text-segment", 0x8048000) + SIZEOF_HEADERS) | |
.interp | |
*(.interp) | |
.note.gnu.build-id | |
*(.note.gnu.build-id) | |
.hash | |
*(.hash) | |
.gnu.hash | |
*(.gnu.hash) | |
.dynsym | |
*(.dynsym) | |
.dynstr | |
*(.dynstr) | |
.gnu.version | |
*(.gnu.version) | |
.gnu.version_d | |
*(.gnu.version_d) | |
.gnu.version_r | |
*(.gnu.version_r) | |
.rel.init | |
*(.rel.init) | |
.rel.text | |
*(.rel.text .rel.text.* .rel.gnu.linkonce.t.*) | |
.rel.fini | |
*(.rel.fini) | |
.rel.rodata | |
*(.rel.rodata .rel.rodata.* .rel.gnu.linkonce.r.*) | |
.rel.data.rel.ro | |
*(.rel.data.rel.ro .rel.data.rel.ro.* .rel.gnu.linkonce.d.rel.ro.*) | |
.rel.data | |
*(.rel.data .rel.data.* .rel.gnu.linkonce.d.*) | |
.rel.tdata | |
*(.rel.tdata .rel.tdata.* .rel.gnu.linkonce.td.*) | |
.rel.tbss | |
*(.rel.tbss .rel.tbss.* .rel.gnu.linkonce.tb.*) | |
.rel.ctors | |
*(.rel.ctors) | |
.rel.dtors | |
*(.rel.dtors) | |
.rel.got 0x08048054 0x0 | |
*(.rel.got) | |
.rel.got 0x08048054 0x0 bootasm.o | |
.rel.bss | |
*(.rel.bss .rel.bss.* .rel.gnu.linkonce.b.*) | |
.rel.ifunc | |
*(.rel.ifunc) | |
.rel.plt 0x08048054 0x0 | |
*(.rel.plt) | |
[!provide] PROVIDE (__rel_iplt_start = .) | |
*(.rel.iplt) | |
.rel.iplt 0x08048054 0x0 bootasm.o | |
[!provide] PROVIDE (__rel_iplt_end = .) | |
.init | |
*(SORT_NONE(.init)) | |
.plt 0x08048058 0x0 | |
*(.plt) | |
*(.iplt) | |
.iplt 0x08048058 0x0 bootasm.o | |
.plt.got | |
*(.plt.got) | |
.plt.sec | |
*(.plt.sec) | |
.text 0x00007c00 0x1a3 | |
*(.text.unlikely .text.*_unlikely .text.unlikely.*) | |
*(.text.exit .text.exit.*) | |
*(.text.startup .text.startup.*) | |
*(.text.hot .text.hot.*) | |
*(.text .stub .text.* .gnu.linkonce.t.*) | |
.text 0x00007c00 0x7e bootasm.o | |
0x00007c00 start | |
.text 0x00007c7e 0x125 bootmain.o | |
0x00007c7e waitdisk | |
0x00007c90 readsect | |
0x00007ce3 readseg | |
0x00007d22 bootmain | |
*(.gnu.warning) | |
.fini | |
*(SORT_NONE(.fini)) | |
[!provide] PROVIDE (__etext = .) | |
[!provide] PROVIDE (_etext = .) | |
[!provide] PROVIDE (etext = .) | |
.rodata | |
*(.rodata .rodata.* .gnu.linkonce.r.*) | |
.rodata1 | |
*(.rodata1) | |
.eh_frame_hdr | |
*(.eh_frame_hdr) | |
*(.eh_frame_entry .eh_frame_entry.*) | |
.eh_frame 0x00007da4 0xb8 | |
*(.eh_frame) | |
.eh_frame 0x00007da4 0xb8 bootmain.o | |
*(.eh_frame.*) | |
.gcc_except_table | |
*(.gcc_except_table .gcc_except_table.*) | |
.gnu_extab | |
*(.gnu_extab*) | |
.exception_ranges | |
*(.exception_ranges .exception_ranges*) | |
0x00007e5c . = . | |
.eh_frame | |
*(.eh_frame) | |
*(.eh_frame.*) | |
.gnu_extab | |
*(.gnu_extab) | |
.gcc_except_table | |
*(.gcc_except_table .gcc_except_table.*) | |
.exception_ranges | |
*(.exception_ranges .exception_ranges*) | |
.tdata 0x00007e5c 0x0 | |
[!provide] PROVIDE (__tdata_start = .) | |
*(.tdata .tdata.* .gnu.linkonce.td.*) | |
.tbss | |
*(.tbss .tbss.* .gnu.linkonce.tb.*) | |
*(.tcommon) | |
.preinit_array 0x00007e5c 0x0 | |
[!provide] PROVIDE (__preinit_array_start = .) | |
*(.preinit_array) | |
[!provide] PROVIDE (__preinit_array_end = .) | |
.init_array 0x00007e5c 0x0 | |
[!provide] PROVIDE (__init_array_start = .) | |
*(SORT_BY_INIT_PRIORITY(.init_array.*) SORT_BY_INIT_PRIORITY(.ctors.*)) | |
*(.init_array EXCLUDE_FILE(*crtend?.o *crtend.o *crtbegin?.o *crtbegin.o) .ctors) | |
[!provide] PROVIDE (__init_array_end = .) | |
.fini_array 0x00007e5c 0x0 | |
[!provide] PROVIDE (__fini_array_start = .) | |
*(SORT_BY_INIT_PRIORITY(.fini_array.*) SORT_BY_INIT_PRIORITY(.dtors.*)) | |
*(.fini_array EXCLUDE_FILE(*crtend?.o *crtend.o *crtbegin?.o *crtbegin.o) .dtors) | |
[!provide] PROVIDE (__fini_array_end = .) | |
.ctors | |
*crtbegin.o(.ctors) | |
*crtbegin?.o(.ctors) | |
*(EXCLUDE_FILE(*crtend?.o *crtend.o) .ctors) | |
*(SORT_BY_NAME(.ctors.*)) | |
*(.ctors) | |
.dtors | |
*crtbegin.o(.dtors) | |
*crtbegin?.o(.dtors) | |
*(EXCLUDE_FILE(*crtend?.o *crtend.o) .dtors) | |
*(SORT_BY_NAME(.dtors.*)) | |
*(.dtors) | |
.jcr | |
*(.jcr) | |
.data.rel.ro | |
*(.data.rel.ro.local* .gnu.linkonce.d.rel.ro.local.*) | |
*(.data.rel.ro .data.rel.ro.* .gnu.linkonce.d.rel.ro.*) | |
.dynamic | |
*(.dynamic) | |
.got 0x00007e5c 0x0 | |
*(.got) | |
.got 0x00007e5c 0x0 bootasm.o | |
*(.igot) | |
.got.plt 0x00007e5c 0x0 | |
*(.got.plt) | |
.got.plt 0x00007e5c 0x0 bootasm.o | |
*(.igot.plt) | |
.igot.plt 0x00007e5c 0x0 bootasm.o | |
.data 0x00007e5c 0x0 | |
*(.data .data.* .gnu.linkonce.d.*) | |
.data 0x00007e5c 0x0 bootasm.o | |
.data 0x00007e5c 0x0 bootmain.o | |
.data1 | |
*(.data1) | |
0x00007e5c _edata = . | |
[!provide] PROVIDE (edata = .) | |
0x00007e5c . = . | |
0x00007e5c __bss_start = . | |
.bss 0x00007e5c 0x0 | |
*(.dynbss) | |
*(.bss .bss.* .gnu.linkonce.b.*) | |
.bss 0x00007e5c 0x0 bootasm.o | |
.bss 0x00007e5c 0x0 bootmain.o | |
*(COMMON) | |
0x00007e5c . = ALIGN ((. != 0x0)?0x4:0x1) | |
0x00007e5c . = ALIGN (0x4) | |
0x00007e5c . = SEGMENT_START ("ldata-segment", .) | |
0x00007e5c . = ALIGN (0x4) | |
0x00007e5c _end = . | |
[!provide] PROVIDE (end = .) | |
.stab | |
*(.stab) | |
.stabstr | |
*(.stabstr) | |
.stab.excl | |
*(.stab.excl) | |
.stab.exclstr | |
*(.stab.exclstr) | |
.stab.index | |
*(.stab.index) | |
.stab.indexstr | |
*(.stab.indexstr) | |
.comment 0x00000000 0x11 | |
*(.comment) | |
.comment 0x00000000 0x11 bootmain.o | |
0x12 (size before relaxing) | |
.debug | |
*(.debug) | |
.line | |
*(.line) | |
.debug_srcinfo | |
*(.debug_srcinfo) | |
.debug_sfnames | |
*(.debug_sfnames) | |
.debug_aranges 0x00000000 0x40 | |
*(.debug_aranges) | |
.debug_aranges | |
0x00000000 0x20 bootasm.o | |
.debug_aranges | |
0x00000020 0x20 bootmain.o | |
.debug_pubnames | |
*(.debug_pubnames) | |
.debug_info 0x00000000 0x50e | |
*(.debug_info .gnu.linkonce.wi.*) | |
.debug_info 0x00000000 0x26 bootasm.o | |
.debug_info 0x00000026 0x4e8 bootmain.o | |
.debug_abbrev 0x00000000 0x1ea | |
*(.debug_abbrev) | |
.debug_abbrev 0x00000000 0x14 bootasm.o | |
.debug_abbrev 0x00000014 0x1d6 bootmain.o | |
.debug_line 0x00000000 0x12c | |
*(.debug_line .debug_line.* .debug_line_end) | |
.debug_line 0x00000000 0x5d bootasm.o | |
.debug_line 0x0000005d 0xcf bootmain.o | |
.debug_frame | |
*(.debug_frame) | |
.debug_str 0x00000000 0x1e1 | |
*(.debug_str) | |
.debug_str 0x00000000 0x36 bootasm.o | |
.debug_str 0x00000036 0x1ab bootmain.o | |
0x1e2 (size before relaxing) | |
.debug_loc 0x00000000 0x15c | |
*(.debug_loc) | |
.debug_loc 0x00000000 0x15c bootmain.o | |
.debug_macinfo | |
*(.debug_macinfo) | |
.debug_weaknames | |
*(.debug_weaknames) | |
.debug_funcnames | |
*(.debug_funcnames) | |
.debug_typenames | |
*(.debug_typenames) | |
.debug_varnames | |
*(.debug_varnames) | |
.debug_pubtypes | |
*(.debug_pubtypes) | |
.debug_ranges | |
*(.debug_ranges) | |
.debug_macro | |
*(.debug_macro) | |
.debug_addr | |
*(.debug_addr) | |
.gnu.attributes | |
*(.gnu.attributes) | |
/DISCARD/ | |
*(.note.GNU-stack) | |
*(.gnu_debuglink) | |
*(.gnu.lto_*) | |
OUTPUT(bootblock.o elf32-i386) |
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
# set prefix on `i386-jos-elf-`. See detail for the page, https://pdos.csail.mit.edu/6.828/2018/tools.html. | |
## -nostdinc: no std include | |
$ gcc -fno-pic -static -fno-builtin -fno-strict-aliasing -O2 -Wall -MD -ggdb -m32 -Werror -fno-omit-frame-pointer -fno-stack-protector -fno-pic -O -nostdinc -I. -c bootmain.c | |
$ gcc -fno-pic -static -fno-builtin -fno-strict-aliasing -O2 -Wall -MD -ggdb -m32 -Werror -fno-omit-frame-pointer -fno-stack-protector -fno-pic -nostdinc -I. -c bootasm.S | |
## -m: Emulate the emulation linker. -N: Set the text and data sections to be readable and writable. | |
## -e start: Use entry as the explicit symbol for beginning execution of your program | |
## -Ttext 0x7C00: Locate a section in the output file at the absolute address given by 0x7C00. | |
$ ld -m elf_i386 -N -e start -Ttext 0x7C00 -o bootblock.o bootasm.o bootmain.o -M | |
$ objdump -S bootblock.o > bootblock.asm |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment