Here is my method for getting Windows 98 up and running on an old PC. I do it this way because I find it to be the fastest. There may be better ways, but this is mine :)
This was written quickly mostly as I was performing these steps. There are probably some typos or errors, and probably plenty of situations where I wrote it bad and it is hard to understand :) If you have suggestions / corrections email me at <myname>@<my-website>.id
. Include a name and I can credit you.
This document assumes you are already familiar and comfortable with using Linux and the terminal, and old versions of Windows.
This could likely also be done on Windows 10, etc. I'm not sure, but instead of /dev/sdX you would be using \\.\PhysicalDriveX
or something like that. You can identify your disks using diskpart
. I apologize for not being more help here :) Fortunately this is a decently covered topic online.
On that note: In theory, this doesn't need to be done with QEMU. Running the win 98 first stage installer in a VM on a fast PC and then completing the second stage on real old hardware shouldn't be OS/Hypervisor dependent.
Shout out to Phil's Computer Lab, The Retro Web, CPU-World, and Vogons for being fantastic resources.
-
Phil's Computer Lab has plenty of resources for benchmarking DOS, some drivers, and some cool old ATI graphics demos. He also runs a great YouTube Channel that is a wonderful resource spanning 10 years.
-
The Retro Web likely has a manual, BIOS, and other information for your motherboard. It is also great if you are looking to find good cross-flashing candidates as they have detailed chipset information, etc.
-
CPU-World has tons of information on basically any CPU (maybe x86/AMD64 only?)
-
Vogons is a large community that has tons of information
Things to have ready
-
An older PC, preferrably with good hardware support for Windows 9x, from now on called "Old System". See below for specifics on my system
-
A newer PC running a recent-ish version of Linux. Something modern-ish from the last 10-15 years or so, from now on called "New System"
-
A storage device for the Old System that you can access / modify from the New System. I like using IDE-SD card adapters
-
A copy of Windows 98 SE in ISO form. Must be OEM Full, as this is the only one that I know of that supports booting from directly
-
QEMU installed on your New System. we will be using qemu-system-i386 to do this
Old System info
The system I will be performing this on has the following specifications:
Motherboard: FIC-SD11 aka ASPEN2. This is a Slot A motherboard with the AMD 750 "Irongate" chipset. OEM board from a Compaq machine.
CPU: AutheticAMD Athlon 550 @ 750MHz with a "gold fingers" board installed.
Memory: 1x Micron MT16SLDT1664AG 128MB, 100MHz, CL2 SDRAM (Note, I have had issues using more than 768MB of ram on Windows 98. There are ways around this not documented here).
Storage: Generic eBay IDE -> SD card adapter. Marked SD35VC0. Using a Sandisk 256GB SD card. (Windows can only handle drives up to 137(?) GB. I created 4 ~64GB partitions on the card for this process (partitioning detailed below)
Graphics: ATI Radeon 8500 - This isn't super important. Just make sure it has drivers for Windows 98.
Notes
The motherboard I was using had a bug in its bios that prevented it from recognizing my SD card due to its size. Luckily, The Retro Web had an updated beta BIOS for my motherboard.
Make sure the SD card you are using is fast, or at least not terrible. I tried 3 different cards I had laying around and found that performance in Windows 98 was abysmal. I even had one SD card that had decent write speeds (tested at 50MB/s), but still performed horribly. A good indicator of how it will perform, would be to try copying a directory with a lot of small files and some big files to the SD card from our New System before using it. If the copy seems to take forever, with long periods of time where it is just sitting there seemingly doing nothing, it will perform poorly. I ended up using a SanDisk Extreme SDXC UHS-I C10 U3 V30 4K UHD GTX TI SUPER XXX INSANE EDITION card I bought online.
The process
- Insert the SD card into your New System.
- Open up a terminal and identify your SD card using the command
sudo fdisk -l
user@fedora41:~/Projects/Win98Install $ sudo fdisk -l
Disk /dev/nvme0n1: 1.82 TiB, 2000398934016 bytes, 3907029168 sectors
Disk model: Sabrent Rocket 4 Plus Gaming
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disklabel type: gpt
Disk identifier: 0B41F2AE-2CF5-48BD-A967-164E748E0ACC
Device Start End Sectors Size Type
/dev/nvme0n1p1 2048 1230847 1228800 600M EFI System
/dev/nvme0n1p2 1230848 3327999 2097152 1G Linux extended boot
/dev/nvme0n1p3 3328000 3258585087 3255257088 1.5T Linux filesystem
/dev/nvme0n1p4 3258585088 3806365695 547780608 261.2G Linux filesystem
/dev/nvme0n1p5 3806365696 3907028991 100663296 48G Linux swap
Disk /dev/sda: 238.3 GiB, 255869321216 bytes, 499744768 sectors
Disk model: Multi-Card
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
user@fedora41:~/Projects/Win98Install $
-
Here you can see /dev/sda is my SD card. I know this because I already know that my specific SD card reader identifies as "Multi-Card". If you are unsure, stop until you are. If you don't have any NVME drives, you will have other disks that have similar looking devices nodes (ex:
/dev/sdb
or/dev/sdc
). If you want to be sure, remove the SD card and/or reader and runsudo fdisk -l
again. You should be able to see which device is now missing. -
Extract the
win98
directory from your Windows 98 ISO using your favorite tool, keeping only the win98/ directory.
user@fedora41:~/Projects/Win98Install $ ls
'Windows 98 Second Edition.iso'
user@fedora41:~/Projects/Win98Install $ 7z x Windows\ 98\ Second\ Edition.iso
7-Zip [64] 16.02 : Copyright (c) 1999-2016 Igor Pavlov : 2016-05-21
p7zip Version 16.02 (locale=en_US.UTF-8,Utf16=on,HugeFiles=on,64 bits,16 CPUs AMD Ryzen 7 75800X3D 8-Core Processor (A20F12),ASM,AES-NI)
Scanning the drive for archives:
1 file, 655591424 bytes (626 MiB)
Extracting archive: Windows 98 Second Edition.iso
--
Path = Windows 98 Second Edition.iso
Type = Iso
Physical Size = 655591424
Created = 1999-04-23 13:22:00
Everything is Ok
Folders: 365
Files: 3534
Size: 664735416
Compressed: 655591424
user@fedora41:~/Projects/Win98Install $ ls
add-ons autorun.inf '[BOOT]' cdsample drivers readme.txt setup.exe setuptip.txt tools win98 'Windows 98 Second Edition.iso'
user@fedora41:~/Projects/Win98Install $ find . -mindepth 1 -maxdepth 1 ! -name 'win98' -exec rm -rf {} +
user@fedora41:~/Projects/Win98Install $ ls
win98
user@fedora41:~/Projects/Win98Install $
- Partition your SD Card using
sudo fdisk -c=dos /dev/sdX
where sdX is your SD card's device node.
user@fedora41:~/Projects/Win98Install $ sudo fdisk -c=dos /dev/sda
Welcome to fdisk (util-linux 2.40.2).
Changes will remain in memory only, until you decide to write them.
Be careful before using the write command.
Device does not contain a recognized partition table.
DOS-compatible mode is deprecated.
Created a new DOS (MBR) disklabel with disk identifier 0x0b044227.
Command (m for help): o
DOS-compatible mode is deprecated.
Created a new DOS (MBR) disklabel with disk identifier 0x95a19fec.
Command (m for help): n
Partition type
p primary (0 primary, 0 extended, 4 free)
e extended (container for logical partitions)
Select (default p): p
Partition number (1-4, default 1): <enter>
First sector (63-499744767, default 63): <enter>
Last sector, +/-sectors or +/-size{K,M,G,T,P} (63-499744767, default 499744767): +64G
Created a new partition 1 of type 'Linux' and of size 64 GiB.
Command (m for help): n
Partition type
p primary (1 primary, 0 extended, 3 free)
e extended (container for logical partitions)
Select (default p): <enter>
Using default response p.
Partition number (2-4, default 2): <enter>
First sector (134217792-499744767, default 134217792): <enter>
Last sector, +/-sectors or +/-size{K,M,G,T,P} (134217792-499744767, default 499744767): +64G
Created a new partition 2 of type 'Linux' and of size 64 GiB.
Command (m for help): n
Partition type
p primary (2 primary, 0 extended, 2 free)
e extended (container for logical partitions)
Select (default p): <enter>
Using default response p.
Partition number (3,4, default 3): <enter>
First sector (268435521-499744767, default 268435521): <enter>
Last sector, +/-sectors or +/-size{K,M,G,T,P} (268435521-499744767, default 499744767): +64G
Created a new partition 3 of type 'Linux' and of size 64 GiB.
Command (m for help): n
Partition type
p primary (3 primary, 0 extended, 1 free)
e extended (container for logical partitions)
Select (default e): p
Selected partition 4
First sector (402653250-499744767, default 402653250): <enter>
Last sector, +/-sectors or +/-size{K,M,G,T,P} (402653250-499744767, default 499744767):<enter>
Created a new partition 4 of type 'Linux' and of size 46.3 GiB.
Command (m for help): t
Partition number (1-4, default 4): 1
Hex code or alias (type L to list all): c
Changed type of partition 'W95 FAT32' to 'W95 FAT32 (LBA)'.
Command (m for help): t
Partition number (1-4, default 4): 2
Hex code or alias (type L to list all): c
Changed type of partition 'Linux' to 'W95 FAT32 (LBA)'.
Command (m for help): t
Partition number (1-4, default 4): 3
Hex code or alias (type L to list all): c
Changed type of partition 'Linux' to 'W95 FAT32 (LBA)'.
Command (m for help): t
Partition number (1-4, default 4): 4
Hex code or alias (type L to list all): c
Changed type of partition 'Linux' to 'W95 FAT32 (LBA)'.
Command (m for help): w
The partition table has been altered.
Calling ioctl() to re-read partition table.
Syncing disks.
Here, we created 4 primary partitions. 3 with 64GB and 1 with 46.3GB. Then we changed all of them to type b.
To confirm this worked:
user@fedora41:~/Projects/Win98Install $ sudo fdisk -l /dev/sda
Disk /dev/sda: 238.3 GiB, 255869321216 bytes, 499744768 sectors
Disk model: Multi-Card
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disklabel type: dos
Disk identifier: 0x95a19fec
Device Boot Start End Sectors Size Id Type
/dev/sda1 63 134217791 134217729 64G c W95 FAT32 (LBA)
/dev/sda2 134217792 268435520 134217729 64G c W95 FAT32 (LBA)
/dev/sda3 268435521 402653249 134217729 64G c W95 FAT32 (LBA)
/dev/sda4 402653250 499744767 97091518 46.3G c W95 FAT32 (LBA)
-
Create a FAT32 filesystem on the first partition (You can do this for the rest in Windows 98 later) with
sudo mkfs.fat -F32 /dev/sdX1
-
Mount the partition with either mount or using your desktop environment's GUI
sudo mount --mkdir /dev/sdX1 tmpmnt/
-
Copy the win98 directory to the SD card:
sudo cp -rv win98 tmpmnt/
-
To make sure we are finished copying, and the cache is flushed to the card, run
sync
-
Use qemu-system-i386 to boot the Windows 98 ISO
sudo qemu-system-i386 -cpu pentium2 -accel kvm -smp 1 -M pc -m 64M -drive file=/dev/sda,format=raw,if=none,id=disk -device ide-hd,drive=disk -cdrom "Windows 98 Second Edition.iso" -boot d
Explanation of options:
-cpu pentium2
identify the emulated machine as a pentium2, for compatibility
-accel kvm
uses your CPU's virtualization features to (greatly) improve performance. If you have issues with the command you can try without this. It will be super slow. If you are having issues with it, it is likely that you just have virtualization disabled in your BIOS. AMD CPUs have had this since the Athlon64 from 2003, and Intel has had it since the Pentium 4 from 2005.
-smp 1
only emulate 1 core. DOS / 9x only support 1 core. This is probably not even neccessary, I think this is the default
-M pc
emulate a standard pc with an Intel 440FX chipset, and a PIIX
-m 64M
give the emulated machine 64MB of RAM. This doesn't have to match your Old System.
-drive [...]
specify your SD card as the emulated machine's primary disk drive
-device [...]
same as above
-cdrom [...]
specify the path to your Windows 98 SE ISO file
-boot d
boot from the CD drive, in this case the ISO.
-
Once QEMU has started, The Windows 98 setup boot menu will appear. Pick option 2 to boot from the emulated CD-ROM drive
-
In the second menu, pick option 2 again to boot with CD-ROM support
-
Give the machine a second, and eventually you should see a DOS command prompt
-
First, some SD cards need to have this run to fix the MBR
fdisk /mbr
-
Then, begin the Windows 98 installer
C:\win98\setup.exe
-
This will begin the first stage of the installation process. Doing this stage on the New System is the whole reason I use this method. Stage 1 can be anywhere from "glacial" to "that wasn't too horrible" on real hardware, and when using a CD, leaning towards "glacial".
Follow the prompts and answer any questions.
-
Once the installer finishes Stage 1, it is going to ask you to reboot. Do not do this. if you do, you will have to restart Stage 1. The reason we do this is Stage 1 is hardware agnostic (afaik). The second stage is when hardware is identified and preliminary drivers are loaded.
-
Instead of rebooting, simply close QEMU either by clicking the close button or going into the terminal window and doing a CTRL+C
-
Just in case, run
sync
again on your New System to make sure we don't have any writes cached waiting to go to the SD card. -
Mount the first partition on the SD card again, create a folder in the root called
Drivers
and place any drivers you will need on the Old System once it is up and running. -
Unmount the SD card, and transfer it to your Old System
-
Start the Old System, and boot to the SD card. You should see the Windows 98 logo and the second stage installer should complete.
-
Welcome to Windows 98. Now you may start installing your drivers and doing whatever it is you set out to do.