文章目录
- 前言
- 前置知识
- makefile
- 位图
- 内存池规划
- 实验操作
- 实验一
- 实验二
- 实验三
- 实验四
- 实验五
前言
博客记录《操作系统真象还原》第八章实验的操作~
实验环境:ubuntu18.04+VMware , Bochs下载安装
实验内容:
- 实现 assert 断言。
- 实现字符串操作函数。(memset,memcpy,strcpy,strlen,strchr等)
- 实现位图进行内存管理。
- 实现内存管理系统的基础部分。
- 在实验4的基础上实现简单的内存分配。
前置知识
makefile
makefile了解
makefile定义:该文件描述程序中各个文件之间的相互关系,并且提供每一个文件的更新命令。
当执行make命令时,需要makefile文件,告诉make命令需要怎么样的去编译和链接程序。
基本语法
makefile 基本语法包括三部分
目标文件:依赖文件
[Tab]命令
- 目标文件是指此规则中想要生成的文件,可以是.o 结尾的目标文件,也可以是可执行文件,也可以是个伪目标。
- 依赖文件是指要生成此规则中的目标文件,需要哪些文件。
- 命令是指此规则中要执行的动作。【在行首必须以 Tab 开头】
【补充1】make
程序 如何判断需要更新文件?
在 Linux 中,文件分为属性和数据两部分,每个文件有三种时间(命令stat
可查看)。make 程序分别获取依赖文件和目标文件的mtime(modify time),对比依赖文件的 mtime 是否比目标文件的 mtime 新,从而是否要执行规则中的命令。
【补充2】makefile
的文件名是否固定?
makefile
的文件名是不固定的,可在执行 make 时用-f 参数来指定。如果未用-f 指定,默认情况下,make 会先去找名为 GNUmakefile 的文件,若该文件不存在,再去找名为 makefile 的文件,若makefile也不存在,最后去找名为 Makefile 的文件。
(makefile详细操作见原书或者百度官方文档)
位图
实验三用到这部分知识。
位图:位图是用字节中的 1 位去映射其他单位大小的资源。本质是映射。
OS可以使用位图进行内存管理(如下图所示)。若用位图来管理内存,位图中的每一位都将表示实际物理内存中的 4KB,也就是一页,即位图中的一位对应物理内存中的一页,如果某位为 0,表示该位对应的页未分配,可用。反之,暂时不可再分配。
内存池规划
用户程序所占用的内存空间是由操作系统分配。
在保护模式下,程序地址变成了虚拟地址,虚拟地址对应的物理地址是由分页机制做的映射。
由于在分页机制下有了虚拟地址和物理地址,便于管理,我们创建了虚拟内存地址池和物理内存地址池。
先来描述物理内存池的规划(示意图如下所示)。
物理内存池的划分:
- 一部分只用来运行内核,即此内存池中的物理内存只给操作系统使用。这部分称为内核物理内存池。
- 另一部分只用来运行用户进程,即此内存池中的物理内存只用来分配给用户进程。这部分称为用户物理内存池。
内存池中的内存按页为单位大小来获取,一页4KB。
即,把物理内存分成两个内存池。
虚拟内存地址池(示意图如下)
- 内核:这里,我们让内核通过内存管理系统申请内存。为此,它要有个虚拟地址池。当它申请内存时,从内核自己的虚拟地址池中分配虚拟地址,再从内核物理内存池(内核专用)中分配物理内存,最后在内核自己的页表将这两种地址建立好映射关系。
- 用户进程:对用户进程来说,它向内存管理系统,即操作系统,申请内存时,操作系统先从用户进程自己的虚拟地址池中分配空闲虚拟地址,然后再从用户物理内存池(所有用户进程共享)中分配空闲的物理内存,然后在该用户进程自己的页表将这两种地址建立好映射关系。
实验操作
实验一
本实验实现assert 断言
(base) user@ubuntu:/home/cooiboi/bochs/kernel$ sudo vim debug.c
(base) user@ubuntu:/home/cooiboi/bochs/kernel$ sudo vim debug.h
(base) user@ubuntu:/home/cooiboi/bochs/kernel$ sudo vim interrupt.c
(base) user@ubuntu:/home/cooiboi/bochs/kernel$ sudo vim interrupt.h
(base) user@ubuntu:/home/cooiboi/bochs/kernel$ sudo vim main.c
编写makefile文件(注意自己电脑文件的路径)
(base) user@ubuntu:/home/cooiboi/bochs$ sudo vim makefile
BUILD_DIR = ./build
ENTRY_POINT = 0xc0001500
AS = nasm
CC = gcc
LD = ld
LIB = -I lib/ -I lib/kernel/ -I lib/user/ -I kernel/ -I device/
ASFLAGS = -f elf
CFLAGS = -Wall -m32 -fno-stack-protector $(LIB) -c -fno-builtin -W -Wstrict-prototypes -Wmissing-prototypes
LDFLAGS = -m elf_i386 -Ttext $(ENTRY_POINT) -e main -Map $(BUILD_DIR)/kernel.map
OBJS = $(BUILD_DIR)/main.o $(BUILD_DIR)/init.o $(BUILD_DIR)/interrupt.o \
$(BUILD_DIR)/timer.o $(BUILD_DIR)/kernel.o $(BUILD_DIR)/print.o \
$(BUILD_DIR)/debug.o
############## c代码编译 ###############
############## 后面的代码以后照本宣科即可 ###############
$(BUILD_DIR)/main.o: kernel/main.c lib/kernel/print.h \
lib/stdint.h kernel/init.h
$(CC) $(CFLAGS) $< -o $@
$(BUILD_DIR)/init.o: kernel/init.c kernel/init.h lib/kernel/print.h \
lib/stdint.h kernel/interrupt.h device/timer.h
$(CC) $(CFLAGS) $< -o $@
$(BUILD_DIR)/interrupt.o: kernel/interrupt.c kernel/interrupt.h \
lib/stdint.h kernel/global.h lib/kernel/io.h lib/kernel/print.h
$(CC) $(CFLAGS) $< -o $@
$(BUILD_DIR)/timer.o: device/timer.c device/timer.h lib/stdint.h\
lib/kernel/io.h lib/kernel/print.h
$(CC) $(CFLAGS) $< -o $@
$(BUILD_DIR)/debug.o: kernel/debug.c kernel/debug.h \
lib/kernel/print.h lib/stdint.h kernel/interrupt.h
$(CC) $(CFLAGS) $< -o $@
############## 汇编代码编译 ###############
$(BUILD_DIR)/kernel.o: kernel/kernel.S
$(AS) $(ASFLAGS) $< -o $@
$(BUILD_DIR)/print.o: lib/kernel/print.S
$(AS) $(ASFLAGS) $< -o $@
############## 链接所有目标文件 #############
$(BUILD_DIR)/kernel.bin: $(OBJS)
$(LD) $(LDFLAGS) $^ -o $@
.PHONY : mk_dir hd clean all
mk_dir:
if [ ! -d $(BUILD_DIR) ]; then mkdir $(BUILD_DIR); fi
hd:
dd if=$(BUILD_DIR)/kernel.bin \
of=/home/cooiboi/bochs/boot/hd60M.img \
bs=512 count=200 seek=9 conv=notrunc
clean:
cd $(BUILD_DIR) && rm -f ./*
build: $(BUILD_DIR)/kernel.bin
all: mk_dir build hd
先进入root模式,否则会出现 Permission denied
(base) user@ubuntu:/home/cooiboi/bochs$ su
Password:
执行make all
命令
root@ubuntu:/home/cooiboi/bochs# make all
if [ ! -d ./build ]; then mkdir ./build; fi
gcc -Wall -m32 -fno-stack-protector -I lib/ -I lib/kernel/ -I lib/user/ -I kernel/ -I device/ -c -fno-builtin -W -Wstrict-prototypes -Wmissing-prototypes kernel/init.c -o build/init.o
gcc -Wall -m32 -fno-stack-protector -I lib/ -I lib/kernel/ -I lib/user/ -I kernel/ -I device/ -c -fno-builtin -W -Wstrict-prototypes -Wmissing-prototypes kernel/interrupt.c -o build/interrupt.o
gcc -Wall -m32 -fno-stack-protector -I lib/ -I lib/kernel/ -I lib/user/ -I kernel/ -I device/ -c -fno-builtin -W -Wstrict-prototypes -Wmissing-prototypes kernel/debug.c -o build/debug.o
ld -m elf_i386 -Ttext 0xc0001500 -e main -Map ./build/kernel.map build/main.o build/init.o build/interrupt.o build/timer.o build/kernel.o build/print.o build/debug.o -o build/kernel.bin
dd if=./build/kernel.bin \
of=/home/cooiboi/bochs/boot/hd60M.img \
bs=512 count=200 seek=9 conv=notrunc
22+1 records in
22+1 records out
11732 bytes (12 kB, 11 KiB) copied, 0.000227052 s, 51.7 MB/s
启动Bochs
sudo bin/bochs -f boot/bochsrc.disk
实验二
本实验实现与字符串相关的函数
例如 memset,memcpy,strcpy,strlen,strchr等
在 lib 下创建 string.c 和 string.h
root@ubuntu:/home/cooiboi/bochs/lib# sudo vim string.c
root@ubuntu:/home/cooiboi/bochs/lib# sudo vim string.h
root@ubuntu:/home/cooiboi/bochs/lib# ls
kernel stdint.h string.c string.h user
修改main.c,让其输出Hello OS
的长度以及比较断言操作
root@ubuntu:/home/cooiboi/bochs/kernel# sudo vim main.c
#include "print.h"
#include "init.h"
#include "debug.h"
#include "string.h"
int main(void) {
put_str("I am kernel\n");
init_all();
put_str("length:");
put_int(strlen("Hello OS"));
ASSERT(strcmp("bbb","bbb"));
while(1);
}
修改makefile文件,共3处修改
OBJS = $(BUILD_DIR)/main.o $(BUILD_DIR)/init.o $(BUILD_DIR)/interrupt.o \
$(BUILD_DIR)/timer.o $(BUILD_DIR)/kernel.o $(BUILD_DIR)/print.o \
$(BUILD_DIR)/debug.o $(BUILD_DIR)/string.o
$(BUILD_DIR)/main.o: kernel/main.c lib/kernel/print.h \
lib/stdint.h kernel/init.h lib/string.h
$(CC) $(CFLAGS) $< -o $@
$(BUILD_DIR)/string.o: lib/string.c lib/string.h \
lib/stdint.h kernel/debug.h lib/string.h kernel/global.h
$(CC) $(CFLAGS) $< -o $@
完整makefile文件
BUILD_DIR = ./build
ENTRY_POINT = 0xc0001500
AS = nasm
CC = gcc
LD = ld
LIB = -I lib/ -I lib/kernel/ -I lib/user/ -I kernel/ -I device/
ASFLAGS = -f elf
CFLAGS = -Wall -m32 -fno-stack-protector $(LIB) -c -fno-builtin -W -Wstrict-prototypes -Wmissing-prototypes
LDFLAGS = -m elf_i386 -Ttext $(ENTRY_POINT) -e main -Map $(BUILD_DIR)/kernel.map
OBJS = $(BUILD_DIR)/main.o $(BUILD_DIR)/init.o $(BUILD_DIR)/interrupt.o \
$(BUILD_DIR)/timer.o $(BUILD_DIR)/kernel.o $(BUILD_DIR)/print.o \
$(BUILD_DIR)/debug.o $(BUILD_DIR)/string.o
############## c代码编译 ###############
############## 后面的代码以后照本宣科即可 ###############
$(BUILD_DIR)/main.o: kernel/main.c lib/kernel/print.h \
lib/stdint.h kernel/init.h lib/string.h
$(CC) $(CFLAGS) $< -o $@
$(BUILD_DIR)/init.o: kernel/init.c kernel/init.h lib/kernel/print.h \
lib/stdint.h kernel/interrupt.h device/timer.h
$(CC) $(CFLAGS) $< -o $@
$(BUILD_DIR)/interrupt.o: kernel/interrupt.c kernel/interrupt.h \
lib/stdint.h kernel/global.h lib/kernel/io.h lib/kernel/print.h
$(CC) $(CFLAGS) $< -o $@
$(BUILD_DIR)/timer.o: device/timer.c device/timer.h lib/stdint.h\
lib/kernel/io.h lib/kernel/print.h
$(CC) $(CFLAGS) $< -o $@
$(BUILD_DIR)/debug.o: kernel/debug.c kernel/debug.h \
lib/kernel/print.h lib/stdint.h kernel/interrupt.h
$(CC) $(CFLAGS) $< -o $@
$(BUILD_DIR)/string.o: lib/string.c lib/string.h \
lib/stdint.h kernel/debug.h lib/string.h kernel/global.h
$(CC) $(CFLAGS) $< -o $@
############## 汇编代码编译 ###############
$(BUILD_DIR)/kernel.o: kernel/kernel.S
$(AS) $(ASFLAGS) $< -o $@
$(BUILD_DIR)/print.o: lib/kernel/print.S
$(AS) $(ASFLAGS) $< -o $@
############## 链接所有目标文件 #############
$(BUILD_DIR)/kernel.bin: $(OBJS)
$(LD) $(LDFLAGS) $^ -o $@
.PHONY : mk_dir hd clean all
mk_dir:
if [ ! -d $(BUILD_DIR) ]; then mkdir $(BUILD_DIR); fi
hd:
dd if=$(BUILD_DIR)/kernel.bin \
of=/home/cooiboi/bochs/boot/hd60M.img \
bs=512 count=200 seek=9 conv=notrunc
clean:
cd $(BUILD_DIR) && rm -f ./*
build: $(BUILD_DIR)/kernel.bin
all: mk_dir build hd
make all
root@ubuntu:/home/cooiboi/bochs# make all
if [ ! -d ./build ]; then mkdir ./build; fi
gcc -Wall -m32 -fno-stack-protector -I lib/ -I lib/kernel/ -I lib/user/ -I kernel/ -I device/ -c -fno-builtin -W -Wstrict-prototypes -Wmissing-prototypes kernel/main.c -o build/main.o
gcc -Wall -m32 -fno-stack-protector -I lib/ -I lib/kernel/ -I lib/user/ -I kernel/ -I device/ -c -fno-builtin -W -Wstrict-prototypes -Wmissing-prototypes lib/string.c -o build/string.o
ld -m elf_i386 -Ttext 0xc0001500 -e main -Map ./build/kernel.map build/main.o build/init.o build/interrupt.o build/timer.o build/kernel.o build/print.o build/debug.o build/string.o -o build/kernel.bin
dd if=./build/kernel.bin \
of=/home/cooiboi/bochs/boot/hd60M.img \
bs=512 count=200 seek=9 conv=notrunc
23+1 records in
23+1 records out
12284 bytes (12 kB, 12 KiB) copied, 0.000235485 s, 52.2 MB/s
BUG: NULL未定义
root@ubuntu:/home/cooiboi/bochs# sudo make all
if [ ! -d ./build ]; then mkdir ./build; fi
gcc -Wall -m32 -fno-stack-protector -I lib/ -I lib/kernel/ -I lib/user/ -I kernel/ -I device/ -c -fno-builtin -W -Wstrict-prototypes -Wmissing-prototypes lib/string.c -o build/string.o
In file included from lib/string.c:3:0:
lib/string.c: In function ‘memset’:
lib/string.c:7:19: error: ‘NULL’ undeclared (first use in this function)
ASSERT(dst_ != NULL);
^
kernel/debug.h:16:11: note: in definition of macro ‘ASSERT’
if (CONDITION) {} else { \
^
lib/string.c:7:19: note: each undeclared identifier is reported only once for each function it appears in
ASSERT(dst_ != NULL);
^
kernel/debug.h:16:11: note: in definition of macro ‘ASSERT’
if (CONDITION) {} else { \
^
lib/string.c: In function ‘memcpy’:
lib/string.c:15:19: error: ‘NULL’ undeclared (first use in this function)
ASSERT(dst_ != NULL && src_ != NULL);
^
kernel/debug.h:16:11: note: in definition of macro ‘ASSERT’
if (CONDITION) {} else { \
^
lib/string.c: In function ‘memcmp’:
lib/string.c:26:16: error: ‘NULL’ undeclared (first use in this function)
ASSERT(a != NULL || b != NULL);
^
kernel/debug.h:16:11: note: in definition of macro ‘ASSERT’
if (CONDITION) {} else { \
^
lib/string.c: In function ‘strcpy’:
lib/string.c:39:19: error: ‘NULL’ undeclared (first use in this function)
ASSERT(dst_ != NULL && src_ != NULL);
^
kernel/debug.h:16:11: note: in definition of macro ‘ASSERT’
if (CONDITION) {} else { \
^
lib/string.c: In function ‘strlen’:
lib/string.c:47:18: error: ‘NULL’ undeclared (first use in this function)
ASSERT(str != NULL);
^
kernel/debug.h:16:11: note: in definition of macro ‘ASSERT’
if (CONDITION) {} else { \
^
lib/string.c: In function ‘strcmp’:
lib/string.c:55:16: error: ‘NULL’ undeclared (first use in this function)
ASSERT(a != NULL && b != NULL);
^
kernel/debug.h:16:11: note: in definition of macro ‘ASSERT’
if (CONDITION) {} else { \
^
lib/string.c: In function ‘strchr’:
lib/string.c:67:18: error: ‘NULL’ undeclared (first use in this function)
ASSERT(str != NULL);
^
kernel/debug.h:16:11: note: in definition of macro ‘ASSERT’
if (CONDITION) {} else { \
^
lib/string.c: In function ‘strrchr’:
lib/string.c:79:18: error: ‘NULL’ undeclared (first use in this function)
ASSERT(str != NULL);
^
kernel/debug.h:16:11: note: in definition of macro ‘ASSERT’
if (CONDITION) {} else { \
^
lib/string.c: In function ‘strcat’:
lib/string.c:93:19: error: ‘NULL’ undeclared (first use in this function)
ASSERT(dst_ != NULL && src_ != NULL);
^
kernel/debug.h:16:11: note: in definition of macro ‘ASSERT’
if (CONDITION) {} else { \
^
lib/string.c: In function ‘strchrs’:
lib/string.c:103:18: error: ‘NULL’ undeclared (first use in this function)
ASSERT(str != NULL);
^
kernel/debug.h:16:11: note: in definition of macro ‘ASSERT’
if (CONDITION) {} else { \
^
lib/string.c: In function ‘strchr’:
lib/string.c:75:1: warning: control reaches end of non-void function [-Wreturn-type]
}
^
makefile:38: recipe for target 'build/string.o' failed
make: *** [build/string.o] Error 1
解决方法:
在lib/string.h文件加入#define NULL 0
启动Bochs
sudo bin/bochs -f boot/bochsrc.disk
root@ubuntu:/home/cooiboi/bochs# sudo bin/bochs -f boot/bochsrc.disk
实验三
实现位图进行内存管理。
在 lib/kernel 目录下创建 bitmap.c 和 bitmap.h 文件。
root@ubuntu:/home/cooiboi/bochs/lib/kernel# sudo vim bitmap.c
root@ubuntu:/home/cooiboi/bochs/lib/kernel# sudo vim bitmap.h
lib/kernel/bitmap.h
struct bitmap 定义了两个成员变量:位图的指针 bits 和位图的字节长度 btmp_bytes_len。
实验四
实现内存管理系统的基础部分
(这部分代码存在问题,可以直接跳过进入到下一个实验)
在kernel目录下创建 memory.c 和 memory.h 文件 。
root@ubuntu:/home/cooiboi/bochs/kernel# vim memory.c
root@ubuntu:/home/cooiboi/bochs/kernel# vim memory.h
在 /kernel/init.c 下加了一个#include “memory.h” 和 一句 mem_init();
root@ubuntu:/home/cooiboi/bochs/kernel# vim init.c
修改makefile文件,修改3处
OBJS = $(BUILD_DIR)/main.o $(BUILD_DIR)/init.o $(BUILD_DIR)/interrupt.o \
$(BUILD_DIR)/timer.o $(BUILD_DIR)/kernel.o $(BUILD_DIR)/print.o \
$(BUILD_DIR)/debug.o $(BUILD_DIR)/string.o $(BUILD_DIR)/memory.o
$(BUILD_DIR)/main.o: kernel/main.c lib/kernel/print.h \
lib/stdint.h kernel/init.h lib/string.h kernel/memory.h
$(CC) $(CFLAGS) $< -o $@
$(BUILD_DIR)/memory.o: kernel/memory.c kernel/memory.h lib/stdint.h lib/kernel/bitmap.h \
kernel/global.h kernel/global.h kernel/debug.h lib/kernel/print.h \
lib/kernel/io.h kernel/interrupt.h lib/string.h lib/stdint.h
$(CC) $(CFLAGS) $< -o $@
bitmap.h
需要添加
typedef int bool;
root@ubuntu:/home/cooiboi/bochs# make all
if [ ! -d ./build ]; then mkdir ./build; fi
gcc -Wall -m32 -fno-stack-protector -I lib/ -I lib/kernel/ -I lib/user/ -I kernel/ -I device/ -c -fno-builtin -W -Wstrict-prototypes -Wmissing-prototypes kernel/main.c -o build/main.o
gcc -Wall -m32 -fno-stack-protector -I lib/ -I lib/kernel/ -I lib/user/ -I kernel/ -I device/ -c -fno-builtin -W -Wstrict-prototypes -Wmissing-prototypes kernel/init.c -o build/init.o
In file included from kernel/memory.h:4:0,
from kernel/init.c:5:
lib/kernel/bitmap.h:12:1: error: unknown type name ‘bool’
bool bitmap_scan_test(struct bitmap* btmp, uint32_t bit_idx);
^
makefile:22: recipe for target 'build/init.o' failed
make: *** [build/init.o] Error 1
实验五
在实验4的基础上实现简单的内存分配。
在kernel目录下创建 memory.c 和 memory.h 文件 。
root@ubuntu:/home/cooiboi/bochs/kernel# vim memory.c
root@ubuntu:/home/cooiboi/bochs/kernel# vim memory.h
在 /kernel/init.c 下加了一个#include “memory.h” 和 一句 mem_init();
root@ubuntu:/home/cooiboi/bochs/kernel# vim init.c
/lib/kernel/bitmap.h 中添加了typedef int bool;
修改makefile文件(注意:需要根据自己实际目录修改)
BUILD_DIR = ./build
ENTRY_POINT = 0xc0001500
AS = nasm
CC = gcc
LD = ld
LIB = -I lib/ -I lib/kernel/ -I lib/user/ -I kernel/ -I device/
ASFLAGS = -f elf
CFLAGS = -Wall -m32 -fno-stack-protector $(LIB) -c -fno-builtin -W -Wstrict-prototypes -Wmissing-prototypes
LDFLAGS = -m elf_i386 -Ttext $(ENTRY_POINT) -e main -Map $(BUILD_DIR)/kernel.map
OBJS = $(BUILD_DIR)/main.o $(BUILD_DIR)/init.o $(BUILD_DIR)/interrupt.o \
$(BUILD_DIR)/timer.o $(BUILD_DIR)/kernel.o $(BUILD_DIR)/print.o \
$(BUILD_DIR)/debug.o $(BUILD_DIR)/string.o $(BUILD_DIR)/memory.o \
$(BUILD_DIR)/bitmap.o
############## c代码编译 ###############
$(BUILD_DIR)/main.o: kernel/main.c lib/kernel/print.h \
lib/stdint.h kernel/init.h lib/string.h kernel/memory.h
$(CC) $(CFLAGS) $< -o $@
$(BUILD_DIR)/init.o: kernel/init.c kernel/init.h lib/kernel/print.h \
lib/stdint.h kernel/interrupt.h device/timer.h kernel/memory.h
$(CC) $(CFLAGS) $< -o $@
$(BUILD_DIR)/interrupt.o: kernel/interrupt.c kernel/interrupt.h \
lib/stdint.h kernel/global.h lib/kernel/io.h lib/kernel/print.h
$(CC) $(CFLAGS) $< -o $@
$(BUILD_DIR)/timer.o: device/timer.c device/timer.h lib/stdint.h\
lib/kernel/io.h lib/kernel/print.h
$(CC) $(CFLAGS) $< -o $@
$(BUILD_DIR)/debug.o: kernel/debug.c kernel/debug.h \
lib/kernel/print.h lib/stdint.h kernel/interrupt.h
$(CC) $(CFLAGS) $< -o $@
$(BUILD_DIR)/string.o: lib/string.c lib/string.h \
kernel/debug.h kernel/global.h
$(CC) $(CFLAGS) $< -o $@
$(BUILD_DIR)/memory.o: kernel/memory.c kernel/memory.h \
lib/stdint.h lib/kernel/bitmap.h kernel/debug.h lib/string.h
$(CC) $(CFLAGS) $< -o $@
$(BUILD_DIR)/bitmap.o: lib/kernel/bitmap.c lib/kernel/bitmap.h \
lib/string.h kernel/interrupt.h lib/kernel/print.h kernel/debug.h
$(CC) $(CFLAGS) $< -o $@
############## 汇编代码编译 ###############
$(BUILD_DIR)/kernel.o: kernel/kernel.S
$(AS) $(ASFLAGS) $< -o $@
$(BUILD_DIR)/print.o: lib/kernel/print.S
$(AS) $(ASFLAGS) $< -o $@
############## 链接所有目标文件 #############
$(BUILD_DIR)/kernel.bin: $(OBJS)
$(LD) $(LDFLAGS) $^ -o $@
.PHONY : mk_dir hd clean all
mk_dir:
if [ ! -d $(BUILD_DIR) ]; then mkdir $(BUILD_DIR); fi
hd:
dd if=$(BUILD_DIR)/kernel.bin \
of=/home/cooiboi/bochs/boot/hd60M.img \
bs=512 count=200 seek=9 conv=notrunc
clean:
cd $(BUILD_DIR) && rm -f ./*
build: $(BUILD_DIR)/kernel.bin
all: mk_dir build hd
启动Bochs~
使用info tab
查看页表中虚拟地址与物理地址的映射关系。
左边是虚拟地址的范围,右边是所映射的物理地址。
虚拟地址范围 0x00100000~0x00104fff 所映射的物理地址范围是 0x200000~0x204fff。
我们也可以使用page 虚拟地址
获取物理地址。
参考资料
- 《操作系统真象还原》
- 《操作系统真象还原》第八章 ---- 初入内存管理系统 涉足MakeFile 了解摸谈一二