SMB Share Between Linux and MS-DOS in QEMU

Objective

To create a network share between a Linux host and an MS-DOS guest running in QEMU in order to share files between the host and a running guest bidirectionally and instantly; and to have a packet driver ready at interrupt 0x60 for the usual-suspect networking programs.

Systems

Prerequisites

Samba installed (samba package in Debian). Configuration will be described later.

A QEMU VM with an installation of MS-DOS 6.22. I’ve installed from disk images found in the Internet Archive and started the setup described here from a clean slate.

Files for the DOS guest

Microsoft Network Client 3.0. This post provides a ZIP archive containing two self-extracting archives for DOS, each of which contains the files for one installation disk. I struggled a bit trying to create floppy images using qemu-img and mkfs.fat, and copying the files from within the VM (the floppies kept getting corrupt), so I ended up using mtools for formatting and copying.

dd if=/dev/zero of=disk1.img bs=1024 count=1440
mformat -f 1440 -i disk1.img :: # Note the double colon at the end of these lines
mcopy -i disk1.img hd/DSK1/* ::
mdir -i disk1.img ::

You can mount your raw (not qcow2) harddisk image as a loopback device in order to get the files out of the guest after self-extraction. Since the image has a partition table, this requires passing mount the offset to the actual filesystem, which can be done using a Bash function like the one below. Which will probably break if the output format of fdisk doesn’t match exactly what I have. The gist is just offset = physical_sector_size * start_sector_of_partition.

#
# mount_img(image, mount_point)
#
mount_img() {
    o=$(sudo fdisk -l "$1" | tr '\n' ' ')
    ptn1='Sector size[^:]+:[^/]+/ ([0-9]+)'
    ptn2=$1'1[[:space:]*]+([0-9]+)'
    [[ "$o" =~ $ptn1 ]]; secsize=${BASH_REMATCH[1]}
    [[ "$o" =~ $ptn2 ]]; startsec=${BASH_REMATCH[1]}
    uid=$(id -u); gid=$(id -g)
    sudo mount -o loop,offset=$((secsize * startsec)),uid=$uid,gid=$gid "$1" "$2"
}

It is not advisable to have the image mounted while the guest is running: I’ve experienced disk writes from the guest being discarded when the disk was mounted on both sides. This is precisely why I wanted to set up a network share. It’s still good to be able to mount the image and write to it though, since this is how you revert changes to the guest’s AUTOEXEC.BAT and CONFIG.SYS when you’ve bricked it.

AMD PCnet FAST III Ethernet drivers. You can get these here (only OEMSETUP.INF and PCNTND.DOS are needed).

Packet driver interface over NDIS. DIS_PKT.DOS is in the archive downloadable here.

So, to recapitulate, by now you have the following resources ready.

Samba configuration

Before installing anything in DOS, let’s configure Samba. The SMB that Microsoft Network Client will be speaking is quite old, so we need to tune Samba down to let it accept the stone age version of the protocol. This is done quite easily by setting a few options in /etc/samba/smb.conf.

In the [global] section:

   netbios name = ELSEWHERE
   server min protocol = CORE
   server max protocol = NT1
   lanman auth = yes
   client lanman auth = yes
   ntlm auth = yes
   raw NTLMv2 auth = yes
   client NTLMv2 auth = yes
   bind interfaces only = no
   map to guest = Bad User
   guest ok = yes

netbios name is your personal name, and it must match what you use to connect from the guest side later, so keep note of it.

And, at the bottom of the file, add a section describing the share. The section name (dos_share here) is the name of the share and will be passed to the net utility in DOS later.

[dos_share]
   comment = good stuff
   path = /home/user/dosshare
   browseable = yes
   read only = no
   guest ok = yes
   create mask = 0777
   directory mask = 0777
   force user = user

In force user = user, user is your username on the host. (I happen to always name myself user.) The path is of course the directory on the host where the shared files will be located. Create it.

After applying these changes, restart Samba (sudo systemctl restart smbd) and verify its status is OK (sudo systemctl status smbd).

Installing Microsoft Network Client

With that out of the way, and the prerequisites from the other section met, we can start installing the DOS software. Launch qemu-system-i386 with the harddisk image and the two floppy images, passing the correct network card model (pcnet):

qemu-system-i386 -m 8m -fda disk1.img -fdb disk2.img -hda hd.img \
    -net nic,model=pcnet -net user -monitor stdio

-monitor stdio is a convenience that starts a ‘qemu shell’ where you can enter commands such as change floppy0 image_file.img, eject floppy0, and system_reset while the guest is running. Interestingly, qemu also supports rendering the VGA text screen directly in your terminal using ncurses, and when you do this, you can assign the monitor to a socket and connect to it with socat. This requires qemu to have been built with ncurses support. Using the ncurses display has the advantage of being able to copy from the VGA screen to the host clipboard. If your terminal’s colour scheme makes some DOS screens unreadable, you can change the terminal colours using ANSI escape codes to set them to the standard CGA palette, like printf '\e]4;5;#AA00AA\a' for setting colour 5 to magenta, for example. (Provided your terminal emulator supports this.) A function that sets all 16 CGA colours can be found in the util.sh script that’s in the archive that I will attach below.

qemu-system-i386 -m 8m -fda disk1.img -fdb disk2.img -hda hd.img -net nic,model=pcnet \
    -net user -display curses -monitor unix:/tmp/qemu.sock,server,nowait

socat - UNIX-CONNECT:/tmp/qemu.sock

Now that we’re in DOS, we can start the MNC setup utility.

A:
SETUP

Install the Network Client files in C:\NET (the default). When prompted to pick an adapter, select *Network adapter not shown on list below ....

MNC install 1

Then specify the path where you put OEMSETUP.INF and PCNTND.DOS before (C:\PCNET).

MNC install 2

It will find the Advanced Micro Devices PCNET family adapter. Install it. I just accepted when it asked me if I’d like to ‘setup for best performance’. Then enter your username. This can be anything and doesn’t have to match the username on the host side. On the following screen, select Change Setup Options.

MNC install 3

Change Change Redir Options to Use the Basic Redirector.

MNC install 4

Go back to the previous screen, select Change Network Configuration, and there, add the TCP/IP protocol (Add Protocol -> Microsoft TCP/IP). Your Installed Network Adapter(s) and Protocol(s) should end up looking like this.

MNC install 5

Then go back to the previous screen and select The listed options are correct. It will ask you for the OEM Driver Disk, which at this point is B:\ (disk2.img). This concludes the MNC installer. Go to your qemu monitor, enter eject floppy0 and eject floppy1, then back to DOS, and hit ENTER to reboot. On startup, some network-related things will be printed, after which you are asked for your username. Confirm the one you’ve entered before, then enter an empty password. When asked if you want to create a password-list file, enter Y, and confirm your empty password. After this, MNC’s initial setup is completed.

MNC install 6

Open your LMHOSTS file (EDIT C:\NET\LMHOSTS) and add an entry for the netbios name that you’ve set in your Samba configuration:

10.0.2.2    ELSEWHERE   #PRE #NOFNR

10.0.2.2 is the IP address by which the host is reachable from the guest. It’s a qemu default. Reboot the quest (by entering system_reset in the qemu monitor). Apparently the LMHOSTS entry is required to be present at boot time. Now you can mount your share.

net use /PERSISTENT:NO z: \\ELSEWHERE\dos_share
Working share

(net has already been added to the path.) I’m using /PERSISTENT:NO because I’ve experienced some hiccups when mounting the share in persistent mode. In case you do mount a persistent share and want to remove it: net use z: /DELETE. The same can be achieved by wiping C:\NET\CONNECT.DAT, where the shares are persisted in a binary format. Anyway, now you can edit files on the host and see the changes reflected in DOS instantly, and vice versa.

There’s something else left to do though. We need to free up some conventional memory (i.e. the first 640K of RAM), as all the network stuff that’s being loaded on startup now uses quite a bit of it. We’ll get rid of NWLINK, as we don’t need IPX, and we’ll move some things to high memory. I’ll add the files we’re modifying (AUTOEXEC.BAT, CONFIG.SYS, and NET\PROTOCOL.INI) to the archive I’ll attach below.

Open C:\NET\PROTOCOL.INI and remove these lines:

transport=ms$nwlink,MS$NWLINK
lana0=ms$pcntn3,1,ms$nwlink

Change the lana entries in [network.setup] so you have

lana0=ms$pcntn3,1,ms$ndishlp
lana1=ms$pcntn3,1,tcpip

Then add the [PKTDRV] section.

[PKTDRV]
DriverName=PKTDRV$
BINDINGS=MS$PCNTN3
INTVEC=0x60
CHAINVEC=0x68

That’s it for this file. Let’s move on to CONFIG.SYS. Change it so it contains the following.

DEVICE=C:\DOS\SETVER.EXE
DEVICE=C:\DOS\HIMEM.SYS
DEVICE=C:\DOS\EMM386.EXE NOEMS
DOS=HIGH,UMB
FILES=30
BUFFERS=15,0
DEVICEHIGH=C:\NET\PROTMAN.DOS /I:C:\NET
DEVICEHIGH=C:\NET\PCNTND.DOS
DEVICEHIGH=C:\NET\DIS_PKT.DOS
DEVICEHIGH=C:\NET\NEMM.DOS
DEVICEHIGH=C:\NET\TCPDRV.DOS
DEVICEHIGH=C:\NET\ifshlp.sys
LASTDRIVE=Z

Now, let’s edit AUTOEXEC.BAT. Remove these lines:

C:\NET\nwlink
C:\NET\umb.com
C:\NET\nmtsr.exe
C:\NET\emsbfr.exe
C:\NET\net start

Lastly, we add a line to mount our share on startup (if desired), so the whole of AUTOEXEC.BAT ends up looking like this.

@ECHO OFF
PROMPT $p$g
PATH C:\NET;C:\DOS
SET TEMP=C:\DOS
C:\NET\net initialize
C:\NET\netbind.com
C:\NET\tcptsr.exe
C:\NET\tinyrfc.exe
NET USE /YES /PERSISTENT:NO Z: \\ELSEWHERE\dos_share

Now we have our share ready every time the DOS VM boots up, and MEM reveals that our Total under 1 MB of free memory is 563K, which is fair, I guess.

Oh, and here’s the archive I’ve mentioned, containing the required files for DOS, and the configuration files we’ve changed.

dos-smb-share.tar.bz2 (1.1M)

That’s all, folks. Happy DOSing!

–hekliet, 2026-06-24

[^1] Hansen, U. (2007). Networking FreeDOS - NDIS driver installation (W. Spiegl, Mod., 2022). Retrieved from https://home.mnet-online.de/willybilly/fdhelp-109/en/hhstndrd/network/ndis_ins.htm