《Linu内核源代码解读》由会员分享,可在线阅读,更多相关《Linu内核源代码解读(13页珍藏版)》请在金锄头文库上搜索。
1、Linux 内核源代码解读!悬赏分:5 - 提问时间 2007-1-24 16:28 问题为何被关闭赵炯书中,Bootsect代码中有mov ax , #BOOTSEG 等我曾自学过80x86汇编,没有见过#的用法,在这为什么要用#?另外,JMPI的用法是什么?与JMP的区别是什么?提问者: Linux 探索者 - 一级答复 共 1 条检举系统初始化程序boot.s 的分析 转系统初始化程序boot.s 的分析:阚志刚,2000/03/20 下午, 在前人的基础之上进行整理完善*1* *1* *1* *1* *1* *1* *1* *1* *1* *1* *1* *1* *1* *1* *1*
2、 *1* *1* *1* *1* *1* *1* *1* *1* *1* *1* *1* *1* *1* *1* *1* *1* *1* *1* *1* *1* *1* *1* *1* *1* *1* *1* *1* *1* *1* *1* *1* *1* *1* *1* *1* *1* *1* *1* *1* *1* *1* *1* *1* *1* *1* *1* *1* *1* *1* *1* *1* *1* *1* *1* *1* *1* *1* *1* *1* *1* *1* *1* *1* *1* *1*i* *i* *i* *i* *i* *i* *i* *i* *i* *i* *
3、i* *i* *i* *i*boot.s is loaded at 0x7c00 by the bios-startup routines, and moves itself out of the way to address 0x90000, and jumps there.当PC机启动时,In tel系列的CPU首先进入的是实模式,并开始执行位于地址OxFFFO处的 代码,也就是ROM-BIOS起始位置的代码。BIOS先进行一系列的系统自检,然后初始化位于 地址 0 的中断向量表。 最后 BIOS 将启动盘的第一个扇区装入 0x7C00(31K; 0111,1100,0000,0000),
4、并开始执行此处的代码。这就是对内核初始化过程的一个最简单的 描述。最初, Linux 核心的最开始部分是用 8086 汇编语言编写的。当开始运行时,核心将自己装入 到绝对地址 0x90000(576K; 1001,0000,0000,0000,0000),再将其后的 2k 字节装入到地址 0x90200(576.5k; 1001,0000,0010,0000,0000)处, 最后将核心的其余部分装入到 0x10000(64k; 1,0000,0000,0000,0000).It then loads the system at 0x10000, using BIOS interrupts. T
5、hereafter it disables all interrupts, moves the system down to 0x0000, changes to protectedmode, and calls the start of system. System then must RE-initialize the protected mode in its own tables, and enable interrupts as needed.然后,关掉所有中断,把系统下移到0x0000(0k; 0000,0000,0000,0000,0000)处,改变到保 护模式,然后开始系统的运
6、行系统必须重新在保护模式下初始化自己的系统表格,并且打 开所需的中断NOTE1! currentlysystemisatmost8*65536(8*64k=512k;1000,0000,0000,0000,0000)bytes long. This should be no problem, even in the future. I want to keep it simple.This512kBkernelsizeshouldbeenough - in fact more would mean wed have to move not just these start-up routine
7、s, but also do something about the cache-memory(block IO devices). The area left over in the lower 640 kB (0xA0000 ; 1010,0000,0000,0000,0000) is meant for these. No other memory is assumed to be physical, ie all memory over 1Mb is demand-paging. All addresses under 1Mb are guaranteed to match their
8、 physical addresses.NOTE1 abouve is no longer valid in its entirety. cache-memory is allocated above the 1Mb mark as well as below. Otherwise it is mainly correct.NOTE 2! The boot disk type must be set at compile-time, by setting the following equ. Having the boot-up procedure hunt for the right dis
9、k type is severe brain-damage. The loader has been made as simple as possible (had to, to get it in 512 bytes with the code to move to protected mode), and continuos read errors will result in a unbreakable loop. Reboot by hand. It loads pretty fast by getting whole sectors at a time whenever possib
10、le.| 1.44Mb disks: sectors = 18| 1.2Mb disks:| sectors = 15| 720kB disks:| sectors = 9*1* *1* *1* *1* *1* *1* *1* *1* *1* *1* *1* *1* *1* *1* *1* *1* *1* *1* *1* *1* *1* *1* *1* *1* *1* *1* *1* *1* *1* *1* *1* *1* *1* *1* *1* *1* *1* *1* *1* *1* *1* *1* *1* *1* *1* *1* *1* *1* *1* *1* *1* *1* *1* *1
11、* *1* *1* *1* *1* *1* *1* *1* *1* *1* *1* *1* *1* *1* *1* *1* *1* *1* *1* *1* *1* *1* *1* *1* *1* *1* *1*i* *i* *i* *i* *i* *i* *i* *i* *i* *i* *i* *i* *i* *i*.globl begtext, begdata, begbss, endtext, enddata, endbss.text begtext:.databegdata:.bss begbss: .textBOOTSEG = 0x07c0|把第一个扇区装入到此处INITSEG = 0
12、x9000|核心装入地址的段地址SYSSEG = 0x1000|system loaded at 0x10000 (65536).ENDSEG = SYSSEG + SYSSIZEISYSSIZE 在 Makefile 中定义的 二entry startstart:mov ax,#BOOTSEG| BOOTSEG = 0x07C0;现在应仍处在 REAL MODE 下.mov ds,ax| 移动自身从 BOOTSEG:0000 到 INITSEG:0000 movax,#INITSEG| 共 512 字节.moves,ax| 那么 BOOT.S 处在 0x90000-0x90200.movcx
13、,#256subsi,si| 寄存器清零subdi,di| 寄存器清零repmovw|将由SI作为指针的源串中的一个字节或字或双字传送到由DI作为指针的目的串中,并根 据标志DF值自动修|改这两个指针以指向串中下一项。若带有前缀REP,则重复执行这一传送,直到CX寄存器 等于零为止。| 源地址:DS=0x07C0(31K; 0111,1100,0000,0000);| 目的地址: ES=0x9000(576K; 1001,0000,0000,0000,0000)|小结:BIOS将启动盘的第一个扇区调入到0x07C00处,然后系统把自己从0x07C00处移动 到 0x90000-| 0x9020
14、0 处.jmpigo,INITSEGgo: mov ax,csmovds,axmov es,ax| 将 DS,ES,SS 均设为 0x9000, 所有数据都以| 0x9000 为段偏移.movss,ax| 堆栈偏移 0x9000movsp,#0x400| 栈顶指针 0x9000:0x0400, 堆栈空间 512bytes?movah,#0x03| read cursor posxorbh,bh int 0x10movcx,#24movbx,#0x0007mov| page 0, attribute 7 (normal) bp,#msg1| 显示 Loading System .movax,#0
15、x1301| write string, move cursorint0x10| ok, weve written the message, now| we want to load the system (at 0x10000)|我们已经完成了 “Loading. ”的在屏幕上显示,|以下我们将完成把核心从0xl0000(64k)移到0x01000(4k)处.movax,#SYSSEG| SYSSEG = 0x1000moves,ax| segment of 0x010000callread_it| 读内核到 0x10000callkill_motor|杀了软驱!?二| if the read went well we get current cursor position ans save it for | posterity.movah,#0x03|readcursorposxorbh,bhint0x10|saveit inknown place, con_init fetchesmov510,dx| it from 0x90510(1001,0000,0101,0001,0000).|功能03H,读取光标位置和类型。AH=03H, BH