9

I have a 386 with 4GB drive (7769/16/63). It's a Compaq from 1992 so it does not have any translation options in BIOS. DOS is installed on the first 1023 cylinders (essentially the maximum size it can be). I thought it would be interesting to install an old release of Slackware on the remaining ~3.5GB in a second partition.

This is much more complicated that I thought, but maybe because I don't understand this well enough. I can install Linux on the 2nd partition, but have to use a boot disk then mount that partition as root. My usual boot manager go-to xfdisk will boot DOS as usual, but won't boot Linux for the obvious reason. I tried LILO in the MBR but all that does is display "L" with a repeating "40". Does any version of LILO allow booting Linux past 1023 cylinders?

I also tried another obscure boot manager that's supposed to do the trick, "nuni", but I'm tired of fighting with that.

I know loadlin is another option, but because I'm picky I'd prefer to choose DOS or Linux from a boot menu right after POST. Is there any rational way to do this with software alone (not XTIDE)? I know I could make a boot partition near the end of the 1023 cylinder mark, but I'm not sure how to do that and haven't been able to find a guide.

Is there any boot manager that bypasses BIOS and allows this natively?

EDIT: I have gotten nuni to work after many, many attempts. This is only in PCem right now but I have no reason to not believe it'll also work on the real computer. I'm using both nunimbr to dual boot, and nuni to load Linux. It boots either DOS, or Linux which starts after cylinder 1023. I'm not sure what was wrong, but I did move up to Slackware 8.0 and began using an old 0.99.05 version of nasm.

EDIT 2: Thank you to everyone who responded. There is a ton of good information here. However I have given up and will use loadlin with a DOS 6.22 menu in autoexec.bat which I guess isn't so bad. nunimbr worked no problem, but I cannot get nuni to work as it simply hard locks with no output when I select the partition with nunimbr. Someone mentioned plop, but that won't see the 2nd partition. gparted (or parted for CLI) I'm having trouble getting to run due to missing libraries, etc. There is no CDROM on this system, and I'd rather not move the drive to a newer system each time I make some change affecting boot although that would make things easier.

10
  • 4
    If the version of DOS is recent enough, it's possible to have a CONFIG.SYS menu that allows a choice between two configurations, one of which runs LOADLIN and the other of which runs AUTOEXEC.BAT as normal. You may consider that cheating, but the effect is pretty much indistinguishable from a standalone boot menu.
    – john_e
    Oct 28, 2023 at 22:33
  • What's the drive geometry? Does the BIOS support translation, so are you limited to 504MB limit or 2GB limit, or some other limit?
    – Justme
    Oct 28, 2023 at 22:34
  • 1
    If nuni puts up too much of a fight for you, you might want to try plop, which is a blessing for old BIOSes
    – tofro
    Oct 29, 2023 at 7:29
  • 1
    @Joshua A GRUB2 image with built-in pata, part_msdos and ext2 modules fits in 60 sectors, so just enough to fit in cylinder 0 head 0 (with a 63-sector-per-track geometry). Adding search.fs_uuid adds 2 more sectors. This is after XZ compression, but without Reed–Solomon ECC. Oct 30, 2023 at 20:57
  • 1
    @Joshua With a fresh/modern [additional] PC, a SATA/PATA/IDE-to-USB adapter is ~$20. The old drive can be pulled out of the 386 PC and connected to the newer PC via the adapter. gparted can run on the newer PC, and reimage the old HD with that. It can also install grub2 on the front of the disk, etc. Also, the entire disk image can be saved [byte-for-byte] to a file, so it can be restored if a misteak [mistake :-)] is made. Oct 30, 2023 at 22:27

5 Answers 5

12

As the large disk howto explains, LILO bootstraps through a loader that still uses the BIOS, this is why LILO didn't work for you.

On the other hand, nuni does not use BIOS services but accesses IDE drives directly.

That's why it works with nuni.

5
  • LILO has LBA support, but you have to tell it in lilo.config or it will initialize with CHS support. Too bad it doesn't check at install time that the address it out of maximum range. Reading OP's question, that won't help him though.
    – Joshua
    Oct 30, 2023 at 3:06
  • Does this LBA support not rely on BIOS services? Oct 30, 2023 at 10:58
  • 2
    @Joshua, LILO doesn't have LBA support, since it is not a storage driver. LBA is specific to IDE storage devices and their drivers. A BIOS, or OS IDE driver may support LBA, but lilo cannot. lilo accesses storage devices through BIOS int13h or extended int13h. Using int13h access with a non translating and non LBA BIOS from 1992 will result in the 528MB IDE hard drive size limit. Linux and its bootloader, or whatever will contain the IDE driver, must be within the first 528MB of the disk. Oct 30, 2023 at 16:28
  • 2
    @AlexCannon LILO does have LBA support, as "LBA support" is also a name for the "exteded int13h" interface you already mentioned yourself. While "classic int13h" takes CHS values as arguments, "extended int13h" takes LBA values. Oct 31, 2023 at 23:27
  • No wonder so many people are confused. I should say "IDE LBA support" or "BIOS LBA extended int13h"! Nov 1, 2023 at 20:26
8

LILO only requires the /boot partition to be within the area accessible by the BIOS. AFAIK there is no technical reason to not have /boot, on a FAT partition, so you could have a symbolic link from /boot to /msdos/boot, and if /msdos is the mount point of the DOS partition you can have the data required to boot Linux on the DOS partition without resorting to loadlin.

Note that having /boot on a FAT partition is fine, but installing the LILO boot stub into the FAT partition is not fine, as it will overwrite the boot sector/BPB of the FAT partition. Use boot=/dev/hda to install linux in the MBR, or install the LILO boot stub into the start of the linux partition (if the start still is in the first 1024 cylinders)

5
  • There is one. Don't install lilo to a FAT filesystem. It will trash it. (That is install=/dev/hda1; boot.b and map can be on a FAT just fine).
    – Joshua
    Oct 30, 2023 at 3:08
  • @Joshua, DOS will trash lilo, or lilo will corrupt the DOS FAT partition? Oct 30, 2023 at 16:21
  • @AlexCannon: Lilo will corrupt the FAT filesystem.
    – Joshua
    Oct 30, 2023 at 18:15
  • 1
    @Joshua I clarified my answer that I am not talking about install=ing linux to the FAT partition, but use the FAT partition for boot.b, map and vmlinuz while LILO is installed to the MBR. Oct 31, 2023 at 23:24
  • “there is no technical reason to not have /boot, on a FAT partition” – Long file names (that will survive encounters with other operating systems)? Symbolic links? (Occasionally useful to link /boot/vmlinuz to default kernel image) Denying read permission to non-root users on a per-file basis? (To keep a boot manager password secure while allowing /boot/config-* to be read) There are ways around those things, but it’s not like it’s nothing. Nov 20, 2023 at 12:05
4

We can make this work.

  1. Have a floppy disk that can boot the linux on your hard disk, either using lilo or syslinux to load kernel from floppy disk. Make sure you have access to the boot command prompt so you can put in root= argument.

  2. Assuming DOS is installed normally, you can make a partition on sectors 2-63 (sector 1 is MBR). Do so. The type should be 81.

  3. After doing so, reboot Linux (from the floppy disk in step 1 of course). You may have changed which partition is the root partition. Don't be surprised if this takes a couple tries.

  4. Identify the partition using the mount command. It will be the /dev/hda? partition that doesn't mount.

  5. Run mkfs.minix /dev/hdan where n is the partition you identified above. We use minix fs because it can make filesystems as small as 10kb.

  6. run mkdir /stand;mkdir /msdos to create the toplevel mount points

  7. Edit fstab so that you have something like this (partition numbers are guesses)

/dev/hda1 /stand minix defaults 0 1
/dev/hda2 /msdos msdos defaults 0 2
/dev/hda3 / ext2 defaults 0 3
/proc /proc proc defaults 0 4
...
  1. Mount everything

  2. Do rm /boot/map as it's definitely a trash version.

  3. If you have /boot/boot.b do mv /boot/boot.b /stand/boot.b

  4. Do mv /boot /msdos/linux && ln -s msdos/linux /boot to transfer the boot kernel to the fat partition. Note there's an assumption here that your kernel name is zimage or something similar. Long kernel names need vfat instead.

  5. Set up lilo.conf

If you have lilo 22.5 or newer, it should look like this:

boot=/dev/hda
map=/stand/map
install=menu
default=linux

image=/boot/vmlinuz
    label=linux
    root=/dev/hda3
other=/dev/hda2
    label=dos

If you have older lilo it should look like this:

boot=/dev/hda
map=/stand/map
install=/stand/boot.b
default=linux

image=/boot/vmlinuz
    label=linux
    root=/dev/hda3
other=/dev/hda2
    label=dos

If this system has an initrd there should also be a line initrd=/boot/initrd.gz right after root=

  1. run lilo -t && lilo; if everything is set up correctly, it will install

  2. boot DOS (command dos from the boot menu)

  3. Do cd /linux and attrib +s +h * to prevent DEFRAG from breaking Linux booting.

You should be able to get away without the /stand partition, but why waste the disk space? This also protects the all-important map file from shenanigans from DOS programs. (If map moves the machine state won't make any sense on boot.)

There's one future advantage to using the tiny filesystem; I used to have a single-sector boot menu inside the MBR; if you managed to find one you could change lilo to use boot=/dev/hdan and have the MBR boot menu choose between Linux and DOS. (It was a lot nicer than LILO's text menu that I had back in the day.)

2
  • I don't understand the purpose of making a tiny filesystem within the first cylinder of the disk. Is it to prevent MSDOS utilities from moving the lilo boot.b file and corrupting lilo? If booting from a floppy, loading ~30KB from the floppy instead of using the first cylinder would hardly increase the boot time. Can boot.b or /stand be put on the floppy? The first cylinder of the disk is not entirely safe as some DOS disk or boot utilities use it. Oct 30, 2023 at 16:19
  • @AlexCannon: Yeah the tiny filesystem is to prevent boot.b and map from being messed up. I haven't encountered any DOS stuff that scribbles on those cylinders unbidden. Things like EZDisk would but that's definitely not in play here. Yes, you could use a floppy disk. If I were setting this up anew I would use the last few BIOS cylinders for /boot instead of any of this; but OP seems to not want to try to shrink the DOS partition.
    – Joshua
    Oct 30, 2023 at 18:19
3

Just use loadlin from within the DOS partition which is within the BIOS accessible area of the disk, or shrink the DOS partition and create a small /boot partition that is within 1023 cylinders.

If you make a new /boot partition, you can install the linux boot loader boot sector in the MBR of the disk and then rely on the boot menu from the Linux boot loader to boot DOS. Or you could install it in the partition sector of the /boot partition (such as /dev/hda2) and then rely on setting one partition or the other as the active partition and the DOS MBR will boot boot the one that is active. Or you could put the Linux boot loader boot sector on a floppy and put in the floppy when you want to start the boot loader on the /boot partition.

I find that grub 1.x or syslinux are easier to work with than lilo. Lilo requires that the lilo program be run every time a file (such as a kernel) is moved or updated on the /boot partition.

2
1

Per Joshuas comments ...

I've had good luck with gparted, booted from a live CD/USB, for resizing/moving partitions. It understands many filesystem formats. And, if a partition is resized, it will adjust the filesystem inside the partition.

For example, the tough part is shrinking a partition. gparted will "do the right thing" and shove data down to the front of the partition and adjust any block pointers and free block maps as needed.

But, as Joshua pointed out, this would be difficult on such an old PC directly (i.e. no CD/USB boot and the code may assume something a more recent CPU arch than a 386 (even in 32 bit mode).

My solution would be to use an additional PC/laptop. With a fresh/modern [additional] PC, a SATA/PATA/IDE-to-USB adapter is ~$20:

  • The old drive can be [physically] pulled out of the 386 PC and connected to the newer PC via the adapter.
  • gparted can run on the newer PC, and repartion/reimage the old HD with that.
  • It can also install grub2 on the front of the disk
  • Also, the entire disk image can be saved [byte-for-byte] to a file on the laptop, so it can be restored if a misteak [mistake :-)] is made. This aspect could be worth its weight in gold, even if we don't use gparted for resizing.
  • As an additional safety, with the adapter, the [existing] DOS files could be backed up to a .zip file or other backup media

UPDATE:

How that will handle the geometry difference? The 386 sees a 504 MiB drive with 1024/16/63 geometry, even if the drive itself is 7769/16/63,

That may be a valid point: (BIOS aside) Can the 386's disk adapter address the extra disk space?

I assumed that it could because OP was booting linux off a floppy and it was able to access the linux partition (via linux device drivers that talk directly to the adapter).

Also, Compaq was somewhat ahead of its time--in its day, so I'm guessing yes [I actually had to do some work on one circa 1989]. But, OP's Compaq is 1992, the year that LBA addressing was introduced. IIRC, Compaq tended to be an early adopter of such things, so the system might support LBA addressing (even if DOS or the BIOS didn't).

and USB has no notion of geometry and linux may use any made-up geometry on the drive. Especially if the drive is repartitioned without care. – Justme

With gparted, it accesses the disk via the raw device, so it does its own mapping. It's pretty flexible as it's intended for crash repair scenarios as well (IIRC).

I haven't used such USB adapters before, so this is just a guess. It doesn't present (doesn't have to present) as a USB disk/stick in the classic sense of an LBA scheme. You can send special commands to the adapter that mimic the ancient port H/W (e.g. set cyl, head, sector). So, the USB adapter functions like a dumb IDE adapter of the era.


UPDATE #2:

Can you show the partition table (e.g. fdisk -l output)?

What is the starting offset of the first partition? If part1 starts at (e.g.) 1024 sectors vs directly abutting the MBR, you can install grub.

As an alternative, you could create a contiguous file in the DOS filesystem and point the grub MBR/boot block to read from that contiguous area instead of physical sector 2.

This gets the grub second stage going.

Now, grub has a driver for DOS fat FS available.

You can put the /boot directory (holding grub .mod files, ramdisk images, and vmlinux images) in a subdirectory in the DOS filesystem. You can point grub to that (instead of a partition with a small linux FS).

This gets around any BIOS limitation with not supporting full CHS addressing. That is, if it didn't you couldn't boot DOS.

So, no need to resize the DOS partition!

After grub brings up the kernel, the kernel can access the disk controller directly. It will read the partition table. You just need to add an entry in the MBR for the linux FS (e.g. ext2 or ext3).

Your 4GB IDE disk is (CHS?) 7769/16/63. So, this seems to be EIDE/ATA-2 (vs. IDE/ATA-1)? See: https://computer.howstuffworks.com/ide.htm

You do not need LBA addressing because CHS can go up to 8GB.


UPDATE #3:

Justme has a good point. You MUST BE CAREFUL when taking a hard drive out of an old non translating non LBA supporting BIOS like this. The new drive controller and/or the disk utility might assume that the drive is being accessed in translation mode and completely mess up the CHS geometry.

gparted is [much] smarter than the disk partition programs you're probably used to under DOS.

This is a common situation when trying to partition a drive on the more modern system to use in the old one. In this case I believe it would be safe because the CHS geometry is stored in the MBR, and the disk utility should use that.

Yes, and that is exactly what gparted does/uses.

Whether a filesystem uses CHS or LBA addressing [internally] is specified by the partition type byte in [classical] MBR partition entry.

Even if the FS uses LBA on a strictly CHS disk controller (integrated into the disk drive itself), the filesystem software device driver would have to translate the LBA block addresses back into CHS given to the disk controller (via the host adapter card).

Note that linux filesystems do not store CHS in inodes, etc. Never have, never will. So, they always had to translate them into CHS before passing them to the controller (if the H/W controller didn't support absolute block addressing). And, linux was bootable on 1992 era hard disks just fine.

Remember that IDE et. al. is a logical H/W interface. The PC host adapter card just passes digital commands to the controller that is integrated into the card in the disk drive.

By contrast, the older ST506 interface was (MFM) bit stream oriented at 5MHz. https://en.wikipedia.org/wiki/ST506/ST412 The disk drive had an integrated analog formatter board that could translate a bit stream from the PC disk controller to levels to the magnetic disk heads.

Because the drive had to maintain 5Mhz compatibility, this limited the amount of data that could be stored. By going to the logical IDE interface (the controller and formatter were now in the drive), the drive could take advantage of any special enhancements in the drive's recording surface.

Also, with ST506, the drive was at the mercy of the quality of the particular computer system's disk controller. A badly implemented controller would make the disk "look bad".

Also, it was [more] difficult to pull a given disk from one computer manufacturer's controller to another due to minute differences in how the controller implemented the standard:

  • The exact format of the sector preamble/marker.
  • The sector CRC algorithm.
  • How much time/space to allot for the "write splice" area.
  • How many sectors per track.

Side note: For example, I worked for a computer company that actually "overclocked" the [earlier] 8" disk drives to increase the total capacity by putting in 3 extra sectors per track. IIRC, we also did this for the 5.25" ST506 drives, so we had greater capacity than competitors but the drives had to be reformatted [at the bit level] to be used by other manufacturers.

Of course it won't boot in the modern system unless transation is disabled. – Alex Cannon

Obviously, we don't want it to boot from the USB-to-IDE adapter on the modern system. We just want it to arrange the tables and images correctly.

This is similar to having an SD card reader/writer on a PC to create a bootable linux SD card image that we then put into a Raspberry Pi (e.g.).


UPDATE #4:

MFM drives do not have a "bit stream to magnetic signal" conversion inside the drive.

The encoded signal (MFM or whatever) is presented at a "standard" level (e.g. 5v TTL and/or differential or whatever) between the system's controller board and the drive's formatter board.

It is converted (level shifted) to whatever voltage/current level the drive's magnetic heads require by the drive's formatter board.

The MFM/RLL data cable does not carry a raw PC bit stream, but an MFM encoded bitstream at 5MBps or an RLL encoded bitstream at 7.5MBps.

I believe I [already] said that: the older ST506 interface was (MFM) bit stream oriented at 5MHz

The formatter / decoder that translates between MFM/RLL and a raw data bit stream is part of the controller.

There may be some confusion as to terminology.

Early ST506 drives had a board on (or in) the drive itself. This was the formatter board.

The controller board was a separate board, provided by the computer system manufacturer, that plugged into the system's bus (e.g. ISA, VME, etc.).

The controller would DMA in/out data bytes from system memory and convert to/from an MFM stream when talking to the formatter board. The formatter did not understand anything about disk sectors (or even bytes). It just knew bits [again, encoded].

The controller would send cylinder/head to the drive, the drive would seek the heads, and the controller would wait for the heads to settle on a track.

Then, the controller would read/write the bits as a stream to/from the drive/formatter.

It was the responsibility of the controller to manage anything related to the sector format of the track. It could/would wait for the index pulse from the drive, write sector headers, data areas, CRC, inter-record gap, write splice, etc.

The [typical] format of a track was a series of sectors, with a format like:

Sector header:
  preamble_bits | sector_number | sector_header_CRC | header-to-data-gap (bits)
Data area:
  preamble_bits | data_bits/bytes | data_CRC | inter-sector gap/write splice (bits)

This byte/sector formatting was at a level higher than the MFM stream. Only the controller knew about this format as the formatter only knew bits.

The controller (and not the formatter) would decide:

  • How many bits for preamble and what value
  • Whether the bytes were encoded little-endian or big-endian
  • How many bits to have for the sector-header to data block gap
  • How may bits to have in the inter-sector gap. This had to be larger to allow the logic to recover from the write splice which appeared as a "glitch" (after the data for a sector was rewritten).
  • When reading, the controller would look for the sector header, read the data, verify the CRC.
  • When writing, the controller would look for the sector header, wait a bit, enable the write current, write the data preamble, the data bytes/bits, write the data CRC, disable the write current.

There was some variation in performance/reliability of the drives because the sector formatting/density, CRC verification, etc. was done by the controller [provided by the computer system manufacturer and not the drive manufacturer].

This changed with ESDI: ESDI puts all the bitstream encoding logic into the drive, and transfers a raw bit stream at 10MBps over the data cable. – Michael Karcher

ESDI came later as the time frame I was talking about was 1981-1986. It was this integration that allowed the drive to take full advantage of whatever [proprietary] recording technology it had.

As I mentioned, with IDE, the system's disk controller was renamed the "host adapter" and talked to the drive in byte/sector "logical" mode, now giving the sector number to the drive.

11
  • How that will handle the geometry difference? The 386 sees a 504 MiB drive with 1024/16/63 geometry, even if the drive itself is 7769/16/63, and USB has no notion of geometry and linux may use any made-up geometry on the drive. Especially if the drive is repartitioned without care.
    – Justme
    Oct 30, 2023 at 23:39
  • 1
    @Joshua I get that part, but the drive may end up being repartitioned with wrong geometry because the USB mass media driver has no notion of physical geometry. It may assume the drive having e.g. 971/128/63 or 517/240/63 or 487/255/63 or whatever and since that does not match the 1024/16/63 it will show up in the 386, it won't work. BPB won't store cylinders but that is only used for floppies, not IDE drives. MBR will contain partition info in CHS format.
    – Justme
    Oct 30, 2023 at 23:51
  • 1
    Justme has a good point. You MUST BE CAREFUL when taking a hard drive out of an old non translating non LBA supporting BIOS like this. The new drive controller and/or the disk utility might assume that the drive is being accessed in translation mode and completely mess up the CHS geometry. This is a common situation when trying to partition a drive on the more modern system to use in the old one. In this case I believe it would be safe because the CHS geometry is stored in the MBR, and the disk utility should use that. Of course it won't boot in the modern system unless transation is disabled. Oct 31, 2023 at 1:51
  • 1
    On your updates. 1) "If part1 starts at (e.g.) 1024 sectors" It won't be. It's almost certainly at sector 64 if it isn't right there at 2 (rare but possible). 2) "You do not need LBA addressing because CHS can go up to 8GB." His doesn't. His bios doesn't do CHS translation so he's limited to 1024/16/63 thus 504MB maximum addressable range.
    – Joshua
    Oct 31, 2023 at 14:12
  • 1
    @MichaelKarcher There may be some confusion as to terminology. I've added an update. Nov 3, 2023 at 2:38

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .