Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Running Dynamic (contents) Win9x Image in DosBox-X #5292

Closed
2 tasks done
joeskeen opened this issue Nov 27, 2024 · 5 comments
Closed
2 tasks done

Running Dynamic (contents) Win9x Image in DosBox-X #5292

joeskeen opened this issue Nov 27, 2024 · 5 comments
Labels

Comments

@joeskeen
Copy link

Question

I've been trying to create a solution for running many old software titles from my childhood. As all of these titles ran on Windows 9x or earlier, I'm seeking for a DosBox-based solution. My prototype solution ran Windows 3.1 in normal DosBox, and would have separate dosbox.conf files per game that would mount the shared Windows 3.1 HD, the game disk image, then run the game in Windows using RUNEXIT and finally exit DosBox. This mostly works OK, but comes with a few downsides:

  • Some software titles rely on different versions of libraries/frameworks being installed, which conflict with one another.
  • Since the install happens on a shared system drive, the "Program Manager" shows a ton of things available, but they won't work unless you launch with that program's specific dosbox.conf file.
  • Undoing anything that changes at a system level is pretty much impossible (no isolation, no change tracking, etc.)
  • Normal DosBox doesn't really work well with Windows 9x.

For the last reason listed, I have decided to go with DosBox-X for my next version of this. My vision:

  • All these will be run on my Linux computer lab machines (that my kids use)
  • Have a base Windows 98 SE install directory
  • Use overlayfs or similar to overlay a game-specific folder on the base Windows 98 image, allowing the game to be installed, but any file changes to be separated into the game-specific folder
  • While playing the game, have a third overlayfs layer for user-specific data (i.e. savegames, settings, etc.). This allows me to have one master readonly copy of both Windows and the game install, and allow my kids to each play the titles without messing each other's data up.
  • After initial setup, non-root users should be able to run any of the titles, so any mounting needs to be done using FUSE

After doing some prototyping, I got the overlayfs to work great. However, when trying to mount the overlayfs mount point directory into DosBox-X, it became clear that I wasn't going to be able to boot into Windows 98 that way, as you can only BOOT into disk image files, not local directories.

So, my next idea was to overlay the filesystem, then copy everything into a disk image, then imgmount the image into DosBox-X, boot, then profit. But unfortunately, I have had a terrible time trying to get this to work as well. Things I've tried:

  • Using many variations of dd if=/dev/zero of=image.img, sfdisk, mkfs.fat, fusefat to try to set up and copy data onto the disk image. The output of this always had issues when trying to mount it in DosBox-X. First, imgmount c image.img would fail with an error about not being able to detect disk geometry. If I explicitly set disk geometry and specify partition number, it will mount, but if you do dir c: you get a directory listing where all the names are blank (so it names them ~1, ~2, etc.). The strange thing about this is that sometimes it shows their actual names on the far right, and you can cd into directories, but something's not right. And if I try to boot from it, I get "Image file is read-only! Boot in write-protected mode. Booting from drive A..."
  • I've also tried having DosBox-X create an image file with imgmake, then mount it in Linux and copy the files over. Problem there is that Linux Fat drivers don't seem to like the format of the image, and so you either get a readonly image you can't change, or you get Operation not permitted, or Transport endpoint not connected. I'm really not sure what's going on here.

So my question is, given the aims I listed above, is there any sane way to do this? I was hoping that FAT disk images would more or less work with each other, but DosBox-X seems to hate images created outside of it, and Linux seems to hate images created by DosBox-X. Or is there some way I can mount the directory and run Windows 98 without using an image file?

Have you checked that no similar question(s) exist?

  • I have searched and didn't find any similar question.

Code of Conduct & Contributing Guidelines

  • I agree to follow the code of conduct and the contributing guidelines.
@joeskeen joeskeen changed the title Running Dynamic Win9x Image in DosBox-X Running Dynamic (contents) Win9x Image in DosBox-X Nov 27, 2024
@joeskeen
Copy link
Author

FWIW, this is my current script I'm running:

# remove old image if it exists
fusermount -u mnt 2>/dev/null
rm -f 2G.img

truncate -s 2G 2G.img                       # creates the image file
echo 'type=06,bootable' | sfdisk 2G.img     # creates a single bootable partition that takes up the whole disk
sfdisk -l 2G.img                            # shows the partition table
sfdisk -g 2G.img                            # shows the geometry of the disk
mkfs.fat -mbr=y -F 16 2G.img                # formats the partition as FAT
mkdir -p mnt                                # creates a mount point
fusefat -o rw+ -o umask=777 2G.img mnt      # mounts the image with open permissions
cp -r win98se/* mnt                         # copy all files from the directory where the Windows-installed disk image was extracted to
ls -alh mnt                                 # shows the contents of the image - looks great from the Linux side

# When trying to mount the image in DOSBox-X (`imgmount c 2G.img`) , the following error occurs:
# Could not extract drive geometry from image.
# Use parameter -size bps,spc,hpc,cyl to specify the geometry.
# Unable to detect geometry
# 
# so I mount it using:
# imgmount c 2G.img -size 512,63,255,261 -o partidx=1
# 
# This works, kinda, but try running `dir c:` and you'll see that the file names are not there.
# Also, the disk is not bootable, even though fdisk says it is.

@Torinde
Copy link
Contributor

Torinde commented Nov 28, 2024

Good initiative!
I like the triple layer separation:

  1. base Win9x installation
  2. Win9x + game1/2/3/...
  3. Win9x + game1 + user1/2/3/...
  4. even more levels/branches may be useful, e.g. savestate/snapshot-like capability for each user to go different routes in a game, etc.

You may check if dynamic and differencing VHDs, your requirements seem similar to those for eXoWin9x.

@rderooy
Copy link
Contributor

rderooy commented Nov 28, 2024

As you found out, and as documented on the Wiki, you cannot boot from folders. And the support for non-bootable folder mounts when booting an OS in DOSBox-X is limited (any changes will not be saved).

For mounting, I have not had issues with using gnome-disk-image-mounter with mounting FAT images created using imgmake. e.g., as specified on the DOSBox-X wiki:

gnome-disk-image-mounter -w hdd.img

You can umount it as a regular user afterwards.

Alternatively, you can have a script that you run from within DOSBox-X that does the necessary steps. e.g.,

[autoexec]
@echo off
imgmake hdd.img -t hd_2gig
imgmount c hdd.img
IF NOT EXIST C:\WINDOWS\WIN.COM GOTO INSTALL
IMGMOUNT 0 empty -fs none -t floppy -size 512,15,2,80
IMGMOUNT 1 empty -fs none -t floppy -size 512,36,2,80
IMGMOUNT C hdd.img -ide 1m
IMGMOUNT D empty -t iso -ide 2m
boot c:
GOTO END

:INSTALL
cls
echo 1) Windows 98 RTM
echo 2) Windows 98 OEM
echo 3) Windows 98SE OEM
echo 4) Windows 98SE OEM CD-ROM boot
echo.
choice /c:1234 /N Select OS to install

IF ERRORLEVEL == 4 goto CDBOOT
IF ERRORLEVEL == 3 imgmount D "CD/Windows 98 Second Edition.iso" -u
IF ERRORLEVEL == 2 imgmount D "CD/Windows 98 First Edition.iso" -u
IF ERRORLEVEL == 1 imgmount D "CD/Windows_98_retail.iso" -u
GOTO COPY

:CDBOOT
imgmount D "CD/Windows 98 Second Edition.iso"
imgmount A -bootcd D
boot a:
goto END

:COPY
xcopy d:\win98 c:\windows\options\cabs /i /e
c:
cd windows\options\cabs
cls
echo 1) Install using response file
echo 2) Manual installation
echo.
choice /c:12 /N Select option

IF ERRORLEVEL == 2 GOTO DRIVERS

mount x .
copy x:\MSBATCH.INF .
mount x -u

:DRIVERS
cls
echo 1) Copy drivers to C:\DRIVERS
echo 2) Skip copying drivers
echo.
choice /C:12 /N Select option

IF ERRORLEVEL == 2 GOTO SETUP

mount x .
mkdir c:\drivers
xcopy x:\drivers\s3 c:\drivers\s3 /i /e
xcopy x:\drivers\sb c:\drivers\sb /i /e
xcopy x:\drivers\voodoo c:\drivers\voodoo /i /e
mount x -u

:SETUP
echo "Running Windows 98 SETUP.EXE"
CONFIG -SET TURBO=ON
setup /IS 

:END

@joeskeen
Copy link
Author

Thanks @Torinde and @rderooy! I've gotten things working, although there are SO MANY LAYERS lol.

I'm using a differencing VHD for each layer:

  • Windows install
  • Game install
  • User savegame data

This provides the right level of sandboxing for my purposes (although someone could tweak it for further save state shenanigans).

To get a game to launch, there's a lot going on:

  • In DosBox-X, it creates the user image if needed, copies files and configures boot settings (to boot Windows98 to command-line) and creates a boot script, then boots from c:
  • In Win98 Command line, it sets up CD-ROM drivers, then calls win A:\PROG.BAT (I'm not using RUNEXIT.EXE as the Win9x version of it I found didn't work for me)
  • Once Windows 98 boots up, it immediately launches the game using START /W. It waits for the game to end, then calls C:\WINDOWS\RUNDLL32.EXE SHELL32.DLL,SHExitWindowsEx 1 to shut down Windows, and in turn DosBox-X

You can take my implementation out for a drive by cloning and following instructions in my GitHub repo: https://github.com/joeskeen/oldgames

@Torinde
Copy link
Contributor

Torinde commented Dec 1, 2024

@exoscoriae, @Python-Exoproject you may be interested in above solution for eXoWin9x - three VHD layers for Windows/Game/User branching-off.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

3 participants