* i386CPU加电或"总清"(reset)以后CPU处于实地址模式,并且代码段寄存器CS的内容为0xffff,而取指令指针
* (寄存器)IP的内容为0,也就是说,CPU加电或"总清"后从线性地址0xffff0开始取第一条指令.所以采用i386
* CPU的系统在0xffff0的位置上需有不挥发存储器.
*/
/*
* ===================== 内存结构图(会随着setup的运行而变动),说明部分见P666 =========================
*
* |------------------------|
* | |
* | |
* | |
* | |
* | |
* | |
* | | ▲ 高内存
* | | |
* | | |
* | |
* |------------------------| 0x100000(1MB)<--|
* | | |
* | | |
* | | |--用于图形接口卡以及BIOS本身
* | | |
* | | |
* |-->|------------------------| 0xA0000 <--|----|
* | | | |
* | | setup.S所在内存 | |
* | | | |
* | |------------------------| 0x90200 |--64KB
* | | | |
* | | bootsect.S所在内存 | |
* | | 以后会存放一些参数 | |
* | | | |
* | |------------------------| 0x90000 <--|----|
* | | | |
* | | 4KB用于引导命令行 | |
* | | (LILO支持引导命令行) | |
* | | 及 | |
* | | 一些需传递给内核的数据| |
* | | (从BIOS收集得到) | |
* | | | |
* | |------------------------| |
* | | | |
* | | | |
* (640KB系统基本内存)--| | 508KB | |--512KB
* | | | |
* | | | |
* | |------------------------| 0x10000 <--|----|
* | | | |
* | | BIOS保留使用 | |--64KB
* | | Linux引导保留部分空间 | |
* | | | |
* |-->|------------------------| 0 <--|
*
*
* 内核一般经过压缩,压缩后的内核就像一大块数据,跟引导扇区和引导辅助程序的映象拼接在一起,成为内核
* 的"引导映象".大小不超过508KB的引导映象称为"小映象",文件名为zImage,否则为"大内核",文件名为bzImage
* 由于bzImage在基本内存装载不下,所以要装载在0x100000(1MB)的地方. 不过,不管是zImage还是bzImage,
* 解除压缩后的内核映象总放在地址为0x100000(1MB)的地方.
*
* arch/i386/boot/tools中的build.c用来拼接引导映象的工具
*
* ================================================================================================= */
/*
* bootsect.S Copyright (C) 1991, 1992 Linus Torvalds
*
* modified by Drew Kckhardt
* modified by Bruce Evans (bde)
* modified by Chris Noe (May 1999) (as86 -> gas)
*
* bootsect is loaded at 0x7c00 by the bios-startup routines, and moves itself out of the
* way to address 0x90000, and jumps there.
*
* bde - should not jump blindly(盲目地,摸索地), there may be systems with only 512k low
* memory. Use int 0x12 to get the top of memory, etc.
*
* It then loads 'setup' directly after itself (0x90200), and the system at 0x10000, using
* BIOS interrupts.
*
* NOTE! currently system is at most (8*65536-4096)(即8*64KB-4KB,见上图)) bytes long.
* This should be no problem, even in the future. I want to keey it simple. This 508 kB
* kernel size should be enough, especially(特别) as this doesn't contain the buffer cache
* as in minix (and especially now that the kernel is compressed(被压缩的 :-)
*
* The loader has been made as simple as possible, and continues read errors will result in
* (导致) a unbreakable loop. Reboot by hand. It loads pretty(优美的,恰当的) fast by getting
* whole tracks(轨迹..) at a time whenever possible.
*/
#include <linux/config.h> /* for CONFIG_BOOT_RDONLY */
#include <asm/boot.h>
SETUPSECS = 4 /* default nr of setup-sectors */
BOOTSEG = 0x07C0 /* original address of boot-sector */
INITSEG = DEF_INITSEG /* 0x9000: we move boot here - out of the way */
SETUPSEG = DEF_SETUPSEG /* 0x9020: setup starts here */
SYSSEG = DEF_SYSSEG /* 0x1000: system loaded at 0x10000 (65536) */
SYSSIZE = DEF_SYSSIZE /* 0x7F00: system size: # of 16-byte clicks */
/* to be loaded - 0x7F00*16=508KB */
ROOT_DEV = 0 /* ROOT_DEV is now written by "build" */
SWAP_DEV = 0 /* SWAP_DEV is now written by "build" */
#ifndef SVGA_MODE
#define SVGA_MODE ASK_VGA /* 0xfffd - ask for it at bootup */
#endif
#ifndef RAMDISK
#define RAMDISK 0
#endif
#ifndef CONFIG_ROOT_RDONLY
#define CONFIG_ROOT_RDONLY 1
#endif
.code16
.text
.global _start /* 告知连接程序,程序从_start标号开始执行. */
_start:
#if 0 /* hook(钩) for debugger, harmless(无害的) unless BIOS is fussy(繁琐的..) (old HP) */
/* INT 3功能是在程序中设置一个断电,程序运行到INT 3自动停下来
* 后可以用单步调试功能一步一步的调下去.
*/
int $0x3
#endif
/* 将引导扇区代码从0x07C00移到0x90000处 */
movw $BOOTSEG, %ax /* ds段基址: 0x07C0 */
movw %ax, %ds
movw $INITSEG, %ax /* es段基址: 0x9000 */
movw %ax, %es
movw $256, %cx
subw %si, %si
subw %di, %di
cld
rep
movsw /* DS:[SI] -> ES:[DI] */
