sistema de gestión de memoria

prefacio

El blog registra el funcionamiento del experimento en el Capítulo 8 de "Restauración de la verdad del sistema operativo" ~

Entorno experimental: ubuntu18.04 + VMware, descargue e instale Bochs

Contenido del experimento:

  1. Implementar afirmación de aserción.
  2. Implementar funciones de manipulación de cadenas. (memset, memcpy, strcpy, strlen, strchr, etc.)
  3. Implementa un mapa de bits para la gestión de memoria.
  4. Implementa las partes básicas del sistema de gestión de memoria.
  5. Realice una asignación de memoria simple sobre la base del Experimento 4.

conocimientos previos

archivo make

Comprensión del archivo Make

Definición de Makefile: este archivo describe la relación entre los distintos archivos del programa y proporciona comandos de actualización para cada archivo.

Al ejecutar el comando make, se requiere un archivo make para indicarle al comando make cómo compilar y vincular el programa.

gramática básica

La sintaxis básica de makefile consta de tres partes.

目标文件:依赖文件
[Tab]命令
  1. El archivo de destino se refiere al archivo que desea generar en esta regla. Puede ser un archivo de destino que termina en .o, un archivo ejecutable o un pseudo destino.
  2. Los archivos dependientes se refieren a qué archivos son necesarios para generar los archivos de destino en esta regla.
  3. Un comando es una acción que se debe realizar en esta regla. [Debe comenzar con Tab al principio de la línea]

[Suplemento 1] make¿Cómo determina el programa que los archivos deben actualizarse?

En Linux, los archivos se dividen en dos partes: atributos y datos. Cada archivo tiene tres tiempos ( statvisibles con comandos). El programa make obtiene el mtime (tiempo de modificación) del archivo dependiente y el archivo de destino respectivamente, compara si el mtime del archivo dependiente es más nuevo que el mtime del archivo de destino y determina si se debe ejecutar el comando en la regla.

makefile¿ Está arreglado el nombre del archivo de [Suplemento 2] ?

makefileEl nombre del archivo no es fijo y se puede especificar con el parámetro -f al ejecutar make. Si no se especifica -f, de forma predeterminada, make buscará primero un archivo llamado GNUmakefile. Si el archivo no existe, buscará un archivo llamado makefile. Si makefile no existe, finalmente buscará un archivo. llamado Makefile.documento.

(Para obtener operaciones detalladas con archivos MAKE, consulte el libro original o la documentación oficial de Baidu)

mapa de bits

El experimento 3 utiliza este conocimiento.

Mapa de bits: el mapa de bits utiliza 1 bit por byte para asignar recursos de otros tamaños de unidades. La esencia es el mapeo.

El sistema operativo puede utilizar mapas de bits para la gestión de la memoria (como se muestra en la siguiente figura). Si se utiliza un mapa de bits para administrar la memoria, cada bit en el mapa de bits representará 4 KB en la memoria física real, que es una página. Es decir, un bit en el mapa de bits corresponde a una página en la memoria física. Si un bit es 0 , Indica que la página correspondiente a este bit no está asignada ni disponible. De lo contrario, no será redistribuible temporalmente.

Insertar descripción de la imagen aquí

Planificación del grupo de memoria

El espacio de memoria que ocupan los programas de usuario lo asigna el sistema operativo.

En modo protegido, la dirección del programa se convierte en una dirección virtual y el mecanismo de paginación asigna la dirección física correspondiente a la dirección virtual.

Dado que hay direcciones virtuales y direcciones físicas bajo el mecanismo de paginación, la administración es más fácil, por lo que creamos un grupo de direcciones de memoria virtual y un grupo de direcciones de memoria física .

Primero describamos la planificación del grupo de memoria física (el diagrama esquemático se muestra a continuación).

División del grupo de memoria física:

  • Parte de ella solo se usa para ejecutar el kernel, es decir, la memoria física en este grupo de memoria solo la usa el sistema operativo. Esta parte se llama grupo de memoria física del kernel.
  • La otra parte solo se usa para ejecutar procesos de usuario, es decir, la memoria física en este grupo de memoria solo se asigna a procesos de usuario. Esta parte se denomina grupo de memoria física del usuario.

La memoria en el grupo de memoria se obtiene en unidades de páginas, siendo una página de 4 KB.

Insertar descripción de la imagen aquí
Es decir, la memoria física se divide en dos grupos de memoria.

Grupo de direcciones de memoria virtual (diagrama esquemático a continuación)

  • Kernel: aquí dejamos que el kernel solicite memoria a través del sistema de administración de memoria. Para ello cuenta con un pool de direcciones virtuales. Cuando solicita memoria, asigna una dirección virtual del propio grupo de direcciones virtuales del kernel, luego asigna memoria física del grupo de memoria física del kernel (específico del kernel) y finalmente establece una relación de mapeo entre las dos direcciones en la propia página del kernel. mesa.
  • Proceso de usuario: para un proceso de usuario, cuando solicita memoria del sistema de administración de memoria, es decir, el sistema operativo, el sistema operativo primero asigna direcciones virtuales libres del propio grupo de direcciones virtuales del proceso de usuario y luego asigna direcciones virtuales libres de el grupo de memoria física del usuario (todos los usuarios asignan memoria física libre en el proceso compartido) y luego establecen una relación de mapeo entre las dos direcciones en la propia tabla de páginas del proceso del usuario.

Insertar descripción de la imagen aquí

Operación experimental

experimento uno

Este experimento implementa la afirmación.

(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

Escriba un archivo MAKE (tenga en cuenta la ruta del archivo de su computadora)

(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

Ingrese primero al modo raíz; de lo contrario, apareceráPermission denied

(base) user@ubuntu:/home/cooiboi/bochs$ su
Password: 

ejecutar make allcomando

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

Empezar Bochs

sudo bin/bochs -f boot/bochsrc.disk

Insertar descripción de la imagen aquí

Experimento 2

Este experimento implementa funciones relacionadas con cadenas.

Por ejemplo memset, memcpy, strcpy, strlen, strchr, etc.

Cree string.c y string.h en lib

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

Modifique main.c para permitir Hello OSla longitud de su salida y comparar operaciones de aserción

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);
}

Modifique el archivo MAKE, un total de 3 modificaciones.

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 $@

archivo make completo

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

ERROR: NULL no está definido

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

Solución :

Agregue el archivo lib/string.h#define NULL 0

Insertar descripción de la imagen aquí


Empezar Bochs

sudo bin/bochs -f boot/bochsrc.disk
root@ubuntu:/home/cooiboi/bochs# sudo bin/bochs -f boot/bochsrc.disk

Insertar descripción de la imagen aquí

Experimento 3

Implementa un mapa de bits para la gestión de memoria.

Cree los archivos bitmap.c y bitmap.h en el directorio lib/kernel.

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

Insertar descripción de la imagen aquí
struct bitmap define dos variables miembro: bits de puntero de mapa de bits y longitud de bytes de mapa de bits btmp_bytes_len.

Experimento 4

Implementar la parte básica del sistema de gestión de memoria.

(Hay un problema con esta parte del código, puedes omitirlo e ir al siguiente experimento)

Cree los archivos Memory.c y Memory.h en el directorio del kernel.

root@ubuntu:/home/cooiboi/bochs/kernel# vim memory.c
root@ubuntu:/home/cooiboi/bochs/kernel# vim memory.h

Se agregó un #include "memory.h" y un mem_init(); en /kernel/init.c.

root@ubuntu:/home/cooiboi/bochs/kernel# vim init.c

Modifique el archivo MAKE, modifique 3 lugares

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

Necesita agregar

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

Experimento 5

Realice una asignación de memoria simple sobre la base del Experimento 4.

Cree los archivos Memory.c y Memory.h en el directorio del kernel.

root@ubuntu:/home/cooiboi/bochs/kernel# vim memory.c
root@ubuntu:/home/cooiboi/bochs/kernel# vim memory.h

Se agregó un #include "memory.h" y un mem_init(); en /kernel/init.c.

root@ubuntu:/home/cooiboi/bochs/kernel# vim init.c

Agregado en /lib/kernel/bitmap.htypedef int bool;

Insertar descripción de la imagen aquí

Modifique el archivo MAKE (nota: debe modificarlo de acuerdo con su directorio real)

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

Iniciar Bochs ~

Insertar descripción de la imagen aquí

Úselo para info tabver la relación de mapeo entre direcciones virtuales y direcciones físicas en la tabla de páginas.

A la izquierda está el rango de direcciones virtuales y a la derecha está la dirección física asignada.

El rango de direcciones virtuales es 0x00100000~0x00104fff y el rango de direcciones físicas asignadas es 0x200000~0x204fff.
Insertar descripción de la imagen aquí
También podemos page 虚拟地址obtener la dirección física usando .

Insertar descripción de la imagen aquí

Referencias

Supongo que te gusta

Origin blog.csdn.net/weixin_42888638/article/details/128627195
Recomendado
Clasificación