initial commit, asm operating system with the MikeOS bootloader
This commit is contained in:
commit
c99ecaa620
70
build-linux.sh
Executable file
70
build-linux.sh
Executable file
@ -0,0 +1,70 @@
|
||||
#!/bin/sh
|
||||
|
||||
# This script assembles the CrawOS bootloader, kernel and programs
|
||||
# with NASM, and then creates floppy and CD images (on Linux)
|
||||
|
||||
# Only the root user can mount the floppy disk image as a virtual
|
||||
# drive (loopback mounting), in order to copy across the files
|
||||
|
||||
# (If you need to blank the floppy image: 'mkdosfs disk_images/crawos.flp')
|
||||
|
||||
|
||||
if test "`whoami`" != "root" ; then
|
||||
echo "You must be logged in as root to build (for loopback mounting)"
|
||||
echo "Enter 'su' or 'sudo bash' to switch to root"
|
||||
exit
|
||||
fi
|
||||
|
||||
|
||||
if [ ! -e disk_images/crawos.flp ]
|
||||
then
|
||||
echo ">>> Creating new CrawOS floppy image..."
|
||||
mkdosfs -C disk_images/crawos.flp 1440 || exit
|
||||
fi
|
||||
|
||||
|
||||
echo ">>> Assembling bootloader..."
|
||||
|
||||
nasm -O0 -w+orphan-labels -f bin -o source/bootload/bootload.bin source/bootload/bootload.asm || exit
|
||||
|
||||
|
||||
echo ">>> Assembling CrawOS kernel..."
|
||||
|
||||
cd source
|
||||
nasm -O0 -w+orphan-labels -f bin -o kernel.bin kernel.asm || exit
|
||||
cd ..
|
||||
|
||||
|
||||
echo ">>> Assembling programs..."
|
||||
|
||||
|
||||
echo ">>> Adding bootloader to floppy image..."
|
||||
|
||||
dd status=noxfer conv=notrunc if=source/bootload/bootload.bin of=disk_images/crawos.flp || exit
|
||||
|
||||
|
||||
echo ">>> Copying CrawOS kernel and programs..."
|
||||
|
||||
rm -rf tmp-loop
|
||||
|
||||
mkdir tmp-loop && mount -o loop -t vfat disk_images/crawos.flp tmp-loop && cp source/kernel.bin tmp-loop/
|
||||
|
||||
|
||||
sleep 0.2
|
||||
|
||||
echo ">>> Unmounting loopback floppy..."
|
||||
|
||||
umount tmp-loop || exit
|
||||
|
||||
rm -rf tmp-loop
|
||||
|
||||
|
||||
echo ">>> Creating CD-ROM ISO image..."
|
||||
|
||||
rm -f disk_images/crawos.iso
|
||||
mkisofs -quiet -V 'MIKEOS' -input-charset iso8859-1 -o disk_images/crawos.iso -b crawos.flp disk_images/ || exit
|
||||
|
||||
echo '>>> Done!'
|
||||
|
||||
sudo qemu-system-i386 -drive file=disk_images/crawos.flp,index=0,if=floppy,format=raw
|
||||
|
117
build-macos.sh
Executable file
117
build-macos.sh
Executable file
@ -0,0 +1,117 @@
|
||||
#!/bin/bash -u
|
||||
|
||||
if ! [ "$(id -u)" -eq 0 ]; then
|
||||
echo "[halt] Not running with superuser privileges."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "[okay] running as superuser."
|
||||
|
||||
vercomp() {
|
||||
[ "$1" = "$2" ] && return 0
|
||||
|
||||
local IFS=.
|
||||
local i ver1=($1) ver2=($2)
|
||||
unset IFS
|
||||
if [ "${#ver1[@]}" -ne "${#ver2[@]}" ]; then
|
||||
echo "[halt] versions being compared don't have the same form!" >&2
|
||||
echo "[halt] '$1' vs '$2'" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
for ((i = 0; i < ${#ver1[@]}; ++i)); do
|
||||
(( ${ver1[i]} > ${ver2[i]} )) && return 1
|
||||
(( ${ver1[i]} < ${ver2[i]} )) && return 2
|
||||
done
|
||||
|
||||
return 0
|
||||
}
|
||||
|
||||
nasm_version_check () {
|
||||
vercomp $1 $2
|
||||
case $? in
|
||||
0) op='=';;
|
||||
1) op='>';;
|
||||
2) op='<';;
|
||||
esac
|
||||
if [ $op = '=' ] || [ $op = '>' ]; then
|
||||
echo "[okay] nasm version at least '$2'"
|
||||
return 0
|
||||
else
|
||||
echo "[halt] nasm version is too low" >&2
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
|
||||
# Main
|
||||
declare -r NASM_VER_REGEX='[0-9]+\.[0-9]+\.[0-9]+'
|
||||
declare -r MINIMUM_NASM_VERSION=2.10.09
|
||||
declare -r NASM_PATH=$(which nasm)
|
||||
|
||||
declare current_nasm_version=
|
||||
|
||||
if [ -z "$NASM_PATH" ]; then
|
||||
echo "[halt] nasm was not found on the system! Make sure it is named nasm and is in the path."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
current_nasm_version=$(nasm -v)
|
||||
|
||||
[ $? -ne 0 ] && echo '[halt] error calling nasm' >&2 && exit 1
|
||||
|
||||
if [[ "$current_nasm_version" =~ $NASM_VER_REGEX ]]; then
|
||||
current_nasm_version=${BASH_REMATCH[0]}
|
||||
echo "[okay] found current nasm version of '$current_nasm_version'"
|
||||
else
|
||||
echo "[halt] could not determine nasm version" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
nasm_version_check "$current_nasm_version" "$MINIMUM_NASM_VERSION"
|
||||
|
||||
[ $? -ne 0 ] && echo "[halt] nasm not found or version is incompatible" >&2 && exit 1
|
||||
|
||||
"$NASM_PATH" -O0 -f bin -o source/bootload/bootload.bin source/bootload/bootload.asm || exit 1
|
||||
echo "[okay] assembled bootloader"
|
||||
|
||||
cd source
|
||||
"$NASM_PATH" -O0 -f bin -o kernel.bin kernel.asm || exit 1
|
||||
echo "[okay] assembled kernel"
|
||||
cd ..
|
||||
|
||||
cd programs
|
||||
for i in *.asm; do
|
||||
"$NASM_PATH" -O0 -f bin $i -o "$(basename $i .asm).bin" || exit 1
|
||||
echo "[okay] assembled program: $i"
|
||||
done
|
||||
echo "[okay] assembled all programs"
|
||||
cd ..
|
||||
|
||||
cp disk_images/mikeos.flp disk_images/mikeos.dmg
|
||||
echo "[okay] copied floppy image"
|
||||
|
||||
dd conv=notrunc if=source/bootload/bootload.bin of=disk_images/mikeos.dmg || exit 1
|
||||
echo "[okay] added bootloader to image"
|
||||
|
||||
tmp_file=$(mktemp -d /tmp/$(basename $0).XXXXXX)
|
||||
[ $? -ne 0 ] && echo "[halt] error creating a temp file" >&2 && exit 1
|
||||
|
||||
dev=$(echo -n $(hdid -nobrowse -nomount disk_images/mikeos.dmg))
|
||||
[ $? -ne 0 ] && echo "[halt] could not create disk from image" >&2 && exit 1
|
||||
|
||||
mount -t msdos "$dev" "$tmp_file"
|
||||
[ $? -ne 0 ] && echo "[halt] could not mount "$dev"" >&2 && exit 1
|
||||
|
||||
cp source/kernel.bin "$tmp_file/"
|
||||
cp programs/*.bin programs/*.bas programs/sample.pcx programs/vedithlp.txt programs/gen.4th programs/hello.512 "$tmp_file"
|
||||
echo "[okay] added programs to image"
|
||||
|
||||
diskutil umount "$tmp_file"
|
||||
hdiutil detach "$dev"
|
||||
rm -rf "$tmp_file"
|
||||
echo "[okay] unmounted floppy image"
|
||||
|
||||
rm -f disk_images/mikeos.iso
|
||||
mkisofs -quiet -V 'MIKEOS' -input-charset iso8859-1 -o disk_images/mikeos.iso -b mikeos.dmg disk_images/ || exit 1
|
||||
echo "[okay] converted floppy to ISO-8859-1 image"
|
||||
echo "[done] build completed"
|
80
build-openbsd.sh
Executable file
80
build-openbsd.sh
Executable file
@ -0,0 +1,80 @@
|
||||
#!/bin/sh
|
||||
|
||||
# This script assembles the MikeOS bootloader, kernel and programs
|
||||
# with NASM, and then creates floppy and CD images (on OpenBSD)
|
||||
|
||||
# Only the root user can mount the floppy disk image as a virtual
|
||||
# drive (loopback mounting), in order to copy across the files
|
||||
|
||||
|
||||
echo "Experimental OpenBSD build script..."
|
||||
|
||||
|
||||
if test "`whoami`" != "root" ; then
|
||||
echo "You must be logged in as root to build (for loopback mounting)"
|
||||
echo "Enter 'su' to switch to root"
|
||||
exit
|
||||
fi
|
||||
|
||||
|
||||
if [ ! -e disk_images/mikeos.flp ]
|
||||
then
|
||||
echo ">>> Creating new MikeOS floppy image..."
|
||||
dd if=/dev/zero of=disk_images/mikeos.flp bs=512 count=2880 || exit
|
||||
vnconfig vnd3 disk_images/mikeos.flp && newfs_msdos -f 1440 vnd3c && vnconfig -u vnd3 || exit
|
||||
fi
|
||||
|
||||
|
||||
echo ">>> Assembling bootloader..."
|
||||
|
||||
nasm -O0 -w+orphan-labels -f bin -o source/bootload/bootload.bin source/bootload/bootload.asm || exit
|
||||
|
||||
|
||||
echo ">>> Assembling MikeOS kernel..."
|
||||
|
||||
cd source
|
||||
nasm -O0 -w+orphan-labels -f bin -o kernel.bin kernel.asm || exit
|
||||
cd ..
|
||||
|
||||
|
||||
echo ">>> Assembling programs..."
|
||||
|
||||
cd programs
|
||||
|
||||
for i in *.asm
|
||||
do
|
||||
nasm -O0 -w+orphan-labels -f bin $i -o `basename $i .asm`.bin || exit
|
||||
done
|
||||
|
||||
cd ..
|
||||
|
||||
|
||||
echo ">>> Adding bootloader to floppy image..."
|
||||
|
||||
dd conv=notrunc if=source/bootload/bootload.bin of=disk_images/mikeos.flp || exit
|
||||
|
||||
|
||||
echo ">>> Copying MikeOS kernel and programs..."
|
||||
|
||||
rm -rf tmp-loop
|
||||
vnconfig vnd3 disk_images/mikeos.flp || exit
|
||||
|
||||
mkdir tmp-loop && mount -t msdos /dev/vnd3c tmp-loop && cp source/kernel.bin tmp-loop/
|
||||
|
||||
cp programs/*.bin programs/*.bas programs/sample.pcx programs/vedithlp.txt programs/gen.4th programs/hello.512 tmp-loop
|
||||
|
||||
echo ">>> Unmounting loopback floppy..."
|
||||
|
||||
umount tmp-loop || exit
|
||||
|
||||
vnconfig -u vnd3 || exit
|
||||
rm -rf tmp-loop
|
||||
|
||||
|
||||
echo ">>> Creating CD-ROM ISO image..."
|
||||
|
||||
rm -f disk_images/mikeos.iso
|
||||
mkisofs -quiet -V 'MIKEOS' -r -J -o disk_images/mikeos.iso -b mikeos.flp disk_images/ || exit
|
||||
|
||||
echo '>>> Done!'
|
||||
|
40
buildwin.bat
Executable file
40
buildwin.bat
Executable file
@ -0,0 +1,40 @@
|
||||
@echo off
|
||||
echo Build script for Windows
|
||||
echo.
|
||||
|
||||
echo Assembling bootloader...
|
||||
cd source\bootload
|
||||
nasm -O0 -f bin -o bootload.bin bootload.asm
|
||||
cd ..
|
||||
|
||||
echo Assembling MikeOS kernel...
|
||||
nasm -O0 -f bin -o kernel.bin kernel.asm
|
||||
|
||||
echo Assembling programs...
|
||||
cd ..\programs
|
||||
for %%i in (*.asm) do nasm -O0 -f bin %%i
|
||||
for %%i in (*.bin) do del %%i
|
||||
for %%i in (*.) do ren %%i %%i.bin
|
||||
cd ..
|
||||
|
||||
echo Adding bootsector to disk image...
|
||||
cd disk_images
|
||||
dd count=2 seek=0 bs=512 if=..\source\bootload\bootload.bin of=.\mikeos.flp
|
||||
cd ..
|
||||
|
||||
echo Mounting disk image...
|
||||
imdisk -a -f disk_images\mikeos.flp -s 1440K -m B:
|
||||
|
||||
echo Copying kernel and applications to disk image...
|
||||
copy source\kernel.bin b:\
|
||||
copy programs\*.bin b:\
|
||||
copy programs\sample.pcx b:\
|
||||
copy programs\vedithlp.txt b:\
|
||||
copy programs\gen.4th b:\
|
||||
copy programs\hello.512 b:\
|
||||
copy programs\*.bas b:\
|
||||
|
||||
echo Dismounting disk image...
|
||||
imdisk -D -m B:
|
||||
|
||||
echo Done!
|
BIN
disk_images/crawos.flp
Normal file
BIN
disk_images/crawos.flp
Normal file
Binary file not shown.
BIN
disk_images/crawos.iso
Normal file
BIN
disk_images/crawos.iso
Normal file
Binary file not shown.
1057
doc/CHANGES.TXT
Executable file
1057
doc/CHANGES.TXT
Executable file
File diff suppressed because it is too large
Load Diff
41
doc/CREDITS.TXT
Executable file
41
doc/CREDITS.TXT
Executable file
@ -0,0 +1,41 @@
|
||||
==================================================================
|
||||
MikeOS -- Open source 16-bit operating system for x86 PCs
|
||||
Copyright (C) 2006 - 2022 MikeOS Developers -- see doc/LICENSE.TXT
|
||||
==================================================================
|
||||
|
||||
|
||||
PROJECT ADMIN (MAIN CODE AND HANDBOOKS)
|
||||
|
||||
* Mike Saunders -- okachi@gmail.com
|
||||
|
||||
|
||||
DEVELOPMENT
|
||||
|
||||
* E Dehling
|
||||
* Ian Seyler
|
||||
* John Endler
|
||||
* Joshua Beck
|
||||
* Justin Tokarchuk
|
||||
* Mark M
|
||||
* Matej Horvat
|
||||
* Michael van Tellingen
|
||||
* Mike Gonta
|
||||
* Pablo Gonzales
|
||||
* Peter Nemeth
|
||||
* Paulo Valongo
|
||||
* Takayoshi Sasano
|
||||
* Tomasz Gorol
|
||||
* Tslil Clingman
|
||||
* Walt Nagel
|
||||
* Yutaka Saiko
|
||||
|
||||
|
||||
WEBSITE, DOCS AND ARTWORK
|
||||
|
||||
* Nitin Reddy Katkam -- logo and site design
|
||||
* Paul Sommers -- Handbook API reference
|
||||
* Helen Ewart -- MikeOS cat mascot
|
||||
|
||||
|
||||
==================================================================
|
||||
|
37
doc/LICENSE.TXT
Executable file
37
doc/LICENSE.TXT
Executable file
@ -0,0 +1,37 @@
|
||||
==================================================================
|
||||
MikeOS -- License
|
||||
==================================================================
|
||||
|
||||
|
||||
Copyright (C) 2006 - 2022 MikeOS Developers -- http://mikeos.sourceforge.net
|
||||
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
* Neither the name MikeOS nor the names of any MikeOS contributors
|
||||
may be used to endorse or promote products derived from this software
|
||||
without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY MIKEOS DEVELOPERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL MIKEOS DEVELOPERS BE LIABLE FOR ANY
|
||||
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
|
||||
USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
|
||||
==================================================================
|
||||
|
1210
doc/handbook-appdev-asm.html
Executable file
1210
doc/handbook-appdev-asm.html
Executable file
File diff suppressed because it is too large
Load Diff
1537
doc/handbook-appdev-basic.html
Executable file
1537
doc/handbook-appdev-basic.html
Executable file
File diff suppressed because it is too large
Load Diff
7277
doc/handbook-forth.html
Executable file
7277
doc/handbook-forth.html
Executable file
File diff suppressed because it is too large
Load Diff
505
doc/handbook-sysdev.html
Executable file
505
doc/handbook-sysdev.html
Executable file
@ -0,0 +1,505 @@
|
||||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
||||
<html xmlns="http://www.w3.org/1999/xhtml">
|
||||
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
|
||||
|
||||
<title>The MikeOS System Developer Handbook</title>
|
||||
|
||||
<style type="text/css">
|
||||
|
||||
body {
|
||||
font-family: sans-serif;
|
||||
}
|
||||
|
||||
h1 {
|
||||
margin-top:5px;
|
||||
color: #A00000;
|
||||
}
|
||||
|
||||
h2 {
|
||||
color: #A00000;
|
||||
}
|
||||
|
||||
h3 {
|
||||
margin-top:5px;
|
||||
color: #A00000;
|
||||
}
|
||||
|
||||
hr {
|
||||
border: 0;
|
||||
color: #A00000;
|
||||
background-color: #A00000;
|
||||
height: 3px;
|
||||
}
|
||||
|
||||
pre {
|
||||
background-color: #F0F0F0;
|
||||
border: 5px solid #F0F0F0;
|
||||
}
|
||||
|
||||
a {
|
||||
text-decoration: none;
|
||||
color: #0000F0;
|
||||
}
|
||||
|
||||
a:visited {
|
||||
text-decoration: none;
|
||||
color: #0000F0;
|
||||
}
|
||||
|
||||
a:hover {
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
li {
|
||||
margin-left: -1ex;
|
||||
}
|
||||
|
||||
</style>
|
||||
|
||||
</head>
|
||||
|
||||
<body>
|
||||
|
||||
|
||||
|
||||
<table border="0" cellpadding="10">
|
||||
<tr>
|
||||
|
||||
|
||||
|
||||
<!-- NAVIGATION PANEL -->
|
||||
|
||||
<td style="border:1px solid black; width:160px;" valign="top">
|
||||
|
||||
<h3>Navigate</h3>
|
||||
|
||||
<p><strong>Overview</strong></p>
|
||||
<ul>
|
||||
<li><a href="#introduction">Introduction</a></li>
|
||||
<li><a href="#structure">Structure</a></li>
|
||||
<li><a href="#memorymap">Memory map</a></li>
|
||||
<li><a href="#codepath">Code path</a></li>
|
||||
</ul>
|
||||
|
||||
<p><strong>Building</strong></p>
|
||||
<ul>
|
||||
<li><a href="#buildlinux">Linux</a></li>
|
||||
<li><a href="#buildwindows">Windows</a></li>
|
||||
<li><a href="#buildothers">Others</a></li>
|
||||
</ul>
|
||||
|
||||
<p><strong>Modifying</strong></p>
|
||||
<ul>
|
||||
<li><a href="#modoverview">Overview</a></li>
|
||||
<li><a href="#systemcalls">System calls</a></li>
|
||||
<li><a href="#patches">Patches</a></li>
|
||||
</ul>
|
||||
|
||||
<p><strong>Extra</strong></p>
|
||||
<ul>
|
||||
<li><a href="#help">Help</a></li>
|
||||
<li><a href="#license">License</a></li>
|
||||
</ul>
|
||||
|
||||
</td>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<!-- MAIN CONTENT PANEL -->
|
||||
|
||||
<td valign="top">
|
||||
|
||||
<h1>The MikeOS System Developer Handbook</h1>
|
||||
|
||||
<h3>For version 4.7, 9 April 2022 - (C) MikeOS Developers</h3>
|
||||
|
||||
<p>This documentation file explains how to build MikeOS from the source code, make changes
|
||||
to the kernel, and add new system calls. If you have any questions, see
|
||||
<a href="http://mikeos.sourceforge.net">the MikeOS website</a> for contact details
|
||||
and mailing list information.</p>
|
||||
|
||||
<p>Click the links on the left to navigate around this guide.</p>
|
||||
|
||||
<br />
|
||||
|
||||
|
||||
<hr noshade="noshade" />
|
||||
|
||||
|
||||
<h2>Overview</h2>
|
||||
|
||||
<a name="introduction"></a>
|
||||
<h3>Introduction</h3>
|
||||
|
||||
<p>The MikeOS kernel is written in 16-bit x86 real mode assembly language. This provides easy access
|
||||
to BIOS routines for handling the keyboard, screen and floppy drive, so that we don't need complicated
|
||||
drivers. Therefore most of the code is focused on actual OS aspects: loading programs,
|
||||
system calls and so forth.</p>
|
||||
|
||||
<p>Additionally, MikeOS avoids the real mode segmentation complications by existing in a single 64KiB segment.
|
||||
The first 32KiB (0 - 32767) of RAM is reserved for the kernel; the second 32KiB is for external program code
|
||||
and memory.</p>
|
||||
|
||||
|
||||
<br />
|
||||
|
||||
|
||||
<a name="structure"></a>
|
||||
<h3>Structure</h3>
|
||||
|
||||
<p>These are the most important files and directories in the MikeOS zip file:</p>
|
||||
|
||||
<ul>
|
||||
<li><strong>source/</strong> -- Contains the entire OS source code</li>
|
||||
<li><strong>source/bootload/</strong> -- Source to generate BOOTLOAD.BIN, which is added to the disk image when building</li>
|
||||
<li><strong>source/features/</strong> -- Components of MikeOS such as FAT12 support, string routines, the BASIC interpreter etc</li>
|
||||
<li><strong>source/kernel.asm</strong> -- The core kernel source file, which pulls in other source files</li>
|
||||
<li><strong>programs/</strong> -- Source code for programs added to the disk image</li>
|
||||
</ul>
|
||||
|
||||
|
||||
<br />
|
||||
|
||||
|
||||
|
||||
<a name="memorymap"></a>
|
||||
<h3>Memory map</h3>
|
||||
|
||||
<p>This is the makeup of the 64KiB memory segment after MikeOS has loaded:</p>
|
||||
|
||||
<br />
|
||||
|
||||
<center>
|
||||
<table border="1" cellpadding="10">
|
||||
<tr><td><center><br />
|
||||
<strong>0 - 24575 (hex: 0h - 5FFFh)</strong><br />
|
||||
24KiB kernel executable code<br />
|
||||
<br />- - - - - - - - - - - - - - -<br /><br />
|
||||
<strong>24576 - 32767 (hex: 6000h - 7FFFh)</strong><br />
|
||||
8KiB kernel disk operation buffer<br /><br />
|
||||
</center></td></tr>
|
||||
<tr><td><center>
|
||||
<strong>32768 - 65535 (hex: 8000h - FFFFh</strong><br />
|
||||
32KiB space for external programs</center></td></tr>
|
||||
</table>
|
||||
</center>
|
||||
|
||||
<br />
|
||||
|
||||
<p>So, the first 32KiB is devoted to the MikeOS kernel code and its 8KiB buffer for performing disk operations.
|
||||
After that we have another 32KiB of memory, this time for external programs. These are loaded at the 32KiB point
|
||||
and hence need to be ORGed to 32768 as described in the App Developer Handbook.</p>
|
||||
|
||||
|
||||
<br />
|
||||
|
||||
|
||||
<a name="codepath"></a>
|
||||
<h3>Code path</h3>
|
||||
|
||||
<p>When the PC starts up, it loads the bootblock, <strong>BOOTLOAD.BIN</strong>, that was inserted into
|
||||
the first sector (512 bytes) of the floppy disk image by the build script. It loads this at memory location
|
||||
31744 (7C00h in hex) and begins executing it.</p>
|
||||
|
||||
<p><strong>BOOTLOAD.BIN</strong> then scans the floppy disk for <strong>KERNEL.BIN</strong> and loads it at
|
||||
memory location <strong>2000h:0000h</strong>. Here, the 2000h is the segment and 0000h is the offset
|
||||
in that segment -- you don't need to concern yourself with this, but effectively it means that the kernel is
|
||||
loaded at location 131072 (128KiB) in the PC's RAM. (You get a complete memory location by multiplying the segment
|
||||
by 16 and adding the offset.)</p>
|
||||
|
||||
<p>Once the bootloader has loaded the kernel, it jumps to memory location 131072 (aka 2000h:0000h)
|
||||
to begin executing it. After this, for simplicity we ignore segments and just use offsets (0000h to FFFFh),
|
||||
thereby giving us 64KiB of RAM to use.</p>
|
||||
|
||||
<p>At the start of the kernel we have a series of <strong>jmp</strong> instructions.
|
||||
Why are these here? Well, the system calls are in semi-random places in the kernel executable.
|
||||
As MikeOS evolves, the exact locations of these system calls shifts around; an external program can't guarantee
|
||||
where they are. So we have a list of vectors right at the very start of the kernel which <strong>jmp</strong> to these
|
||||
calls, so an external program can <strong>call</strong> these vectors and know that they'll never move!</p>
|
||||
|
||||
<p>There's a <strong>jmp</strong> just before these vectors to skip over them, and then the main kernel execution
|
||||
starts, setting up various things and offering the user a choice of a program list or command line interface.</p>
|
||||
|
||||
|
||||
<br />
|
||||
|
||||
|
||||
<hr noshade="noshade" />
|
||||
|
||||
|
||||
<h2>Building</h2>
|
||||
|
||||
<a name="buildlinux"></a>
|
||||
<h3>Linux</h3>
|
||||
|
||||
<p><strong>Build requirements:</strong> the NASM assembler, dosfstools package, 'mkisofs' utility and root access. We need root
|
||||
access because we loopback-mount the floppy disk image to insert our files.</p>
|
||||
|
||||
<p>To build MikeOS, open a terminal and switch into the expanded MikeOS package. Enter <strong>sudo bash</strong>
|
||||
in Ubuntu-flavoured distros, or just <strong>su</strong> in others, to switch to the root user. Then enter:</p>
|
||||
|
||||
<pre>
|
||||
./build-linux.sh
|
||||
</pre>
|
||||
|
||||
<p>This will use NASM to assemble the bootloader, kernel and supplied programs, then write the bootloader to the
|
||||
<strong>mikeos.flp</strong> floppy disk image in the <strong>disk_images/</strong> directory. (It writes the 512-byte
|
||||
bootloader to the first sector of the floppy disk image to create a boot sector and set up a DOS-like
|
||||
filesystem.) Next, the build script loopback-mounts the <strong>mikeos.flp</strong> image onto the filesystem - in other
|
||||
words, mounting the image as if it was a real floppy. The script copies over the kernel (<strong>kernel.bin</strong>)
|
||||
and binaries from the <strong>programs/</strong> directory, before unmounting the floppy image.</p>
|
||||
|
||||
<p>With that done, the script runs the 'mkisofs' utility to generate a CD-ROM ISO image of MikeOS, injecting
|
||||
the floppy image as a boot section. So we end up with two files in the <strong>disk_images/</strong> directory:
|
||||
one for floppy disks and one for CD-Rs. You can now use them in an emulator or on a real PC as described in
|
||||
the Running section above.</p>
|
||||
|
||||
|
||||
<br />
|
||||
|
||||
|
||||
<a name="buildwindows"></a>
|
||||
<h3>Windows</h3>
|
||||
|
||||
<p>Get the latest version of NASM for Windows from <a href="http://www.nasm.us/pub/nasm/releasebuilds/">this site</a>
|
||||
(look for the 'win32' package. Then extract the <strong>nasm.exe</strong> file into your Windows folder (or somewhere in the path).</p>
|
||||
|
||||
<p>The ImDisk Virtual Disk Driver is needed since Windows does not have a
|
||||
built-in mechanism for loopback drives. Get it from <a href="http://www.ltr-data.se/files/imdiskinst.exe">here</a>
|
||||
(or Google it if the link is outdated). After downloading run imdiskinst.exe to install. Follow the default prompts
|
||||
during the install. Also get <a href="http://www.osdever.net/downloads/other/pcopy02.zip">PartCopy</a> for copying
|
||||
the bootloader on to the disk image.</p>
|
||||
|
||||
<p>To build MikeOS, double-click on <strong>build-win.bat</strong> or run it from the command line.
|
||||
This batch file calls NASM to do the work needed to compile MikeOS and its applications.
|
||||
This script mounts the floppy disk image as if it were a real disk, using:</p>
|
||||
|
||||
<pre>
|
||||
imdisk -a -f mikeos.flp -s 1440K -m B:
|
||||
</pre>
|
||||
|
||||
<p>You can use that command outside of <strong>build-win.bat</strong> if you want to add files to <strong>mikeos.flp</strong>,
|
||||
and unmount it with:</p>
|
||||
|
||||
<pre>
|
||||
imdisk -d -m B:
|
||||
</pre>
|
||||
|
||||
<p>Lastly, to test in the <a href="http://www.omledom.com">QEMU PC emulator</a>,
|
||||
Extract QEMU to somewhere on your computer -- <strong>C:\</strong> is best. Then enter: the following to run MikeOS under QEMU:</p>
|
||||
|
||||
<pre>
|
||||
qemu.exe -L . -m 4 -boot a -fda mikeos.flp -soundhw all -localtime
|
||||
</pre>
|
||||
|
||||
<p>Make sure you put the proper path names in! Ask on the mailing list if you have any problems.</p>
|
||||
|
||||
|
||||
|
||||
<br />
|
||||
|
||||
<a name="buildothers"></a>
|
||||
<h3>Others</h3>
|
||||
|
||||
<p>Along with the scripts for building on Linux and Windows, you'll also find scripts for macOS and OpenBSD.
|
||||
These have not been as thoroughly tested as the others, so if you find any glitches, please let us know!</p>
|
||||
|
||||
<p>If you want to make a build script for a new platform, it needs to:</p>
|
||||
|
||||
<ol>
|
||||
<li>Assemble the bootloader and add it to the first sector of <strong>mikeos.flp</strong></li>
|
||||
<li>Assemble the kernel and copy it onto the floppy</li>
|
||||
<li>Assemble the add-on programs and copy them onto the floppy</li>
|
||||
</ol>
|
||||
|
||||
<p>So you will need some way of copying the 512 byte bootsector into a floppy image, and loopback mounting the
|
||||
image to copy across the kernel and programs.</p>
|
||||
|
||||
|
||||
<br />
|
||||
|
||||
|
||||
|
||||
<hr noshade="noshade" />
|
||||
|
||||
|
||||
<h2>Modifying</h2>
|
||||
|
||||
<a name="modoverview"></a>
|
||||
<h3>Overview</h3>
|
||||
|
||||
<p>To test out code, the simplest approach is to create a new app in the <strong>programs/</strong> directory, build
|
||||
MikeOS and run your program. You can then be guaranteed that your code isn't interfering with the kernel code (at least
|
||||
at the assembling stage!). When you're happy with it, you may want to introduce it into <strong>source/kernel.asm</strong>
|
||||
or a specific file in <strong>source/features/</strong>.</p>
|
||||
|
||||
<p>Note that the files in <strong>source/features/</strong> correspond to the system calls in <strong>programs/mikedev.inc</strong>
|
||||
(and detailed in the App Developer Handbook), but those source files also include internal calls that are used by the kernel and
|
||||
are not accessible to user programs. So use 'grep' or the search tool of your choice to find specific calls if they're not
|
||||
available through the API.</p>
|
||||
|
||||
<br />
|
||||
|
||||
|
||||
<a name="systemcalls"></a>
|
||||
<h3>System calls</h3>
|
||||
|
||||
<p>Adding new system calls is easy and fun - it extends MikeOS! So if you want to help out, this is the best way to start.
|
||||
Open up <strong>source/features/screen.asm</strong> in a text editor and paste in the following after the header text:</p>
|
||||
|
||||
|
||||
<pre>
|
||||
; -----------------------------------------------------------------
|
||||
; os_say_hello -- Prints 'Hello' to the screen
|
||||
; IN/OUT: Nothing
|
||||
|
||||
os_say_hello:
|
||||
pusha
|
||||
|
||||
mov si, .message
|
||||
call os_print_string
|
||||
|
||||
popa
|
||||
ret
|
||||
|
||||
.message db 'Hello', 0
|
||||
</pre>
|
||||
|
||||
<p>There we have it: a new system call that prints 'Hello' to the screen. Hardly a much-needed feature, but it's
|
||||
a starting point. The first three lines are comments explaining what the call does, and what registers it accepts
|
||||
or returns (like variable passing in high-level languages). Then we have the <strong>os_say_hello:</strong> label
|
||||
which indicates where the code starts, before a <strong>pusha</strong>.</p>
|
||||
|
||||
<p>All system calls should start with <strong>pusha</strong> and end with <strong>popa</strong> before <strong>ret</strong>:
|
||||
this stores registers on the stack at the start, and then pops them off at the end, so that we don't end up changing
|
||||
a bunch of registers and confusing the calling program. (If you're passing back a value, say in AX, you should
|
||||
store AX in a temporary word and drop it back in between the <strong>popa</strong> and <strong>ret</strong>, as
|
||||
seen in <strong>os_wait_for_key</strong> in <strong>keyboard.asm</strong>.)</p>
|
||||
|
||||
<p>The body of our code simply places the location of our message string into the SI register, then calls another
|
||||
MikeOS routine, <strong>os_print_string</strong>. You can freely call other routines from your own system call.</p>
|
||||
|
||||
<p>Once we've done this, we can access this routine throughout the kernel. But what about external programs? They
|
||||
have no idea where this call is in the kernel! The trick we use is <strong>vectors</strong> - a bunch of <strong>jmp</strong>
|
||||
instructions at the start of our kernel code, which jump to these routines. Because these vectors are at the start,
|
||||
they never change their position, so we always know where they are.</p>
|
||||
|
||||
<p>For instance, right now, your new system call may be at 0x9B9D in the kernel. But if you add another call before it,
|
||||
or someone else does, it may move to 0x9FA6 in the kernel binary. We simply don't know where it's going to be. But
|
||||
if we put at vector at the start of our kernel, before anything else happens, we can use that as the starting point
|
||||
as the vector will never move!</p>
|
||||
|
||||
<p>Open up <strong>source/kernel.asm</strong> and scroll down to the list of system call vectors. You can see they start
|
||||
from 0003h. Scroll to the bottom of the list and you'll see something like this:</p>
|
||||
|
||||
<pre>
|
||||
jmp os_string_tokenize ; 00CFh
|
||||
</pre>
|
||||
|
||||
<p>The comment here indicates where this bit of code lies in the kernel binary. Once again, it's static, and
|
||||
basically says: if your program wants to call <strong>os_string_tokenize</strong>, it should call 00CFh, as
|
||||
this jumps to the required routine and will never change position.</p>
|
||||
|
||||
<p>Let's add a vector to our new call. Add this beneath the existing vectors:</p>
|
||||
|
||||
<pre>
|
||||
jmp os_say_hello ; 00D2h
|
||||
</pre>
|
||||
|
||||
<p>How do we know this <strong>jmp</strong> is at 00D2h in the kernel binary? Well, just follow the pattern in the
|
||||
<strong>jmp</strong>s above - it's pretty easy to guess. If you're unsure, you can always use
|
||||
<strong>ndisasm</strong> to disassemble the kernel and look for the location of the final
|
||||
<strong>jmp</strong> in the list.</p>
|
||||
|
||||
<p>That's all good and well, but there's one last thing: people writing external programs don't want to
|
||||
call an ugly number like 00C9h when they run our routine. They want to access it by name, so we need
|
||||
to add a line to <strong>mikedev.inc</strong> in the <strong>programs/</strong> directory:</p>
|
||||
|
||||
<pre>
|
||||
os_say_hello equ 00D2h ; Prints 'Hello' to screen
|
||||
</pre>
|
||||
|
||||
<p>Now, any program that includes <strong>mikedev.inc</strong> will be able to call our routine by name.
|
||||
Et voila: a brand new system call for MikeOS!</p>
|
||||
|
||||
|
||||
<br />
|
||||
|
||||
|
||||
<a name="patches"></a>
|
||||
<h3>Patches</h3>
|
||||
|
||||
<p>If you've made some improvements or additions to MikeOS and wish to submit them, great! If they're small changes -
|
||||
such as a bugfix or minor tweak - you can paste the altered code into an email. Explain what it does and where it
|
||||
goes in the source code, and if it's OK, we'll include it.</p>
|
||||
|
||||
<p>If your change is larger (e.g. a system call) and affects various parts of the code, you're better off with a
|
||||
patch. On UNIX-like systems such as Linux, you can use the <strong>diff</strong> command-line utility to generate
|
||||
a list of your changes. For this, you will need the original (release) source code tree of MikeOS, along with the
|
||||
tree of your modified code. For instance, you may have the original code in a directory called
|
||||
<strong>mikeos-4.2/</strong> and your enhanced version in <strong>new-mikeos-4.0/</strong>.</p>
|
||||
|
||||
<p>Switch to the directory beneath these, and enter:</p>
|
||||
|
||||
<pre>
|
||||
diff -ru mikeos-4.2 new-mikeos-4.2 > patch.txt
|
||||
</pre>
|
||||
|
||||
<p>This collates the differences between the two directories, and directs the output to the file <strong>patch.txt</strong>.
|
||||
Have a look at the file to make sure it's OK (you can see how it shows which lines have changed), and then attach the
|
||||
file to an email.</p>
|
||||
|
||||
<p>Please post fixes and patches to the MikeOS mailing list (see <a href="http://mikeos.sourceforge.net">the website</a>).</p>
|
||||
|
||||
|
||||
|
||||
<br />
|
||||
|
||||
|
||||
<hr noshade="noshade" />
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<h2>Extra</h2>
|
||||
|
||||
<a name="help"></a>
|
||||
<h3>Help</h3>
|
||||
|
||||
|
||||
<p>If you have any questions about MikeOS, or you're developing a similar OS and want
|
||||
to share code and ideas, go to <a href="http://mikeos.sourceforge.net/">the MikeOS website</a>
|
||||
and join the mailing list as described.</p>
|
||||
|
||||
|
||||
<br />
|
||||
|
||||
|
||||
<a name="license"></a>
|
||||
<h3>License</h3>
|
||||
|
||||
<p>MikeOS is open source and released under a BSD-like license (see <strong>doc/LICENSE.TXT</strong>
|
||||
in the MikeOS <strong>.zip</strong> file). Essentially, it means you can do anything you like with the
|
||||
code, including basing your own project on it, providing you retain the license file and give credit
|
||||
to the MikeOS developers for their work.</p>
|
||||
|
||||
|
||||
<br />
|
||||
|
||||
|
||||
<hr noshade="noshade" />
|
||||
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
|
469
doc/handbook-user.html
Executable file
469
doc/handbook-user.html
Executable file
@ -0,0 +1,469 @@
|
||||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
||||
<html xmlns="http://www.w3.org/1999/xhtml">
|
||||
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
|
||||
|
||||
<title>The MikeOS User Handbook</title>
|
||||
|
||||
<style type="text/css">
|
||||
|
||||
body {
|
||||
font-family: sans-serif;
|
||||
}
|
||||
|
||||
h1 {
|
||||
margin-top:5px;
|
||||
color: #69A000;
|
||||
}
|
||||
|
||||
h2 {
|
||||
color: #69A000;
|
||||
}
|
||||
|
||||
h3 {
|
||||
margin-top:5px;
|
||||
color: #69A000;
|
||||
}
|
||||
|
||||
hr {
|
||||
border: 0;
|
||||
color: #69A000;
|
||||
background-color: #69A000;
|
||||
height: 3px;
|
||||
}
|
||||
|
||||
pre {
|
||||
background-color: #F0F0F0;
|
||||
border: 5px solid #F0F0F0;
|
||||
}
|
||||
|
||||
a {
|
||||
text-decoration: none;
|
||||
color: #0000F0;
|
||||
}
|
||||
|
||||
a:visited {
|
||||
text-decoration: none;
|
||||
color: #0000F0;
|
||||
}
|
||||
|
||||
a:hover {
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
li {
|
||||
margin-left: -1ex;
|
||||
}
|
||||
|
||||
</style>
|
||||
|
||||
</head>
|
||||
|
||||
<body>
|
||||
|
||||
|
||||
|
||||
<table border="0" cellpadding="10">
|
||||
<tr>
|
||||
|
||||
|
||||
|
||||
<!-- NAVIGATION PANEL -->
|
||||
|
||||
<td style="border:1px solid black; width:160px;" valign="top">
|
||||
|
||||
<h3>Navigate</h3>
|
||||
|
||||
<p><strong>Booting</strong></p>
|
||||
<ul>
|
||||
<li><a href="#diskimages">Disk images</a></li>
|
||||
<li><a href="#writing">Writing</a></li>
|
||||
<li><a href="#realpcs">Real PCs</a></li>
|
||||
<li><a href="#emulators">Emulators</a></li>
|
||||
</ul>
|
||||
|
||||
<p><strong>Running</strong></p>
|
||||
<ul>
|
||||
<li><a href="#usage">Usage</a></li>
|
||||
<li><a href="#programs">Programs</a></li>
|
||||
<li><a href="#copyingfiles">Copying files</a></li>
|
||||
<li><a href="#monitor">Monitor</a></li>
|
||||
<li><a href="#serialport">Serial port</a></li>
|
||||
</ul>
|
||||
|
||||
<p><strong>Extra</strong></p>
|
||||
<ul>
|
||||
<li><a href="#help">Help</a></li>
|
||||
<li><a href="#license">License</a></li>
|
||||
</ul>
|
||||
|
||||
</td>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<!-- MAIN CONTENT PANEL -->
|
||||
|
||||
<td valign="top">
|
||||
|
||||
<h1>The MikeOS User Handbook</h1>
|
||||
|
||||
<h3>For version 4.7, 9 April 2022 - (C) MikeOS Developers</h3>
|
||||
|
||||
<p>This documentation file explains how to boot and use the MikeOS operating system on a real PC or an
|
||||
emulator. If you have just downloaded MikeOS and want to run it, this is the guide you need. If you have
|
||||
any questions, see <a href="http://mikeos.sourceforge.net">the MikeOS website</a> for contact details
|
||||
and mailing list information.</p>
|
||||
|
||||
<p>Click the links on the left to navigate around this guide.</p>
|
||||
|
||||
<br />
|
||||
|
||||
|
||||
<hr noshade="noshade" />
|
||||
|
||||
|
||||
<h2>Booting</h2>
|
||||
|
||||
<a name="diskimages"></a>
|
||||
<h3>Disk images</h3>
|
||||
|
||||
<p>After you have extracted the MikeOS <strong>.zip</strong> file, switch into the
|
||||
<strong>disk_images/</strong> directory and you'll see three files:</p>
|
||||
|
||||
<ul>
|
||||
<li><strong>mikeos.flp</strong> -- Floppy disk image containing MikeOS and programs</li>
|
||||
<li><strong>mikeos.dmg</strong> -- Same as above, but with a Mac-friendly extension</li>
|
||||
<li><strong>mikeos.iso</strong> -- CD ISO image built using the floppy disk image</li>
|
||||
</ul>
|
||||
|
||||
<p>So, these files are virtual disk images that you can write to real floppy disks or
|
||||
CD-Rs, or run in a PC emulator as described in a moment.</p>
|
||||
|
||||
|
||||
<br />
|
||||
|
||||
|
||||
<a name="writing"></a>
|
||||
<h3>Writing</h3>
|
||||
|
||||
<p>For running MikeOS on a real PC, you will need to write one of the virtual disk images
|
||||
to physical media. If you have a USB key then this is simple -- we can write the floppy disk
|
||||
image to the USB key, and the PC will boot it like a virtual floppy.</p>
|
||||
|
||||
<p>On Linux, insert your USB key and unmount it when it appears (but don't remove it). Then open a command line
|
||||
window and enter <strong>dmesg</strong> to view the kernel messages. You will see an indication at the end of the messages of the device you just plugged
|
||||
in -- eg <strong>/dev/sdb</strong>. Note that you just need the device, eg /dev/sdb, rather than the number (eg /dev/sdb1). Then enter (in the disk_images directory):</p>
|
||||
|
||||
<pre>dd if=mikeos.flp of=/dev/sdb</pre>
|
||||
|
||||
<p>Of course, replace sdb with the device node. The key is now ready for booting.</p>
|
||||
|
||||
<p>On Windows, download the open source <a href="http://translate.google.com/translate?u=http%3A%2F%2Fshounen.ru%2Fsoft%2Fflashnul%2F&hl=en&ie=UTF8&sl=ru&tl=en">Flashnul</a> program, plug in your USB key and
|
||||
enter <strong>flashnul -p</strong> to get a list of drives. When you've spotted your USB key, enter
|
||||
<strong>flashnul [number] -L mikeos.flp</strong> (in the disk_images directory), replacing [number]
|
||||
with the number you got before. The key is now ready for booting.</p>
|
||||
|
||||
<p>Note: if you plug your USB key back into the machine, the operating system may try to alter the
|
||||
partition structure and stop it from working properly. So treat it as a MikeOS-only key until you
|
||||
want to reformat it for normal use.</p>
|
||||
|
||||
<p>For floppy disks, on Windows you can use a program called <a href="http://www.chrysocome.net/rawwrite">RawWrite</a>
|
||||
to copy <strong>mikeos.flp</strong> to a floppy disk. On Linux, use the <strong>dd</strong>
|
||||
utility like this:</p>
|
||||
|
||||
<pre>dd if=mikeos.flp of=/dev/fd0</pre>
|
||||
|
||||
<p>If you want to run MikeOS on a machine that doesn't have a floppy drive and doesn't
|
||||
boot from USB keys, you can burn and boot the <strong>mikeos.iso</strong> CD image. Any decent Windows CD burning software will
|
||||
allow you to write an ISO image to a CD-R; if you don't have one, try <a href="http://infrarecorder.org">InfraRecorder.</a></p>
|
||||
|
||||
<p>On Linux, a graphical burning program such as K3b should do the trick, or you can use
|
||||
the command line:</p>
|
||||
|
||||
<pre>cdrecord -dao dev=/dev/cdrom mikeos.iso</pre>
|
||||
|
||||
|
||||
<br />
|
||||
|
||||
|
||||
<a name="realpcs"></a>
|
||||
<h3>Real PCs</h3>
|
||||
|
||||
<p>At a minimum, any 386 PC with 1MB of memory and a keyboard should be able to run MikeOS. In
|
||||
fact, you may be able to get it running on an older machine -- please do let us know if so! Just
|
||||
start your PC with the MikeOS floppy, CD-ROM or USB key inserted, and you should see the initial
|
||||
dialog screen.</p>
|
||||
|
||||
<p>On some systems, you may need to change the boot order in your BIOS so that the PC boots
|
||||
from the floppy, CD or USB key rather than the hard drive.</p>
|
||||
|
||||
|
||||
<br />
|
||||
|
||||
|
||||
<a name="emulators"></a>
|
||||
<h3>Emulators</h3>
|
||||
|
||||
<p>A quick way to try MikeOS, and one that doesn't involve writing disk images to physical media,
|
||||
is to use an emulator. This is particularly useful if you're writing MikeOS software or changing
|
||||
the OS as described in the other two Handbooks.</p>
|
||||
|
||||
<p>Some of the best emulators:</p>
|
||||
|
||||
<ul>
|
||||
<li><strong>QEMU</strong> -- Small, simple and open source (<a href="http://www.qemu.org">link</a>)</li>
|
||||
<li><strong>VirtualBox</strong> -- Very powerful with a good GUI (<a href="http://www.virtualbox.org">link</a>)</li>
|
||||
<li><strong>VMware</strong> -- Popular proprietary virtualisation app (<a href="http://www.vmware.com">link</a>)</li>
|
||||
<li><strong>Bochs</strong> -- Takes a bit of work to set up, but good debugging tools (<a href="http://bochs.sourceforge.net">link</a>)</li>
|
||||
</ul>
|
||||
|
||||
<p>For VirtualBox and VMware, configure the boot device to use the MikeOS floppy disk or CD ISO image.
|
||||
With QEMU on Linux, run <strong>test-linux.sh</strong>, or for QEMU on Windows switch into the directory
|
||||
where you installed the emulator and enter:</p>
|
||||
|
||||
<pre>
|
||||
qemu.exe -L . -m 4 -boot a -fda mikeos.flp -soundhw all -localtime
|
||||
</pre>
|
||||
|
||||
<p>You will need to change the path to <strong>mikeos.flp</strong> accordingly.</p>
|
||||
|
||||
|
||||
<br />
|
||||
|
||||
|
||||
<hr noshade="noshade" />
|
||||
|
||||
|
||||
<h2>Running</h2>
|
||||
|
||||
<a name="usage"></a>
|
||||
<h3>Usage</h3>
|
||||
|
||||
<p>When MikeOS starts up, you'll see a dialog box which gives you the option of a program
|
||||
list of a command line interface. Using the cursor keys and Enter, choose OK for the former
|
||||
and Cancel for the latter.</p>
|
||||
|
||||
<p>In the program list you can select a <strong>.BIN</strong> or <strong>.BAS</strong> program with the up/down cursor
|
||||
keys and hit Enter to run it. Also, you can press Esc to return back to the original list/CLI
|
||||
selection screen.</p>
|
||||
|
||||
<p>At the command line, enter <strong>DIR</strong> to show a list of programs, and <strong>HELP</strong>
|
||||
to display inbuilt commands. You can run a program by entering the full filename (eg <strong>EDIT.BIN</strong>)
|
||||
or just the name without the extension (eg <strong>EDIT</strong>). There are also file management commands such
|
||||
as COPY, REN, DEL and SIZE.</p>
|
||||
|
||||
|
||||
<br />
|
||||
|
||||
|
||||
<a name="programs"></a>
|
||||
<h3>Programs</h3>
|
||||
|
||||
<p>MikeOS includes several programs to perform various tasks and demonstrate features of the OS, such as:</p>
|
||||
|
||||
<ul>
|
||||
<li><strong>EDIT.BIN</strong> -- Simple full-screen text editor (Unix-type text files only)</li>
|
||||
<li><strong>VEDIT.BIN</strong> -- An alternative Vi-like editor</li>
|
||||
<li><strong>EXAMPLE.BAS</strong> -- Demonstration of BASIC features (open it in EDIT.BIN to explore)</li>
|
||||
<li><strong>FILEMAN.BIN</strong> -- Delete, rename and copy files on the floppy disk</li>
|
||||
<li><strong>HANGMAN.BIN</strong> -- Guess the names of cities around the world</li>
|
||||
<li><strong>MEMEDIT.BAS</strong> -- Colourful, powerful memory editor</li>
|
||||
<li><strong>DRAW.BAS</strong> -- ASCII art drawing program</li>
|
||||
<li><strong>CALC.BAS</strong> -- Powerful calculator</li>
|
||||
<li><strong>SUDOKU.BAS</strong> -- Sudoku game</li>
|
||||
<li><strong>LIFE.BIN</strong> -- An implementation of Conway's Game of Life</li>
|
||||
<li><strong>CF.BAS</strong> -- Cosmic Flight game</li>
|
||||
<li><strong>FORTH.BIN</strong> -- Forth interpreter</li>
|
||||
<li><strong>PONG.BIN</strong> -- Pong game (press Esc to exit)</li>
|
||||
<li><strong>LINES.BIN</strong> -- VGA video mode demo (press F to speed up, S to slow down, C to clear and Esc to exit)</li>
|
||||
<li><strong>MUNCHER.BAS</strong> -- Snake-like game (use WASD keys)</li>
|
||||
<li><strong>ADVNTURE.BAS</strong> -- A text adventure</li>
|
||||
<li><strong>KEYBOARD.BIN</strong> -- Musical keyboard; use the bottom row of keys to play and Q to quit</li>
|
||||
<li><strong>MONITOR.BIN</strong> -- Simple machine code monitor (see below)</li>
|
||||
<li><strong>TERMINAL.BIN</strong> -- Minicom-like serial terminal program (see below)</li>
|
||||
<li><strong>VIEWER.BIN</strong> -- Views text files and 320x200x16 PCX images such as <strong>SAMPLE.PCX</strong></li>
|
||||
<li><strong>CODEBYTE.BIN</strong> -- Machine code editor; load <strong>HELLO.512</strong> for an example</li>
|
||||
</ul>
|
||||
|
||||
<p>Note that <strong>FILEMAN.BIN</strong> and <strong>EDIT.BIN</strong> try to write to the floppy drive,
|
||||
so if you've booted from a CD-R and try to manipulate files you will see write errors as it's a read-only
|
||||
medium after burning.</p>
|
||||
|
||||
|
||||
<br />
|
||||
|
||||
|
||||
<a name="copyingfiles"></a>
|
||||
<h3>Copying files</h3>
|
||||
|
||||
<p>If you've written MikeOS to a real floppy disk, you can just copy extra files
|
||||
onto that disk in your file manager. But if you want to add files to the floppy disk images,
|
||||
that requires a bit of extra work -- you need to access the disk image as if it was a real
|
||||
floppy. First up is Linux: switch to the MikeOS main directory, then enter the following
|
||||
commands as root:</p>
|
||||
|
||||
<pre>
|
||||
mkdir looptmp
|
||||
mount -o loop -t vfat disk_images/mikeos.flp looptmp
|
||||
</pre>
|
||||
|
||||
<p>Now the contents of the MikeOS virtual floppy disk image are accessible in the newly-created <strong>looptmp/</strong>
|
||||
directory. (We have loopback-mounted the disk image onto our filesystem.) Copy your programs into that directory, for example:</p>
|
||||
|
||||
<pre>
|
||||
cp MYPROG.BIN looptmp/
|
||||
</pre>
|
||||
|
||||
<p>When you're done, unmount the virtual floppy image and remove the temporary directory:</p>
|
||||
|
||||
<pre>
|
||||
umount looptmp
|
||||
rm -rf looptmp
|
||||
</pre>
|
||||
|
||||
<p>You can now write <strong>mikeos.flp</strong> to a floppy disk or boot it in an emulator. If you want
|
||||
to recreate the CD ISO image, run <strong>build-linux.sh</strong> as root; this will update <strong>mikeos.iso</strong>
|
||||
with the new floppy contents.</p>
|
||||
|
||||
<p>If you're running Windows, you will need a special program to access <strong>mikeos.flp</strong> as if it
|
||||
was a real floppy. One tool you can use is the <a href="http://www.ltr-data.se/files/imdiskinst.exe">ImDisk
|
||||
Virtual Disk Driver</a>; download and run it to install. You can then mount the floppy disk image like this:</p>
|
||||
|
||||
<pre>
|
||||
imdisk -a -f mikeos.flp -s 1440K -m B:
|
||||
</pre>
|
||||
|
||||
Copy your files into the <strong>B:</strong> drive. When you are finished, enter:
|
||||
|
||||
<pre>
|
||||
imdisk -d -m B:
|
||||
</pre>
|
||||
|
||||
<p>Now the files that you copied to <strong>B:</strong> have been written into <strong>mikeos.flp</strong>.</p>
|
||||
|
||||
|
||||
<br />
|
||||
|
||||
|
||||
<a name="monitor"></a>
|
||||
<h3>Monitor</h3>
|
||||
|
||||
<p>Yutaka Saito has contributed a MikeOS program that lets you enter machine code in hexadecimal format
|
||||
and execute it. Run <strong>MONITOR.BIN</strong> from the command line and you'll be presented
|
||||
with a '=' prompt. Now you can enter your instructions, or just 'x' to exit back to the OS.</p>
|
||||
|
||||
<p>MikeOS programs are loaded at the 32KiB (32768) point. The monitor converts hex code and executes
|
||||
it at location 36864 in RAM -- that is, 4KiB after the where the monitor program is loaded. This is
|
||||
so that your code doesn't overwrite the monitor! Consequently, any code you run should
|
||||
be ORGed to 36864. For example, this is a small MikeOS program which displays the letter 'M' on
|
||||
the screen. After we've assembled it, we can run <strong>ndisasm</strong> on the resulting binary
|
||||
to see the hexadecimal codes:</p>
|
||||
|
||||
<br />
|
||||
|
||||
<center>
|
||||
<table width="50%" cellpadding="3" border="1">
|
||||
<tr><td><strong>Source code</strong></td><td><strong>Hexadecimal</strong></td></tr>
|
||||
<tr><td>BITS 16</td><td> </td></tr>
|
||||
<tr><td>%INCLUDE "mikedev.inc"</td><td> </td></tr>
|
||||
<tr><td>ORG 36864</td><td> </td></tr>
|
||||
<tr><td> </td><td> </td></tr>
|
||||
<tr><td>mov si, message</td><td>BE0790</td></tr>
|
||||
<tr><td>call os_print_string</td><td>E8FD6F</td></tr>
|
||||
<tr><td>ret</td><td>C3</td></tr>
|
||||
<tr><td> </td><td> </td></tr>
|
||||
<tr><td>message db 'M', 0</td><td>4D00</td></tr>
|
||||
</table>
|
||||
</center>
|
||||
|
||||
<br />
|
||||
|
||||
<p>(The first three lines are merely assembly directives, so they don't generate any code.) Now
|
||||
that we have the hex codes, we can enter them into the monitor. Note that the code must be terminated
|
||||
with a dollar sign ($) character, and spaces are allowed. So, you can enter at the '=' prompt:</p>
|
||||
|
||||
<pre>BE0790 E8FD6F C3 4D00$</pre>
|
||||
|
||||
<p>When you enter this, the monitor will convert the hex codes to machine code at location 36864 in
|
||||
RAM, and call that location to execute it. (Just like normal MikeOS programs, you should finish with
|
||||
a <strong>ret</strong> instruction.) After execution, you'll be returned to the monitor. You can then
|
||||
enter 'r' to re-run the converted code, or 'x' to exit.</p>
|
||||
|
||||
|
||||
<br />
|
||||
|
||||
|
||||
<a name="serialport"></a>
|
||||
<h3>Serial port</h3>
|
||||
|
||||
<p>You can use MikeOS as a Minicom-like serial terminal emulator with <strong>TERMINAL.BIN</strong>. This lets
|
||||
you connect a MikeOS machine to, for instance, a UNIX machine, and operate the UNIX machine from
|
||||
MikeOS. Connect a serial (null-modem) cable between the two machines, then set up your UNIX machine
|
||||
with a terminal session on the serial port.</p>
|
||||
|
||||
<p>For instance, if you have a Linux machine, you would add a line like this to /etc/inittab:</p>
|
||||
|
||||
<pre>
|
||||
T0:2345:respawn:/sbin/getty/ -L ttyS0 9600 vt100
|
||||
</pre>
|
||||
|
||||
<p>When you restart your Linux machine, it will wait for a login on the serial port. Connect
|
||||
the null-modem cable to a MikeOS machine, and run TERMINAL.BIN in MikeOS. You can now enter your
|
||||
username and password to log in.</p>
|
||||
|
||||
<p>Note that MikeOS configures the serial port to be 9600 baud, no parity, 8 data bits, 1 stop
|
||||
bit. If you wish to change these settings, edit <strong>source/features/serial.asm</strong> and see the port
|
||||
port setup code at the start of the file (then rebuild MikeOS as described in the <em>System Developer Handbook</em>).
|
||||
Also note that only a handful of VT100 commands have been implemented at present, so programs which do complicated
|
||||
things with the screen (such as Emacs) may not display properly.</p>
|
||||
|
||||
<p>To exit the program, press the F8 key. (You can change this to a different key by editing
|
||||
the source code near the start of <strong>programs/terminal.asm</strong>.)</p>
|
||||
|
||||
|
||||
<br />
|
||||
|
||||
|
||||
<hr noshade="noshade" />
|
||||
|
||||
|
||||
<h2>Extra</h2>
|
||||
|
||||
<a name="help"></a>
|
||||
<h3>Help</h3>
|
||||
|
||||
|
||||
<p>If you have any questions about MikeOS, or you're developing a similar OS and want
|
||||
to share code and ideas, go to <a href="http://mikeos.sourceforge.net/">the MikeOS website</a>
|
||||
and join the mailing list as described.</p>
|
||||
|
||||
|
||||
<br />
|
||||
|
||||
|
||||
<a name="license"></a>
|
||||
<h3>License</h3>
|
||||
|
||||
<p>MikeOS is open source and released under a BSD-like license (see <strong>doc/LICENSE.TXT</strong>
|
||||
in the MikeOS <strong>.zip</strong> file). Essentially, it means you can do anything you like with the
|
||||
code, including basing your own project on it, providing you retain the license file and give credit
|
||||
to the MikeOS developers for their work.</p>
|
||||
|
||||
|
||||
<br />
|
||||
|
||||
|
||||
<hr noshade="noshade" />
|
||||
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
|
||||
</body>
|
||||
</html>
|
||||
|
BIN
source/bootload/.bootload.asm.swp
Executable file
BIN
source/bootload/.bootload.asm.swp
Executable file
Binary file not shown.
BIN
source/bootload/.hexdump.swp
Executable file
BIN
source/bootload/.hexdump.swp
Executable file
Binary file not shown.
BIN
source/bootload/.swp
Executable file
BIN
source/bootload/.swp
Executable file
Binary file not shown.
357
source/bootload/bootload.asm
Executable file
357
source/bootload/bootload.asm
Executable file
@ -0,0 +1,357 @@
|
||||
; ==================================================================
|
||||
; The Mike Operating System bootloader
|
||||
; Copyright (C) 2006 - 2022 MikeOS Developers -- see doc/LICENSE.TXT
|
||||
;
|
||||
; Based on a free boot loader by E Dehling. It scans the FAT12
|
||||
; floppy for KERNEL.BIN (the MikeOS kernel), loads it and executes it.
|
||||
; This must grow no larger than 512 bytes (one sector), with the final
|
||||
; two bytes being the boot signature (AA55h). Note that in FAT12,
|
||||
; a cluster is the same as a sector: 512 bytes.
|
||||
; ==================================================================
|
||||
|
||||
|
||||
BITS 16
|
||||
|
||||
jmp short bootloader_start ; Jump past disk description section
|
||||
nop ; Pad out before disk description
|
||||
|
||||
|
||||
; ------------------------------------------------------------------
|
||||
; Disk description table, to make it a valid floppy
|
||||
; Note: some of these values are hard-coded in the source!
|
||||
; Values are those used by IBM for 1.44 MB, 3.5" diskette
|
||||
|
||||
OEMLabel db "MIKEBOOT" ; Disk label
|
||||
BytesPerSector dw 512 ; Bytes per sector
|
||||
SectorsPerCluster db 1 ; Sectors per cluster
|
||||
ReservedForBoot dw 1 ; Reserved sectors for boot record
|
||||
NumberOfFats db 2 ; Number of copies of the FAT
|
||||
RootDirEntries dw 224 ; Number of entries in root dir
|
||||
; (224 * 32 = 7168 = 14 sectors to read)
|
||||
LogicalSectors dw 2880 ; Number of logical sectors
|
||||
MediumByte db 0F0h ; Medium descriptor byte
|
||||
SectorsPerFat dw 9 ; Sectors per FAT
|
||||
SectorsPerTrack dw 18 ; Sectors per track (36/cylinder)
|
||||
Sides dw 2 ; Number of sides/heads
|
||||
HiddenSectors dd 0 ; Number of hidden sectors
|
||||
LargeSectors dd 0 ; Number of LBA sectors
|
||||
DriveNo dw 0 ; Drive No: 0
|
||||
Signature db 41 ; Drive signature: 41 for floppy
|
||||
VolumeID dd 00000000h ; Volume ID: any number
|
||||
VolumeLabel db "MIKEOS "; Volume Label: any 11 chars
|
||||
FileSystem db "FAT12 " ; File system type: don't change!
|
||||
|
||||
|
||||
; ------------------------------------------------------------------
|
||||
; Main bootloader code
|
||||
|
||||
bootloader_start:
|
||||
mov ax, 07C0h ; Set up 4K of stack space above buffer
|
||||
add ax, 544 ; 8k buffer = 512 paragraphs + 32 paragraphs (loader)
|
||||
cli ; Disable interrupts while changing stack
|
||||
mov ss, ax
|
||||
mov sp, 4096
|
||||
sti ; Restore interrupts
|
||||
|
||||
mov ax, 07C0h ; Set data segment to where we're loaded
|
||||
mov ds, ax
|
||||
|
||||
; NOTE: A few early BIOSes are reported to improperly set DL
|
||||
|
||||
cmp dl, 0
|
||||
je no_change
|
||||
mov [bootdev], dl ; Save boot device number
|
||||
mov ah, 8 ; Get drive parameters
|
||||
int 13h
|
||||
jc fatal_disk_error
|
||||
and cx, 3Fh ; Maximum sector number
|
||||
mov [SectorsPerTrack], cx ; Sector numbers start at 1
|
||||
movzx dx, dh ; Maximum head number
|
||||
add dx, 1 ; Head numbers start at 0 - add 1 for total
|
||||
mov [Sides], dx
|
||||
|
||||
no_change:
|
||||
mov eax, 0 ; Needed for some older BIOSes
|
||||
|
||||
|
||||
; First, we need to load the root directory from the disk. Technical details:
|
||||
; Start of root = ReservedForBoot + NumberOfFats * SectorsPerFat = logical 19
|
||||
; Number of root = RootDirEntries * 32 bytes/entry / 512 bytes/sector = 14
|
||||
; Start of user data = (start of root) + (number of root) = logical 33
|
||||
|
||||
floppy_ok: ; Ready to read first block of data
|
||||
mov ax, 19 ; Root dir starts at logical sector 19
|
||||
call l2hts
|
||||
|
||||
mov si, buffer ; Set ES:BX to point to our buffer (see end of code)
|
||||
mov bx, ds
|
||||
mov es, bx
|
||||
mov bx, si
|
||||
|
||||
mov ah, 2 ; Params for int 13h: read floppy sectors
|
||||
mov al, 14 ; And read 14 of them
|
||||
|
||||
pusha ; Prepare to enter loop
|
||||
|
||||
|
||||
read_root_dir:
|
||||
popa ; In case registers are altered by int 13h
|
||||
pusha
|
||||
|
||||
stc ; A few BIOSes do not set properly on error
|
||||
int 13h ; Read sectors using BIOS
|
||||
|
||||
jnc search_dir ; If read went OK, skip ahead
|
||||
call reset_floppy ; Otherwise, reset floppy controller and try again
|
||||
jnc read_root_dir ; Floppy reset OK?
|
||||
|
||||
jmp reboot ; If not, fatal double error
|
||||
|
||||
|
||||
search_dir:
|
||||
popa
|
||||
|
||||
mov ax, ds ; Root dir is now in [buffer]
|
||||
mov es, ax ; Set DI to this info
|
||||
mov di, buffer
|
||||
|
||||
mov cx, word [RootDirEntries] ; Search all (224) entries
|
||||
mov ax, 0 ; Searching at offset 0
|
||||
|
||||
|
||||
next_root_entry:
|
||||
xchg cx, dx ; We use CX in the inner loop...
|
||||
|
||||
mov si, kern_filename ; Start searching for kernel filename
|
||||
mov cx, 11
|
||||
rep cmpsb
|
||||
je found_file_to_load ; Pointer DI will be at offset 11
|
||||
|
||||
add ax, 32 ; Bump searched entries by 1 (32 bytes per entry)
|
||||
|
||||
mov di, buffer ; Point to next entry
|
||||
add di, ax
|
||||
|
||||
xchg dx, cx ; Get the original CX back
|
||||
loop next_root_entry
|
||||
|
||||
mov si, file_not_found ; If kernel is not found, bail out
|
||||
call print_string
|
||||
jmp reboot
|
||||
|
||||
|
||||
found_file_to_load: ; Fetch cluster and load FAT into RAM
|
||||
mov ax, word [es:di+0Fh] ; Offset 11 + 15 = 26, contains 1st cluster
|
||||
mov word [cluster], ax
|
||||
|
||||
mov ax, 1 ; Sector 1 = first sector of first FAT
|
||||
call l2hts
|
||||
|
||||
mov di, buffer ; ES:BX points to our buffer
|
||||
mov bx, di
|
||||
|
||||
mov ah, 2 ; int 13h params: read (FAT) sectors
|
||||
mov al, 9 ; All 9 sectors of 1st FAT
|
||||
|
||||
pusha ; Prepare to enter loop
|
||||
|
||||
|
||||
read_fat:
|
||||
popa ; In case registers are altered by int 13h
|
||||
pusha
|
||||
|
||||
stc
|
||||
int 13h ; Read sectors using the BIOS
|
||||
|
||||
jnc read_fat_ok ; If read went OK, skip ahead
|
||||
call reset_floppy ; Otherwise, reset floppy controller and try again
|
||||
jnc read_fat ; Floppy reset OK?
|
||||
|
||||
; ******************************************************************
|
||||
fatal_disk_error:
|
||||
; ******************************************************************
|
||||
mov si, disk_error ; If not, print error message and reboot
|
||||
call print_string
|
||||
jmp reboot ; Fatal double error
|
||||
|
||||
|
||||
read_fat_ok:
|
||||
popa
|
||||
|
||||
mov ax, 2000h ; Segment where we'll load the kernel
|
||||
mov es, ax
|
||||
mov bx, 0
|
||||
|
||||
mov ah, 2 ; int 13h floppy read params
|
||||
mov al, 1
|
||||
|
||||
push ax ; Save in case we (or int calls) lose it
|
||||
|
||||
|
||||
; Now we must load the FAT from the disk. Here's how we find out where it starts:
|
||||
; FAT cluster 0 = media descriptor = 0F0h
|
||||
; FAT cluster 1 = filler cluster = 0FFh
|
||||
; Cluster start = ((cluster number) - 2) * SectorsPerCluster + (start of user)
|
||||
; = (cluster number) + 31
|
||||
|
||||
load_file_sector:
|
||||
mov ax, word [cluster] ; Convert sector to logical
|
||||
add ax, 31
|
||||
|
||||
call l2hts ; Make appropriate params for int 13h
|
||||
|
||||
mov ax, 2000h ; Set buffer past what we've already read
|
||||
mov es, ax
|
||||
mov bx, word [pointer]
|
||||
|
||||
pop ax ; Save in case we (or int calls) lose it
|
||||
push ax
|
||||
|
||||
stc
|
||||
int 13h
|
||||
|
||||
jnc calculate_next_cluster ; If there's no error...
|
||||
|
||||
call reset_floppy ; Otherwise, reset floppy and retry
|
||||
jmp load_file_sector
|
||||
|
||||
|
||||
; In the FAT, cluster values are stored in 12 bits, so we have to
|
||||
; do a bit of maths to work out whether we're dealing with a byte
|
||||
; and 4 bits of the next byte -- or the last 4 bits of one byte
|
||||
; and then the subsequent byte!
|
||||
|
||||
calculate_next_cluster:
|
||||
mov ax, [cluster]
|
||||
mov dx, 0
|
||||
mov bx, 3
|
||||
mul bx
|
||||
mov bx, 2
|
||||
div bx ; DX = [cluster] mod 2
|
||||
mov si, buffer
|
||||
add si, ax ; AX = word in FAT for the 12 bit entry
|
||||
mov ax, word [ds:si]
|
||||
|
||||
or dx, dx ; If DX = 0 [cluster] is even; if DX = 1 then it's odd
|
||||
|
||||
jz even ; If [cluster] is even, drop last 4 bits of word
|
||||
; with next cluster; if odd, drop first 4 bits
|
||||
|
||||
odd:
|
||||
shr ax, 4 ; Shift out first 4 bits (they belong to another entry)
|
||||
jmp short next_cluster_cont
|
||||
|
||||
|
||||
even:
|
||||
and ax, 0FFFh ; Mask out final 4 bits
|
||||
|
||||
|
||||
next_cluster_cont:
|
||||
mov word [cluster], ax ; Store cluster
|
||||
|
||||
cmp ax, 0FF8h ; FF8h = end of file marker in FAT12
|
||||
jae end
|
||||
|
||||
add word [pointer], 512 ; Increase buffer pointer 1 sector length
|
||||
jmp load_file_sector
|
||||
|
||||
|
||||
end: ; We've got the file to load!
|
||||
pop ax ; Clean up the stack (AX was pushed earlier)
|
||||
mov dl, byte [bootdev] ; Provide kernel with boot device info
|
||||
|
||||
jmp 2000h:0000h ; Jump to entry point of loaded kernel!
|
||||
|
||||
|
||||
; ------------------------------------------------------------------
|
||||
; BOOTLOADER SUBROUTINES
|
||||
|
||||
reboot:
|
||||
mov ax, 0
|
||||
int 16h ; Wait for keystroke
|
||||
mov ax, 0
|
||||
int 19h ; Reboot the system
|
||||
|
||||
|
||||
print_string: ; Output string in SI to screen
|
||||
pusha
|
||||
|
||||
mov ah, 0Eh ; int 10h teletype function
|
||||
|
||||
.repeat:
|
||||
lodsb ; Get char from string
|
||||
cmp al, 0
|
||||
je .done ; If char is zero, end of string
|
||||
int 10h ; Otherwise, print it
|
||||
jmp short .repeat
|
||||
|
||||
.done:
|
||||
popa
|
||||
ret
|
||||
|
||||
|
||||
reset_floppy: ; IN: [bootdev] = boot device; OUT: carry set on error
|
||||
push ax
|
||||
push dx
|
||||
mov ax, 0
|
||||
mov dl, byte [bootdev]
|
||||
stc
|
||||
int 13h
|
||||
pop dx
|
||||
pop ax
|
||||
ret
|
||||
|
||||
|
||||
l2hts: ; Calculate head, track and sector settings for int 13h
|
||||
; IN: logical sector in AX, OUT: correct registers for int 13h
|
||||
push bx
|
||||
push ax
|
||||
|
||||
mov bx, ax ; Save logical sector
|
||||
|
||||
mov dx, 0 ; First the sector
|
||||
div word [SectorsPerTrack]
|
||||
add dl, 01h ; Physical sectors start at 1
|
||||
mov cl, dl ; Sectors belong in CL for int 13h
|
||||
mov ax, bx
|
||||
|
||||
mov dx, 0 ; Now calculate the head
|
||||
div word [SectorsPerTrack]
|
||||
mov dx, 0
|
||||
div word [Sides]
|
||||
mov dh, dl ; Head/side
|
||||
mov ch, al ; Track
|
||||
|
||||
pop ax
|
||||
pop bx
|
||||
|
||||
mov dl, byte [bootdev] ; Set correct device
|
||||
|
||||
ret
|
||||
|
||||
|
||||
; ------------------------------------------------------------------
|
||||
; STRINGS AND VARIABLES
|
||||
|
||||
kern_filename db "KERNEL BIN" ; MikeOS kernel filename
|
||||
|
||||
disk_error db "Floppy error! Press any key...", 0
|
||||
file_not_found db "KERNEL.BIN not found!", 0
|
||||
|
||||
bootdev db 0 ; Boot device number
|
||||
cluster dw 0 ; Cluster of the file we want to load
|
||||
pointer dw 0 ; Pointer into Buffer, for loading kernel
|
||||
|
||||
|
||||
; ------------------------------------------------------------------
|
||||
; END OF BOOT SECTOR AND BUFFER START
|
||||
|
||||
times 510-($-$$) db 0 ; Pad remainder of boot sector with zeros
|
||||
dw 0AA55h ; Boot signature (DO NOT CHANGE!)
|
||||
|
||||
|
||||
buffer: ; Disk buffer begins (8k after this, stack starts)
|
||||
|
||||
|
||||
; ==================================================================
|
||||
|
BIN
source/bootload/bootload.bin
Executable file
BIN
source/bootload/bootload.bin
Executable file
Binary file not shown.
BIN
source/features/.cli.asm.swp
Normal file
BIN
source/features/.cli.asm.swp
Normal file
Binary file not shown.
BIN
source/features/.screen.asm.swp
Normal file
BIN
source/features/.screen.asm.swp
Normal file
Binary file not shown.
BIN
source/features/.strings.asm.swp
Normal file
BIN
source/features/.strings.asm.swp
Normal file
Binary file not shown.
49
source/features/cli.asm
Normal file
49
source/features/cli.asm
Normal file
@ -0,0 +1,49 @@
|
||||
os_start_cli:
|
||||
pusha
|
||||
|
||||
mov si, prompt
|
||||
call os_print_string
|
||||
|
||||
mov di, user_input
|
||||
|
||||
call os_display_input
|
||||
|
||||
popa
|
||||
ret
|
||||
|
||||
; ------------------------------------------------
|
||||
|
||||
os_read_cli:
|
||||
pusha
|
||||
|
||||
.output_the_user_input:
|
||||
call os_print_newline
|
||||
|
||||
mov si, command_result_text
|
||||
call os_print_string
|
||||
|
||||
mov si, user_input
|
||||
call os_print_string
|
||||
|
||||
call os_print_newline
|
||||
|
||||
.check_matches: ; Check if the user input matches any internal commands
|
||||
mov si, user_input
|
||||
mov di, help_string
|
||||
call os_compare_strings
|
||||
cmp cl, 1
|
||||
je print_help_text
|
||||
|
||||
.finish:
|
||||
call os_start_cli
|
||||
|
||||
print_help_text:
|
||||
mov si, help_text
|
||||
call os_print_string_nl
|
||||
|
||||
|
||||
user_input times 20 db 0
|
||||
prompt db 'CrawOS > ', 0
|
||||
help_string db 'HELP', 0
|
||||
help_text db 'This is CrawOS', 0
|
||||
command_result_text db 'You typed: ', 0
|
6
source/features/power.asm
Normal file
6
source/features/power.asm
Normal file
@ -0,0 +1,6 @@
|
||||
os_reboot:
|
||||
mov ax, 0x5307
|
||||
mov bx, 0x0001
|
||||
mov cx, 0x0003
|
||||
int 0x19
|
||||
|
152
source/features/screen.asm
Executable file
152
source/features/screen.asm
Executable file
@ -0,0 +1,152 @@
|
||||
; ==================================================================
|
||||
; MikeOS -- The Mike Operating System kernel
|
||||
; Copyright (C) 2006 - 2021 MikeOS Developers -- see doc/LICENSE.TXT
|
||||
;
|
||||
; SCREEN HANDLING SYSTEM CALLS
|
||||
; ==================================================================
|
||||
|
||||
; ------------------------------------------------------------------
|
||||
; os_print_string -- Displays text
|
||||
; IN: SI = message location (zero-terminated string)
|
||||
; OUT: Nothing (registers preserved)
|
||||
|
||||
os_print_string:
|
||||
pusha
|
||||
|
||||
mov ah, 0Eh ; int 10h teletype function, we're telling the BIOS we will print something
|
||||
|
||||
.repeat:
|
||||
lodsb ; Get char from si into al
|
||||
cmp al, 0 ; Compare al to 0
|
||||
je .done ; If char is zero, end of string
|
||||
|
||||
int 10h ; Otherwise, print it
|
||||
jmp .repeat ; And move on to next char
|
||||
|
||||
.done:
|
||||
popa
|
||||
ret
|
||||
|
||||
; Exact same as the above procedure, but this adds a newline
|
||||
; after priting, similar to the difference between Rust's print! and println!
|
||||
os_print_string_nl: pusha
|
||||
|
||||
mov ah, 0Eh ; int 10h teletype function, we're telling the BIOS we will print something
|
||||
|
||||
.repeat:
|
||||
lodsb ; Get char from si into al
|
||||
cmp al, 0 ; Compare al to 0
|
||||
je .done ; If char is zero, end of string
|
||||
|
||||
int 10h ; Otherwise, print it
|
||||
jmp .repeat ; And move on to next char
|
||||
|
||||
.done:
|
||||
call os_print_newline
|
||||
popa
|
||||
ret
|
||||
|
||||
; --------------------------------------------
|
||||
|
||||
os_print_newline:
|
||||
pusha
|
||||
|
||||
mov ah, 03h
|
||||
int 10h
|
||||
|
||||
mov ah, 02h
|
||||
add dh, 1
|
||||
mov dl, 0
|
||||
int 10h
|
||||
|
||||
popa
|
||||
ret
|
||||
|
||||
|
||||
; -------------------------------------------
|
||||
|
||||
os_clear_screen:
|
||||
pusha
|
||||
|
||||
mov ah, 00h
|
||||
mov al, 03h ; Set video mode to textmode (80x25). 16 colors, 8 pages
|
||||
int 10h
|
||||
|
||||
mov ah, 02h
|
||||
mov dh, 0
|
||||
mov dl, 0
|
||||
int 10h
|
||||
|
||||
popa
|
||||
ret
|
||||
|
||||
; -------------------------------------------
|
||||
|
||||
; AX = key pressed
|
||||
os_read_input:
|
||||
mov ah, 11h ; BIOS call to check for key
|
||||
int 16h ; Interrupt
|
||||
jnz .key_pressed ; Jump if input isn't 0
|
||||
|
||||
hlt
|
||||
jmp os_read_input
|
||||
|
||||
.key_pressed:
|
||||
mov ah, 10h
|
||||
int 16h
|
||||
ret
|
||||
|
||||
; -------------------------------------------
|
||||
|
||||
os_display_input:
|
||||
pusha
|
||||
|
||||
call .check_key_pressed
|
||||
|
||||
jmp os_display_input
|
||||
|
||||
.check_key_pressed:
|
||||
call os_read_input
|
||||
|
||||
cmp al, 08h
|
||||
je .backspace
|
||||
|
||||
cmp al, 0Dh
|
||||
je .enter_key
|
||||
|
||||
cmp al, 1Bh
|
||||
je .esc_key
|
||||
|
||||
call .print_current_input
|
||||
ret
|
||||
|
||||
.esc_key:
|
||||
call os_reboot
|
||||
|
||||
.enter_key:
|
||||
mov al, 0
|
||||
stosb
|
||||
mov di, user_input
|
||||
|
||||
call os_read_cli
|
||||
|
||||
.backspace:
|
||||
mov ah, 0Eh
|
||||
|
||||
mov al, 08h
|
||||
int 10h
|
||||
mov al, 20h
|
||||
int 10h
|
||||
mov al, 08h
|
||||
int 10h
|
||||
|
||||
dec di
|
||||
jmp os_display_input
|
||||
|
||||
.print_current_input:
|
||||
stosb
|
||||
|
||||
mov ah, 0Eh
|
||||
int 10h
|
||||
|
||||
ret
|
28
source/features/strings.asm
Normal file
28
source/features/strings.asm
Normal file
@ -0,0 +1,28 @@
|
||||
; How string comparison works
|
||||
; DI => scasb compares value stored in DI which is 's' with 's' stored in AX register
|
||||
; and then increments DI if DF is 0
|
||||
; v
|
||||
; memory address 1: |s|n|a|t|0|
|
||||
; memory address 2: |s|n|a|k|e|0|
|
||||
; ^
|
||||
; SI => lodsb loads value stored at SI to AX and then increments SI if DF is 0
|
||||
os_compare_strings:
|
||||
pusha
|
||||
|
||||
.compare:
|
||||
lodsb
|
||||
scasb ; Compare di to si
|
||||
jne .unequal ; If they are no equal, jump to .unequal
|
||||
cmp al, 0 ; Check if string is finished
|
||||
je .equal ; If it has, return true
|
||||
jmp .compare ; Finally, repeat
|
||||
|
||||
.unequal:
|
||||
mov cl, 0 ; Change to 0 if unquality is proven
|
||||
popa
|
||||
ret
|
||||
|
||||
.equal:
|
||||
mov cl, 1
|
||||
popa
|
||||
ret
|
108
source/kernel.asm
Executable file
108
source/kernel.asm
Executable file
@ -0,0 +1,108 @@
|
||||
; ==================================================================
|
||||
; MikeOS -- The Mike Operating System kernel
|
||||
; Copyright (C) 2006 - 2022 MikeOS Developers -- see doc/LICENSE.TXT
|
||||
;
|
||||
; This is loaded from the drive by BOOTLOAD.BIN, as KERNEL.BIN.
|
||||
; First we have the system call vectors, which start at a static point
|
||||
; for programs to use. Following that is the main kernel code and
|
||||
; then additional system call code is included.
|
||||
; ==================================================================
|
||||
|
||||
|
||||
BITS 16
|
||||
CPU 386 ; pusha offsets depends on a 386 or better
|
||||
; FS and GS require a 386 or better
|
||||
|
||||
%DEFINE CRAWOS_VER '0.0.2' ; OS version number
|
||||
%DEFINE CRAWOS_API_VER 1 ; API version for programs to check
|
||||
|
||||
|
||||
; This is the location in RAM for kernel disk operations, 24K
|
||||
; after the point where the kernel has loaded; it's 8K in size,
|
||||
; because external programs load after it at the 32K point:
|
||||
|
||||
disk_buffer equ 24576
|
||||
|
||||
|
||||
; ------------------------------------------------------------------
|
||||
; OS CALL VECTORS -- Static locations for system call vectors
|
||||
; Note: these cannot be moved, or it'll break the calls!
|
||||
|
||||
; The comments show exact locations of instructions in this section,
|
||||
; and are used in programs/mikedev.inc so that an external program can
|
||||
; use a CrawOS system call without having to know its exact position
|
||||
; in the kernel source code...
|
||||
|
||||
os_call_vectors:
|
||||
jmp os_main ; 0000h -- Called from bootloader
|
||||
jmp os_print_string ; 0003h
|
||||
jmp os_read_input
|
||||
jmp os_display_input
|
||||
jmp os_start_cli
|
||||
|
||||
|
||||
; ------------------------------------------------------------------
|
||||
; START OF MAIN KERNEL CODE
|
||||
|
||||
os_main:
|
||||
cli ; Clear interrupts
|
||||
mov ax, 0
|
||||
mov ss, ax ; Set stack segment and pointer
|
||||
mov sp, 0FFFFh
|
||||
sti ; Restore interrupts
|
||||
|
||||
cld ; The default direction for string operations
|
||||
; will be 'up' - incrementing address in RAM
|
||||
|
||||
mov ax, 2000h ; Set all segments to match where kernel is loaded
|
||||
mov ds, ax ; After this, we don't need to bother with
|
||||
mov es, ax ; segments ever again, as MikeOS and its programs
|
||||
mov fs, ax ; live entirely in 64K
|
||||
mov gs, ax
|
||||
|
||||
cmp dl, 0
|
||||
je no_change
|
||||
mov [bootdev], dl ; Save boot device number
|
||||
push es
|
||||
mov ah, 8 ; Get drive parameters
|
||||
int 13h
|
||||
pop es
|
||||
and cx, 3Fh ; Maximum sector number
|
||||
mov [SecsPerTrack], cx ; Sector numbers start at 1
|
||||
movzx dx, dh ; Maximum head number
|
||||
add dx, 1 ; Head numbers start at 0 - add 1 for total
|
||||
mov [Sides], dx
|
||||
|
||||
no_change:
|
||||
call os_clear_screen
|
||||
call os_start_cli
|
||||
|
||||
bootdev db 0
|
||||
SecsPerTrack dw 18
|
||||
Sides dw 2
|
||||
|
||||
; ------------------------------------------------------------------
|
||||
; SYSTEM VARIABLES -- Settings for programs and system calls
|
||||
|
||||
|
||||
; Time and date formatting
|
||||
|
||||
fmt_12_24 db 0 ; Non-zero = 24-hr format
|
||||
|
||||
fmt_date db 0, '/' ; 0, 1, 2 = M/D/Y, D/M/Y or Y/M/D
|
||||
; Bit 7 = use name for months
|
||||
; If bit 7 = 0, second byte = separator character
|
||||
|
||||
|
||||
; ------------------------------------------------------------------
|
||||
; FEATURES -- Code to pull into the kernel
|
||||
|
||||
%INCLUDE "features/screen.asm"
|
||||
%INCLUDE "features/cli.asm"
|
||||
%INCLUDE "features/power.asm"
|
||||
%INCLUDE "features/strings.asm"
|
||||
|
||||
; ==================================================================
|
||||
; END OF KERNEL
|
||||
; ==================================================================
|
||||
|
6
test-linux.sh
Executable file
6
test-linux.sh
Executable file
@ -0,0 +1,6 @@
|
||||
#!/bin/sh
|
||||
|
||||
# This script starts the QEMU PC emulator, booting from the
|
||||
# MikeOS floppy disk image
|
||||
|
||||
qemu-system-i386 -soundhw pcspk -drive format=raw,file=disk_images/mikeos.flp,index=0,if=floppy
|
Loading…
x
Reference in New Issue
Block a user