操作系统与网络实现 之三

关于磁盘的数据存储和定位

这是一个磁盘示意图:

一个磁盘有两面。0面和1面。

磁道共80个,编号由外向里(0号-79号)。

扇区(Sector)是磁盘存储的最小单位,一个扇区有512字节,一个磁道有18个扇区(1号-18号)。

为方便存取文件必须对扇区进行编号,这编号称为软盘地址。软盘地址由磁头号、磁道号、扇区号三部分组成。

(1)磁头号。0面对应0号磁头,1面对应1号磁头。

(2)磁道号。从软盘的最外侧00道开始,由外向里排列,3.5英寸高密软盘共80个磁道。

(3)扇区号。1号至18号

软盘的大小计算方式如下:

2*80*18*512 = 1474560Byte = 1440KB

如果我们用磁头号+磁道号+扇区号来表达,那么:0.0.1表示0面0磁道1扇区

读磁盘是这样的,在同一磁道里的18个扇区是连续读,读完这个磁道,转换磁头,那么就像下面这样:

0.0.1读至0.0.18,转换磁头,1.0.1读至1.0.18,转换磁头,0.1.1读至0.1.18,转换磁头,1.1.1读至1.1.18,......

对应的我们将用到int 13h功能,这里介绍一下:

功能02H 
功能描述:读扇区 
入口参数:AH=02H
AL=扇区数 
CH=磁道 
CL=开始扇区 
DH=磁头 
DL=驱动器号,00H~7FH:软盘;80H~0FFH:硬盘   这里我们的DL是0
ES:BX=缓冲区的地址  也就是我们要写入的地址

下面我们看看将一个kernelloader.asm的可执行代码kernelloader.bin读到内存0x1000中的子程序,前面已经知道,boot.bin存放在0磁道第1个扇区,kernelloader.bin紧接着boot.bin,排列在0磁道第2个扇区,目前kernelloader共占据1个扇区512字节:

read_kernelloader:                                       ;读入 kernelloader 程序

push              es

.read_kernelloader:

mov               ax , 0x1000                           ;kernelloader.bin 所在的段基址

mov               es , ax

mov               bx , 0                                 ;写入到内存0x1000:0000

mov               ah , 2

mov               dh , 0                                 ;磁头

mov               dl , 0                                  ;驱动器号

mov               ch , 0                                  ;磁道0

mov               cl , 2                                  ;第2个扇区

mov               al , 1                                  ;读入扇区数,每个扇区为 512B

int               0x13

jc                .read_kernelloader

pop               es

ret

因为受512字节限制,boot.asm能做的事情实在有限,下面我们改变一下boot.asm功能,让它只负责读取kernelloader程序到内存0x1000:0000的地方,然后跳转到0x1000:0000执行kernelloader程序,这样可以摆脱boot启动程序只有512字节的限制,可以让kernelloader做许多事情。

两个程序如下:

boot.asm

[BITS 16]                                                  ;编译成16位的指令

[ORG 0x7C00]

jmp                 main

read_kernelloader:                                        ;读入 kernelloader 程序

push              es

.rk:

mov               ax , 0x1000                            ;kernelloader.bin 所在的段基址

mov               es , ax

mov               bx , 0

mov               ah , 2

mov               dl , 0

mov               ch , 0

mov               cl , 2

mov               al , 1                                 ;读入扇区数,每个扇区为 512B

int               0x13

jc                .rk

pop               es

ret

main:                                                       ;主程序

mov               ax , 0x0                               ;boot.bin 程序的段基址

mov               ds , ax

call              read_kernelloader                    ;读入 kernelloader 程序

jmp dword         0x1000:0                              ;跳转到 kernelloader 处执行

times 510-($-$$) db 0

db 0x55

db 0xAA

kernelloader程序将放在boot程序之后,目前小于512字节,也就是0面,0磁道,第二扇区开始,占据一个扇区的位置。

kernelloader.asm

[BITS 16]

jmp main

ns db 0x48,0x65,0x6C,0x6C,0x6F,0x20,0x77,0x6F,0x72,0x6C,0x64,0x21,‘f‘,‘r‘,‘o‘,‘m‘,‘ ‘,‘y‘,‘a‘   ;;hello world!from ya

main:

mov ax, cs

mov ds, ax

mov es, ax

mov cx,19           ;循环19次

mov bx,0            ;从数组[0]开始

mov ah,0eh

next:

mov al,[ns+bx]

int 10h

inc bx

dec cx

jnz next              ;cx不为0则继续

po:

jmp po

修改makefile文件,最后在bochs运行a.img,显示Hello world!from ya

makefile

######################

#声明要编译的所有组成,这里的ya是本工程名称,可以取任何名字,这里就用ya

######################

ya:out/boot.bin out/kernelloader.bin out/creat_img.exe out/write_in_img.exe A B C

#开始对各部分编译,注意不是空格是Tab键

out/boot.bin:code/boot.asm

nasm code/boot.asm -o out/boot.bin

out/kernelloader.bin:code/kernelloader.asm

nasm code/kernelloader.asm -o out/kernelloader.bin

# 制作内核映象文件

out/creat_img.exe:code/creat_img.c

gpp code/creat_img.c -o out/creat_img.exe

# 执行dos命令,在final目录下生成a.img文件

A:

out/creat_img.exe final/a.img

# 写入文件,argv[1]=目标文件 argv[2]=源文件  argv[3]=写入偏移量

#在DOS下用法: write.exe a.img kernelloader.bin 512

out/write_in_img.exe:code/write_in_img.c

gpp code/write_in_img.c -o out/write_in_img.exe

# 执行dos命令,向a.img写入代码,内容是boot.bin

# 从0偏移量起始

B:

out/write_in_img.exe final/a.img out/boot.bin 0

# 执行dos命令,向a.img写入代码,内容是kernelloader.bin

# boot.bin已经占用了512字节,从512偏移量起始

C:

out/write_in_img.exe final/a.img out/kernelloader.bin 512

时间: 2024-08-04 09:13:54

操作系统与网络实现 之三的相关文章

什么是网络操作系统?网络操作系统具有哪些基本功能?

网络操作系统是网络上各计算机能方便而有效地共享网络资源,为网络用户提供所需的各种服务的软件和有关规程的集合. 网络操作系统与通常的操作系统有所不同,它除了应具有通常操作系统应具有的处理机管理.存储器管理.设备管理和文件管理外, 还应具有以下两大功能:(1)提供高效.可靠的网络通信能力:(2)提供多种网络服务功能,如:远程作业录入并进行处理的服务功能:文件转输服务功能:电子邮件服务功能:远程打印服务功能 原文地址:https://www.cnblogs.com/Hello1world/p/9940

爬虫学习 05.Python网络爬虫之三种数据解析方式

爬虫学习 05.Python网络爬虫之三种数据解析方式 引入 回顾requests实现数据爬取的流程 指定url 基于requests模块发起请求 获取响应对象中的数据 进行持久化存储 其实,在上述流程中还需要较为重要的一步,就是在持久化存储之前需要进行指定数据解析.因为大多数情况下的需求,我们都会指定去使用聚焦爬虫,也就是爬取页面中指定部分的数据值,而不是整个页面的数据.因此,本次课程中会给大家详细介绍讲解三种聚焦爬虫中的数据解析方式.至此,我们的数据爬取的流程可以修改为: 指定url 基于r

操作系统和网络基础的整理

操作系统 为何要有操作系统: 计算机系统非常庞大难懂,程序员写程序时需要搞懂计算机系统,效率很低. 操作系统的出现缓解了程序员的大部分工作,操作系统管理及优化计算机硬件,程序员不需要全部搞懂计算机系统就可写代码编写软件. 软件在操作系统的基础上运行,间接使用硬件. 操作系统的位置: 操作系统位于计算机硬件及应用程序之间,协调.管理和控制计算机硬件和软件系统的一个程序. 操作系统的功能: 操作系统协调.管理和控制计算机硬件和软件的一个软件. 操作系统的功能由操作系统运行内核态管理硬件和操作系统运行

操作系统与网络基础

操作系统简介 1.为什么需要操作系统? 现代计算机系统是一个复杂的系统.应用程序员无法掌握其中的每一个细节,于是,计算安装了一层软件(系统软件),称为操作系统.它的任务就是为用户程序提供一个更好.更简单.更清晰的计算机模型,并管理计算机系统中的所有设备.简单来讲,将硬件这些繁琐的工作由操作系统来干,程序员只需要考虑自己的应用软件的编写,应用软件直接使用操作系统提供的功能来间接使用硬件. 2.操作系统的位置 操作系统位于计算机硬件与应用软件之间,本质也是一个软件.操作系统由操作系统的内核(运行于内

ovf虚机模板导入后,操作系统原网络设置失效,脚本设定新的网络!

从虚拟机ovf模板导入的虚拟机网络设置会发生改变,网卡会发生改变,所以导致虚拟机启动后网络不能用. 所以要做下面几件事情,网络才会可用: 1 首先查看/etc/udev/rules.d/70-persistent-net.rules文件,在文件最后出现的eth网卡为系统建立的新网卡,以及mac地址.将原来网卡那行注释掉. 2 查看/etc/sysconfig/network-scripts/ifcfg-eth0(1)这个文件,这个文件为原始虚拟机的网络设置 3 将原有ifcfg-eh文件进行改名

(48)LINUX应用编程和网络编程之三Linux获取系统信息

3.3.1.关于时间的概念 3.3.1.1.GMT时间 (1)GMT是格林尼治时间,也就是格林尼治地区的当地之间. (2)GMT时间的意义?[用格林尼治的当地时间作为全球国际时间],用以描述全球性的事件的时间,方便大家记忆 (3)一般为了方便,一个国家都统一使用一个当地时间. 3.3.1.2.UTC时间 (1)GMT时间是以前使用的,使用天文来测试的,近些年来越来越多的使用UTC原子钟时间. (2)关于北京时间,可以参考:http://www.cnblogs.com/qiuyi21/archiv

Python网络爬虫之三种数据解析方式

引入 回顾requests实现数据爬取的流程 指定url 基于requests模块发起请求 获取响应对象中的数据 进行持久化存储 其实,在上述流程中还需要较为重要的一步,就是在持久化存储之前需要进行指定数据解析.因为大多数情况下的需求,我们都会指定去使用聚焦爬虫,也就是爬取页面中指定部分的数据值,而不是整个页面的数据.因此,本次课程中会给大家详细介绍讲解三种聚焦爬虫中的数据解析方式.至此,我们的数据爬取的流程可以修改为: 指定url 基于requests模块发起请求 获取响应中的数据 数据解析

《Python网络爬虫之三种数据解析方式?

回顾requests实现数据爬取的流程 指定url 基于requests模块发起请求 获取响应对象中的数据 进行持久化存储 其实,在上述流程中还需要较为重要的一步,就是在持久化存储之前需要进行指定数据解析.因为大多数情况下的需求,我们都会指定去使用聚焦爬虫,也就是爬取页面中指定部分的数据值,而不是整个页面的数据.因此,本次课程中会给大家详细介绍讲解三种聚焦爬虫中的数据解析方式.至此,我们的数据爬取的流程可以修改为: 指定url 基于requests模块发起请求 获取响应中的数据 数据解析 进行持

05,Python网络爬虫之三种数据解析方式

回顾requests实现数据爬取的流程 指定url 基于requests模块发起请求 获取响应对象中的数据 进行持久化存储 其实,在上述流程中还需要较为重要的一步,就是在持久化存储之前需要进行指定数据解析.因为大多数情况下的需求,我们都会指定去使用聚焦爬虫,也就是爬取页面中指定部分的数据值,而不是整个页面的数据.因此,本次课程中会给大家详细介绍讲解三种聚焦爬虫中的数据解析方式.至此,我们的数据爬取的流程可以修改为: 指定url 基于requests模块发起请求 获取响应中的数据 数据解析 进行持