···7788[[_TOC_]]
991010+## ToDo
1111+[ ] Revist memory management... I think the code is a bit to simplisic (want to add virtual memory management.)
1212+1013## Notes
1114Since I don't belive there is one perfect source for the relevant topics, I spend a lot of time reading code from others.
1215* [armOS (*Thanos Koutroubas*)](https://github.com/thanoskoutr/armOS): This project is pretty much where I want to be at the end (I guess), and its nice to see what will be necessary for this...
···88set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -T ${ARCH_DIR}/linker.ld")
991010set(SOURCES
1111+ src/kernel/kerio.c
1212+ src/kernel/gpu.c
1313+ src/kernel/mailbox.c
1414+ src/kernel/framebuffer.c
1115 src/kernel/memory.c
1216 src/kernel/atag.c
1317 src/kernel/uart.c
···18221923# Create minimal ELF binary from sources.
2024add_executable(${KERNEL}.elf ${SOURCES})
2121-2222-if(${ARCH} STREQUAL "AARCH_32")
2323- if(${MODEL} STREQUAL "MODEL_0")
2424- target_compile_definitions(${KERNEL}.elf PUBLIC MODEL_0 AARCH_32)
2525- elseif(${MODEL} STREQUAL "MODEL_2")
2626- target_compile_definitions(${KERNEL}.elf PUBLIC MODEL_2 AARCH_32)
2727- endif()
2828-elseif(${ARCH} STREQUAL "AARCH_64")
2929- if(${MODEL} STREQUAL "MODEL_3")
3030- target_compile_definitions(${KERNEL}.elf PUBLIC MODEL_3 AARCH_64)
3131- elseif(${MODEL} STREQUAL "MODEL_4")
3232- target_compile_definitions(${KERNEL}.elf PUBLIC MODEL_4 AARCH_64)
3333- endif()
3434-endif()
35253626# The compiler must make no assumptions about the build.
3727set_target_properties(${KERNEL}.elf PROPERTIES LINK_FLAGS "-nostdlib -nostartfiles")
+16-14
os/include/common/stdlib.h
···33 * @brief Implement basic functionality of the stdint-C-library.
44 */
5566+#include <stddef.h> // defines NULL and size_t
77+#include <stdint.h>
68#ifndef STDLIB_H
79#define STDLIB_H
81099-#include <stddef.h> // defines NULL and size_t
1111+#define MIN(x,y) ((x < y ? x : y))
1212+#define MAX(x,y) ((x < y ? y : x))
1313+1414+typedef struct divmod_result {
1515+ uint32_t div;
1616+ uint32_t mod;
1717+} divmod_t;
1818+1919+divmod_t divmod(uint32_t dividend, uint32_t divisor);
2020+uint32_t div(uint32_t dividend, uint32_t divisor);
10211122/**
1223 * @brief Fills the first @a n bytes of the memory area pointed to by @a s with the constant byte @a c.
1324 * @return A pointer to the memory area s.
1425 */
1515-void* memset(void* s, int c, size_t n);
2626+void* memset(void * dest, int c, unsigned int bytes);
16271728/**
1829 * @brief Copies @a n bytes from memory area @a src to memory area @a dest. The memory areas must not overlap.
1930 * @return A pointer to dest.
2031 */
2121-void* memcpy(void* dest, const void* src, size_t n);
3232+void* memcpy(void * dest, const void * src, unsigned int bytes);
22332334/**
2435 * @brief int -> str(int)
···2839 * @param value Value to be converted to a string.
2940 * @return A pointer to the resulting null-terminated string.
3041 */
3131-char* itoa(int value);
4242+char* itoa(int value, int base);
32433333-/*
3434- * Converts an int to a null-terminated string using the specified base.
3535- * @param value Value to be converted to a string.
3636- * @param base Numerical base used to represent the value as a string.
3737- * Where 10 means decimal base, 16 hexadecimal, 8 octal, and 2 binary.
3838- * (Only base 10 supported for now)
3939- * @return A pointer to the resulting null-terminated string.
4040- */
4141-// char *itoa(int value, int base);
42444345/**
4446 * @brief str -> int
···4850 * @return The converted integral number as an int value.
4951 * If no valid conversion could be performed, it returns zero.
5052 */
5151-int atoi(const char* str);
5353+int atoi(char* str);
525453555456/**
+1-1
os/include/common/string.h
···33 * @brief Some basic functions to manipulate strings.
44 */
5566+#include <stddef.h> // defines NULL and size_t
67#ifndef STRING_H
78#define STRING_H
8999-#include <stddef.h> // defines NULL and size_t
10101111/**
1212 * @brief Calculates the length of the string pointed to by @a s, excluding the terminating null byte ('\0').
···11+#ifndef STDIO_H
22+#define STDIO_H
33+44+char getc(void);
55+void putc(char c);
66+77+void puts(const char * s);
88+99+// This version of gets copies until newline, replacing newline with null char, or until buflen.
1010+// whichever comes first
1111+void gets(char * buf, int buflen);
1212+1313+void printf(const char * fmt, ...);
1414+1515+#endif
+108
os/include/kernel/mailbox.h
···11+#include <stdint.h>
22+#include "peripherals/base.h"
33+#ifndef MAILBOX_H
44+#define MAILBOX_H
55+66+#define MAILBOX_OFFSET 0xB880
77+88+#define MAILBOX_BASE MMIO_BASE + MAILBOX_OFFSET
99+#define MAIL0_READ (((mail_message_t *)(0x00 + MAILBOX_BASE)))
1010+#define MAIL0_STATUS (((mail_status_t *)(0x18 + MAILBOX_BASE)))
1111+#define MAIL0_WRITE (((mail_message_t *)(0x20 + MAILBOX_BASE)))
1212+#define PROPERTY_CHANNEL 8
1313+#define FRAMEBUFFER_CHANNEL 1
1414+1515+typedef struct {
1616+ uint8_t channel: 4;
1717+ uint32_t data: 28;
1818+} mail_message_t;
1919+2020+typedef struct {
2121+ uint32_t reserved: 30;
2222+ uint8_t empty: 1;
2323+ uint8_t full:1;
2424+} mail_status_t;
2525+2626+mail_message_t mailbox_read(int channel);
2727+void mailbox_send(mail_message_t msg, int channel);
2828+2929+/**
3030+ * A property message can either be a request, or a response, and a response can be successfull or an error
3131+ */
3232+typedef enum {
3333+ REQUEST = 0x00000000,
3434+ RESPONSE_SUCCESS = 0x80000000,
3535+ RESPONSE_ERROR = 0x80000001
3636+} buffer_req_res_code_t;
3737+3838+3939+/*
4040+ * A buffer that holds many property messages.
4141+ * The last tag must be a 4 byte zero, and then padding to make the whole thing 4 byte aligned
4242+ */
4343+typedef struct {
4444+ uint32_t size; // Size includes the size itself
4545+ buffer_req_res_code_t req_res_code;
4646+ uint32_t tags[1]; // A concatenated sequence of tags. will use overrun to make large enough
4747+} property_message_buffer_t;
4848+4949+5050+/**
5151+ * A message is identified by a tag. These are some of the possible tags
5252+ */
5353+typedef enum {
5454+ NULL_TAG = 0,
5555+ FB_ALLOCATE_BUFFER = 0x00040001,
5656+ FB_RELESE_BUFFER = 0x00048001,
5757+ FB_GET_PHYSICAL_DIMENSIONS = 0x00040003,
5858+ FB_SET_PHYSICAL_DIMENSIONS = 0x00048003,
5959+ FB_GET_VIRTUAL_DIMENSIONS = 0x00040004,
6060+ FB_SET_VIRTUAL_DIMENSIONS = 0x00048004,
6161+ FB_GET_BITS_PER_PIXEL = 0x00040005,
6262+ FB_SET_BITS_PER_PIXEL = 0x00048005,
6363+ FB_GET_BYTES_PER_ROW = 0x00040008
6464+} property_tag_t;
6565+6666+/**
6767+ * For each possible tag, we create a struct corresponding to the request value buffer, and the response value buffer
6868+ */
6969+7070+typedef struct {
7171+ void * fb_addr;
7272+ uint32_t fb_size;
7373+} fb_allocate_res_t;
7474+7575+typedef struct {
7676+ uint32_t width;
7777+ uint32_t height;
7878+} fb_screen_size_t;
7979+8080+8181+/*
8282+ * The value buffer can be any one of these types
8383+ */
8484+typedef union {
8585+ uint32_t fb_allocate_align;
8686+ fb_allocate_res_t fb_allocate_res;
8787+ fb_screen_size_t fb_screen_size;
8888+ uint32_t fb_bits_per_pixel;
8989+ uint32_t fb_bytes_per_row;
9090+} value_buffer_t;
9191+9292+/*
9393+ * A message_buffer can contain any number of these
9494+ */
9595+typedef struct {
9696+ property_tag_t proptag;
9797+ value_buffer_t value_buffer;
9898+} property_message_tag_t;
9999+100100+101101+/**
102102+ * given an array of tags, will send all of the tags given, and will populate that array with the responses.
103103+ * the given array should end with a "null tag" with the proptag field set to 0.
104104+ * returns 0 on success
105105+ */
106106+int send_messages(property_message_tag_t * tags);
107107+108108+#endif // MAILBOX_H
···66 * > Also all three are controlled by the auxiliary enable register.
77 */
8899+#include "gpio.h"
910#ifndef AUX_H
1011#define AUX_H
1111-1212-#include "gpio.h"
13121413/**
1514 * @brief Enum containg all the relevant addresses. The offset is again the same for all RPi's, but the base address is not.