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

Boot

1. When the computer is switched on, the instruction pointer is set to address FFFF0 to begin execution in real mode under the BIOS. 2. The BIOS performs power-on self-tests and finds the boot device by searching partition boot sectors. 3. Once the master boot record is found, it loads the first stage bootloader (GRUB), which then loads the second stage and kernel image.

Uploaded by

memoarfaa
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
189 views

Boot

1. When the computer is switched on, the instruction pointer is set to address FFFF0 to begin execution in real mode under the BIOS. 2. The BIOS performs power-on self-tests and finds the boot device by searching partition boot sectors. 3. Once the master boot record is found, it loads the first stage bootloader (GRUB), which then loads the second stage and kernel image.

Uploaded by

memoarfaa
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 10

New Jersey Institute of Technology Computer Science Department

Tue, 1/24/2017 v4.10


Chapter 2 Booting
• Turn the switch on
• RIP = FFFF0 (last 16B segment), operates in DOS real mode (max 1 MB)
• BIOS - basic input output system EEPROM (flash memory)
• CMOS flash memory
• POST Power On Self Test - inventory checking
• Search primary active disk for boot record
• BIOS reads boot.S MBR master boot record 512 B (HCS001): bootloader (446
B) + partitions (64 B) + signature (2 B)
• GRUB stage1: boot.S (MBR) -> diskboot.S -> startup.S -> grub_main() in
main.c
• GRUB stage2: grub_main -> ... -> grub_show_menu -> show_menu ->
grub_menu_execute_entry -> 1 grub_parser_execute; 2
grub_command_execute -> grub_linux_boot -> code32_start
• Linux/arch/x86/boot/header.S --> arch/x86/boot/main.c --> arch/x86/boot/pm.c -
-> arch/x86/boot/pmjump.S
• startup_32() #1: arch/x86/boot/compressed/head_32.S -> extract_kernel()
• startup_32() #2: arch/x86/kernel/head_32.S: initial_code -> i386_start_kernel
• head_32.c: i386_start_kernel -> start_kernel
• Linux/init/main.c: start_kernel()

CS680 Linux Kernel Programming 1 Spring 2017 Andrew Sohn


New Jersey Institute of Technology Computer Science Department
Machine booting process: Power-on to start_kernel()

63 RIP 0 Main Memory 1. Flip the switch


1 FFFF0
the very
first addre FFFFF 1MB
2. RIP - FFFF0 (operate in DOS real
ss mode)
the last segment of 1MB 2 16 Bytes FFFF0 3. BIOS - basic input output system
ROM
switch on 4. POST power on self test
5. CMOS flash memory
6. Search boot device for OS boot sec-
1MB FFFFF tor
7. Copy MBR to 0x7c00 (defined in
boot.S)
8. BIOS loads MBR.
3 9. Grub stage1: boot.S, diskboot.S,
BIOS ROM startup.S
1MB
BOOT 10. Grub stage2: show_menu()
use int x13
(bios interrupt)
7 defined in 11. arch/x86/boot/header.S > main.c ->
MBR 512B 07C00 boot.S 12. -> pm.c -> pmjump.S
4 13. compressed/head_32.S: startup_32()
POST 8 00000 0B #1
14. kernel/head_32.S: startup_32() #2
0B 00000
15. i386_start_kernel()
16. init/main.c: start_kernel()
6 search boot sector 5
MBR CHS=001 (512B)
256B FF

CMOS Flash Primary active bootable disk


Memory 256B

0B 00

CS680 Linux Kernel Programming 2 Spring 2017 Andrew Sohn


New Jersey Institute of Technology Computer Science Department

Basic Input Output System (BIOS) ROM


• Flip the switch - power good signal from the power supply
• instruction pointer (RIP/EIP or program counter) is loaded FFFF0 (FFFFF is 1
MB - IBM DOS real mode). FFFF0 is hardwired by microprocessor/mobo.
• FFFF0 has a jump instruction to jump to BIOS ROM.
• Executes routines at the memory mapped to BIOS ROM
• power on self test (POST)
• look for video card, video card’s built in BIOS program at xC000, executes.
• look for other device’s ROMs, IDE/ATA disk BIOS at xC8000, executes.
• display startup screen
• memory count-up test
• perform a system inventory, search for COM and LPT ports.
• Detect and configure Plug and Play devices
• display a summary screen about system configuration
• search for a drive to boot from: A, B, C, ... using the CMOS boot sequence set-
ting.
• Search for a master boot record at CHS=001.
• Copy MBR to RAM at 0x7C00 (BOOT defined in boot.S) -> boot.S=grup stage
1

CS680 Linux Kernel Programming 3 Spring 2017 Andrew Sohn


New Jersey Institute of Technology Computer Science Department
CMOS Flash memory
Basic Input Output Systems (BIOS EEPROM)

(n+p type transistor) BIOS


CMOS Flash
256B

... FF • in mega btyes


... ..

... .. • Vendors include


century
...
32
..
• American Megatrends (AMI)
... .. Status Register A • Phoenix
RTC SR B 0B 7 6 5 4 3 2 1 0
RTC SR A 0A -- -- -- -- -- -- -- --
• Insyde Software
year 09
• AwardBIOS
month 08 1 for binary, 0 for BCD
date 07 • AMIBIOS
1 for 24 hour format
day
hour
06
05
• SeaBIOS
hour 04 7 6 5 4 3 2 1 0
minute 03 0 0 0 1 0 0 0 0 binary

02 for 16
minute
second 01 0 0 0 1 0 1 1 0 BCD

second 00

8 bits

CS680 Linux Kernel Programming 4 Spring 2017 Andrew Sohn


New Jersey Institute of Technology Computer Science Department
Master Boot Record C:H:S=0:0:1 (512 B)
Cylinder 0: Head 0: Sector 1

Master boot record

magic number AA55 (2B) 1FE Partition table entry 16 Bytes

Byte15

Byte0
partition table 4 entries partition type FAT/EXT2/VFAT...
(total 64B)
each entry 16B B15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 B0
PS H CS C PT H CS C starting LBA # of sectors
(LBA=logical block addressing)
starting CHS ending CHS

Byte 15 Byte 14 Byte 13 Byte 12


76543210 765432107654321076543210
GRUB 1 Head Cy Sector Cylinder

C:H:S=10:8:6=24bits->16M sectors -> max 8GB


bit7=1: primary, active int x13
bootable partition
0: secondary LBA=32 bits -> 4G sectors -> max 2 TB

000

15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 little-endian: symmetric to avoid big/little endian problem


1 0 1 0 1 0 1 0 0 1 0 1 0 1 0 1 little endian: least significant byte in smallest address
big endian: most significant byte in smallest address
A A 5 5

CS680 Linux Kernel Programming 5 Spring 2017 Andrew Sohn


New Jersey Institute of Technology Computer Science Department
MBR 512 = 446 NOP
+ 64 + 2 boot drive after BPB, fa=CLI
jump to the next instruction
dd bs=512 count=1 if=/dev/sda | od -Ax -tx1z -v
JUMP 7C4A

BPB BIOS parameter block


stage2 location
000000 eb 48 90 d0 bc 00 7c fb 50 07 50 1f fc be 1b 7c >.H....|.P.P....|<
000010 bf 1b 06 50 57 b9 e5 01 f3 a4 cb bd be 07 b1 04 >...PW...........<
000020 38 6e 00 7c 09 75 13 83 c5 10 e2 f4 cd 18 8b f5 >8n.|.u..........<
boot drive

000030 83 c6 10 49 74 19 38 2c 74 f6 a0 b5 07 b4 03 02 >...It.8,t.......<
000040 80 00 00 80 41 b4 04 00 00 08 fa 90 90 f6 c2 80 >....A...........<
000050 75 02 b2 80 ea 59 7c 00 00 31 c0 8e d8 8e d0 bc >u....Y|..1......<
000060 00 20 fb a0 40 7c 3c ff 74 02 88 c2 52 f6 c2 80 >. ..@|<.t...R...<
000070 74 54 b4 41 bb aa 55 cd 13 5a 52 72 49 81 fb 55 LBA begins here
>tT.A..U..ZRrI..U<
000080 aa 75 43 a0 41 7c 84 c0 75 05 83 e1 01 74 37 66 >.uC.A|..u....t7f<
HDD error

000090 8b 4c 10 be 05 7c c6 44 ff 01 66 8b 1e 44 7c c7 >.L...|.D..f..D|.<
0000a0 04 10 00 c7 44 02 01 00 66 89 5c 08 c7 44 06 00 >....D...f.\..D..<
0000b0 70 66 31 c0 89 44 04 66 89 44 0c b4 42 cd 13 72 >pf1..D.f.D..B..r<
0000c0 05 bb 00 70 eb 7d b4 08 cd 13 73 0a f6 c2 80 0f >...p.}....s.....<
0000d0 84 f0 00 e9 8d 00 be 05 7c c6 44 ff 00 66 31 c0 save # of heads
>........|.D..f1.<
0000e0 88 f0 40 66 89 44 04 31 d2 88 ca c1 e2 02 88 e8 save # of cylinders
>[email protected]........<
0000f0 88 f4 40 89 44 08 31 c0 88 d0 c0 e8 02 66 89 04 >[email protected]..<
000100 66 a1 44 7c 66 31 d2 66 f7 34 88 54 0a 66 31 d2 save # of sectors
>f.D|f1.f.4.T.f1.<
72 2a = read error

000110 66 f7 74 04 88 54 0b 89 44 0c 3b 44 08 7d 3c 8a geom error


>f.t..T..D.;D.}<.<
000120 54 0d c0 e2 06 8a 4c 0a fe c1 08 d1 8a 6c 0c 5a >T.....L......l.Z<
000130 8a 74 0b bb 00 70 8e c3 31 db b8 01 02 cd 13 72
read 1 sector INT 13
>.t...p..1......r<
000140 2a 8c c3 8e 06 48 7c 60 1e b9 00 01 8e db 31 f6 >*....H|`......1.<
000150 31 ff fc f3 a5 1f 61 ff 26 42 7c be 7f 7d e8 40 jmp [7242 (or 0042)]
>1.....a.&B|..}.@<
000160 00 eb 0e be 84 7d e8 38 00 eb 06 be 8e 7d e8 30 >.....}.8.....}.0<
000170 00 be 93 7d e8 2a 00 eb fe 47 52 55 42 20 00 47 0042
>...}.*...GRUB .G< has 8000
000180 65 6f 6d 00 48 61 72 64 20 44 69 73 6b 00 52 65 display error messags
>eom.Hard Disk.Re<
000190 61 64 00 20 45 72 72 6f 72 00 bb 01 00 b4 0e cd >ad. Error.......< partition table
0001a0 10 ac 3c 00 75 f4 c3 00 00 00 00 00 00 00 00 00 >..<.u...........<
0001b0 00 00 00 00 00 00 00 00 b6 a0 fd 8c 00 00 80 01 >................<
0001c0 01 00 83 fe 3f 18 3f 00 00 00 9a 20 06 00 00 00 >....?.?.... ....<
0001d0 01 19 8e fe ff ff d9 20 06 00 13 5f 84 09 00 00 bootloader
>....... ..._....<
0001e0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 >................<
0001f0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 55 aa signature
>..............U.<
512B

000200
800:0000 = 0000:8000
CS680 Linux Kernel Programming 6 Spring 2017 Andrew Sohn
New Jersey Institute of Technology Computer Science Department
GRUB Stage 1
BIOS copies MBR boot.S to 0x7c00
• jmp to boot.S 0x7c00 Main Memory

grub-core/boot/i386/pc kernel compiles by “make bzImage”


boot.S at 0x7c00 high address for big kernel
100000 1MB
16 bytes
• copy diskboot.S image to buffer FFFF0
BIOS
GRUB_BOOT_MACHINE_BUFFER_SEG 0x7000
• copy from buffer to kernel_address
GRUB_BOOT_MACHINE_KERNEL_ADDR 0x8000
• jmp to kernel_address 0x8000
0
grub-core/kern/i386
diskboot.S 3 startup.S loaded by diskboot.S
---
0x8200

• copy startup.S image to 0x8200 4 1 diskboot.S loaded by boot.S


---
0x8000 kernel_address

• jump to 0x8200 startup.S


Stage1 MBR boot.S loaded by BIOS MBR
07C00
grub-core/kern/i386
2
startup.S
• call EXT_C(grub_main)
diskboot.S - buffer loaded by MBR boot.S buffer
x7000
---
---
x7000 8KB x8000 ?KB

CS680 Linux Kernel Programming 7 Spring 2017 Andrew Sohn


New Jersey Institute of Technology Computer Science Department
GRUB Stage 2
main.c commands/boot.c
• grub_machine_init()
• grub_load_modules(); • GRUB_MOD_INIT(boot)
-> grub_dl_load_core(); -> grub_register_command(“boot”,..);
-> grub_dl_call_init() -> grub_register_command_prio()
-> mod->init(mod) -> grub_command_list <- global var
• grub_register_core_commands()
such as ls, insmod, set, unset, env vars
=> grub_cmd_boot()
• grub_load_config() • GRUB_MOD_FINI(boot)
-> grub_parser_execute
• grub_load_normal_mode()
-> grub_dl_load(“normal”)
-> grub_command_execute(“normal”) • GRUB_MOD_INIT(linux)
-> cmd->func(cmd,argc,argv) => grub_cmd_linux()
• grub_cmd_linux
=> grub_cmd_normal() -> grub_loader_set(grub_linux_boot,...)
• grub_enter_normal_mode() -> grub_loader_boot_func = g_l_b
-> grub_normal_execute(config) -> grub_loader_loaded = 1
-> 1 read_config_file(config) -> loaded = 1
-> 2 grub_show_menu() • GRUB_MOD_FINI(boot)

CS680 Linux Kernel Programming 8 Spring 2017 Andrew Sohn


New Jersey Institute of Technology Computer Science Department
GRUB Stage 2
menu.c commands/boot.c
• show_menu() • GRUB_MOD_INIT(boot)
-> run_menu() -> grub_cmd_boot()
-> e = grub_menu_get_entry()
-> grub_menu_execute_entry(e) • grub_cmd_boot
-> a grub_script_execute_sorucecode -> grub_loader_boot(grub_linux_boot,...)
-> b grub_cmd_execute(“boot”,...) -> grub_loader_boot_func()
• GRUB_MOD_INIT(linux)
• a grub_script_execute_sourcecode
(entry->sourcecode) -> grub_cmd_linux()
-> parsed_script = grub_script_parse(line) • grub_cmd_linux
-> grub_script_execute(parsed_script) -> grub_loader_set(grub_linux_boot,...)
-> grub_script_execute_cmd(script->cmd) -> grub_loader_boot_func = g_l_b
-> cmd->exec(cmd) -> grub_loader_loaded = 1
-> loaded = 1
• b grub_cmd_execute(“boot”,...)
-> grub_cmd_boot()
-> grub_relocator_prepare_relocs()
-> grub_loader_boot()
-> grub_cpu_relocator_jumper()
-> grub_loader_boot_func() -> *relstart = rels0;
-> grub_linux_boot() -> asm volatile (“cli”)
-> state.eip = params->code32_start -> ((void (*) (void)) relst) ()
-> grub_relocator32_boot() --> code32_start --> 0x100000
CS680 Linux Kernel Programming 9 Spring 2017 Andrew Sohn
New Jersey Institute of Technology Computer Science Department
Linux/arch/x86/boot
header.S: pmjump.S:
• code32_start: .long 0x100000 in protected_mode_jump:
header.S • .byte 0x66, 0xea # ljmpl opcode
• calll main # Jump to C code (should • jmpl *%eax
not return) # Jump to the 32-bit entrypoint

main.c: main(void) compressed/head_32.S:


• copy_boot_params(); ENTRY(startup_32):
• ... • call extract_kernel
• detect_memory(); • jmp *%eax
• keyboard_init();
• go_to_protected_mode(); compressed/misc.c: *extract_kerne(..)
• __decompress(...)
pm.c: go_to_protected_mode(void)
• setup_idt() x86/kernel/head_32.S:
• setup_gdt() ENTRY(startup_32):
• protected_mode_jump(code32_start) • jmp *(initial_code)
• ENTRY(initial_code)
pmjump.S: • .long i386_start_kernel
protected_mode_jump:
• .byte 0x66, 0xea # ljmpl opcode x86/kernel/head_32.c:
• jmpl *%eax • asmlinkage __visible void __init
# Jump to the 32-bit entrypoint i386_start_kernel(void)
-> start_kernel();
CS680 Linux Kernel Programming 10 Spring 2017 Andrew Sohn

You might also like