1.创建启动软盘

image.pngimage.png
开头写一段二进制代码,这代码就是os的内核。
把这代码写到一个文件里,这个文件我们把他当成虚拟软盘,也是我们的启动软盘。
image.png

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语言和汇编语言互相调用

  1. package os;
  2. import java.io.DataOutputStream;
  3. import java.io.FileOutputStream;
  4. import java.util.ArrayList;
  5. import java.util.HashMap;
  6. /**
  7. * @Auther: zhayin:zhayin.lz@alibaba-inc.com
  8. * @Date: 2021/8/16 6:04 下午
  9. * @Description:
  10. */
  11. public class Floppy {
  12. enum MAGNETIC_HEAD {
  13. MAGNETIC_HEAD_0,
  14. MAGETIC_HEAD_1
  15. };
  16. public int SECTOR_SIZE = 512;
  17. private int CYLINDER_COUNT = 80; //80个柱面
  18. private int SECTORS_COUNT = 18;
  19. private MAGNETIC_HEAD magneticHead = MAGNETIC_HEAD.MAGNETIC_HEAD_0;
  20. private int current_cylinder = 0;
  21. private int current_sector = 0;
  22. private HashMap<Integer,ArrayList<ArrayList<byte[]>> > floppy = new HashMap<Integer,ArrayList<ArrayList<byte[]>> >(); //一个磁盘两个面
  23. public Floppy() {
  24. initFloppy();
  25. }
  26. private void initFloppy() {
  27. //一个磁盘有两个盘面
  28. floppy.put(MAGNETIC_HEAD.MAGNETIC_HEAD_0.ordinal(), initFloppyDisk());
  29. floppy.put(MAGNETIC_HEAD.MAGETIC_HEAD_1.ordinal(), initFloppyDisk());
  30. }
  31. private ArrayList<ArrayList<byte[]>> initFloppyDisk() {
  32. ArrayList<ArrayList<byte[]>> floppyDisk = new ArrayList<ArrayList<byte[]>>(); //磁盘的一个面
  33. //一个磁盘面有80个柱面
  34. for(int i = 0; i < CYLINDER_COUNT; i++) {
  35. floppyDisk.add(initCylinder());
  36. }
  37. return floppyDisk;
  38. }
  39. private ArrayList<byte[]> initCylinder() {
  40. //构造一个柱面,一个柱面有18个扇区
  41. ArrayList<byte[]> cylinder = new ArrayList<byte[]> ();
  42. for (int i = 0; i < SECTORS_COUNT; i++) {
  43. byte[] sector = new byte[SECTOR_SIZE];
  44. cylinder.add(sector);
  45. }
  46. return cylinder;
  47. }
  48. public void setMagneticHead(MAGNETIC_HEAD head) {
  49. magneticHead = head;
  50. }
  51. public void setCylinder(int cylinder) {
  52. // 柱面/磁道 编号1-80
  53. if (cylinder < 0) {
  54. this.current_cylinder = 0;
  55. }
  56. else if (cylinder >= 80) {
  57. this.current_cylinder = 79;
  58. }
  59. else {
  60. this.current_cylinder = cylinder;
  61. }
  62. }
  63. public void setSector(int sector) {
  64. //sector 编号从1到18
  65. if (sector < 0) {
  66. this.current_sector = 0;
  67. }
  68. else if (sector > 18) {
  69. this.current_sector = 18 - 1;
  70. }
  71. else {
  72. this.current_sector = sector - 1;
  73. }
  74. }
  75. public byte[] readFloppy(MAGNETIC_HEAD head, int cylinder_num, int sector_num) {
  76. setMagneticHead(head);
  77. setCylinder(cylinder_num);
  78. setSector(sector_num);
  79. ArrayList<ArrayList<byte[]>> disk = floppy.get(this.magneticHead.ordinal());
  80. ArrayList<byte[]> cylinder = disk.get(this.current_cylinder);
  81. byte[] sector = cylinder.get(this.current_sector);
  82. return sector;
  83. }
  84. public void writeFloppy(MAGNETIC_HEAD head, int cylinder_num, int sector_num, byte[] buf) {
  85. setMagneticHead(head);
  86. setCylinder(cylinder_num);
  87. setSector(sector_num);
  88. ArrayList<ArrayList<byte[]>> disk = floppy.get(this.magneticHead.ordinal());
  89. ArrayList<byte[]> cylinder = disk.get(this.current_cylinder);
  90. cylinder.set(this.current_sector, buf);
  91. }
  92. public void makeFloppy(String fileName) {
  93. try {
  94. /**
  95. * 虚拟软盘是纯粹的二进制文件,逻辑结构如下:
  96. * 前512*18个字节是对应盘面0,柱面0的所有扇区内容
  97. * 后512*18个字节对应盘面1,柱面0的所有扇区内容
  98. * 然后512*18字节对应盘面0,柱面1的所有扇区内容
  99. */
  100. DataOutputStream out = new DataOutputStream(new FileOutputStream(fileName));
  101. for (int head = 0; head <= MAGNETIC_HEAD.MAGETIC_HEAD_1.ordinal(); head++) {
  102. for (int cylinder = 0; cylinder < CYLINDER_COUNT; cylinder++) {
  103. for (int sector = 1; sector <= SECTORS_COUNT; sector++) {
  104. byte[] buf = readFloppy(MAGNETIC_HEAD.values()[head], cylinder, sector);
  105. out.write(buf);
  106. }
  107. }
  108. }
  109. } catch (Exception e) {
  110. // TODO Auto-generated catch block
  111. e.printStackTrace();
  112. }
  113. }
  114. }