mirror of
				https://github.com/cfenollosa/os-tutorial.git
				synced 2025-06-13 12:54:24 +00:00 
			
		
		
		
	lesson 22, malloc
This commit is contained in:
		
							parent
							
								
									f98a02f6cc
								
							
						
					
					
						commit
						293f556a7e
					
				
							
								
								
									
										47
									
								
								22-malloc/Makefile
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										47
									
								
								22-malloc/Makefile
									
									
									
									
									
										Normal file
									
								
							@ -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
 | 
			
		||||
							
								
								
									
										18
									
								
								22-malloc/README.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										18
									
								
								22-malloc/README.md
									
									
									
									
									
										Normal file
									
								
							@ -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.
 | 
			
		||||
							
								
								
									
										1
									
								
								22-malloc/boot
									
									
									
									
									
										Symbolic link
									
								
							
							
						
						
									
										1
									
								
								22-malloc/boot
									
									
									
									
									
										Symbolic link
									
								
							@ -0,0 +1 @@
 | 
			
		||||
../21-shell/boot
 | 
			
		||||
							
								
								
									
										1
									
								
								22-malloc/cpu
									
									
									
									
									
										Symbolic link
									
								
							
							
						
						
									
										1
									
								
								22-malloc/cpu
									
									
									
									
									
										Symbolic link
									
								
							@ -0,0 +1 @@
 | 
			
		||||
../21-shell/cpu
 | 
			
		||||
							
								
								
									
										1
									
								
								22-malloc/drivers
									
									
									
									
									
										Symbolic link
									
								
							
							
						
						
									
										1
									
								
								22-malloc/drivers
									
									
									
									
									
										Symbolic link
									
								
							@ -0,0 +1 @@
 | 
			
		||||
../21-shell/drivers
 | 
			
		||||
							
								
								
									
										36
									
								
								22-malloc/kernel/kernel.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										36
									
								
								22-malloc/kernel/kernel.c
									
									
									
									
									
										Normal file
									
								
							@ -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> ");
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										6
									
								
								22-malloc/kernel/kernel.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										6
									
								
								22-malloc/kernel/kernel.h
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,6 @@
 | 
			
		||||
#ifndef KERNEL_H
 | 
			
		||||
#define KERNEL_H
 | 
			
		||||
 | 
			
		||||
void user_input(char *input);
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
							
								
								
									
										1
									
								
								22-malloc/libc/function.h
									
									
									
									
									
										Symbolic link
									
								
							
							
						
						
									
										1
									
								
								22-malloc/libc/function.h
									
									
									
									
									
										Symbolic link
									
								
							@ -0,0 +1 @@
 | 
			
		||||
../../21-shell/libc/function.h
 | 
			
		||||
							
								
								
									
										33
									
								
								22-malloc/libc/mem.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										33
									
								
								22-malloc/libc/mem.c
									
									
									
									
									
										Normal file
									
								
							@ -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;
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										12
									
								
								22-malloc/libc/mem.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										12
									
								
								22-malloc/libc/mem.h
									
									
									
									
									
										Normal file
									
								
							@ -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
 | 
			
		||||
							
								
								
									
										1
									
								
								22-malloc/libc/string.c
									
									
									
									
									
										Symbolic link
									
								
							
							
						
						
									
										1
									
								
								22-malloc/libc/string.c
									
									
									
									
									
										Symbolic link
									
								
							@ -0,0 +1 @@
 | 
			
		||||
../../21-shell/libc/string.c
 | 
			
		||||
							
								
								
									
										1
									
								
								22-malloc/libc/string.h
									
									
									
									
									
										Symbolic link
									
								
							
							
						
						
									
										1
									
								
								22-malloc/libc/string.h
									
									
									
									
									
										Symbolic link
									
								
							@ -0,0 +1 @@
 | 
			
		||||
../../21-shell/libc/string.h
 | 
			
		||||
		Loading…
	
		Reference in New Issue
	
	Block a user