minimalist kernel and OS. targets x86_64 and the pinephone (aarch64)
osdev kernel

kernel: add base, wip fb device

0039766.xyz 8cf3065a 315dd098

Waiting for spindle ...
+533
+1
.gitignore
··· 1 + /kernel/build-*/
+4
kernel/.gitignore
··· 1 + subprojects/.wraplock 2 + subprojects/cc-runtime 3 + subprojects/freestnd-c-hdrs 4 + subprojects/limine-protocol
+13
kernel/conf/gcc-aarch64.ini
··· 1 + [binaries] 2 + c = 'aarch64-elf-gcc' 3 + ar = 'aarch64-elf-gcc-ar' 4 + strip = 'aarch64-elf-strip' 5 + 6 + [properties] 7 + ld = 'aarch64-elf-ld' 8 + 9 + [host_machine] 10 + system = 'none' 11 + cpu_family = 'aarch64' 12 + cpu = 'unknown' 13 + endian = 'little'
+13
kernel/conf/gcc-x86_64.ini
··· 1 + [binaries] 2 + c = 'x86_64-elf-gcc' 3 + ar = 'x86_64-elf-gcc-ar' 4 + strip = 'x86_64-elf-strip' 5 + 6 + [properties] 7 + ld = 'x86_64-elf-ld' 8 + 9 + [host_machine] 10 + system = 'none' 11 + cpu_family = 'x86_64' 12 + cpu = 'x86_64' 13 + endian = 'little'
+13
kernel/conf/host-aarch64.ini
··· 1 + [binaries] 2 + c = 'cc' 3 + ar = 'ar' 4 + strip = 'strip' 5 + 6 + [properties] 7 + ld = 'ld' 8 + 9 + [host_machine] 10 + system = 'none' 11 + cpu_family = 'aarch64' 12 + cpu = 'unknown' 13 + endian = 'little'
+13
kernel/conf/host-x86_64.ini
··· 1 + [binaries] 2 + c = 'cc' 3 + ar = 'ar' 4 + strip = 'strip' 5 + 6 + [properties] 7 + ld = 'ld' 8 + 9 + [host_machine] 10 + system = 'none' 11 + cpu_family = 'x86_64' 12 + cpu = 'x86_64' 13 + endian = 'little'
+13
kernel/conf/llvm-aarch64.ini
··· 1 + [binaries] 2 + c = 'clang' 3 + ar = 'llvm-ar' 4 + strip = 'llvm-strip' 5 + 6 + [properties] 7 + ld = 'ld.lld' 8 + 9 + [host_machine] 10 + system = 'none' 11 + cpu_family = 'aarch64' 12 + cpu = 'unknown' 13 + endian = 'little'
+13
kernel/conf/llvm-x86_64.ini
··· 1 + [binaries] 2 + c = 'clang' 3 + ar = 'llvm-ar' 4 + strip = 'llvm-strip' 5 + 6 + [properties] 7 + ld = 'ld.lld' 8 + 9 + [host_machine] 10 + system = 'none' 11 + cpu_family = 'x86_64' 12 + cpu = 'x86_64' 13 + endian = 'little'
+74
kernel/link/aarch64.lds
··· 1 + /* Tell the linker that we want an aarch64 ELF64 output file */ 2 + OUTPUT_FORMAT(elf64-littleaarch64) 3 + 4 + /* We want the symbol kmain to be our entry point */ 5 + ENTRY(kmain) 6 + 7 + /* Define the program headers we want so the bootloader gives us the right */ 8 + /* MMU permissions; this also allows us to exert more control over the linking */ 9 + /* process. */ 10 + PHDRS 11 + { 12 + limine_requests PT_LOAD; 13 + text PT_LOAD; 14 + rodata PT_LOAD; 15 + data PT_LOAD; 16 + } 17 + 18 + SECTIONS 19 + { 20 + /* We want to be placed in the topmost 2GiB of the address space, for optimisations */ 21 + /* and because that is what the Limine spec mandates. */ 22 + /* Any address in this region will do, but often 0xffffffff80000000 is chosen as */ 23 + /* that is the beginning of the region. */ 24 + . = 0xffffffff80000000; 25 + 26 + /* Define a section to contain the Limine requests and assign it to its own PHDR */ 27 + .limine_requests : { 28 + KEEP(*(.limine_requests_start)) 29 + KEEP(*(.limine_requests)) 30 + KEEP(*(.limine_requests_end)) 31 + } :limine_requests 32 + 33 + /* Move to the next memory page for .text */ 34 + . = ALIGN(CONSTANT(MAXPAGESIZE)); 35 + 36 + .text : { 37 + *(.text .text.*) 38 + } :text 39 + 40 + /* Move to the next memory page for .rodata */ 41 + . = ALIGN(CONSTANT(MAXPAGESIZE)); 42 + 43 + .rodata : { 44 + *(.rodata .rodata.*) 45 + } :rodata 46 + 47 + /* Add a .note.gnu.build-id output section in case a build ID flag is added to the */ 48 + /* linker command. */ 49 + .note.gnu.build-id : { 50 + *(.note.gnu.build-id) 51 + } :rodata 52 + 53 + /* Move to the next memory page for .data */ 54 + . = ALIGN(CONSTANT(MAXPAGESIZE)); 55 + 56 + .data : { 57 + *(.data .data.*) 58 + } :data 59 + 60 + /* NOTE: .bss needs to be the last thing mapped to :data, otherwise lots of */ 61 + /* unnecessary zeros will be written to the binary. */ 62 + /* If you need, for example, .init_array and .fini_array, those should be placed */ 63 + /* above this. */ 64 + .bss : { 65 + *(.bss .bss.*) 66 + *(COMMON) 67 + } :data 68 + 69 + /* Discard .note.* and .eh_frame* since they may cause issues on some hosts. */ 70 + /DISCARD/ : { 71 + *(.eh_frame*) 72 + *(.note .note.*) 73 + } 74 + }
+74
kernel/link/x86_64.lds
··· 1 + /* Tell the linker that we want an x86_64 ELF64 output file */ 2 + OUTPUT_FORMAT(elf64-x86-64) 3 + 4 + /* We want the symbol kmain to be our entry point */ 5 + ENTRY(kmain) 6 + 7 + /* Define the program headers we want so the bootloader gives us the right */ 8 + /* MMU permissions; this also allows us to exert more control over the linking */ 9 + /* process. */ 10 + PHDRS 11 + { 12 + limine_requests PT_LOAD; 13 + text PT_LOAD; 14 + rodata PT_LOAD; 15 + data PT_LOAD; 16 + } 17 + 18 + SECTIONS 19 + { 20 + /* We want to be placed in the topmost 2GiB of the address space, for optimisations */ 21 + /* and because that is what the Limine spec mandates. */ 22 + /* Any address in this region will do, but often 0xffffffff80000000 is chosen as */ 23 + /* that is the beginning of the region. */ 24 + . = 0xffffffff80000000; 25 + 26 + /* Define a section to contain the Limine requests and assign it to its own PHDR */ 27 + .limine_requests : { 28 + KEEP(*(.limine_requests_start)) 29 + KEEP(*(.limine_requests)) 30 + KEEP(*(.limine_requests_end)) 31 + } :limine_requests 32 + 33 + /* Move to the next memory page for .text */ 34 + . = ALIGN(CONSTANT(MAXPAGESIZE)); 35 + 36 + .text : { 37 + *(.text .text.*) 38 + } :text 39 + 40 + /* Move to the next memory page for .rodata */ 41 + . = ALIGN(CONSTANT(MAXPAGESIZE)); 42 + 43 + .rodata : { 44 + *(.rodata .rodata.*) 45 + } :rodata 46 + 47 + /* Add a .note.gnu.build-id output section in case a build ID flag is added to the */ 48 + /* linker command. */ 49 + .note.gnu.build-id : { 50 + *(.note.gnu.build-id) 51 + } :rodata 52 + 53 + /* Move to the next memory page for .data */ 54 + . = ALIGN(CONSTANT(MAXPAGESIZE)); 55 + 56 + .data : { 57 + *(.data .data.*) 58 + } :data 59 + 60 + /* NOTE: .bss needs to be the last thing mapped to :data, otherwise lots of */ 61 + /* unnecessary zeros will be written to the binary. */ 62 + /* If you need, for example, .init_array and .fini_array, those should be placed */ 63 + /* above this. */ 64 + .bss : { 65 + *(.bss .bss.*) 66 + *(COMMON) 67 + } :data 68 + 69 + /* Discard .note.* and .eh_frame* since they may cause issues on some hosts. */ 70 + /DISCARD/ : { 71 + *(.eh_frame*) 72 + *(.note .note.*) 73 + } 74 + }
+153
kernel/meson.build
··· 1 + project( 2 + 'kernel', 3 + 'c', 4 + meson_version: '>=0.60.0', 5 + default_options: [ 6 + 'c_std=gnu11', 7 + 'b_staticpic=false', 8 + 'b_pie=false', 9 + 'b_lto=false', 10 + 'buildtype=debugoptimized', 11 + 'warning_level=2', 12 + ], 13 + ) 14 + 15 + target_arch = host_machine.cpu_family() 16 + 17 + c_std = 'gnu11' 18 + supported_archs = ['aarch64', 'x86_64'] 19 + unsupported_options = ['b_staticpic', 'b_pie', 'b_lto'] 20 + 21 + include_directories = include_directories( 22 + 'source', 23 + 'source/hal', 24 + ) 25 + 26 + sources = files( 27 + 'source/init.c', 28 + ) 29 + 30 + subdir('source/rtl') 31 + subdir('source/dev') 32 + subdir(f'source/hal/@target_arch@') 33 + 34 + if not meson.is_cross_build() 35 + error('Kernel can only be cross-compiled') 36 + endif 37 + 38 + dependencies = [ 39 + subproject('cc-runtime').get_variable('cc_runtime_dep'), 40 + subproject('freestnd-c-hdrs').get_variable('freestnd_c_hdrs_dep'), 41 + subproject('limine-protocol').get_variable('limine_protocol_dep'), 42 + ] 43 + 44 + exec_name = meson.project_name() 45 + 46 + if target_arch not in supported_archs 47 + error('Unsupported architecture: ' + target_arch) 48 + endif 49 + 50 + if get_option('c_std') != c_std 51 + error(f'@exec_name@ needs to build as @c_std@') 52 + endif 53 + 54 + foreach option : unsupported_options 55 + if get_option(option) 56 + error(f'@exec_name@ does not support building with @option@, set @option@ to false') 57 + endif 58 + endforeach 59 + 60 + 61 + c_compiler = meson.get_compiler('c') 62 + 63 + if meson.has_external_property('ld') 64 + ld = meson.get_external_property('ld') 65 + else 66 + ld = '' 67 + if c_compiler.get_id() == 'clang' 68 + ld_prog = find_program('ld.lld', required: false) 69 + if ld_prog.found() 70 + ld = ld_prog.full_path() 71 + endif 72 + endif 73 + if ld == '' 74 + ld = 'ld' 75 + endif 76 + 77 + if not meson.is_cross_build() 78 + ld_env = run_command('sh', '-c', 'printf "%s\\n" "$LD"', check: true).stdout().strip() 79 + if ld_env != '' 80 + ld = ld_env 81 + endif 82 + endif 83 + endif 84 + 85 + if ld == 'ld' 86 + ld = 'ld.bfd' 87 + endif 88 + 89 + c_args = [] 90 + link_args = run_command('sh', '-c', 'printf "%s\\n" "$LDFLAGS"', check: true).stdout().split() 91 + 92 + if c_compiler.get_id() == 'clang' 93 + c_args += ['-target', f'@target_arch@-unknown-none-elf'] 94 + endif 95 + 96 + link_args += [ 97 + '-nostdlib', 98 + '-static', 99 + '-z', 'max-page-size=0x1000', 100 + '--gc-sections', 101 + '-T', meson.current_source_dir() / f'link/@target_arch@.lds', 102 + ] 103 + 104 + 105 + if target_arch == 'x86_64' 106 + c_args += [ 107 + '-m64', 108 + '-march=x86-64', 109 + '-mabi=sysv', 110 + '-mgeneral-regs-only', 111 + '-mno-red-zone', 112 + '-mcmodel=kernel', 113 + ] 114 + 115 + link_args += [ 116 + '-m', 'elf_x86_64', 117 + ] 118 + elif target_arch == 'aarch64' 119 + c_args += [ 120 + '-mcpu=generic', 121 + '-march=armv8-a+nofp+nosimd', 122 + '-mgeneral-regs-only', 123 + ] 124 + 125 + link_args += [ 126 + '-m', 'aarch64elf', 127 + ] 128 + endif 129 + 130 + output_static_lib = static_library( 131 + exec_name, 132 + sources: sources, 133 + include_directories: include_directories, 134 + dependencies: dependencies, 135 + c_args: c_args, 136 + install: false, 137 + ) 138 + 139 + custom_target( 140 + output: exec_name + '-' + target_arch, 141 + input: output_static_lib, 142 + command: [ 143 + ld, 144 + link_args, 145 + '--whole-archive', 146 + '@INPUT@', 147 + '--no-whole-archive', 148 + '-o', '@OUTPUT@', 149 + ], 150 + install: true, 151 + install_dir: get_option('datadir') / exec_name, 152 + install_mode: 'rw-r--r--', 153 + )
+4
kernel/source/dev/fb/fb.c
··· 1 + #include <stddef.h> 2 + #include <stdbool.h> 3 + #include <limine.h> 4 + #include <dev/fb/fb.h>
kernel/source/dev/fb/fb.h

This is a binary file and will not be displayed.

+2
kernel/source/dev/meson.build
··· 1 + sources += meson.current_source_dir() / 'fb/fb.c' 2 + sources += meson.current_source_dir() / 'term/term.c'
kernel/source/dev/term/term.c

This is a binary file and will not be displayed.

kernel/source/dev/term/term.h

This is a binary file and will not be displayed.

+9
kernel/source/hal/aarch64/init.c
··· 1 + #include <stdint.h> 2 + #include <stddef.h> 3 + #include <stdbool.h> 4 + 5 + void halt_forever(void) { 6 + for (;;) { 7 + asm ("wfi"); 8 + } 9 + }
+1
kernel/source/hal/aarch64/meson.build
··· 1 + sources += meson.current_source_dir() / 'init.c'
+5
kernel/source/hal/main.h
··· 1 + #include <stdint.h> 2 + #include <stddef.h> 3 + #include <stdbool.h> 4 + 5 + void halt_forever(void);
+9
kernel/source/hal/x86_64/init.c
··· 1 + #include <stdint.h> 2 + #include <stddef.h> 3 + #include <stdbool.h> 4 + 5 + void halt_forever(void) { 6 + for (;;) { 7 + asm ("hlt"); 8 + } 9 + }
+1
kernel/source/hal/x86_64/meson.build
··· 1 + sources += meson.current_source_dir() / 'init.c'
+10
kernel/source/init.c
··· 1 + #include <stdint.h> 2 + #include <stddef.h> 3 + #include <stdbool.h> 4 + #include <limine.h> 5 + #include <hal/main.h> 6 + 7 + 8 + void kmain(void) { 9 + halt_forever(); 10 + }
+1
kernel/source/rtl/meson.build
··· 1 + sources += meson.current_source_dir() / 'strings.c'
+55
kernel/source/rtl/strings.c
··· 1 + #include <stdint.h> 2 + #include <stddef.h> 3 + #include <stdbool.h> 4 + 5 + 6 + void *memcpy(void *restrict dest, const void *restrict src, size_t n) { 7 + uint8_t *restrict pdest = (uint8_t *restrict)dest; 8 + const uint8_t *restrict psrc = (const uint8_t *restrict)src; 9 + 10 + for (size_t i = 0; i < n; i++) { 11 + pdest[i] = psrc[i]; 12 + } 13 + 14 + return dest; 15 + } 16 + 17 + void *memset(void *s, int c, size_t n) { 18 + uint8_t *p = (uint8_t *)s; 19 + 20 + for (size_t i = 0; i < n; i++) { 21 + p[i] = (uint8_t)c; 22 + } 23 + 24 + return s; 25 + } 26 + 27 + void *memmove(void *dest, const void *src, size_t n) { 28 + uint8_t *pdest = (uint8_t *)dest; 29 + const uint8_t *psrc = (const uint8_t *)src; 30 + 31 + if (src > dest) { 32 + for (size_t i = 0; i < n; i++) { 33 + pdest[i] = psrc[i]; 34 + } 35 + } else if (src < dest) { 36 + for (size_t i = n; i > 0; i--) { 37 + pdest[i-1] = psrc[i-1]; 38 + } 39 + } 40 + 41 + return dest; 42 + } 43 + 44 + int memcmp(const void *s1, const void *s2, size_t n) { 45 + const uint8_t *p1 = (const uint8_t *)s1; 46 + const uint8_t *p2 = (const uint8_t *)s2; 47 + 48 + for (size_t i = 0; i < n; i++) { 49 + if (p1[i] != p2[i]) { 50 + return p1[i] < p2[i] ? -1 : 1; 51 + } 52 + } 53 + 54 + return 0; 55 + }
+5
kernel/subprojects/cc-runtime.wrap
··· 1 + [wrap-git] 2 + url = https://codeberg.org/OSDev/cc-runtime.git 3 + revision = dae79833b57a01b9fd3e359ee31def69f5ae899b 4 + depth = 1 5 + patch_directory = cc-runtime
+5
kernel/subprojects/flanterm.wrap
··· 1 + [wrap-git] 2 + url = https://codeberg.org/Mintsuki/Flanterm.git 3 + revision = f9d424145bdde18872714094434797e2f44ff5b4 4 + depth = 1 5 + patch_directory = flanterm
+5
kernel/subprojects/freestnd-c-hdrs.wrap
··· 1 + [wrap-git] 2 + url = https://codeberg.org/OSDev/freestnd-c-hdrs-0bsd.git 3 + revision = 5df91dd7062ad0c54f5ffd86193bb9f008677631 4 + depth = 1 5 + patch_directory = freestnd-c-hdrs
+5
kernel/subprojects/limine-protocol.wrap
··· 1 + [wrap-git] 2 + url = https://codeberg.org/Limine/limine-protocol.git 3 + revision = 8a888d7ab3b274fad1a357a922e799fc2ff20729 4 + depth = 1 5 + patch_directory = limine-protocol
+7
kernel/subprojects/packagefiles/cc-runtime/meson.build
··· 1 + project('cc-runtime', 'c') 2 + 3 + cc_runtime_dep = declare_dependency( 4 + sources: files( 5 + 'src/cc-runtime.c', 6 + ), 7 + )
+11
kernel/subprojects/packagefiles/flanterm/meson.build
··· 1 + project('flanterm', 'c') 2 + 3 + flanterm_dep = declare_dependency( 4 + sources: files( 5 + 'src/flanterm.c', 6 + 'src/flanterm_backends/fb.c', 7 + ), 8 + include_directories: include_directories( 9 + 'src/', 10 + ), 11 + )
+7
kernel/subprojects/packagefiles/freestnd-c-hdrs/meson.build
··· 1 + project('freestnd-c-hdrs', 'c') 2 + 3 + freestnd_c_hdrs_dep = declare_dependency( 4 + include_directories: include_directories( 5 + 'include', 6 + ), 7 + )
+7
kernel/subprojects/packagefiles/limine-protocol/meson.build
··· 1 + project('limine-protocol', 'c') 2 + 3 + limine_protocol_dep = declare_dependency( 4 + include_directories: include_directories( 5 + 'include', 6 + ), 7 + )