Fix setup of usermode stack and added final system call to exit.
This commit is contained in:
parent
193e3a19dc
commit
3fff3bd8fc
@ -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'])
|
||||||
|
|
||||||
|
@ -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;
|
||||||
|
@ -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());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -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"
|
||||||
|
Loading…
x
Reference in New Issue
Block a user