Separate arch-specific and arch-agnostic code
This commit is contained in:
		
							parent
							
								
									b1011b780f
								
							
						
					
					
						commit
						49d6f19516
					
				
					 4 changed files with 120 additions and 105 deletions
				
			
		
							
								
								
									
										16
									
								
								build.zig
									
										
									
									
									
								
							
							
						
						
									
										16
									
								
								build.zig
									
										
									
									
									
								
							|  | @ -8,7 +8,7 @@ const ArrayList = std.ArrayList; | |||
| const warn = std.debug.warn; | ||||
| const mem = std.mem; | ||||
| 
 | ||||
| const src_files = [][]const u8{"kernel/kmain"}; | ||||
| var src_files: ArrayList([]const u8) = undefined; | ||||
| 
 | ||||
| fn concat(allocator: *std.mem.Allocator, str: []const u8, str2: []const u8) !std.Buffer { | ||||
|     var b = try std.Buffer.init(allocator, str); | ||||
|  | @ -17,6 +17,7 @@ fn concat(allocator: *std.mem.Allocator, str: []const u8, str2: []const u8) !std | |||
| } | ||||
| 
 | ||||
| pub fn build(b: *Builder) void { | ||||
|     src_files = ArrayList([]const u8).init(b.allocator); | ||||
|     const debug = b.option(bool, "debug", "build with debug symbols / make qemu wait for a debug connection") orelse false; | ||||
|     var build_path = b.option([]const u8, "build-path", "path to build to") orelse "bin"; | ||||
|     var src_path = b.option([]const u8, "source-path", "path to source") orelse "src"; | ||||
|  | @ -25,6 +26,13 @@ pub fn build(b: *Builder) void { | |||
| 
 | ||||
|     const iso_path = concat(b.allocator, build_path, "/pluto.iso") catch unreachable; | ||||
| 
 | ||||
|     src_files.append("kernel/kmain") catch unreachable; | ||||
| 
 | ||||
|     // Add the architecture init file to the source files | ||||
|     var arch_init = concat(b.allocator, "kernel/arch/", target) catch unreachable; | ||||
|     arch_init.append("/arch") catch unreachable; | ||||
|     src_files.append(arch_init.toSlice()) catch unreachable; | ||||
| 
 | ||||
|     var objects_steps = buildObjects(b, builtin_target, build_path, src_path); | ||||
|     var link_step = buildLink(b, builtin_target, build_path); | ||||
|     const iso_step = buildISO(b, build_path, iso_path.toSlice()); | ||||
|  | @ -41,7 +49,7 @@ pub fn build(b: *Builder) void { | |||
| fn buildTest(b: *Builder, src_path: []const u8) void { | ||||
|     const step = b.step("test", "Run all tests"); | ||||
|     const src_path2 = concat(b.allocator, src_path, "/") catch unreachable; | ||||
|     for (src_files) |file| { | ||||
|     for (src_files.toSlice()) |file| { | ||||
|         var file_src = concat(b.allocator, src_path2.toSlice(), file) catch unreachable; | ||||
|         file_src.append(".zig") catch unreachable; | ||||
|         const tst = b.addTest(file_src.toSlice()); | ||||
|  | @ -100,7 +108,7 @@ fn buildLink(b: *Builder, target: builtin.Arch, build_path: []const u8) *Step { | |||
|     exec.setOutputDir(elf_path.toSlice()); | ||||
|     exec.setLinkerScriptPath("link.ld"); | ||||
|     exec.setTarget(target, builtin.Os.freestanding, builtin.Abi.gnu); | ||||
|     for (src_files) |file| { | ||||
|     for (src_files.toSlice()) |file| { | ||||
|         var file_obj = concat(b.allocator, build_path, "/") catch unreachable; | ||||
|         file_obj.append(file) catch unreachable; | ||||
|         file_obj.append(".o") catch unreachable; | ||||
|  | @ -112,7 +120,7 @@ fn buildLink(b: *Builder, target: builtin.Arch, build_path: []const u8) *Step { | |||
| fn buildObjects(b: *Builder, target: builtin.Arch, build_path: []const u8, src_path: []const u8) ArrayList(*Step) { | ||||
|     var objects = ArrayList(*Step).init(b.allocator); | ||||
|     const src_path2 = concat(b.allocator, src_path, "/") catch unreachable; | ||||
|     for (src_files) |file| { | ||||
|     for (src_files.toSlice()) |file| { | ||||
|         var file_src = concat(b.allocator, src_path2.toSlice(), file) catch unreachable; | ||||
|         file_src.append(".zig") catch unreachable; | ||||
|         const obj = b.addObject(file, file_src.toSlice()); | ||||
|  |  | |||
							
								
								
									
										2
									
								
								src/kernel/arch.zig
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										2
									
								
								src/kernel/arch.zig
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,2 @@ | |||
| /// Initialise the architecture | ||||
| pub extern fn init() void; | ||||
							
								
								
									
										103
									
								
								src/kernel/arch/x86/arch.zig
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										103
									
								
								src/kernel/arch/x86/arch.zig
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,103 @@ | |||
| extern fn kmain() void; | ||||
| 
 | ||||
| const MultiBoot = packed struct { | ||||
|     magic: i32, | ||||
|     flags: i32, | ||||
|     checksum: i32, | ||||
| }; | ||||
| 
 | ||||
| const ALIGN = 1 << 0; | ||||
| const MEMINFO = 1 << 1; | ||||
| const MAGIC = 0x1BADB002; | ||||
| const FLAGS = ALIGN | MEMINFO; | ||||
| 
 | ||||
| export var multiboot align(4) linksection(".rodata.boot") = MultiBoot{ | ||||
|     .magic = MAGIC, | ||||
|     .flags = FLAGS, | ||||
|     .checksum = -(MAGIC + FLAGS), | ||||
| }; | ||||
| 
 | ||||
| const KERNEL_ADDR_OFFSET = 0xC0000000; | ||||
| const KERNEL_PAGE_NUMBER = KERNEL_ADDR_OFFSET >> 22; | ||||
| // The number of pages occupied by the kernel, will need to be increased as we add a heap etc. | ||||
| const KERNEL_NUM_PAGES = 1; | ||||
| 
 | ||||
| // The initial page directory used for booting into the higher half. Should be overwritten later | ||||
| export var boot_page_directory: [1024]u32 align(4096) linksection(".rodata.boot") = init: { | ||||
|     // Increase max number of branches done by comptime evaluator | ||||
|     @setEvalBranchQuota(1024); | ||||
|     // Temp value | ||||
|     var dir: [1024]u32 = undefined; | ||||
| 
 | ||||
|     // Page for 0 -> 4 MiB. Gets unmapped later | ||||
|     dir[0] = 0x00000083; | ||||
| 
 | ||||
|     var i = 0; | ||||
|     var idx = 1; | ||||
| 
 | ||||
|     // Fill preceding pages with zeroes. May be unecessary but incurs no runtime cost | ||||
|     while (i < KERNEL_PAGE_NUMBER - 1) : ({ | ||||
|         i += 1; | ||||
|         idx += 1; | ||||
|     }) { | ||||
|         dir[idx] = 0; | ||||
|     } | ||||
| 
 | ||||
|     // Map the kernel's higher half pages increasing by 4 MiB every time | ||||
|     i = 0; | ||||
|     while (i < KERNEL_NUM_PAGES) : ({ | ||||
|         i += 1; | ||||
|         idx += 1; | ||||
|     }) { | ||||
|         dir[idx] = 0x00000083 | (i << 22); | ||||
|     } | ||||
|     // Fill suceeding pages with zeroes. May be unecessary but incurs no runtime cost | ||||
|     i = 0; | ||||
|     while (i < 1024 - KERNEL_PAGE_NUMBER - KERNEL_NUM_PAGES) : ({ | ||||
|         i += 1; | ||||
|         idx += 1; | ||||
|     }) { | ||||
|         dir[idx] = 0; | ||||
|     } | ||||
|     break :init dir; | ||||
| }; | ||||
| 
 | ||||
| export var kernel_stack: [16 * 1024]u8 align(16) linksection(".bss.stack") = undefined; | ||||
| 
 | ||||
| export nakedcc fn _start() align(16) linksection(".text.boot") noreturn { | ||||
|     // Seth the page directory to the boot directory | ||||
|     asm volatile ( | ||||
|         \\.extern boot_page_directory | ||||
|         \\mov $boot_page_directory, %%ecx | ||||
|         \\mov %%ecx, %%cr3 | ||||
|     ); | ||||
|     // Enable 4 MiB pages | ||||
|     asm volatile ( | ||||
|         \\mov %%cr4, %%ecx | ||||
|         \\or $0x00000010, %%ecx | ||||
|         \\mov %%ecx, %%cr4 | ||||
|     ); | ||||
|     // Enable paging | ||||
|     asm volatile ( | ||||
|         \\mov %%cr0, %%ecx | ||||
|         \\or $0x80000000, %%ecx | ||||
|         \\mov %%ecx, %%cr0 | ||||
|     ); | ||||
|     asm volatile ("jmp start_higher_half"); | ||||
|     while (true) {} | ||||
| } | ||||
| 
 | ||||
| export nakedcc fn start_higher_half() noreturn { | ||||
|     // Invalidate the page for the first 4MiB as it's no longer needed | ||||
|     asm volatile ("invlpg (0)"); | ||||
|     // Setup the stack | ||||
|     asm volatile ( | ||||
|         \\.extern KERNEL_STACK_END | ||||
|         \\mov $KERNEL_STACK_END, %%esp | ||||
|         \\mov %%esp, %%ebp | ||||
|     ); | ||||
|     kmain(); | ||||
|     while (true) {} | ||||
| } | ||||
| 
 | ||||
| export fn init() void {} | ||||
|  | @ -5,106 +5,7 @@ | |||
| // Date: 2019-03-30 | ||||
| // | ||||
| const builtin = @import("builtin"); | ||||
| 
 | ||||
| const MultiBoot = packed struct { | ||||
|     magic: i32, | ||||
|     flags: i32, | ||||
|     checksum: i32, | ||||
| }; | ||||
| 
 | ||||
| const ALIGN = 1 << 0; | ||||
| const MEMINFO = 1 << 1; | ||||
| const MAGIC = 0x1BADB002; | ||||
| const FLAGS = ALIGN | MEMINFO; | ||||
| 
 | ||||
| export var multiboot align(4) linksection(".rodata.boot") = MultiBoot{ | ||||
|     .magic = MAGIC, | ||||
|     .flags = FLAGS, | ||||
|     .checksum = -(MAGIC + FLAGS), | ||||
| }; | ||||
| 
 | ||||
| const KERNEL_ADDR_OFFSET = 0xC0000000; | ||||
| const KERNEL_PAGE_NUMBER = KERNEL_ADDR_OFFSET >> 22; | ||||
| // The number of pages occupied by the kernel, will need to be increased as we add a heap etc. | ||||
| const KERNEL_NUM_PAGES = 1; | ||||
| 
 | ||||
| // The initial page directory used for booting into the higher half. Should be overwritten later | ||||
| export var boot_page_directory: [1024]u32 align(4096) linksection(".rodata.boot") = init: { | ||||
|     // Increase max number of branches done by comptime evaluator | ||||
|     @setEvalBranchQuota(1024); | ||||
|     // Temp value | ||||
|     var dir: [1024]u32 = undefined; | ||||
| 
 | ||||
|     // Page for 0 -> 4 MiB. Gets unmapped later | ||||
|     dir[0] = 0x00000083; | ||||
| 
 | ||||
|     var i = 0; | ||||
|     var idx = 1; | ||||
| 
 | ||||
|     // Fill preceding pages with zeroes. May be unecessary but incurs no runtime cost | ||||
|     while (i < KERNEL_PAGE_NUMBER - 1) : ({ | ||||
|         i += 1; | ||||
|         idx += 1; | ||||
|     }) { | ||||
|         dir[idx] = 0; | ||||
|     } | ||||
| 
 | ||||
|     // Map the kernel's higher half pages increasing by 4 MiB every time | ||||
|     i = 0; | ||||
|     while (i < KERNEL_NUM_PAGES) : ({ | ||||
|         i += 1; | ||||
|         idx += 1; | ||||
|     }) { | ||||
|         dir[idx] = 0x00000083 | (i << 22); | ||||
|     } | ||||
|     // Fill suceeding pages with zeroes. May be unecessary but incurs no runtime cost | ||||
|     i = 0; | ||||
|     while (i < 1024 - KERNEL_PAGE_NUMBER - KERNEL_NUM_PAGES) : ({ | ||||
|         i += 1; | ||||
|         idx += 1; | ||||
|     }) { | ||||
|         dir[idx] = 0; | ||||
|     } | ||||
|     break :init dir; | ||||
| }; | ||||
| 
 | ||||
| export var kernel_stack: [16 * 1024]u8 align(16) linksection(".bss.stack") = undefined; | ||||
| 
 | ||||
| export nakedcc fn _start() align(16) linksection(".text.boot") noreturn { | ||||
|     // Seth the page directory to the boot directory | ||||
|     asm volatile ( | ||||
|         \\.extern boot_page_directory | ||||
|         \\mov $boot_page_directory, %%ecx | ||||
|         \\mov %%ecx, %%cr3 | ||||
|     ); | ||||
|     // Enable 4 MiB pages | ||||
|     asm volatile ( | ||||
|         \\mov %%cr4, %%ecx | ||||
|         \\or $0x00000010, %%ecx | ||||
|         \\mov %%ecx, %%cr4 | ||||
|     ); | ||||
|     // Enable paging | ||||
|     asm volatile ( | ||||
|         \\mov %%cr0, %%ecx | ||||
|         \\or $0x80000000, %%ecx | ||||
|         \\mov %%ecx, %%cr0 | ||||
|     ); | ||||
|     asm volatile ("jmp start_higher_half"); | ||||
|     while (true) {} | ||||
| } | ||||
| 
 | ||||
| export nakedcc fn start_higher_half() noreturn { | ||||
|     // Invalidate the page for the first 4MiB as it's no longer needed | ||||
|     asm volatile ("invlpg (0)"); | ||||
|     // Setup the stack | ||||
|     asm volatile ( | ||||
|         \\.extern KERNEL_STACK_END | ||||
|         \\mov $KERNEL_STACK_END, %%esp | ||||
|         \\mov %%esp, %%ebp | ||||
|     ); | ||||
|     kmain(); | ||||
|     while (true) {} | ||||
| } | ||||
| const arch = @import("arch.zig"); | ||||
| 
 | ||||
| pub fn panic(msg: []const u8, error_return_trace: ?*builtin.StackTrace) noreturn { | ||||
|     @setCold(true); | ||||
|  | @ -113,7 +14,8 @@ pub fn panic(msg: []const u8, error_return_trace: ?*builtin.StackTrace) noreturn | |||
|     while (true) {} | ||||
| } | ||||
| 
 | ||||
| fn kmain() void { | ||||
| pub export fn kmain() void { | ||||
|     arch.init(); | ||||
|     terminal.initialize(); | ||||
|     terminal.write("Hello, kernel World!"); | ||||
| } | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Sam Tebbs
						Sam Tebbs