搜索
查看
编辑修改
首页
UNITY
NODEJS
PYTHON
AI
GIT
PHP
GO
CEF3
JAVA
HTML
CSS
搜索
IT小白
这个屌丝很懒,什么也没留下!
关注作者
热门标签
jquery
HTML
CSS
PHP
ASP
PYTHON
GO
AI
C
C++
C#
PHOTOSHOP
UNITY
iOS
android
vue
xml
爬虫
SEO
LINUX
WINDOWS
JAVA
MFC
CEF3
CAD
NODEJS
GIT
Pyppeteer
article
热门文章
1
【程序人生】探索2024年AI辅助研发趋势_2024年程序员用ai
2
python机器人开发教程:学习如何使用Python编程创建机器人_python训练机器人功能的函数trian()跟机器人对话功能的函数exchange()
3
【Spark】Spark 高频面试题英语版(1)_interactive shell is not supported.
4
大学英语四新视野 课后习题+答案翻译 Unit1~Unit8_have you ever heard people say that
5
100个网络运维工作者必须知道的小知识!(上)_网络维护员怎么了解安全拓扑
6
鸿蒙2.0手机更新名单,鸿蒙2.0支持哪些手机-鸿蒙2.0首批升级名单
7
Ubuntu没有声音(听不到声音)的解决方法
8
source build/envsetup.sh 之后_source build/envsetup.sh执行无响应
9
机器学习(零) -- 系列文章目录及链接
10
解决使用pip无法安装rasa与无限依赖告警:INFO: This is taking longer than usual. You might need to provide the....
当前位置:
article
> 正文
boot/loader.asm_asm booloader
作者:IT小白 | 2024-04-01 00:46:24
赞
踩
asm booloader
Code:
;By Marcus Xing
;boot/loader.asm
;加载原始KERNEL.BIN,在保护模式下分析ELF把各
;段转移到对应的虚拟地址上,并把控制权交给KERNEL
org 0100h
%include "pm.inc"
;-------------------------------------------------------------------------宏信息
Base_Of_Loader equ 9000h ;加载LOADER的段地址
Offset_Of_Loader equ 0100h ;加载LOADER的偏移地址
Base_Of_Kernel equ 8000h ;加载KERNEL的段地址
Offset_Of_Kernel equ 0h ;加载KERNEL的偏移地址
Base_Of_Page_Dir equ 200000h ;页目录表的首址
Base_Of_Page_Tbl equ 201000h ;页表的首址
Base_Of_Loader_Phy_Addr equ Base_Of_Loader * 10h ;加载LOADER的物理基地址
Base_Of_Kernel_Phy_Addr equ Base_Of_Kernel * 10h ;加载原始KERNEL的物理基地址
Root_Dir_Begin_Sector equ 19 ;根目录区的逻辑起始逻辑扇区
Kernel_Entry_Point_Phy_Addr equ 30400h ;内核的入口地址
;-------------------------------------------------------------------CODE_SEGMENT
[section .code16]
[bits 16]
LABEL_START:
mov ax,cs
mov ds,ax
mov ax,3000h
mov ss,ax
mov sp,0100h
;取得内存信息存入缓冲区
;进入保护模式后显示出来
;BIOS int 15h
xor ebx,ebx ;后续值,不用程序员关注,初始为0
mov di,_Memory_Info_Buffer ;es:di指向缓冲区
.l:
mov ecx,20 ;每个ARDStruct为20字节
mov edx,0534d4150h ;
edx
=
'SMAP'
mov eax,0e820h ;功能号
int 15h
jc .fail ;如果CF为1,则出错,置ARDStruct变量为0
add di,20 ;es:di指向下一段缓冲区
inc dword [_d_ARDStruct_Num] ;ARDStruct变量自增1
cmp ebx,0 ;判断ebx是否为0,为0则读取结束,否则继续读取
jne .l
jmp .done
.fail:
mov dword [_d_ARDStruct_Num],0
.done:
;回车
push _sz_Return
call Disp_Str_In_Real_Mode
add sp,2
;显示字符串Loading
push _sz_Loading_Message
call Disp_Str_In_Real_Mode
add sp,2
;es指向缓冲区的段地址
mov ax,Base_Of_Kernel
mov es,ax
LABEL_READ_NEXT_SECTOR:
mov bx,Offset_Of_Kernel ;bx指向缓冲区的偏移地址
cmp word [_w_Root_Dir_Search_For_Loop],0 ;比较循环变量是否为0
je LABEL_NO_FOUND ;为0代表没找到,跳转到相应的标号处理
dec word [_w_Root_Dir_Search_For_Loop] ;尚未为0,循环变量自减1
;读取当前根目录区扇区至缓冲区
push 1
push word [_w_Root_Dir_Sector_No]
call Read_Sector
add sp,4
inc word [_w_Root_Dir_Sector_No] ;定位到下一个根目录扇区,为下一次读做准备
mov dx,16 ;一个扇区有16个FCB,要循环16次
LABEL_GO_ON_NEXT_DIR_ITEM:
cmp dx,0 ;判断是否为0
je LABEL_READ_NEXT_SECTOR ;为0就读下一个根目录扇区
dec dx ;dx自减1
mov cx,11 ;FCB中的文件名字段有11位,故循环变量为11
mov si,_s_Name_Of_Kernel ;si定位到要比较的字符串偏移处
LABEL_GO_ON_CMP:
cmp cx,0 ;判断比较计数器是否为0,为0表示比较成功
je LABEL_FOUNDED ;即找到KERNEL.BIN,跳转到相应标号处理
dec cx ;cx自减1
mov al,[si] ;ds:si指向比较字符串,赋给al
cmp al,[es:bx] ;es:bx指向当前FCB的文件名字段,比较两者
je LABEL_CMP_OK ;比较成功则进行下一次比较
and bx,0ffe0h ;不成功则把bx的低5位清零,因为一个FCB为32
add bx,32 ;字节,再加32则定位到下一个FCB的文件名处
jmp LABEL_GO_ON_NEXT_DIR_ITEM ;跳转,比较下一个FCB
LABEL_CMP_OK:
;两个串的定位器都自增1
inc si
inc bx
jmp LABEL_GO_ON_CMP ;跳转下一次比较
;没找到KERNEL,跳转到这儿,显示完相应信息后死循环
LABEL_NO_FOUND:
push _sz_No_Kernel_Message
call Disp_Str_In_Real_Mode
add sp,2
jmp $
;找到了KERNEL,跳转到这儿
LABEL_FOUNDED:
and bx,0ffe0h ;使es:bx指向找到的KERNEL的FCB的起始处
mov cx,[es:bx + 1ah] ;取得KERNEL的相对于数据区的偏移扇区号
;注意:2为数据区的第一个扇区
mov ax,cx
mov bx,Offset_Of_Kernel ;
es:bx
=
8000h
:0000h,准备读入一个数据扇区
LABEL_GO_ON_LOADING:
;每从数据区读一个扇区则显示一个点
push _sz_Dot
call Disp_Str_In_Real_Mode
add sp,2
add ax,31 ;得到要读取的数据扇区的逻辑地址
;读一个数据扇区
push 1
push ax
call Read_Sector
add sp,4
;得到当前数据扇区在FAT中的值
push cx
call Get_FAT_Entry
add sp,2
;判断有没有下一个扇区,有则根据得到的下一个数据相对扇区号继续读
;没有则可以分析KERNEL.BIN的ELF格式了
cmp ax,0fffh
je LABEL_START_LOADING
add bx,512 ;定位KERNEL的加载偏移地址
mov cx,ax
jmp LABEL_GO_ON_LOADING ;跳转回去进行相应处理
;KERNEL数据全部加载完毕后跳转到此
LABEL_START_LOADING:
;打印准备信息
push _sz_Ready_Message
call Disp_Str_In_Real_Mode
add sp,2
;回车
push _sz_Return
call Disp_Str_In_Real_Mode
add sp,2
;下一步准备跳入保护模式
call Kill_Motor ;关闭软驱马达
lgdt [GDT_Ptr] ;加载GDT信息到GDTR
cli ;关中断
;打开A20,可以寻址到1M开外
in al,92h
or al,00000010b
out 92h,al
;CR0最低位置1,使CPU处于保护模式
mov eax,cr0
or al,1
mov cr0,eax
;跳转到32位代码段中
jmp dword Selector_Flat_C:(Base_Of_Loader_Phy_Addr + LABEL_SEG_CODE32)
;--------------------------------------------------------------PM_CODE32_SECTION
[section .code32]
[bits 32]
LABEL_SEG_CODE32:
;ds,es,ss,fs都指向4G读写平坦段
mov ax,Selector_Flat_RW
mov ds,ax
mov es,ax
mov fs,ax
;设置好堆栈,1K空间
mov ss,ax
mov esp,Stack32_Len
;gs指向显存段
mov ax,Selector_Video
mov gs,ax
;-------------------------------------------------------------------显示内存信息
;显示内存头信息
push sz_Memory_Info_Title
call Disp_Str
add esp,4
;回车
push sz_Return
call Disp_Str
add esp,4
mov ecx,[d_ARDStruct_Num] ;ecx
<
-ADRStruct
个数,控制外层循环
mov esi,Memory_Info_Buffer ;ds:esi指向内存信息缓冲区
.1:
mov edx,5 ;控制内层循环,因为1个ARDStruct有5个字段
mov edi,d_Base_Addr_Low ;es:edi指向ARDStruct缓冲区
.2:
cmp edx,0 ;判断edx是否为0
je .3 ;是的话跳转到.3
dec edx
lodsd ;eax
<
-ds:esi
,add esi,4
;显示出来
push eax
call Disp_Int
pop eax
stosd ;es:edi
<
-eax
,add edi,4
;打印2个空格
call Disp_Space
call Disp_Space
jmp .2 ;继续内层循环
.3:
cmp dword [d_Type],1 ;判断类型字段是否为1,即是否可被我们的OS使用
jne .4 ;不是就跳转到4,显示下一个ARDStruct
;判断当前ARDStruct地址范围
;跟当前内存范围大小,当前内存
;范围小则更新之
mov eax,[d_Base_Addr_Low]
add eax,[d_Length_Low]
cmp [d_Memory_Size],eax
ja .3
mov [d_Memory_Size],eax
.4:
;回车
push sz_Return
call Disp_Str
add esp,4
loop .1 ;执行外层循环
;显示内存范围字符串
push sz_Memory_Size
call Disp_Str
add esp,4
;显示内存范围数值
push dword [d_Memory_Size]
call Disp_Int
add esp,4
;回车
push sz_Return
call Disp_Str
add esp,4
;--------------------------------------------------------------分页设置(一一对应)
mov eax,[d_Memory_Size]
mov ebx,1024 * 1024 * 4 ;一个页目录项对应4M物理内存
div ebx ;eax
<
-
页目录表个数
cmp edx,0
je .11
inc eax ;余数不为0页目录加1
.11:
push eax ;暂存页目录个数
mov ecx,eax ;循环次数
mov eax,Base_Of_Page_Tbl | 1b | 10b | 100b ;指向页表,每个页目录可读可写,用户级,存在
mov edi,Base_Of_Page_Dir ;es:edi指向页目录表地址
.22:
stosd
add eax,4096
loop .22
pop eax ;恢复页目录个数
mov ebx,1024 ;每个页目录项对应1024个页表项
mul ebx
mov ecx,eax ;ecx
<
-
页目录项个数
mov eax,0 | 1b | 10b | 100b ;一一映射,每个页表项可读可写,用户级,存在
mov edi,Base_Of_Page_Tbl ;es:edi指向页表地址
.33:
stosd
add eax,4096
loop .33
;cr3
<
-
页目录地址
mov eax,Base_Of_Page_Dir
mov cr3,eax
;置cr0最高位为1,打开分页
mov eax,cr0
or eax,80000000h
mov cr0,eax
;------------------------------------------------------把ELF格式的KERNEL读入内存
;KERNEL.BIN原始文件位于8000h:0h处
mov cx,[Base_Of_Kernel_Phy_Addr + 44] ;取得PROGRAM HEADER的个数
and ecx,0ffffh ;ecx高16位清零
mov esi,[Base_Of_Kernel_Phy_Addr + 28] ;取得PROGRAM HEADER TABLE相对文件偏移
add esi,Base_Of_Kernel_Phy_Addr ;ds:esi指向PROGRAM HEADER TABLE的第一项
.s:
cmp dword [esi + 0],0 ;判断当前PROGRAM HEADER的TYPE是否为0
je .next ;为0直接跳过处理下一项
push dword [esi + 16] ;当前PROGRAM HEADER的长度入栈
push dword [esi + 8] ;当前PROGRAM HEADER的虚拟地址入栈
mov eax,[esi + 4]
add eax,Base_Of_Kernel_Phy_Addr ;eax
<
-
当前PROGRAM HEADER的内容地址
push eax
call Memory_Copy ;复制之
add esp,12
.next:
add esi,32 ;ds:esi指向下一个项,一个项32字节
loop .s
push dword [d_Disp_Pos_In_PM] ;进入内核前把显示位置入栈供内核使用
;********************************************************************
jmp Selector_Flat_C:Kernel_Entry_Point_Phy_Addr ;****正式进入内核****
;********************************************************************
;-------------------------------------------------------------PM_STACK32_SECTION
[section .stack32]
[bits 32]
times 1024 db 0
Stack32_Len equ Base_Of_Loader_Phy_Addr + $
;-------------------------------------------------------------------DATA_SECTION
LABEL_DATA:
_w_Root_Dir_Sector_No dw Root_Dir_Begin_Sector ;根目录区起始逻辑扇区
_w_Root_Dir_Search_For_Loop dw 14 ;找LOADER循环次数,就
;是根目录区扇区个数
_b_Is_Odd db 0 ;FAT ENTRY逻辑地址的奇或偶
_w_Disp_Pos_In_RM dw 0 ;实模式显示地址
_d_Disp_Pos_In_PM dd 320 ;保护模式显示地址,从第3行开始
;一些用到的串
_sz_Loading_Message db 'Loading',0
_sz_Ready_Message db 'Ready',0
_sz_No_Kernel_Message db 'No Kernel',0
_sz_Dot db '.',0
_sz_Return db 0ah,0
_sz_Space db 20h,0
_sz_PM_Message db 'HELLO!',0
_s_Name_Of_Kernel db 'KERNEL BIN'
_sz_Memory_Info_Title db 'BaseAddrL BaseAddrH LengthLow LengthHigh Type',0
_sz_Memory_Size db 'Memory Size:',0
_Memory_Info_Buffer: ;内存信息缓冲区,能存放12个ARDStruct,
times 256 db 0 ;如果内存太大可能不够用
_d_ARDStruct_Num dd 0 ;ARDStruct的个数
;一个ARDStructd的缓冲区
_d_Base_Addr_Low dd 0 ;基址低32位
_d_Base_Addr_High dd 0 ;基址高32位
_d_Length_Low dd 0 ;长度低32位
_d_Length_High dd 0 ;长度高32位
_d_Type dd 0 ;类型
_d_Memory_Size dd 0 ;可用内存长度
;保护模式下用到得标号(偏移)
d_Disp_Pos_In_PM equ Base_Of_Loader_Phy_Addr + _d_Disp_Pos_In_PM
sz_PM_Message equ Base_Of_Loader_Phy_Addr + _sz_PM_Message
sz_Return equ Base_Of_Loader_Phy_Addr + _sz_Return
sz_Space equ Base_Of_Loader_Phy_Addr + _sz_Space
sz_Memory_Info_Title equ Base_Of_Loader_Phy_Addr + _sz_Memory_Info_Title
sz_Memory_Size equ Base_Of_Loader_Phy_Addr + _sz_Memory_Size
Memory_Info_Buffer equ Base_Of_Loader_Phy_Addr + _Memory_Info_Buffer
d_ARDStruct_Num equ Base_Of_Loader_Phy_Addr + _d_ARDStruct_Num
d_Base_Addr_Low equ Base_Of_Loader_Phy_Addr + _d_Base_Addr_Low
d_Base_Addr_High equ Base_Of_Loader_Phy_Addr + _d_Base_Addr_High
d_Length_Low equ Base_Of_Loader_Phy_Addr + _d_Length_Low
d_Length_High equ Base_Of_Loader_Phy_Addr + _d_Length_High
d_Type equ Base_Of_Loader_Phy_Addr + _d_Type
d_Memory_Size equ Base_Of_Loader_Phy_Addr + _d_Memory_Size
;----------------------------------------------------------------------------GDT
[section .gdt]
;GDT开始
LABEL_GDT:
LABEL_DESC_DUMMY:
Descriptor 0,0,0
LABEL_DESC_FLAT_RW:
Descriptor 0,0fffffh,DA_DRW + DA_32 + DA_LIMIT_4K ;读写4G平坦段
LABEL_DESC_FLAT_C:
Descriptor 0,0fffffh,DA_CR + DA_32 + DA_LIMIT_4K ;4G可执行段
LABEL_DESC_VIDEO:
Descriptor 0b8000h,0ffffh,DA_DRW + DA_DPL3 ;指向显存首址段,DPL为3
;为之后的进程准备
;选择子
Selector_Flat_RW equ LABEL_DESC_FLAT_RW - LABEL_GDT
Selector_Flat_C equ LABEL_DESC_FLAT_C - LABEL_GDT
Selector_Video equ LABEL_DESC_VIDEO - LABEL_GDT + SA_RPL3
;RPL为3,为之后的进程准备
GDT_Len equ $ - LABEL_GDT ;GDT长度宏
GDT_Ptr: ;准备加载进GDTR的6字节数据结构
dw GDT_Len - 1
dd Base_Of_Loader_Phy_Addr + LABEL_GDT
;------------------------------------------------------------lib_in_protect_mode
[section .lib_in_protect_mode]
[bits 32]
%include "lib_in_protect_mode.inc"
;---------------------------------------------------------------lib_in_real_mode
[section .lib_in_real_mode]
[bits 16]
%include "lib_in_real_mode.inc"
声明:
本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:
https://www.wpsshop.cn/w/IT小白/article/detail/346632
推荐阅读
article
FastBoot
刷机
方法_fast
boot
flash
boot
...
极力推荐Android 开发大总结文章:欢迎收藏程序员Android 力荐 ,Android 开发者需要的必备技能 本篇...
赞
踩
article
fast
boot
刷
boot
命令_fast
boot
flash
boot
...
fast
boot
flash
boot
_b //rooted
boot
路径fast
boot
flash
boot
_a /...
赞
踩
article
玩机搞机
-----
安卓全机型
刷
机卡
fast
boot
模式
解决方法与故障解析_
刷
twrp
时卡在
fast
...
3
-----
刷
机中途电脑问题或者其他原因没有写入完固件重启卡
fast
boot
模式
。4
-----
格机或者误檫除手机全部分区...
赞
踩
article
全志A64开发环境的搭建和遇到的问题_
u
-
boot
.
fex
will
merge
s
u
ni
.
fex
...
二、编译全志A64的内核1.查看帮助$cd lichee $ ./b
u
ild.sh -hTop level b
u
ild ...
赞
踩
article
深入浅出 -
Android
系统移植与平台开发(二) - 准备
Android
开发环境_emulat...
编译
Android
源码关于android系统的编译,
Android
的官方网站上也给出了详细的说明。http://sour...
赞
踩
article
【
SpringBoot
】核心依赖和自动配置_<
parent
> <
groupi
d>
org
.spring...
之前介绍了spring
boot
是有多么的好,那么,我们现在通过一个小demo来看他是有多么的强大!一、核心pom引入我们...
赞
踩
article
Spring
Boot + Vue +
Electron
跨平台
应用
介绍_
spingboot
vue
...
虽然B/S是目前开发的主流,但是C/S仍然有很大的市场需求。受限于浏览器的沙盒限制,网页
应用
无法满足某些场景下的使用需求...
赞
踩
article
spring
boot
+ vue +
element
-ui全栈
开发
入门——基于
Electron
桌面...
前言
Electron
是由Github
开发
,用HTML,CSS和JavaScript来构建跨平台桌面应用程序的一个...
赞
踩
article
使用
electron
打包
spring
-
boot
+
vue
项目
开发桌面
exe
端
项目
一站式全部解决!专栏有...
js 14以下(直接安装 node.js 即可)后端:jre 1.8(必须1.8)我以及给大家汇总完毕直接点击进去下载即...
赞
踩
article
spring
boot
+ vue +
element
-ui全栈
开发
入门——基于
Electron
桌面...
前言
Electron
是由Github
开发
,用HTML,CSS和JavaScript来构建跨平台桌面应用程序的一个开...
赞
踩
article
S
pring
Boot
+ Vue 如此强大?竟然可以
开发
基于 C/
S
架构
的应用...
作者 |xiangzhihongsegmentfault.com/a/1190000021376934前言虽然 B/
S
...
赞
踩
article
撸了个
Spring
Boot
+
Vue
可视化
拖拽
编辑的
大屏
系统,爽!_
vue
大屏
设计器...
大屏
设计是一个
可视化
拖拽
编辑的,直观,酷炫,具有科技感的图表工具全开源项目。
vue
-router:
Vue
提供的前端路由工...
赞
踩
article
基于
Spring
Boot
+
Vue
的博客系统 03——设计主界面_
b
-
col
b
-
row
...
0. 图标问题图标使用阿里巴巴矢量图标,官方网站:https://www.iconfont.cn/home/index使...
赞
踩
article
Spring
Boot
+ Vue 也
可以
开发
C/S 架构的
应用
,快来试试!...
点击上方“阿拉奇学Java”,选择“置顶或者星标”每天早晨07点28分, 与你相约!链接:segmentfault.co...
赞
踩
article
spring
boot
+
vue
+
element
-ui全栈开发入门——基于
Electron
桌面...
一、node.js开发环境windows系统,去网站https://nodejs.org/en/download/,下载...
赞
踩
article
集成
Spring
Boot
Actuator
来监控和
管理应用程序
的
健康状况
、
性能指标
等...
通过以上步骤,您就可以轻松地集成
Spring
Boot
Actuator
来监控和管理您的
Spring
Boot
应用程序。...
赞
踩
article
【
Spring
Boot
源码
学习】共享
MetadataReaderFactory
上下文
初始化
器...
本篇 Huazie 带大家详细分析一下 共享
MetadataReaderFactory
上下文
初始化
器【
Spring
...
赞
踩
article
java
企业
工程
管理
系统软件
源码+
Spring
Cloud
+
Spring
Boot
+二次开发...
该系统涵盖了项目
管理
、合同
管理
、预警
管理
、竣工
管理
、质量
管理
等多个方面,通过数据字典、编码
管理
、用户
管理
、菜单
管理
等功能...
赞
踩
article
spring
boot
生成
PDF
模板文件...
spring
boot
生成
PDF
模板文件
spring
boot
生成
PDF
模板文件 ...
赞
踩
article
SpringBoot
+Vue
在线教育
系统
(源码+论文)_培训管理
系统
vue
spring
boot
...
本站是一个B/S模式
系统
,采用
SpringBoot
框架,MySQL数据库设计开发,充分保证
系统
的稳定性。本
系统
的使用使管...
赞
踩
相关标签
lg
boot
卡fastboot模式
刷机卡fast
卡fast解决
fastboot刷机
全志
A64
lichee
android
function
ubuntu
平台
gcc
编译器
java
后端
spring boot
vue.js
electron
ui
前端
ViewUI
javascript