myOS
自制操作系统
学习过程
关于一个程序的组成
这张图片形象展示了一个程序是如何在代码中分布的
1.栈区
- 栈区由编译器自动分配释放,由操作系统自动管理,无须手动管理。
- 栈区上的内容只在函数范围内存在,当函数运行结束,这些内容也会自动被销毁。
- 栈区按内存地址由高到低方向生长,其最大大小由编译时确定,速度快,但自由性差,最大空间不大。
- 栈区是先进后出原则,即先进去的被堵在屋里的最里面,后进去的在门口,释放的时候门口的先出去。
存放内容:临时创建的局部变量和const定义的局部变量存放在栈区。
函数调用和返回时,其入口参数和返回值存放在栈区。
2.堆区
堆区由程序员分配内存和释放。
堆区按内存地址由低到高方向生长,其大小由系统内存/虚拟内存上限决定,速度较慢,但自由性大,可用空间大。
这里可能还会有内存映射段,用于动态链接库/文件映射
3.全局(静态)区
全局(静态)区介绍
通常是用于那些在编译期间就能确定存储大小的变量的存储区,但它用于的是在整个程序运行期间都可见的全局变量和静态变量。
全局区有 .bss段 和 .data段组成,可读可写。
BSS段
BSS段(Block Started by Symbol segment)是计算机程序内存布局中的一个重要组成部分,主要用于存储程序中未初始化的全局变量和静态变量。它位于数据段(.data段)之后,堆(heap)段之前
未初始化的全局变量和未初始化的静态变量存放在.bss段。
初始化为0的全局变量和初始化为0的静态变量存放在.bss段。
.bss段不占用可执行文件空间,其内容由操作系统初始化。
BSS段的主要特点是:
- 存储内容:专门用于存放程序中未初始化的全局变量和静态变量
- 初始化特性:在程序加载到内存时会被系统自动清零(初始化为0或空指针)
- 空间效率:在可执行文件中不占用实际存储空间,只记录所需空间大小
BSS段在计算机系统中发挥着重要作用,具有多项优势:
- 内存效率:通过只记录未初始化变量所需空间大小而不实际存储零值,显著减小可执行文件体积
- 例如:一个包含
int ar[30000];
的程序,编译后文件比初始化版本int ar[300000] = {1, 2, 3...}
- 例如:一个包含
- 运行效率:操作系统可批量清零BSS段,比单独初始化每个变量更高效
- 编程便利:程序员无需显式初始化全局/静态变量为零,简化代码编写
- 嵌入式系统优势:在资源受限的嵌入式环境中,BSS段能有效节省宝贵的内存空间
.data段
已初始化的全局变量存放在.data段。
已初始化的静态变量存放在.data段。
.data段占用可执行文件空间,其内容有程序初始化。
4. 常量区
- 字符串、数字等常量存放在常量区。
- const修饰的全局变量存放在常量区。
- 程序运行期间,常量区的内容不可以被修改。
5.代码区
- 程序执行代码存放在代码区,其值不能修改(若修改则会出现错误)。
- 字符串常量和define定义的常量也有可能存放在代码区。
操作系统的启动流程
- BIOS(Basic Input/Output System),基本输入输出系统,该系统存储于主板的ROM芯片上,计算机在开机时,会最先读取该系统,然后会有一个加电自检过程,这个过程其实就是检查CPU和内存,计算机最基本的组成单元(控制器、运算器和存储器),还会检查其他硬件,若没有异常就开始加载BIOS程序到内存当中。详细的BIOS功能,这边就不说了,BIOS主要的一个功能就是存储了磁盘的启动顺序,BIOS会按照启动顺序去查找第一个磁盘头的MBR信息,并加载和执行MBR中的Bootloader程序,若第一个磁盘不存在MBR,则会继续查找第二个磁盘(PS:启动顺序可以在BIOS的界面中进行设置),一旦BootLoader程序被检测并加载内存中,BIOS就将控制权交接给了BootLoader程序。
- MBR(Master Boot Record),主引导记录,MBR存储于磁盘的头部,大小为512bytes,其中,446bytes用于存储BootLoader程序,64bytes用于存储分区表信息,最后2bytes用于MBR的有效性检查。
- GRUB(Grand Unified Bootloader),多系统启动程序,其执行过程可分为三个步骤:
- Stage1:这个其实就是MBR,它的主要工作就是查找并加载第二段Bootloader程序(stage2),但系统在没启动时,MBR根本找不到文件系统,也就找不到stage2所存放的位置,因此,就有了stage1_5
- Stage1_5:该步骤就是为了识别文件系统
- Stage2:GRUB程序会根据/boot/grub/grub.conf文件查找Kernel的信息,然后开始加载Kernel程序,当Kernel程序被检测并在加载到内存中,GRUB就将控制权交接给了Kernel程序。
注意!现代操作系统使用了UEFI启动,但是我们现在不说UEFI,请自行忽略
但是这样也需要我们的Boot程序按照Mutileboot 规范来编译内核,才可以被GRUB引导。 按照Mutileboot规范,内核必须在起始的8KB中的(512字节)包含这一个多引导项头(Multiboot header)。 而且,这个多引导项头里面必须有3个4字节对齐的块。
一些指令
clt
,表示clear interrupt,关闭所有硬件中断
hlt
,表示停止CPU运行,即HALT