操作系统源代码阅读
(马如林)
序言
0x55的启动标志,最大512个字节。
汇编代码,将自己复制到内存并跳转到指定地址运行初始化的程序。系统启动是在实地址模式下运行的。
初始化使用系统初始化过程,设置内存,重新设置中断,跳转到保护模式,装载内核,最后跳转到内核开始函数。
部分参数使用编译命令传递。
复制软驱内容及Setup.bin、Kernel.bin到指定位置,然后跳转到特定位置执行,Setup.bin是编译过的代码,对系统进行初始化,最后跳转到内核的Main函数地址进行执行,文件系统设置也可以设置在此。
进入初始化段后,对系统内存等进行读取并设置。
重新设置PIC(Interl和IBM的不同设置)。
关闭软驱。
跳转到32位保护模式和程序Main函数。
LIDT(设置中断描述符表)
LGDT->段描述符基地址和大小
段选择子->段描述符
段描述符(8字节)->段基地址、段界限(大小)、段属性等信息。
段选择子 : 描述符索引、TI(Table Indicator)、RPL(requested privilege level) 16位
段选择子(获取32位基地址)
+ 32位偏移地址
-----------------------------------------------------
线性地址
文件启动设置
Superblock:表示一个特定的文件系统
Inode:表示一个指定文件
Dentry:目录入口
File:表示一个打开的文件
可对其进行编程,设置每过一段时间(一般10ms)发出一个中断请求。
键盘码
标准设定80*25行等。
16位编码模式
段内:修改IP
段间:IP、CS修改
push IP
jmp near ptr 标号
1 (SP) = (SP) -2
((SS) *16 +(SP)) = (IP)
2 (IP) = (IP) + 16位位移
pop IP
1 (IP) = ((SS)*16 + (sp))
2 (SP)=(SP) + 2
dseg segment message DB 'Hello world', 0DH, 0AH, 24H dseg ends
cseg segment assume cs:cseg, ds: dseg begin: mov ax, dseg mov ds,ax mov dx, offset message mov ah, 9 int 21h
mov ah,4ch int 21h cseg ends end begin
|
GDB官方网址http://www.gnu.org/software/gdb/
无限循环
无限循环,效率比while(1)高。
和链接有关,查看链接文件等。
size_t is an unsigned data type defined by several C/C++ standards.
format (archetype, string-index, first-to-check)
“函数指针”是指向函数的指针变量,因而“函数指针”本身首先应是指针变量,只不过该指针变量指向函数。
int max(int x,int y){ return(x>y?x:y); } void main() { int (*ptr)(); int a,b,c; ptr=max; scanf("%d,%d",&a,&b); c=(*ptr)(a,b); printf("a=%d,b=%d,max=%d",a,b,c); } |
指针函数是指带指针的函数,即本质是一个函数。我们知道函数都又有返回类型(如果不返回值,则为无值型),只不过指针函数返回类型是某一类型的指针。
其定义格式如下所示:
返回类型标识符 *返回名称(形式参数表)
{ 函数体 }
返回类型可以是任何基本类型和复合类型。返回指针的函数的用途十分广泛。事实上,每一个函数,即使它不带有返回某种类型的指针,它本身都有一个入口地址,该地址相当于一个指针。
指针有两个属性:指向变量/对象的地址和长度。但是指针只存储地址,长度则取决于指针的类型编译器根据指针的类型从指针指向的地址向后寻址指针类型不同则寻址范围也不同,比如: int*从指定地址向后寻找4字节作为变量的存储单元 double*从指定地址向后寻找8字节作为变量的存储单元。
Bochs主页http://bochs.sourceforge.net/。本文件使用的版本:bochs-2.4.5.tar.gz。参考Bochs的手册(Bochs User Manual),进行安装。
gunzip -c bochs-version.tar.gz | tar -xvf – cd ./configure --enable-debugger --enable-disasm ./configure --enable-gdb-stub(使用gdb调式功能和debug不能同时使用) make make install |
bochs -version |
Bochs安装
安装过程报错,修改如下:
gui/libgui.a(gtk_enh_dbg_osdep.o): In function `MakeGTKthreads()':./build/bochs-2.4.2/gui/gtk_enh_dbg_osdep.cc:2120: undefined reference to `pthread_create' |
修改Makefile文件 |
LIBS = -lm -lgtk-x11-2.0 -lgdk-x11-2.0 -latk-1.0 -lgdk_pixbuf-2.0 -lpangocairo-1.0 -lpango-1.0 -lcairo -lgobject-2.0 -lgmodule-2.0 -ldl -lglib-2.0 -lpthread |
Bochs设置
Bochs调式
使用GDB Stub进行C调试。
1 gcc –g内核代码 2 make 3 bochs -q -f bochsrc.txt 等待远程调式连接
|
1 cd project0/build/geekos 2 gdb kernel.exe 3 target remote localhost:1234 4 cont |
官方地址http://www.kernel.org/
ftp://ftp.kernel.org/pub/linux/kernel/存放源文件,注意1.0以前的在Historic里。
http://www.gnu.org/software/make/manual/make.html
egrep 'Main' kernel.syms |awk '{print $1}'
00016704
#! /usr/bin/perl
# Find the number of 512-byte sectors needed to store # given file.
# $Revision: 1.1 $
use strict qw(refs vars);
if ( scalar(@ARGV) != 1 ) { print STDERR "Usage: numsecs <filename>/n"; exit 1; }
my $filename = shift @ARGV; my $size = (-s $filename ); die "Couldn't get size of $filename: $!" if ( !defined $size );
my $result = int($size / 512); my $remainder = $size % 512; $result++ if ( $remainder > 0 );
print "$result/n"; |
|
|
$./numsecs ../build/geekos/kernel.bin 81 $./numsecs ../build/geekos/setup.bin 1 |
$nasm file.asm object
标题
目的,方法,结果,结论
$ ndisasm object
dd if=boot.bin of=/dev/fd1 bs=512 count=1
Makefile文件的实例应用
test.c #include "stdio.h" #include "test.h"
int main() {
printf("this is a test. /n"); PAUSE(1000); printf("this is second test. /n"); KASSERT(1==1); printf("this is 3 test. /n");
}
test.h #define PAUSE(count) / do { / unsigned long i; / for (i = 0; i < (count); ++i) / ; / } while (0)
#define KASSERT(cond) / do { / if (!(cond)) { / printf("test /n"); / while (1) / ; / } / } while (0)
Makefile #targets : prerequisites # command # ... # object : test.c test.h gcc -o object test.c
clean : rm -f object
|
本课程是编译、软盘制作、dd命令及Bochs调试的综合使用。
8259A和定时中断
跳转到main函数
#define KASSERT(cond) / do { / if (!(cond)) { / printf("test /n"); / while (1) / ; / } / } while (0)
|
定时器计数等
进程间通信
原子操作
Linux.Kernel.Development.2nd.Edition. Robert Love
Understanding.The.Linux.Kernel Daniel P. Bovet & Marco Cesati
汇编语言 王爽
80X86汇编语言程序设计教程 杨季文
C程序设计语言 Kernigham & Ritchie
操作系统设计与实现 Andrew S. Tanenbaum & Albert S. Woodhull
数据结构 严蔚敏
Linux内核源代码情景分析 毛德操
计算机操作系统实践教程 黄庭辉 王宇英
深入理解Linux内核 Bovet & Cesati
深入理解计算机操作系统 Bryant
Linux内核设计与实现
Linux设备驱动程序
计算机组成原理 唐朔飞
Operating Systems
计算机组织与体系结构性能设计
Orange’s 一个操作系统的实现 于渊
NASM参考手册
Linux中的汇编语言
莱昂氏UNIX源代码分析
linux程序设计 Neil Matthew & Richard Stones
v1.Basic Architecture(24547004)
v2.Instruction Set Reference(24547104)
v3.System Programming Guide(24547204)
http://www.chinaunix.net
http://www.kernal.org
http://www.linux-tutorial.info/index.php