内存管理系统

前言

博客记录《操作系统真象还原》第八章实验的操作~

实验环境:ubuntu18.04+VMware , Bochs下载安装

实验内容:

  1. 实现 assert 断言。
  2. 实现字符串操作函数。(memset,memcpy,strcpy,strlen,strchr等)
  3. 实现位图进行内存管理。
  4. 实现内存管理系统的基础部分。
  5. 在实验4的基础上实现简单的内存分配。

前置知识

makefile

makefile了解

makefile定义:该文件描述程序中各个文件之间的相互关系,并且提供每一个文件的更新命令。

当执行make命令时,需要makefile文件,告诉make命令需要怎么样的去编译和链接程序。

基本语法

makefile 基本语法包括三部分

目标文件:依赖文件
[Tab]命令
  1. 目标文件是指此规则中想要生成的文件,可以是.o 结尾的目标文件,也可以是可执行文件,也可以是个伪目标。
  2. 依赖文件是指要生成此规则中的目标文件,需要哪些文件。
  3. 命令是指此规则中要执行的动作。【在行首必须以 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 虚拟地址获取物理地址。

在这里插入图片描述

参考资料

猜你喜欢

转载自blog.csdn.net/weixin_42888638/article/details/128627195