lesson 22, malloc

pull/6/head
Carlos 9 years ago
parent f98a02f6cc
commit 293f556a7e

@ -0,0 +1,47 @@
C_SOURCES = $(wildcard kernel/*.c drivers/*.c cpu/*.c libc/*.c)
HEADERS = $(wildcard kernel/*.h drivers/*.h cpu/*.h libc/*.h)
# Nice syntax for file extension replacement
OBJ = ${C_SOURCES:.c=.o cpu/interrupt.o}
# Change this if your cross-compiler is somewhere else
CC = /usr/local/i386elfgcc/bin/i386-elf-gcc
GDB = /usr/local/i386elfgcc/bin/i386-elf-gdb
# -g: Use debugging symbols in gcc
CFLAGS = -g -m32 -nostdlib -nostdinc -fno-builtin -fno-stack-protector -nostartfiles -nodefaultlibs \
-Wall -Wextra -Werror
# First rule is run by default
os-image.bin: boot/bootsect.bin kernel.bin
cat $^ > os-image.bin
# '--oformat binary' deletes all symbols as a collateral, so we don't need
# to 'strip' them manually on this case
kernel.bin: boot/kernel_entry.o ${OBJ}
i386-elf-ld -o $@ -Ttext 0x1000 $^ --oformat binary
# Used for debugging purposes
kernel.elf: boot/kernel_entry.o ${OBJ}
i386-elf-ld -o $@ -Ttext 0x1000 $^
run: os-image.bin
qemu-system-i386 -fda os-image.bin
# Open the connection to qemu and load our kernel-object file with symbols
debug: os-image.bin kernel.elf
qemu-system-i386 -s -fda os-image.bin -d guest_errors,int &
${GDB} -ex "target remote localhost:1234" -ex "symbol-file kernel.elf"
# Generic rules for wildcards
# To make an object, always compile from its .c
%.o: %.c ${HEADERS}
${CC} ${CFLAGS} -ffreestanding -c $< -o $@
%.o: %.asm
nasm $< -f elf -o $@
%.bin: %.asm
nasm $< -f bin -o $@
clean:
rm -rf *.bin *.dis *.o os-image.bin *.elf
rm -rf kernel/*.o boot/*.bin drivers/*.o boot/*.o cpu/*.o libc/*.o

@ -0,0 +1,18 @@
*Concepts you may want to Google beforehand: malloc*
**Goal: Implement a memory allocator**
We will add a kernel memory allocator to `libc/mem.c`. It is
implemented as a simple pointer to free memory, which keeps
growing.
The `kmalloc()` function can be used to request an aligned page,
and it will also return the real, physical address, for later use.
We'll change the `kernel.c` leaving all the "shell" code there,
Let's just try out the new `kmalloc()`, and check out that
our first page starts at 0x10000 (as hardcoded on `mem.c`) and
subsequent `kmalloc()`'s produce a new address which is
aligned 4096 bytes or 0x1000 from the previous one.
The rest of the files are unchanged from last lesson.

@ -0,0 +1 @@
../21-shell/boot

@ -0,0 +1 @@
../21-shell/cpu

@ -0,0 +1 @@
../21-shell/drivers

@ -0,0 +1,36 @@
#include "../cpu/isr.h"
#include "../drivers/screen.h"
#include "kernel.h"
#include "../libc/string.h"
#include "../libc/mem.h"
void main() {
isr_install();
irq_install();
kprint("Type something, it will go through the kernel\n"
"Type END to halt the CPU or PAGE to request a kmalloc()\n> ");
}
void user_input(char *input) {
if (strcmp(input, "END") == 0) {
kprint("Stopping the CPU. Bye!\n");
asm volatile("hlt");
} else if (strcmp(input, "PAGE") == 0) {
/* Lesson 22: Code to test kmalloc, the rest is unchanged */
u32 phys_addr;
u32 page = kmalloc(1000, 1, &phys_addr);
char page_str[16];
int_to_ascii(page, page_str);
char phys_str[16];
int_to_ascii(phys_addr, phys_str);
kprint("Page: ");
kprint(page_str);
kprint(", physical address: ");
kprint(phys_str);
kprint("\n");
}
kprint("You said: ");
kprint(input);
kprint("\n> ");
}

@ -0,0 +1,6 @@
#ifndef KERNEL_H
#define KERNEL_H
void user_input(char *input);
#endif

@ -0,0 +1 @@
../../21-shell/libc/function.h

@ -0,0 +1,33 @@
#include "mem.h"
void memory_copy(u8 *source, u8 *dest, int nbytes) {
int i;
for (i = 0; i < nbytes; i++) {
*(dest + i) = *(source + i);
}
}
void memory_set(u8 *dest, u8 val, u32 len) {
u8 *temp = (u8 *)dest;
for ( ; len != 0; len--) *temp++ = val;
}
/* This should be computed at link time, but a hardcoded
* value is fine for now. Remember that our kernel starts
* at 0x1000 as defined on the Makefile */
u32 free_mem_addr = 0x10000;
/* Implementation is just a pointer to some free memory which
* keeps growing */
u32 kmalloc(u32 size, int align, u32 *phys_addr) {
/* Pages are aligned to 4K, or 0x1000 */
if (align == 1 && (free_mem_addr & 0xFFFFF000)) {
free_mem_addr &= 0xFFFFF000;
free_mem_addr += 0x1000;
}
/* Save also the physical address */
if (phys_addr) *phys_addr = free_mem_addr;
u32 ret = free_mem_addr;
free_mem_addr += size; /* Remember to increment the pointer */
return ret;
}

@ -0,0 +1,12 @@
#ifndef MEM_H
#define MEM_H
#include "../cpu/types.h"
void memory_copy(u8 *source, u8 *dest, int nbytes);
void memory_set(u8 *dest, u8 val, u32 len);
/* At this stage there is no 'free' implemented. */
u32 kmalloc(u32 size, int align, u32 *phys_addr);
#endif

@ -0,0 +1 @@
../../21-shell/libc/string.c

@ -0,0 +1 @@
../../21-shell/libc/string.h
Loading…
Cancel
Save