当前位置: 首页 > wzjs >正文

电子商务网站数据库怎么做国内最新新闻事件今天

电子商务网站数据库怎么做,国内最新新闻事件今天,襄樊做网站,wordpress nginx 伪静态文章目录 前言获取物理内存容量利用 BIOS 中断 0x15 子功能 0xe820 获取内存利用 BIOS 中断 0x15 子功能 0xe801 获取内存利用 BIOS 中断 0x15 子功能 0x88 获取内存内存容量检测代码编译运行 结语 前言 经过上一章的学习实践,目前我们已经进入32位保护模式了。本章…

文章目录

    • 前言
    • 获取物理内存容量
      • 利用 BIOS 中断 0x15 子功能 0xe820 获取内存
      • 利用 BIOS 中断 0x15 子功能 0xe801 获取内存
      • 利用 BIOS 中断 0x15 子功能 0x88 获取内存
      • 内存容量检测代码
      • 编译运行
    • 结语

前言

经过上一章的学习实践,目前我们已经进入32位保护模式了。本章的标题是保护模式进阶,向内核迈进,那么就是要在保护模式下进一步编程。

郑钢老师在上一章提到,之前的四章偏向于理论,代码量相对较小,接下来的章节代码量会更多,这对我而言会是一个挑战。

这章内容较多,我打算花2-3天时间完成学习,博客也会分成若干部分,每部分完成一节内容。

第四章知识笔记博客链接:《操作系统真象还原》第四章(1)-CSDN博客

第四章实践部分博客链接:《操作系统真象还原》第四章(2)-CSDN博客

本章参考博客链接:《操作系统真象还原》第五章 ---- 轻取物理内存容量 启用分页畅游虚拟空间 力斧直斩内核先劈一角 闲庭信步摸谈特权级_真象还原 分页 info tab-CSDN博客


获取物理内存容量

保护模式可以访问4GB内存,为了维护这么大的内存空间,就要有相应的内存管理体系。想要管理内存,首先就要先获取内存容量,bios可以通过0x15中断获取内存信息,bios是在实模式下运行的,我们要在进入保护模式之前获取内存容量。

利用 BIOS 中断 0x15 子功能 0xe820 获取内存

子功能 0xE820 的强大之处是返回的内存信息较丰富,包括多个属性字段,所以需要一种格式结构来组织这些数据。内存信息的内容是用地址范围描述符来描述的,用于存储这种描述符的结构称之为地址范围描述符(Address Range Descriptor Structure,ARDS)。

ards长20字节,分为5段,每段4字节,每次调用0x15就会返回一个这样结构的数据。

字节偏移量属性名称描述
0BaseAddrLow第32位基地址
4BaseAddrHigh高32位基地址
8LengthLow低32位内存长度,以字节为单位
12LengthHigh高32位内存长度,以字节为单位
16Type本段内存类型

关于type字段

Type 值名 称描 述
1AddressRangeMemory这段内存可以被操作系统使用
2AddressRangeReserved内存使用中或者被系统保留,操作系统不可以用此内存
其他未定义未定义,将来会用到,目前保留。但是需要操作系统一样将其视为ARR(AddressRangeReserved)

关于0x15中断的0xe820子功能的参数

调用或返回寄存器或状态位参 数 用 途
输入EAX子功能号:EAX 寄存器用来指定子功能号,此处输入为 0xE820
EBXARDS 后续值:内存信息需要按类型分多次返回,由于每次执行一次中断都只返回一种类型内存的 ARDS 结构,所以要记录下一个待返回的内存 ARDS,在下一次中断调用时通过此值告诉 BIOS 该返回哪个 ARDS,这就是后续值的作用。第一次调用时一定要置为 0,EBX具体值我们不用关注,字取决于具体 BIOS 的实现。每次中断返回后,BIOS 会更新此值
ES:DIARDS 缓冲区:BIOS 将获取到的内存信息写入此寄存器指向的内存,每次都以 ARDS 格式返回
ECXARDS 结构的字节大小:用来指示 BIOS 写入的字节数。调用者和 BIOS 都同时支持的大小是 20 字节,将来也许会扩展此结构
EDX固定为签名标记 0x534d4150,此十六进制数字是字符串 SMAP 的 ASCII 码:BIOS 将调用者正在请求的内存信息写入 ES:DI 寄存器所指向的 ARDS 缓冲区后,再用此签名校验其中的信息
输出CF 位若 CF 位为 0 表示调用未出错,CF 为 1,表示调用出错
EAX字符串 SMAP 的 ASCII 码 0x534d4150
ES:DIARDS 缓冲区地址,同输入值是一样的,返回时此结构中已经被BIOS 填充了内存信息
ECXBIOS 写入到 ES:DI 所指向的 ARDS 结构中的字节数,BIOS 最小写入 20 字节
EBX后续值:下一个 ARDS 的位置。每次中断返回后,BIOS 会更新此值,BIOS 通过此值可以找到下一个待返回的 ARDS 结构,咱们不需要改变 EBX 的值,下一次中断调用时还会用到它。在 CF 位为 0 的情况下,若返回后的 EBX 值为 0,表示这是最后一个 ARDS 结构

此中断的调用步骤如下。

  1. 填写好“调用前输入”中列出的寄存器。
  2. 执行中断调用 int 0x15。
  3. 在 CF 位为 0 的情况下,“返回后输出”中对应的寄存器便会有对应的结果。

利用 BIOS 中断 0x15 子功能 0xe801 获取内存

这种方法相对简单,但是只能识别4GB内存,而且数据放到两个寄存器里。低于 15MB 的内存以 1KB 为单位大小来记录,单位数量在寄存器 AX 和 CX 中记录,其中 AX 和 CX 的值是一样的,所以在 15MB 空间以下的实际内存容量=AX*1024。AX、CX 最大值为 0x3c00,即 0x3c00*1024=15MB。16MB~4GB 是以 64KB 为单位大小来记录的,单位数量在寄存器 BX 和 DX 中记录,其中 BX 和 DX 的值是一样的,所以 16MB 以上空间的内存实际大小=BX*64*1024

为什么要分成两部分,分界线是16mb?为了兼容有24根地址总线的80286cpu,此cpu寻址范围是16mb,当时有一些isa设备要利用15-16mb空间作为缓冲区,出现了内存空洞。后续cpu为了兼容286保留了这一特性。

相关参数如下

调用或返回寄存器或状态位描述
输入AX子功能号:0xE801
输出CF若 CF 位为 0 表示调用未出错,CF 为 1,表示调用出错
AX以 1KB 为单位,只显示 15MB 以下的内存容量,故最大值为 0x3c00,即AX 表示的最大内存为 0x3c00*1024=15MB
BX以 64KB 为单位,内存空间 16MB~4GB 中连续的单位数量,即内存大小为 BX*64x1024 字节
CX同AX
DX同BX

此中断的调用步骤如下。

  1. 将 AX 寄存器写入 0xE801。
  2. 执行中断调用 int 0x15。
  3. 在 CF 位为 0 的情况下,“返回后输出”中对应的寄存器便会有对应的结果。

利用 BIOS 中断 0x15 子功能 0x88 获取内存

最后一个获取内存的方法也同样是 BIOS 0x15 中断,子功能号是 0x88。该方法使用最简单,只能识别最大 64MB 的内存。使用的时候结构要加上1MB。

输入:AH 子功能号:0x88

输出:1.CF 位 若 CF 位为 0 表示调用未出错,CF 为 1,表示调用出错

2.AX 以 1KB 为单位大小,内存空间 1MB 之上的连续单位数量,不包括低端1MB 内存。故内存大小为 AX*1024 字节+1MB

此中断的调用步骤如下。

(1)将 AX 寄存器写入 0x88。

(2)执行中断调用 int 0x15。

(3)在 CF 位为 0 的情况下,“返回后输出”中对应的寄存器便会有对应的结果。

内存容量检测代码

关于jxx组指令的参考博客:汇编跳转指令: JMP、JECXZ、JA、JB、JG、JL、JE、JZ、JS、JC、JO、JP 等_jg指令-CSDN博客

%include "boot.inc"
section loader vstart=LOADER_BASE_ADDRLOADER_STACK_TOP equ LOADER_BASE_ADDRjmp loader_start
;-------------------- 这部分完成GDT和4个段描述符的构建 --------------------------------
;编译后程序的地址是越来越高的,所以代码要先开辟低地址再开辟高地址。8字节64位是一个段描述符。dd命令开辟出一个4字节32位空间。
GDT_BASE:dd 0x00000000dd 0x00000000		;第一个段描述符无法使用,开辟出来空着
CODE_DESC:dd 0x0000ffff		;前四位是16位段基址,设置为0,后四位是16位段界限,设置为1。高位在前低位在后dd DESC_CODE_HIGH4	;提前在配置文件中写好的高32位
DATA_STACK_DESC:dd 0x0000ffffdd DESC_DATA_HIGH4	;数据和栈用相同的段描述符,具体说明看博客
VIDEO_DESC:dd 0x80000007		;这部分请看博客里的说明。dd DESC_VIDEO_HIGH4
;-------------------- 这部分完成GDT大小的计算,同时预留出60个段描述符的空间 --------------------------------
;这部分为加载gdt做准备。dq定义4字8字节64位。times是nasm提供的伪指令,作用是循环。以后我们还要向gdt里添加别的表符,这里提前留出位置。GDT_SIZE equ $-GDT_BASEGDT_LIMIT equ GDT_SIZE-1times 59 dq 0times 5 db 0
;-------------------- 这部分完成构建选择子 --------------------------------
;选择子放在段寄存器里,16位大小,高13位是gdt的索引,第2位是ti位,指示索引是gdt的还是ldt的,0、1两位是特权级位。SELECTOR_CODE equ (0x0001<<3)+TI_GDT+RPL0	;0001就是下标1,左移3位相当于*8,因为一个表项是8字节SELECTOR_DATA equ (0x0002<<3)+TI_GDT+RPL0SELECTOR_VIDEO equ (0x0003<<3)+TI_GDT+RPL0
;-------------------- 这部分设置保存内存容量的标号--------------------------------
;关于这个标号的地址,loader.S的起始地址是0x900,这行前面有64个8字节的段描述符,所以这里是0x900+0x200=0xb00total_mem_bytes dd 0	;初始为0,最终变成总内存容量
;-------------------- 这部分完成定义GDT指针 --------------------------------
gdt_ptr:dw GDT_LIMIT	;前2字节是gdt的界限dd GDT_BASE		;后4字节是gdt的起始位置
;-------------------- 这部分实现三种获取内存容量的方法 --------------------------------
;注意我们这次删除了实模式下打印字符串的功能ards_buf times 244 db 0	;设置ards缓冲区,存放ardsards_nr dw 0		;用于记录ards结构体的数量;这两行开辟256字节的空间,人工对齐loader_start:
;-------------------- 方法1:利用0xe820获取内存 --------------------------------
;以下部分,通过0xe801获取所有的ardsxor ebx,ebx		;用异或置零,初始ebx设置为0,后续我们不需要再处理mov edx,0x534d4150	;固定值mov di,ards_buf		;es:di指向缓冲区,es在mbr设置,这里修改di即可
.e820_mem_get_loop:mov eax,0x0000e820	;因为执行完int 0x15后eax,ebx,ecx会变化,所以每次循环都要重新设置mov ecx,20		;返回的字节数,固定为20int 0x15jc .e820_failed_so_try_e801 ;如果e820失败,尝试e801add di,cx		;+20字节指向下一个ardsinc word [ards_nr]	;记录ards数量cmp ebx,0		;如果ebx=0且cf=0,所有ards全部返回jnz .e820_mem_get_loop 	;如果ebx!=0,继续循环
;以下部分,遍历ards,找到最大的32位基地址+内存长度,即为最大内存容量mov cx,[ards_nr]mov ebx,ards_bufxor edx,edx		;edx保存最大内存容量,初始置0
.find_max_mem_area:mov eax,[ebx]		;32位基地址add eax,[ebx+8]		;内存长度add ebx,20		;指向下一个ardscmp edx,eaxjge .next_ards		;如果edx>=eax,跳转到下一个ards,否则让edx=eax,最终效果是找到最大的ardsmov edx,eax
.next_ards:loop .find_max_mem_areajmp .mem_get_ok
;-------------------- 方法2:利用0xe801获取内存 --------------------------------
;返回后,ax=cx单位是1kb,里面是小于16mb的单位数,bx=dx单位是64kb,里面是大于16mb的单位数。最终需要转化为字节数。
.e820_failed_so_try_e801:mov ax,0x0000e801int 0x15jc .e801_failed_so_try88	;如果e801失败,尝试88方法
;以下计算出低于16mb的内存容量大小mov cx,0x400		;1024mul cx			;16位乘法,结果是32位,低16在ax,高16在dxshl edx,16		;左移16位and eax,0x0000ffff	;保留低16位or edx,eax		;拼接edx的高16位和eax低16位,放到edx中add edx,0x100000	;+1mb,原因是获取的内存比实际内存少1mbmov esi,edx		;备份edx
;以下计算16mb以上内存容量大小xor eax,eaxmov ax,bx		;大于16mb的单位数存在bx、dx里mov ecx,0x10000		;单位是64kbmul ecx			;32位乘法,结果是64位,低32位在eax,高32位在edxadd esi,eax		;这种方法的上限就是4gb,所以不必理会高32位,只需要把低32位加进结果即可mov edx,esijmp .mem_get_ok
;-------------------- 方法3:利用0x88获取内存 --------------------------------
;这部分是方法2的简化版,代码参考2,不再写注释
.e801_failed_so_try88:mov ah,0x88int 0x15jc .error_hltand eax,0x0000ffffmov cx,0x400mul cxshl edx,16or edx,eaxadd edx,0x100000
;-------------------- 这部分记录内存容量 --------------------------------
;如果三种方法都失败,跳转到这里,进行一个死循环
.error_hlt:jmp $
;不管使用了哪种子命令,只要成功,都要跳转到这里记录,单位是1字节
.mem_get_ok:mov [total_mem_bytes],edx	;在total_mem_bytes地址记录总内存容量
;-------------------- 这部分完成进入保护模式的三个步骤 --------------------------------in al,0x92 or al,0000_0010B out 0x92,al 		;打开 A20lgdt [gdt_ptr] 		;加载 GDTmov eax, cr0 or eax, 0x00000001 mov cr0, eax		;cr0 第 0 位置 1
;-------------------- 验证是否进入保护模式 --------------------------------jmp dword SELECTOR_CODE:p_mode_start ; 刷新流水线
[bits 32] 
p_mode_start: mov ax,SELECTOR_DATA mov ds,ax mov es,ax mov ss,ax mov esp,LOADER_STACK_TOP mov ax,SELECTOR_VIDEOmov gs,ax mov byte [gs:160], 'P' ;通过显卡打印一个字符,验证是否进入保护模式jmp $

编译运行

这里我顺手调整了一下mbr,所以先编译写入mbr

nasm -I include/ -o mbr.bin mbr.S
dd if=/home/hongbai/bochs/mbr.bin of=/home/hongbai/bochs/bin/c.img bs=512 count=1 conv=notrunc

编译写入loader

nasm -I include/ -o loader.bin loader.S
dd if=/home/hongbai/bochs/loader.bin of=/home/hongbai/bochs/bin/c.img bs=512 count=4 seek=2 conv=notrunc

运行bochs

cd bin
./bochs -f bochsrc.disk

结果截图:

我们先打开bochsrc.disk配置文件,看一下我们给bochs配置了多少内存。内存大小是megs行,我设置的是512mb大小。

在控制台输入ctrl+c,中断bochs运行,再输入xp 0xb00,查看内存容量是否探测成功。结果如下:

0x20000000正是我设置的512MB内存大小,说明程序运行正常。


结语

这一部分没什么好说的,主要就是完成获取内存容量的功能,新增了一些代码。后续还有内存分页,加载内核,特权级几部分内容,我计划在清明假期把它们全部完成,最后写一个大总结。

http://www.dtcms.com/wzjs/14952.html

相关文章:

  • dream chaser wordpress青岛谷歌优化
  • 有经验的合肥网站建设百度人气榜排名
  • 驻马店网站优化合理使用说明
  • 做外链一般都用网站首页吗网站访问量
  • 做网站安全维护是什么东东百度关键词优化软件网站
  • 织梦如何做中英文网站竞价 推广
  • 湘潭网站seo北京最新疫情最新消息
  • 单招网站开发百度知道推广软件
  • 微商城分销系统多少钱济南seo培训
  • 做网站怎么别人搜不出来怎么推广产品
  • 秦皇岛网站制作哪个好重庆今天刚刚发生的重大新闻
  • c web网站开发框架自己开发网站
  • 贵州网站制作公司电话百度一下网页打开
  • 做电影网站怎样赚钱吗只要做好关键词优化
  • web站点优化广州seo网站推广
  • 嘉兴网页设计seo网站设计
  • 中国建筑装饰设计网系统优化软件哪个最好的
  • 青岛美容化妆品外贸网站建设重庆seo网络优化师
  • 网站后台怎么添加代码千度搜索引擎
  • 如何做一家专门卖零食的网站潍坊做网站公司
  • 丽水微信网站建设价格怎么做蛋糕
  • wordpress discuz 统一账号自己搜20条优化措施
  • 哪个网站建设公司靠谱线在成都网站推广公司
  • wordpress 带宽购物郑州seo排名第一
  • 建设厅网站上传身份证今天的最新消息新闻
  • 免费tickle网站网站百度关键词优化
  • wordpress加载模板文件路径seo学校培训课程
  • wordpress有收益嘛网站建设优化推广系统
  • 网站开发 报价广告推广赚钱在哪接
  • 做cpa用什么类型的网站好北京seo网络优化师