oslab's People
oslab's Issues
Lab1
bootsect.s
linux 0.11的bootsect.s
首先由BIOS读到内存的0x7c00
处,bootsect
模块开始执行后,会将自己移动到0x90000
处。之后bootsect
模块会将setup
模块读入内存0x90200
处,system
模块则被读入到0x10000
处。
执行权交由setup
模块之后,bootsect
就失去作用了,setup
模块将system
模块移动到内存的开始处,即0x00
处。
关于上述加电启动的描述,图示非常清晰
关于为什么代码要移来移去,这里面有很多历史遗留问题。
1981年8月,IBM公司最早的个人电脑IBM PC 5150上市,就用了8088这个芯片。
当时,搭配的操作系统是86-DOS。这个操作系统需要的内存最少是32KB。我们知道,内存地址从0x0000开始编号,32KB的内存就是0x0000~0x7FFF。
8088芯片本身需要占用0x0000~0x03FF,用来保存各种中断处理程序的储存位置。(主引导记录本身就是中断信号INT 19h的处理程序。)所以,内存只剩下0x0400~0x7FFF可以使用。
为了把尽量多的连续内存留给操作系统,主引导记录就被放到了内存地址的尾部。由于一个扇区是512字节,主引导记录本身也会产生数据,需要另外留出512字节保存。所以,它的预留位置就变成了:
0x7FFF – 512 – 512 = 0x7C00
0x7C00就是这样来的。
计算机启动后,32KB内存的使用情况如下。
+——————— 0x0
| Interrupts vectors
+——————— 0x400
| BIOS data area
+——————— 0x5??
| OS load area
+——————— 0x7C00
| Boot sector
+——————— 0x7E00
| Boot data/stack
+——————— 0x7FFF
| (not used)
+——————— (…)
在此之后,这个传统可能沿袭了下来,所以1991年的时候,bootsect
还是要首先被读到0x7c00
处。
而关于为什么system
模块不从0开始的问题,是由于在setup
模块在获取硬件信息时,需要用到BIOS的中断来获取硬件参数。当BIOS初始化时会在物理内存的开始出放置一个大小为1KB
大小的中断向量表。因此在使用完此中断向量表之前,system
模块只能先找个地方暂时存一下。
Lab2
系统调用
系统调用过程:
- 把系统调用的编号存入eax寄存器
- 把函数参数存入其它通用寄存器
- 触发0x80号中断(int 0x80)
include/unistd.h
中定义了系统调用的宏,如
#define __NR_close 6
可以在unistd.h
中添加新的系统调用的宏,并且指定编号。
在kernel/system_call.s
中,定义了系统调用的总数nr_system_calls
,需要修改。其中的 _system_call
函数中有一句call sys_call_table(,%eax,4)
,根据汇编寻址方法实际应为
call sys_call_table + 4 * %eax # 其中eax中放的是系统调用号,即__NR_xxxxxx
即从sys_call_table
中找出相应的系统调用。
sys_call_table
定义在include/linux/sys.h
中,它包含函数定义和函数数组。
makefile文件的用法需要学习。
定义好的系统调用需要自己实现,这里的who.c
在kernel
中实现。系统调用时,内核态在获取用户态数据时需要使用get_fs_byte()
,发送数据时使用put_fs_byte()
。
在应用程序中要有
#define __LIBRARY__ /* 有它,_syscall1等才有效。详见unistd.h */
#include <unistd.h> /* 有它,编译器才能获知自定义的系统调用的编号 */
/* iam()在用户空间的接口函数 */
_syscall1(int, iam, const char*, name);
/* whoami()在用户空间的接口函数 */
_syscall2(int, whoami,char*,name,unsigned int,size);
这样应用程序的main
函数才能调用系统调用,如下:
_syscall1(int,iam,const char*,name)
int main(int argc,char* argv[])
{
int n;
n=iam(argv[1]);
return n;
}
C语言中,main函数的参数argc
表示传递给main
函数的命令行参数的个数,argv
数组存放了传递的参数,其中0号元素存放的是程序的路径名,如:
~/Documents$ ./a.out 123
参数个数2
0号参数为./a.out
1号参数为123
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.