isaacschemm: A cartoon of myself as a snail (snail8)
[personal profile] isaacschemm posting in [community profile] snailsharp

I recently expanded my triple-boot PC to boot four operating systems off the same drive: DOS, Windows XP, Windows 7, and Debian.

Generally, in the old BIOS world, you'd handle this by having GRUB (controlled and configured by the Linux installation) as the main bootloader, and let it boot Windows and DOS from there. But I like to take a more unconventional method (detailed here) where I have the newest installed version of Windows control the main bootloader, and let Linux boot from DOS.

There were three big changes I made this time.

First, I kept Windows XP and Windows 7 both installed to separate extended partitions. I believe they both install their bootloaders to the DOS partition - I know Windows 7, by default, won't map it to a drive letter because it assumes it's just a system partition (you can change this from Disk Management).

To limit the number of consecutive menus, after installing Windows 7, I removed FreeDOS from the boot.ini used by Windows XP's bootloader (ntldr) and added it to Windows 7's (bootmgr). The bootsect.dos (extracted and created by Windows XP's installer) can be loaded through bootmgr by adding a new entry:

bcdedit /create /d "FreeDOS 1.3" /application bootsector
bcdedit /set {new-guid} device partition=e:
bcdedit /set {new-guid} path \bootsect.dos
bcdedit /displayorder {new-guid} /addlast

Options like /displayorder or /default can be used to customize its spot in the menu.

But most importantly, I still wanted Debian to boot from DOS so it wouldn't touch the MBR (making it easy to delete or replace from within DOS/Windows without breaking anything). But instead of installing grub-legacy in Debian to generate the menu.lst and using GRUB4DOS to boot it (which I'm sure would have worked fine), I wanted to use a method of booting Debian that would rely only on the partition GUID, and not on the drive number.

A snail character between IDE and SATA cables with a thought bubble reading "(hd0,5)"

I put together a script which can run from within Debian every time the initramfs is regenerated:

#!/bin/sh

# This script will copy the Debian kernel and initrd to a DOS partition along
# with a copy of LINLD.COM and a batch file, so you can boot it from DOS
# without a bootloader.

# Copy this script to /etc/initramfs/post-update.d/ and make it executable.

# https://snailsharp.dreamwidth.org
# CC0

set -e

if [ "$0" == "doshook-installer" ];then
mkdir -p /target/etc/initramfs/post-update.d
cp -v "$0" /target/etc/initramfs/post-update.d/zz-doshook
chmod +x /target/etc/initramfs/post-update.d/zz-doshook
exit
fi

MOUNTPOINT=/dos
FOLDER=debian
COMMAND=debian

DESTINATION=$MOUNTPOINT/$FOLDER

if [ -f /vmlinuz ] && [ -f /initrd.img ] && [ -f $MOUNTPOINT/COMMAND.COM ];then
mkdir -p $DESTINATION
if [ ! -f $DESTINATION/linld.com ] && which wget > /dev/null;then
echo "Downloading linld.com..."
wget -qO $DESTINATION/linld.com https://distro.ibiblio.org/slitaz/boot/linld.com
fi
echo "Copying kernel and initial ramdisk to $DESTINATION..."
echo -n "The contents of this folder are automatically generated by the script $0 on partition $(findmnt --output=UUID --noheadings --target=/vmlinuz). Run $COMMAND.bat to boot Linux from this partition." > $DESTINATION/readme.txt
echo -n "@linld.com image=vmlinuz initrd=initrd.img cl=root=UUID=$(findmnt --output=UUID --noheadings --target=/vmlinuz)" > $DESTINATION/$COMMAND.bat
cp -v /vmlinuz $DESTINATION
cp -v /initrd.img $DESTINATION
fi

The doshook-installer check is for added convenience: it lets me run it from a shell within the Debian installer - assuming the DOS partition is mounted within the Debian install as /dos - and, as long as the script is named doshook-installer and run with sh doshook-installer, it will just copy itself to the appropriate folder in the target installation and make the copy executable. The rest of the script runs each time Debian makes a new initramfs, and it:

  • Ensures that a DOS installation is mounted at /dos by looking for COMMAND.COM
  • Makes a debian folder in the root of the DOS partition
  • Copies LINLD to that folder, if it's not there already (and wget is installed)
  • Creates a readme
  • Creates debian.bat
  • Copies the kernel and initramfs to the DOS parititon

Finally, I decided to customize the FreeDOS boot menu by adding a few options. Here's my FDCONFIG.SYS:

SET DOSDIR=C:\FreeDOS

!COUNTRY=001,858,C:\FreeDOS\BIN\COUNTRY.SYS
!LASTDRIVE=Z
!BUFFERS=20
!FILES=40
!MENUCOLOR=7,0

MENUDEFAULT=1,5
MENU 1 - Load FreeDOS with JEMMEX, no EMS (most UMBs), max RAM free
MENU 2 - Load FreeDOS with JEMMEX (more compatible)
MENU 3 - Load FreeDOS with JEMM386 (Expanded Memory)
MENU 4 - Load FreeDOS low with some drivers (Safe Mode)
MENU 5 - Load FreeDOS without drivers (Emergency Mode)
MENU 6 - Microsoft Word 5.5
MENU 7 - Debian
MENU 8 - Power Off

123?DOS=HIGH
123?DOS=UMB
123?DOSDATA=UMB

1?DEVICE=C:\FreeDOS\BIN\JEMMEX.EXE NOEMS X=TEST I=TEST NOVME NOINVLPG
2?DEVICE=C:\FreeDOS\BIN\JEMMEX.EXE NOEMS X=TEST NOVME NOINVLPG
34?DEVICE=C:\FreeDOS\BIN\HIMEMX.EXE
3?DEVICE=C:\FreeDOS\BIN\JEMM386.EXE X=TEST NOVME NOINVLPG

12?SHELLHIGH=C:\FreeDOS\BIN\COMMAND.COM C:\FreeDOS\BIN /E:1024 /P=C:\FDAUTO.BAT
345678?SHELL=C:\FreeDOS\BIN\COMMAND.COM C:\FreeDOS\BIN /E:1024 /P=C:\FDAUTO.BAT

This is accompanied by some additional commands in FDAUTO.BAT (placed near the beginning, after the alias definitions):

if "%config%"=="8" shutdown

if "%config%"=="7" cd %dosdrv%\debian
if "%config%"=="7" debian.bat

if "%config%"=="6" ctmouse
if "%config%"=="6" cd %dosdrv%\word
if "%config%"=="6" word.exe
if "%config%"=="6" reboot

This allows me to quickly do the two things I want to do from DOS: run the word processor, and boot to Debian (the one OS that isn't in bootmgr's list).

Snail#

A programming blog where the gimmick is that I pretend to be a snail.

Expand Cut Tags

No cut tags

Style Credit

Page generated Jul. 15th, 2025 05:40 pm
Powered by Dreamwidth Studios