0% found this document useful (0 votes)
7 views

03 Boot

The document discusses the boot process of an x86 computer, beginning with the BIOS initializing hardware and loading the first disk sector containing the bootloader, which then loads and transfers control to the operating system binary stored in ELF format on the disk. It also covers backward compatibility methods like 16-bit segments and descriptor tables that allow older 16-bit code to run on 32-bit and 64-bit processors.
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
7 views

03 Boot

The document discusses the boot process of an x86 computer, beginning with the BIOS initializing hardware and loading the first disk sector containing the bootloader, which then loads and transfers control to the operating system binary stored in ELF format on the disk. It also covers backward compatibility methods like 16-bit segments and descriptor tables that allow older 16-bit code to run on 32-bit and 64-bit processors.
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 15

Booting

Backward compatibility: x86 segments, descriptor tables


BIOS, Bootloader, Read/write disk sectors, ELF format

Abhilash Jindal Reference. xv6 book: Appendix B


Agenda

• Boot a minimal OS!


• Understand code
• Learn what happens when we power on a computer
• Learn few more x86 details required for booting
Boot up sequence (1): BIOS

• For backward
compatibility, PC
boots in 16-bit mode

• BIOS does initial


BIOS ROM
0x00100000
eip BIOS ROM
0x00100000
hardware check: are
eip 0x000F0000 0x000F0000 CPUs, memory, disk
functional?
0x000C0000 0x000C0000
VGA display VGA display
0x000A0000 0x000A0000
Boot up sequence (2): Bootloader

• BIOS loads first disk


sector (512 bytes) at
0x7c00 and gives
control

eip BIOS ROM


0x00100000
BIOS ROM
0x00100000
• We need to write a
0x000F0000 0x000F0000 boot loader that
fits in the first
sector of disk
0x000C0000 0x000C0000
VGA display VGA display
0x000A0000 0x000A0000
• Boot loader changes
Bootloader
0x00007C00 eip
Bootloader
0x00007C00 to 32 bit mode
Boot up sequence (3): OS

• gcc prepares OS image


in Executable and
Linkable Format (ELF)

OS OS
• Bootloader copies OS
0x00100000 eip 0x00100000 image starting from
BIOS ROM BIOS ROM disk sector 1 to
0x000F0000 0x000F0000
0x100000 and transfers
control to it

VGA display
0x000C0000
VGA display
0x000C0000
• We need to tell gcc that
0x000A0000 0x000A0000
image will be loaded at
eip Bootloader
0x00007C00
Bootloader
0x00007C00
0x100000
Backward compatibility

• When boot loader gets control, the CPU is in 16-bit mode


• This is for backward compatibility. OS written for 16-bit mode should just
work for 32-bit and 64-bit machines

• Bootloader explicitly switches from 16-bit mode to 32-bit mode


• Understand how hardware provides backward compatibility and some
historical details of 16-bit architecture
16-bit registers
• All registers were 16-bit on 16-bit
CPU

• movw %ax, %bx : move low 16


bits of %eax into 16 bits of %ebx

• movb %al, %bl : move low 8 bits of


%eax into 8 bits of %ebx

• When CPU is in 16-bit mode, 32-bit


and 64-bit machines continue to
support same opcode for these
instructions
Segment registers
• 16-bit registers can only point up to 2^16 (=64KB)
addresses in DRAM
CPU
• Full address = (segment registers : offset)
segment:offset
• code segment (cs): ip
• stack segment (ss): sp / bp. MMU

push, pop

• data segment (ds): ax, bx, cx, dx. (segment<<4) + offset


mov (%bx) %ax
Reach up to 2^20 (= 1MB)
• extra segment (es): si, di of addresses
movsb
Far pointers in 16-bit x86

#include <stdio.h>
• p points to (0x5555 << 4) + 0x0005
int foo() { = 0x55555
char far *p =(char far *)0x55550005;
char far *q =(char far *)0x53332225; • q points to (0x5333 << 4) + 0x2225
*p = 80; = 0x55555
(*p)++;
printf("%d",*q);
return 0; • Multiple ways of referencing same
} address making them awkward to
control
Outputs 81
Segment registers in 32-bit
• 32-bit registers can point to 2^32 (=4GB) memory.
• “Protected mode”: extend segment registers for protection

Global Descriptor Table GDTR: Global descriptor


table register
S.No.* Permission Base Limit
cs: top 13 bits
0b…10xxx 0x01 WRITE

0x02 EXECUTE 0x1F 0xFF

… … … …

*: S.No. added only for illustration


CPU
Address translation cs:eip

Global Descriptor Table MMU


cs: top 13 bits
S.No.* Permission Base Limit
0b…10xxx assert(eip < limit)
0x01 WRITE addr = base + eip
0x02 EXECUTE 0x1F 0xFF

… … … …

• Can “protect” different segments from each 0xFF


other 0x1F
Global descriptor table
• Upto 2^13 (=8192)
segment descriptors

• Segment descriptor:
• 32 bit base
• 20 bit limit
• If G=1,
granularity=4KB.

• Max memory
within 1 segment
= 2^20*2^12 =
4GB
Segmented memory model
• Stack cannot grow into code section
Multi-segment
model 23
esp

• Best protection
• Difficult to program

movl %esp %ecx

addl $1 (%ecx)
42
Does not add 1 to the ecx
value at top of the
stack!
Flat memory model

• Easier to program
• Used by xv6

You might also like