diff --git a/bin/build b/bin/build index eaacbdd..8bea109 100755 --- a/bin/build +++ b/bin/build @@ -1,7 +1,15 @@ #!/bin/sh cd src/lib/c +make clean make cd ../.. + cd kernel +make clean + +cd driver/bcm2835 +make + +cd ../.. make diff --git a/src/kernel/Makefile b/src/kernel/Makefile index 1c46c55..033ae96 100644 --- a/src/kernel/Makefile +++ b/src/kernel/Makefile @@ -17,8 +17,8 @@ $(BUILD)/kernel.img.asm: $(BUILD)/kernel.img $(BUILD)/kernel.listing: $(BUILD)/kernel.elf $(COMPILER_PREFIX)-objdump -d $< > $(BUILD)/kernel.listing -$(BUILD)/kernel.elf: $(BUILD) Makefile kernel.ld $(BUILD)/bootstrap.o $(BUILD)/main.o $(BUILD)/driver/bcm2835/gpio $(BUILD)/driver/bcm2835/gpio/gpio.o $(BUILD)/driver/bcm2835/uart $(BUILD)/driver/bcm2835/uart/uart.o - $(LINK) -o $(BUILD)/kernel.elf -T kernel.ld $(BUILD)/bootstrap.o $(BUILD)/main.o $(BUILD)/driver/bcm2835/gpio/gpio.o $(BUILD)/driver/bcm2835/uart/uart.o $(BUILD_PREFIX)/lib/c.o +$(BUILD)/kernel.elf: $(BUILD) Makefile kernel.ld $(BUILD)/bootstrap.o $(BUILD)/main.o + $(LINK) -o $(BUILD)/kernel.elf -T kernel.ld $(BUILD)/bootstrap.o $(BUILD)/main.o $(BUILD)/driver/bcm2835.o $(BUILD_PREFIX)/lib/c.o $(BUILD)/%.o: %.s $(CC) -o $@ $< diff --git a/src/kernel/driver/bcm2835/Makefile b/src/kernel/driver/bcm2835/Makefile new file mode 100644 index 0000000..cfc0e58 --- /dev/null +++ b/src/kernel/driver/bcm2835/Makefile @@ -0,0 +1,19 @@ +TOOLCHAIN = ../../../../bin/toolchain/bin +COMPILER_PREFIX = $(TOOLCHAIN)/arm-none-eabi +CC = $(COMPILER_PREFIX)-gcc --std=gnu11 -I ../../../../include/libc -g -c +PACK = $(COMPILER_PREFIX)-ar rs +BUILD_PREFIX = ../../../../build/idaeus/kernel/driver +BUILD = $(BUILD_PREFIX)/bcm2835 +VPATH = framebuffer gpio mailbox uart + +$(BUILD_PREFIX)/bcm2835.o: $(BUILD)/framebuffer/framebuffer.o $(BUILD)/gpio/gpio.o $(BUILD)/mailbox/mailbox.o $(BUILD)/uart/uart.o + $(PACK) $(BUILD_PREFIX)/bcm2835.o $^ + +$(BUILD)/%.o: %.c $(dir $@) + mkdir -p $(dir $@) + $(CC) -o $@ $< + + +clean: + rm -rf $(BUILD) + rm -f $(BUILD_PREFIX)/bcm2835.o diff --git a/src/kernel/driver/bcm2835/framebuffer/framebuffer.c b/src/kernel/driver/bcm2835/framebuffer/framebuffer.c new file mode 100644 index 0000000..78d3f3b --- /dev/null +++ b/src/kernel/driver/bcm2835/framebuffer/framebuffer.c @@ -0,0 +1,34 @@ +#include "framebuffer.h" +#include "../mailbox/mailbox.h" + +#include + +int framebuffer_init(frame_buffer_info_t* frame_buffer_info, uint32_t width, uint32_t height, uint32_t depth) { + frame_buffer_info->physical_width = 1024; + frame_buffer_info->physical_height = 768; + frame_buffer_info->virtual_width = 1024; + frame_buffer_info->virtual_height = 768; + frame_buffer_info->gpu_pitch = 0; + frame_buffer_info->bit_depth = 16; + frame_buffer_info->x = 0; + frame_buffer_info->y = 0; + frame_buffer_info->gpu_pointer = 0; + frame_buffer_info->gpu_size = 0; + + mailbox_write(1, frame_buffer_info); + + /* + * Check status + */ + int status; + + if (mailbox_read(1, &status) != 0) { + puts("[ERORR] framebuffer_init: failed to read form mail box."); + return -1; + } else if (status != 0) { + puts("[ERORR] framebuffer_init: failed to set up."); + return -2; + } + + return 0; +} diff --git a/src/kernel/driver/bcm2835/framebuffer/framebuffer.h b/src/kernel/driver/bcm2835/framebuffer/framebuffer.h new file mode 100644 index 0000000..e491260 --- /dev/null +++ b/src/kernel/driver/bcm2835/framebuffer/framebuffer.h @@ -0,0 +1,21 @@ +#ifndef KERNEL_DRIVER_BCM2835_FRAMEBUFFER_FRAMEBUFFER_H +#define KERNEL_DRIVER_BCM2835_FRAMEBUFFER_FRAMEBUFFER_H + +#include + +typedef struct { + uint32_t physical_width; + uint32_t physical_height; + uint32_t virtual_width; + uint32_t virtual_height; + uint32_t gpu_pitch; + uint32_t bit_depth; + uint32_t x; + uint32_t y; + uint32_t gpu_pointer; + uint32_t gpu_size; +} __attribute__((packed)) frame_buffer_info_t; + +int framebuffer_init(frame_buffer_info_t* frame_buffer_info, uint32_t width, uint32_t height, uint32_t depth); + +#endif diff --git a/src/kernel/driver/bcm2835/mailbox/mailbox.c b/src/kernel/driver/bcm2835/mailbox/mailbox.c new file mode 100644 index 0000000..4deeb97 --- /dev/null +++ b/src/kernel/driver/bcm2835/mailbox/mailbox.c @@ -0,0 +1,65 @@ +#include "mailbox.h" +#include + +/* + * Address | Size | Name | Description | R/W + * ---------|------|---------------|-----------------------------|---- + * 2000B880 | 4 | Read | Receiving mail. | R + * 2000B890 | 4 | Poll | Receive without retrieving. | R + * 2000B894 | 4 | Sender | Sender information. | R + * 2000B898 | 4 | Status | Information. | R + * 2000B89C | 4 | Configuration | Settings. | RW + * 2000B8A0 | 4 | Write | Sending mail. | W + */ + +#define MAILBOX_BASE_ADDRESS 0x2000B880 +const uint32_t MAILBOX_READ_ADDRESS = MAILBOX_BASE_ADDRESS; +const uint32_t MAILBOX_POLL_ADDRESS = MAILBOX_BASE_ADDRESS + 0x10; +const uint32_t MAILBOX_SENDER_ADDRESS = MAILBOX_BASE_ADDRESS + 0x14; +const uint32_t MAILBOX_STATUS_ADDRESS = MAILBOX_BASE_ADDRESS + 0x18; +const uint32_t MAILBOX_CONFIG_ADDRESS = MAILBOX_BASE_ADDRESS + 0x1C; +const uint32_t MAILBOX_WRITE_ADDRESS = MAILBOX_BASE_ADDRESS + 0x20; + +void mailbox_write(uint8_t mailbox, void* mail) { + if ((uint32_t)mail & 0xF != 0) { + puts("[ERROR] mailbox_write: pointer not aligned."); + return; + } + + if (mailbox > 15) { + puts("[ERROR] mailbox_write: mailbox > 15."); + return; + } + puts("write"); + uint32_t* write = (uint32_t*)MAILBOX_WRITE_ADDRESS; + uint32_t* status = (uint32_t*)MAILBOX_STATUS_ADDRESS; + mail += 0x40000000 + mailbox; + + while (*status & 0x80000000 == 0) { + + } + + *write = mail; + +} + +int mailbox_read(uint8_t mailbox, uint32_t* mail) { + if (mailbox > 15) { + puts("[ERROR] mailbox_write: mailbox > 15."); + return -1; + } + + uint32_t* read = (uint32_t*)MAILBOX_READ_ADDRESS; + uint32_t* status = (uint32_t*)MAILBOX_STATUS_ADDRESS; + + //do { + //while ((*status & 0x40000000) == 0) { + + //} + + *mail = *read; + //} while ((*mail & 0xF) != mailbox); + + *mail &= 0xFFFFFFF0; + return 0; +} diff --git a/src/kernel/driver/bcm2835/mailbox/mailbox.h b/src/kernel/driver/bcm2835/mailbox/mailbox.h new file mode 100644 index 0000000..6a05031 --- /dev/null +++ b/src/kernel/driver/bcm2835/mailbox/mailbox.h @@ -0,0 +1,9 @@ +#ifndef KERNEL_DRIVER_BCM2835_MAILBOX_MAILBOX_H +#define KERNEL_DRIVER_BCM2835_MAILBOX_MAILBOX_H + +#include + +void mailbox_write(uint8_t mailbox, void* mail); +int mailbox_read(uint8_t mailbox, uint32_t* mail); + +#endif diff --git a/src/kernel/main.c b/src/kernel/main.c index 3d3594b..df449b0 100644 --- a/src/kernel/main.c +++ b/src/kernel/main.c @@ -1,8 +1,26 @@ #include #include "driver/bcm2835/uart/uart.h" +#include "driver/bcm2835/framebuffer/framebuffer.h" + + void main(void) { uart_init(); libc_init_putc(uart_putc); - puts("Hello World!"); + puts("framebuffer init"); + frame_buffer_info_t frame_buffer_info; + framebuffer_init(&frame_buffer_info, 1024, 768, 16); + puts("draw"); + + uint16_t* img = frame_buffer_info.gpu_pointer; + uint16_t color = 0; + + for (uint32_t x = 0; x < frame_buffer_info.physical_width; x++) { + for (uint32_t y = 0; y < frame_buffer_info.physical_height; y++) { + *img = color++; + img += 2; + } + } + + puts("terminate"); }