Skip to content

Commit 293f556

Browse files
committed
lesson 22, malloc
1 parent f98a02f commit 293f556

File tree

12 files changed

+158
-0
lines changed

12 files changed

+158
-0
lines changed

22-malloc/Makefile

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
C_SOURCES = $(wildcard kernel/*.c drivers/*.c cpu/*.c libc/*.c)
2+
HEADERS = $(wildcard kernel/*.h drivers/*.h cpu/*.h libc/*.h)
3+
# Nice syntax for file extension replacement
4+
OBJ = ${C_SOURCES:.c=.o cpu/interrupt.o}
5+
6+
# Change this if your cross-compiler is somewhere else
7+
CC = /usr/local/i386elfgcc/bin/i386-elf-gcc
8+
GDB = /usr/local/i386elfgcc/bin/i386-elf-gdb
9+
# -g: Use debugging symbols in gcc
10+
CFLAGS = -g -m32 -nostdlib -nostdinc -fno-builtin -fno-stack-protector -nostartfiles -nodefaultlibs \
11+
-Wall -Wextra -Werror
12+
13+
# First rule is run by default
14+
os-image.bin: boot/bootsect.bin kernel.bin
15+
cat $^ > os-image.bin
16+
17+
# '--oformat binary' deletes all symbols as a collateral, so we don't need
18+
# to 'strip' them manually on this case
19+
kernel.bin: boot/kernel_entry.o ${OBJ}
20+
i386-elf-ld -o $@ -Ttext 0x1000 $^ --oformat binary
21+
22+
# Used for debugging purposes
23+
kernel.elf: boot/kernel_entry.o ${OBJ}
24+
i386-elf-ld -o $@ -Ttext 0x1000 $^
25+
26+
run: os-image.bin
27+
qemu-system-i386 -fda os-image.bin
28+
29+
# Open the connection to qemu and load our kernel-object file with symbols
30+
debug: os-image.bin kernel.elf
31+
qemu-system-i386 -s -fda os-image.bin -d guest_errors,int &
32+
${GDB} -ex "target remote localhost:1234" -ex "symbol-file kernel.elf"
33+
34+
# Generic rules for wildcards
35+
# To make an object, always compile from its .c
36+
%.o: %.c ${HEADERS}
37+
${CC} ${CFLAGS} -ffreestanding -c $< -o $@
38+
39+
%.o: %.asm
40+
nasm $< -f elf -o $@
41+
42+
%.bin: %.asm
43+
nasm $< -f bin -o $@
44+
45+
clean:
46+
rm -rf *.bin *.dis *.o os-image.bin *.elf
47+
rm -rf kernel/*.o boot/*.bin drivers/*.o boot/*.o cpu/*.o libc/*.o

22-malloc/README.md

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

22-malloc/boot

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
../21-shell/boot

22-malloc/cpu

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
../21-shell/cpu

22-malloc/drivers

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
../21-shell/drivers

22-malloc/kernel/kernel.c

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
#include "../cpu/isr.h"
2+
#include "../drivers/screen.h"
3+
#include "kernel.h"
4+
#include "../libc/string.h"
5+
#include "../libc/mem.h"
6+
7+
void main() {
8+
isr_install();
9+
irq_install();
10+
11+
kprint("Type something, it will go through the kernel\n"
12+
"Type END to halt the CPU or PAGE to request a kmalloc()\n> ");
13+
}
14+
15+
void user_input(char *input) {
16+
if (strcmp(input, "END") == 0) {
17+
kprint("Stopping the CPU. Bye!\n");
18+
asm volatile("hlt");
19+
} else if (strcmp(input, "PAGE") == 0) {
20+
/* Lesson 22: Code to test kmalloc, the rest is unchanged */
21+
u32 phys_addr;
22+
u32 page = kmalloc(1000, 1, &phys_addr);
23+
char page_str[16];
24+
int_to_ascii(page, page_str);
25+
char phys_str[16];
26+
int_to_ascii(phys_addr, phys_str);
27+
kprint("Page: ");
28+
kprint(page_str);
29+
kprint(", physical address: ");
30+
kprint(phys_str);
31+
kprint("\n");
32+
}
33+
kprint("You said: ");
34+
kprint(input);
35+
kprint("\n> ");
36+
}

22-malloc/kernel/kernel.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
#ifndef KERNEL_H
2+
#define KERNEL_H
3+
4+
void user_input(char *input);
5+
6+
#endif

22-malloc/libc/function.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
../../21-shell/libc/function.h

22-malloc/libc/mem.c

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
#include "mem.h"
2+
3+
void memory_copy(u8 *source, u8 *dest, int nbytes) {
4+
int i;
5+
for (i = 0; i < nbytes; i++) {
6+
*(dest + i) = *(source + i);
7+
}
8+
}
9+
10+
void memory_set(u8 *dest, u8 val, u32 len) {
11+
u8 *temp = (u8 *)dest;
12+
for ( ; len != 0; len--) *temp++ = val;
13+
}
14+
15+
/* This should be computed at link time, but a hardcoded
16+
* value is fine for now. Remember that our kernel starts
17+
* at 0x1000 as defined on the Makefile */
18+
u32 free_mem_addr = 0x10000;
19+
/* Implementation is just a pointer to some free memory which
20+
* keeps growing */
21+
u32 kmalloc(u32 size, int align, u32 *phys_addr) {
22+
/* Pages are aligned to 4K, or 0x1000 */
23+
if (align == 1 && (free_mem_addr & 0xFFFFF000)) {
24+
free_mem_addr &= 0xFFFFF000;
25+
free_mem_addr += 0x1000;
26+
}
27+
/* Save also the physical address */
28+
if (phys_addr) *phys_addr = free_mem_addr;
29+
30+
u32 ret = free_mem_addr;
31+
free_mem_addr += size; /* Remember to increment the pointer */
32+
return ret;
33+
}

22-malloc/libc/mem.h

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
#ifndef MEM_H
2+
#define MEM_H
3+
4+
#include "../cpu/types.h"
5+
6+
void memory_copy(u8 *source, u8 *dest, int nbytes);
7+
void memory_set(u8 *dest, u8 val, u32 len);
8+
9+
/* At this stage there is no 'free' implemented. */
10+
u32 kmalloc(u32 size, int align, u32 *phys_addr);
11+
12+
#endif

0 commit comments

Comments
 (0)