We can *actually* load commercial carts now

This commit is contained in:
wheremyfoodat 2022-10-03 20:18:14 +03:00
parent 87bf469447
commit fca54b99a7
2 changed files with 45 additions and 7 deletions

View file

@ -73,14 +73,50 @@ std::optional<NCSD> Memory::loadNCSD(const std::filesystem::path& path) {
printf("NCSD with an invalid CXI in partition 0?\n"); printf("NCSD with an invalid CXI in partition 0?\n");
return std::nullopt; return std::nullopt;
} }
printf("Text address = %08X, page count = %08X\n", cxi.text.address, cxi.text.size);
printf("Rodata address = %08X, page count = %08X\n", cxi.rodata.address, cxi.rodata.size);
printf("Data address = %08X, page count = %08X\n", cxi.data.address, cxi.data.size);
// Map code file to memory // Map code file to memory
const auto& code = cxi.codeFile; auto& code = cxi.codeFile;
printf("Text address = %08X page count = %08X\n", cxi.text.address, cxi.text.size); u32 bssSize = (cxi.bssSize + 0xfff) & ~0xfff; // Round BSS size up to a page boundary
printf("Rodata address = %08X page count = %08X\n", cxi.rodata.address, cxi.rodata.size); // Total memory to allocate for loading
printf("Data address = %08X page count = %08X\n", cxi.data.address, cxi.data.size); u32 totalSize = (cxi.text.pageCount + cxi.rodata.pageCount + cxi.data.pageCount) * pageSize + bssSize;
code.resize(code.size() + bssSize, 0); // Pad the .code file with zeroes for the BSS segment
ncsd.entrypoint = cxi.text.address; if (code.size() < totalSize) {
Helpers::panic("Total code size as reported by the exheader is larger than the .code file");
return std::nullopt;
}
const auto opt = findPaddr(totalSize);
if (!opt.has_value()) {
Helpers::panic("Failed to find paddr to map CXI file's code to");
return std::nullopt;
}
const auto paddr = opt.value();
std::memcpy(&fcram[paddr], &code[0], totalSize); // Copy the 3 segments + BSS to FCRAM
// Map the ROM on the kernel side
u32 textOffset = 0;
u32 textAddr = cxi.text.address;
u32 textSize = cxi.text.pageCount * pageSize;
u32 rodataOffset = textOffset + textSize;
u32 rodataAddr = cxi.rodata.address;
u32 rodataSize = cxi.rodata.pageCount * pageSize;
u32 dataOffset = rodataOffset + rodataSize;
u32 dataAddr = cxi.data.address;
u32 dataSize = cxi.data.pageCount * pageSize + bssSize; // We're merging the data and BSS segments, as BSS is just pre-initted .data
allocateMemory(textAddr, paddr + textOffset, textSize, true, true, false, true); // Text is R-X
allocateMemory(rodataAddr, paddr + rodataOffset, rodataSize, true, true, false, false); // Rodata is R--
allocateMemory(dataAddr, paddr + dataOffset, dataSize, true, true, true, false); // Data+BSS is RW-
ncsd.entrypoint = textAddr;
return ncsd; return ncsd;
} }

View file

@ -67,9 +67,11 @@ void ServiceManager::getServiceHandle(u32 messagePointer) {
std::string service = mem.readString(messagePointer + 4, 8); std::string service = mem.readString(messagePointer + 4, 8);
log("srv::getServiceHandle (Service: %s, nameLength: %d, flags: %d)\n", service.c_str(), nameLength, flags); log("srv::getServiceHandle (Service: %s, nameLength: %d, flags: %d)\n", service.c_str(), nameLength, flags);
if (service == "APT:S") { if (service == "APT:S") { // TODO: APT:A, APT:S and APT:U are slightly different
handle = KernelHandles::APT; handle = KernelHandles::APT;
} else if (service == "APT:A") { // TODO: APT:A and APT:S are slightly different } else if (service == "APT:A") {
handle = KernelHandles::APT;
} else if (service == "APT:U") {
handle = KernelHandles::APT; handle = KernelHandles::APT;
} else if (service == "hid:USER") { } else if (service == "hid:USER") {
handle = KernelHandles::HID; handle = KernelHandles::HID;