Linux 和 DOS 一起使用

作者:Marty Leisner

当机器出厂时预装了 DOS,硬盘通常被安排成整个磁盘都是 C: 盘。即使您只想运行 DOS,这也是非常不灵活的,如果您还想运行其他操作系统,那更是无法忍受的。PC 分区表支持以下配置(总共允许 4 个):

  • 一个主 DOS 分区

  • 一个扩展分区(包含多个逻辑分区)

  • 一个或多个非 DOS 分区(非常适合 Linux)

调整分区大小

为了运行 Linux,您通常需要重新分区您的磁盘,无论您运行什么操作系统(DOS 或 UNIX),这通常都是一个好主意,原因如下:

  • 灵活性

  • 抗崩溃性 通常,磁盘问题仅限于介质上的一个逻辑磁盘。通过在一个物理设备上拥有多个逻辑磁盘,如果出现任何问题,它将被限制在一个分区内。

  • 控制 您可能不想将整个硬盘分配给任何应用程序。为应用程序集分配分区可以限制它们可以使用的磁盘空间量。您可能会在分区上遇到“磁盘空间不足”的情况,但不一定是整个磁盘。

当您想要重新分区您的磁盘时,标准程序过去是:

  • 备份到软盘

  • 擦除您的硬盘

  • 重新分区

  • 恢复您的软盘

这可能适用于备份几兆字节,但现在 PC 通常安装了 200 Mb 的 Microsoft Windows 系统,几乎没有关于什么重要和什么不重要的文档。有一个非常聪明的实用程序叫做 fips,由 Arno Schaefer 编写,电子邮件地址是 schaefer@rbg.informatik.th-darmstadt.de。它保存在 sunsite.unc.edu 的 /pub/Linux/system/Install/fips12.zip 中。

fips 非破坏性地缩小您的主分区,将您的所有文件保留在原位。您运行 defrag(一个 MS-DOS 程序)将所有文件打包到连续的扇区中,然后运行 fips 来缩小您的主分区。

然后您可以重新启动并创建一个扩展 DOS 分区(使用 DOS fdisk 程序),并使用 Linux 创建 Linux 分区(使用 Linux fdisk 程序)。fips 是一个很棒的工具,解决了非常实际的问题。请在使用前仔细阅读说明;任何写入分区表的工具,如 fdisk,都应谨慎使用。

注意: 使用 fdisk 时要非常小心。在您确定 DOS 和 Linux 在分区位置上达成一致之前,不要对您的介质做任何破坏性的事情(即从 DOS 执行 mkfs 或 format)。我注意到 DOS fdisk 程序有一些非常“糟糕”的特性——它将可用空间读取为 100 Mb(这是正确的),但是当我允许它使用所有可用空间创建一个分区时,它创建了一个 350 Mb 的分区(非常糟糕!)

使用扩展分区

扩展分区是绕过物理磁盘上 4 个分区限制的一种方法。扩展分区可以作为更多分区的容器,这些分区可以是 DOS、Linux(原生或交换)或任何其他类型。请记住,非 DOS 分区需要在非 DOS 版本的 fdisk 中创建。扩展分区对于生成超过通常找到的 4 个分区非常方便。我从未见过关于向系统添加交换空间的良好讨论——一个好的方法是使用扩展分区。

扩展分区是一个好主意——对于运行 DOS 来说。扩展分区中的每个逻辑分区都由 DOS 赋予一个字母(例如 D:、E:、F:)。这些驱动器中的每一个都可以格式化并在 DOS 下使用。我使用一个名为 join 的应用程序,从 DOS 6 开始,它不再与 DOS 一起分发,但您仍然可以通过 ftp 从 ftp.microsoft.com 的 /peropsys/msdos/public/supplmnt/ 获取副本。join 本质上允许您“挂载驱动器”,以便您拥有一个单一的层次结构树(如 Linux)。

例如,我可能会配置一个系统,其中 D: 驱动器用于个人资料,E: 驱动器用于 djgpp,它是 GNU C 编译器到 DOS 的移植版本。然后,在我的 C 盘根目录下,我为 \marty、\gnu 创建目录,并在我的 autoexec.bat 中,我有

join d: \marty
join e: \gnu

这样我就不必处理驱动器号了。我还将 A: 连接到 \a,所以我的软盘出现在树上。但是,如果您这样做,您将破坏 DOS format 程序以及几乎所有商业软件的 DOS 安装/设置程序。似乎它们只能处理 A:。

不幸的是,您不能将 join 与网络驱动器一起使用。当我们谈论 DOSEMU 时,稍后会详细介绍这一点。

使用 loadlin 和 config.sys

我发现使用 loadlin(一个基于 DOS 的加载器)很有效;这具有始终在运行 Linux 之前启动工作系统的明显优势。我对 LILO 的经验是,如果您没有正确操作,您的系统只能用作镇纸。在我的 MS-DOS config.sys 中,我利用了菜单,结果如清单 1 所示。

menuitem=dos
menuitem=simple.dos
menuitem=linux.1.2.8
menuitem=scandisk
menudefault=linux.1.2.8,5

[linux.1.2.8]
SHELL=C:\loadlin\loadlin.exe \loadlin\zimage.128 root=/dev/hdc2 -v ro

[simple.dos]

[dos]
DEVICE=C:\DOS\HIMEM.SYS
DEVICEHIGH=C:\MAGICS20\CDIFINIT.SYS /T:X
DEVICEHIGH=C:\MTM\MTMCDAI.SYS /D:MTMIDE01
DEVICEHIGH /L:2,12048 =C:\DOS\SETVER.EXE
DOS=HIGH
STACKS=9,256

[scandisk]
SHELL=c:\dos\scandisk.exe /all /checkonly

我以 5 秒的延迟启动 Linux,这样做的好处是系统始终可以启动 DOS 并且可以在某种程度上工作。我发现这比使用 LILO 和修改硬盘上的主引导记录更可取(如果您做错了任何事情,您需要从软盘启动才能恢复)。

可以很容易地从命令行选择多个内核和/或配置。使用 loadlin,您必须创建一个压缩内核 (make zImage),然后将其放在 DOS 分区上。我发现即使在首次安装 Linux 时,此策略也很有效(而不是处理引导和根软盘,系统只需根软盘即可引导内核)。您可以轻松地添加到菜单中,以拥有多个不同的内核可以从中启动。请记住,您可以使用 rdev 实用程序将默认值(如根设备)构建到内核中。

在您的 autoexec.bat 中,您可以使用以下策略:

goto %config%

:simple.dos
PATH=C:\marty\bin;C:\gnu\bin;C:\dos;C:\
goto end

:dos
SET SOUND16=C:\MAGICS20
C:\MAGICS20\SNDINIT /b
SET BLASTER=A220 I7 D1 T4
C:\DOS\SMARTDRV.EXE 512 512 /C
C:\DOS\IMOUSE.COM
PROMPT $p$g
SET PATH=c:\gnu\bin;C:\MARTY\BIN;C:\WINDOWS;C:\DOS;

SET TEMP=C:\DOS
JOIN d: \marty
JOIN f: \gnu
goto end

:end

simple.dos 设置在概念上与在单用户模式下启动 Linux 相同。我发现它对于调试 DOS 系统非常有用。如果您愿意,您可以添加 config.sys 菜单项以启动不同的内核、在单用户模式下启动 Linux、从软盘启动 Linux 等。

UMSDOS 文件系统

在标准 Linux 内核配置中,UMSDOS 文件系统未启用。如果您需要在 Linux 和 DOS 之间共享文件系统,UMSDOS 有许多主要优势。它保留了完整的 Unix 语义,因此您不必总是受到 DOS 问题的困扰,例如:

  • 缺少链接

  • 8+3 文件命名约定的限制

  • 文件名中字符的限制

  • 一个日期(而不是访问/更改/修改时间)

  • 缺少所有者/组

使用 UMSDOS,您可以利用在 DOS 和 Linux 之间共享的文件系统,并在运行 Linux 时看起来像 Linux 文件系统。如果您希望文件在 MS-DOS 和 Linux 之间可移植,请将自己限制为 DOS 文件名(8+3 个字符)。如果您希望文件出现在 DOS 下,请不要使用链接。使用 Linux 文件系统,很容易做诸如创建“点文件”、对树进行 gzip-r、创建链接和备份文件之类的事情。任何文件都可以在 MS-DOS 中读取;但是,如果您不符合 MS-DOS 文件命名约定,文件将被“修改”(即,它们的名称被压缩以适应 8+3 命名空间)。这种修改类似于 mfs 中发生的情况;那些使用 PC-NFS 的人可能对此很熟悉。

当您开始运行 UMSDOS 文件系统时,请记住运行名为 umssync 的应用程序,它会在 --linux-.--- 文件和目录内容之间创建一致性。如果您在 Linux 不知情的情况下在 DOS 下添加或删除文件,您可能会遇到问题。在挂载发生后从 /etc/rc.d/rc.local 或 /etc/rc.d/rc.M 调用 umssync,这应该不是问题。

我注意到 UMSDOS 文件系统中的一个问题——挂载点归 root 所有,只有 root 可写,并且日期是 epoch 的开始。一个简单的解决方法是在挂载后,根据需要在您的 /etc/rc.d/rc.local 文件中对挂载点执行 chown/chmod。此外,我发现偶尔从 DOS 运行 scandisk 很有用(请注意 config.sys 中的 scandisk 目标)。

与正常的 ext2 相比,DOS 和 UMSDOS 文件系统存在性能损失。如果您在单个目录中有数百个文件,则性能损失会变得严重(当您执行 ls 时,去喝杯咖啡)。我注意到顺序 I/O(使用名为 Bonnie 的测试器)在 ext2 上比 UMSDOS 略快。

但是,如果您正在使用 DOSEMU,UMSDOS 是理想的选择。您将 DOS 文件放在 UMSDOS 分区上,您可以轻松地从 DOS、DOSEMU 或 Linux 访问它们。如果它们保持在 8+3 个字符的 DOS 文件系统范围内,它们在 DOS 和 Linux 上看起来都是一样的。UMSDOS 分区在与 DOS 共享文件时提供了很大的优势(比 MSDOS 文件系统更大,因为它将 Linux 文件视为 Linux 文件),但必须注意性能。

DOSEMU 的文件系统视图

DOSEMU 可以通过几种不同的方式访问文件,这些方式以不同的方式与 DOS 和 Linux 集成。方法有:

镜像

一个文件,其排列方式使其看起来像 DOS 硬盘。它是一个存储在文件中的“虚拟”硬盘。

分区

直接访问 MS-DOS 分区。如果该分区也在 Linux 上使用,则不应是可写的。请注意,您可以将挂载的分区用作 DOSEMU 文件系统,这可能会破坏文件系统。如果它们都是只读的,这是最安全的;如果您想使它们可写,您应该一次只使其中一个可写。此外,如果 DOS 分区可以从 DOSEMU 写入,则多个 DOSEMU 会话可能会导致相同类型的文件系统损坏。

整个磁盘

直接使用整个磁盘。对此要非常小心。使用时,将其设置为 [cw]只读[ecw] 会很有用。

重定向访问 通过重定向器访问任何 Linux 目录。这非常

有趣——继续阅读以了解更多关于此的信息。

通常,DOSEMU 从一个小的镜像文件启动(一个专门构造的文件,它在 DOSEMU 看来像一个硬盘,有自己的文件系统和主引导记录)。软盘被视为传统的软盘。DOSEMU 可以读取它们——并且您需要一个可引导的 MSDOS 软盘来启动该过程。要开始将虚拟硬盘设置为 C: 盘,您首先从可引导的 MSDOS 软盘启动,然后执行

A>fdisk /mbr
A>sys c:

然后您可以从虚拟硬盘 C: 启动。这在 DOSEMU 文档中有更全面的介绍。

镜像硬盘通常仅用于启动 DOSEMU。您可以将此镜像视为一个大型虚拟硬盘,但缺点是您只能从 DOSEMU 访问此磁盘。稍后将解释的其他形式都可以从 Linux 访问,MS-DOS 分区可以从原始 MS-DOS 访问。

DOSEMU 支持整个磁盘访问(例如 /dev/hdc)和分区访问。我从未使用过整个磁盘访问,似乎没有充分的理由这样做。但是,我使用过分区访问。这些分区不能同时被 Linux 挂载,因为 DOSEMU 会操作物理分区,这会使内核感到困惑,并可能破坏分区。DOSEMU 需要有权访问物理分区(您必须确保您有权读取和写入)。

我发现最有趣的方法是重定向器。这允许您将 Linux 文件系统视为网络驱动器。如果您重定向 Linux 文件系统的根目录,您可以轻松地在 DOSEMU 中访问您的所有 Linux 文件。如果您有 NFS 挂载或自动挂载程序正在运行,您甚至可以无缝地遍历到其他机器。请注意,它找到的所有内容都必须转换为 8+3 MS-DOS 命名空间。

如果不需要修改,它工作得很好。但是,您可能会看到这个:

F:\dir a*

 Volume in drive F is s2/dist/X11
 Directory of F:\

ARCH                       05-26-95   1:01a
ACM-4~YX GZ        971,391 06-02-95  11:02p
ARENA    TAR       604,160 05-19-95   9:43p
ARENA~D0 GZ        530,468 05-22-95   8:35p

而不是这个:

leisner@compudyne$ ls -d a*
acm-4.7.tar.gz   arch/
arena-96.tar.gz  arena.tar

大多数时候您都可以弄清楚它的意思。我注意到在识别拼写相同但某些字符大小写不同的文件时存在一些问题。在 Unix 上,它们是不同的,但 DOS 没有文件名称大小写的概念(例如,您将遇到 makefile 和 Makefile 的问题)。

在 Linux 上启动 DOSEMU

您不应该在虚拟硬盘上做太多事情,除了启动。我发现拥有一个 ~/dos 目录很有效。我在虚拟硬盘上的 config.sys 看起来像这样:

# make sure we support ems
devicehigh=c:\ems.sys
# the last drive is m, it can range up to z:
# the default is f:
lastdrive=m
FILES=40
SWITCHES=/f
# make a copy of c: drive on l:
install=c:\subst.exe l: c:\
# this is the fun part
# change the concept of c: drive
install=c:\lredir.exe  c: LINUX\fs>{home}\dos

最后几行是最有趣的。我正在使虚拟硬盘通过 L: 驱动器可供 dosemu 访问。如果您想“锁定”虚拟硬盘,请使用 chmod 命令使文件只读。然后,继续从用户的 ~/dos 目录启动(期望 autoexec.bat 在那里)。这意味着 autoexec.bat 只是一个普通的 Linux 文件。您可以使用任何 Linux 编辑器编辑它,但您必须记住在每行末尾放置 \r(这是一个 control-M 字符;在 vi 中执行:

control-v-m,

在 Emacs 中执行 control-q-m)。在我的 autoexec.bat 中,我有:

lredir f: linux\fs\${PWD}
lredir e: linux\fs\
set PATH=e:\dos\gnu\bin;e:\dos\c\dos;c:\;c:\bin
f:

${...} 语法允许替换环境变量。PWD 是当前工作目录。Bash 通常不会为您导出它;我显式添加:

export PWD

到我的 .bashrc 文件。

我只是将 F: 驱动器映射到我的当前工作目录。这非常方便,因为当我在 Linux 上处理 DOS 文件时,我可以随时随地启动 DOSEMU。

我将我的整个文件系统映射到 E:。这使得几乎所有可以在 Linux 下访问的文件也可以在 DOSEMU 下访问。这包括 NFS 文件。

某些程序在使用重定向器时会出现问题,因为它充当网络驱动器。对于这些程序,您需要使用分区访问、镜像访问或 RAM 磁盘。

从已安装的 DOS 系统和 Win95 启动

进一步扩展上述场景,我们实际上可以使用以下命令从 DOS 硬盘启动:

disk { wholedisk "/dev/hda" readonly }

这有很多优点——主要是虚拟硬盘不必创建和维护(请注意,虚拟硬盘仅在 DOSEMU 中可读,这使得维护很麻烦)。DOSEMU 允许您在配置文件(使用 EmuSys 或 EmuBat)或从环境(使用 AUTOEXEC 和 CONFIG)中选择系统文件(config.sys 和 autoexec.bat)的扩展名。此启动盘不可写,因此请使用 lredir 切换到可写的 C: 驱动器。

我通常有一个名为 config.emu 的 DOSEMU config.sys 文件。在其中,我只是将 C: 驱动器(从虚拟硬盘)更改为 ~/dos 目录,并在那里有一个 autoexec.bat 文件。我还有指向常用 DOS 程序(即 command.com)的链接。

Win95 在此方案中抛出了一些曲线。自官方发布以来,我一直在使用 Win95,并且对其印象深刻(任何东西都可以改进 Windows 3.1 的问题)。Win95 使用文件 MSDOS.SYS 来控制启动过程,作为另一个 ASCII 配置文件。为了激活 config.sys 菜单以启动 DOS 或 Linux,以下方法在 MSDOS.SYS 中有效:

[Options]
Logo=0
BootMulti=1
BootGUI=0
BootDelay=0

在这种情况下,在您运行 Linux 后,启动 DOSEMU 将允许您运行 DOS 版本 7。

如果您在启动时按下 F4,您也可以运行旧版本的 DOS(如果这是一个升级)。但是在这种情况下,如果您启动 Linux,然后从 DOS 硬盘启动 DOSEMU,启动加载程序会变得非常混乱,因为它会在 Win95 和旧版本的 DOS 系统之间洗牌文件,如 msdos.sys、config.sys 和 autoexec.bat,并将适当的文件放在适当的位置以供适当的 DOS 使用(Win95 配置文件以 .w40 结尾,旧版本的 DOS 文件以 .dos 结尾)。显然,您不希望在 Linux 下运行 DOSEMU!

结论

我偶尔使用 DOS,但在 MS-DOS 中做了很多工作,因为我正在开发 DOSEMU 和 alpha djgpp。我发现您可以通过扩展分区对分区进行非常灵活的操作,并且 Linux 对 DOS 文件系统处理得非常好(尤其是 UMSDOS)。

我发现 MS-DOS 应用程序的交叉开发是 DOS 软件开发的理想选择,您可以编写可移植的软件并在 Linux 上尝试它——然后使用 Linux 编译器生成 .EXE djgpp 文件并在 DOSEMU 中运行 djgpp 二进制文件。

Marty Leisner (leisner@sdsp.mc.xerox.com) 是 Xerox 公司的专业程序员,他第一次接触 Unix 是在运行 V7 的 PDP 11 上。

加载 Disqus 评论