《Linux内核设计的艺术》学习笔记(六)执行setup.s
参考资料
jmpi , SETUPSEG // 0x90200
到这里,bootsect.s的执行就算结束了。控制权转移到了setup.s文件的手中。
setup程序的主要作用是利用ROM BIOS中断读取机器系统数据,并将这些数据保存到0x90000开始的位置。下表基本归纳了Line 109之前的所有代码逻辑。
表1 setup.s前半段代码的作用
内存地址 | 长度(字节) | 名称 | 描述 |
0x90000 | 2 | 光标位置 | 行列都是从0开始,各占一个字节。由int 0x10中断(入口参数为AH=0x03)取得到DX中,并保存到内存。 |
0x90002 | 2 | 扩展内存数 | 系统从1MB开始的扩展内存数值(KB)。由0x15中断(入口参数为AH=0x88)取得到AX中,并保存到内存。 |
0x90004 | 2 | 当前活动页 | 当前显示的页面。由int 0x10中断(入口参数为AH=0x0F)取得到BH中,并保存到内存。 |
0x90006 | 1 | 显示模式 | 同上,由int 0x10中断(入口参数为AH=0x0F)取得到AL中,并保存到内存。 |
0x90007 | 1 | 字符的列数 | 同上,int 0x10中断(入口参数为AH=0x0F)取得到AH中,并保存到内存。 |
0x90008 | 2 | 未知 | 被破坏了。int 0x10中断(入口参数为AH=0x0F,BL=0x10)。 |
0x9000A | 1 | 内存大小标识 | 同上,int 0x10中断(入口参数AH=0x0F,BL=0x10)取得到BL中,并保存到内存(0x00=64K,0x01=128K,0x02=192K,0x03=256K)。 |
0x9000B | 1 | 视频状态 | 同上,int 0x10中断(入口参数AH=0x0F,BL=0x10)取得到BL中,并保存到内存(0x00为彩色模式,I/O端口为0x3DX;0x01为单色,I/O端口为0x3BX)。 |
0x9000C | 2 | 显卡特性参数 | 同上,int 0x10中断(入口参数AH=0x0F,BL=0x10)取得到CX中,并保存到内存。CH和CL各有含义。 |
0x90080 | 16 | 硬盘hd0参数表 | 取中断向量0x41所指的内存值,放于0x9000:0x0080处。由movsb命令实现。 |
0x90090 | 16 | 硬盘hd1参数表 | 取中断向量0x46所指的内存值,放于0x9000:0x0090处。由movsb命令实现。 |
0x901FC | 2 | 根设备号 | 根文件系统所在的设备号在bootsect.s中设置,这里没有代码参与。 见bootsect.s中第251行。 |
接下来使用cli命令屏蔽中断。
cld命令将DF设置为0,增址方向。std与之相反。
通过movsw命令,将system模块从0x10000到0x8FFFF的内存数据块(512KB)移动到0x00000开始的位置。每次移动64KB,共移动8次。
初始化IDT寄存器和GDT寄存器。
选通A20地址线。
重新对8259A中断控制器编程。
通过lmsw命令将0x0001写入到控制寄存器CR0中,打开保护模式。
最后,通过jmpi 0, 8命令跳转至CS段8,偏移地址为0处。即,0x00000处。
图1 setup.s程序结束后内存中程序示意图
setup.s代码如下:
!
! setup.s (C) Linus Torvalds
!
! setup.s is responsible for getting the system data from the BIOS,
! and putting them into the appropriate places in system memory.
! both setup.s and system has been loaded by the bootblock.
!
! This code asks the bios for memory/disk/other parameters, and
! puts them in a "safe" place: 0x90000-0x901FF, ie where the
! boot-block used to be. It is then up to the protected mode
! system to read them from there before the area is overwritten
! for buffer-blocks.
! ! NOTE! These had better be the same as in bootsect.s! INITSEG = 0x9000 ! we move boot here - out of the way
SYSSEG = 0x1000 ! system loaded at 0x10000 ().
SETUPSEG = 0x9020 ! this is the current segment .globl begtext, begdata, begbss, endtext, enddata, endbss
.text
begtext:
.data
begdata:
.bss
begbss:
.text entry start
start: ! ok, the read went well so we get current cursor position and save it for
! posterity. mov ax,#INITSEG ! this is done in bootsect already, but...
mov ds,ax
mov ah,#0x03 ! read cursor pos
xor bh,bh
int 0x10 ! save it in known place, con_init fetches
mov [],dx ! it from 0x90000. ! Get memory size (extended mem, kB) mov ah,#0x88
int 0x15
mov [],ax ! Get video-card data: mov ah,#0x0f
int 0x10
mov [],bx ! bh = display page
mov [],ax ! al = video mode, ah = window width ! check for EGA/VGA and some config parameters mov ah,#0x12
mov bl,#0x10
int 0x10
mov [],ax
mov [],bx
mov [],cx ! Get hd0 data mov ax,#0x0000
mov ds,ax
lds si,[*0x41]
mov ax,#INITSEG
mov es,ax
mov di,#0x0080
mov cx,#0x10
rep
movsb ! Get hd1 data mov ax,#0x0000
mov ds,ax
lds si,[*0x46]
mov ax,#INITSEG
mov es,ax
mov di,#0x0090
mov cx,#0x10
rep
movsb ! Check that there IS a hd1 :-) mov ax,#0x01500
mov dl,#0x81
int 0x13
jc no_disk1
cmp ah,#
je is_disk1
no_disk1:
mov ax,#INITSEG
mov es,ax
mov di,#0x0090
mov cx,#0x10
mov ax,#0x00
rep
stosb
is_disk1: ! now we want to move to protected mode ... cli ! no interrupts allowed ! ! first we move the system to it's rightful place mov ax,#0x0000
cld ! 'direction'=0, movs moves forward
do_move:
mov es,ax ! destination segment
add ax,#0x1000
cmp ax,#0x9000
jz end_move
mov ds,ax ! source segment
sub di,di
sub si,si
mov cx,#0x8000
rep
movsw
jmp do_move ! then we load the segment descriptors end_move:
mov ax,#SETUPSEG ! right, forgot this at first. didn't work :-)
mov ds,ax
lidt idt_48 ! load idt with ,
lgdt gdt_48 ! load gdt with whatever appropriate ! that was painless, now we enable A20 call empty_8042
mov al,#0xD1 ! command write
out #0x64,al
call empty_8042
mov al,#0xDF ! A20 on
out #0x60,al
call empty_8042 ! well, that went ok, I hope. Now we have to reprogram the interrupts :-(
! we put them right after the intel-reserved hardware interrupts, at
! int 0x20-0x2F. There they won't mess up anything. Sadly IBM really
! messed this up with the original PC, and they haven't been able to
! rectify it afterwards. Thus the bios puts interrupts at 0x08-0x0f,
! which is used for the internal hardware interrupts as well. We just
! have to reprogram the 's, and it isn't fun. mov al,#0x11 ! initialization sequence
out #0x20,al ! send it to 8259A-
.word 0x00eb,0x00eb ! jmp $+, jmp $+
out #0xA0,al ! and to 8259A-
.word 0x00eb,0x00eb
mov al,#0x20 ! start of hardware int's (0x20)
out #0x21,al
.word 0x00eb,0x00eb
mov al,#0x28 ! start of hardware int's (0x28)
out #0xA1,al
.word 0x00eb,0x00eb
mov al,#0x04 ! - is master
out #0x21,al
.word 0x00eb,0x00eb
mov al,#0x02 ! - is slave
out #0xA1,al
.word 0x00eb,0x00eb
mov al,#0x01 ! mode for both
out #0x21,al
.word 0x00eb,0x00eb
out #0xA1,al
.word 0x00eb,0x00eb
mov al,#0xFF ! mask off all interrupts for now
out #0x21,al
.word 0x00eb,0x00eb
out #0xA1,al ! well, that certainly wasn't fun :-(. Hopefully it works, and we don't
! need no steenking BIOS anyway (except for the initial loading :-).
! The BIOS-routine wants lots of unnecessary data, and it's less
! "interesting" anyway. This is how REAL programmers do it.
!
! Well, now's the time to actually move into protected mode. To make
! things as simple as possible, we do no register set-up or anything,
! we let the gnu-compiled -bit programs do that. We just jump to
! absolute address 0x00000, in -bit protected mode. mov ax,#0x0001 ! protected mode (PE) bit
lmsw ax ! This is it!
jmpi , ! jmp offset of segment (cs) ! This routine checks that the keyboard command queue is empty
! No timeout is used - if this hangs there is something wrong with
! the machine, and we probably couldn't proceed anyway.
empty_8042:
.word 0x00eb,0x00eb
in al,#0x64 ! 8042 status port
test al,#2 ! is input buffer full?
jnz empty_8042 ! yes - loop
ret gdt:
.word 0,0,0,0 ! dummy .word 0x07FF ! 8Mb - limit=2047 (2048*4096=8Mb)
.word 0x0000 ! base address=0
.word 0x9A00 ! code read/exec
.word 0x00C0 ! granularity=4096, 386 .word 0x07FF ! 8Mb - limit=2047 (2048*4096=8Mb)
.word 0x0000 ! base address=0
.word 0x9200 ! data read/write
.word 0x00C0 ! granularity=4096, 386 idt_48:
.word 0 ! idt limit=0
.word 0,0 ! idt base=0L gdt_48:
.word 0x800 ! gdt limit=2048, 256 GDT entries
.word 512+gdt,0x9 ! gdt base = 0X9xxxx .text
endtext:
.data
enddata:
.bss
endbss:
《Linux内核设计的艺术》学习笔记(六)执行setup.s的更多相关文章
- linux内核设计与实现学习笔记-模块
模块 1.概念: 如果让LINUX Kernel单独运行在一个保护区域,那么LINUX Kernel就成为了“单内核”. LINUX Kernel是组件模式的,所谓组件模式是指:LINUX K ...
- 《Linux内核设计与分析》第六周读书笔记——第三章
<Linux内核设计与实现>第六周读书笔记——第三章 20135301张忻估算学习时间:共2.5小时读书:2.0代码:0作业:0博客:0.5实际学习时间:共3.0小时读书:2.0代码:0作 ...
- Linux内核设计与实现 读书笔记 转
Linux内核设计与实现 读书笔记: http://www.cnblogs.com/wang_yb/tag/linux-kernel/ <深入理解LINUX内存管理> http://bl ...
- linux内核设计的艺术--系统启动第一步
计算机究竟是如何执行起来的呢,在我学习计算机的时候一直不是非常明确,可是近期借了本<linux内核设计的艺术>算是知道了计算机从按开机到启动操作系统之间究竟做了些什么. 这本书刚開始介绍的 ...
- linux内核分析第四周学习笔记
linux内核分析第四周学习笔记 标签(空格分隔): 20135328陈都 陈都 原创作品转载请注明出处 <Linux内核分析>MOOC课程http://mooc.study.163.co ...
- Linux内核分析第二周学习笔记
linux内核分析第二周学习笔记 标签(空格分隔): 20135328陈都 陈都 原创作品转载请注明出处 <Linux内核分析>MOOC课程http://mooc.study.163.co ...
- linux内核分析第一周学习笔记
linux内核分析第一周学习笔记 标签(空格分隔): 20135328陈都 陈都 原创作品转载请注明出处 <Linux内核分析>MOOC课程http://mooc.study.163.co ...
- 初探内核之《Linux内核设计与实现》笔记上
内核简介 本篇简单介绍内核相关的基本概念. 主要内容: 单内核和微内核 内核版本号 1. 单内核和微内核 原理 优势 劣势 单内核 整个内核都在一个大内核地址空间上运行. 1. 简单.2. 高效 ...
- Linux内核设计与实现 总结笔记(第六章)内核数据结构
内核数据结构 Linux内核实现了这些通用数据结构,而且提倡大家在开发时重用. 内核开发者应该尽可能地使用这些数据结构,而不要自作主张的山寨方法. 通用的数据结构有以下几种:链表.队列.映射和二叉树 ...
- Linux内核设计与实现 总结笔记(第十六章)页高速缓存和页回写
页高速缓存是Linux内核实现磁盘缓存.磁盘告诉缓存重要源自:第一,访问磁盘的速度要远远低于访问内存. 第二,数据一旦被访问,就很有可能在短期内再次被访问到.这种短时期内集中访问同一片数据的原理称作临 ...
随机推荐
- innodb的锁到底占用多少内存
举个简单的例子: CREATE TABLE `sample` ( `i` ) unsigned NOT NULL auto_increment, `j` ) default NULL, PRIMARY ...
- zabbix监控mysql主从
最近在公司搭建了zabbix监控系统,现在需要用zabbix来监控mysql的主从同步情况 现在说一下配置的详细步骤: 1.首先给mysql分配一个监控的账号: mysql> grant rep ...
- 3.1将AngularJS放入上下文
本章,作者将AngularJS放在全球web app开发的上下文里,并为后面的章节设置功能.AngularJS的目标,是带来一款工具,它有服务端开发web client的能力,并易于开发,测试,富.复 ...
- Extended Data Type Properties [AX 2012]
Extended Data Type Properties [AX 2012] This topic has not yet been rated - Rate this topic Updated: ...
- MongoDB C# / .NET Driver
MongoDB C# Driver是官方提供的.NET C#驱动. Getting Started with the C# Driver C# Driver Tutorial C# Driver LI ...
- jar包里查找指定的class文件,排查是否存在或重复,工具软件:Java Class Finder
jar包里查找指定的class文件,排查是否存在或重复,工具软件:Java Class Finder 1,下载工具地址:www.idesksoft.com/classfinder.html,如图: 2 ...
- 再谈自主开发与企业IT管理
前两天写<自主开发与带兵打仗>分析了一下自主开发的利与弊,得到了园内不少朋友的反馈,但我觉得还有很多东西没有交待清楚,可能有很多朋友也跟我一样在公司的IT部门,有自己的研发团队也有很多外购 ...
- 检索 COM 类工厂中 CLSID 为 {} 的组件时失败,原因是出现以下错误: 80070005
检索 COM 类工厂中 CLSID 为 {00024500-0000-0000-C000-000000000046} 的组件时失败,原因是出现以下错误: 80070005.跟踪了一下,结果是将记录导出 ...
- fzu 2171 防守阵地 II
Problem 2171 防守阵地 II Accept: 31 Submit: 112Time Limit: 3000 mSec Memory Limit : 32768 KB Prob ...
- Android ActivityThread(主线程或UI线程)简介
1. ActivityThread功能 它管理应用进程的主线程的执行(相当于普通Java程序的main入口函数),并根据AMS的要求(通过IApplicationThread接口,AMS为Client ...