* header.S
*
* Copyright (C) 1991, 1992 Linus Torvalds
*
* Based on bootsect.S and setup.S基于bootsect.S和setup.S
* modified by more people than can be counted
*
* Rewritten as a common file by H. Peter Anvin (Apr 2007)
*
* BIG FAT NOTE: We're in real mode using 64k segments. Therefore segment
当前是64K段的实模式,
* addresses must be multiplied by 16 to obtain their respective linear
而段地址必须通过乘以16来获得相应的线性地址
* addresses. To avoid confusion, linear addresses are written using leading
* hex while segment addresses are written as segment:offset.
为了避免混淆,用十六进制前缀表示线性地址,用seg:off表示段地址
*
*/
#include
#include
#include
#include
#include
#include
#include "boot.h"
#include "voffset.h"
#include "zoffset.h"
BOOTSEG = 0x07C0 /* original address of boot-sector */
SYSSEG = 0x1000 /* historical load address >> 4 */
#ifndef SVGA_MODE
#define SVGA_MODE ASK_VGA
#endif
#ifndef RAMDISK
#define RAMDISK 0
#endif
#ifndef ROOT_RDONLY
#define ROOT_RDONLY 1
#endif
#在setup.ld连接脚本中安排地址
.code16
.section ".bstext", "ax" #a->可重定位,x可执行
.global bootsect_start
bootsect_start:
# Normalize the start address
ljmp $BOOTSEG, $start2 #0x07C0
start2:
movw %cs, %ax
movw %ax, %ds #设置ds,es,ss为0x07c0
movw %ax, %es
movw %ax, %ss
xorw %sp, %sp #栈指针清0,压栈会怎样?回绕?
sti #开中断
cld
movw $bugger_off_msg, %si
msg_loop:
lodsb
andb %al, %al #找结束字节0
jz bs_die
movb $0xe, %ah
movw $7, %bx
int $0x10 #显示信息
jmp msg_loop
int 0x10的调用信息是
Teletype output AH=0Eh AL = Character, BH = Page Number, BL = Color (only in graphic mode)
List of BIOS color attributes
Hex Binary Color
0 0000 Black
1 0001 Blue
2 0010 Green
3 0011 Cyan
4 0100 Red
5 0101 Magenta
6 0110 Brown
7 0111 Light Gray
8 1000 Dark Gray
9 1001 Light Blue
A 1010 Light Green
B 1011 Light Cyan
C 1100 Light Red
D 1101 Light Magenta
E 1110 Yellow
F 1111 White
bs_die:
# Allow the user to press a key, then reboot
xorw %ax, %ax
int $0x16
int $0x19
int 0x16调用约定是
Int 0x16
AH = 00h
Return: AH = BIOS scan code
AL = ASCII character
int 0x19调用约定
Int 0x19
This interrupt reboots the system without clearing memory or restoring
interrupt vectors. Because interrupt vectors are preserved, this
interrupt usually causes a system hang if any TSRs have hooked
vectors from 00h through 1Ch, particularly INT 08.
# int 0x19 should never return. In case it does anyway,
# invoke the BIOS reset code...
ljmp $0xf000,$0xfff0
.section ".bsdata", "a"
bugger_off_msg:
.ascii "Direct booting from floppy is no longer supported.\r\n"
.ascii "Please use a boot loader program instead.\r\n"
.ascii "\n"
.ascii "Remove disk and press any key to reboot . . .\r\n"
.byte 0
# Kernel attributes; used by setup. This is part 1 of the
# header, from the old boot sector.
.section ".header", "a"
.globl hdr
hdr:
setup_sects: .byte 0 /* Filled in by build.c */
root_flags: .word ROOT_RDONLY
syssize: .long 0 /* Filled in by build.c */
ram_size: .word 0 /* Obsolete */
vid_mode: .word SVGA_MODE
root_dev: .word 0 /* Filled in by build.c */
boot_flag: .word 0xAA55
在setup.ld中,hdr被指定到497
. = 497;
.header : { *(.header) }
hdr保存一些重要的参数
举例vmlinuz-2.6.9-42.EL中
000001f0h: 00
0A
01 00
51 B4 00 00
00 00
FF FF
01 09
55 AA ; ....Q?.....U
以上对应老版本的bootsect.S,例如2.4.0内核
在老版中bootsect.S载入后面的setup和内核,执行setup
较新版的内核不再支持,转而将这部分任务交给lilo,grub等加载器完成