Project

General

Profile

Actions

Emulator Issues #12939

closed

regression: running loose elf/dol with virtual disc

Added by Anonymous almost 2 years ago. Updated over 1 year ago.

Status:
Won't fix
Priority:
Normal
Assignee:
-
% Done:

0%

Operating system:
N/A
Issue type:
Bug
Milestone:
Regression:
No
Relates to usability:
No
Relates to performance:
No
Easy:
No
Relates to maintainability:
No
Regression start:
Fixed in:

Description

For quite a long time it was possible to manually set the directory which the DirectoryBlob code would use to create a virtual disc. This could be used along with executing a elf/dol for easily running any executable as if it was in an image file consisting of the loose files.

At some point, DirectoryBlob became more strict and now requires some community-invented directory layout in order to consider a directory structured as a valid virtual disc. Currently, that means the following must exist:

sys

  • main.dol
  • boot.bin

first off, it should be noted that if the above exist, the code then implicitly relies on the following being present:

sys

  • main.dol
  • boot.bin
  • bi2.bin
  • apploader.img
    files

it seems like if these extra files don't actually exist, you'll get the "failed to init core" message, which is fairly vague. Dolphin should either sanity check them up-front and show proper error, or create some default-initialized placeholders that work most of the time.

Finally, (and the main point of this issue) is that there is no way to boot from elf in this setup, which is a major regression and should be fixed (just allow "main.elf" as well?).

Actions #1

Updated by JosJuice almost 2 years ago

Is the bug that Dolphin does not create a virtual disc in memory as it should, or just that it fails to boot it? If it's the latter, you should set the Default ISO path to the sys/main.dol file of a virtual disc (the actual content of this DOL file doesn't really matter), and then launch the DOL/ELF file you want to run from a location which is not part of the virtual disc.

Actions #2

Updated by Anonymous almost 2 years ago

That is similar to how it used to work (using "default iso"). The problem now seems to be that IsValidDirectoryBlob checks explicitly for "/sys/main.dol". Currently if Default ISO is set and a elf file is launched, IsValidDirectoryBlob is called with the path to the elf, and DirectoryBlob object is not created.

Actions #3

Updated by Anonymous almost 2 years ago

So after setting default iso to a path which ends in "/sys/main.dol", and executing an elf file, the problem is that the apploader is not executed and therefor the value at 0x80000038 remains 0, while it should point to the fst. The proper thing to do is to convert the elf to a dol in memory (accessible via the virtual disc), and run the apploader. I assume this (effectively) happened before.

Actions #4

Updated by JosJuice almost 2 years ago

Dolphin never ran apploaders for ELF files, but it seems like it did write to 0x80000038 manually. I dropped that part of the code, presumably because it seemed to be of no use for running games, but I suppose there would be no harm in readding it.

https://github.com/dolphin-emu/dolphin/blob/5.0/Source/Core/Core/Boot/Boot.cpp#L76

Actions #5

Updated by Anonymous almost 2 years ago

I think it was covered before by running apploader https://github.com/dolphin-emu/dolphin/blob/5.0/Source/Core/Core/Boot/Boot.cpp#L413 or initialized by dolphin, yes. Is it worth doing 'correctly' now, or just always initializing the fields in e.g. here https://github.com/dolphin-emu/dolphin/blob/master/Source/Core/Core/Boot/Boot.cpp#L544 ?

Actions #6

Updated by Anonymous almost 2 years ago

if i manually convert the elf to dol outside of dolphin, then add some code to run apploader, it at least works:

diff --git a/Source/Core/Core/Boot/Boot.cpp b/Source/Core/Core/Boot/Boot.cpp
index 0ad7f6ec12..cd27d8ff33 100644
--- a/Source/Core/Core/Boot/Boot.cpp
+++ b/Source/Core/Core/Boot/Boot.cpp
@@ -466,11 +466,12 @@ bool CBoot::Load_BS2(const std::string& boot_rom_filename)
   return true;
 }

-static void SetDefaultDisc()
+static std::optional<const DiscIO::VolumeDisc*> SetDefaultDisc()
 {
   const std::string default_iso = Config::Get(Config::MAIN_DEFAULT_ISO);
   if (!default_iso.empty())
-    SetDisc(DiscIO::CreateDisc(default_iso));
+    return SetDisc(DiscIO::CreateDisc(default_iso));
+  return {};
 }

 static void CopyDefaultExceptionHandlers()
@@ -529,14 +530,16 @@ bool CBoot::BootUp(std::unique_ptr<BootParameters> boot)
       if (!executable.reader->IsValid())
         return false;

-      if (!executable.reader->LoadIntoMemory())
+      auto default_disc = SetDefaultDisc();
+      if (!default_disc)
       {
-        PanicAlertFmtT("Failed to load the executable to memory.");
-        return false;
+        if (!executable.reader->LoadIntoMemory())
+        {
+          PanicAlertFmtT("Failed to load the executable to memory.");
+          return false;
+        }
       }

-      SetDefaultDisc();
-
       SetupMSR();
       SetupBAT(config.bWii);
       CopyDefaultExceptionHandlers();
@@ -560,6 +563,11 @@ bool CBoot::BootUp(std::unique_ptr<BootParameters> boot)
         SetupGCMemory();
       }

+      if (default_disc)
+      {
+        RunApploader(config.bWii, **default_disc, {});
+      }
+
       SConfig::OnNewTitleLoad();

       PC = executable.reader->GetEntryPoint();
diff --git a/Source/Core/Core/Boot/Boot_BS2Emu.cpp b/Source/Core/Core/Boot/Boot_BS2Emu.cpp
index 1265317a90..feec60b4cd 100644
--- a/Source/Core/Core/Boot/Boot_BS2Emu.cpp
+++ b/Source/Core/Core/Boot/Boot_BS2Emu.cpp
@@ -372,7 +372,7 @@ bool CBoot::SetupWiiMemory(IOS::HLE::IOSC::ConsoleType console_type)
   values in this region will also be placed here by the game as it boots.
   They are:
   0x80000038  Start of FST
-  0x8000003c  Size of FST Size
+  0x8000003c  Size of FST
   0x80000060  Copyright code
   */

diff --git a/Source/Core/DiscIO/DirectoryBlob.cpp b/Source/Core/DiscIO/DirectoryBlob.cpp
index 86de55595a..30005759b5 100644
--- a/Source/Core/DiscIO/DirectoryBlob.cpp
+++ b/Source/Core/DiscIO/DirectoryBlob.cpp
@@ -1087,7 +1087,7 @@ void DirectoryBlobPartition::BuildFST(std::vector<FSTBuilderNode> root_nodes, u6
   // overflow check, compare the aligned name offset with the aligned name table size
   ASSERT(Common::AlignUp(name_offset, 1ull << m_address_shift) == name_table_size);

-  // write FST size and location
+  // write FST location, size and max size
   Write32((u32)(fst_address >> m_address_shift), 0x0424, &m_disc_header);
   Write32((u32)(m_fst_data.size() >> m_address_shift), 0x0428, &m_disc_header);
   Write32((u32)(m_fst_data.size() >> m_address_shift), 0x042c, &m_disc_header);

is that an OK change? it would be nicer if the DirectoryBlob's main.dol gets overridden with whatever executable you've launched but...at least it works.

Actions #7

Updated by Anonymous almost 2 years ago

issue can be closed i guess: "default iso" with path set to /sys/main.dol has to be used, and there is no support for elf or different dol path.

Actions #8

Updated by JMC4789 over 1 year ago

  • Status changed from New to Won't fix

Closing as requested, though it's a bit iffy.

Actions

Also available in: Atom PDF