1.创建启动软盘
开头写一段二进制代码,这代码就是os的内核。
把这代码写到一个文件里,这个文件我们把他当成虚拟软盘,也是我们的启动软盘。
2.使用汇编语言实现内核
https://blog.csdn.net/tyler_download/article/details/51761750
主要就是解释汇编语言的内容。
寄存器是在cpu里的各种硬件。可以把他看成是内存。但是比内存快。
寄存器在汇编里作用就相当于java里定义的变量
第512个字节是55aa(规定好的)
中断就是一个函数。是bios提供给汇编语言的库函数。
hal相当于halt,让系统自己休眠。当使用鼠标或者键盘的时候会恢复。
汇编可以规定颜色。可以调用硬件打印。
3.模拟软盘
https://blog.csdn.net/tyler_download/article/details/51815483
软盘有三个概念:
扇面,
柱面=磁道
扇区。
软盘有两个盘面,一个盘面有80个磁道,每个磁道有18个扇区。
每个扇区的大小是512个字节
这节主要是实现软盘。后面用汇编语言的代码解释一下:
java代码负责模拟软盘。这个软盘有5121880*2个字节的大小。最后生成一个.img文件
前512个字节的内容是从boot.bat里读的。后面的内容随便。
4.让内核突破512字节的限制
https://blog.csdn.net/tyler_download/article/details/51970921
写一个内核加载器,这个内核加载器要很小,能够在512字节中放下。而且功能很单一,负责把操作系统内核加载到系统内存里。加载完之后就把cpu执行权再交给内核。
要素:内核加载器、内核、内存。
举个例子:去游乐园,游乐园的门很小(512字节),本来所有的项目都是放在门这里。后来增加设施,门口这地方不够用了,就安排一些大力神仙(内存加载器)在游乐园门口负责把各种设施放到他们应该放的地方。放完之后,在把门口的路变成通往第一个设备的路。
设备是内核。门口的地方是最开始的扇区,512字节。0面0柱面0扇区。
说一下整体代码逻辑:
kernerl.bat里面是内核代码。这个内核功能就负责打印一句话
用java读取出来这个文件的内容,并放到软盘0x8000地址所在柱面处。
然后把内存加载器的文件里的内容也读取出来放到0盘面0柱面0扇区处。
然后把这个软盘弄成img,用vm运行即可。
5.由实模式进入保护模式之32位寻址
有个数据结构
从实模式到保护模式,没讲清楚保护的意思
6.超强寻址
把内容写到5M处,然后从5M处再把代码读到内存。
7.c语言和汇编语言互相调用
package os;
import java.io.DataOutputStream;
import java.io.FileOutputStream;
import java.util.ArrayList;
import java.util.HashMap;
/**
* @Auther: zhayin:zhayin.lz@alibaba-inc.com
* @Date: 2021/8/16 6:04 下午
* @Description:
*/
public class Floppy {
enum MAGNETIC_HEAD {
MAGNETIC_HEAD_0,
MAGETIC_HEAD_1
};
public int SECTOR_SIZE = 512;
private int CYLINDER_COUNT = 80; //80个柱面
private int SECTORS_COUNT = 18;
private MAGNETIC_HEAD magneticHead = MAGNETIC_HEAD.MAGNETIC_HEAD_0;
private int current_cylinder = 0;
private int current_sector = 0;
private HashMap<Integer,ArrayList<ArrayList<byte[]>> > floppy = new HashMap<Integer,ArrayList<ArrayList<byte[]>> >(); //一个磁盘两个面
public Floppy() {
initFloppy();
}
private void initFloppy() {
//一个磁盘有两个盘面
floppy.put(MAGNETIC_HEAD.MAGNETIC_HEAD_0.ordinal(), initFloppyDisk());
floppy.put(MAGNETIC_HEAD.MAGETIC_HEAD_1.ordinal(), initFloppyDisk());
}
private ArrayList<ArrayList<byte[]>> initFloppyDisk() {
ArrayList<ArrayList<byte[]>> floppyDisk = new ArrayList<ArrayList<byte[]>>(); //磁盘的一个面
//一个磁盘面有80个柱面
for(int i = 0; i < CYLINDER_COUNT; i++) {
floppyDisk.add(initCylinder());
}
return floppyDisk;
}
private ArrayList<byte[]> initCylinder() {
//构造一个柱面,一个柱面有18个扇区
ArrayList<byte[]> cylinder = new ArrayList<byte[]> ();
for (int i = 0; i < SECTORS_COUNT; i++) {
byte[] sector = new byte[SECTOR_SIZE];
cylinder.add(sector);
}
return cylinder;
}
public void setMagneticHead(MAGNETIC_HEAD head) {
magneticHead = head;
}
public void setCylinder(int cylinder) {
// 柱面/磁道 编号1-80
if (cylinder < 0) {
this.current_cylinder = 0;
}
else if (cylinder >= 80) {
this.current_cylinder = 79;
}
else {
this.current_cylinder = cylinder;
}
}
public void setSector(int sector) {
//sector 编号从1到18
if (sector < 0) {
this.current_sector = 0;
}
else if (sector > 18) {
this.current_sector = 18 - 1;
}
else {
this.current_sector = sector - 1;
}
}
public byte[] readFloppy(MAGNETIC_HEAD head, int cylinder_num, int sector_num) {
setMagneticHead(head);
setCylinder(cylinder_num);
setSector(sector_num);
ArrayList<ArrayList<byte[]>> disk = floppy.get(this.magneticHead.ordinal());
ArrayList<byte[]> cylinder = disk.get(this.current_cylinder);
byte[] sector = cylinder.get(this.current_sector);
return sector;
}
public void writeFloppy(MAGNETIC_HEAD head, int cylinder_num, int sector_num, byte[] buf) {
setMagneticHead(head);
setCylinder(cylinder_num);
setSector(sector_num);
ArrayList<ArrayList<byte[]>> disk = floppy.get(this.magneticHead.ordinal());
ArrayList<byte[]> cylinder = disk.get(this.current_cylinder);
cylinder.set(this.current_sector, buf);
}
public void makeFloppy(String fileName) {
try {
/**
* 虚拟软盘是纯粹的二进制文件,逻辑结构如下:
* 前512*18个字节是对应盘面0,柱面0的所有扇区内容
* 后512*18个字节对应盘面1,柱面0的所有扇区内容
* 然后512*18字节对应盘面0,柱面1的所有扇区内容
*/
DataOutputStream out = new DataOutputStream(new FileOutputStream(fileName));
for (int head = 0; head <= MAGNETIC_HEAD.MAGETIC_HEAD_1.ordinal(); head++) {
for (int cylinder = 0; cylinder < CYLINDER_COUNT; cylinder++) {
for (int sector = 1; sector <= SECTORS_COUNT; sector++) {
byte[] buf = readFloppy(MAGNETIC_HEAD.values()[head], cylinder, sector);
out.write(buf);
}
}
}
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}