├── .gitignore ├── boot ├── fixup.dat ├── fixup4.dat ├── start.elf ├── start4.elf ├── bootcode.bin ├── fixup4cd.dat ├── fixup_cd.dat ├── start4cd.elf ├── start_cd.elf ├── armstub8-rpi4.bin ├── config.txt ├── README.md ├── LICENCE.broadcom └── armstub8.S ├── src ├── driver │ ├── base.zig │ ├── GPIO.zig │ └── UART.zig ├── linker.ld ├── main.zig ├── aarch64 │ ├── kernel_pt.zig │ ├── mmu.h │ ├── Arch.zig │ └── kernel_pt.c └── start.S ├── LICENSE └── README.md /.gitignore: -------------------------------------------------------------------------------- 1 | **/zig-cache 2 | **/zig-out 3 | **/.vscode -------------------------------------------------------------------------------- /boot/fixup.dat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JingYiJun/ZerOS/HEAD/boot/fixup.dat -------------------------------------------------------------------------------- /boot/fixup4.dat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JingYiJun/ZerOS/HEAD/boot/fixup4.dat -------------------------------------------------------------------------------- /boot/start.elf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JingYiJun/ZerOS/HEAD/boot/start.elf -------------------------------------------------------------------------------- /boot/start4.elf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JingYiJun/ZerOS/HEAD/boot/start4.elf -------------------------------------------------------------------------------- /boot/bootcode.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JingYiJun/ZerOS/HEAD/boot/bootcode.bin -------------------------------------------------------------------------------- /boot/fixup4cd.dat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JingYiJun/ZerOS/HEAD/boot/fixup4cd.dat -------------------------------------------------------------------------------- /boot/fixup_cd.dat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JingYiJun/ZerOS/HEAD/boot/fixup_cd.dat -------------------------------------------------------------------------------- /boot/start4cd.elf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JingYiJun/ZerOS/HEAD/boot/start4cd.elf -------------------------------------------------------------------------------- /boot/start_cd.elf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JingYiJun/ZerOS/HEAD/boot/start_cd.elf -------------------------------------------------------------------------------- /boot/armstub8-rpi4.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JingYiJun/ZerOS/HEAD/boot/armstub8-rpi4.bin -------------------------------------------------------------------------------- /src/driver/base.zig: -------------------------------------------------------------------------------- 1 | pub const KERNEL_BASE = 0xffff_0000_0000_0000; 2 | pub const MMIO_BASE = KERNEL_BASE + 0x3F00_0000; 3 | pub const LOCAL_BASE = KERNEL_BASE + 0x4000_0000; 4 | -------------------------------------------------------------------------------- /boot/config.txt: -------------------------------------------------------------------------------- 1 | arm_64bit=1 2 | enable_uart=1 3 | # disable_l2cache=1 4 | 5 | [pi4] 6 | device_tree= 7 | enable_gic=0 8 | core_freq_min=250 9 | armstub=armstub8-rpi4.bin 10 | -------------------------------------------------------------------------------- /boot/README.md: -------------------------------------------------------------------------------- 1 | This folder contains necessary files to boot rpi-os up. They are downloaded from . 2 | 3 | `armstub8-rpi4.bin` is compiled from `armstub8.S` by following make rules: 4 | 5 | ```makefile 6 | %8-rpi4.o: %8.S 7 | $(CC) -DBCM2711=1 -c $< -o $@ 8 | 9 | %8-rpi4.elf: %8-rpi4.o 10 | $(LD) --section-start=.text=0 $< -o $@ 11 | 12 | %8-rpi4.tmp: %8-rpi4.elf 13 | $(OBJCOPY) $< -O binary $@ 14 | 15 | %8-rpi4.bin: %8-rpi4.tmp 16 | dd if=$< ibs=256 of=$@ conv=sync 17 | ``` 18 | -------------------------------------------------------------------------------- /src/driver/GPIO.zig: -------------------------------------------------------------------------------- 1 | const base = @import("base.zig"); 2 | 3 | pub const GPIO_BASE = base.MMIO_BASE + 0x0020_0000; 4 | 5 | pub const GPFSEL0 = GPIO_BASE + 0x00; 6 | pub const GPFSEL1 = GPIO_BASE + 0x04; 7 | pub const GPFSEL2 = GPIO_BASE + 0x08; 8 | pub const GPFSEL3 = GPIO_BASE + 0x0C; 9 | pub const GPFSEL4 = GPIO_BASE + 0x10; 10 | pub const GPFSEL5 = GPIO_BASE + 0x14; 11 | pub const GPSET0 = GPIO_BASE + 0x1C; 12 | pub const GPSET1 = GPIO_BASE + 0x20; 13 | pub const GPCLR0 = GPIO_BASE + 0x28; 14 | pub const GPLEV0 = GPIO_BASE + 0x34; 15 | pub const GPLEV1 = GPIO_BASE + 0x38; 16 | pub const GPEDS0 = GPIO_BASE + 0x40; 17 | pub const GPEDS1 = GPIO_BASE + 0x44; 18 | pub const GPHEN0 = GPIO_BASE + 0x64; 19 | pub const GPHEN1 = GPIO_BASE + 0x68; 20 | pub const GPPUD = GPIO_BASE + 0x94; 21 | pub const GPPUDCLK0 = GPIO_BASE + 0x98; 22 | pub const GPPUDCLK1 = GPIO_BASE + 0x9C; 23 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright 2023 精益君 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 6 | 7 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 8 | 9 | THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -------------------------------------------------------------------------------- /src/linker.ld: -------------------------------------------------------------------------------- 1 | OUTPUT_ARCH(aarch64) 2 | ENTRY(_start) 3 | BASE_ADDRESS = 0xFFFF000000080000; 4 | 5 | SECTIONS 6 | { 7 | . = BASE_ADDRESS; 8 | 9 | .text : ALIGN(4K) { 10 | PROVIDE(__text_start = .); 11 | KEEP(*(.text.boot)) 12 | *(.text .text.*) 13 | } 14 | 15 | 16 | .rodata : ALIGN(4K) { 17 | PROVIDE(__text_end = .); 18 | PROVIDE(__rodata_start = .); 19 | *(.rodata .rodata.*) 20 | 21 | /* KEEP(*(.debug_info)) 22 | KEEP(*(.debug_abbrev)) 23 | KEEP(*(.debug_aranges)) 24 | KEEP(*(.debug_line)) 25 | KEEP(*(.debug_str)) 26 | KEEP(*(.debug_ranges)) 27 | KEEP(*(.debug_pubnames)) 28 | KEEP(*(.debug_pubtypes)) 29 | KEEP(*(.debug_frame)) */ 30 | } 31 | 32 | 33 | .data : ALIGN(4K) { 34 | PROVIDE(__rodata_end = .); 35 | PROVIDE(__data_start = .); 36 | *(.data .data.*) 37 | } 38 | 39 | .bss : ALIGN(4K) { 40 | PROVIDE(__data_end = .); 41 | PROVIDE(__bss_start = .); 42 | *(.bss .bss.*) 43 | PROVIDE(__bss_end = .); 44 | } 45 | 46 | /DISCARD/ : { 47 | *(.eh_frame) 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /src/main.zig: -------------------------------------------------------------------------------- 1 | // const kernel_pt_module = @import("aarch64/kernel_pt.zig"); 2 | const Arch = @import("aarch64/Arch.zig"); 3 | const UART = @import("driver/UART.zig"); 4 | const std = @import("std"); 5 | const builtin = @import("std").builtin; 6 | // const kernel_pt_module = @import("aarch64/kernel_pt.zig"); 7 | 8 | // comptime { 9 | // @export(kernel_pt_module.kernel_pt, .{ .name = "kernel_pt", .linkage = .Strong }); 10 | // @export(kernel_pt_module._kernel_pt_level2, .{ .name = "_kernel_pt_level2", .linkage = .Strong }); 11 | // @export(kernel_pt_module._kernel_pt_level3, .{ .name = "_kernel_pt_level3", .linkage = .Strong }); 12 | // } 13 | 14 | extern var __bss_start: usize; 15 | extern var __bss_end: usize; 16 | 17 | var hello: [16]u8 = undefined; 18 | 19 | export fn main() noreturn { 20 | var cpu_id = Arch.cpu_id(); 21 | // stop all other cpus. 22 | if (cpu_id != 0) { 23 | Arch.stop_cpu(); 24 | } 25 | 26 | // clear bbs 27 | for (@intFromPtr(&__bss_start)..@intFromPtr(&__bss_end)) |p| { 28 | @as(*volatile u8, @ptrFromInt(p)).* = 0; 29 | } 30 | 31 | // init UART 32 | UART.init(); 33 | 34 | // print hello world; 35 | @memcpy(hello[0..14], "hello, world!\n"); 36 | UART.puts(&hello); 37 | 38 | // print current timestamp 39 | const current_timestamp = Arch.get_timestamp(); 40 | UART.printf("{d}\n", .{current_timestamp}); 41 | 42 | // print __bss_start 43 | UART.printf("&__bss_start = {p}; &__bss_end = {p}\n", .{ &__bss_start, &__bss_end }); 44 | 45 | Arch.stop_cpu(); 46 | } 47 | 48 | pub fn panic(_: []const u8, _: ?*builtin.StackTrace, _: ?usize) noreturn { 49 | @setCold(true); 50 | Arch.stop_cpu(); 51 | } 52 | -------------------------------------------------------------------------------- /boot/LICENCE.broadcom: -------------------------------------------------------------------------------- 1 | Copyright (c) 2006, Broadcom Corporation. 2 | Copyright (c) 2015, Raspberry Pi (Trading) Ltd 3 | All rights reserved. 4 | 5 | Redistribution. Redistribution and use in binary form, without 6 | modification, are permitted provided that the following conditions are 7 | met: 8 | 9 | * This software may only be used for the purposes of developing for, 10 | running or using a Raspberry Pi device, or authorised derivative 11 | device manufactured via the element14 Raspberry Pi Customization Service 12 | * Redistributions must reproduce the above copyright notice and the 13 | following disclaimer in the documentation and/or other materials 14 | provided with the distribution. 15 | * Neither the name of Broadcom Corporation nor the names of its suppliers 16 | may be used to endorse or promote products derived from this software 17 | without specific prior written permission. 18 | 19 | DISCLAIMER. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND 20 | CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, 21 | BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND 22 | FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 23 | COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 24 | INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 25 | BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS 26 | OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 27 | ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR 28 | TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE 29 | USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH 30 | DAMAGE. 31 | 32 | -------------------------------------------------------------------------------- /src/aarch64/kernel_pt.zig: -------------------------------------------------------------------------------- 1 | const PAGE_SIZE = 4096; 2 | 3 | // memory region attributes 4 | const MT_DEVICE_nGnRnE = 0x0; 5 | const MT_NORMAL = 0x1; 6 | const MT_NORMAL_NC = 0x2; 7 | const MT_DEVICE_nGnRnE_FLAGS = 0x00; 8 | const MT_NORMAL_FLAGS = 0xFF; // Inner/Outer Write-Back Non-Transient RW-Allocate 9 | const MT_NORMAL_NC_FLAGS = 0x44; // Inner/Outer Non-Cacheaconst 10 | 11 | const SH_OUTER = 2 << 8; 12 | const SH_INNER = 3 << 8; 13 | 14 | const AF_USED = 1 << 10; 15 | 16 | const PTE_NORMAL_NC = (MT_NORMAL_NC << 2) | AF_USED | SH_OUTER; 17 | const PTE_NORMAL = (MT_NORMAL << 2) | AF_USED | SH_OUTER; 18 | const PTE_DEVICE = (MT_DEVICE_nGnRnE << 2) | AF_USED; 19 | 20 | const PTE_VALID = 0x1; 21 | 22 | const PTE_TABLE = 0x3; 23 | const PTE_BLOCK = 0x1; 24 | const PTE_PAGE = 0x3; 25 | 26 | const PTE_KERNEL = 0 << 6; 27 | const PTE_USER = 1 << 6; 28 | const PTE_RO = 1 << 7; 29 | const PTE_RW = 0 << 7; 30 | 31 | const PTE_KERNEL_DATA = PTE_KERNEL | PTE_NORMAL | PTE_BLOCK; 32 | const PTE_KERNEL_DEVICE = PTE_KERNEL | PTE_DEVICE | PTE_BLOCK; 33 | const PTE_USER_DATA = PTE_USER | PTE_NORMAL | PTE_PAGE; 34 | 35 | const PTE_HIGH_NX = 1 << 54; 36 | 37 | const KSPACE_MASK = 0xffff000000000000; 38 | 39 | const N_PTE_PER_TABLE = 512; 40 | const N_PTE_INTERVEL = 0x0020_0000; 41 | const PTEntry = usize; 42 | const PTEntries = [N_PTE_PER_TABLE]PTEntry; 43 | 44 | pub var _kernel_pt_level3: PTEntries align(PAGE_SIZE) = _kernel_pt_level3_init: { 45 | var tmp: PTEntries = undefined; 46 | for (0..tmp.len) |i| { 47 | if (i < N_PTE_PER_TABLE - 8) { 48 | tmp[i] = (i * N_PTE_INTERVEL) | PTE_KERNEL_DATA; 49 | } else { 50 | tmp[i] = (i * N_PTE_INTERVEL) | PTE_KERNEL_DEVICE; 51 | } 52 | } 53 | break :_kernel_pt_level3_init tmp; 54 | }; 55 | 56 | pub var _kernel_pt_level2: PTEntries align(PAGE_SIZE) = 57 | [_]PTEntry{ 58 | 0, // must set to &_kernel_pt_level3 + PTE_TABLE at runtime 59 | 0x4000_0000 | PTE_KERNEL_DEVICE, 60 | 0, 61 | 0xC000_0000 | PTE_KERNEL_DEVICE, 62 | } ++ [_]PTEntry{0} ** (N_PTE_PER_TABLE - 4); 63 | 64 | pub var kernel_pt: PTEntries align(PAGE_SIZE) = 65 | [_]PTEntry{0} ** (N_PTE_PER_TABLE); 66 | -------------------------------------------------------------------------------- /src/aarch64/mmu.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | // #include 4 | typedef unsigned long long u64; 5 | 6 | #define PAGE_SIZE 4096 7 | 8 | /* memory region attributes */ 9 | #define MT_DEVICE_nGnRnE 0x0 10 | #define MT_NORMAL 0x1 11 | #define MT_NORMAL_NC 0x2 12 | #define MT_DEVICE_nGnRnE_FLAGS 0x00 13 | #define MT_NORMAL_FLAGS 0xFF /* Inner/Outer Write-Back Non-Transient RW-Allocate */ 14 | #define MT_NORMAL_NC_FLAGS 0x44 /* Inner/Outer Non-Cacheable */ 15 | 16 | #define SH_OUTER (2 << 8) 17 | #define SH_INNER (3 << 8) 18 | 19 | #define AF_USED (1 << 10) 20 | 21 | #define PTE_NORMAL_NC ((MT_NORMAL_NC << 2) | AF_USED | SH_OUTER) 22 | #define PTE_NORMAL ((MT_NORMAL << 2) | AF_USED | SH_OUTER) 23 | #define PTE_DEVICE ((MT_DEVICE_nGnRnE << 2) | AF_USED) 24 | 25 | #define PTE_VALID 0x1 26 | 27 | #define PTE_TABLE 0x3 28 | #define PTE_BLOCK 0x1 29 | #define PTE_PAGE 0x3 30 | 31 | #define PTE_KERNEL (0 << 6) 32 | #define PTE_USER (1 << 6) 33 | #define PTE_RO (1 << 7) 34 | #define PTE_RW (0 << 7) 35 | 36 | #define PTE_KERNEL_DATA (PTE_KERNEL | PTE_NORMAL | PTE_BLOCK) 37 | #define PTE_KERNEL_DEVICE (PTE_KERNEL | PTE_DEVICE | PTE_BLOCK) 38 | #define PTE_USER_DATA (PTE_USER | PTE_NORMAL | PTE_PAGE) 39 | 40 | #define N_PTE_PER_TABLE 512 41 | 42 | #define PTE_HIGH_NX (1LL << 54) 43 | 44 | #define KSPACE_MASK 0xffff000000000000 45 | 46 | // convert kernel address into physical address. 47 | #define K2P(addr) ((u64)(addr) - (KSPACE_MASK)) 48 | 49 | // convert physical address into kernel address. 50 | #define P2K(addr) ((u64)(addr) + (KSPACE_MASK)) 51 | 52 | // convert any address into kernel address space. 53 | #define KSPACE(addr) ((u64)(addr) | (KSPACE_MASK)) 54 | 55 | // conver any address into physical address space. 56 | #define PSPACE(addr) ((u64)(addr) & (~KSPACE_MASK)) 57 | 58 | typedef u64 PTEntry; 59 | typedef PTEntry PTEntries[N_PTE_PER_TABLE]; 60 | typedef PTEntry *PTEntriesPtr; 61 | 62 | #define VA_OFFSET(va) ((u64)(va) & 0xFFF) 63 | #define PTE_ADDRESS(pte) ((pte) & ~0xFFFF000000000FFF) 64 | #define PTE_FLAGS(pte) ((pte) & 0xFFFF000000000FFF) 65 | #define P2N(addr) (addr>>12) 66 | #define PAGE_BASE(addr) (addr & ~(PAGE_SIZE - 1)) 67 | 68 | -------------------------------------------------------------------------------- /src/aarch64/Arch.zig: -------------------------------------------------------------------------------- 1 | const Intrinsic = @This(); 2 | 3 | pub inline fn cpu_id() usize { 4 | // zig inline assembly is unstable right now, see https://github.com/ziglang/zig/issues/215 5 | // and https://ziglang.org/documentation/master/#Assembly 6 | // currently using https://llvm.org/docs/LangRef.html#inline-assembler-expressions 7 | // and https://gcc.gnu.org/onlinedocs/gcc/Extended-Asm.html 8 | return asm volatile ("mrs %[ret], mpidr_el1" 9 | : [ret] "=r" (-> usize), 10 | ) & 0xff; 11 | } 12 | 13 | // instruct compiler not to reorder instructions around the fence. 14 | pub inline fn compiler_fence() void { 15 | asm volatile ("" ::: "memory"); 16 | } 17 | 18 | inline fn read_system_register(comptime name: []const u8) usize { 19 | return asm volatile ("mrs %[ret], " ++ name 20 | : [ret] "=r" (-> usize), 21 | ); 22 | } 23 | 24 | pub inline fn get_clock_frequency() usize { 25 | return read_system_register("cntfrq_el0"); 26 | } 27 | 28 | pub inline fn get_timestamp() usize { 29 | return read_system_register("cntpct_el0"); 30 | } 31 | 32 | // set-event instruction. 33 | pub inline fn sev() void { 34 | asm volatile ("sev" ::: "memory"); 35 | } 36 | 37 | // wait-for-event instruction. 38 | pub inline fn wfe() void { 39 | asm volatile ("wfe" ::: "memory"); 40 | } 41 | 42 | pub inline fn stop_cpu() noreturn { 43 | while (true) 44 | wfe(); 45 | } 46 | 47 | // for `device_get/put_*`, there's no need to protect them with architectual 48 | // barriers, since they are intended to access device memory regions. These 49 | // regions are already marked as nGnRnE in `kernel_pt`. 50 | 51 | pub inline fn device_put_u32(addr: usize, value: u32) void { 52 | compiler_fence(); 53 | @as(*volatile u32, @ptrFromInt(addr)).* = value; 54 | compiler_fence(); 55 | } 56 | 57 | pub inline fn device_get_u32(addr: usize) u32 { 58 | compiler_fence(); 59 | const result = @as(*volatile u32, @ptrFromInt(addr)).*; 60 | compiler_fence(); 61 | return result; 62 | } 63 | 64 | pub fn delay_us(n: usize) void { 65 | const freq = get_clock_frequency(); 66 | var end = get_timestamp(); 67 | var now = end; 68 | end += freq / 1_000_000 * n; 69 | 70 | // see: https://github.com/ziglang/zig/issues/2159 71 | while (true) : (now = get_timestamp()) { 72 | if (now <= end) break; 73 | } 74 | } 75 | -------------------------------------------------------------------------------- /src/driver/UART.zig: -------------------------------------------------------------------------------- 1 | const std = @import("std"); 2 | 3 | const GPIO = @import("GPIO.zig"); 4 | const base = @import("base.zig"); 5 | const Arch = @import("../aarch64/Arch.zig"); 6 | const device_get_u32 = Arch.device_get_u32; 7 | const device_put_u32 = Arch.device_put_u32; 8 | const delay_us = Arch.delay_us; 9 | 10 | const AUX_BASE = base.MMIO_BASE + 0x215000; 11 | 12 | const AUX_ENABLES = AUX_BASE + 0x04; 13 | const AUX_MU_IO_REG = AUX_BASE + 0x40; 14 | const AUX_MU_IER_REG = AUX_BASE + 0x44; 15 | const AUX_MU_IIR_REG = AUX_BASE + 0x48; 16 | const AUX_MU_LCR_REG = AUX_BASE + 0x4C; 17 | const AUX_MU_MCR_REG = AUX_BASE + 0x50; 18 | const AUX_MU_LSR_REG = AUX_BASE + 0x54; 19 | const AUX_MU_MSR_REG = AUX_BASE + 0x58; 20 | const AUX_MU_SCRATCH = AUX_BASE + 0x5C; 21 | const AUX_MU_CNTL_REG = AUX_BASE + 0x60; 22 | const AUX_MU_STAT_REG = AUX_BASE + 0x64; 23 | const AUX_MU_BAUD_REG = AUX_BASE + 0x68; 24 | 25 | const AUX_UART_CLOCK = 250000000; 26 | 27 | fn AUX_MU_BAUD(comptime baudrate: comptime_int) comptime_int { 28 | return (AUX_UART_CLOCK / (baudrate * 8)) - 1; 29 | } 30 | 31 | pub fn init() void { 32 | // enable pins 14 and 15 33 | device_put_u32(GPIO.GPPUD, 0); 34 | delay_us(5); 35 | device_put_u32(GPIO.GPPUDCLK0, (1 << 14) | (1 << 15)); 36 | delay_us(5); 37 | device_put_u32(GPIO.GPPUDCLK0, 0); 38 | 39 | // enable mini uart and access to its registers. 40 | device_put_u32(AUX_ENABLES, 1); 41 | // disable auto flow control, receiver and transmitter (for now). 42 | device_put_u32(AUX_MU_CNTL_REG, 0); 43 | // enable receiving interrupts. 44 | device_put_u32(AUX_MU_IER_REG, 3 << 2 | 1); 45 | // enable 8-bit mode. 46 | device_put_u32(AUX_MU_LCR_REG, 3); 47 | // set RTS line to always high. 48 | device_put_u32(AUX_MU_MCR_REG, 0); 49 | // set baud rate to 115200. 50 | device_put_u32(AUX_MU_BAUD_REG, AUX_MU_BAUD(115200)); 51 | // clear receive and transmit FIFO. 52 | device_put_u32(AUX_MU_IIR_REG, 6); 53 | // finally, enable receiver and transmitter. 54 | device_put_u32(AUX_MU_CNTL_REG, 3); 55 | 56 | // set_interrupt_handler(IRQ_AUX, uart_intr); 57 | } 58 | 59 | pub fn get_char() u8 { 60 | const state = device_get_u32(AUX_MU_IIR_REG); 61 | if ((state & 1) || (state & 6) != 4) 62 | return (u8) - 1; 63 | 64 | return device_get_u32(AUX_MU_IO_REG) & 0xff; 65 | } 66 | 67 | pub fn put_char(c: u8) void { 68 | while (device_get_u32(AUX_MU_LSR_REG) & 0x20 == 0) {} 69 | 70 | device_put_u32(AUX_MU_IO_REG, c); 71 | 72 | // fix Windows's '\r'. 73 | if (c == '\n') 74 | put_char('\r'); 75 | } 76 | 77 | pub fn puts(s: []const u8) void { 78 | for (s) |c| { 79 | put_char(c); 80 | } 81 | } 82 | 83 | var buf: [512]u8 = undefined; 84 | 85 | pub fn printf(comptime fmt: []const u8, args: anytype) void { 86 | const buf_print_to = std.fmt.bufPrint(&buf, fmt, args) catch |err| { 87 | @panic(@errorName(err)); 88 | }; 89 | puts(buf_print_to); 90 | } 91 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # ZerOS 2 | 3 | 用 [Zig](https://ziglang.org/) 写的简易操作系统,用于复旦大学 2023 年秋季学期《操作系统》课程的配套实验。 4 | 5 | 名字随便起的,寓意 Zero OS 即自己的第一个操作系统。~~不如放一只可爱猫猫~~ 6 | 7 | 为什么用 Zig?因为比 C 更现代化,有包管理和一部分语法糖;比 Rust 更能操作内存且心智负担稍小。而且 Zig 有强大的编译期计算和静态反射能力,一部分标准库也可以在裸金属上使用,并且可以和 C 代码无缝集成。 8 | 9 | > 但是 Zig 语言有很多小毛病,稳定性不如 Rust。o(╥﹏╥)o 10 | 11 | ## 特点 12 | 13 | - 目前只能跑在树莓派 3B 上,在 qemu 上能通过测试。 14 | - 尽量使用 Zig 语言 15 | 16 | ## 构建指南 17 | 18 | ### 前置要求 19 | 20 | #### 安装 Zig 21 | 22 | Zig 目前正在快速迭代,每个小版本的 API 都会有很大变动。目前推荐使用 0.11.1 稳定版。 23 | 24 | 安装过程详见:https://ziglang.org/learn/getting-started/,源码仓库:https://github.com/ziglang/zig 25 | 26 | 如果从源码构建,需要安装 `clang-16 libclang-16-dev llvm-16 libllvm16 lld-16 liblld-16-dev zstd libzstd-dev` ,必须是 16 版本。CMake 构建必须要指定 `CLANG_INCLUDE_DIRS` 和 `LLD_INCLUDE_DIRS`。 27 | 28 | 这是我的构建命令: 29 | 30 | ```shell 31 | mkdir build && cd build 32 | cmake .. -DCMAKE_INSTALL_PREFIX=/usr/local -DCMAKE_BUILD_TYPE=Release -DCLANG_INCLUDE_DIRS=/usr/lib/llvm-16 -DLLD_INCLUDE_DIRS=/usr/lib/llvm-16 33 | make -j && make install 34 | ``` 35 | 36 | #### 建议安装 zls 37 | 38 | zls 是 Zig 的语言服务器,建议安装。 39 | 40 | [zls](https://github.com/zigtools/zls)。可以使用 0.11.0 版本的二进制包,也可以使用本地 Zig (master 版本)构建。 41 | 42 | zls 项目根目录下,我的构建命令是: 43 | 44 | ```shell 45 | zig build -Doptimize=ReleaseFast -Ddata_version=master --verbose -p /usr/local 46 | ``` 47 | 48 | #### VS Code 配置 Zig 开发环境 49 | 50 | 我的开发环境是 VS Code + wsl2,使用 Zig 官方的 VS Code 插件可以获得语法高亮、补全、跳转、格式化等功能。 51 | 52 | VS Code 支持用 C/C++ 的远程调试功能调试 Zig 代码。详见 [知乎:VS Code与GDB Server远程调试](https://zhuanlan.zhihu.com/p/295099630) 和 [知乎:在 Windows 版 VS Code 中调试 Zig 代码](https://zhuanlan.zhihu.com/p/463740524) 53 | 54 | 为什么不用 CLion?目前 JetBrains 系 IDE 的远程功能比较烂,运行成本高。 55 | 56 | ### 构建本项目 57 | 58 | Zig 项目会尽可能使用 `build.zig` 构建脚本构建程序,尽量不使用 `make`。同时会使用到 `llvm-objdump-16` 和 `llvm-objcopy-16`。不使用 `aarch64-linux-gnu-*` 的软件。 59 | 60 | 使用 ```zig build --help``` 获得所有帮助。 61 | 62 | #### 构建 ELF 63 | 64 | ```shell 65 | zig build 66 | ``` 67 | 68 | 这会将项目构建为 elf 格式,默认安装到 `zig-out/bin` 目录下。只会构建到 `kernel8.elf`。 69 | 70 | #### 直接启动 qemu 71 | 72 | ```shell 73 | zig build qemu 74 | ``` 75 | 76 | 这一步会构建 `kernel8.elf`, `kernel8.asm`, `kernel8.hdr`, `kernel8.img` 并且启动 qemu。 77 | 78 | #### qemu + gdb 79 | 80 | ```shell 81 | zig build qemu-debug 82 | ``` 83 | 84 | 在启动 qemu 的同时启动 gdb-server,监听 tcp::1234。 85 | 86 | ### 项目清理 87 | 88 | #### 清理输出文件 89 | 90 | ```shell 91 | zig build uninstall 92 | ``` 93 | 94 | 这会清除 `zig build` 的输出文件。 95 | 96 | #### 清理构建缓存 97 | 98 | ```shell 99 | zig build clean 100 | ``` 101 | 102 | 这会直接删除 `zig-out` 和 `zig-cache` 文件夹。 103 | 104 | ## 目标 105 | 106 | - [ ] 完成 OS 实验要求。 107 | - [ ] 内核 panic 时打印调用栈信息,基于 https://andrewkelley.me/post/zig-stack-traces-kernel-panic-bare-bones-os.html。 108 | - [ ] 跑在香橙派和其他的 aarch64 开发板上。 109 | - [ ] 移植一些系统级应用程序。 110 | 111 | ## 已知问题 112 | 113 | - 构建得到的 `kernel8.elf` debug 信息引用了不存在的行,错误信息会输出到 `kernel8.asm.log`。 114 | - 目前的 Zig 不支持[链接时全局变量初始化](https://github.com/ziglang/zig/issues/9512),而页表 `kernel_pt.c` 依赖于这一点,所以不方便移植到 Zig。但是实际上只有 `start.S` 依赖于这个文件,所以我直接拿过来,利用 Zig 无缝衔接 C 的特性把 `kernel_pt.c` 缝进了项目里面。 115 | 116 | ## 参考项目 117 | 118 | - [Fudan 2022Fall OS](https://github.com/FDUCSLG/OS-2022Fall-Fudan) 119 | - [Fudan 2021Fall OS](https://github.com/FDUCSLG/OS-2021Fall-dev) 120 | - [w568w's Rarmo](https://github.com/w568w/Rarmo) 121 | - [rCore-Tutorial-Book-v3](https://rcore-os.github.io/rCore-Tutorial-Book-v3/) 122 | - [Pluto: An x86 kernel written in Zig](https://github.com/ZystemOS/pluto) 123 | - [ClashOS: multiplayer arcade game for bare metal Raspberry Pi 3 B+](https://github.com/andrewrk/clashos) 124 | - [raspi3-tutorial](https://github.com/bztsrc/raspi3-tutorial) 125 | 126 | ## 开源许可证 127 | 128 | 本项目以 MIT 许可证开源。 -------------------------------------------------------------------------------- /src/start.S: -------------------------------------------------------------------------------- 1 | /* SCR_EL3, Secure Configuration Register (EL3). */ 2 | #define SCR_RESERVED (3 << 4) 3 | #define SCR_RW (1 << 10) 4 | #define SCR_HCE (1 << 8) 5 | #define SCR_SMD (1 << 7) 6 | #define SCR_NS (1 << 0) 7 | #define SCR_VALUE (SCR_RESERVED | SCR_RW | SCR_HCE | SCR_SMD | SCR_NS) 8 | 9 | /* SPSR_EL1/2/3, Saved Program Status Register. */ 10 | #define SPSR_MASK_ALL (7 << 6) 11 | #define SPSR_EL1h (5 << 0) 12 | #define SPSR_EL2h (9 << 0) 13 | #define SPSR_EL3_VALUE (SPSR_MASK_ALL | SPSR_EL2h) 14 | #define SPSR_EL2_VALUE (SPSR_MASK_ALL | SPSR_EL1h) 15 | 16 | /* HCR_EL2, Hypervisor Configuration Register (EL2). */ 17 | #define HCR_RW (1 << 31) 18 | #define HCR_VALUE HCR_RW 19 | 20 | /* SCTLR_EL1, System Control Register (EL1). */ 21 | #define SCTLR_RESERVED ((3 << 28) | (3 << 22) | (1 << 20) | (1 << 11) | (1 << 8) | (1 << 7)) 22 | #define SCTLR_EE_LITTLE_ENDIAN (0 << 25) 23 | #define SCTLR_E0E_LITTLE_ENDIAN (0 << 24) 24 | #define SCTLR_I_CACHE (1 << 12) 25 | #define SCTLR_D_CACHE (1 << 2) 26 | #define SCTLR_MMU_DISABLED (0 << 0) 27 | #define SCTLR_MMU_ENABLED (1 << 0) 28 | #define SCTLR_VALUE_MMU_DISABLED (SCTLR_RESERVED | SCTLR_EE_LITTLE_ENDIAN | SCTLR_E0E_LITTLE_ENDIAN | \ 29 | SCTLR_I_CACHE | SCTLR_D_CACHE | SCTLR_MMU_DISABLED) 30 | 31 | /* CPACR_EL1, Architectural Feature Access Control Register. */ 32 | #define CPACR_FP_EN (3 << 20) 33 | #define CPACR_TRACE_EN (0 << 28) 34 | #define CPACR_VALUE (CPACR_FP_EN | CPACR_TRACE_EN) 35 | 36 | /* Translation Control Register */ 37 | #define TCR_T0SZ (64 - 48) 38 | #define TCR_T1SZ ((64 - 48) << 16) 39 | #define TCR_TG0_4K (0 << 14) 40 | #define TCR_TG1_4K (2 << 30) 41 | #define TCR_SH0_INNER (3 << 12) 42 | #define TCR_SH1_INNER (3 << 28) 43 | #define TCR_SH0_OUTER (2 << 12) 44 | #define TCR_SH1_OUTER (2 << 28) 45 | #define TCR_ORGN0_IRGN0 ((1 << 10) | (1 << 8)) 46 | #define TCR_ORGN1_IRGN1 ((1 << 26) | (1 << 24)) 47 | #define TCR_VALUE (TCR_T0SZ | TCR_T1SZ | TCR_TG0_4K | TCR_TG1_4K | \ 48 | TCR_SH0_OUTER | TCR_SH1_OUTER | TCR_ORGN0_IRGN0 | TCR_ORGN1_IRGN1) 49 | 50 | /* memory region attributes */ 51 | #define MT_DEVICE_nGnRnE 0x0 52 | #define MT_NORMAL 0x1 53 | #define MT_NORMAL_NC 0x2 54 | #define MT_DEVICE_nGnRnE_FLAGS 0x00 55 | #define MT_NORMAL_FLAGS 0xFF /* Inner/Outer Write-back Non-transient RW-Allocate */ 56 | #define MT_NORMAL_NC_FLAGS 0x44 /* Inner/Outer Non-cacheable */ 57 | #define MAIR_VALUE ((MT_DEVICE_nGnRnE_FLAGS << (8 * MT_DEVICE_nGnRnE)) | \ 58 | (MT_NORMAL_FLAGS << (8 * MT_NORMAL)) | \ 59 | (MT_NORMAL_NC_FLAGS << (8 * MT_NORMAL_NC))) 60 | 61 | /* kernel stack size per CPU. Kernel stack sizes are fixed. */ 62 | #define KERNEL_STACK_SIZE 4096 63 | 64 | .section ".text.boot" 65 | 66 | .global _start 67 | _start: 68 | /** 69 | * wake up other CPUs. 70 | * see . 71 | * which has been incorporated in `start.elf` (or `bootcode.bin`?). 72 | */ 73 | mov x15, x0 74 | adr x0, entry 75 | mov x1, #1 76 | mov x2, #2 77 | mov x3, #3 78 | mov x9, 0xd8 79 | str x0, [x9, x1, lsl #3] 80 | str x0, [x9, x2, lsl #3] 81 | str x0, [x9, x3, lsl #3] 82 | 83 | dsb sy 84 | isb 85 | 86 | sev 87 | 88 | entry: 89 | /* get current exception level from CurrentEL[3:2]. */ 90 | mrs x9, CurrentEL 91 | /* MRS (Move Register from Special Register) 指令是 ARM 架构中的一条指令,用于将特殊寄存器的值复制到通用寄存器中。 92 | * 在这个上下文中,mrs x9, CurrentEL 指令的含义是将当前 EL(Exception Level)的值复制到 x9 寄存器中。\ 93 | * 特殊寄存器是 ARM 处理器中的一组寄存器,用于存储处理器状态和控制信息。CurrentEL 是一个特殊寄存器,用于记录当前异常级别的值。 94 | * 异常级别(EL)是 ARM 处理器中的一种概念,用于表示当前的运行环境。 95 | * https://jiyang.site/posts/rpios-processor-init/ 96 | */ 97 | and x9, x9, #0xc 98 | cmp x9, #8 99 | beq el2 100 | bgt el3 101 | 102 | el3: 103 | mov x9, #SCR_VALUE 104 | msr scr_el3, x9 105 | /* MSR (Move to Special Register) 指令是 ARM 架构中的一条指令,用于将通用寄存器的值复制到特殊寄存器中。 */ 106 | mov x9, #SPSR_EL3_VALUE 107 | msr spsr_el3, x9 108 | /* SPSR_EL3 (Saved Program Status Register) 是一个特殊寄存器,用于记录异常发生时的处理器状态。 */ 109 | adr x9, el2 110 | /* ADR (Address of a Label) 指令是 ARM 架构中的一条指令,用于将标签的地址复制到通用寄存器中。 */ 111 | msr elr_el3, x9 112 | /* ELR_EL3 (Exception Link Register) 是一个特殊寄存器,用于记录异常发生时的下一条指令的地址。 */ 113 | eret 114 | /* ERET (Exception Return) 指令是 ARM 架构中的一条指令,用于从异常处理程序返回到异常发生时的上下文中。 */ 115 | 116 | el2: 117 | /** 118 | * HCR_EL2.RW, bit[31] = 1: the execution state for EL1 is AArch64. 119 | * the execution state for EL0 is determined by the current 120 | * value of PSTATE.nRW when executing at EL0. 121 | */ 122 | mov x9, #HCR_VALUE 123 | msr hcr_el2, x9 124 | 125 | /* setup SCTLR access. */ 126 | ldr x9, =SCTLR_VALUE_MMU_DISABLED 127 | msr sctlr_el1, x9 128 | 129 | /* enable SIMD instructions. */ 130 | ldr x9, =CPACR_VALUE 131 | msr cpacr_el1, x9 132 | 133 | /* change execution level to EL1. */ 134 | mov x9, #SPSR_EL2_VALUE 135 | msr spsr_el2, x9 136 | adr x9, el1 137 | msr elr_el2, x9 138 | eret 139 | 140 | el1: 141 | /* initial kernel_pt */ 142 | /* zig does not support link-time initialization yet. see https://github.com/ziglang/zig/issues/9512 */ 143 | /* using c files */ 144 | adr x9, kernel_pt 145 | 146 | /* higher and lower half map to same physical memory region. */ 147 | msr ttbr0_el1, x9 148 | msr ttbr1_el1, x9 149 | 150 | ldr x9, =TCR_VALUE 151 | msr tcr_el1, x9 152 | 153 | ldr x9, =MAIR_VALUE 154 | msr mair_el1, x9 155 | 156 | isb 157 | 158 | /* enable MMU. */ 159 | mrs x9, sctlr_el1 160 | orr x9, x9, #SCTLR_MMU_ENABLED 161 | msr sctlr_el1, x9 162 | 163 | isb 164 | 165 | /* read CPUID. */ 166 | mrs x0, mpidr_el1 167 | and x0, x0, #3 168 | 169 | /* sp = _start - CPUID * KERNEL_STACK_SIZE */ 170 | mov x10, #KERNEL_STACK_SIZE 171 | mul x10, x10, x0 172 | ldr x9, =_start 173 | sub x9, x9, x10 174 | 175 | /* set up stack pointer, must always be aligned to 16 bytes. */ 176 | msr spsel, #1 177 | mov sp, x9 178 | 179 | mov x0, x15 180 | ldr x9, =main 181 | br x9 182 | -------------------------------------------------------------------------------- /boot/armstub8.S: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2016-2019 Raspberry Pi (Trading) Ltd. 3 | * Copyright (c) 2016 Stephen Warren 4 | * All rights reserved. 5 | * 6 | * Redistribution and use in source and binary forms, with or without 7 | * modification, are permitted provided that the following conditions are met: 8 | * * Redistributions of source code must retain the above copyright notice, 9 | * this list of conditions and the following disclaimer. 10 | * * Redistributions in binary form must reproduce the above copyright notice, 11 | * this list of conditions and the following disclaimer in the documentation 12 | * and/or other materials provided with the distribution. 13 | * * Neither the name of the copyright holder nor the names of its contributors 14 | * may be used to endorse or promote products derived from this software 15 | * without specific prior written permission. 16 | * 17 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 18 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 19 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 20 | * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 21 | * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 22 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 23 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 24 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 25 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 26 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 27 | * POSSIBILITY OF SUCH DAMAGE. 28 | */ 29 | 30 | #define BIT(x) (1 << (x)) 31 | 32 | #if BCM2711 33 | #ifdef HIGH_PERI 34 | #define LOCAL_CONTROL 0x4c0000000 35 | #define LOCAL_PRESCALER 0x4c0000008 36 | #else 37 | #define LOCAL_CONTROL 0xff800000 38 | #define LOCAL_PRESCALER 0xff800008 39 | #endif 40 | #else 41 | #define LOCAL_CONTROL 0x40000000 42 | #define LOCAL_PRESCALER 0x40000008 43 | #endif 44 | 45 | #ifdef HIGH_PERI 46 | #define GIC_DISTB 0x4c0041000 47 | #define GIC_CPUB 0x4c0042000 48 | #else 49 | #define GIC_DISTB 0xff841000 50 | #define GIC_CPUB 0xff842000 51 | #endif 52 | 53 | #if BCM2711 54 | #define OSC_FREQ 54000000 55 | #else 56 | #define OSC_FREQ 19200000 57 | #endif 58 | 59 | #define SCR_RW BIT(10) 60 | #define SCR_HCE BIT(8) 61 | #define SCR_SMD BIT(7) 62 | #define SCR_RES1_5 BIT(5) 63 | #define SCR_RES1_4 BIT(4) 64 | #define SCR_NS BIT(0) 65 | #define SCR_VAL \ 66 | (SCR_RW | SCR_HCE | SCR_SMD | SCR_RES1_5 | SCR_RES1_4 | SCR_NS) 67 | 68 | #define ACTLR_VAL \ 69 | (BIT(0) | BIT(1) | BIT(4) | BIT(5) | BIT(6)) 70 | 71 | #define CPUECTLR_EL1 S3_1_C15_C2_1 72 | #define CPUECTLR_EL1_SMPEN BIT(6) 73 | 74 | #define SPSR_EL3_D BIT(9) 75 | #define SPSR_EL3_A BIT(8) 76 | #define SPSR_EL3_I BIT(7) 77 | #define SPSR_EL3_F BIT(6) 78 | #define SPSR_EL3_MODE_EL2H 9 79 | #define SPSR_EL3_VAL \ 80 | (SPSR_EL3_D | SPSR_EL3_A | SPSR_EL3_I | SPSR_EL3_F | SPSR_EL3_MODE_EL2H) 81 | 82 | #define L2CTLR_EL1 S3_1_C11_C0_2 83 | 84 | 85 | #define GICC_CTRLR 0x0 86 | #define GICC_PMR 0x4 87 | #define IT_NR 0x8 // Number of interrupt enable registers (256 total irqs) 88 | #define GICD_CTRLR 0x0 89 | #define GICD_IGROUPR 0x80 90 | 91 | .globl _start 92 | _start: 93 | /* 94 | * LOCAL_CONTROL: 95 | * Bit 9 clear: Increment by 1 (vs. 2). 96 | * Bit 8 clear: Timer source is 19.2MHz crystal (vs. APB). 97 | */ 98 | ldr x0, =LOCAL_CONTROL 99 | str wzr, [x0] 100 | /* LOCAL_PRESCALER; divide-by (0x80000000 / register_val) == 1 */ 101 | mov w1, 0x80000000 102 | str w1, [x0, #(LOCAL_PRESCALER - LOCAL_CONTROL)] 103 | 104 | /* Set L2 read/write cache latency to 3 */ 105 | mrs x0, L2CTLR_EL1 106 | mov x1, #0x22 107 | orr x0, x0, x1 108 | msr L2CTLR_EL1, x0 109 | 110 | /* Set up CNTFRQ_EL0 */ 111 | ldr x0, =OSC_FREQ 112 | msr CNTFRQ_EL0, x0 113 | 114 | /* Set up CNTVOFF_EL2 */ 115 | msr CNTVOFF_EL2, xzr 116 | 117 | /* Enable FP/SIMD */ 118 | /* All set bits below are res1; bit 10 (TFP) is set to 0 */ 119 | mov x0, #0x33ff 120 | msr CPTR_EL3, x0 121 | 122 | /* Set up SCR */ 123 | mov x0, #SCR_VAL 124 | msr SCR_EL3, x0 125 | 126 | /* Set up ACTLR */ 127 | mov x0, #ACTLR_VAL 128 | msr ACTLR_EL3, x0 129 | 130 | /* Set SMPEN */ 131 | mov x0, #CPUECTLR_EL1_SMPEN 132 | msr CPUECTLR_EL1, x0 133 | 134 | #ifdef GIC 135 | bl setup_gic 136 | #endif 137 | /* 138 | * Set up SCTLR_EL2 139 | * All set bits below are res1. LE, no WXN/I/SA/C/A/M 140 | */ 141 | ldr x0, =0x30c50830 142 | msr SCTLR_EL2, x0 143 | 144 | /* Switch to EL2 */ 145 | mov x0, #SPSR_EL3_VAL 146 | msr spsr_el3, x0 147 | adr x0, in_el2 148 | msr elr_el3, x0 149 | eret 150 | in_el2: 151 | 152 | mrs x6, MPIDR_EL1 153 | and x6, x6, #0x3 154 | cbz x6, primary_cpu 155 | 156 | adr x5, spin_cpu0 157 | secondary_spin: 158 | wfe 159 | ldr x4, [x5, x6, lsl #3] 160 | cbz x4, secondary_spin 161 | mov x0, #0 162 | b boot_kernel 163 | 164 | primary_cpu: 165 | ldr w4, kernel_entry32 166 | ldr w0, dtb_ptr32 167 | 168 | boot_kernel: 169 | mov x1, #0 170 | mov x2, #0 171 | mov x3, #0 172 | br x4 173 | 174 | .ltorg 175 | 176 | .org 0xd8 177 | .globl spin_cpu0 178 | spin_cpu0: 179 | .quad 0 180 | .org 0xe0 181 | .globl spin_cpu1 182 | spin_cpu1: 183 | .quad 0 184 | .org 0xe8 185 | .globl spin_cpu2 186 | spin_cpu2: 187 | .quad 0 188 | .org 0xf0 189 | .globl spin_cpu3 190 | spin_cpu3: 191 | # Shared with next two symbols/.word 192 | # FW clears the next 8 bytes after reading the initial value, leaving 193 | # the location suitable for use as spin_cpu3 194 | .org 0xf0 195 | .globl stub_magic 196 | stub_magic: 197 | .word 0x5afe570b 198 | .org 0xf4 199 | .globl stub_version 200 | stub_version: 201 | .word 0 202 | .org 0xf8 203 | .globl dtb_ptr32 204 | dtb_ptr32: 205 | .word 0x0 206 | .org 0xfc 207 | .globl kernel_entry32 208 | kernel_entry32: 209 | .word 0x0 210 | 211 | // Leave space for the ATAGS, which are loaded at 0x100 212 | // See https://www.raspberrypi.org/forums/viewtopic.php?f=72&t=293320 213 | .org 0x400 214 | 215 | #ifdef GIC 216 | 217 | setup_gic: // Called from secure mode - set all interrupts to group 1 and enable. 218 | mrs x0, MPIDR_EL1 219 | ldr x2, =GIC_DISTB 220 | tst x0, #0x3 221 | b.ne 2f // secondary cores 222 | 223 | mov w0, #3 // Enable group 0 and 1 IRQs from distributor 224 | str w0, [x2, #GICD_CTRLR] 225 | 2: 226 | add x1, x2, #(GIC_CPUB - GIC_DISTB) 227 | mov w0, #0x1e7 228 | str w0, [x1, #GICC_CTRLR] // Enable group 1 IRQs from CPU interface 229 | mov w0, #0xff 230 | str w0, [x1, #GICC_PMR] // priority mask 231 | add x2, x2, #GICD_IGROUPR 232 | mov x0, #(IT_NR * 4) 233 | mov w1, #~0 // group 1 all the things 234 | 3: 235 | subs x0, x0, #4 236 | str w1, [x2, x0] 237 | b.ne 3b 238 | ret 239 | 240 | #endif 241 | 242 | .globl dtb_space 243 | dtb_space: 244 | -------------------------------------------------------------------------------- /src/aarch64/kernel_pt.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | __attribute__((__aligned__(PAGE_SIZE))) PTEntries _kernel_pt_level3 = { 4 | 0x0 | PTE_KERNEL_DATA, 0x200000 | PTE_KERNEL_DATA, 0x400000 | PTE_KERNEL_DATA, 5 | 0x600000 | PTE_KERNEL_DATA, 0x800000 | PTE_KERNEL_DATA, 0xa00000 | PTE_KERNEL_DATA, 6 | 0xc00000 | PTE_KERNEL_DATA, 0xe00000 | PTE_KERNEL_DATA, 0x1000000 | PTE_KERNEL_DATA, 7 | 0x1200000 | PTE_KERNEL_DATA, 0x1400000 | PTE_KERNEL_DATA, 0x1600000 | PTE_KERNEL_DATA, 8 | 0x1800000 | PTE_KERNEL_DATA, 0x1a00000 | PTE_KERNEL_DATA, 0x1c00000 | PTE_KERNEL_DATA, 9 | 0x1e00000 | PTE_KERNEL_DATA, 0x2000000 | PTE_KERNEL_DATA, 0x2200000 | PTE_KERNEL_DATA, 10 | 0x2400000 | PTE_KERNEL_DATA, 0x2600000 | PTE_KERNEL_DATA, 0x2800000 | PTE_KERNEL_DATA, 11 | 0x2a00000 | PTE_KERNEL_DATA, 0x2c00000 | PTE_KERNEL_DATA, 0x2e00000 | PTE_KERNEL_DATA, 12 | 0x3000000 | PTE_KERNEL_DATA, 0x3200000 | PTE_KERNEL_DATA, 0x3400000 | PTE_KERNEL_DATA, 13 | 0x3600000 | PTE_KERNEL_DATA, 0x3800000 | PTE_KERNEL_DATA, 0x3a00000 | PTE_KERNEL_DATA, 14 | 0x3c00000 | PTE_KERNEL_DATA, 0x3e00000 | PTE_KERNEL_DATA, 0x4000000 | PTE_KERNEL_DATA, 15 | 0x4200000 | PTE_KERNEL_DATA, 0x4400000 | PTE_KERNEL_DATA, 0x4600000 | PTE_KERNEL_DATA, 16 | 0x4800000 | PTE_KERNEL_DATA, 0x4a00000 | PTE_KERNEL_DATA, 0x4c00000 | PTE_KERNEL_DATA, 17 | 0x4e00000 | PTE_KERNEL_DATA, 0x5000000 | PTE_KERNEL_DATA, 0x5200000 | PTE_KERNEL_DATA, 18 | 0x5400000 | PTE_KERNEL_DATA, 0x5600000 | PTE_KERNEL_DATA, 0x5800000 | PTE_KERNEL_DATA, 19 | 0x5a00000 | PTE_KERNEL_DATA, 0x5c00000 | PTE_KERNEL_DATA, 0x5e00000 | PTE_KERNEL_DATA, 20 | 0x6000000 | PTE_KERNEL_DATA, 0x6200000 | PTE_KERNEL_DATA, 0x6400000 | PTE_KERNEL_DATA, 21 | 0x6600000 | PTE_KERNEL_DATA, 0x6800000 | PTE_KERNEL_DATA, 0x6a00000 | PTE_KERNEL_DATA, 22 | 0x6c00000 | PTE_KERNEL_DATA, 0x6e00000 | PTE_KERNEL_DATA, 0x7000000 | PTE_KERNEL_DATA, 23 | 0x7200000 | PTE_KERNEL_DATA, 0x7400000 | PTE_KERNEL_DATA, 0x7600000 | PTE_KERNEL_DATA, 24 | 0x7800000 | PTE_KERNEL_DATA, 0x7a00000 | PTE_KERNEL_DATA, 0x7c00000 | PTE_KERNEL_DATA, 25 | 0x7e00000 | PTE_KERNEL_DATA, 0x8000000 | PTE_KERNEL_DATA, 0x8200000 | PTE_KERNEL_DATA, 26 | 0x8400000 | PTE_KERNEL_DATA, 0x8600000 | PTE_KERNEL_DATA, 0x8800000 | PTE_KERNEL_DATA, 27 | 0x8a00000 | PTE_KERNEL_DATA, 0x8c00000 | PTE_KERNEL_DATA, 0x8e00000 | PTE_KERNEL_DATA, 28 | 0x9000000 | PTE_KERNEL_DATA, 0x9200000 | PTE_KERNEL_DATA, 0x9400000 | PTE_KERNEL_DATA, 29 | 0x9600000 | PTE_KERNEL_DATA, 0x9800000 | PTE_KERNEL_DATA, 0x9a00000 | PTE_KERNEL_DATA, 30 | 0x9c00000 | PTE_KERNEL_DATA, 0x9e00000 | PTE_KERNEL_DATA, 0xa000000 | PTE_KERNEL_DATA, 31 | 0xa200000 | PTE_KERNEL_DATA, 0xa400000 | PTE_KERNEL_DATA, 0xa600000 | PTE_KERNEL_DATA, 32 | 0xa800000 | PTE_KERNEL_DATA, 0xaa00000 | PTE_KERNEL_DATA, 0xac00000 | PTE_KERNEL_DATA, 33 | 0xae00000 | PTE_KERNEL_DATA, 0xb000000 | PTE_KERNEL_DATA, 0xb200000 | PTE_KERNEL_DATA, 34 | 0xb400000 | PTE_KERNEL_DATA, 0xb600000 | PTE_KERNEL_DATA, 0xb800000 | PTE_KERNEL_DATA, 35 | 0xba00000 | PTE_KERNEL_DATA, 0xbc00000 | PTE_KERNEL_DATA, 0xbe00000 | PTE_KERNEL_DATA, 36 | 0xc000000 | PTE_KERNEL_DATA, 0xc200000 | PTE_KERNEL_DATA, 0xc400000 | PTE_KERNEL_DATA, 37 | 0xc600000 | PTE_KERNEL_DATA, 0xc800000 | PTE_KERNEL_DATA, 0xca00000 | PTE_KERNEL_DATA, 38 | 0xcc00000 | PTE_KERNEL_DATA, 0xce00000 | PTE_KERNEL_DATA, 0xd000000 | PTE_KERNEL_DATA, 39 | 0xd200000 | PTE_KERNEL_DATA, 0xd400000 | PTE_KERNEL_DATA, 0xd600000 | PTE_KERNEL_DATA, 40 | 0xd800000 | PTE_KERNEL_DATA, 0xda00000 | PTE_KERNEL_DATA, 0xdc00000 | PTE_KERNEL_DATA, 41 | 0xde00000 | PTE_KERNEL_DATA, 0xe000000 | PTE_KERNEL_DATA, 0xe200000 | PTE_KERNEL_DATA, 42 | 0xe400000 | PTE_KERNEL_DATA, 0xe600000 | PTE_KERNEL_DATA, 0xe800000 | PTE_KERNEL_DATA, 43 | 0xea00000 | PTE_KERNEL_DATA, 0xec00000 | PTE_KERNEL_DATA, 0xee00000 | PTE_KERNEL_DATA, 44 | 0xf000000 | PTE_KERNEL_DATA, 0xf200000 | PTE_KERNEL_DATA, 0xf400000 | PTE_KERNEL_DATA, 45 | 0xf600000 | PTE_KERNEL_DATA, 0xf800000 | PTE_KERNEL_DATA, 0xfa00000 | PTE_KERNEL_DATA, 46 | 0xfc00000 | PTE_KERNEL_DATA, 0xfe00000 | PTE_KERNEL_DATA, 0x10000000 | PTE_KERNEL_DATA, 47 | 0x10200000 | PTE_KERNEL_DATA, 0x10400000 | PTE_KERNEL_DATA, 0x10600000 | PTE_KERNEL_DATA, 48 | 0x10800000 | PTE_KERNEL_DATA, 0x10a00000 | PTE_KERNEL_DATA, 0x10c00000 | PTE_KERNEL_DATA, 49 | 0x10e00000 | PTE_KERNEL_DATA, 0x11000000 | PTE_KERNEL_DATA, 0x11200000 | PTE_KERNEL_DATA, 50 | 0x11400000 | PTE_KERNEL_DATA, 0x11600000 | PTE_KERNEL_DATA, 0x11800000 | PTE_KERNEL_DATA, 51 | 0x11a00000 | PTE_KERNEL_DATA, 0x11c00000 | PTE_KERNEL_DATA, 0x11e00000 | PTE_KERNEL_DATA, 52 | 0x12000000 | PTE_KERNEL_DATA, 0x12200000 | PTE_KERNEL_DATA, 0x12400000 | PTE_KERNEL_DATA, 53 | 0x12600000 | PTE_KERNEL_DATA, 0x12800000 | PTE_KERNEL_DATA, 0x12a00000 | PTE_KERNEL_DATA, 54 | 0x12c00000 | PTE_KERNEL_DATA, 0x12e00000 | PTE_KERNEL_DATA, 0x13000000 | PTE_KERNEL_DATA, 55 | 0x13200000 | PTE_KERNEL_DATA, 0x13400000 | PTE_KERNEL_DATA, 0x13600000 | PTE_KERNEL_DATA, 56 | 0x13800000 | PTE_KERNEL_DATA, 0x13a00000 | PTE_KERNEL_DATA, 0x13c00000 | PTE_KERNEL_DATA, 57 | 0x13e00000 | PTE_KERNEL_DATA, 0x14000000 | PTE_KERNEL_DATA, 0x14200000 | PTE_KERNEL_DATA, 58 | 0x14400000 | PTE_KERNEL_DATA, 0x14600000 | PTE_KERNEL_DATA, 0x14800000 | PTE_KERNEL_DATA, 59 | 0x14a00000 | PTE_KERNEL_DATA, 0x14c00000 | PTE_KERNEL_DATA, 0x14e00000 | PTE_KERNEL_DATA, 60 | 0x15000000 | PTE_KERNEL_DATA, 0x15200000 | PTE_KERNEL_DATA, 0x15400000 | PTE_KERNEL_DATA, 61 | 0x15600000 | PTE_KERNEL_DATA, 0x15800000 | PTE_KERNEL_DATA, 0x15a00000 | PTE_KERNEL_DATA, 62 | 0x15c00000 | PTE_KERNEL_DATA, 0x15e00000 | PTE_KERNEL_DATA, 0x16000000 | PTE_KERNEL_DATA, 63 | 0x16200000 | PTE_KERNEL_DATA, 0x16400000 | PTE_KERNEL_DATA, 0x16600000 | PTE_KERNEL_DATA, 64 | 0x16800000 | PTE_KERNEL_DATA, 0x16a00000 | PTE_KERNEL_DATA, 0x16c00000 | PTE_KERNEL_DATA, 65 | 0x16e00000 | PTE_KERNEL_DATA, 0x17000000 | PTE_KERNEL_DATA, 0x17200000 | PTE_KERNEL_DATA, 66 | 0x17400000 | PTE_KERNEL_DATA, 0x17600000 | PTE_KERNEL_DATA, 0x17800000 | PTE_KERNEL_DATA, 67 | 0x17a00000 | PTE_KERNEL_DATA, 0x17c00000 | PTE_KERNEL_DATA, 0x17e00000 | PTE_KERNEL_DATA, 68 | 0x18000000 | PTE_KERNEL_DATA, 0x18200000 | PTE_KERNEL_DATA, 0x18400000 | PTE_KERNEL_DATA, 69 | 0x18600000 | PTE_KERNEL_DATA, 0x18800000 | PTE_KERNEL_DATA, 0x18a00000 | PTE_KERNEL_DATA, 70 | 0x18c00000 | PTE_KERNEL_DATA, 0x18e00000 | PTE_KERNEL_DATA, 0x19000000 | PTE_KERNEL_DATA, 71 | 0x19200000 | PTE_KERNEL_DATA, 0x19400000 | PTE_KERNEL_DATA, 0x19600000 | PTE_KERNEL_DATA, 72 | 0x19800000 | PTE_KERNEL_DATA, 0x19a00000 | PTE_KERNEL_DATA, 0x19c00000 | PTE_KERNEL_DATA, 73 | 0x19e00000 | PTE_KERNEL_DATA, 0x1a000000 | PTE_KERNEL_DATA, 0x1a200000 | PTE_KERNEL_DATA, 74 | 0x1a400000 | PTE_KERNEL_DATA, 0x1a600000 | PTE_KERNEL_DATA, 0x1a800000 | PTE_KERNEL_DATA, 75 | 0x1aa00000 | PTE_KERNEL_DATA, 0x1ac00000 | PTE_KERNEL_DATA, 0x1ae00000 | PTE_KERNEL_DATA, 76 | 0x1b000000 | PTE_KERNEL_DATA, 0x1b200000 | PTE_KERNEL_DATA, 0x1b400000 | PTE_KERNEL_DATA, 77 | 0x1b600000 | PTE_KERNEL_DATA, 0x1b800000 | PTE_KERNEL_DATA, 0x1ba00000 | PTE_KERNEL_DATA, 78 | 0x1bc00000 | PTE_KERNEL_DATA, 0x1be00000 | PTE_KERNEL_DATA, 0x1c000000 | PTE_KERNEL_DATA, 79 | 0x1c200000 | PTE_KERNEL_DATA, 0x1c400000 | PTE_KERNEL_DATA, 0x1c600000 | PTE_KERNEL_DATA, 80 | 0x1c800000 | PTE_KERNEL_DATA, 0x1ca00000 | PTE_KERNEL_DATA, 0x1cc00000 | PTE_KERNEL_DATA, 81 | 0x1ce00000 | PTE_KERNEL_DATA, 0x1d000000 | PTE_KERNEL_DATA, 0x1d200000 | PTE_KERNEL_DATA, 82 | 0x1d400000 | PTE_KERNEL_DATA, 0x1d600000 | PTE_KERNEL_DATA, 0x1d800000 | PTE_KERNEL_DATA, 83 | 0x1da00000 | PTE_KERNEL_DATA, 0x1dc00000 | PTE_KERNEL_DATA, 0x1de00000 | PTE_KERNEL_DATA, 84 | 0x1e000000 | PTE_KERNEL_DATA, 0x1e200000 | PTE_KERNEL_DATA, 0x1e400000 | PTE_KERNEL_DATA, 85 | 0x1e600000 | PTE_KERNEL_DATA, 0x1e800000 | PTE_KERNEL_DATA, 0x1ea00000 | PTE_KERNEL_DATA, 86 | 0x1ec00000 | PTE_KERNEL_DATA, 0x1ee00000 | PTE_KERNEL_DATA, 0x1f000000 | PTE_KERNEL_DATA, 87 | 0x1f200000 | PTE_KERNEL_DATA, 0x1f400000 | PTE_KERNEL_DATA, 0x1f600000 | PTE_KERNEL_DATA, 88 | 0x1f800000 | PTE_KERNEL_DATA, 0x1fa00000 | PTE_KERNEL_DATA, 0x1fc00000 | PTE_KERNEL_DATA, 89 | 0x1fe00000 | PTE_KERNEL_DATA, 0x20000000 | PTE_KERNEL_DATA, 0x20200000 | PTE_KERNEL_DATA, 90 | 0x20400000 | PTE_KERNEL_DATA, 0x20600000 | PTE_KERNEL_DATA, 0x20800000 | PTE_KERNEL_DATA, 91 | 0x20a00000 | PTE_KERNEL_DATA, 0x20c00000 | PTE_KERNEL_DATA, 0x20e00000 | PTE_KERNEL_DATA, 92 | 0x21000000 | PTE_KERNEL_DATA, 0x21200000 | PTE_KERNEL_DATA, 0x21400000 | PTE_KERNEL_DATA, 93 | 0x21600000 | PTE_KERNEL_DATA, 0x21800000 | PTE_KERNEL_DATA, 0x21a00000 | PTE_KERNEL_DATA, 94 | 0x21c00000 | PTE_KERNEL_DATA, 0x21e00000 | PTE_KERNEL_DATA, 0x22000000 | PTE_KERNEL_DATA, 95 | 0x22200000 | PTE_KERNEL_DATA, 0x22400000 | PTE_KERNEL_DATA, 0x22600000 | PTE_KERNEL_DATA, 96 | 0x22800000 | PTE_KERNEL_DATA, 0x22a00000 | PTE_KERNEL_DATA, 0x22c00000 | PTE_KERNEL_DATA, 97 | 0x22e00000 | PTE_KERNEL_DATA, 0x23000000 | PTE_KERNEL_DATA, 0x23200000 | PTE_KERNEL_DATA, 98 | 0x23400000 | PTE_KERNEL_DATA, 0x23600000 | PTE_KERNEL_DATA, 0x23800000 | PTE_KERNEL_DATA, 99 | 0x23a00000 | PTE_KERNEL_DATA, 0x23c00000 | PTE_KERNEL_DATA, 0x23e00000 | PTE_KERNEL_DATA, 100 | 0x24000000 | PTE_KERNEL_DATA, 0x24200000 | PTE_KERNEL_DATA, 0x24400000 | PTE_KERNEL_DATA, 101 | 0x24600000 | PTE_KERNEL_DATA, 0x24800000 | PTE_KERNEL_DATA, 0x24a00000 | PTE_KERNEL_DATA, 102 | 0x24c00000 | PTE_KERNEL_DATA, 0x24e00000 | PTE_KERNEL_DATA, 0x25000000 | PTE_KERNEL_DATA, 103 | 0x25200000 | PTE_KERNEL_DATA, 0x25400000 | PTE_KERNEL_DATA, 0x25600000 | PTE_KERNEL_DATA, 104 | 0x25800000 | PTE_KERNEL_DATA, 0x25a00000 | PTE_KERNEL_DATA, 0x25c00000 | PTE_KERNEL_DATA, 105 | 0x25e00000 | PTE_KERNEL_DATA, 0x26000000 | PTE_KERNEL_DATA, 0x26200000 | PTE_KERNEL_DATA, 106 | 0x26400000 | PTE_KERNEL_DATA, 0x26600000 | PTE_KERNEL_DATA, 0x26800000 | PTE_KERNEL_DATA, 107 | 0x26a00000 | PTE_KERNEL_DATA, 0x26c00000 | PTE_KERNEL_DATA, 0x26e00000 | PTE_KERNEL_DATA, 108 | 0x27000000 | PTE_KERNEL_DATA, 0x27200000 | PTE_KERNEL_DATA, 0x27400000 | PTE_KERNEL_DATA, 109 | 0x27600000 | PTE_KERNEL_DATA, 0x27800000 | PTE_KERNEL_DATA, 0x27a00000 | PTE_KERNEL_DATA, 110 | 0x27c00000 | PTE_KERNEL_DATA, 0x27e00000 | PTE_KERNEL_DATA, 0x28000000 | PTE_KERNEL_DATA, 111 | 0x28200000 | PTE_KERNEL_DATA, 0x28400000 | PTE_KERNEL_DATA, 0x28600000 | PTE_KERNEL_DATA, 112 | 0x28800000 | PTE_KERNEL_DATA, 0x28a00000 | PTE_KERNEL_DATA, 0x28c00000 | PTE_KERNEL_DATA, 113 | 0x28e00000 | PTE_KERNEL_DATA, 0x29000000 | PTE_KERNEL_DATA, 0x29200000 | PTE_KERNEL_DATA, 114 | 0x29400000 | PTE_KERNEL_DATA, 0x29600000 | PTE_KERNEL_DATA, 0x29800000 | PTE_KERNEL_DATA, 115 | 0x29a00000 | PTE_KERNEL_DATA, 0x29c00000 | PTE_KERNEL_DATA, 0x29e00000 | PTE_KERNEL_DATA, 116 | 0x2a000000 | PTE_KERNEL_DATA, 0x2a200000 | PTE_KERNEL_DATA, 0x2a400000 | PTE_KERNEL_DATA, 117 | 0x2a600000 | PTE_KERNEL_DATA, 0x2a800000 | PTE_KERNEL_DATA, 0x2aa00000 | PTE_KERNEL_DATA, 118 | 0x2ac00000 | PTE_KERNEL_DATA, 0x2ae00000 | PTE_KERNEL_DATA, 0x2b000000 | PTE_KERNEL_DATA, 119 | 0x2b200000 | PTE_KERNEL_DATA, 0x2b400000 | PTE_KERNEL_DATA, 0x2b600000 | PTE_KERNEL_DATA, 120 | 0x2b800000 | PTE_KERNEL_DATA, 0x2ba00000 | PTE_KERNEL_DATA, 0x2bc00000 | PTE_KERNEL_DATA, 121 | 0x2be00000 | PTE_KERNEL_DATA, 0x2c000000 | PTE_KERNEL_DATA, 0x2c200000 | PTE_KERNEL_DATA, 122 | 0x2c400000 | PTE_KERNEL_DATA, 0x2c600000 | PTE_KERNEL_DATA, 0x2c800000 | PTE_KERNEL_DATA, 123 | 0x2ca00000 | PTE_KERNEL_DATA, 0x2cc00000 | PTE_KERNEL_DATA, 0x2ce00000 | PTE_KERNEL_DATA, 124 | 0x2d000000 | PTE_KERNEL_DATA, 0x2d200000 | PTE_KERNEL_DATA, 0x2d400000 | PTE_KERNEL_DATA, 125 | 0x2d600000 | PTE_KERNEL_DATA, 0x2d800000 | PTE_KERNEL_DATA, 0x2da00000 | PTE_KERNEL_DATA, 126 | 0x2dc00000 | PTE_KERNEL_DATA, 0x2de00000 | PTE_KERNEL_DATA, 0x2e000000 | PTE_KERNEL_DATA, 127 | 0x2e200000 | PTE_KERNEL_DATA, 0x2e400000 | PTE_KERNEL_DATA, 0x2e600000 | PTE_KERNEL_DATA, 128 | 0x2e800000 | PTE_KERNEL_DATA, 0x2ea00000 | PTE_KERNEL_DATA, 0x2ec00000 | PTE_KERNEL_DATA, 129 | 0x2ee00000 | PTE_KERNEL_DATA, 0x2f000000 | PTE_KERNEL_DATA, 0x2f200000 | PTE_KERNEL_DATA, 130 | 0x2f400000 | PTE_KERNEL_DATA, 0x2f600000 | PTE_KERNEL_DATA, 0x2f800000 | PTE_KERNEL_DATA, 131 | 0x2fa00000 | PTE_KERNEL_DATA, 0x2fc00000 | PTE_KERNEL_DATA, 0x2fe00000 | PTE_KERNEL_DATA, 132 | 0x30000000 | PTE_KERNEL_DATA, 0x30200000 | PTE_KERNEL_DATA, 0x30400000 | PTE_KERNEL_DATA, 133 | 0x30600000 | PTE_KERNEL_DATA, 0x30800000 | PTE_KERNEL_DATA, 0x30a00000 | PTE_KERNEL_DATA, 134 | 0x30c00000 | PTE_KERNEL_DATA, 0x30e00000 | PTE_KERNEL_DATA, 0x31000000 | PTE_KERNEL_DATA, 135 | 0x31200000 | PTE_KERNEL_DATA, 0x31400000 | PTE_KERNEL_DATA, 0x31600000 | PTE_KERNEL_DATA, 136 | 0x31800000 | PTE_KERNEL_DATA, 0x31a00000 | PTE_KERNEL_DATA, 0x31c00000 | PTE_KERNEL_DATA, 137 | 0x31e00000 | PTE_KERNEL_DATA, 0x32000000 | PTE_KERNEL_DATA, 0x32200000 | PTE_KERNEL_DATA, 138 | 0x32400000 | PTE_KERNEL_DATA, 0x32600000 | PTE_KERNEL_DATA, 0x32800000 | PTE_KERNEL_DATA, 139 | 0x32a00000 | PTE_KERNEL_DATA, 0x32c00000 | PTE_KERNEL_DATA, 0x32e00000 | PTE_KERNEL_DATA, 140 | 0x33000000 | PTE_KERNEL_DATA, 0x33200000 | PTE_KERNEL_DATA, 0x33400000 | PTE_KERNEL_DATA, 141 | 0x33600000 | PTE_KERNEL_DATA, 0x33800000 | PTE_KERNEL_DATA, 0x33a00000 | PTE_KERNEL_DATA, 142 | 0x33c00000 | PTE_KERNEL_DATA, 0x33e00000 | PTE_KERNEL_DATA, 0x34000000 | PTE_KERNEL_DATA, 143 | 0x34200000 | PTE_KERNEL_DATA, 0x34400000 | PTE_KERNEL_DATA, 0x34600000 | PTE_KERNEL_DATA, 144 | 0x34800000 | PTE_KERNEL_DATA, 0x34a00000 | PTE_KERNEL_DATA, 0x34c00000 | PTE_KERNEL_DATA, 145 | 0x34e00000 | PTE_KERNEL_DATA, 0x35000000 | PTE_KERNEL_DATA, 0x35200000 | PTE_KERNEL_DATA, 146 | 0x35400000 | PTE_KERNEL_DATA, 0x35600000 | PTE_KERNEL_DATA, 0x35800000 | PTE_KERNEL_DATA, 147 | 0x35a00000 | PTE_KERNEL_DATA, 0x35c00000 | PTE_KERNEL_DATA, 0x35e00000 | PTE_KERNEL_DATA, 148 | 0x36000000 | PTE_KERNEL_DATA, 0x36200000 | PTE_KERNEL_DATA, 0x36400000 | PTE_KERNEL_DATA, 149 | 0x36600000 | PTE_KERNEL_DATA, 0x36800000 | PTE_KERNEL_DATA, 0x36a00000 | PTE_KERNEL_DATA, 150 | 0x36c00000 | PTE_KERNEL_DATA, 0x36e00000 | PTE_KERNEL_DATA, 0x37000000 | PTE_KERNEL_DATA, 151 | 0x37200000 | PTE_KERNEL_DATA, 0x37400000 | PTE_KERNEL_DATA, 0x37600000 | PTE_KERNEL_DATA, 152 | 0x37800000 | PTE_KERNEL_DATA, 0x37a00000 | PTE_KERNEL_DATA, 0x37c00000 | PTE_KERNEL_DATA, 153 | 0x37e00000 | PTE_KERNEL_DATA, 0x38000000 | PTE_KERNEL_DATA, 0x38200000 | PTE_KERNEL_DATA, 154 | 0x38400000 | PTE_KERNEL_DATA, 0x38600000 | PTE_KERNEL_DATA, 0x38800000 | PTE_KERNEL_DATA, 155 | 0x38a00000 | PTE_KERNEL_DATA, 0x38c00000 | PTE_KERNEL_DATA, 0x38e00000 | PTE_KERNEL_DATA, 156 | 0x39000000 | PTE_KERNEL_DATA, 0x39200000 | PTE_KERNEL_DATA, 0x39400000 | PTE_KERNEL_DATA, 157 | 0x39600000 | PTE_KERNEL_DATA, 0x39800000 | PTE_KERNEL_DATA, 0x39a00000 | PTE_KERNEL_DATA, 158 | 0x39c00000 | PTE_KERNEL_DATA, 0x39e00000 | PTE_KERNEL_DATA, 0x3a000000 | PTE_KERNEL_DATA, 159 | 0x3a200000 | PTE_KERNEL_DATA, 0x3a400000 | PTE_KERNEL_DATA, 0x3a600000 | PTE_KERNEL_DATA, 160 | 0x3a800000 | PTE_KERNEL_DATA, 0x3aa00000 | PTE_KERNEL_DATA, 0x3ac00000 | PTE_KERNEL_DATA, 161 | 0x3ae00000 | PTE_KERNEL_DATA, 0x3b000000 | PTE_KERNEL_DATA, 0x3b200000 | PTE_KERNEL_DATA, 162 | 0x3b400000 | PTE_KERNEL_DATA, 0x3b600000 | PTE_KERNEL_DATA, 0x3b800000 | PTE_KERNEL_DATA, 163 | 0x3ba00000 | PTE_KERNEL_DATA, 0x3bc00000 | PTE_KERNEL_DATA, 0x3be00000 | PTE_KERNEL_DATA, 164 | 0x3c000000 | PTE_KERNEL_DATA, 0x3c200000 | PTE_KERNEL_DATA, 0x3c400000 | PTE_KERNEL_DATA, 165 | 0x3c600000 | PTE_KERNEL_DATA, 0x3c800000 | PTE_KERNEL_DATA, 0x3ca00000 | PTE_KERNEL_DATA, 166 | 0x3cc00000 | PTE_KERNEL_DATA, 0x3ce00000 | PTE_KERNEL_DATA, 0x3d000000 | PTE_KERNEL_DATA, 167 | 0x3d200000 | PTE_KERNEL_DATA, 0x3d400000 | PTE_KERNEL_DATA, 0x3d600000 | PTE_KERNEL_DATA, 168 | 0x3d800000 | PTE_KERNEL_DATA, 0x3da00000 | PTE_KERNEL_DATA, 0x3dc00000 | PTE_KERNEL_DATA, 169 | 0x3de00000 | PTE_KERNEL_DATA, 0x3e000000 | PTE_KERNEL_DATA, 0x3e200000 | PTE_KERNEL_DATA, 170 | 0x3e400000 | PTE_KERNEL_DATA, 0x3e600000 | PTE_KERNEL_DATA, 0x3e800000 | PTE_KERNEL_DATA, 171 | 0x3ea00000 | PTE_KERNEL_DATA, 0x3ec00000 | PTE_KERNEL_DATA, 0x3ee00000 | PTE_KERNEL_DATA, 172 | 0x3f000000 | PTE_KERNEL_DEVICE, 0x3f200000 | PTE_KERNEL_DEVICE, 0x3f400000 | PTE_KERNEL_DEVICE, 173 | 0x3f600000 | PTE_KERNEL_DEVICE, 0x3f800000 | PTE_KERNEL_DEVICE, 0x3fa00000 | PTE_KERNEL_DEVICE, 174 | 0x3fc00000 | PTE_KERNEL_DEVICE, 0x3fe00000 | PTE_KERNEL_DEVICE}; 175 | 176 | __attribute__((__aligned__(PAGE_SIZE))) PTEntries _kernel_pt_level2 = { 177 | K2P(_kernel_pt_level3) + PTE_TABLE, 178 | 0x40000000 | PTE_KERNEL_DEVICE, 179 | 0, 180 | 0xC0000000 | PTE_KERNEL_DEVICE, 181 | }; 182 | 183 | // the first level of kernel PT (page table). 184 | __attribute__((__aligned__(PAGE_SIZE))) PTEntries kernel_pt = {K2P(_kernel_pt_level2) + PTE_TABLE}; 185 | --------------------------------------------------------------------------------