diff options
Diffstat (limited to 'xxx')
| -rw-r--r-- | xxx/bochs/bochsdebug | 2 | ||||
| -rw-r--r-- | xxx/bochs/bochsrc | 965 | ||||
| -rw-r--r-- | xxx/boot1/Makefile | 13 | ||||
| -rw-r--r-- | xxx/boot1/disk_load_16.asm | 103 | ||||
| -rw-r--r-- | xxx/boot1/mbr.asm | 106 | ||||
| -rw-r--r-- | xxx/boot1/print_string_16.asm | 115 | ||||
| -rw-r--r-- | xxx/boot2/GDT.asm | 77 | ||||
| -rw-r--r-- | xxx/boot2/Makefile | 28 | ||||
| -rw-r--r-- | xxx/boot2/check_a20_16.asm | 61 | ||||
| -rw-r--r-- | xxx/boot2/common_pm.asm | 86 | ||||
| -rw-r--r-- | xxx/boot2/disk_load_16.asm | 281 | ||||
| -rw-r--r-- | xxx/boot2/memmap.asm | 57 | ||||
| -rw-r--r-- | xxx/boot2/mp.asm | 37 | ||||
| -rw-r--r-- | xxx/boot2/pm.asm | 36 | ||||
| -rw-r--r-- | xxx/boot2/print_string_16.asm | 115 | ||||
| -rw-r--r-- | xxx/boot2/stage2.asm | 267 | ||||
| -rw-r--r-- | xxx/boot2/vesa_setup_16.asm | 93 | ||||
| -rw-r--r-- | xxx/inactive/acpi.c | 171 | ||||
| -rw-r--r-- | xxx/inactive/acpi.h | 2 | ||||
| -rw-r--r-- | xxx/inactive/e1000.c | 4 | ||||
| -rw-r--r-- | xxx/inactive/e1000.h | 1 | ||||
| -rw-r--r-- | xxx/inactive/floppy.c | 575 | ||||
| -rw-r--r-- | xxx/inactive/floppy.h | 1 | ||||
| -rw-r--r-- | xxx/inactive/mouse.c | 175 | ||||
| -rw-r--r-- | xxx/inactive/mp.c | 179 | ||||
| -rw-r--r-- | xxx/inactive/mp.h | 2 | ||||
| -rw-r--r-- | xxx/inactive/pci.c | 133 | ||||
| -rw-r--r-- | xxx/inactive/smp.c | 101 | ||||
| -rw-r--r-- | xxx/inactive/smp.h | 20 |
29 files changed, 3806 insertions, 0 deletions
diff --git a/xxx/bochs/bochsdebug b/xxx/bochs/bochsdebug new file mode 100644 index 0000000..fabafe9 --- /dev/null +++ b/xxx/bochs/bochsdebug @@ -0,0 +1,2 @@ +continue + diff --git a/xxx/bochs/bochsrc b/xxx/bochs/bochsrc new file mode 100644 index 0000000..fc56d19 --- /dev/null +++ b/xxx/bochs/bochsrc @@ -0,0 +1,965 @@ +# +# +# +## You may now use double quotes around pathnames, in case +# your pathname includes spaces. + +#======================================================================= +# CONFIG_INTERFACE +# +# The configuration interface is a series of menus or dialog boxes that +# allows you to change all the settings that control Bochs's behavior. +# Depending on the platform there are up to 3 choices of configuration +# interface: a text mode version called "textconfig" and two graphical versions +# called "win32config" and "wx". The text mode version uses stdin/stdout and +# is always compiled in, unless Bochs is compiled for wx only. The choice +# "win32config" is only available on win32 and it is the default there. +# The choice "wx" is only available when you use "--with-wx" on the configure +# command. If you do not write a config_interface line, Bochs will +# choose a default for you. +# +# NOTE: if you use the "wx" configuration interface, you must also use +# the "wx" display library. +#======================================================================= +#config_interface: textconfig +#config_interface: wx + +#======================================================================= +# DISPLAY_LIBRARY +# +# The display library is the code that displays the Bochs VGA screen. Bochs +# has a selection of about 10 different display library implementations for +# different platforms. If you run configure with multiple --with-* options, +# the display_library command lets you choose which one you want to run with. +# If you do not write a display_library line, Bochs will choose a default for +# you. +# +# The choices are: +# x use X windows interface, cross platform +# sdl use SDL library, cross platform +# svga use SVGALIB library for Linux, allows graphics without X11 +# term text only, uses curses/ncurses library, cross platform +# rfb provides an interface to AT&T's VNC viewer, cross platform +# wx use wxWidgets library, cross platform +# nogui no display at all +# +# NOTE: if you use the "wx" configuration interface, you must also use +# the "wx" display library. +# +# Specific options: +# Some display libraries now support specific option to control their +# behaviour. See the examples below for currently supported options. +#======================================================================= +#display_library: rfb, options="timeout=60" # time to wait for client +#display_library: sdl #, options="fullscreen" # startup in fullscreen mode +#display_library: term +#display_library: wx +#display_library: x, options="hideIPS" # disable IPS output in status bar +display_library: x, options="gui_debug" # use GTK debugger gui +#display_library: term +#display_library: x +# + +#======================================================================= +# ROMIMAGE: +# The ROM BIOS controls what the PC does when it first powers on. +# Normally, you can use a precompiled BIOS in the source or binary +# distribution called BIOS-bochs-latest. The ROM BIOS is usually loaded +# starting at address 0xf0000, and it is exactly 64k long. Another option +# is 128k BIOS which is loaded at address 0xe0000. +# You can also use the environment variable $BXSHARE to specify the +# location of the BIOS. +# The usage of external large BIOS images (up to 512k) at memory top is +# now supported, but we still recommend to use the BIOS distributed with +# Bochs. The start address optional, since it can be calculated from image size. +#======================================================================= +#romimage: file=/usr/share/bochs/BIOS-bochs-latest +#romimage: file=bios/seabios-0.5.1.bin +#romimage: file=mybios.bin, address=0xfff80000 # 512k at memory top +romimage: file=/home/miguel/opt/bochs-2.6.6/bios/BIOS-bochs-latest + + +#======================================================================= +# CPU: +# This defines cpu-related parameters inside Bochs: +# +# COUNT: +# Set the number of processors:cores per processor:threads per core +# when Bochs is compiled for SMP emulation. +# Bochs currently supports up to 8 threads running simultaniosly. +# If Bochs is compiled without SMP support, it won't accept values +# different from 1. +# +# QUANTUM: +# Maximum amount of instructions allowed to execute by processor before +# returning control to another cpu. This option exists only in Bochs +# binary compiled with SMP support. +# +# RESET_ON_TRIPLE_FAULT: +# Reset the CPU when triple fault occur (highly recommended) rather than +# PANIC. Remember that if you trying to continue after triple fault the +# simulation will be completely bogus ! +# +# MSRS: +# Define path to user CPU Model Specific Registers (MSRs) specification. +# See example in msrs.def. +# +# IGNORE_BAD_MSRS: +# Ignore MSR references that Bochs does not understand; print a warning +# message instead of generating #GP exception. This option is enabled +# by default but will not be avaiable if configurable MSRs are enabled. +# +# IPS: +# Emulated Instructions Per Second. This is the number of IPS that bochs +# is capable of running on your machine. You can recompile Bochs with +# --enable-show-ips option enabled, to find your host's capability. +# Measured IPS value will then be logged into your log file or shown +# in the status bar (if supported by the gui). +# +# 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: +# +# Bochs Machine/Compiler Mips +# ____________________________________________________________________ +# 2.3.7 3.2Ghz Intel Core 2 Q9770 with WinXP/g++ 3.4 50 to 55 Mips +# 2.3.7 2.6Ghz Intel Core 2 Duo with WinXP/g++ 3.4 38 to 43 Mips +# 2.2.6 2.6Ghz Intel Core 2 Duo with WinXP/g++ 3.4 21 to 25 Mips +# 2.2.6 2.1Ghz Athlon XP with Linux 2.6/g++ 3.4 12 to 15 Mips +# 2.0.1 1.6Ghz Intel P4 with Win2000/g++ 3.3 5 to 7 Mips +#======================================================================= +cpu: count=2, ips=10000000 #, reset_on_triple_fault=1, ignore_bad_msrs=1, msrs="msrs.def" + +#======================================================================= +# CPUID: +# +# This defines features and functionality supported by Bochs emulated CPU: +# +# MMX: +# Select MMX instruction set support. +# This option exists only if Bochs compiled with BX_CPU_LEVEL >= 5. +# +# SEP: +# Select SYSENTER/SYSEXIT instruction set support. +# This option exists only if Bochs compiled with BX_CPU_LEVEL >= 6. +# +# SSE: +# Select SSE instruction set support. +# Any of NONE/SSE/SSE2/SSE3/SSSE3/SSE4_1/SSE4_2 could be selected. +# This option exists only if Bochs compiled with BX_CPU_LEVEL >= 6. +# +# XAPIC: +# Select XAPIC extensions support. +# This option exists only if Bochs compiled with BX_CPU_LEVEL >= 6. +# +# AES: +# Select AES instruction set support. +# This option exists only if Bochs compiled with BX_CPU_LEVEL >= 6. +# +# MOVBE: +# Select MOVBE Intel(R) Atom instruction support. +# This option exists only if Bochs compiled with BX_CPU_LEVEL >= 6. +# +# XSAVE: +# Select XSAVE extensions support. +# This option exists only if Bochs compiled with BX_CPU_LEVEL >= 6. +# +# 1G_PAGES: +# Enable 1G page size support in long mode. +# This option exists only if Bochs compiled with x86-64 support. +# +# PCID: +# Enable Process-Context Identifiers (PCID) support in long mode. +# This option exists only if Bochs compiled with x86-64 support. +# +# FSGSBASE: +# Enable GS/GS BASE access instructions support in long mode. +# This option exists only if Bochs compiled with x86-64 support. +# +# MWAIT: +# Select MONITOR/MWAIT instructions support. +# This option exists only if Bochs compiled with --enable-monitor-mwait. +# +# MWAIT_IS_NOP: +# When this option is enabled MWAIT will not put the CPU into a sleep state. +# This option exists only if Bochs compiled with --enable-monitor-mwait. +# +# VENDOR_STRING: +# Set the CPUID vendor string returned by CPUID(0x0). This should be a +# twelve-character ASCII string. +# +# BRAND_STRING: +# Set the CPUID vendor string returned by CPUID(0x80000002 .. 0x80000004). +# This should be at most a forty-eight-character ASCII string. +# +# STEPPING: +# Set stepping information returned by CPUID. Default stepping value is 3. +# +# CPUID_LIMIT_WINNT: +# Determine whether to limit maximum CPUID function to 3. This mode is +# required to workaround WinNT installation and boot issues. +#======================================================================= +#cpuid: mmx=1, sep=1, sse=sse4_2, xapic=1, aes=1, movbe=1, xsave=1 +#cpuid: stepping=5 +#cpuid: cpuid_limit_winnt=0 +#cpuid: mmx=1, sep=1, sse=sse4_2, xapic=1, aes=1, movbe=1, xsave=1 + +#======================================================================= +# MEMORY +# Set the amount of physical memory you want to emulate. +# +# GUEST: +# Set amount of guest physical memory to emulate. The default is 32MB, +# the maximum amount limited only by physical address space limitations. +# +# HOST: +# Set amount of host memory you want to allocate for guest RAM emulation. +# It is possible to allocate less memory than you want to emulate in guest +# system. This will fake guest to see the non-existing memory. Once guest +# system touches new memory block it will be dynamically taken from the +# memory pool. You will be warned (by FATAL PANIC) in case guest already +# used all allocated host memory and wants more. +# +#======================================================================= +memory: guest=128, host=1024 + +#======================================================================= +# OPTROMIMAGE[1-4]: +# You may now load up to 4 optional ROM images. Be sure to use a +# read-only area, typically between C8000 and EFFFF. These optional +# ROM images should not overwrite the rombios (located at +# F0000-FFFFF) and the videobios (located at C0000-C7FFF). +# Those ROM images will be initialized by the bios if they contain +# the right signature (0x55AA) and a valid checksum. +# It can also be a convenient way to upload some arbitrary code/data +# in the simulation, that can be retrieved by the boot loader +#======================================================================= +#optromimage1: file=optionalrom.bin, address=0xd0000 +#optromimage2: file=optionalrom.bin, address=0xd1000 +#optromimage3: file=optionalrom.bin, address=0xd2000 +#optromimage4: file=optionalrom.bin, address=0xd3000 + +#optramimage1: file=FoolData.img, address=0x90000 +#optramimage2: file=/path/file2.img, address=0x0020000 +#optramimage3: file=/path/file3.img, address=0x0030000 +#optramimage4: file=/path/file4.img, address=0x0040000 + +#======================================================================= +# VGAROMIMAGE +# You now need to load a VGA ROM BIOS into C0000. +#======================================================================= +#vgaromimage: file=/usr/share/vgabios/vgabios.bin +#vgaromimage: file=/usr/share/vgabios/vgabios.qxl.bin +#vgaromimage: file=/home/miguel/temp/vgabios-0.7a.bin +#vgaromimage: file=/home/miguel/temp/vgabios-0.7a.cirrus.bin +# +#vgaromimage: file=/usr/share/vgabios/vgabios.qxl.bin +#vgaromimage: file=/usr/share/vgabios/vgabios.debug.bin +#vgaromimage: file=/usr/share/vgabios/vgabios.cirrus.bin +#vgaromimage: file=/usr/share/bochs/VGABIOS-lgpl-latest +vgaromimage: file=/home/miguel/opt/bochs-2.6.6/bios/VGABIOS-lgpl-latest-cirrus + +#======================================================================= +# VGA: +# Here you can specify the display extension to be used. With the value +# 'none' you can use standard VGA with no extension. Other supported +# values are 'vbe' for Bochs VBE and 'cirrus' for Cirrus SVGA support. +#======================================================================= +#vga: extension=vbe +vga: extension=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' (or 'floppy'). +# +# You can set the initial status of the media to 'ejected' or 'inserted'. +# floppya: 2_88=path, status=ejected (2.88M 3.5" media) +# floppya: 1_44=path, status=inserted (1.44M 3.5" media) +# floppya: 1_2=path, status=ejected (1.2M 5.25" media) +# floppya: 720k=path, status=inserted (720K 3.5" media) +# floppya: 360k=path, status=inserted (360K 5.25" media) +# floppya: 320k=path, status=inserted (320K 5.25" media) +# floppya: 180k=path, status=inserted (180K 5.25" media) +# floppya: 160k=path, status=inserted (160K 5.25" media) +# floppya: image=path, status=inserted (guess media type from image size) +# floppya: 1_44=vvfat:path, status=inserted (use directory as VFAT media) +# floppya: type=1_44 (1.44M 3.5" floppy drive, no media) +# +# 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 win32 platforms, use drive letters +# such as a: or b: as the path. The parameter 'image' works with image files +# only. In that case the size must match one of the supported types. +# The parameter 'type' can be used to enable the floppy drive without media +# and status specified. Usually the drive type is set up based on the media type. +# The optional parameter 'write_protected' can be used to control the media +# write protect switch. By default it is turned off. +#======================================================================= +#floppya: 1_44=FoolOS.img, status=inserted +#floppya: image=../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, write_protected=1 +#floppya: 1_44=/dev/rfd0a, 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 addresses and the irq must be specified. +# +# ata0 and ata1 are enabled by default with the values shown below +# +# 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=0x3e0, irq=11 +# ata3: enabled=1, ioaddr1=0x168, ioaddr2=0x360, irq=9 +#======================================================================= +#ata0: enabled=1, ioaddr1=0x1f0, ioaddr2=0x3f0, irq=14 +#ata1: enabled=1, ioaddr1=0x170, ioaddr2=0x370, irq=15 +#ata2: enabled=0, ioaddr1=0x1e8, ioaddr2=0x3e0, irq=11 +#ata3: enabled=0, ioaddr1=0x168, ioaddr2=0x360, 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] +# mode= only valid for disks [flat|concat|external|dll|sparse|vmware3] +# mode= only valid for disks [undoable|growing|volatile|vvfat] +# path= path of the image / directory +# 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 translation of the bios, only for disks [none|lba|large|rechs|auto] +# model= string returned by identify device command +# journal= optional filename of the redolog for undoable, volatile and vvfat disks +# +# 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 is mandatory for hard disks. Disk geometry autodetection works with +# images created by bximage if CHS is set to 0/0/0 (cylinders are calculated +# using heads=16 and spt=63). For other hard disk images and modes the +# cylinders, heads, and spt are mandatory. In all cases the disk size reported +# from the image must be exactly C*H*S*512. +# +# Default values are: +# mode=flat, biosdetect=auto, translation=auto, model="Generic 1234" +# +# The biosdetect option has currently no effect on the bios +# +# Examples: + ata0-master: type=disk, mode=flat, path=FoolOS.img #, cylinders=10, heads=4, spt=18 +# ata0-master: type=disk, mode=flat, path=disk.img +# ata0-slave: type=disk, mode=flat, path=20M.sample, cylinders=615, heads=4, spt=17 +# ata1-master: type=disk, mode=flat, path=30M.sample, cylinders=615, heads=6, spt=17 +# ata1-slave: type=disk, mode=flat, path=46M.sample, cylinders=940, heads=6, spt=17 +# ata2-master: type=disk, mode=flat, path=62M.sample, cylinders=940, heads=8, spt=17 +# ata2-slave: type=disk, mode=flat, path=112M.sample, cylinders=900, heads=15, spt=17 +# ata3-master: type=disk, mode=flat, path=483M.sample, cylinders=1024, heads=15, spt=63 +# ata3-slave: type=cdrom, path=iso.sample, status=inserted +#======================================================================= +#ata0-master: type=disk, mode=flat, path="d.sample" +#ata0-master: type=disk, mode=flat, path="$HOME/.bochs/guest.hd0", cylinders=#cylinders#, heads=16, spt=63 +#ata0-master: type=disk, mode=flat, path="c.img", cylinders=0 # autodetect +#ata0-slave: type=disk, mode=vvfat, path=/bochs/images/vvfat, journal=vvfat.redolog +#ata0-slave: type=cdrom, path=/dev/cdrom, status=inserted + +#======================================================================= +# BOOT: +# This defines the boot sequence. Now you can specify up to 3 boot drives, +# which can be 'floppy', 'disk', 'cdrom' or 'network' (boot ROM). +# Legacy 'a' and 'c' are also supported. +# Examples: +# boot: floppy +# boot: cdrom, disk +# boot: network, disk +# boot: cdrom, floppy, disk +#======================================================================= +#boot: floppy +boot: disk +#boot: floppy + +#======================================================================= +# CLOCK: +# This defines the parameters of the clock inside Bochs: +# +# SYNC: +# This defines the method how to synchronize the Bochs internal time +# with realtime. With the value 'none' the Bochs time relies on the IPS +# value and no host time synchronization is used. The 'slowdown' method +# sacrifices performance to preserve reproducibility while allowing host +# time correlation. The 'realtime' method sacrifices reproducibility to +# preserve performance and host-time correlation. +# It is possible to enable both synchronization methods. +# +# TIME0: +# Specifies the start (boot) time of the virtual machine. Use a time +# value as returned by the time(2) system call. If no time0 value is +# set or if time0 equal to 1 (special case) or if time0 equal 'local', +# the simulation will be started at the current local host time. +# If time0 equal to 2 (special case) or if time0 equal 'utc', +# the simulation will be started at the current utc time. +# +# Syntax: +# clock: sync=[none|slowdown|realtime|both], time0=[timeValue|local|utc] +# +# Example: +# clock: sync=none, time0=local # Now (localtime) +# clock: sync=slowdown, time0=315529200 # Tue Jan 1 00:00:00 1980 +# clock: sync=none, time0=631148400 # Mon Jan 1 00:00:00 1990 +# clock: sync=realtime, time0=938581955 # Wed Sep 29 07:12:35 1999 +# clock: sync=realtime, time0=946681200 # Sat Jan 1 00:00:00 2000 +# clock: sync=none, time0=1 # Now (localtime) +# clock: sync=none, time0=utc # Now (utc/gmt) +# +# Default value are sync=none, time0=local +#======================================================================= +clock: sync=realtime, time0=local + + +#======================================================================= +# 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=0 + +#======================================================================= +# LOG: +# Give the path of the log file you'd like Bochs debug and misc. verbiage +# to be written to. If you don't use this option or set the filename to +# '-' the output is written to the console. If you really don't want it, +# make it "/dev/null" (Unix) or "nul" (win32). :^( +# +# Examples: +# log: ./bochs.out +# log: /dev/tty +#======================================================================= +#log: /dev/stdout +log: ./bochs.log + +#======================================================================= +# 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 cpu current eip (ignored in SMP configuration) +# %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=report +info: action=report +debug: action=report +#debug: action=report +#pass: action=fatal + +#======================================================================= +# 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, COM2, COM3, COM4: +# This defines a serial port (UART type 16550A). In the 'term' 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. +# In socket* and pipe* (win32 only) modes Bochs becomes either socket/named pipe +# client or server. In client mode it connects to an already running server (if +# connection fails Bochs treats com port as not connected). In server mode it +# opens socket/named pipe and waits until a client application connects to it +# before starting simulation. This mode is useful for remote debugging (e.g. +# with gdb's "target remote host:port" command or windbg's command line option +# -k com:pipe,port=\\.\pipe\pipename). Note: 'socket' is a shorthand for +# 'socket-client' and 'pipe' for 'pipe-client'. Socket modes use simple TCP +# communication, pipe modes use duplex byte mode pipes. +# Other serial modes are 'null' (no input/output), 'file' (output to a file +# specified as the 'dev' parameter), 'raw' (use the real serial port - under +# construction for win32), 'mouse' (standard serial mouse - requires +# mouse option setting 'type=serial', 'type=serial_wheel' or 'type=serial_msys'). +# +# Examples: +# com1: enabled=1, mode=null +# com1: enabled=1, mode=mouse +# com2: enabled=1, mode=file, dev=serial.out +# com3: enabled=1, mode=raw, dev=com1 +# com3: enabled=1, mode=socket-client, dev=localhost:8888 +# com3: enabled=1, mode=socket-server, dev=localhost:8888 +# com4: enabled=1, mode=pipe-client, dev=\\.\pipe\mypipe +# com4: enabled=1, mode=pipe-server, dev=\\.\pipe\mypipe +#======================================================================= +# com1: enabled=1, mode=term, dev=/dev/ttyS0 + + +#======================================================================= +# PARPORT1, PARPORT2: +# 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" +# parport2: enabled=1, file="/dev/lp0" +# parport1: enabled=0 +#======================================================================= +# parport1: enabled=1, file="/dev/lp0" + +#======================================================================= +# 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=resource changes, 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-continuous sound. 750000 is usually a good value. This needs a +# reasonably correct setting for the IPS parameter of the CPU option. +# +# Examples for output devices: +# sb16: midimode=1, midi="", wavemode=1, wave="" # win32 +# sb16: midimode=1, midi=alsa:128:0, wavemode=1, wave=alsa # Linux with ALSA +#======================================================================= +#sb16: midimode=1, midi=/dev/midi00, wavemode=1, wave=/dev/dsp, loglevel=2, log=/dev/stdout, dmatimer=600000 + +#======================================================================= +# VGA_UPDATE_INTERVAL: +# Video memory is scanned for updates and screen updated every so many +# virtual seconds. The default is 50000, about 20Hz. Keep in mind that +# you must tweak the 'cpu: ips=N' 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_interval: 40000 + +# 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_serial_delay: 250 + +#======================================================================= +# KEYBOARD_PASTE_DELAY: +# Approximate time in microseconds between attempts to paste +# characters to the keyboard controller. This leaves time for the +# guest os to deal with the flow of characters. The ideal setting +# depends on how your operating system processes characters. The +# default of 100000 usec (.1 seconds) was chosen because it works +# consistently in Windows. +# +# If your OS is losing characters during a paste, increase the paste +# delay until it stops losing characters. +# +# Examples: +# keyboard_paste_delay: 100000 +#======================================================================= +keyboard_paste_delay: 100000 + +#======================================================================= +# MOUSE: +# This defines parameters for the emulated mouse type, the initial status +# of the mouse capture and the runtime method to toggle it. +# +# TYPE: +# With the mouse type option you can select the type of mouse to emulate. +# The default value is 'ps2'. The other choices are 'imps2' (wheel mouse +# on PS/2), 'serial', 'serial_wheel' and 'serial_msys' (one com port requires +# setting 'mode=mouse'). To connect a mouse to an USB port, see the 'usb_uhci' +# or 'usb_ohci' option (requires PCI and USB support). +# +# ENABLED: +# The Bochs gui creates mouse "events" unless the 'enabled' option is +# set to 0. The hardware emulation itself is not disabled by this. +# Unless you have a particular reason for enabling the mouse by default, +# it is recommended that you leave it off. You can also toggle the mouse +# usage at runtime (RFB, SDL, Win32, wxWidgets and X11 - see below). +# +# TOGGLE: +# The default method to toggle the mouse capture at runtime is to press the +# CTRL key and the middle mouse button ('ctrl+mbutton'). This option allows +# to change the method to 'ctrl+f10' (like DOSBox), 'ctrl+alt' (like QEMU) +# or 'f12' (replaces win32 'legacyF12' option). +# +# Examples: +# mouse: enabled=1 +# mouse: type=imps2, enabled=1 +# mouse: type=serial, enabled=1 +# mouse: enabled=0, toggle=ctrl+f10 +#======================================================================= +mouse: enabled=1 + +#======================================================================= +# 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 + +#======================================================================= +# ne2k: NE2000 compatible ethernet adapter +# +# Examples: +# ne2k: ioaddr=IOADDR, irq=IRQ, mac=MACADDR, ethmod=MODULE, ethdev=DEVICE, script=SCRIPT +# +# ioaddr, irq: You probably won't need to change ioaddr and irq, unless there +# are IRQ conflicts. These arguments are ignored when assign the ne2k to a +# PCI slot. +# +# mac: The MAC address MUST NOT match the address of any machine on the net. +# Also, the first byte must be an even number (bit 0 set means a multicast +# address), and you cannot use ff:ff:ff:ff:ff:ff because that's the broadcast +# address. For the ethertap module, you must use fe:fd:00:00:00:01. There may +# be other restrictions too. To be safe, just use the b0:c4... address. +# +# ethdev: The ethdev value is the name of the network interface on your host +# platform. On UNIX machines, you can get the name by running ifconfig. On +# Windows machines, you must run niclist to get the name of the ethdev. +# Niclist source code is in misc/niclist.c and it is included in Windows +# binary releases. +# +# script: The script value is optional, and is the name of a script that +# is executed after bochs initialize the network interface. You can use +# this script to configure this network interface, or enable masquerading. +# This is mainly useful for the tun/tap devices that only exist during +# Bochs execution. The network interface name is supplied to the script +# as first parameter +# +# If you don't want to make connections to any physical networks, +# you can use the following 'ethmod's to simulate a virtual network. +# null: All packets are discarded, but logged to a few files. +# arpback: ARP is simulated. Disabled by default. +# vde: Virtual Distributed Ethernet +# vnet: ARP, ICMP-echo(ping), DHCP and read/write TFTP are simulated. +# The virtual host uses 192.168.10.1. +# DHCP assigns 192.168.10.2 to the guest. +# TFTP uses the ethdev value for the root directory and doesn't +# overwrite files. +# +#======================================================================= +# ne2k: ioaddr=0x300, irq=9, mac=b0:c4:20:00:00:00, ethmod=linux, ethdev=eth0 +# ne2k: ioaddr=0x300, irq=9, mac=fe:fd:00:00:00:01, ethmod=tap, ethdev=tap0 +# ne2k: ioaddr=0x300, irq=9, mac=fe:fd:00:00:00:01, ethmod=tuntap, ethdev=/dev/net/tun0, script=./tunconfig +# ne2k: ioaddr=0x300, irq=9, mac=b0:c4:20:00:00:01, ethmod=null, ethdev=eth0 +# ne2k: ioaddr=0x300, irq=9, mac=b0:c4:20:00:00:01, ethmod=vde, ethdev="/tmp/vde.ctl" +# ne2k: ioaddr=0x300, irq=9, mac=b0:c4:20:00:00:01, ethmod=vnet, ethdev="c:/temp" + +#======================================================================= +# pnic: Bochs/Etherboot pseudo-NIC +# +# Example: +# pnic: enabled=1, mac=MACADDR, ethmod=MODULE, ethdev=DEVICE, script=SCRIPT +# +# The pseudo-NIC accepts the same syntax (for mac, ethmod, ethdev, script) and +# supports the same networking modules as the NE2000 adapter. In addition to +# this, it must be assigned to a PCI slot. +#======================================================================= +#pnic: enabled=1, mac=b0:c4:20:00:00:00, ethmod=vnet + +#======================================================================= +# KEYBOARD_MAPPING: +# This enables a remap of a physical localized keyboard to a +# virtualized us keyboard, as the PC architecture expects. +# If enabled, the keymap file must be specified. +# +# Examples: +# keyboard_mapping: enabled=1, map=gui/keymaps/x11-pc-de.map +#======================================================================= +#keyboard_mapping: enabled=0, map=/usr/share/bochs/keymaps/x11-pc-de.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 is a combination of maximum +# 3 key names (listed below) separated with a '-' character. +# Valid key names: +# "alt", "bksl", "bksp", "ctrl", "del", "down", "end", "enter", "esc", +# "f1", ... "f12", "home", "ins", "left", "menu", "minus", "pgdwn", "pgup", +# "plus", "right", "shift", "space", "tab", "up", "win", "print" and "power". +# +# Example: +# user_shortcut: keys=ctrl-alt-del +#======================================================================= +#user_shortcut: keys=ctrl-alt-del + +#======================================================================= +# I440FXSUPPORT: +# This option controls the presence of the i440FX PCI chipset. You can +# also specify the devices connected to PCI slots. Up to 5 slots are +# available now. These devices are currently supported: ne2k, pcivga, +# pcidev, pcipnic and usb_ohci. If Bochs is compiled with Cirrus SVGA +# support you'll have the additional choice 'cirrus'. +# +# Example: +# i440fxsupport: enabled=1, slot1=pcivga, slot2=ne2k +#======================================================================= +#i440fxsupport: enabled=1 + +#======================================================================= +# USB_UHCI: +# This option controls the presence of the USB root hub which is a part +# of the i440FX PCI chipset. With the portX parameter you can connect devices +# to the hub (currently supported: 'mouse', 'tablet', 'keypad', 'disk', 'cdrom' +# 'hub' and 'printer'). +# +# The optionsX parameter can be used to assign specific options to the device +# connected to the corresponding USB port. Currently this feature is only used +# to set the speed reported by device and by the 'disk' device to specify +# an alternative redolog file of some image modes. +# +# If you connect the mouse or tablet to one of the ports, Bochs forwards the +# mouse movement data to the USB device instead of the selected mouse type. +# When connecting the keypad to one of the ports, Bochs forwards the input of +# the numeric keypad to the USB device instead of the PS/2 keyboard. +# +# To connect a 'flat' mode image as an USB hardisk you can use the 'disk' device +# with the path to the image separated with a colon. To use other disk image modes +# similar to ATA disks the syntax 'disk:mode:filename' must be used (see below). +# +# To emulate an USB cdrom you can use the 'cdrom' device name and the path to +# an ISO image or raw device name also separated with a colon. An option to +# insert/eject media is available in the runtime configuration. +# +# The device name 'hub' connects an external hub with max. 8 ports (default: 4) +# to the root hub. To specify the number of ports you have to add the value +# separated with a colon. Connecting devices to the external hub ports is only +# available in the runtime configuration. +# +# The device 'printer' emulates the HP Deskjet 920C printer. The PCL data is +# sent to a file specified in bochsrc.txt. The current code appends the PCL +# code to the file if the file already existed. It would probably be nice to +# overwrite the file instead, asking user first. +#======================================================================= +#usb_uhci: enabled=1 +#usb_uhci: enabled=1, port1=mouse, port2=disk:usbstick.img +#usb_uhci: enabled=1, port1=hub:7, port2=disk:growing:usbdisk.img +#usb_uhci: enabled=1, port2=disk:undoable:usbdisk.img, options1=journal:redo.log +#usb_uhci: enabled=1, port1=printer:printdata.bin, port2=cdrom:image.iso + +#======================================================================= +# USB_OHCI: +# This option controls the presence of the USB OHCI host controller with a +# 2-port hub. The portX option accepts the same device types with the same +# syntax as the UHCI controller (see above). The OHCI HC must be assigned to +# a PCI slot. +#======================================================================= +#usb_ohci: enabled=1 +#usb_ohci: enabled=1, port1=printer:usbprinter.bin + +#======================================================================= +# CMOSIMAGE: +# This defines image file that can be loaded into the CMOS RAM at startup. +# The rtc_init parameter controls whether initialize the RTC with values stored +# in the image. By default the time0 argument given to the clock option is used. +# With 'rtc_init=image' the image is the source for the initial time. +# +# Example: +# cmosimage: file=cmos.img, rtc_init=image +#======================================================================= +#cmosimage: file=cmos.img, rtc_init=time0 + +#======================================================================= +# MAGIC_BREAK: +# This enables the "magic breakpoint" feature when using the debugger. +# The useless cpu instruction XCHG BX, BX causes Bochs to enter the +# debugger mode. This might be useful for software development. +# +# Example: +# magic_break: enabled=1 +#======================================================================= +#magic_break: enabled=1 + +#======================================================================= +# PORT_E9_HACK: +# The 0xE9 port doesn't exists in normal ISA architecture. However, we +# define a convention here, to display on the console of the system running +# Bochs anything that is written to it. The idea is to provide debug output +# very early when writing BIOS or OS code for example, without having to +# bother with setting up a serial port or etc. Reading from port 0xE9 will +# will return 0xe9 to let you know if the feature is available. +# Leave this 0 unless you have a reason to use it. +# +# Example: +# port_e9_hack: enabled=1 +#======================================================================= +#port_e9_hack: enabled=1 + +#======================================================================= +# DEBUG_SYMBOLS: +# This loads symbols from the specified file for use in Bochs' internal +# debugger. Symbols are loaded into global context. This is equivalent to +# issuing ldsym debugger command at start up. +# +# Example: +# debug_symbols: file="kernel.sym" +# debug_symbols: file="kernel.sym", offset=0x80000000 +#======================================================================= +#debug_symbols: file="kernel.sym" + +#======================================================================= +# other stuff +#======================================================================= +#load32bitOSImage: os=nullkernel, path=../kernel.img, iolog=../vga_io.log +#load32bitOSImage: os=linux, path=../linux.img, iolog=../vga_io.log, initrd=../initrd.img +#text_snapshot_check: enabled=1 +#print_timestamps: enabled=1 + +#------------------------- +# PCI host device mapping +#------------------------- +#pcidev: vendor=0x1234, device=0x5678 + +#======================================================================= +# GDBSTUB: +# Enable GDB stub. See user documentation for details. +# Default value is enabled=0. +#======================================================================= +#gdbstub: enabled=0, port=1234, text_base=0, data_base=0, bss_base=0 + +#======================================================================= +# PLUGIN_CTRL: +# Controls the presence of optional plugins without a separate option. +# By default all existing plugins are enabled. These plugins are currently +# supported: 'acpi', 'biosdev', 'extfpuirq', 'gameport', 'iodebug', +# 'pci_ide', 'speaker' and 'unmapped'. +#======================================================================= +#plugin_ctrl: biosdev=0, speaker=0 + +#======================================================================= +# USER_PLUGIN: +# Load user-defined plugin. This option is available only if Bochs is +# compiled with plugin support. Maximum 8 different plugins are supported. +# See the example in the Bochs sources how to write a plugin device. +#======================================================================= +#user_plugin: name=testdev +# +# +# +## +pci: enabled=1, chipset=i440fx, slot1=cirrus +#i440fxsupport: enabled=1, slot1=cirrus +e1000: enabled=1, mac=52:54:00:12:34:56 #, ethmod=slirp, script=slirp.conf + + diff --git a/xxx/boot1/Makefile b/xxx/boot1/Makefile new file mode 100644 index 0000000..b9b2e24 --- /dev/null +++ b/xxx/boot1/Makefile @@ -0,0 +1,13 @@ +#master boot record + +include ../Makefile.common + +MBR=mbr.bin + +ASM_SOURCES=$(wildcard *.asm) + +$(MBR): $(ASM_SOURCES) + +clean: + -rm $(MBR) + diff --git a/xxx/boot1/disk_load_16.asm b/xxx/boot1/disk_load_16.asm new file mode 100644 index 0000000..6d1e4b3 --- /dev/null +++ b/xxx/boot1/disk_load_16.asm @@ -0,0 +1,103 @@ +; +;disk_load_16 +; + +[bits 16] + +STR_LBA: + db "LBA Support Detected",0 + +STR_CHS: + db "No CHS Support!)",0 + +STR_ERROR: + db "Disk Read Error",0 + +STR_DONE: + db "Stage 2 Loaded",0 + +disk_load_16: + + pusha + + ; check if LBA is supported + mov ah,0x41 + mov bx,0x55aa + int 0x13 + jnc disk_load_lba + jmp disk_load_chs + +disk_load_lba: + + mov bx, STR_LBA + call print_string + call print_nextline + + mov dl,[BOOT_DRIVE] + xor ah,ah + mov ah,0x42 + + mov bx,0 + mov ds,bx + lea si,[lba_adr] + + int 0x13 + jnc disk_load_finish + jmp disk_load_error + +disk_load_chs: + + mov bx, STR_CHS + call print_string + call print_nextline + jmp $ + + mov bx,0 ;target es:bx + mov es,bx + mov bx,0x7e00 + + mov al,50 ;number of sectors to read + mov ah,0x02 ;BIOS read sector func + + mov cl,2 ; sector + mov ch,0 ; cylinder + + mov dl,[BOOT_DRIVE] + mov dh,0 ;head + + int 0x13 ;bios interrupt + + jnc disk_load_finish + +disk_load_error: + + call print_nextline + mov bx, STR_ERROR + call print_string + call print_nextline + jmp $ + +disk_load_finish: + + call print_nextline + mov bx, STR_DONE + call print_string + call print_nextline + + + popa + ret + + +;; here we hold the lba addr +lba_adr: + + dw 0x10 ; size of packet ( 16 byte) + dw 16 ; number of sectors to read + + ; target is 0x7e00 + dw 0x7e00 ; target addr. offset + dw 0x0000 ; target addr. sector + + dd 1 ; first sector to read + dd 0 diff --git a/xxx/boot1/mbr.asm b/xxx/boot1/mbr.asm new file mode 100644 index 0000000..c0a555d --- /dev/null +++ b/xxx/boot1/mbr.asm @@ -0,0 +1,106 @@ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; +; FOOL-OS Master Boot Record +; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; +; This is the Master Boot Record for x86 +; +; We are limited to 512 bytes (one sector) +; minus 64 bytes for the partition table +; minus 2 bytes formagic number (0xaa55) +; +; all we do here is : +; +; 1. Put the Stack at 0x07bff (it is counting down) +; 2. Remeber Boot Drive at [BOOT_DRIVE] +; 3. Print PR message and Boot Drive number +; 4. Load Second Stage Bootloader from Boot Drive at next sector +; 5. Show Info Message after successfull loading +; 6. Jump to 2nd Stage Boot Loader +; +; Refer to a memory map as needed: +; http://wiki.osdev.org/Memory_Map_(x86) + +; Everything here is 16bit +[bits 16] + +; Per definition this will be loaded by the BIOS at 0x7c00 +[org 0x7c00] + +; skip constants and includes +jmp stage1 + +; string constants (null terminated) +STR_1: db "Fool Loader Stage 1. v0.1",0 +STR_2: db "Starting Stage 2",0 +STR_BOOT: db "Boot drive: ",0 + +; some space (one byte) to remember the Boot Drive +BOOT_DRIVE: db 0xff + +; include print and disk load routines +%include "print_string_16.asm" +%include "disk_load_16.asm" + +; Here we start! +stage1: + + ; first of all, setup the stack (right under our MBR) + ; ~30KB space guaranteed + mov bp,0x07bff + mov sp,bp + + ; remember BOOT_DRIVE (as was set by BIOS in dl) + mov [BOOT_DRIVE],dl + + ; clear screen and print PR message + call print_clear + call print_nextline + + mov bx, STR_1 + call print_string + call print_nextline + + + ; print bootdrive number + mov bx, STR_BOOT + call print_string + + mov al,[BOOT_DRIVE] + call print_hex_byte + call print_nextline + + + ; Actually Load the Second Stage Bootloader! + call disk_load_16 + + + ; show info message that 2nd Stage was loaded + mov bx, STR_2 + call print_string + call print_nextline + call print_nextline + + + ; save Boot Drive in dl for second stage + mov dl,[BOOT_DRIVE] + + + ; jump to the next sector where we loaded the 2nd stage + jmp 0x7e00 + + + ; nothing essential under this line + ; we need this to follow some mbr standards + + ; fill at least 4x16byte with zeroes. (partition table) + ; (otherwise my Acer Aspire will not boot) + times 64 db 0x0 + + ; fill rest with zeroes + times 510-($-$$) db 0x0 + + ; magic number so we get identified as MBR + dw 0xaa55 + diff --git a/xxx/boot1/print_string_16.asm b/xxx/boot1/print_string_16.asm new file mode 100644 index 0000000..9f81a87 --- /dev/null +++ b/xxx/boot1/print_string_16.asm @@ -0,0 +1,115 @@ +[bits 16] + +BLANK: + db 0x12 + +SPACE: + db " ",0 + +;print_string routine ([bx]) +;this routine will print a null terminated string at [bx] to the screen. +print_string: + + pusha ;push all registers + mov ah,0x0e + + print_string_loop: + + ;check if value at [bx] is "\0" (end of string) + mov cl,[bx] + cmp cl,0 + je print_string_finish + + ;otherwise instruct BIOS to print the current char + mov al,cl + int 0x10 + + ;proceed with next char + inc bx + jmp print_string_loop + + print_string_finish: + + popa ;pop all registers + ret ;return to caller + +print_clear: + +pusha + mov ah,0x6 ;func + mov al,0 ;scroll one line + mov bh,[BLANK] ;blank char + + mov ch,0 ;upper left corner + mov cl,0 + mov dh,20 ;lower right corner + mov dl,40 + int 0x10 + + mov ah,0x2 + mov bh,0 + mov dl,0 + mov dh,20 + int 0x10 +popa + +print_nextline: + + pusha + + mov ah,0x6 ;func + mov al,1 ;scroll one line + mov bh,[BLANK] ;blank char + + mov ch,0 ;upper left corner + mov cl,0 + mov dh,20 ;lower right corner + mov dl,40 + int 0x10 + + + mov ah,0x3 + mov bh,0 + int 0x10 + + + mov ah,0x2 + mov dl,0 + int 0x10 + + mov bx,SPACE + call print_string + + popa + ret + + +;print byte from al to screen + print_hex_byte: + + pusha + + mov [.temp],al + shr al,4 + cmp al,10 + sbb al,69h + das + + mov ah,0Eh + int 10h + + mov al,[.temp] + ror al,4 + shr al,4 + cmp al,10 + sbb al,69h + das + + mov ah,0Eh + int 10h + +popa + + ret + + .temp db 0 diff --git a/xxx/boot2/GDT.asm b/xxx/boot2/GDT.asm new file mode 100644 index 0000000..4c14b46 --- /dev/null +++ b/xxx/boot2/GDT.asm @@ -0,0 +1,77 @@ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;; Miguel's FoolOS Helper Functions ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; +; Global Descriptor Table +; we have the null descriptor and a code and data block for a start +; +; 0x80 code segment +; 0x10 data segment +; +; this file contains pure data +; +; +; +; +global gdt_descriptor + +gdt_start: + +gdt_null: ;null descriptor (2 x 4 bytes) + dd 0x0 + dd 0x0 + +gdt_code: + ; flags: + ; present: 1 / privilege: 00 / type: 1 + ; code: 1 / conforming: 0 / readable: 1 / accessed: 0 + ; granularity: 1 / 16-bit default: 1 / 64-bit seg: 0 / AVL: 0 + dw 0xffff ;limit + dw 0x0 ;base + db 0x0 ;base + db 10011010b ;flags + db 11001111b ;flags & seg.limit + db 0x0 ;base + +gdt_data: + ; flags: + ; code: 0 / expand down: 0 / writable: 1 / accessed: 0 + dw 0xffff + dw 0x0 + db 0x0 + db 10010010b + db 11001111b + db 0x0 + +gdt16_code: + ; flags: + ; present: 1 / privilege: 00 / type: 1 + ; code: 1 / conforming: 0 / readable: 1 / accessed: 0 + ; granularity: 1 / 16-bit default: 1 / 64-bit seg: 0 / AVL: 0 + dw 0xffff ;limit + dw 0x0 ;base + db 0x0 ;base + db 10011010b ;flags + db 10001111b ;flags & seg.limit + db 0x0 ;base + +gdt16_data: + ; flags: + ; code: 0 / expand down: 0 / writable: 1 / accessed: 0 + dw 0xffff + dw 0x0 + db 0x0 + db 10010010b + db 10001111b + db 0x0 + +gdt_end: + +gdt_descriptor: + dw gdt_end-gdt_start-1 + dd gdt_start + +CODE_SEG equ gdt_code - gdt_start +DATA_SEG equ gdt_data - gdt_start +CODE16_SEG equ gdt16_code - gdt_start +DATA16_SEG equ gdt16_data - gdt_start diff --git a/xxx/boot2/Makefile b/xxx/boot2/Makefile new file mode 100644 index 0000000..f2537ce --- /dev/null +++ b/xxx/boot2/Makefile @@ -0,0 +1,28 @@ +#master boot record + +include ../Makefile.common + +.PHONY: all clean + +STAGE2=stage2.bin +MP=mp.bin +CONFIG=config.inc + + + +ASM_SOURCES=$(wildcard *.asm) + +all: $(STAGE2) $(MP) + +$(CONFIG): ../kernel/config.h + cat ../kernel/config.h | grep "^#define" | sed -e "s/#/%/" -e "s/\/\/.*//" > $@ + +$(STAGE2): $(ASM_SOURCES) $(CONFIG) +$(MP): $(ASM_SOURCES) + +clean: + -rm $(STAGE2) $(MP) $(CONFIG) + + + + diff --git a/xxx/boot2/check_a20_16.asm b/xxx/boot2/check_a20_16.asm new file mode 100644 index 0000000..43da6e3 --- /dev/null +++ b/xxx/boot2/check_a20_16.asm @@ -0,0 +1,61 @@ +; The following code is public domain licensed + +[bits 16] + +; Function: check_a20 +; +; Purpose: to check the status of the a20 line in a completely self-contained state-preserving way. +; The function can be modified as necessary by removing push's at the beginning and their +; respective pop's at the end if complete self-containment is not required. +; +; Returns: 0 in ax if the a20 line is disabled (memory wraps around) +; 1 in ax if the a20 line is enabled (memory does not wrap around) + +check_a20: + pushf + push ds + push es + push di + push si + + cli + + xor ax, ax ; ax = 0 + mov es, ax + + not ax ; ax = 0xFFFF + mov ds, ax + + mov di, 0x0500 + mov si, 0x0510 + + mov al, byte [es:di] + push ax + + mov al, byte [ds:si] + push ax + + mov byte [es:di], 0x00 + mov byte [ds:si], 0xFF + + cmp byte [es:di], 0xFF + + pop ax + mov byte [ds:si], al + + pop ax + mov byte [es:di], al + + mov ax, 0 + je check_a20__exit + + mov ax, 1 + +check_a20__exit: + pop si + pop di + pop es + pop ds + popf + + ret diff --git a/xxx/boot2/common_pm.asm b/xxx/boot2/common_pm.asm new file mode 100644 index 0000000..c96e1a8 --- /dev/null +++ b/xxx/boot2/common_pm.asm @@ -0,0 +1,86 @@ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;; Miguel's FoolOS Helper Functions ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; +;print_string_pm +;print_hex_pm +; +; +; + +[bits 32] + +VIDEO_MEM equ 0xb8000 +WHITE_ON_BLACK equ 0x0f + +;global data +STR_HEX_OUT_PM: + db "0x0000",0 + +; print [ebx] at ecx +print_string_pm: + pusha + mov edx, VIDEO_MEM + add edx,ecx + print_string_pm_loop: + mov al,[ebx] + mov ah, WHITE_ON_BLACK + cmp al,0 + je print_string_pm_done + mov [edx],ax + add ebx,1 + add edx,2 + jmp print_string_pm_loop + +print_string_pm_done: + popa + ret + +;print_hex_pm routine (dx) at ecx +;will print the value of the bx register as hex to the screen +print_hex_pm: + + pusha + + + ;begin with last hex val (hex_out[5]) + mov bx,STR_HEX_OUT_PM+5 + + ;lets loop throuth all 4 'digits' + print_hex_pm_loop: + + ;get least significan hex digit to cx + mov cx,dx + and cx,0x000F + + ;check range (0-9 vs a-f) + cmp cx,10 + jl print_hex_pm_setnum + + ;set hex a-f + mov al,'A'-10 + add al,cl + jmp print_hex_pm_al + + ;set hex 0-9 + print_hex_pm_setnum: + mov al,'0' + add al,cl + + ; set hex_out[bx] to al + print_hex_pm_al: + mov [bx],al + + ;proceed with the next significant hex 'digit' + dec bx + shr dx,4 + + ;check if finished (otherwise loop) + cmp bx,STR_HEX_OUT_PM+1 + jne print_hex_pm_loop + + ;output complete hex string and return to caller + popa + mov bx,STR_HEX_OUT_PM + call print_string_pm + ret diff --git a/xxx/boot2/disk_load_16.asm b/xxx/boot2/disk_load_16.asm new file mode 100644 index 0000000..65b1bff --- /dev/null +++ b/xxx/boot2/disk_load_16.asm @@ -0,0 +1,281 @@ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;; Miguel's FoolOS Helper Functions ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; +;disk_load_16 +; + +[bits 16] + +STR_ERROR: + db "Disk Read Error",0 + +STR_SPACE: + db " ",0 + +STR_OK: + db "Kernel Loaded",0 +STR_PROGRESS: + db ".",0 + +bpbSectorsPerTrack: + dw 18 + +bpbHeadsPerCylinder: + dw 2 + +LBA: + dw 10 ; current lba + +disk_load_16: + + ; check if LBA is supported + mov ah,0x41 + mov bx,0x55aa + int 0x13 + jnc disk_load_lba + jmp disk_load_chs + + +;####################### + +disk_load_lba: + + pusha + + mov bx,0x1800 ;target es:bx + mov es,bx + mov bx,0 + + next_sectors_lba: + + jmp skip_debug_lba + ;show es - target + pusha + mov bx,es + + ;mov al,bh + ;call print_hex_byte + + ;mov al,bl + ;call print_hex_byte + + mov bx,[LBA] + + mov al,bh + call print_hex_byte + + mov al,bl + call print_hex_byte + + popa + ;-- + + skip_debug_lba: + + mov [lba_addr_sector],es + mov ax,[LBA] + mov [lba_first_sector],ax + + mov dl,[BOOT_DRIVE] + + mov ah,0x42 + mov bx,0 + mov ds,bx + lea si,[lba_adr] + int 0x13 + jc disk_read_error + + mov bx,es + add bx,0x0800 + + mov ax,[LBA] + add ax,64 ; 64 sectors = 0x2000*4 bytes + mov [LBA],ax + + cmp bx,0x9000 + je disk_load_finish + + mov es,bx ;next target es:bx + mov bx,0 + + jmp next_sectors_lba + +;####################### + + +disk_load_chs: + + pusha + + ; get boot drive geometry + mov ah,8 + mov dl,[BOOT_DRIVE] + int 0x13 + + add dh,1 + and cl,0x3f + + mov [bpbSectorsPerTrack],cl + mov [bpbHeadsPerCylinder],dh + ; + + ;show geometry + mov al,dh + call print_hex_byte + + mov bx, STR_SPACE + call print_string + + mov al,cl + call print_hex_byte + + call print_nextline + popa + ; + + pusha + + + mov bx,0x1800 ;target es:bx + mov es,bx + mov bx,0 + + next_sectors_chs: + + ;jmp skip_debug + pusha + + mov bx, STR_SPACE + call print_string + + ;show es - target + mov bx,es + + mov al,bh + call print_hex_byte + + mov al,bl + call print_hex_byte + + mov bx, STR_SPACE + call print_string + + ;show next LBA numer + mov ax,[LBA] + mov al,ah + call print_hex_byte + + mov ax,[LBA] + call print_hex_byte + + mov bx, STR_SPACE + call print_string + + popa + + mov ax,[LBA] + + ;calculate chs + call lba_to_chs + + ;show chs sector/ head / cylinder + mov al,cl + call print_hex_byte + + mov al,dh + call print_hex_byte + + mov al,ch + call print_hex_byte + + call print_nextline + + skip_debug: + + + mov ax,[LBA] + + ;calculate chs + call lba_to_chs + + ; and now READ it! + mov al,1 ;number of sectors to read + mov dl,[BOOT_DRIVE] + + mov ah,0x02 ;BIOS read sector func + int 0x13 ;bios interrupt + + jc disk_read_error + + mov bx,es + add bx,0x0020 + cmp bx,0x9000 + je disk_load_finish + + mov es,bx + mov bx,0 + + mov ax,[LBA] + add ax,1 + mov [LBA],ax + + jmp next_sectors_chs + +disk_read_error: + mov bx, STR_ERROR + call print_string + call print_nextline + ;jmp $ + +disk_load_finish: + + mov bx, STR_PROGRESS + call print_string +; call print_nextline + + popa + ret + + + +;lba to chs translation: +; input : ax - lba +; output: cl - sector +; dh - head +; ch - cylinder / track + +lba_to_chs: + + xor dx, dx ; prepare dx:ax for operation + div WORD [bpbSectorsPerTrack] ; divide by sectors per track + inc dl ; add 1 (obsolute sector formula) + mov cl, dl + + xor dx, dx ; prepare dx:ax for operation + div WORD [bpbHeadsPerCylinder] ; mod by number of heads (Absolue head formula) + mov dh,dl ; everything else was already done from the first formula + + mov ch, al ; not much else to do :) + ret + +;; here we hold the lba addr +lba_adr: + + dw 0x10 ; size of packet ( 16 byte) + dw 64 ; number of sectors to read + + ; target is 0x10000 + + dw 0x0000 ; target addr. offset + +lba_addr_sector: + dw 0x1800 ; target addr. sector + +lba_first_sector: + dw 10 ; first sector to read + dw 0 + + dd 0 + + ; diff --git a/xxx/boot2/memmap.asm b/xxx/boot2/memmap.asm new file mode 100644 index 0000000..d101557 --- /dev/null +++ b/xxx/boot2/memmap.asm @@ -0,0 +1,57 @@ +;--------------------------------------------- +; Get memory map from bios +; /in es:di->destination buffer for entries +; /ret bp=entry count +;--------------------------------------------- + +; stolen from: http://www.brokenthorn.com/Resources/OSDev17.html +struc MemoryMapEntry + .baseAddress resq 1 ; base address of address range + .length resq 1 ; length of address range in bytes + .type resd 1 ; type of address range + .acpi_null resd 1 ; reserved +endstruc + +[bits 16] + +BiosGetMemoryMap: + pushad + xor ebx, ebx + xor bp, bp ; number of entries stored here + mov edx, 'PAMS' ; 'SMAP' + mov eax, 0xe820 + mov ecx, 24 ; memory map entry struct is 24 bytes + int 0x15 ; get first entry + jc .error + cmp eax, 'PAMS' ; bios returns SMAP in eax + jne .error + test ebx, ebx ; if ebx=0 then list is one entry long; bail out + je .error + jmp .start +.next_entry: + mov edx, 'PAMS' ; some bios's trash this register + mov ecx, 24 ; entry is 24 bytes + mov eax, 0xe820 + int 0x15 ; get next entry +.start: + jcxz .skip_entry ; if actual returned bytes is 0, skip entry +.notext: + mov ecx, [es:di + MemoryMapEntry.length] ; get length (low dword) + test ecx, ecx ; if length is 0 skip it + jne short .good_entry + mov ecx, [es:di + MemoryMapEntry.length + 4]; get length (upper dword) + jecxz .skip_entry ; if length is 0 skip it +.good_entry: + inc bp ; increment entry count + add di, 24 ; point di to next entry in buffer +.skip_entry: + cmp ebx, 0 ; if ebx return is 0, list is done + jne .next_entry ; get next entry + jmp .done +.error: + stc +.done: + + mov [MEMMAP_SIZE_OFFSET],bp + popad + ret diff --git a/xxx/boot2/mp.asm b/xxx/boot2/mp.asm new file mode 100644 index 0000000..b6efd04 --- /dev/null +++ b/xxx/boot2/mp.asm @@ -0,0 +1,37 @@ +; other processors will enter here! +[org 0x7000] ; here the binary will be loaded + +[bits 16] + + cli ;switch off interrupts! + lgdt [gdt_descriptor] ;load descriptor table! + + ;switch on 32-bit protected mode + mov eax, cr0 + or eax,0x1 + mov cr0, eax + + jmp 0x8:init_pm + +[bits 32] +init_pm: + + mov ax, 0x10 + mov ds, ax + mov ss, ax + mov es, ax + mov fs, ax + mov gs, ax + + mov ebp, 0x95000 + mov esp, ebp + + call boot_32_pm ;continue booting in 32-bit protected mode + +boot_32_pm: + + mov eax,1 +; + call 0x18000 ;jump into our Kernel! + +%include "GDT.asm" diff --git a/xxx/boot2/pm.asm b/xxx/boot2/pm.asm new file mode 100644 index 0000000..e6f3474 --- /dev/null +++ b/xxx/boot2/pm.asm @@ -0,0 +1,36 @@ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;; Miguel's FoolOS Helper Functions ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; +; switch_to_pm - actual switch from 16bit real to 32bit protected +; init_pm - sets up some regs and calls boot_32_pm +; + +[bits 16] +switch_to_pm: + + cli ;switch off interrupts! + lgdt [gdt_descriptor] ;load descriptor table! +; lldt [gdt_descriptor] ;load descriptor table! (local) + + ;switch on 32-bit protected mode + mov eax, cr0 + or eax,0x1 + mov cr0, eax + + jmp CODE_SEG:init_pm + +[bits 32] +init_pm: + + mov ax, DATA_SEG + mov ds, ax + mov ss, ax + mov es, ax + mov fs, ax + mov gs, ax + + mov ebp, 0x07bff + mov esp, ebp + + call boot_32_pm ;continue booting in 32-bit protected mode diff --git a/xxx/boot2/print_string_16.asm b/xxx/boot2/print_string_16.asm new file mode 100644 index 0000000..9f81a87 --- /dev/null +++ b/xxx/boot2/print_string_16.asm @@ -0,0 +1,115 @@ +[bits 16] + +BLANK: + db 0x12 + +SPACE: + db " ",0 + +;print_string routine ([bx]) +;this routine will print a null terminated string at [bx] to the screen. +print_string: + + pusha ;push all registers + mov ah,0x0e + + print_string_loop: + + ;check if value at [bx] is "\0" (end of string) + mov cl,[bx] + cmp cl,0 + je print_string_finish + + ;otherwise instruct BIOS to print the current char + mov al,cl + int 0x10 + + ;proceed with next char + inc bx + jmp print_string_loop + + print_string_finish: + + popa ;pop all registers + ret ;return to caller + +print_clear: + +pusha + mov ah,0x6 ;func + mov al,0 ;scroll one line + mov bh,[BLANK] ;blank char + + mov ch,0 ;upper left corner + mov cl,0 + mov dh,20 ;lower right corner + mov dl,40 + int 0x10 + + mov ah,0x2 + mov bh,0 + mov dl,0 + mov dh,20 + int 0x10 +popa + +print_nextline: + + pusha + + mov ah,0x6 ;func + mov al,1 ;scroll one line + mov bh,[BLANK] ;blank char + + mov ch,0 ;upper left corner + mov cl,0 + mov dh,20 ;lower right corner + mov dl,40 + int 0x10 + + + mov ah,0x3 + mov bh,0 + int 0x10 + + + mov ah,0x2 + mov dl,0 + int 0x10 + + mov bx,SPACE + call print_string + + popa + ret + + +;print byte from al to screen + print_hex_byte: + + pusha + + mov [.temp],al + shr al,4 + cmp al,10 + sbb al,69h + das + + mov ah,0Eh + int 10h + + mov al,[.temp] + ror al,4 + shr al,4 + cmp al,10 + sbb al,69h + das + + mov ah,0Eh + int 10h + +popa + + ret + + .temp db 0 diff --git a/xxx/boot2/stage2.asm b/xxx/boot2/stage2.asm new file mode 100644 index 0000000..160d75c --- /dev/null +++ b/xxx/boot2/stage2.asm @@ -0,0 +1,267 @@ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; +; THE FOOL-BOOT-LOADER +; +; * X sectors of our kernel loaded at KERNEL_OFFSET from floppy +; +; * memory map made available at MEMMAP_OFFSET +; (check at MEMMEP_SIZE_OFFSET for number of entries) +; +; * the VESA mode specified by VESA_MODE_SELECT will be set up +; (check at VESA_MODES, and VESA_MODE_INFO +; for additional information) +; +; * interrupts disabled +; +; * 32-bit protected mode set up. +; +; * esp set under MBR +; +; * A20 gate opened +; +; * and finally we will jump into the C world to kernel_main() ! +; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + + +;we want 16-bit instructions, before we switch to 32-bit protected mode. +[bits 16] + +;define origin of boot record in memory: 0x7c00 was bootloader0 +;this is where the BIOS per definition will put the first +;512 bytes of data from the boot device +;wer are one sector after that. +[org 0x7e00] + +;;define some constants +;;where we will load our kernel into memory and some +;;other memory locations +; +MEMMAP_SIZE_OFFSET equ 0xa000 +MEMMAP_OFFSET equ 0xa001 + +VESA_MODES equ 0xb000 ; do NOT overwrite yourself! be careful! +VESA_MODE_INFO equ 0xc000 + +VESA_MODE_SELECT equ 0x4114 +CHUNKS_TO_LOAD equ 0x20 ;number of 0x8000 * 512 byte chunks to load into ram +; + +jmp boot_16 ;start boot process + +;;SOME Global Data, mainly info/error strings +FILL: + times 32 db 0x66 + +BOOT_DRIVE: + db 0xff + +LOADER_TARGET: + dd 0x100000 ;here we will put our image + +KERNEL_CHUNK: + dw 0x1 +STR_VERSION: + db "Fool Loader Stage 2 v0.5",0 + +STR_LOAD: + db "Loading Kernel...",0 +STR_BOOT: + db "Boot Drive: ",0 +MEMMAP_INFO: + db "Getting Memory Map from BIOS.",0 +STR_PM: + db "PROTECTED MODE",0 + +; kernel config +%include "config.inc" + +; +;;lets put our temporary GDT (Global Descriptor Table) here +;;kernel should move this away +%include "GDT.asm" +; +;;include 16-bit real mode routines (print_string, disk_load, vesa_setup,check_a20) +%include "disk_load_16.asm" +;%include "boot/check_a20_16.asm" +%include "print_string_16.asm" +%include "vesa_setup_16.asm" +; +;;include our routines for switching to 32-bit protected mode +%include "pm.asm" + +;include some pm mode helpers +%include "common_pm.asm" + +; +; +; +;;get memory map routine +%include "memmap.asm" +; +;;;;;;;;; BOOT 16-bit real ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; +;;lets start +[bits 16] + +idt_real: + dw 0x3ff ; 256 entries, 4b each = 1K + dd 0 ; Real Mode IVT @ 0x0000 + +boot_16: + + mov [BOOT_DRIVE],dl + + + ; hide text-mode cursor + mov ah,0x01 + mov cx,0x2607 + int 0x10 + + + ;pr info + mov bx, STR_VERSION + call print_string + call print_nextline + + ;show bootdrive + mov bx, STR_BOOT + call print_string + mov al,dl + call print_hex_byte + call print_nextline + + + ; memmap message + mov bx,MEMMAP_INFO + call print_string + call print_nextline + + ;get memory map from bios before we enter 32 bit protected mode + mov ax,0 ; set target address in es:di (0:offset) + mov es,ax + mov di,MEMMAP_OFFSET + call BiosGetMemoryMap ; this will also put the number of entries + ; of the memory map at MEMMAP_SIZE_OFFSET + + ; Load the KERNEL Image + mov bx, STR_LOAD + call print_string + call print_nextline + +kernel_load: + + call disk_load_16 + + + + ; init vesa on last iteration! + mov ax,[KERNEL_CHUNK] + cmp ax,(CHUNKS_TO_LOAD-1) + jne skip_vesa_init + + %ifndef FOOLOS_CONSOLE + call VesaSetup + %endif + + skip_vesa_init: + + call switch_to_pm +; +;;;;;;;;; BOOT 32-bit protected mode;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +[bits 32] +boot_32_pm: + + ;Fast A20 Gate: + ;http://wiki.osdev.org/A20_Line + in al, 0x92 + or al, 2 + out 0x92, al + + ; tell the world we are protected + ;mov ebx,STR_PM + ;mov ecx,2*23*80 + ;call print_string_pm + + ;increment chunk number + mov ax,[KERNEL_CHUNK] + add ax,1 + mov [KERNEL_CHUNK],ax + + ;check if all chunkgs loaded (hardcoded to 0x6 for a start) + ;each chunk is 0x8000 * 15 bytes + cmp ax,CHUNKS_TO_LOAD + je finish_load + + ; show KERNEL CHUNK value +; push edx ; persist edx for some reason!? +; mov edx,0 +; mov dx,[KERNEL_CHUNK] +; mov ecx,2*24*80 +; call print_hex_pm +; pop edx + + + ; here we actually do copy the chunk into ext mem! + mov eax,[LOADER_TARGET] + mov ebx,0x18000 + + copy_next_byte: + + mov ecx,[ebx] + mov [eax],ecx + + inc eax + inc ebx + cmp ebx, 0x90000 + + jne copy_next_byte + mov [LOADER_TARGET],eax ;persist next target address + + + ; and now go back to real! (first 16bit protected!) + jmp CODE16_SEG:reinit_16 + + finish_load: + ; + + ; call kernel! + mov eax,0 ;tell the kernel + ; we are the booting processor + jmp 0x100000 ;jump into our Kernel! + + +[bits 16] +reinit_16: ;16 bit protected mode + + mov eax,DATA16_SEG + mov ds,eax + mov es,eax + mov fs,eax + mov gs,eax + mov ss,eax + + + mov eax,cr0 + and eax,!0x1 ; Disable protected mode + mov cr0, eax + + jmp 0:realmode + + +realmode: + + mov sp,0x07000 + mov bp,sp + + mov ax,0 + mov ds,ax + mov es,ax + mov fs,ax + mov gs,ax + mov ss,ax + + lidt [idt_real] + + sti + jmp kernel_load diff --git a/xxx/boot2/vesa_setup_16.asm b/xxx/boot2/vesa_setup_16.asm new file mode 100644 index 0000000..5bee57c --- /dev/null +++ b/xxx/boot2/vesa_setup_16.asm @@ -0,0 +1,93 @@ +VESA_CHECK1: + db "VESA: get modes!",0 +VESA_CHECK2: + db "VESA: get info on target mode!",0 +VESA_CHECK3: + db "VESA: switching to target mode!",0 +VESA_PAUSE: + db "[Press any key to switch to VESA 0x114]",0 + +VesaSetup: + + pusha + + ;VESA: get all available vesa modes! + mov ax,0 ; set target address in es:di (0:offset) + mov es,ax + mov di,VESA_MODES + mov ax,0x4f00 ;vesa function: Get Controller Info + int 0x10 ; call the interrupt to get the data from the bios! + vesa_err: + mov bx, VESA_CHECK1 + call print_string + call print_nextline + cmp ax,0x004f + je vesa_ok + jmp vesa_err + vesa_ok: + ; + + + ;VESA: get vesa info on mode of interest + mov ax,0 ; set target address in es:di (0:offset) + mov es,ax + mov di,VESA_MODE_INFO + mov ax,0x4f01 ;vesa function: Get Mode Info + mov cx,VESA_MODE_SELECT + int 0x10 ; call the interrupt to get the data from the bios! + vesa_err2: + mov bx, VESA_CHECK2 + call print_string + call print_nextline + cmp ax,0x004f + je vesa_ok2 + jmp vesa_err2 + vesa_ok2: + + ;show press any key +; call print_nextline +; mov bx, VESA_PAUSE +; call print_string +; call print_nextline + + ;preempt keyboard buffer + + next_key: + + mov ah,0x1 ;get scnacode from kb (non-blocking) + int 0x16 + jnz get_key ; nothing to preempt + + jmp wait_key + + get_key: + mov ah,0 ;get key from buffer + int 0x16 + +; mov al,ah +; call print_hex_byte +; call print_nextline + + jmp next_key + + ;;;;;;;;;;;;;;;;; + wait_key: +; mov ah,0 ; block waiting for keyboard scancode +; int 0x16 + + + ;VESA: finally switch to the mode of choice! + mov ax,0x4f02 ;vesa function: Set Mode + mov bx,VESA_MODE_SELECT + + int 0x10 + cmp ax,0x004f + je vesa_ok3 + vesa_err3: + mov bx, VESA_CHECK3 + call print_string + call print_nextline + jmp vesa_err3 + vesa_ok3: + popa + ret diff --git a/xxx/inactive/acpi.c b/xxx/inactive/acpi.c new file mode 100644 index 0000000..b42f628 --- /dev/null +++ b/xxx/inactive/acpi.c @@ -0,0 +1,171 @@ +// Advanced Configuration and Power Interface +// http://wiki.xomb.org/index.php?title=ACPI_Tables + +#define FOOLOS_MODULE_NAME "acpi" + +#include "lib/logger/log.h" +#include "lib/int/stdint.h" +#include "lib/bool/bool.h" +#include "lib/string/string.h" +#include "smp.h" + + +typedef struct acpi_rsdt_struct +{ + char sig[4]; + uint32_t length; + uint8_t revision; + uint8_t checksum; + char oemid[6]; + char oemtabid[8]; + uint32_t oemrevision; + uint32_t vendor; + uint32_t rev; +}acpi_rsdt; + +typedef struct aspi_rsdp_struct +{ + char sig[8]; //signature + uint8_t checksum; + char oem[6]; + uint8_t revision; + + uint32_t ptr_rsdt; + uint32_t length; + + uint64_t ptr_xsdt; //same info but with 64bit pointers (preferred) + uint8_t checksum_ext; + uint8_t reserved[3]; + +}acpi_rsdp; + +typedef struct +{ + char sig[4]; + uint32_t length; + uint8_t rev; + uint8_t checksum; + char oemid[6]; + char oemtableid[8]; + char oemrev[4]; + char creatorid[4]; + char creatorrev[4]; + uint32_t apic_local; + uint32_t flags; + +}acpi_madt; + +uint8_t *apci_get_next_entry(uint8_t *addr,smp_processors *procdata) +{ + + log(FOOLOS_MODULE_NAME,FOOLOS_LOG_DEBUG,"Examining MADT Entry at 0x%08X",addr); + + if(*addr==0) + { + log(FOOLOS_MODULE_NAME,FOOLOS_LOG_INFO,"MADT Entry: LocalAPIC"); + // usable + if(addr[4]&1) + { + if(procdata->processors>=SMP_MAX_PROC){ + + panic(FOOLOS_MODULE_NAME,"we do not support that many processors. recompile with higher SMP_MAX_PROC."); + } + + procdata->local_apic_id[procdata->processors]=addr[3]; + procdata->processors++; + } + + } + else if(*addr==1) + { + log(FOOLOS_MODULE_NAME,FOOLOS_LOG_INFO,"MADT Entry: IO APIC"); + } + else if(*addr==2)log(FOOLOS_MODULE_NAME,FOOLOS_LOG_INFO,"MADT Entry: Interrupt Source Override"); + else log(FOOLOS_MODULE_NAME,FOOLOS_LOG_INFO,"MADT Entry: type:0x%X",*addr); + + return addr+addr[1]; +} + + +void acpi_check_madt(uint32_t *madt,smp_processors *procdata) +{ + acpi_madt *table=(acpi_madt *)*madt; + + log(FOOLOS_MODULE_NAME,FOOLOS_LOG_DEBUG,"Looking for MADT Table at %08X.",table); + if(strcmp("APIC",table->sig,4)) + { + log(FOOLOS_MODULE_NAME,FOOLOS_LOG_INFO,"Found MADT Table at 0x%08X",table); + uint8_t *end=(uint8_t *)table; + end+=table->length; + + uint8_t *entry=(uint8_t *)table; + entry+=sizeof(acpi_madt); + + procdata->local_apic_address=table->apic_local; + + while(entry<end) + { + entry=apci_get_next_entry(entry,procdata); + } + + + } +} + +void acpi_read_rsdt(acpi_rsdt *rsdt,smp_processors *procdata) +{ + log(FOOLOS_MODULE_NAME,FOOLOS_LOG_INFO,"Reading RSDT Table at 0x%08X",rsdt); + + if(!strcmp("RSDT",rsdt->sig,4)) + panic(FOOLOS_MODULE_NAME,"Signature MISMATCH!"); + + int entries=(rsdt->length-sizeof(acpi_rsdt))/4; + uint32_t *first=(uint32_t *)rsdt; + first+=sizeof(acpi_rsdt)/4; + + log(FOOLOS_MODULE_NAME,FOOLOS_LOG_INFO,"Entries: %d",entries); + log(FOOLOS_MODULE_NAME,FOOLOS_LOG_INFO,"Looking for MADT Table"); + for(int i=0;i<entries;i++) + { + + acpi_check_madt(first,procdata); + first++; + } + +} + +// search for the RSDB table in +// 0x7ffff - 0x9ffff (max) +// 0xe0000 - 0xfffff + +bool acpi_find(smp_processors *procdata) +{ + log(FOOLOS_MODULE_NAME,FOOLOS_LOG_INFO,"Looking for RSDP Table"); + char *search=(char *)0x9f000; //will be 16 bit aligned; + procdata->processors=0; + procdata->boot=0; + + while(search<=(char *)0xfffff) + { + if(strcmp("RSD PTR ",search,8)) // notice trailing space in "RSD PTR " + { + uint8_t checksum=0; + for(int i=0;i<20;i++) + checksum+=search[i]; + + if(checksum==0) + { + log(FOOLOS_MODULE_NAME,FOOLOS_LOG_INFO,"RSDP Table found at 0x%08X",search); + acpi_rsdp *rsdp=(acpi_rsdp *)search; + acpi_read_rsdt(rsdp->ptr_rsdt,procdata); + return true; + } + } + + search++; + + if(search==0xa0000)search=0xe0000; + + } + return false; +} diff --git a/xxx/inactive/acpi.h b/xxx/inactive/acpi.h new file mode 100644 index 0000000..b7c7342 --- /dev/null +++ b/xxx/inactive/acpi.h @@ -0,0 +1,2 @@ +#include "smp.h" +bool acpi_find(smp_processors *procdata); diff --git a/xxx/inactive/e1000.c b/xxx/inactive/e1000.c new file mode 100644 index 0000000..99194be --- /dev/null +++ b/xxx/inactive/e1000.c @@ -0,0 +1,4 @@ + +void init_e1000() +{ +} diff --git a/xxx/inactive/e1000.h b/xxx/inactive/e1000.h new file mode 100644 index 0000000..5413fe1 --- /dev/null +++ b/xxx/inactive/e1000.h @@ -0,0 +1 @@ +void init_e1000(); diff --git a/xxx/inactive/floppy.c b/xxx/inactive/floppy.c new file mode 100644 index 0000000..1dbe137 --- /dev/null +++ b/xxx/inactive/floppy.c @@ -0,0 +1,575 @@ + +/* + * Fool OS Simple Floppy Driver. + * + * coded by M.idziorek <m.i@gmx.at> on 20th of august 2014 A.D + * + * tested in : bochs, qemu and virutalbox so far + * + * resources: + * + * * http://wiki.osdev.org/Floppy_Disk_Controller#DMA_Data_Transfers + * * http://forum.osdev.org/viewtopic.php?f=1&t=13538 + * * http://www.brokenthorn.com/Resources/OSDev20.html + * * http://bochs.sourceforge.net/cgi-bin/lxr/source/iodev/floppy.cc + * * http://viralpatel.net/taj/tutorial/chs_translation.php + * + */ + +#define FOOLOS_MODULE_NAME "floppy" +#include "config.h" + +#ifdef FOOLOS_COMPILE_FLOPPY + +#include "lib/logger/log.h" + +#include "x86.h" + +#define FLPY_SECTORS_PER_TRACK 18 + +void flpydsk_send_command (uint8_t cmd); +void flpydsk_wait_irq (); +void flpydsk_check_int (uint32_t* st0, uint32_t* cyl); + +static volatile int _CurrentDrive=0; +static volatile uint8_t _FloppyDiskIRQ; + +// temporary dma hack +//! initialize DMA to use phys addr 1k-64k +void flpydsk_initialize_dma () { + + x86_outb (0x0a,0x06); //mask dma channel 2 + + x86_outb (0xd8,0xff); //reset master flip-flop + + //changed to 0x000 (Address) + x86_outb (0x04, 0x00); //low + x86_outb (0x04, 0x05); //high + x86_outb (0x81,0x00); //page reg + + x86_outb (0xd8, 0xff); //reset master flip-flop + + // x86_outb (0x05, 0xff); //count to 0x23ff (number of bytes in a 3.5" floppy disk track) +// x86_outb (0x05, 0x23); +// hey, lets do just ONE sector instead (0x200) + x86_outb (0x05, 0xff); //low + x86_outb (0x05, 0x01); //high + + x86_outb (0x80, 0); //external page register = 0 + + x86_outb (0x0a, 0x02); //unmask dma channel 2 + log("dma",FOOLOS_LOG_INFO,"initialized"); +} + +//! prepare the DMA for read transfer +void flpydsk_dma_read () { + x86_outb (0x0a, 0x06); //mask dma channel 2 + + x86_outb (0x0b, 0x56); //single transfer, address increment, autoinit, read, channel 2 + + x86_outb (0x0a, 0x02); //unmask dma channel 2 + log("dma",FOOLOS_LOG_INFO,"configured for reading"); +} + +//! prepare the DMA for write transfer +void flpydsk_dma_write () { + + x86_outb (0x0a, 0x06); //mask dma channel 2 + x86_outb (0x0b, 0x5a); //single transfer, address increment, autoinit, write, channel 2 + x86_outb (0x0a, 0x02); //unmask dma channel 2 + log("dma",FOOLOS_LOG_INFO,"configured for writing"); +} +// +// + +enum FLPYDSK_IO { + + FLPYDSK_DOR = 0x3f2, + FLPYDSK_MSR = 0x3f4, + FLPYDSK_FIFO = 0x3f5, //data register + FLPYDSK_CTRL = 0x3f7 +}; + +enum FLPYDSK_DOR_MASK { + + FLPYDSK_DOR_MASK_DRIVE0 = 0, //00000000 = here for completeness sake + FLPYDSK_DOR_MASK_DRIVE1 = 1, //00000001 + FLPYDSK_DOR_MASK_DRIVE2 = 2, //00000010 + FLPYDSK_DOR_MASK_DRIVE3 = 3, //00000011 + FLPYDSK_DOR_MASK_RESET = 4, //00000100 + FLPYDSK_DOR_MASK_DMA = 8, //00001000 + FLPYDSK_DOR_MASK_DRIVE0_MOTOR = 16, //00010000 + FLPYDSK_DOR_MASK_DRIVE1_MOTOR = 32, //00100000 + FLPYDSK_DOR_MASK_DRIVE2_MOTOR = 64, //01000000 + FLPYDSK_DOR_MASK_DRIVE3_MOTOR = 128 //10000000 +}; + +enum FLPYDSK_MSR_MASK { + + FLPYDSK_MSR_MASK_DRIVE1_POS_MODE = 1, //00000001 + FLPYDSK_MSR_MASK_DRIVE2_POS_MODE = 2, //00000010 + FLPYDSK_MSR_MASK_DRIVE3_POS_MODE = 4, //00000100 + FLPYDSK_MSR_MASK_DRIVE4_POS_MODE = 8, //00001000 + FLPYDSK_MSR_MASK_BUSY = 16, //00010000 + FLPYDSK_MSR_MASK_DMA = 32, //00100000 + FLPYDSK_MSR_MASK_DATAIO = 64, //01000000 + FLPYDSK_MSR_MASK_DATAREG = 128 //10000000 +}; + +enum FLPYDSK_CMD { + + FDC_CMD_READ_TRACK = 2, + FDC_CMD_SPECIFY = 3, + FDC_CMD_CHECK_STAT = 4, + FDC_CMD_WRITE_SECT = 5, + FDC_CMD_READ_SECT = 6, + FDC_CMD_CALIBRATE = 7, + FDC_CMD_CHECK_INT = 8, + FDC_CMD_WRITE_DEL_S = 9, + FDC_CMD_READ_ID_S = 0xa, + FDC_CMD_READ_DEL_S = 0xc, + FDC_CMD_FORMAT_TRACK = 0xd, + FDC_CMD_SEEK = 0xf +}; + +enum FLPYDSK_CMD_EXT { + + FDC_CMD_EXT_SKIP = 0x20, //00100000 + FDC_CMD_EXT_DENSITY = 0x40, //01000000 + FDC_CMD_EXT_MULTITRACK = 0x80 //10000000 +}; + +enum FLPYDSK_GAP3_LENGTH { + + FLPYDSK_GAP3_LENGTH_STD = 42, + FLPYDSK_GAP3_LENGTH_5_14= 32, + FLPYDSK_GAP3_LENGTH_3_5= 27 +}; + +enum FLPYDSK_SECTOR_DTL { + + FLPYDSK_SECTOR_DTL_128 = 0, + FLPYDSK_SECTOR_DTL_256 = 1, + FLPYDSK_SECTOR_DTL_512 = 2, + FLPYDSK_SECTOR_DTL_1024 = 4 +}; + +void flpydsk_write_dor (uint8_t val ) { + + //! write the digital output register + x86_outb (FLPYDSK_DOR, val); + +} + +void flpydsk_write_ccr (uint8_t val) { + + //! write the configuation control + x86_outb (FLPYDSK_CTRL, val); +} + + +void flpydsk_motor_on() +{ + log(FOOLOS_MODULE_NAME,FOOLOS_LOG_DEBUG,"starting motor..."); + //x86_outb (FLPYDSK_DOR, FLPYDSK_DOR_MASK_DRIVE0_MOTOR | FLPYDSK_DOR_MASK_RESET); + x86_outb (FLPYDSK_DOR, 0x1c); + sleep(10); // wait ~ 1/3 second +} + +void flpydsk_motor_off() +{ + log(FOOLOS_MODULE_NAME,FOOLOS_LOG_DEBUG,"stopping motor..."); + x86_outb (FLPYDSK_DOR, 0x0c); +} + +int flpydsk_calibrate (uint32_t drive) { + + uint32_t st0, cyl; + + if (drive >= 4) + { + + log(FOOLOS_MODULE_NAME,FOOLOS_LOG_INFO,"ERROR!"); + return -2; + } + + //! turn on the motor + flpydsk_motor_on(); + + int i; + for (i = 0; i < 10; i++) { + + log(FOOLOS_MODULE_NAME,FOOLOS_LOG_DEBUG,"calibrating"); + //! send command + flpydsk_send_command ( FDC_CMD_CALIBRATE ); + flpydsk_send_command ( drive ); + flpydsk_wait_irq (); + flpydsk_check_int ( &st0, &cyl); + + //! did we fine cylinder 0? if so, we are done + if (!cyl) { + if(st0 & 0xC0) { + log(FOOLOS_MODULE_NAME,FOOLOS_LOG_INFO,"calibrating FAILED!"); + } + // flpydsk_control_motor (false); + flpydsk_motor_off(); + return 0; + } + } + log(FOOLOS_MODULE_NAME,FOOLOS_LOG_INFO,"calibrating FAILED!"); + +// flpydsk_control_motor (false); + flpydsk_motor_off(); + return -1; +} + + + +void flpydsk_disable_controller () { + + flpydsk_write_dor (0); +} + +void flpydsk_enable_controller () { + + flpydsk_write_dor ( FLPYDSK_DOR_MASK_RESET | FLPYDSK_DOR_MASK_DMA); +} + + +uint8_t flpydsk_read_status () { + + //! just return main status register + return x86_inb (FLPYDSK_MSR); +} + +uint8_t flpydsk_read_data () { + + //! same as above function but returns data register for reading + int i; + for (i = 0; i < 500; i++ ) + if ( flpydsk_read_status () & FLPYDSK_MSR_MASK_DATAREG ) + return x86_inb (FLPYDSK_FIFO); + + log(FOOLOS_MODULE_NAME,FOOLOS_LOG_INFO,"reading data FAILED!"); +} +void flpydsk_send_command (uint8_t cmd) { + + //! wait until data register is ready. We send commands to the data register + int i; + for (i = 0; i < 500; i++ ) + if ( flpydsk_read_status () & FLPYDSK_MSR_MASK_DATAREG ) + { + x86_outb(FLPYDSK_FIFO, cmd); + return; + } + log(FOOLOS_MODULE_NAME,FOOLOS_LOG_INFO,"writing data FAILED!"); +} + +void flpydsk_drive_data (uint32_t stepr, uint32_t loadt, uint32_t unloadt, int dma ) { + + uint32_t data = 0; + + flpydsk_send_command (FDC_CMD_SPECIFY); + + data = ( (stepr & 0xf) << 4) | (unloadt & 0xf); + flpydsk_send_command (data); + + data = (loadt) << 1 | dma; + flpydsk_send_command (data); +} + +void flpydsk_reset() +{ + uint32_t st0, cyl; + + //! reset the controller + log(FOOLOS_MODULE_NAME,FOOLOS_LOG_DEBUG,"reset controller"); + flpydsk_disable_controller (); + flpydsk_enable_controller (); + flpydsk_wait_irq (); + + //! send CHECK_INT/SENSE INTERRUPT command to all drives + int i; + for (i=0; i<4; i++) + flpydsk_check_int (&st0,&cyl); + + //! transfer speed 500kb/s + flpydsk_write_ccr (0); + + //! pass mechanical drive info. steprate=3ms, unload time=240ms, load time=16ms +// flpydsk_drive_data (3,16,240,0); +// + + flpydsk_send_command (FDC_CMD_SPECIFY); + flpydsk_send_command (0xdf); /* steprate = 3ms, unload time = 240ms */ + flpydsk_send_command (0x02); /* load time = 16ms, no-DMA = 0 */ + + //! calibrate the disk + flpydsk_calibrate ( _CurrentDrive ); +} + +void int_floppy_handler() +{ + X86_IRQ_BEGIN + _FloppyDiskIRQ=1; + X86_IRQ_END +} + +void flpydsk_wait_irq() +{ + log(FOOLOS_MODULE_NAME,FOOLOS_LOG_FINE,"waiting for irq6"); + + while (1) + { + sleep(2); + x86_int_disable(); + if(_FloppyDiskIRQ==1)break; + x86_int_enable(); + + } + _FloppyDiskIRQ = 0; + x86_int_enable(); + + log(FOOLOS_MODULE_NAME,FOOLOS_LOG_FINE,"irq6 received"); +} + +void flpydsk_check_int (uint32_t* st0, uint32_t* cyl) { + + flpydsk_send_command (FDC_CMD_CHECK_INT); + + *st0 = flpydsk_read_data (); + *cyl = flpydsk_read_data (); +} + +void flpydsk_write_sector_imp (uint8_t head, uint8_t track, uint8_t sector) { + + //sector=1; + //! set the DMA for read transfer + flpydsk_dma_write (); + + //flpydsk_drive_data (13, 1, 0xf, 0); + log(FOOLOS_MODULE_NAME,FOOLOS_LOG_DEBUG,"writing head/track/sector"); + + uint32_t st0, cyl; + + //! write a sector + flpydsk_send_command ( + FDC_CMD_WRITE_SECT | FDC_CMD_EXT_MULTITRACK | + FDC_CMD_EXT_DENSITY); + flpydsk_send_command ( head << 2 | _CurrentDrive ); + flpydsk_send_command ( track); + flpydsk_send_command ( head); // first head should match with above! + flpydsk_send_command ( sector); + flpydsk_send_command ( FLPYDSK_SECTOR_DTL_512 ); + //flpydsk_send_command ( 1 ); // number of tracks we want + flpydsk_send_command ( FLPY_SECTORS_PER_TRACK ); // number of tracks ! + + /* + flpydsk_send_command ( + ( ( sector + 1 ) >= FLPY_SECTORS_PER_TRACK ) + ? FLPY_SECTORS_PER_TRACK : sector + 1 ); + */ + + flpydsk_send_command ( FLPYDSK_GAP3_LENGTH_3_5 ); + flpydsk_send_command ( 0xff ); + + //! wait for irq + flpydsk_wait_irq (); + + //! read status info + int j; + for (j=0; j<7; j++) + flpydsk_read_data (); + + //! let FDC know we handled interrupt + flpydsk_check_int (&st0,&cyl); +} +void flpydsk_read_sector_imp (uint8_t head, uint8_t track, uint8_t sector) { + + //sector=1; + //! set the DMA for read transfer + flpydsk_dma_read (); + + //flpydsk_drive_data (13, 1, 0xf, 0); + log(FOOLOS_MODULE_NAME,FOOLOS_LOG_DEBUG,"reading head/track/sector"); + + uint32_t st0, cyl; + + //! read in a sector + flpydsk_send_command ( + FDC_CMD_READ_SECT | FDC_CMD_EXT_MULTITRACK | + FDC_CMD_EXT_SKIP | FDC_CMD_EXT_DENSITY); + flpydsk_send_command ( head << 2 | _CurrentDrive ); + flpydsk_send_command ( track); + flpydsk_send_command ( head); + flpydsk_send_command ( sector); + flpydsk_send_command ( FLPYDSK_SECTOR_DTL_512 ); + //flpydsk_send_command ( 1 ); // number of tracks we want + flpydsk_send_command ( FLPY_SECTORS_PER_TRACK ); // number of tracks ! + + /* + flpydsk_send_command ( + ( ( sector + 1 ) >= FLPY_SECTORS_PER_TRACK ) + ? FLPY_SECTORS_PER_TRACK : sector + 1 ); + */ + + + flpydsk_send_command ( FLPYDSK_GAP3_LENGTH_3_5 ); + flpydsk_send_command ( 0xff ); + + //! wait for irq + flpydsk_wait_irq (); + + //! read status info + int j; + for (j=0; j<7; j++) + flpydsk_read_data (); + + //! let FDC know we handled interrupt + flpydsk_check_int (&st0,&cyl); +} + +int flpydsk_seek ( uint32_t cyl, uint32_t head ) +{ + //cyl=1; + //head=1; + + uint32_t st0, cyl0; + + if (_CurrentDrive >= 4) + return -1; + + int i; + for (i = 0; i < 10; i++ ) { + + log(FOOLOS_MODULE_NAME,FOOLOS_LOG_DEBUG,"seeking cyl: %d, head: %d",cyl,head); + + //! send the command + flpydsk_send_command (FDC_CMD_SEEK); + flpydsk_send_command ( (head << 2) | _CurrentDrive); + flpydsk_send_command (cyl); + + + //! wait for the results phase IRQ + flpydsk_wait_irq (); + flpydsk_check_int (&st0,&cyl0); + + //! found the cylinder? + if ( cyl0 == cyl) + return 0; + } + + return -1; +} + +void flpydsk_lba_to_chs (int lba,int *head,int *track,int *sector) { + + //cylinder + // +// *track = lba % ( FLPY_SECTORS_PER_TRACK * 2 ); + /// *head = ( lba % FLPY_SECTORS_PER_TRACK ) % 2;//* 2 ) ) / ( FLPY_SECTORS_PER_TRACK ); + //*sector = (lba % FLPY_SECTORS_PER_TRACK) +1; + + *head = ( lba % ( FLPY_SECTORS_PER_TRACK * 2 ) ) / ( FLPY_SECTORS_PER_TRACK ); + *track = lba / ( FLPY_SECTORS_PER_TRACK * 2 ); + *sector = lba % FLPY_SECTORS_PER_TRACK + 1; +} + + +uint8_t* flpydsk_read_sector (int sectorLBA) { + + log(FOOLOS_MODULE_NAME,FOOLOS_LOG_DEBUG,"reading sector: %d",sectorLBA); + + + if (_CurrentDrive >= 4) + return 0; + + //! convert LBA sector to CHS + int head=0, track=0, sector=1; + flpydsk_lba_to_chs (sectorLBA, &head, &track, §or); + + + //! turn motor on and seek to track + // start motor + flpydsk_motor_on(); + + if (flpydsk_seek (track, head) != 0) + return 0; + + //! read sector and turn motor off + flpydsk_read_sector_imp (head, track, sector); + // flpydsk_control_motor (false); + flpydsk_motor_off(); + + + //! warning: this is a bit hackish + //return (uint8_t*) DMA_BUFFER; + return (uint8_t*) 0x0; +} + +uint8_t* flpydsk_write_sector (int sectorLBA) { + + log(FOOLOS_MODULE_NAME,FOOLOS_LOG_DEBUG,"writing sector: %d",sectorLBA); + + if (_CurrentDrive >= 4) + return 0; + + //! convert LBA sector to CHS + int head=0, track=0, sector=1; + flpydsk_lba_to_chs (sectorLBA, &head, &track, §or); + + + //! turn motor on and seek to track + // start motor + flpydsk_motor_on(); + + if (flpydsk_seek (track, head) != 0) + return 0; + + //! read sector and turn motor off + flpydsk_write_sector_imp (head, track, sector); + // flpydsk_control_motor (false); + flpydsk_motor_off(); + + + //! warning: this is a bit hackish + //return (uint8_t*) DMA_BUFFER; + return (uint8_t*) 0x0; +} + +void floppy_init() +{ + // init dma + flpydsk_initialize_dma (); + + _CurrentDrive=0; + _FloppyDiskIRQ = 0; + + log(FOOLOS_MODULE_NAME,FOOLOS_LOG_INFO,"driver init (wathchdog: 0x%08X)",&_FloppyDiskIRQ); + + + flpydsk_reset (); + + char *dma=0x0500; + + log(FOOLOS_MODULE_NAME,FOOLOS_LOG_INFO,"test reading"); + + flpydsk_read_sector(65); + log(FOOLOS_MODULE_NAME,FOOLOS_LOG_INFO,"finished reading"); + + flpydsk_reset (); + + flpydsk_read_sector(64); + log(FOOLOS_MODULE_NAME,FOOLOS_LOG_INFO,"finished reading"); + log(FOOLOS_MODULE_NAME,FOOLOS_LOG_INFO,"test read: %s",dma); + + flpydsk_reset (); + +// log(FOOLOS_MODULE_NAME,FOOLOS_LOG_INFO,"test write (sector: 100)"); +// flpydsk_write_sector(100); +// log(FOOLOS_MODULE_NAME,FOOLOS_LOG_INFO,"finished writing"); + + +} + +#endif diff --git a/xxx/inactive/floppy.h b/xxx/inactive/floppy.h new file mode 100644 index 0000000..c149a3a --- /dev/null +++ b/xxx/inactive/floppy.h @@ -0,0 +1 @@ +void int_floppy_handler(); diff --git a/xxx/inactive/mouse.c b/xxx/inactive/mouse.c new file mode 100644 index 0000000..910f0cf --- /dev/null +++ b/xxx/inactive/mouse.c @@ -0,0 +1,175 @@ +//http://forum.osdev.org/viewtopic.php?t=10247 +//based on Mouse.inc by SANiK +//License: Use as you wish, except to cause damage + +#define FOOLOS_MODULE_NAME "mouse" + +#include "lib/logger/log.h" +#include "lib/int/stdint.h" + +#include "x86.h" + + +static volatile uint8_t mouse_cycle; +static volatile uint8_t mouse_byte[3]; +volatile int16_t mouse_x; +volatile int16_t mouse_y; +static volatile uint8_t mouse_a; + + +uint8_t mouse_read(); + +void mouse_wait(uint8_t a_type) //unsigned char +{ + uint32_t _time_out=100000; //unsigned int + if(a_type==0) + { + while(_time_out--) //Data + { + if((x86_inb(0x64) & 1)==1) + { + return; + } + } + return; + } + else + { + while(_time_out--) //Signal + { + if((x86_inb(0x64) & 2)==0) + { + return; + } + } + return; + } +} + +void mouse_write(uint8_t a_write) +{ + //Wait to be able to send a command + mouse_wait(1); + //Tell the mouse we are sending a command + x86_outb(0x64, 0xD4); + //Wait for the final part + mouse_wait(1); + //Finally write + x86_outb(0x60, a_write); +} + +int8_t mouse_get_x() +{ + return mouse_x; +} +int8_t mouse_get_y() +{ + return mouse_y; +} + +void mouse_init() +{ + mouse_x=mouse_y=0; + mouse_cycle=0; + + uint8_t _status; //unsigned char + + //Enable the auxiliary mouse device + mouse_wait(1); + x86_outb(0x64, 0xA8); + + //Enable the interrupts + mouse_wait(1); + x86_outb(0x64, 0x20); + mouse_wait(0); + _status=(x86_inb(0x60) | 2); + mouse_wait(1); + x86_outb(0x64, 0x60); + mouse_wait(1); + x86_outb(0x60, _status); + + //Tell the mouse to use default settings + mouse_write(0xF6); + mouse_read(); //Acknowledge + + //Enable the mouse + mouse_write(0xF4); + mouse_read(); //Acknowledge + + log(FOOLOS_MODULE_NAME,FOOLOS_LOG_INFO,"Mouse Initialized"); + +} + +void mouse_log() +{ + //log(FOOLOS_MODULE_NAME,FOOLOS_LOG_INFO,"%02x / %02x / %02x ",mouse_byte[0], mouse_byte[1],mouse_byte[2]); + + if(mouse_byte[0]&0x80||mouse_byte[0]&0x40)return; //skip packet on overflow + if(!(mouse_byte[0]&0x8))panic(FOOLOS_MODULE_NAME,"mouse packets out of sync!?"); // this bit is always 1, otherwise panic! + + + // + if(mouse_byte[1]>127){ + mouse_x-=256; + mouse_x+=mouse_byte[1]; + } + else + { + mouse_x+=mouse_byte[1]; + } + if(mouse_byte[2]>127){ + mouse_y-=256; + mouse_y+=mouse_byte[2]; + } + else + { + mouse_y+=mouse_byte[2]; + } + + + + + if(mouse_x<0)mouse_x=0; + if(mouse_y<0)mouse_y=0; + if(mouse_x>800)mouse_x=800; + if(mouse_y>600)mouse_y=600; + + + //log(FOOLOS_MODULE_NAME,FOOLOS_LOG_INFO,"%d / %d / %02x ",mouse_x, mouse_y,mouse_byte[2]); + //PutFont('X', mouse_x,600-mouse_y, 0xffffff); + +} +//Mouse functions +void mouse_handler()//struct regs *a_r) //struct regs *a_r (not used but just there) +{ + X86_IRQ_BEGIN + + switch(mouse_cycle) + { + case 0: + mouse_byte[0]=x86_inb(0x60); + mouse_cycle++; + break; + case 1: + mouse_byte[1]=x86_inb(0x60); + mouse_cycle++; + break; + case 2: + mouse_byte[2]=x86_inb(0x60); + mouse_cycle=0; + mouse_log(); + break; + + } + + + X86_IRQ_END +} + +uint8_t mouse_read() +{ + //Get's response from mouse + mouse_wait(0); + return x86_inb(0x60); +} + diff --git a/xxx/inactive/mp.c b/xxx/inactive/mp.c new file mode 100644 index 0000000..1f6c2e6 --- /dev/null +++ b/xxx/inactive/mp.c @@ -0,0 +1,179 @@ +#define FOOLOS_MODULE_NAME "mp" + +#include "x86.h" +#include "lib/logger/log.h" // logger facilities +#include "lib/bool/bool.h" +#include "lib/string/string.h" +#include "smp.h" + + + +typedef struct mp_fps_struct +{ + uint32_t sig; //signature "_MP_" + uint32_t conf; //pointer to config struct + uint8_t length; //should be 1 + uint8_t version; // 1=1.1, 4=1.4 + + uint8_t checksum; + + uint8_t features1; + uint8_t features2; + + uint8_t res1; //reserved + uint8_t res2; + uint8_t res3; + +}mp_fps; + +typedef struct mp_config_struct +{ + uint32_t sig; //signature "PCMP" + uint16_t length; //base table length + uint8_t version; //revision 1=1.1 4=1.4 + uint8_t checksum; + + uint32_t oemid1; //OEM id (ascii) + uint32_t oemid2; + + uint32_t prodid1; //Product id (ascii) + uint32_t prodid2; + uint32_t prodid3; + + uint32_t oem_table; //pointer (optional) + uint16_t oem_size; //size of this table + uint16_t entries; //entry count (following the header) + uint32_t local_apic; //local apic address (same for every cpu) + uint16_t length_ext; //extended table length (optional) + uint8_t check_ext; //checksum for ext. table + +}mp_config; + + + +typedef struct proc_struct +{ + uint8_t type; //0=processor + uint8_t apic_id; + uint8_t apic_ver; + uint8_t cpu_bits; + uint32_t cpu_sig; + uint32_t cpu_flags; + +}proc_entry; + +//entries are sorted. (otherwise ignore. bochs!) +uint8_t *walk_mp_table(uint8_t *start_addr,smp_processors *smp) +{ + + if(*start_addr==0x0||*start_addr==0x2) + log(FOOLOS_MODULE_NAME,FOOLOS_LOG_INFO,"entry type: %d",*start_addr); + + // that is a processor + if(*start_addr==0x00) + { + proc_entry *pro=start_addr; + log(FOOLOS_MODULE_NAME,FOOLOS_LOG_INFO,"local apic id: %02X",pro->apic_id); + log(FOOLOS_MODULE_NAME,FOOLOS_LOG_INFO,"cpu enabled bit: %s",pro->cpu_bits&1?"yes":"no"); + log(FOOLOS_MODULE_NAME,FOOLOS_LOG_INFO,"bootstrap cpu bit: %s",pro->cpu_bits&2?"yes":"no"); + + // that is a enabled processor + if(pro->cpu_bits&1) + { + if(smp->processors>=SMP_MAX_PROC) + panic(FOOLOS_MODULE_NAME,"we do not support that many processors. recompile with higher SMP_MAX_PROC."); + + smp->local_apic_id[smp->processors]=pro->apic_id; + // that is the bootstrap processor + if(pro->cpu_bits&2)smp->boot=smp->processors; + smp->processors++; + + } + + return start_addr+20; + } + + return start_addr+8; +} + +void do_mp_conf(mp_config *addr,smp_processors *procdata) +{ + char buf[]="XXXX"; + uint32_t *buf_addr=buf; + *buf_addr=addr->sig; + + log(FOOLOS_MODULE_NAME,FOOLOS_LOG_INFO,"mp_config table addr: %08X",addr); + log(FOOLOS_MODULE_NAME,FOOLOS_LOG_INFO,"mp_config signature: %s",buf); + log(FOOLOS_MODULE_NAME,FOOLOS_LOG_INFO,"mp_config version: %02X",addr->version); + log(FOOLOS_MODULE_NAME,FOOLOS_LOG_INFO,"mp_config # of entries: %d",addr->entries); + log(FOOLOS_MODULE_NAME,FOOLOS_LOG_INFO,"mp_config local apic addr: 0x%08X",addr->local_apic); + log(FOOLOS_MODULE_NAME,FOOLOS_LOG_INFO,"mp_config tabel length: %d",addr->length); + + uint8_t *start_addr=addr; + start_addr+=44; + + procdata->processors=0; + procdata->local_apic_address=addr->local_apic; + + + for(int i=0;i<addr->entries;i++) + { + start_addr=walk_mp_table(start_addr,procdata); + } + + + + +} +bool do_mp_fps(mp_fps *addr,smp_processors *procdata) +{ + + if(addr->length!=1)return false; + if(addr->version!=1&&addr->version!=4)return false; + + char buf[]="XXXX"; + uint32_t *buf_addr=buf; + *buf_addr=addr->sig; + + log(FOOLOS_MODULE_NAME,FOOLOS_LOG_INFO,"signature: %s",buf); + log(FOOLOS_MODULE_NAME,FOOLOS_LOG_INFO,"conf: %08X",addr->conf); + log(FOOLOS_MODULE_NAME,FOOLOS_LOG_INFO,"ver: %02X",addr->version); + log(FOOLOS_MODULE_NAME,FOOLOS_LOG_INFO,"f1: %02X",addr->features1); + + if(addr->features1!=0)panic(FOOLOS_MODULE_NAME,"Intel default config not supported yet!"); + do_mp_conf(addr->conf,procdata); + + return true; +} + +// todo: check checksum,version etc. and narrow down search +bool mp_find(smp_processors *procdata) +{ + + log(FOOLOS_MODULE_NAME,FOOLOS_LOG_INFO,"Looking for Mp Floating Ponter Struct..."); + uint8_t *addr=0x8000; + while(addr<=0xfffff) + { + if(strcmp("_MP_",addr,4)) + { + // log(FOOLOS_MODULE_NAME,FOOLOS_LOG_INFO,"Found at 0x%04X",addr); + if(do_mp_fps(addr,procdata))return true; + } + addr++; + } + + addr=0x190000-1025; + while(addr<=0x190000+1024) + { + if(strcmp("_MP_",addr,4)) + { + // log(FOOLOS_MODULE_NAME,FOOLOS_LOG_INFO,"Found at 0x%04X",addr); + if(do_mp_fps(addr,procdata))return true; + } + addr++; + } + + return false; + +} + diff --git a/xxx/inactive/mp.h b/xxx/inactive/mp.h new file mode 100644 index 0000000..fc7f036 --- /dev/null +++ b/xxx/inactive/mp.h @@ -0,0 +1,2 @@ +#include "smp.h" +bool mp_find(smp_processors *procdata); diff --git a/xxx/inactive/pci.c b/xxx/inactive/pci.c new file mode 100644 index 0000000..e5d9711 --- /dev/null +++ b/xxx/inactive/pci.c @@ -0,0 +1,133 @@ +#include "kernel.h" +#include "x86.h" +#include "e1000.h" +#include "../lib/logger/log.h" // logger facilities +#define FOOLOS_MODULE_NAME "pci" + +#define PCI_CONFIG_DATA 0xCFC +#define PCI_CONFIG_ADDRESS 0xCF8 + + void pciConfigSet (uint8_t bus, uint8_t slot, + uint8_t func, uint8_t offset, uint32_t data) + { + uint32_t address; + uint32_t lbus = (uint32_t)bus; + uint32_t lslot = (uint32_t)slot; + uint32_t lfunc = (uint32_t)func; + uint16_t tmp = 0; + + /* create configuration address as per Figure 1 */ + address = (uint32_t)((lbus << 16) | (lslot << 11) | + (lfunc << 8) | (offset & 0xfc) | ((uint32_t)0x80000000)); + + /* write out the address */ + x86_outl (0xCF8, address); + x86_outl (0xCFC,data); + + } + uint16_t pciConfigReadWord (uint8_t bus, uint8_t slot, + uint8_t func, uint8_t offset) + { + uint32_t address; + uint32_t lbus = (uint32_t)bus; + uint32_t lslot = (uint32_t)slot; + uint32_t lfunc = (uint32_t)func; + uint16_t tmp = 0; + + /* create configuration address as per Figure 1 */ + address = (uint32_t)((lbus << 16) | (lslot << 11) | + (lfunc << 8) | (offset & 0xfc) | ((uint32_t)0x80000000)); + + /* write out the address */ + x86_outl (0xCF8, address); + /* read in the data */ + /* (offset & 2) * 8) = 0 will choose the first word of the 32 bits register */ + tmp = (uint16_t)((x86_inl (0xCFC) >> ((offset & 2) * 8)) & 0xffff); + return (tmp); + } + +void test_bar(uint8_t bus, uint8_t slot, uint8_t offset) +{ + + uint16_t bar_low=pciConfigReadWord(bus,slot,0,offset); + uint16_t bar_high=pciConfigReadWord(bus,slot,0,offset+2); + + // check size + pciConfigSet(bus,slot,0,offset,0xffffffff); + uint16_t size_low=pciConfigReadWord(bus,slot,0,offset); + uint16_t size_high=pciConfigReadWord(bus,slot,0,offset+2); + uint32_t size=(size_high<<16)+size_low; + size=~size; + size++; + // + + // restore original values + pciConfigSet(bus,slot,0,offset,(bar_high<<16)+bar_low); + + + log("e1000",FOOLOS_LOG_INFO,"%s bar: (0x%x 0x%x) size: 0x%x" ,bar_low&1?"i/o":"mem",bar_high, bar_low, size); + +} + +uint16_t pciCheck(uint8_t bus, uint8_t slot) +{ + + uint16_t vendor, device; + + /* try and read the first configuration register. Since there are no */ + /* vendors that == 0xFFFF, it must be a non-existent device. */ + if ((vendor = pciConfigReadWord(bus,slot,0,0)) != 0xFFFF) + { + device = pciConfigReadWord(bus,slot,0,2); + log(FOOLOS_MODULE_NAME,FOOLOS_LOG_INFO,"[%d,%d]: vendor: 0x%x / device: 0x%x",bus,slot,vendor,device); + + // check for: E1000 (82540EM). PCI Ethernet Controller + if(vendor==0x8086&&device==0x100e) + { + // uint16_t irq=pciConfigReadWord(bus,slot,0,0x3C); + // uint16_t irq2=pciConfigReadWord(bus,slot,0,0x3E); + // + init_e1000(); + + test_bar(bus,slot,0x10); + test_bar(bus,slot,0x14); + test_bar(bus,slot,0x18); + + // scr_put_hex(irq); + // scr_put_hex(irq2); + // scr_put_string_nl(";"); + + + } + + + + + } + + return (vendor); + +} + +void pci_init() +{ + log(FOOLOS_MODULE_NAME,FOOLOS_LOG_INFO,"scanning bus"); + // todo: recurse on pci to pci bridges! + // todo: support multiple pci host controllers! + // (check more funcitons of device 0:0) + + uint16_t bus; + uint8_t device; + + for(bus = 0; bus < 256; bus++) + { + for(device = 0; device < 32; device++) + { + + pciCheck(bus, device); + + } + + } + +} diff --git a/xxx/inactive/smp.c b/xxx/inactive/smp.c new file mode 100644 index 0000000..63b4087 --- /dev/null +++ b/xxx/inactive/smp.c @@ -0,0 +1,101 @@ +#define FOOLOS_MODULE_NAME "smp" + +#include "lib/logger/log.h" +#include "lib/int/stdint.h" +#include "smp.h" +#include "mem.h" +#include "spinlock.h" +#include "x86.h" + +#define FOOLOS_APIC_SPUR_INT 0x00f0 +#define FOOLOS_APIC_INT_COMMAND_LOW 0x0300 +#define FOOLOS_APIC_INT_COMMAND_HIGH 0x0310 + +// some multiprocessor shit that should move away TODO +uint32_t c1,c2,c3; +volatile uint8_t proc; +uint32_t cpu_counter[SMP_MAX_PROC]; + +void smp_main() +{ + /// TODO + /////// SYMMETRIC MULTIPROCESSING, APS get caought here, move it away /// + // catch the APs (Application Processors) +// if(mp==1) + { + uint32_t ebp=pmmngr_alloc_block()+4095; + + asm volatile("mov %0, %%ebp"::"r"(ebp)); + asm volatile("mov %ebp, %esp"); + asm volatile("jmp kernel_ap"); + } + + proc=c1=c2=c3=0; + for(int i=0;i<SMP_MAX_PROC;i++)cpu_counter[i]=0; +} + + +void kernel_ap() +{ + proc++; + uint8_t p=proc; + while(1) + { + cpu_counter[p]++; + + lock_spin(0); + if(cpu_counter[p]%1000000==0)log(FOOLOS_MODULE_NAME,FOOLOS_LOG_DEBUG,"cpu[%d] %d",p,cpu_counter[p]); + lock_release(0); + } +} +void smp_log_procdata(smp_processors *procdata) +{ + log(FOOLOS_MODULE_NAME,FOOLOS_LOG_INFO,"---- smp -----"); + for(int i=0;i<procdata->processors;i++) + { + log(FOOLOS_MODULE_NAME,FOOLOS_LOG_INFO,"cpu %d, apic_id: 0x%X, bps: %s, apic_addr:0x%08X",i,procdata->local_apic_id[i],i==procdata->boot?"yes":"no",procdata->local_apic_address); + } + +} + +// this will start all our application processors! +void smp_start_aps(smp_processors *pros,uint8_t *start_sel) +{ + + //lets copy the code to the bootsector ! + + uint8_t *dest=0x7000; + for(int i=0;i<0x100;i++) + { + dest[i]=start_sel[i]; + + } + + //bsp (boot processor) enables its local apic + uint32_t *reg=pros->local_apic_address+FOOLOS_APIC_SPUR_INT; + *reg=0xffffffff; // all bits 1 and interrupt 255 + + for(int i=0;i<pros->processors;i++) + { + if(pros->boot==i)continue; + + log(FOOLOS_MODULE_NAME,FOOLOS_LOG_INFO,"starting cpu %d",i); + + uint8_t dest=pros->local_apic_id[i]; + + reg=pros->local_apic_address+FOOLOS_APIC_INT_COMMAND_HIGH; + *reg=dest<<24; // destination apic. + + reg=pros->local_apic_address+FOOLOS_APIC_INT_COMMAND_LOW; + *reg=(5<<8)|(1<<14); // 101 INIT + + // do we really neet this? + // todo: use some real sleep (not implemented yet :( ) + sleep(30); + + // start proc 0x7 = 0x7000; etc.. + *reg=(6<<8)|(1<<14)|0x7; // 110 SIPI + } +} + + diff --git a/xxx/inactive/smp.h b/xxx/inactive/smp.h new file mode 100644 index 0000000..8737ffc --- /dev/null +++ b/xxx/inactive/smp.h @@ -0,0 +1,20 @@ +#ifndef SMP_H +#define SMP_H + +#define SMP_MAX_PROC 32 + +typedef struct +{ + + uint8_t boot; //which processor in array is bsp + // (boot strap processor) + + uint8_t processors; // total number of usable processors + + uint32_t local_apic_address;// same for every processor + + uint32_t local_apic_id[SMP_MAX_PROC]; // unique for every processor + +}smp_processors; + +#endif |
