diff --git a/kernel/Makefile b/kernel/Makefile index 29e52ce4..c7730a71 100644 --- a/kernel/Makefile +++ b/kernel/Makefile @@ -10,7 +10,8 @@ KERNELS = $(addsuffix /$(KERNEL),$(addprefix $(BUILD_DIR)/,$(BUILD_TARGET))) all: $(KERNELS) %/kernel.img: %/Makefile - make -C $(dir $@) + @echo 'MAKE TARGET' $(dir $@) + @make -C $(dir $@) %/Makefile: Makefile.build FORCE @mkdir -p $(dir $@) @@ -21,6 +22,6 @@ all: $(KERNELS) clean: $(addsuffix .clean,$(BUILD_TARGET)) %.clean: $(BUILD_DIR)/%/Makefile - make -C $(BUILD_DIR)/$(basename $@) clean + @make -C $(BUILD_DIR)/$(basename $@) clean FORCE: diff --git a/kernel/Makefile.build b/kernel/Makefile.build index c926defc..bf8d09ac 100644 --- a/kernel/Makefile.build +++ b/kernel/Makefile.build @@ -2,32 +2,46 @@ AALBASE=$(SRC)/../../aal/manycore AALDIR=$(AALBASE)/$(TARGET) SRCS=$(wildcard $(SRC)/*.c) OBJS=$(notdir $(patsubst %.c,%.o,$(SRCS))) -CFLAGS=-Wall -nostdlib -nostdinc -isystem $(shell $(CC) -print-file-name=include) -O3 -I$(AALBASE)/generic/include -I$(AALDIR)/include -I$(SRC)/include +CFLAGS=-Wall -nostdlib -nostdinc -isystem $(shell $(CC) -print-file-name=include) -O3 -I$(SRC)/include -mcmodel=kernel LDFLAGS=-e arch_start AALOBJ=$(AALDIR)/aal.o -include $(SRC)/configs/config.$(TARGET) +include $(AALDIR)/Makefile.config +include $(AALBASE)/Makefile.common + +ld_kern_cmd_base = $(LD) $(LDFLAGS) -o $@.elf $^ +mkimage_cmd_base = [ -f $(SRC)/scripts/mkimage.$(TARGET) ] && sh $(SRC)/scripts/mkimage.$(TARGET) '$@.elf' '$@' '$(SRC)' || cp $@.elf $@ + +ifeq ($(V),1) + ld_kern_cmd = $(ld_kern_cmd_base) + mkimage_cmd = $(mkimage_cmd_base) +else + ld_kern_cmd = @echo ' ' LDKERN $@; $(ld_kern_cmd_base) + mkimage_cmd = @echo ' ' MKIMAGE $@; $(mkimage_cmd_base) +endif + all: depend kernel.img kernel.img: $(OBJS) $(AALOBJ) - $(LD) $(LDFLAGS) -o $@.elf $^ - [ -f $(SRC)/scripts/mkimage.$(TARGET) ] && sh $(SRC)/scripts/mkimage.$(TARGET) '$@.elf' '$@' '$(SRC)' || cp $@.elf $@ + $(ld_kern_cmd) + $(mkimage_cmd) clean: $(RM) $(OBJS) kernel.img kernel.img.elf Makefile.dep - make -C $(AALDIR) clean + @make -C $(AALDIR) clean depend: Makefile.dep Makefile.dep: $(SRCS) - $(CC) $(CFLAGS) -MM $(SRCS) > Makefile.dep + $(dep_cmd) $(AALOBJ): FORCE - make -C $(AALDIR) CC=$(CC) LD=$(LD) + @make -C $(AALDIR) CC=$(CC) LD=$(LD) %.o: $(SRC)/%.c - $(CC) $(CFLAGS) -c -o $@ $< + $(cc_cmd) FORCE: diff --git a/kernel/configs/config.knf b/kernel/configs/config.knf index daf3af28..eda458bc 100644 --- a/kernel/configs/config.knf +++ b/kernel/configs/config.knf @@ -2,4 +2,4 @@ CC = /home/shimosawa/cross.knf/bin/x86_64-l1om-linux-gcc LD = /home/shimosawa/cross.knf/bin/x86_64-l1om-linux-ld CFLAGS += -mno-sse -mno-mmx -mno-sse2 -mno-3dnow -LDFLAGS += -m elf_l1om +LDFLAGS += -m elf_l1om -T $(SRC)/knf.lds diff --git a/kernel/knf.lds b/kernel/knf.lds new file mode 100644 index 00000000..48a6be6c --- /dev/null +++ b/kernel/knf.lds @@ -0,0 +1,33 @@ +PHDRS +{ + text PT_LOAD FLAGS(5); + data PT_LOAD FLAGS(7); +} +SECTIONS +{ + . = 0x401000; + _head = .; + + .text : { + *(.text); + } : text + + . = ALIGN(4096); + .data : { + *(.data) + *(.data.*) + } :data + .rodata : { + *(.rodata .rodata.*) + } :data + .bss : { + *(.bss .bss.*) + } + . = ALIGN(4096); + _end = .; + + /DISCARD/ : { + *(.eh_frame) + *(.note.gnu.build-id) + } +} diff --git a/kernel/mee.lds b/kernel/mee.lds index 516df774..69c3ad2a 100644 --- a/kernel/mee.lds +++ b/kernel/mee.lds @@ -1,3 +1,33 @@ -MEMORY { - ram (rwx) : ORIGIN = 0x40001000, LENGTH = 4M +PHDRS +{ + text PT_LOAD FLAGS(5); + data PT_LOAD FLAGS(7); +} +SECTIONS +{ + . = 0x40001000; + _head = .; + + .text : { + *(.text); + } : text + + . = ALIGN(4096); + .data : { + *(.data) + *(.data.*) + } :data + .rodata : { + *(.rodata .rodata.*) + } :data + .bss : { + *(.bss .bss.*) + } + . = ALIGN(4096); + _end = .; + + /DISCARD/ : { + *(.eh_frame) + *(.note.gnu.build-id) + } } diff --git a/kernel/mem.c b/kernel/mem.c new file mode 100644 index 00000000..fb12b3a6 --- /dev/null +++ b/kernel/mem.c @@ -0,0 +1,156 @@ +#include +#include +#include +#include +#include +#include + +static unsigned long pa_start, pa_end; +static unsigned long *page_map; +static aal_spinlock_t page_lock; + +static void reserve_pages(unsigned long start, unsigned long end, int type) +{ + unsigned long *m; + + if (start < pa_start) { + start = pa_start; + } + if (end > pa_end) { + end = pa_end; + } + if (start >= end) { + return; + } + + kprintf("reserved: %lx - %lx ", start, end); + + start = (start - pa_start) >> PAGE_SHIFT; + end = (end - pa_start + PAGE_SIZE - 1) >> PAGE_SHIFT; + + kprintf(" (%d pages)\n", end - start); + + m = page_map + (start >> 6); + /* XXX: Also silly */ + for (; start < end; start++) { + *m |= (1 << (start & 63)); + if ((start & 63) == 63) + m++; + } +} + +static unsigned long count_available_pages(void) +{ + unsigned long i, j, n = 0; + unsigned long size = pa_end - pa_start; + + /* XXX: Very silly counting */ + for (i = 0; i < (size >> PAGE_SHIFT) / 64; i++) { + for (j = 0; j < 64; j++) { + if (!(page_map[i] & (1UL << j))) { + n++; + } + } + } + + return n; +} + +static int is_reserved_page(unsigned long phys) +{ + unsigned long idx; + + if (phys < pa_start || phys >= pa_end) { + return 1; + } else { + idx = (phys - pa_start) >> PAGE_SHIFT; + return !!(page_map[idx >> 6] & (1UL << (idx & 63))); + } +} + +static unsigned long last_ap_pa; + +void *allocate_page(enum aal_mc_ap_flag flag) +{ + unsigned long idx, flags; + + /* XXX: wrap around */ + flags = aal_mc_spinlock_lock(&page_lock); + + while (is_reserved_page(last_ap_pa) && last_ap_pa < pa_end) { + last_ap_pa += PAGE_SIZE; + } + if (last_ap_pa >= pa_end) { + aal_mc_spinlock_unlock(&page_lock, flags); + return NULL; + } + idx = (last_ap_pa - pa_start) >> PAGE_SHIFT; + page_map[idx >> 6] |= (1UL << (idx & 63)); + + aal_mc_spinlock_unlock(&page_lock, flags); + + return phys_to_virt(last_ap_pa); +} + +void free_page(void *va) +{ + unsigned long idx, phys, flags; + + phys = virt_to_phys(va); + if (phys < pa_start || phys >= pa_end) { + return; + } + idx = (phys - pa_start) >> PAGE_SHIFT; + + flags = aal_mc_spinlock_lock(&page_lock); + page_map[idx >> 6] &= ~(1UL << (idx & 63)); + aal_mc_spinlock_unlock(&page_lock, flags); +} + +static struct aal_mc_pa_ops allocator = { + .alloc = allocate_page, + .free = free_page, +}; + +static void page_fault_handler(unsigned long address, void *regs) +{ + kprintf("Page fault for %016lx\n", address); + /* TODO */ + panic("page fault"); +} + +void mem_init(void) +{ + unsigned long pages, page_map_pa; + + aal_mc_spinlock_init(&page_lock); + + pa_start = aal_mc_get_memory_address(AAL_MC_GMA_AVAIL_START, 0); + pa_end = aal_mc_get_memory_address(AAL_MC_GMA_AVAIL_END, 0); + + pa_start &= PAGE_MASK; + pa_end = (pa_end + PAGE_SIZE - 1) & PAGE_MASK; + + pages = (pa_end - pa_start) >> PAGE_SHIFT; + + kprintf("mem_init: %lx - %lx, %d pages\n", pa_start, pa_end, pages); + + page_map_pa = aal_mc_get_memory_address(AAL_MC_GMA_HEAP_START, 0); + page_map = phys_to_virt(page_map_pa); + memset(page_map, 0, pages / 8); + /* TODO: Reserve if 'pages' is not a multiple of 8 */ + + kprintf("page_map: %p\n", page_map); + reserve_pages(page_map_pa, page_map_pa + pages / 8, 0); + + aal_mc_reserve_arch_pages(pa_start, pa_end, reserve_pages); + + kprintf("Available pages: %ld pages\n", count_available_pages()); + last_ap_pa = pa_start; + + /* Notify the aal to use my page allocator */ + aal_mc_set_page_allocator(&allocator); + + /* And prepare some exception handlers */ + aal_mc_set_page_fault_handler(page_fault_handler); +} diff --git a/kernel/setup.c b/kernel/setup.c index a4720f48..524ccd33 100644 --- a/kernel/setup.c +++ b/kernel/setup.c @@ -6,6 +6,7 @@ extern struct aal_kmsg_buf kmsg_buf; extern void arch_init(void); extern void kmsg_init(void); +extern void mem_init(void); int main(void) { @@ -15,9 +16,13 @@ int main(void) arch_init(); - cpu_disable_interrupt(); + mem_init(); + + cpu_enable_interrupt(); + while (1) { cpu_halt(); + kprintf("back from halt.\n"); } return 0; }