BIOS注意点
1. BIOS是通过汇编或者C语言写的, 要想调动BIOS程序提供的函数, 需要CPU运行在16位模式下, 而我们的操作系统一般是在32位或者64位运行, 所以在操作系统的启动盘中, 我们需要在16位模式下调用BIOS程序的函数通过BIOS获取一些硬件的参数信息, 接着让CPU进入到32位或者64位模式
再谈C语言中的链接
1. C语言的作者在制作C语言的时候发现, 单单的使用C语言编写程序还是存在着许多的局限性, 为了解决这个问题, C语言的作者就发明了链接, 一部分的库使用汇编语言来说, 当时候链接出可执行文件即可
2. 链接的必要性: 通过源代码生成的目标文件并不是一个独立的二进制文件, 通过链接成为完整的可执行文件
映像文件
1. 通过C语言不能实现的功能, 可以通过汇编语言写一个函数, 编译成.o文件, 让C语言链接进来, 比如C不能直接写数据到VRAM(显卡内存, 可以存储任何数据, 但是这样的话就会损失他的功能, 它主要用于在每一个地址上填入像素), 编写一个汇编函数解决
2. C语言中的char *相当于AL, short *相当于AX, int *相当于EAX, C语言中的指针类型的强制转换相当于 MOV BYTE [0x123], 0x3132中的BYTE, 用来指定存放数据的大小
系统调用(API)到底是怎么一回事
- 由于C语言的局限性, 无法完成一些汇编语言可以完成的功能(主要是C语言中没有对应的指令), 但是作为一个应用程序的开发者, 使用汇编语言开发必然导致效率低下, 内核的开发者就是用汇编语言编写函数库, 生成.o文件, 在.s文件中写下如_printf函数的汇编实现等等, 通过链接器进行链接
- 应用程序调用系统API, 需要知道函数的地址
Window2000操作系统的界面是如何产生
- 首先声明, 屏幕下端的条形码不是图标, 而是通过C语言通过链接到使用汇编实现写好的系统调用在指定内存的位置写数据生成的, 一般都生成的都比较丑
- 我们所看到的gtk等框架可以画图图形界面, 实际上就是跟第一点说的一样, 调用了操作系统相关的.o文件, 里面的代码原始是由汇编语言编写的, 主要是在内存中的指定位置存数据
关于C的编译器
- C语言中的sprintf函数并不是操作系统提供的, 而是C的编译器提供的, 内核的编写者可以调用该函数实现字符串的打印, 但是在Linux和Unix中其实sprintf还是内核开发者自己写的, 因为时代在变化嘛
GDT与IDT
- GDT
为什么不放在寄存器中, 因为放不下:)
- IDT
可编程中断控制器(Programmable Interrupt Controller),也简称为PIC,是微处器与外设之间的中断处理的桥梁,由外设发出的中断请求需要中断控制器来进行处理
内存管理
- 1个字节1个字节的管理内存容易导致出现一小段一小段的内存碎片, 不方便管理, 所以一般以4k位单位管理内存
标准库文件
- 比如putchar, 每一个平台上都一个该函数的声明, 但是其内部的实现是不一样的, 因为内部是一个系统调用, 使用汇编语言完成, 所有不同的平台内容不同; 总之系统库函数是对系统API的封装, 方便开发者使用
新的开始
- 其实我感觉CPU要比内核更高级
在编写bootloader时, 我们将初始化GDT, 加载GDT到gdtr寄存器中(这样CPU才能知道GDT的位置, 因为这一部分不是通过内核的代码可以实现的, 而是CPU的厂商规定的), 开启A20地址线(让CPU可以
寻址4G), 修改cs寄存其中的PE位的值为1(0表示实模式, 1表示保护模式, 在保护模式下CPU才可以
寻址4G, 并且提供了更好的段的数据结构, 就是基于GDT, 这就是为什么在进入到保护模式之前需要
初始化GDT的原因, 因为保护模式需要GDT), 这是系统已经进入到了CPU保护模式, 接着跳转到一个指定的位置, 执行下一个指令
为什么我会感觉CPU更高级一点, 因为中断, 到CPU接受键盘的中断, 就不会管内核, 而是自动地到ldtr寄存器中获取ldt的地址, 根据信号知道对应的表项, 获取需要执行的中断处理函数的地址(这个是内核代码中写的), 执行该函数
- 保护模式运行在32位上, 实模式运行在16位上, BIOS运行在16位上