my method for installing Windows 98 on an older PC

Posted on 2024-12-23

Tux the Linux Mascot Juggling a bunch of Microsoft logos. Fun!

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.

Things to have ready

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

  1. Insert the SD card into your New System.
  2. 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 $ 
  1. 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 run sudo fdisk -l again. You should be able to see which device is now missing.

  2. 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 $ 
  1. 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)
  1. 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

  2. Mount the partition with either mount or using your desktop environment's GUI

    sudo mount --mkdir /dev/sdX1 tmpmnt/
  3. Copy the win98 directory to the SD card:

    sudo cp -rv win98 tmpmnt/
  4. To make sure we are finished copying, and the cache is flushed to the card, run sync

  5. 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.

  1. Once QEMU has started, The Windows 98 setup boot menu will appear. Pick option 2 to boot from the emulated CD-ROM drive Windows 98 setup initial boot menu.

  2. In the second menu, pick option 2 again to boot with CD-ROM support Windows 98 setup second boot menu.

  3. Give the machine a second, and eventually you should see a DOS command prompt

  4. First, some SD cards need to have this run to fix the MBR

    fdisk /mbr
  5. Then, begin the Windows 98 installer

    C:\win98\setup.exe
  6. 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.

  1. 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.

  2. Instead of rebooting, simply close QEMU either by clicking the close button or going into the terminal window and doing a CTRL+C

  3. 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.

  4. 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.

  5. Unmount the SD card, and transfer it to your Old System

  6. Start the Old System, and boot to the SD card. You should see the Windows 98 logo and the second stage installer should complete.

  7. Welcome to Windows 98. Now you may start installing your drivers and doing whatever it is you set out to do.

← Back to Posts