Fix setup of usermode stack and added final system call to exit.

This commit is contained in:
Patrick 2024-01-27 22:51:45 +01:00
parent 193e3a19dc
commit 3fff3bd8fc
6 changed files with 26 additions and 6 deletions

View File

@ -14,7 +14,7 @@ AddOption(
target = GetOption('target') target = GetOption('target')
env = Environment(tools = ['default', 'compilation_db']) env = Environment(tools = ['default', 'compilation_db'])
env.Append(CCFLAGS = ['-g', '-O0']) env.Append(CCFLAGS = ['-g', '-O0', '-fno-stack-protector'])
env.Append(CPPDEFINES = ['BASTL_EXTENSIONS=1']) env.Append(CPPDEFINES = ['BASTL_EXTENSIONS=1'])
# env.Append(CCFLAGS = ['-O2']) # env.Append(CCFLAGS = ['-O2'])

View File

@ -12,7 +12,8 @@ namespace baos
enum class Syscall : std::uint64_t enum class Syscall : std::uint64_t
{ {
FILE_READ = 0, FILE_READ = 0,
FILE_WRITE = 1 FILE_WRITE = 1,
EXIT = 0x3C
}; };
void setupSyscall() noexcept; void setupSyscall() noexcept;

View File

@ -108,7 +108,7 @@ void cmdDumpPageTable() noexcept
} }
} }
extern "C" void main() extern "C" void usermode_main()
{ {
std::string cmd; std::string cmd;
while(true) while(true)
@ -132,6 +132,10 @@ extern "C" void main()
cmdDumpPageTable(); cmdDumpPageTable();
continue; continue;
} }
else if (cmd == "exit")
{
return;
}
std::printf("Unknown command: %s.\n", cmd.c_str()); std::printf("Unknown command: %s.\n", cmd.c_str());
} }
} }

View File

@ -46,5 +46,7 @@ extern "C" void __baosSyscall(baos::Syscall cmd, std::uint64_t param0, std::uint
case Syscall::FILE_WRITE: case Syscall::FILE_WRITE:
sysFileWrite(static_cast<unsigned>(param0), std::bit_cast<const char*>(param1), param2); sysFileWrite(static_cast<unsigned>(param0), std::bit_cast<const char*>(param1), param2);
break; break;
case Syscall::EXIT:
break;
} }
} }

View File

@ -103,6 +103,12 @@ __enterUsermode:
movw %si, %fs movw %si, %fs
movw %si, %gs movw %si, %gs
// the ABI expects the stack pointer to be 16-byte aligned BEFORE calling the function
// i.e. after pushing the instruction pointer, and when arriving in the function, it should be offset by 8 byte
// since we're not using a regular call, manually offset the stack pointer by 8 bytes and write the "return" address
subq $8, %r8
movq $__exitUsermode, (%r8)
movq %rsp, (%rdx) movq %rsp, (%rdx)
pushq %rsi // data segment pushq %rsi // data segment
pushq %r8 pushq %r8
@ -111,10 +117,16 @@ __enterUsermode:
pushq %rcx pushq %rcx
iretq iretq
__exitUsermode:
movq $0x3C, %rdi
syscall
jmp __exitUsermode
.global __handleSyscall .global __handleSyscall
.type __handleSyscall @function .type __handleSyscall @function
// void __handleSyscall() // void __handleSyscall()
__handleSyscall: __handleSyscall:
enter $0, $0
pushq %rcx // store the original instruction pointer pushq %rcx // store the original instruction pointer
pushq %rsp // also store the original stack pointer pushq %rsp // also store the original stack pointer
movq %r8, %rcx movq %r8, %rcx
@ -122,6 +134,7 @@ __handleSyscall:
call __baosSyscall call __baosSyscall
popq %rsp popq %rsp
popq %rcx popq %rcx
leave
sysretq sysretq
/* /*

View File

@ -186,7 +186,7 @@ extern "C"
{ {
EfiBootInfo* gBootInfo; EfiBootInfo* gBootInfo;
void main(); void usermode_main();
void kernel_main() void kernel_main()
{ {
@ -284,7 +284,7 @@ void kernel_main()
initializePCIDevice(header); initializePCIDevice(header);
} }
static std::array<std::uint8_t, 16384> usermodeStack; static std::array<std::uint8_t, 16384> usermodeStack alignas(16);
__enterUsermode(SEGIDX_USER_CODE, SEGIDX_USER_DATA, &tss.rsp0, &main, &usermodeStack.back()); __enterUsermode(SEGIDX_USER_CODE, SEGIDX_USER_DATA, &tss.rsp0, &usermode_main, &usermodeStack.back() + 1);
} }
} // extern "C" } // extern "C"