From a8a206884f48844a282b394af3436fc4641cdb62 Mon Sep 17 00:00:00 2001 From: redfast00 Date: Tue, 21 May 2019 20:08:21 +0200 Subject: [PATCH] Initial commit Co-authored-by: Robbe Van Herck --- .gitignore | 3 + bochs.conf | 518 +++++++++++++++++++++++++++++++++++++++++++++++++++ build.sh | 5 + emulate.sh | 3 + messages.asm | 122 ++++++++++++ run.sh | 2 + 6 files changed, 653 insertions(+) create mode 100644 .gitignore create mode 100644 bochs.conf create mode 100755 build.sh create mode 100755 emulate.sh create mode 100644 messages.asm create mode 100755 run.sh diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..8bfc626 --- /dev/null +++ b/.gitignore @@ -0,0 +1,3 @@ +MyBoot.bin +bochsout.txt +bx_enh_dbg.ini diff --git a/bochs.conf b/bochs.conf new file mode 100644 index 0000000..eac4ccc --- /dev/null +++ b/bochs.conf @@ -0,0 +1,518 @@ +plugin_ctrl: speaker=0 +magic_break: enabled=1 +display_library: x, options="gui_debug" + +#======================================================================= +# ROMIMAGE: +# You now need to load a ROM BIOS into F0000-FFFFF. I've wiped +# out most of the BIOS hooks, and replace them with real BIOS +# support. Normally, you can use a precompiled BIOS in the bios/ +# directory, named BIOS-bochs-latest. +#======================================================================= +#romimage: bios/BIOS-bochs-970717a +##romimage: file=BIOS-bochs-latest, address=0xf0000 +romimage: file=/usr/share/bochs/BIOS-bochs-legacy + + +#romimage: file=bios/BIOS-bochs-2-processors, address=0xf0000 +#romimage: file=bios/BIOS-bochs-4-processors, address=0xf0000 +#romimage: file=bios/rombios.bin, address=0xf0000 + +#======================================================================= +# MEGS +# set this to the default number of Megabytes of memory you want +# to emulate. You may also pass the '-megs xyz' option to bochs +# +# The default is 32MB, most OS's won't need more than that. +#======================================================================= +#megs: 256 +#megs: 128 +#megs: 64 +megs: 32 +#megs: 16 +#megs: 8 +vgaromimage: file=/usr/share/bochs/VGABIOS-lgpl-latest-cirrus + + +#======================================================================= +# FLOPPYA: +# Point this to pathname of floppy image file or device +# This should be of a bootable floppy(image/device) if you're +# booting from 'a'. +# +# You can set the initial status of the media to 'ejected' or 'inserted'. +# floppya: 2_88=path, status=ejected (2.88M 3.5" floppy) +# floppya: 1_44=path, status=inserted (1.44M 3.5" floppy) +# floppya: 1_2=path, status=ejected (1.2M 5.25" floppy) +# floppya: 720k=path, status=inserted (720K 3.5" floppy) +# floppya: 360k=path, status=inserted (360K 5.25" floppy) +# +# The path should be the name of a disk image file. On unix, you can use +# a raw device name such as /dev/fd0 on Linux. On WinNT and Win2k, use +# drive letters such as a: or b: as the path. Raw floppy access is not +# supported on Windows 95 and 98. +#======================================================================= +floppya: 1_44=MyBoot.bin, status=inserted +#floppya: file=../1.44, status=inserted +#floppya: 1_44=/dev/fd0H1440, status=inserted +#floppya: 1_2=../1_2, status=inserted +#floppya: 1_44=a:, status=inserted +#floppya: 1_44=a.img, status=inserted + +#======================================================================= +# FLOPPYB: +# See FLOPPYA above for syntax +#======================================================================= +#floppyb: 1_44=b:, status=inserted +#floppyb: 1_44=b.img, status=inserted + +#======================================================================= +# ATA0, ATA1, ATA2, ATA3 +# ATA controller for hard disks and cdroms +# +# ata[0-3]: enabled=[0|1], ioaddr1=addr, ioaddr2=addr, irq=number +# +# These options enables up to 4 ata channels. For each channel +# the two base io address and the irq must be specified. +# +# ata0 is enabled by default, with ioaddr1=0x1f0, ioaddr2=0x3f0, irq=14 +# +# Examples: +# ata0: enabled=1, ioaddr1=0x1f0, ioaddr2=0x3f0, irq=14 +# ata1: enabled=1, ioaddr1=0x170, ioaddr2=0x370, irq=15 +# ata2: enabled=1, ioaddr1=0x1e8, ioaddr2=0x3e8, irq=11 +# ata3: enabled=1, ioaddr1=0x168, ioaddr2=0x368, irq=9 +#======================================================================= +ata0: enabled=1, ioaddr1=0x1f0, ioaddr2=0x3f0, irq=14 +ata1: enabled=0, ioaddr1=0x170, ioaddr2=0x370, irq=15 +ata2: enabled=0, ioaddr1=0x1e8, ioaddr2=0x3e8, irq=11 +ata3: enabled=0, ioaddr1=0x168, ioaddr2=0x368, irq=9 + +#======================================================================= +# ATA[0-3]-MASTER, ATA[0-3]-SLAVE +# +# This defines the type and characteristics of all attached ata devices: +# type= type of attached device [disk|cdrom] +# path= path of the image +# cylinders= only valid for disks +# heads= only valid for disks +# spt= only valid for disks +# status= only valid for cdroms [inserted|ejected] +# biosdetect= type of biosdetection [none|auto], only for disks on ata0 [cmos] +# translation=type of transation of the bios, only for disks [none|lba|large|rechs|auto] +# model= string returned by identify device command +# +# Point this at a hard disk image file, cdrom iso file, or physical cdrom +# device. To create a hard disk image, try running bximage. It will help you +# choose the size and then suggest a line that works with it. +# +# In UNIX it may be possible to use a raw device as a Bochs hard disk, +# but WE DON'T RECOMMEND IT. In Windows there is no easy way. +# +# In windows, the drive letter + colon notation should be used for cdroms. +# Depending on versions of windows and drivers, you may only be able to +# access the "first" cdrom in the system. On MacOSX, use path="drive" +# to access the physical drive. +# +# The path, cylinders, heads, and spt are mandatory for type=disk +# The path is mandatory for type=cdrom +# +# Default values are: +# biosdetect=auto, translation=auto, model="Generic 1234" +# +# The biosdetect option has currently no effect on the bios +# +# Examples: +# ata0-master: type=disk, path=10M.sample, cylinders=306, heads=4, spt=17 +# ata0-slave: type=disk, path=20M.sample, cylinders=615, heads=4, spt=17 +# ata1-master: type=disk, path=30M.sample, cylinders=615, heads=6, spt=17 +# ata1-slave: type=disk, path=46M.sample, cylinders=940, heads=6, spt=17 +# ata2-master: type=disk, path=62M.sample, cylinders=940, heads=8, spt=17 +# ata2-slave: type=disk, path=112M.sample, cylinders=900, heads=15, spt=17 +# ata3-master: type=disk, path=483M.sample, cylinders=1024, heads=15, spt=63 +# ata3-slave: type=cdrom, path=iso.sample, status=inserted +#======================================================================= +#ata0-master: type=disk, path="30M.sample", cylinders=615, heads=6, spt=17 +#ata0-slave: type=cdrom, path=D:, status=inserted +#ata0-slave: type=cdrom, path=/dev/cdrom, status=inserted +#ata0-slave: type=cdrom, path="drive", status=inserted + +#======================================================================= +# +# The DISKC option is deprecated. Use ATA* options instead. +# +# DISKC: file=, cyl=, heads=, spt= +# Point this at a hard disk image file. To create +# a hard disk image, try running bximage. It will help you choose the +# size and then suggest a diskc line that works with it. +# +# In UNIX it may be possible to use a raw device as a Bochs hard disk, +# but WE DON'T RECOMMEND IT. In Windows there is no easy way. +# +# Examples: +# diskc: file=10M.sample, cyl=306, heads=4, spt=17 +# diskc: file=20M.sample, cyl=615, heads=4, spt=17 +# diskc: file=30M.sample, cyl=615, heads=6, spt=17 +# diskc: file=46M.sample, cyl=940, heads=6, spt=17 +# diskc: file=62M.sample, cyl=940, heads=8, spt=17 +# diskc: file=112M.sample, cyl=900, heads=15, spt=17 +# diskc: file=483M.sample, cyl=1024, heads=15, spt=63 +#======================================================================= +#diskc: file="30M.sample", cyl=615, heads=6, spt=17 + +#======================================================================= +# +# The DISKD option is deprecated. Use ATA* options instead. +# +# DISKD: +# See DISKC above for syntax +# +# NOTE: diskd and cdromd must not be used together! +#======================================================================= +#diskd: file="diskd.img", cyl=615, heads=6, spt=17 + +#======================================================================= +# +# The CDROMD option is deprecated. Use ATA* options instead. +# +# CDROMD: +# +# cdromd: dev=/dev/cdrom, status=inserted +# cdromd: dev=/dev/cdrom, status=ejected +# cdromd: dev=e:, status=ejected +# +# In windows, the drive letter + colon notation should be used for cdroms. +# Depending on versions of windows and drivers, you may only be able to +# access the "first" cdrom in the system. On MacOSX, use path="drive" +# to access the physical drive. +# +# NOTE: diskd and cdromd must not be used together! +#======================================================================= +#cdromd: dev=D:, status=inserted +#cdromd: dev=/dev/cdrom, status=inserted +#cdromd: dev="drive", status=inserted + +#======================================================================= +# NEWHARDDRIVESUPPORT: enabled=[0|1] +# As of cvs version on 5/17/2001, newharddrivesupport is on by default. +#======================================================================= +#newharddrivesupport: enabled=1 + +#======================================================================= +# BOOT: +# This defines your boot drive. +# You can either boot from 'floppy', 'disk' or 'cdrom' +# legacy 'a' and 'c' are also supported +# Examples: +# boot: floppy +# boot: disk +# boot: cdrom +# boot: c +# boot: a +#======================================================================= +boot: floppy +#boot: disk + +#======================================================================= +# FLOPPY_BOOTSIG_CHECK: disabled=[0|1] +# Enables or disables the 0xaa55 signature check on boot floppies +# Defaults to disabled=0 +# Examples: +# floppy_bootsig_check: disabled=0 +# floppy_bootsig_check: disabled=1 +#======================================================================= +#floppy_bootsig_check: disabled=1 +floppy_bootsig_check: disabled=0 + +#======================================================================= +# LOG: +# Give the path of the log file you'd like Bochs debug and misc. verbage +# to be written to. If you really don't want it, make it /dev/null. :^( +# +# Examples: +# log: ./bochs.out +# log: /dev/tty +#======================================================================= +#log: /dev/null +log: bochsout.txt + +#======================================================================= +# LOGPREFIX: +# This handles the format of the string prepended to each log line. +# You may use those special tokens : +# %t : 11 decimal digits timer tick +# %i : 8 hexadecimal digits of cpu0 current eip +# %e : 1 character event type ('i'nfo, 'd'ebug, 'p'anic, 'e'rror) +# %d : 5 characters string of the device, between brackets +# +# Default : %t%e%d +# Examples: +# logprefix: %t-%e-@%i-%d +# logprefix: %i%e%d +#======================================================================= +#logprefix: %t%e%d + +#======================================================================= +# LOG CONTROLS +# +# Bochs now has four severity levels for event logging. +# panic: cannot proceed. If you choose to continue after a panic, +# don't be surprised if you get strange behavior or crashes. +# error: something went wrong, but it is probably safe to continue the +# simulation. +# info: interesting or useful messages. +# debug: messages useful only when debugging the code. This may +# spit out thousands per second. +# +# For events of each level, you can choose to crash, report, or ignore. +# TODO: allow choice based on the facility: e.g. crash on panics from +# everything except the cdrom, and only report those. +# +# If you are experiencing many panics, it can be helpful to change +# the panic action to report instead of fatal. However, be aware +# that anything executed after a panic is uncharted territory and can +# cause bochs to become unstable. The panic is a "graceful exit," so +# if you disable it you may get a spectacular disaster instead. +#======================================================================= +panic: action=ask +error: action=ask +info: action=report +debug: action=ignore + +#======================================================================= +# DEBUGGER_LOG: +# Give the path of the log file you'd like Bochs to log debugger output. +# If you really don't want it, make it /dev/null or '-'. :^( +# +# Examples: +# debugger_log: ./debugger.out +#======================================================================= +#debugger_log: /dev/null +#debugger_log: debugger.out +debugger_log: - + +#======================================================================= +# com1: +# This defines a serial (COM) port. You can specify a device to use as com1. +# This can be a real serial line, or a pty. To use a pty (under X/Unix), +# create two windows (xterms, usually). One of them will run bochs, and the +# other will act as com1. Find out the tty the com1 window using the `tty' +# command, and use that as the `dev' parameter. Then do `sleep 1000000' in +# the com1 window to keep the shell from messing with things, and run bochs in +# the other window. Serial I/O to com1 (port 0x3f8) will all go to the other +# window. +#======================================================================= +#com1: enabled=1, dev=/dev/ttyp9 + + +#======================================================================= +# PARPORT1: +# This defines a parallel (printer) port. When turned on and an output file is +# defined the emulated printer port sends characters printed by the guest OS +# into the output file. On some platforms a device filename can be used to +# send the data to the real parallel port (e.g. "/dev/lp0" on Linux, "lpt1" on +# win32 platforms). +# +# Examples: +# parport1: enabled=1, file="parport.out" +# parport1: enabled=1, file="/dev/lp0" +# parport1: enabled=0 +#======================================================================= +#parport1: enabled=1, file="parport.out" +parport1: enabled=0 + +#======================================================================= +# SB16: +# This defines the SB16 sound emulation. It can have several of the +# following properties. +# All properties are in the format sb16: property=value +# midi: The filename is where the midi data is sent. This can be a +# device or just a file if you want to record the midi data. +# midimode: +# 0=no data +# 1=output to device (system dependent. midi denotes the device driver) +# 2=SMF file output, including headers +# 3=output the midi data stream to the file (no midi headers and no +# delta times, just command and data bytes) +# wave: This is the device/file where wave output is stored +# wavemode: +# 0=no data +# 1=output to device (system dependent. wave denotes the device driver) +# 2=VOC file output, incl. headers +# 3=output the raw wave stream to the file +# log: The file to write the sb16 emulator messages to. +# loglevel: +# 0=no log +# 1=only midi program and bank changes +# 2=severe errors +# 3=all errors +# 4=all errors plus all port accesses +# 5=all errors and port accesses plus a lot of extra info +# dmatimer: +# microseconds per second for a DMA cycle. Make it smaller to fix +# non-continous sound. 750000 is usually a good value. This needs a +# reasonably correct setting for IPS. +# +# For an example look at the next line: +#======================================================================= + +# sb16: midimode=1, midi=/dev/midi00, wavemode=1, wave=/dev/dsp, loglevel=2, log=sb16.log, dmatimer=600000 + +#======================================================================= +# VGA_UPDATE_INTERVAL: +# Video memory is scanned for updates and screen updated every so many +# virtual seconds. The default is 300000, about 3Hz. This is generally +# plenty. Keep in mind that you must tweak the 'ips:' directive +# to be as close to the number of emulated instructions-per-second +# your workstation can do, for this to be accurate. +# +# Examples: +# vga_update_interval: 250000 +#======================================================================= +# vga_update_interval: 300000 +vga: update_freq=30, realtime=1 + +# using for Winstone '98 tests +#vga_update_interval: 100000 + +#======================================================================= +# KEYBOARD_SERIAL_DELAY: +# Approximate time in microseconds that it takes one character to +# be transfered from the keyboard to controller over the serial path. +# Examples: +# keyboard_serial_delay: 200 +#======================================================================= +keyboard: type=mf, serial_delay=200, paste_delay=100000 +# keyboard_serial_delay: 250 +# keyboard_paste_delay: 100000 + +#======================================================================= +# FLOPPY_COMMAND_DELAY: +# Time in microseconds to wait before completing some floppy commands +# such as read/write/seek/etc, which normally have a delay associated. +# I had this hardwired to 50,000 before. +# +# Examples: +# floppy_command_delay: 50000 +#======================================================================= +#floppy_command_delay: 500 + +#======================================================================= +# IPS: +# Emulated Instructions Per Second. This is the number of IPS that bochs +# is capable of running on your machine. Read the note in config.h +# on how to find this. Make sure to recompile after. +# +# IPS is used to calibrate many time-dependent events within the bochs +# simulation. For example, changing IPS affects the frequency of VGA +# updates, the duration of time before a key starts to autorepeat, and +# the measurement of BogoMips and other benchmarks. +# +# Examples: +# Machine Mips +# ________________________________________________________________ +# 650Mhz Athlon K-7 with Linux 2.4.4/egcs-2.91.66 2 to 2.5 Mips +# 400Mhz Pentium II with Linux 2.0.36/egcs-1.0.3 1 to 1.8 Mips +# 166Mhz 64bit Sparc with Solaris 2.x approx 0.75 Mips +# 200Mhz Pentium with Linux 2.x approx 0.5 Mips +# +#======================================================================= +cpu: ips=1000000 + +#======================================================================= +# PIT: +# The PIT is the programmable interval timer. It has an option that tries to +# keep the PIT in sync with real time. This feature is still experimental, +# but it may be useful if you want to prevent Bochs from running too fast, for +# example a DOS video game. Be aware that with the realtime pit option, your +# simulation will not be repeatable; this can a problem if you are debugging. +#======================================================================= +#pit: realtime=1 + +#======================================================================= +# mouse: Not used in any of the GUI specific modules, but the option +# bx_options.mouse_enabled is set to this value. The idea, +# is that the GUI code should not generate mouse events when +# not enabled. The hardware emualation itself is not disabled +# by this. This is to facilitate deterministic runs of bochs. +# +# Examples: +# mouse: enabled=1 +# mouse: enabled=0 +# +# I wouldn't recommend enabling the mouse by default, unless you have a +# really good reason to do so. +#======================================================================= +mouse: enabled=0 + +#======================================================================= +# private_colormap: Request that the GUI create and use it's own +# non-shared colormap. This colormap will be used +# when in the bochs window. If not enabled, a +# shared colormap scheme may be used. Not implemented +# on all GUI's. +# +# Examples: +# private_colormap: enabled=1 +# private_colormap: enabled=0 +#======================================================================= +private_colormap: enabled=0 + +#======================================================================= +# fullscreen: ONLY IMPLEMENTED ON AMIGA +# Request that Bochs occupy the entire screen instead of a +# window. +# +# Examples: +# fullscreen: enabled=0 +# fullscreen: enabled=1 +#======================================================================= +fullscreen: enabled=0 +screenmode: name="sample" +# speaker: enabled=1, mode=system +# keyboard_mapping: enabled=0, map= + +#======================================================================= +# KEYBOARD_TYPE: +# Type of keyboard return by a "identify keyboard" command to the +# keyboard controler. It must be one of "xt", "at" or "mf". +# Defaults to "mf". It should be ok for almost everybody. A known +# exception is french macs, that do have a "at"-like keyboard. +# +# Examples: +# keyboard_type: mf +#======================================================================= +#keyboard_type: mf + +#======================================================================= +# USER_SHORTCUT: +# This defines the keyboard shortcut to be sent when you press the "user" +# button in the headerbar. The shortcut string can be a combination of +# these key names: "alt", "ctrl", "del", "esc", "f1", "f4", "tab", "win". +# Up to 3 keys can be pressed at a time. +# +# Example: +# user_shortcut: keys=ctrlaltdel +#======================================================================= +#user_shortcut: keys=ctrlaltdel + +#======================================================================= +# other stuff +#======================================================================= +# magic_break + +#load32bitOSImage: os=nullkernel, path=../kernel.img, iolog=../vga_io.log +#load32bitOSImage: os=linux, path=../linux.img, iolog=../vga_io.log, initrd=../initrd.img +# i440fxsupport: enabled=0 +#time0: 938581955 + +#======================================================================= +# for Macintosh, use the style of pathnames in the following +# examples. +# +# vgaromimage: :bios:VGABIOS-elpin-2.20 +# romimage: file=:bios:BIOS-bochs-981222a, address=0xf0000 +# floppya: 1_44=[fd:], status=inserted +#======================================================================= + +#vgaromimage: :bios:VGABIOS-elpin-2.40 diff --git a/build.sh b/build.sh new file mode 100755 index 0000000..cc32b32 --- /dev/null +++ b/build.sh @@ -0,0 +1,5 @@ +#!/bin/bash + +rm -rf MyBoot.bin + +nasm -f bin -o MyBoot.bin messages.asm diff --git a/emulate.sh b/emulate.sh new file mode 100755 index 0000000..f39ee4f --- /dev/null +++ b/emulate.sh @@ -0,0 +1,3 @@ +#!/bin/bash + +bochs -q -f bochs.conf diff --git a/messages.asm b/messages.asm new file mode 100644 index 0000000..5656e49 --- /dev/null +++ b/messages.asm @@ -0,0 +1,122 @@ +org 0x7C00 +bits 16 + +WIDTH equ 0x50 +HEIGHT equ 0x18 +VIDEO_MODE equ 0x3 + +;; see http://www.ctyme.com/intr/int-10.htm for interrupts + +start: +;; Use color mode +mov ax, VIDEO_MODE +int 10h + +;; Clear screen +mov ah, 0x06 +mov al, 0x00 +mov bh, 0x0F +mov cx, 0x0000 +mov dh, HEIGHT +mov dl, WIDTH +int 0x10 + +;; Set cursor to bottom of screen +mov dh, HEIGHT +mov dl, 0x00 +mov bh, 0x00 +mov ah, 0x02 +int 0x10 + +.loop: + ;; Read character + mov ah, 0x00 + int 0x16 + + cmp al, 0x0d ; newline + je .newline + cmp al, 0x08 ; delete character + je .change_color_mode + jmp .nonewline + +.change_color_mode: + ;; Read character + mov ah, 0x00 + int 0x16 + mov [color_mode], al + jmp .loop + +.newline: + ;; Scroll up window + mov ah, 0x06 + mov al, 0x01 + mov bh, 0x0F + mov cx, 0x0000 + mov dh, HEIGHT + mov dl, WIDTH + int 0x10 + + ;; Get current cursor position + mov bh, 0x00 + mov ah, 0x03 + int 0x10 + + ;; Move cursor to beginning of screen + mov dl, 0x00 + mov ah, 0x02 + int 0x10 + + jmp .loop + + +.nonewline: + + ;; Write character + mov ah, 0x09 + mov bh, 0x00 + mov bl, [color_mode] + mov cx, 0x01 + int 0x10 + + ;; Get current cursor position + mov ah, 0x03 + int 0x10 + + cmp dl, WIDTH + jge .eol + jmp .noeol + +.eol: + ;; Scroll up window + mov ah, 0x06 + mov al, 0x01 + mov bh, 0x0F + mov cx, 0x0000 + mov dh, HEIGHT + mov dl, WIDTH + int 0x10 + + ;; Move cursor to beginning of screen + mov bh, 0 + mov dh, HEIGHT + mov dl, 0x00 + mov ah, 0x02 + int 0x10 + + jmp .loop + +.noeol: + + ;; Move cursor forward + inc dl + mov ah, 0x02 + int 0x10 + + jmp .loop + +halt: hlt + +color_mode: db 0x05 + +times 510 - ($ - $$) db 0 +dw 0xAA55 diff --git a/run.sh b/run.sh new file mode 100755 index 0000000..119725d --- /dev/null +++ b/run.sh @@ -0,0 +1,2 @@ +#!/bin/bash +./build.sh && ./emulate.sh