前言
这个题目比较抽象,我一时想不出更好的了。
老师留了一个作业,让计算机开机启动自己写的汇编程序,打印一个hello world。
推荐看这些视频:
Coding Master
第6,7,8三个视频+6视频的番外文章
计算机开机过程
操作系统本身就是软件,那启动操作系统也是需要其他程序拉起的,也就是指令,那些指令放在哪里?
答案就是bios程序。
问题又来了,执行程序是需要从内存中读取指令的,而内存一开始是空的,而从磁盘拉取指令到内存又需要指令(程序),这不就套娃了吗?从磁盘往内存拉程序需要内存中本身有程序,乐。
所以就需要一个永久固化在内存中的一端程序指令,这就是bios,实现bios程序的基础是ROM(Read Only Memory)。
ROM和内存逻辑上是拼接的,程序每次启动都会先执行ROM上的bios。
bios会先检查一下计算机各个组件有没有坏的,缺的,确认能跑就会默认到磁盘中的某个地址开始拉取操作系统执行指令。
知道了这些以后,就可以修改电脑的开机程序了。有两种方法:
- 一种是直接把开机程序第一个拉起的启动程序区域替换成我们自己的程序,但是这种就相当于以后开机就不会启动操作系统了,除非你能改回去,不然就废了。所以一般这种都是在虚拟机里玩。
- 另一种是切换拉起的启动程序区域,以前是磁盘,现在换用u盘里我们自己写的启动程序(或者启动盘里的微操作系统),这也就是启动盘的执行原理,你原来是从磁盘调操作系统,现在是从u盘调操作系统,本质上没啥区别,只是读取的地方换了罢了。
直接修改磁盘
创建一个很小的Virtual Box虚拟机,然后用fixvhdw直接把汇编出来的二进制指令写进0地址处。
一般来说,操作系统也是0地址处开始的。
mov ax, 0b800h
mov ds,ax
mov byte [0x00],'1'
mov byte [0x02],'1'
mov byte [0x04],'2'
mov byte [0x06],'0'
mov byte [0x08],'2'
mov byte [0x0a],'0'
mov byte [0x0c],'0'
mov byte [0x0e],'9'
mov byte [0x10],'4'
mov byte [0x12],'4'
mov byte [0x14],','
mov byte [0x16],'c'
mov byte [0x18],'y'
mov byte [0x1a],'y'
mov byte [0x1c],','
mov byte [0x1e],'H'
mov byte [0x20],'a'
mov byte [0x22],'p'
mov byte [0x24],'p'
mov byte [0x26],'y'
mov byte [0x28],' '
mov byte [0x2a],'A'
mov byte [0x2c],'u'
mov byte [0x2e],'t'
mov byte [0x30],'u'
mov byte [0x32],'m'
mov byte [0x34],'n'
mov byte [0x36],' '
mov byte [0x38],'T'
mov byte [0x3a],'e'
mov byte [0x3c],'r'
mov byte [0x3e],'m'
mov byte [0x40],'!'
jmp $
times 510-($-$$) db 0
db 0x55,0xaa
更换启动源
这个一般是在自己电脑上试,你肯定不能把你电脑上磁盘的0地址抹掉,不然基本就废了,拉不起操作系统了。
所以都是换源,即U盘。
实际上,抹掉u盘的0地址,也是把u盘在软件层面搞废了(还能格式化),原来的资源大概率没了,但是你重新覆盖了你的程序以后,还是能继续存资源的。
所以在格式化U盘之前,先把资源挪到其他地方。
U盘的0地址开始的512Byte(一个扇区)空间,这个叫MBR(Master Boot Record)。
如果没有MBR区,U盘就只是一块储存器,没有任何的分区信息,MBR就是记录了U盘分区之类信息的区域。如果把分区相关数据写坏了,那U盘就不会被电脑读取,或者读取了以后不显示空间有多大,很多人碰到过这种问题。
坑
但是呢,现在的电脑保护的越来越好了,开机狂按F12进入启动引导洁面后,很多时候都检测不到U盘,即使是检测到U盘,也不能执行U盘引导。
这是因为有启动保护,是Security Boot,这个要是关了,会触发BitLocker,你需要到官网查找自己机器对应的密码,才能彻底掌控电脑,流程比较麻烦,赶时间的同学基本可以放弃了。
一种折中方法是把自己的操作系统做成镜像,然后弄个虚拟机凑合用。
否则就只能硬刚了。