bootsect.s和setup.s

Linux内核完全注释:第三章 内核引导启动程序-bootsect.s讲解 内核引导启动程序 文件结构 知识补充 BIOS: 计算机启动最开始执行的BIOS程序,BIOS(Basic Input Output System). 使一组固化到计算机内主板上一个ROM芯片上的程序,它保存着计算机最重要的基本输入输出的程序、开机后自检程序和系统自启动程序,它可从CMOS中读写系统设置的具体信息 结合boot/目录下程序讲解计算机启动流程 PC的电源开机后,80x86结构... 阅读详情

内容为 李治军老师操作系统课 的部分笔记

计算机开机执行的操作

以X86 PC为例(X86为Intel处理器架构,即指令集架构(ISA Instruction Set Architecture))

一个地址由段寄存器CS和段内偏移IP组成

  1. x86 PC 刚开机时,CPU初始状态为实模式。

  2. 此时CPU设置CS=0xFFFF,IP=0x0000(CS为Code Segment Register 代码段寄存器,确定起始内存段)

    物理地址 = (CS<<4)+ IP = 0xFFFF0 //所以这就是第一条内存指令
    
  3. 寻址0xFFFF0(ROM BIOS映射区,为BIOS 启动入口地址)

  4. 执行0xFFFF0的指令,检查RAM、键盘、显示器、软硬磁盘

  5. BIOS将磁盘0磁道0扇区(引导扇区BootSector)读入0x7c00处(一个扇区为512B)

  6. 设置CS=0x07c0,IP=0x0000(此时计算出的物理地址为0x7c00,寻址0x7c00,执行引导扇区的指令)

bootsect.s

引导扇区存放的代码 bootsect.s(s后缀为汇编代码),该代码来将操作系统加载到内存中

; 在 as86 汇编语言程序中,凡是以感叹号’!’或分号’;’开始的语句均为注释

;1、操作为:bootsect 把自己搬运到 0x90000,并跳转
;BOOTSEG=0x07c0   INITSEG=0x9000   SETUPSEG=0x9020
entry _start  ; 告知链接程序,程序从 start 标号开始执行
_start:
mov ax,#BOOTSEG
mov ds,ax      ! ds = 0x07c0
mov ax,#INITSEG
mov es,ax      ! es = 0x9000
mov cx,#256    ! cx为计数器,搬运 256 次
!ds为数据段,es为附加段,都为段寄存器,段寄存器需要有偏移才构成实际地址
sub si,si      ! sub为减,前减后结果给前,si-si=0,si = 0
sub di,di      ! di = 0
!si为源偏移,di为目标偏移
! ds:si = 0x07c0:0x0,实际地址:ds<<4+si=0x7c00
! es:di = 0x9000:0x0  实际地址:es<<4+di=0x90000
rep movw           ! 每次搬运1个字,即 2 字节,搬运256次,即512字节,为一个扇区大小
!将7c00处的256个字移动到90000中,7c00为bootsect.s存放的地址,此时将其移动到90000
!start位置为90000
jmpi go,INITSEG  !jmpi段内转跳,cs=INITSEG  ip=go
! INITSEG<<4+go,假设go为100,则此时地址为90100
!start为90000,start的模块为100,start进行完后正好到90100也就是go的位置
————————————————

;2、转跳到go执行下面指令,设置段寄存器和栈
go:	mov	ax,cs
	mov	ds,ax
	mov	es,ax
	mov	ss,ax   ; cs = ds = es = ss = 0x9000,
	!ss为栈段,sp为栈顶指针,栈顶地址为ss:sp,即ss<<4+sp,实模式下栈是往下长的
	mov	sp,#0xFF00		 !ss:sp = 0x9000:0xff00 ,栈的设置	0x9ff00
	
! 因为从 0x90200 地址开始处还要放置 setup 程序,setup 大约为 4 个扇区
! 0x200 * 5 = 0xA00 (512十六进制下为200),0x90200+0xA00=0x90C00
!所以setup 占用范围 = 0x90200 ~ 0x90C00
!又因为栈顶地址必须高于 setup 程序的最高地址(0x90C00)
!栈顶地址(0x9FF00) - setup 结束地址(0x90C00) = 0xF500,栈的大小为0xF500
	
————————————————
;3、加载 setup 模块到 0x90200
load_setup:
	mov	dx,#0x0000		! dh磁头号为0,dl驱动器号为0
	mov	cx,#0x0002		! cl起始扇区号2,因为bootset占了第一个扇区,故从第二个扇区读 ch柱面号0
	mov	bx,#0x0200		! 偏移地址0x200
	mov	ax,#0x0200+SETUPLEN	! 功能号ah=0x02,表示读取扇区,al=要读的扇区数目=SETUPLEN=4 
	!以上为从第二个扇区开始,读取4个扇区,因为第一个扇区地址为90000,一个扇区512字节,
	十六进制为0x200,故setup起始地址为90200
	!es:bx=内存地址,在执行go模块后,es=0x9000,bx=200,es:bx正好也为90200
	int	0x13			! BOIS读磁盘的中断
	jnc	ok_load_setup	! CF = 0 则跳转
	mov	dx,#0x0000     
	mov	ax,#0x0000		!ah功能号为0,al扇区数量为0
	int	0x13            ! 复位磁盘
	j	load_setup
————————————————


ok_load_setup:
;4、获得磁盘驱动器参数(主要是每磁道的扇区数)
	mov	dl,#0x00    !驱动器号为0,说明是软盘
	mov	ax,#0x0800	!ah功能号为0x08,为获取驱动器参数
	int	0x13
	mov	ch,#0x00    !这里用不上软盘的最大磁道号,可以使CH=0      
	mov	sectors,cx  !存下磁道的扇区数
	
	;5、打印一段开机logo
	mov	ah,#0x03	!功能号,读光标的位置
	xor	bh,bh       !bh=页号=0
	int	0x10   !ah为03,故读光标
	mov	cx,#24          ! 24个字符
	mov	bx,#0x0007		! bh页号为0, bl属性为07 , 黑底浅灰字
	mov	bp,#msg1  !bp为显示的字符在内存的什么地方,#msg1为偏移,在bootsect.s尾部
	mov	ax,#0x1301		!功能号ah为13,为在屏幕上显示字符串
	!功能号子参数为01,为使用指定属性,光标更新
	int	0x10  !ah为13,故为显示字符,同一中断号调用不同功能
	
	;6、加载 system 模块
	mov	ax,#SYSSEG  ! SYSSEG=0x1000
	mov	es,ax		! segment of 0x010000
	call	read_it  !读入system模块
	
	;7、跳转到 setup.s 执行
	jmpi 0,SETUPSEG //转入0x9020:0x0000,即90200执行setup.s

!bootsect.s文件尾部:
sectors: .word 0 !扇区磁道数
msg1:
	.byte 13,10
	.ascii "Loading system ..."  !开机时屏幕显示的logo,共cx个字符
	.byte 13,10,13,10

!以上操作为在内存为bp的地方,读取24个字符,页号为0,颜色为黑底浅灰色字

总结,以上代码作用为: 把 bootsect 自己从0x7c00 拷贝到0x90000,设置段寄存器和栈,然后从磁盘加载 setup 模块到0x90200,再打印一段提示信息,最后加载 system 模块,并跳转到 setup 的入口执行。

setup.s

操作系统的代码,完成启动前的操作

INITSEG  = 0x9000	! bootsect.s 的段地址
SYSSEG   = 0x1000	! 系统加载在 0x10000 
SETUPSEG = 0x9020	! 本程序的段地址

start: mov ax,#INITSEG 
mov ds,ax   ;ds=0x9000
mov ah,#0x03    ;0x10中断下ah=0x03为 读取光标位置返回给dx
xor bh,bh int 0x10  
dx mov [0],dx  ;即mov WORD PTR [ds:0], dx  从上可知ds为9000
[0]前面默认有个段寄存器,当前段都指向9000,9000<<4 +0=0x90000
;故将dx给0x90000
mov ah,#0x88 ;0x15中断下,ah=0x88为获取扩展内存大小,返回给ax
int 0x15 
mov [2],ax ... ;[2]为9000<<4+2=0x90002,将扩展内存数存在0x90002处
cli                 //不允许中断
mov ax,#0x0000   cld
do_move: mov es,ax ;es为0x0000 ,do_move类似do while循环,此处进入循环
add ax,#0x1000  ;ax为0x1000
cmp ax,#0x9000  ;ax-9000!=0,故zf=0
jz end_move   ;因zf=0,所以不相等,不跳转,直到ax==0x9000,此时zf=1,终止循环  
;end_move为循环终止
mov ds,ax   ;ds=0x1000
sub di,di  
sub si,si  ;di=si=0x0000
;此时ds:si源地址0x10000   es:di目标地址0x00000
mov cx,#0x8000   ;cx为计数器
rep                 
movsw   ;从0x10000到0x00000移动字,搬运32768次,每次搬运1字,即2字节,2*32768=65536字节
即移动0x10000字节,故是0x10000~0x20000移动到0x00000~0x10000
;最后一次循环es:di为0x70000,di:si为0x80000,故是0x80000~0x90000移动到0x70000~0x80000
jmp do_move  ;跳转do_move继续循环
;以上循环结果为,0x10000~0x90000内容搬运到0x00000~0x80000

;以上结果为操作系统往后一直处于0地址开头,并获取硬件参数,为操作系统管理硬件做准备

linux0.11系列之(二): 启动引导 bootsect.s linux按照学习思路,可以姑且分为五大部分: 启动引导,系统调用,进程调度,内存管理,文件系统那我们从 linux0.11 的启动开始探索。我们可以在boot/目录下看到有三个汇编文件,构成我们linux启动的过程。分别为setup.s, bootsect.s, head.s 其中setup.s也给编译器指明了整个linux启动的入口:entry start start:故事就从这里开始吧。引 阅读详情

相关推荐

ComfyUI安装包运行前准备:安装Git

Git 是一个分布式版本控制系统(Version Control System, VCS),用于跟踪和管理文件(尤其是代码)的变更历史。 简单理解就是,git是用来管理文件的版本的,如果有新的版本,就可以使用git来更新。

聚梦小课堂 2万+

【操作系统系列】Linux 系统启动:bootsect.s、setup.s

系统启动 总体启动过程: (1)BIOS 读入了操作系统的第一个扇区 bootsect.s 文件,然后执行 bootsect.s 执行; (2)bootsect.s 又读入了操作系统的 setup.s 文件,将来交给 setup.s 执行,在其中会完成一些操作系统设置工作; (3)接下来 bootsect.s 还要读入操作系统的主体模块 system 模块,在setup.s 执行完成以后到 system 执行中。 在计算机加电以后,硬件电路会初始化设置PC 寄存器的值。 对于 IBM PC 而言,这个

菜鸡也有大佬梦 2854

使用Typora时LaTeX内联公式简单汇总

0、前言 在使用Typora写笔记时,有时候需要添加上LaTeX排版的公式。以下是整理出的一份简单笔记,方便记忆不清楚时查阅。笔记暂时不够完善,之后再补充。 注:有些公式语法KateX不能解析,但在Typora中可以使用(不用在意) 1、一些基本内联公式 位置关系 展示 LaTeX 说明 x2x^{2}x2 x^{2} 右上标 x2x_{2}x2​ x_{2} 右下标 2x{}^{2}x2x {}^{2}x 左上标 2x{}_{2}x2​x {}_{2}x 左下标

白白旧维的博客 4442

操作系统(一) -- 操作系统的启动(bootsect、setup、head、main)

1. 宏观认识操作系统 1.1 什么是操作系统 操作系统是底层计算机硬件与上层应用软件之间的一个软件,计算机的一切活动都是通过cpu、内存、显卡、显示器等硬件设备来实现的;那为什么我们平时操作计算机的时候从来都不用关心这些东西呢?在c语言里面为什么一个printf(“hello world!”);就可以在屏幕上面显示出”hello world”,而不需要关心cpu、内存这些东西呢?这都是因为有操作系统的存在,其实我们在printf(“hello world!”);的时候都是需要cpu、内存、显卡、总线等

www_dong的博客 2223

一文读懂AI大模型时代的RAG技术

RAG(Retrieval-Augmented Generation,检索增强生成) 是一种结合检索技术与生成模型的技术架构,旨在通过动态引入外部知识库增强大语言模型(LLM)的生成能力。其核心思想是通过检索系统从外部数据源(如企业知识库、实时文档等)获取相关信息,并将检索结果作为上下文输入生成模型,以提高生成答案的准确性、时效性和专业性

awei0916的专栏 2119

C#实战:如何从零构建一个轻量级软PLC梯形图编辑器(附完整源码)

本文详细介绍了如何使用C#从零开始构建一个轻量级软PLC梯形图编辑器。内容涵盖项目架构设计、GDI+图形渲染、编辑交互实现以及核心的扫描执行引擎开发,并提供了定时器、计数器等高级功能的实现思路与完整源码,为开发者深入工业自动化领域提供了实战指南。

4k5l6j7h8的博客 257

bootsect及setup

BIOS和bootsect CPU加电即进入16位实模式 硬件逻辑设计为加电瞬间强行设置:CS=0xF000,IP=0xFFF0,CS:IP=0xFFFF0 而BIOS程序的入口地址即0xFFFF0,是计算机上电后CPU执行的第一条指令的地址 BIOS程序在内存中加载中断向量表和中断服务程序 调用INT 0x19中断,将软盘第一扇区(0面0磁道1扇区)的5...

weixin_30413739的博客 148

计算机视觉 | 面试题:01、过拟合和欠拟合的表现与解决方法

问题 过拟合和欠拟合的表现和解决方法。 其实除了欠拟合和过拟合,还有一种是适度拟合,适度拟合就是我们模型训练想要达到的状态,不过适度拟合这个词平时真的好少见,在做酷狗音乐的笔试题时还懵逼了一会,居然还真的有这样的说法。 这应该是基础中的基础了,笔试题都做烂了。那就当做今天周末,继续放个假吧…… 过拟合 过拟合的表现 模型在训练集上的表现非常好,但是在测试集、验证集以及新数据上的表现很差,损失曲线呈现一种高方差状态。(高方差指的是训练集误差较低,而测试集误差比训练集大较多) 过拟合的原因 从两个角度去分析

Mrrunsen的博客 868

linux内核bootsect.S和setup.S流程

bootsect.s流程 将0x07c00的代码移动到0x90000处并跳转到0x90000处继续执行。 (0x07c00的代码BOIS加载的引导扇区) 跳转后重新设置寄存器(设置段寄存器为0x9000,sp为0x4000-12,代码段,数据段,堆栈段都设置完毕) 从内存0x00078复制原软驱参数表到0x94000-12处,然后修改表中的每磁道最大扇区数为18. 加载setuo模块(后面的4个扇

pk_20140716的专栏 1454

【YOLOv10改进[Backbone]】使用ADNet改进YOLOv10在噪声干扰下的目标检测效果(图像去噪)+ 含全部代码和详细修改方式 + 手撕结构图 + 全网首发

使用ADNet改进YOLOv10在噪声干扰下的目标检测效果(图像去噪)+ 含全部代码和详细修改方式 + 手撕结构图 + 全网首发 + 遥遥领先

静谧、淡雅 2858

【docker】--- 详解 WSL2 中的 Ubuntu 和 Docker Desktop 的区别和关系!

在编程的艺术世界里,代码和灵感需要寻找到最佳的交融点,才能打造出令人为之惊叹的作品。而在这座秋知叶i博客的殿堂里,我们将共同追寻这种完美结合,为未来的世界留下属于我们的独特印记。

秋知叶i 1314

OS实验:bootsect.s 和 setup.s

写在前面 由于直接复制粘贴代码到vim上会出现\r\n导致一些奇怪的错误,因此通过: :%s+\\r\\n+^M+g 能够有效地去掉这些,方便阅读的同时减少错误。 实验内容: 改写 bootsect.s 主要完成如下功能: bootsect.s 能在屏幕上打印一段提示信息“XXX is booting...”,其中 XXX 是你给自己的操作系统起的名字,例如 LZJos、Sunix 等(可以上论坛上秀秀谁的 OS 名字最帅,也可以显示一个特色 logo,以表示自己操作系统的与众不同。) 改写 setup

小楼一夜听春雨 1201

WINCC7.3破解文件

WINCC7.3硬件够破解文件,有需要的下载!WINCC7.3硬件够破解文件,有需要的下载!

linux0.11启动时bootsect.s和setup.s的主要作用

cpu启动时为实模式,此时硬烧录的将cs=0xFFFF,ip=0x0,并自动开始执行0xFFFF0(ROM-BIOS的地址)的代码,BIOS会自检,并在0x0地址处设置中断向量表,此后实模式的int中断全部依赖此表,并将0磁道0扇区的512字节(引导扇区,放bootsect.s)读入内存0x7c000处,并跳转到此地址. bootsect.s只能占512字节,功能有限,所以需要setup.s, 首先bootsect.s将自身从0x7c000移动到0x90000(为setup.s将system移动到0x00

apkjdk的博客 1230

Camera2Demo

在Camera2 的基础上进行封装,使得Camera2一堆初始化逻辑与Activity分离,降低耦合度,完成预览拍照并保存的操作

廖雪峰Python教程[完整版]

廖雪峰的python教程整理的,已经排好版了,而且还是完整的,适合小白

HIT oslab之实验2 操作系统的引导(bootsect.s + setup.s)

零、实验1 实验环境搭建 1.参考教程 2.遇到的问题 (1)dokg: 错误:另外一个进程已经为 dpkg fronted lock 加锁 解决办法:重启,解释 3.补充:查看ubuntu 位数 uname -a 一、实验2的内容 1.实现bootsect.s的屏幕输出功能; 2.bootsect.s读入setup.s; 3.setup.s获取并显示基本硬件参数; 教程:操作系统原理与实践 二、实现bootsect.s的屏幕输出功能 1.代码(和教程有点不同,在2.说明里解释了;按照教程来) m

南七行者的博客 5329

NTscan扫描工具

ntscan是一个扫描器,可以扫描没有密码和弱密码的共享,先到配置文件中填写猜测的用户名和密码,扫描过程中右侧出现的是扫描日志。

linux解析方式,Linux 引导解析(使用bootsect.s+setup.s方式)

我详细解析了bootsect.s,同时阅读了setup.s。其中bootsect.s存放于磁盘的主引导扇区,bios-startup程序加载该程序(bootsect.s)到内存0x700处,并由此执行bootsect.s来引导Linuxkernel。在bootsect.s中加载setup.s至内存中,并在执行完它自身后,jump跳至刚刚已读入的setup部份,继续执行。Linux Kernel I...

weixin_33290540的博客 8714

Linux启动分析 bootsect.S、setup.S、head.S分析(学习转)

Linux启动分析(1)— 一、系统引导过程总体介绍启动流程图:  系统引导过程主要由以下几个步骤组成(以硬盘启动为例) 1、开机;  2、 BIOS加电自检(POST——Power On Self Test),包括检查RAM,keyboard,显示器,软硬磁盘等等。Intel系列的CPU首先进入的是实模式,并开始执行位于地址0xFFFF0处的代码,也就是ROM-BIOS起始位置的代码;3、搜索启动的操作系统,根据BIOS设置,可能会依次访问每个软盘的第一个扇区、硬盘、CD-ROW等;一旦找到有效的启动设备

zhang405744522的专栏 1678

bootsect.S 剖析

本文的目的,在于将linux kernel的boot部分做一个介绍,因为笔者觉得很少有这样的 文章来介绍一个操作系统最最开始的一步----把kernel本身载入至内存中,同时进行一些 机器相关(machine dependent)的初始化工作,由于linux刚好使用的是大家最熟悉的386, 486系列PC,所以在说明其程序流程时,也刚好可以对其相关的PC硬体架构做探讨,可以 说是一举两得。不过

csshuke的专栏 3899

Linux启动分析— bootsect.S、setup.S、head.S分析

bootsect.S,系统引导程序,一般不超过512字节。     在PC系统结构中,线性地址0xA0000以上,即640K以上用于图形接口卡和BIOS自身,640K以下为系统的基本内存。如果配置更多的内存,则0x100000,即1MB处开始称为高内存。当BIOS引导一个系统时

wangsheng8888的专栏 623

linux源代码阅读-系统启动bootsect.s

系统启动bootsect.S一般PC在电源一开时,是由内存中地址FFFF:0000开始执行(这个地址一定在ROM BIOS中,ROM BIOS一般是在FEOOOh到FFFFFh中),而此处的内容则是一个jump指令,jump到另一个位於ROM BIOS中的位置,开始执行一系列的动作,包括了检查RAM,keyboard,显示器,软硬磁盘等等,这些动作是由系统测试代码 (POST,system tes

cglin的专栏 1239

【操作系统】实验楼实验2-操作系统的启动

实验2 ——操作系统的启动 载入环境 cd /home/shiyanlou/oslab/ tar -zxvf hit-oslab-linux-20110823.tar.gz \ -C /home/shiyanlou/ ls -al cd ./linux-0.11/ cd ./boot/ ​ 首先进入oslab文件夹,找到目标压缩包并解压,查看是否解压成功后进入系统。 改写bootsect.s并显示 mv bootsect.s bootsect-old.s gedit bootsect.s ​ 创建一

qq_46612803的博客 2277

Bochs调试Linux内核5 - 启动过程调试 - 认识Bootsect.S

Linux启动到执行顺序是,启动顺序是:BIOS--Bootsect.S--setup.S--head.s---main.c;

bcbobo21cn的专栏 977

Linux 引导解析(使用bootsect.s+setup.s方式)

<br /><br /> 我详细解析了bootsect.s,同时阅读了setup.s。其中bootsect.s存放于磁盘的主引导扇区,bios-startup程序 加载该程序(bootsect.s)到内存0x700处,并由此执行bootsect.s来引导Linux kernel。在bootsect.s中加载setup.s至内存中,并在执行完它自身后,jump跳至刚刚已读入的setup部份,继续执行。 <br />   Linux Kernel Image 生成过程:   一. 引导扇区汇编代码bo

thewayma的专栏 3688

linux0.11启动第一步:bootsect.s

! !#2014-12-13:16-53《开始小结linux启动汇编之旅》 ! !#我们按下开关,执行BIOS程序(上电自检等),最后BIOS自动 !#加载MBR(即主引导分区,主引导分区上的512个字节放着我们 !#的bootsect.s程序--是编译好的二进制码) !#将bootsect.s程序加载到内存0x07c0处(这是BIOS厂商与OS之间 !#的一个协定,BIOS相当一个

you 807
上一篇: 吴恩达机器学习非监督学习
Lincooo
博客等级 码龄4年 61粉丝 6原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值