⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 setup.s

📁 linux 0.11内核的源码
💻 S
📖 第 1 页 / 共 2 页
字号:
!! setup.s (C) 1991 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.!! setup.s 负责从BIOS 中获取系统数据,并将这些数据放到系统内存的适当地方。! 此时setup.s 和system 已经由bootsect 引导块加载到内存中。!! 这段代码询问bios 有关内存/磁盘/其它参数,并将这些参数放到一个! “安全的”地方:0x90000-0x901FF,也即原来bootsect 代码块曾经在! 的地方,然后在被缓冲块覆盖掉之前由保护模式的system 读取。!! NOTE! These had better be the same as in bootsect.s!! 以下这些参数最好和bootsect.s 中的相同!INITSEG = 0x9000 ! we move boot here - out of the way ! 原来bootsect 所处的段。SYSSEG = 0x1000 ! system loaded at 0x10000 (65536). ! system 在0x10000(64k)处。SETUPSEG = 0x9020 ! this is the current segment ! 本程序所在的段地址。.globl begtext, begdata, begbss, endtext, enddata, endbss.textbegtext:.databegdata:.bssbegbss:.textentry startstart:! ok, the read went well so we get current cursor position and save it for! posterity.! ok,整个读磁盘过程都正常,现在将光标位置保存以备今后使用。mov ax,#INITSEG ! this is done in bootsect already, but...! 将ds 置成#INITSEG(0x9000)。这已经在bootsect 程序中! 设置过,但是现在是setup 程序,Linus 觉得需要再重新! 设置一下。mov ds,axmov ah,#0x03 ! read cursor pos! BIOS 中断0x10 的读光标功能号 ah = 0x03! 输入:bh = 页号! 返回:ch = 扫描开始线,cl = 扫描结束线,! dh = 行号(0x00 是顶端),dl = 列号(0x00 是左边)。xor bh,bhint 0x10 ! save it in known place, con_init fetchesmov [0],dx ! it from 0x90000.! 上两句是说将光标位置信息存放在0x90000 处,控制台! 初始化时会来取。! Get memory size (extended mem, kB) ! 下面3 句取扩展内存的大小值(KB)。! 是调用中断0x15,功能号ah = 0x88! 返回:ax = 从0x100000(1M)处开始的扩展内存大小(KB)。! 若出错则CF 置位,ax = 出错码。mov ah,#0x88int 0x15mov [2],ax ! 将扩展内存数值存在0x90002 处(1 个字)。! Get video-card data: ! 下面这段用于取显示卡当前显示模式。! 调用BIOS 中断0x10,功能号 ah = 0x0f! 返回:ah = 字符列数,al = 显示模式,bh = 当前显示页。! 0x90004(1 字)存放当前页,0x90006 显示模式,0x90007 字符列数。mov ah,#0x0fint 0x10mov [4],bx ! bh = display pagemov [6],ax ! al = video mode, ah = window width! check for EGA/VGA and some config parameters ! 检查显示方式(EGA/VGA)并取参数。! 调用BIOS 中断0x10,附加功能选择 -取方式信息! 功能号:ah = 0x12,bl = 0x10! 返回:bh = 显示状态! (0x00 - 彩色模式,I/O 端口=0x3dX)! (0x01 - 单色模式,I/O 端口=0x3bX)! bl = 安装的显示内存! (0x00 - 64k, 0x01 - 128k, 0x02 - 192k, 0x03 = 256k)! cx = 显示卡特性参数(参见程序后的说明)。mov ah,#0x12mov bl,#0x10int 0x10mov [8],ax ! 0x90008 = ??mov [10],bx ! 0x9000A = 安装的显示内存,0x9000B = 显示状态(彩色/单色)mov [12],cx ! 0x9000C = 显示卡特性参数。! Get hd0 data ! 取第一个硬盘的信息(复制硬盘参数表)。! 第1 个硬盘参数表的首地址竟然是中断向量0x41 的向量值!而第2 个硬盘! 参数表紧接第1 个表的后面,中断向量0x46 的向量值也指向这第2 个硬盘! 的参数表首址。表的长度是16 个字节(0x10)。! 下面两段程序分别复制BIOS 有关两个硬盘的参数表,0x90080 处存放第1 个! 硬盘的表,0x90090 处存放第2 个硬盘的表。mov ax,#0x0000mov ds,axlds si,[4*0x41] ! 取中断向量0x41 的值,也即hd0 参数表的地址??ds:simov ax,#INITSEGmov es,axmov di,#0x0080 ! 传输的目的地址: 0x9000:0x0080 ?? es:dimov cx,#0x10 ! 共传输0x10 字节。repmovsb! Get hd1 datamov ax,#0x0000mov ds,axlds si,[4*0x46] ! 取中断向量0x46 的值,也即hd1 参数表的地址??ds:simov ax,#INITSEGmov es,axmov di,#0x0090 ! 传输的目的地址: 0x9000:0x0090 ?? es:dimov cx,#0x10repmovsb! Check that there IS a hd1 :-) ! 检查系统是否存在第2 个硬盘,如果不存在则第2 个表清零。! 利用BIOS 中断调用0x13 的取盘类型功能。! 功能号 ah = 0x15;! 输入:dl = 驱动器号(0x8X 是硬盘:0x80 指第1 个硬盘,0x81 第2 个硬盘)! 输出:ah = 类型码;00 --没有这个盘,CF 置位; 01 --是软驱,没有change-line 支持;! 02 --是软驱(或其它可移动设备),有change-line 支持; 03 --是硬盘。mov ax,#0x01500mov dl,#0x81int 0x13jc no_disk1cmp ah,#3 ! 是硬盘吗?(类型 = 3 ?)。je is_disk1no_disk1:mov ax,#INITSEG ! 第2 个硬盘不存在,则对第2 个硬盘表清零。mov es,axmov di,#0x0090mov cx,#0x10mov ax,#0x00repstosbis_disk1:! now we want to move to protected mode ... ! 从这里开始我们要保护模式方面的工作了。cli ! no interrupts allowed ! ! 此时不允许中断。! first we move the system to it's rightful place! 首先我们将system 模块移到正确的位置。! bootsect 引导程序是将system 模块读入到从0x10000(64k)开始的位置。由于当时假设! system 模块最大长度不会超过0x80000(512k),也即其末端不会超过内存地址0x90000,! 所以bootsect 会将自己移动到0x90000 开始的地方,并把setup 加载到它的后面。! 下面这段程序的用途是再把整个system 模块移动到0x00000 位置,即把从0x10000 到0x8ffff! 的内存数据块(512k),整块地向内存低端移动了0x10000(64k)的位置。mov ax,#0x0000cld ! 'direction'=0, movs moves forwarddo_move:mov es,ax ! destination segment ! es:di??目的地址(初始为0x0000:0x0)add ax,#0x1000cmp ax,#0x9000 ! 已经把从0x8000 段开始的64k 代码移动完?jz end_move

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -