300 likes | 627 Views
Writing Boot Loader with GAS in AT&T X86 Assembly. Dennis Chen. Outline. Introduction Conceptual Flow Prerequisites Implementation Debugging Techniques Demo. Introduction. Scope Load file from floppy image of FAT12 format Execute in real mode No 32-bit addressing
E N D
Writing Boot Loader with GAS in AT&T X86 Assembly Dennis Chen
Outline • Introduction • Conceptual Flow • Prerequisites • Implementation • Debugging Techniques • Demo
Introduction • Scope • Load file from floppy image of FAT12 format • Execute in real mode • No 32-bit addressing • No protected mode enabled • Goal • Use minimal tools available on Linux • Require no root privileges • Modulize as possible as it can • Kept in small footprint (of 512 bytes)
Introduction • Development Environment • Ubuntu 10.10 LTS • Vim + xxd • gmake + binutils • as, ld, objcopy, objdump • gdb
Conceptual Flow • 1. BIOS finds the bootable disk • 2. BIOS loads boot loader: • from the first sector (512 bytes) of the disk • to logical address 0000:7c00h • 3. Jump to the start of boot loader (0000:7c00h) • 4. Boot loader loads FAT and root directory in memory • 5. Boot loader finds specific name “kernel.bin” • by looking up root directory • for the first cluster# if it’s available • 6. Boot loader loads first cluster of “kernel.bin” in memory • e.g., 0050:0000h or 9000:0100h • 7. Boot loader queries FAT entry • to get the next cluster# • Go to step 6 if it’s available; otherwise, go to step 8. • 8. Jump to the start of “kernel.bin” in memory • e.g., 0050:0000h or 9000:0100h
Prerequisites • X86 Assembly Language • AT&T Syntax: GAS • Intel Syntax: MASM, NASM • Addressing in Real Mode • X86 Memory Layout • Locating Data in Floppy • LBA vs. CHS • FAT12 Specification • Tools • Binutils: as, ld, objdump, objcopy • Emulator: qemu or bochs • Debugger: gdb
X86 Assembly Language • Examples: • AT&T Syntax • mov %ax, %bx • mov $0x1234, %ax • movw (%bx), %ax • Intel Syntax • mov bx, ax • mov ax, 1234h • mov ax, word ptr [bx]
Addressing in Real Mode • Logical Address • Syntax: <segment>:<offset> • Range: 1 MiB (220) • e.g., 0000:7c00h = 07c0:0000h • Linear Address • Translation from Logical Address • <segment> * 16 + <offset> • e.g., 9000:0100h = 90100h
Low Memory Area (<=1 MiB) X86 Memory Layout
Units for Locating Disk Data • LBA • Logical Block Addressing • CHS • Cylinder-Head-Sector • Track • Track #0 is located at outer most circle • Cylinder • Same track# spanning platters • Head • 2 Heads for 3.5” 1.44 Floppy • Sector • #1 to #63 (26 - 1) • Off-by-one defect in BIOS • 512 bytes per sector as regularly used • Cluster • A set of sectors
FAT12 Specification • Boot Sector Format • Root Directory • FAT12 Entry Boot Sector FAT #1 FAT #2 Root Directory Data
Boot Sector Format jmp start (0x003d) start: (0x0040 – 3) BPB (BIOS Parameter Block) Boot Code End of Boot Sector (0xaa55)
Boot Sector Format • Byte 0x000~0x002 • jmp start • eb xx 90 • Short jump with small offset (-128 ~127) • Padded with NOP (0x90) • e9 xx xx • Short jump with offset (-32768 ~ 32767) • Byte 0x003~0x03d • BPB (BIOS Parameter Block)
Boot Sector Format • BPB (BIOS Parameter Block) for FAT12
Boot Sector Format • Byte 0x03e~0x1fd • Boot code • Maximum size: 448 bytes • Byte 0x1fe~0x1ff • Signature for end of boot code • 0x55, 0xaa (= 0xaa55)
Root Directory • 32 bytes per entry • Short file name entry • Long file name entry Entry for long file name 0002600: 416b 0065 0072 006e 0065 000f 00da 6c00 Ak.e.r.n.e....l.0002610: 2e00 6200 6900 6e00 0000 0000 ffff ffff ..b.i.n......... 0002620: 4b45 524e 454c 2020 4249 4e20 1800 b355 KERNEL BIN ...U 0002630: 253f 253f 0000 b355 253f 0200 8504 0000 %?%?...U%?...... Entry for short file name
FAT12 Entry • Every FAT entry • occupies 12 bits of a word (2 bytes) • can be indexed by current cluster# • contains the next cluster# or EOC • byte offset# = (cluster# - 2) * 3 / 2 • even_or_odd = (cluster# - 2) * 3 % 2 • FAT Entry (even) = [Byte 0-1] & 0x0fff • FAT Entry (odd) = [Byte 1-2] >> 4 Byte 1 Byte 2 Byte 0 0 8 4 1 9 5 2 A 6 3 B 7 4 0 8 5 1 9 6 2 A 7 3 B FAT Entry (even) FAT Entry (odd)
FAT12 Entry Value of FAT entry
Implementation • Boot code • bpb.s • BPB header and trailing signature • boot.s • Main boot code • console.s • Utility of Console printing using INT 10h • disk.s • Utility of disk accessing using INT 13h • kernel.s • Mock kernel for loading
Implementation • SECTIONS { • . = 0x7c00; • .text : { • .begin = .; • bpb.o (.text); • boot.o (.text); • * (.text); • . = .begin + 510; • bpb.o (.signature); • } • } • SECTIONS { • . = 0x0000; • .text : { • kernel.o (.text) • * (.text) • } • } • Script • boot.ld • kernel.ld
Implementation • Generated Targets • boot.img • Bootable disk image • boot.bin • Bare boot code • boot.elf • Boot code with ELF header and debug information • kernel.bin • Bare kernel binary • kernel.elf • Kernel binary with ELF header and debug information
Debugging Techniques • INT 10h BIOS call • Print asciiz string • Print character • It requires further impl. to output numbers • Remote debugging with gdb • Turn on debug symbol with -g option for as and ld • Edit .gdbinit file: • target remote | exec qemu -gdbstdio -fdaboot.img • symbol-file boot.elfkernel.elf • Enter “gdb” at command line
Debugging Techniques • Launch QEMU directly • Enter “qemu -fda boot.img” at command line • Launch Bochs directly • Edit bochsrc.txt file: • boot: floppy • floppya: type=1_44, 1_44=“boot.img”, inserted • Enter “bochs” at command line
Reference • Orange’s一個作業系統的實現 (ISBN 978-986-7309-52-2) • 使用开源软件自己动手写操作系统 • http://code.google.com/p/writeos/downloads/list • X86 Memory Map • http://wiki.osdev.org/Memory_Map_(x86) • Disk Manipulation • http://en.wikipedia.org/wiki/INT_13H • http://zh.wikipedia.org/wiki/LBA • http://en.wikipedia.org/wiki/Cylinder-head-sector • Boot Sector & FAT • http://wiki.osdev.org/MBR • http://wiki.osdev.org/FAT • http://en.wikipedia.org/wiki/File_Allocation_Table • http://www.microsoft.com/whdc/system/platform/firmware/fatgen.mspx