Directorio de artículos
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:
- Implementar afirmación de aserción.
- Implementar funciones de manipulación de cadenas. (memset, memcpy, strcpy, strlen, strchr, etc.)
- Implementa un mapa de bits para la gestión de memoria.
- Implementa las partes básicas del sistema de gestión de memoria.
- 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]命令
- 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.
- Los archivos dependientes se refieren a qué archivos son necesarios para generar los archivos de destino en esta regla.
- 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 ( stat
visibles 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] ?
makefile
El 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.
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.
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.
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 all
comando
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
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 OS
la 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
Empezar Bochs
sudo bin/bochs -f boot/bochsrc.disk
root@ubuntu:/home/cooiboi/bochs# sudo bin/bochs -f boot/bochsrc.disk
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
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;
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 ~
Úselo para info tab
ver 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.
También podemos page 虚拟地址
obtener la dirección física usando .
Referencias
- "Restauración de la verdad del sistema operativo"
- Capítulo 8 de "Restaurar la verdad del sistema operativo" ---- Ingrese por primera vez al sistema de administración de memoria y participe en MakeFile para aprender sobre él