内存管理系统

news2024/11/26 2:41:22

文章目录

  • 前言
  • 前置知识
    • makefile
    • 位图
    • 内存池规划
  • 实验操作
    • 实验一
    • 实验二
    • 实验三
    • 实验四
    • 实验五

前言

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

实验环境: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 虚拟地址获取物理地址。

在这里插入图片描述

参考资料

  • 《操作系统真象还原》
  • 《操作系统真象还原》第八章 ---- 初入内存管理系统 涉足MakeFile 了解摸谈一二

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/153992.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

合并表记录 C语言实现

合并表记录 描述 数据表记录包含表索引index和数值value&#xff08;int范围的正整数&#xff09;&#xff0c;请对表索引相同的记录进行合并&#xff0c;即将相同索引的数值进行求和运算&#xff0c;输出按照index值升序进行输出。 提示: 0 < index < 11111111 1 <…

产品经理的技术脑:产品是如何工作的?

产品在web中的工作流程如图&#xff1a; 浏览器工作流程&#xff08;客户端&#xff09;&#xff1a; 用户访问网站时输入的URL&#xff0c;浏览器是无法根据输入的URL找到web服务器的&#xff0c;需要通过IP地址找到web服务器&#xff0c;因此&#xff0c;浏览器对用户URL的处…

6.5 工具-ElasticSearch

目录 6.5.1 ElasticSearch概述 6.5.1.1 什么是ElasticSearch 6.5.1.2 Lucene 6.5.1.3 Elastic Stack 6.5.1.4 Solr与ES 6.5.1.4.1 背景 6.5.1.4.2 区别 6.5.1.5 正向索引与倒排索引 6.5.1.5.1 正向索引 6.5.1.5.2 倒排索引 6.5.2 Elasticsearch安装 6.5.3 Elastics…

机器视觉硬件篇--线激光3d相机介绍及编程

一、3D相机简介常见的三维视觉技术&#xff0c;包含双目、ToF、激光三角、结构光等毫米级&#xff1a;双目、ToF、结构光(散斑)的精度为 mm 级&#xff0c;多见于消费领域&#xff0c;如&#xff1a;导航避障&#xff0c;VR/AR&#xff0c;刷脸支付等微米级&#xff1a;线激光、…

08-什么是类加载器,类加载器有哪些, 双亲委派模型机制?

1.类加载器 1.实现通过类的权限定名获取该类的二进制字节流的代码块叫做类加载器。 2.虚拟机设计团队把加载动作放到 JVM 外部实现&#xff0c;以便让应用程序决定如何获取所需的类。 3.类加载器虽然只用于实现类的加载动作&#xff0c;但是对于任意一个类&#xff0c;都需要…

ES索引规划方案

ES索引规划方案 1.引言 《ES索引规划方案》是研发部门针对审计系统需求&#xff0c;对海量日志数据进行实时存储和查询的解决方案&#xff0c;经过不断完善整理成册&#xff0c;以供后续相关开发人员学习使用 1.1.术语 序号用语说明1时序索引以时间为轴&#xff0c;数据只有…

Blender里的三种绑定 (二)约束

文章目录Blender里的三种绑定.约束.变换约束.复制位置.复制旋转.复制缩放.限定距离.限定位置&#xff0c;限定旋转&#xff0c;限定缩放.维持体积.变换.追踪约束.钳制到.阻尼追踪.锁定追踪.拉伸到.标准跟随.关系约束.动作.骨架.子级.基面.跟随路径.轴心.缩裹.Blender里的三种绑…

ViT(Version Transformer)原始论文解读

An Image is Worth 16x16 Words Transformers for Image Recognition at Scale paper&#xff1a;2010.11929.pdf (arxiv.org) code&#xff1a;google-research/vision_transformer (github.com) 期刊/会议&#xff1a;ICLR 2020 摘要 虽然Transformer体系结构已经成为自然…

【保姆级】@PostConstruct @PreDestroy使用示例

简介PostConstruct & PreDestroy被PostConstruct注解修饰的方法会在服务器加载Servlet的时候运行&#xff0c;并且只会被服务器调用一次&#xff0c;类似于Servlet的init()方法&#xff0c;被PostConstruct注解修饰的方法会在构造函数之后&#xff0c;init()方法执行之前执…

群晖NAS搭建portainer

参考&#xff1a; 群晖、威联通、Linux最强docker管理工具portainer安装及汉化教程2022最新版本 Portainer官方文档 How to run Docker commands without sudo on a Synology NAS 因为群晖的NAS是基于linux但是限制很多的系统&#xff0c;有一些东西通过命令行操作可能会遇到权…

Git 常见错误 之 fatal: Authentication failed 简单解决方法

Git 常见错误 之 fatal: Authentication failed 简单解决方法 目录 Git 常见错误 之 fatal: Authentication failed 简单解决方法 一、简单介绍 二、问题现象 三、解决方法 1、修改全局配置用户名 和 邮箱 2、修改凭证(具体问题具体分析) 一、简单介绍 Git(读音为/gɪt…

系分 - 案例分析 - 需求分析

个人总结&#xff0c;仅供参考&#xff0c;欢迎加好友一起讨论 文章目录系分 - 案例分析 - 需求分析结构化分析SA数据流图DFD答题技巧典型例题题目描述参考答案面向对象的分析OOA用例图用例模型细化用例描述用例关系【包含、扩展、泛化】分析模型定义概念类确定类之间的关系类图…

拉伯证券|LPR利率三连降 全国首套房贷利率今年或“奔三”

2022年LPR接连下调。新年伊始&#xff0c;“房贷一族”迎来好消息&#xff0c;一年一度存量房贷利率重定价的日子到了。关于房贷利率挂钩借款商场报价利率(LPR)、重定价日为每年1月1日的住宅顾客&#xff0c;本年的房贷利率将迎来下降。不仅如此&#xff0c;存量公积金借款也于…

Flink实时计算引擎入门教程

Flink实时计算引擎入门教程 1.简介 Fink是一个开源的分布式,高性能,高可用,准确的实时数据计算框架&#xff0c;它主要优点如下: 流式计算: Fink可以连接处理流式(实时)数据。 容错: Fink提供了有状态的计算,会记录任务的中间状态,当执行失败时可以实现故障恢复。 可伸缩: F…

【软件测试】关于BUG的那些点点滴滴

关于BUG1. 如何合理的创建Bug1.1 创建Bug的要素2. Bug 的级别3. Bug 的生命周期3.1 Bug的状态3.2 Bug的生命周期4. 提出Bug后&#xff0c;跟开发产生争执怎么办1. 如何合理的创建Bug 1.1 创建Bug的要素 问题的版本&#xff0c;如浏览器的版本问题的环境&#xff0c;如windows…

融合注意力模块CBAM基于轻量级yolov5n开发共享单车目标检测系统

在很多的项目实战中验证分析注意力机制的加入对于模型最终性能的提升发挥着积极正向的作用&#xff0c;在我之前的一些文章里面也做过了一些尝试&#xff0c;这里主要是想基于轻量级的n系列模型来开发构建共享单车检测系统&#xff0c;在模型中加入CBAM模块&#xff0c;以期在轻…

web自动化测试---使用java+selenium+Junit

目录 1.什么是自动化以及为什么要进行自动化 2.为什么选择selenium作为web自动化工具 3.selenium环境部署 4.什么是驱动以及驱动的原理 5.selenium的基础语法和操作 5.1定位元素 5.2元素的操作 5.3等待 5.4信息打印 5.5窗口 5.6导航 5.7弹窗 5.8鼠标、键盘操作 5.…

Python + Appium 自动化操作微信入门

Appium 是一个开源的自动化测试工具&#xff0c;支持 Android、iOS 平台上的原生应用&#xff0c;支持 Java、Python、PHP 等多种语言。 Appium 封装了 Selenium&#xff0c;能够为用户提供所有常见的 JSON 格式的 Selenium 命令以及额外的移动设备相关的控制命令&#xff0c;…

虚拟化技术

虚拟化 虚拟化技术 目前虚拟化技术有软件模拟、全虚拟化&#xff08;使用二进制翻译&#xff09;、半虚拟化&#xff08;操作系统辅助&#xff09;、硬件辅助虚拟化和容器虚拟化这几种。 &#xff08;1&#xff09;软件虚拟化 软件模拟是通过软件完全模拟cpu、芯片组、磁盘、…

Spring Cloud Gateway 远程代码执行漏洞(CVE-2022-22947)

参考链接&#xff1a;https://blog.csdn.net/xiaobai_20190815/article/details/124045768 http://news.558idc.com/290335.html Java 安全-手把手教你SPEL表达式注入_4ct10n的博客-CSDN博客_spel注入 一、漏洞描述 Spring Cloud Gateway 是基于 Spring Framework 和 Spring…