diff --git a/.bochsrc b/.bochsrc deleted file mode 100644 index 2a42997..0000000 --- a/.bochsrc +++ /dev/null @@ -1,1308 +0,0 @@ -# You may now use double quotes around pathnames, in case -# your pathname includes spaces. - -#======================================================================= -# PLUGIN_CTRL: -# Controls the presence of optional device plugins. These plugins are loaded -# directly with this option and some of them install a config option that is -# only available when the plugin device is loaded. The value "1" means to load -# the plugin and "0" will unload it (if loaded before). -# -# These plugins will be loaded by default (if present): 'biosdev', 'extfpuirq', -# 'gameport', 'iodebug','parallel', 'serial', 'speaker' and 'unmapped'. -# -# These plugins are also supported, but they are usually loaded directly with -# their bochsrc option: 'e1000', 'es1370', 'ne2k', 'pcidev', 'pcipnic', 'sb16', -# 'usb_ehci', 'usb_ohci', 'usb_uhci', 'usb_xhci' and 'voodoo'. -#======================================================================= -#plugin_ctrl: unmapped=0, e1000=1 # unload 'unmapped' and load 'e1000' - -#======================================================================= -# 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 or -# gui console (if available / runtime config) and is always compiled in, unless -# Bochs is compiled for wx only. The choice "win32config" is only available on -# win32/win64 and it is the default on these platforms. The choice "wx" is only -# available when Bochs is compiled with wxWidgets support. 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: win32config -#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 -# win32 use native win32 libraries -# carbon use Carbon library (for MacOS X) -# macintosh use MacOS pre-10 -# amigaos use native AmigaOS libraries -# sdl use SDL 1.2.x library, cross platform -# sdl2 use SDL 2.x library, cross platform -# term text only, uses curses/ncurses library, cross platform -# rfb provides an interface to AT&T's VNC viewer, cross platform -# vncsrv use LibVNCServer for extended RFB(VNC) support -# 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 options to control their -# behaviour. These options are supported by more than one display library: -# -# "cmdmode" - call a headerbar button handler after pressing F7 (sdl, sdl2, -# win32, x) -# "fullscreen" - startup in fullscreen mode (sdl, sdl2) -# "gui_debug" - use GTK debugger gui (sdl, sdl2, x) / Win32 debugger gui (sdl, -# sdl2, win32) -# "hideIPS" - disable IPS output in status bar (rfb, sdl, sdl2, term, vncsrv, -# win32, wx, x) -# "nokeyrepeat" - turn off host keyboard repeat (sdl, sdl2, win32, x) -# "no_gui_console" - use system console instead of builtin gui console -# (rfb, sdl, sdl2, vncsrv, x) -# "timeout" - time (in seconds) to wait for client (rfb, vncsrv) -# -# See the examples below for other currently supported options. -# Setting up options without specifying display library is also supported. -#======================================================================= -#display_library: amigaos -#display_library: carbon -#display_library: macintosh -#display_library: nogui -#display_library: rfb -#display_library: sdl -display_library: sdl2 -#display_library: term -#display_library: vncsrv -# "traphotkeys" - system hotkeys not handled by host OS, but sent to guest -# (win32 in mouse capture and fullscreen mode: alt-tab, win, -# alt-space, alt-esc, ctrl-esc) -# "autoscale" - scale small simulation window by factor 2, 4 or 8 depending -# on desktop window size -#display_library: win32, options="traphotkeys, autoscale" -#display_library: wx -#display_library: x, options="gui_debug" - -#======================================================================= -# CPU: -# This defines cpu-related parameters inside Bochs: -# -# MODEL: -# Selects CPU configuration to emulate from pre-defined list of all -# supported configurations. When this option is used and the value -# is different from 'bx_generic', the parameters of the CPUID option -# have no effect anymore. -# -# CPU configurations that can be selected: -# ----------------------------------------------------------------- -# pentium Intel Pentium (P54C) -# pentium_mmx Intel Pentium MMX -# amd_k6_2_chomper AMD-K6(tm) 3D processor (Chomper) -# p2_klamath Intel Pentium II (Klamath) -# p3_katmai Intel Pentium III (Katmai) -# p4_willamette Intel(R) Pentium(R) 4 (Willamette) -# core_duo_t2400_yonah Intel(R) Core(TM) Duo CPU T2400 (Yonah) -# atom_n270 Intel(R) Atom(TM) CPU N270 -# p4_prescott_celeron_336 Intel(R) Celeron(R) 336 (Prescott) -# athlon64_clawhammer AMD Athlon(tm) 64 Processor 2800+ (Clawhammer) -# athlon64_venice AMD Athlon(tm) 64 Processor 3000+ (Venice) -# turion64_tyler AMD Turion(tm) 64 X2 Mobile TL-60 (Tyler) -# phenom_8650_toliman AMD Phenom X3 8650 (Toliman) -# core2_penryn_t9600 Intel Mobile Core 2 Duo T9600 (Penryn) -# corei5_lynnfield_750 Intel(R) Core(TM) i5 750 (Lynnfield) -# corei5_arrandale_m520 Intel(R) Core(TM) i5 M 520 (Arrandale) -# corei7_sandy_bridge_2600k Intel(R) Core(TM) i7-2600K (Sandy Bridge) -# zambezi AMD FX(tm)-4100 Quad-Core Processor (Zambezi) -# trinity_apu AMD A8-5600K APU (Trinity) -# ryzen AMD Ryzen 7 1700 -# corei7_ivy_bridge_3770k Intel(R) Core(TM) i7-3770K CPU (Ivy Bridge) -# corei7_haswell_4770 Intel(R) Core(TM) i7-4770 CPU (Haswell) -# broadwell_ult Intel(R) Processor 5Y70 CPU (Broadwell) -# -# COUNT: -# Set the number of processors:cores per processor:threads per core when -# Bochs is compiled for SMP emulation. Bochs currently supports up to -# 14 threads (legacy APIC) or 254 threads (xAPIC or higher) 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 ! -# -# CPUID_LIMIT_WINNT: -# Determine whether to limit maximum CPUID function to 2. This mode is -# required to workaround WinNT installation and boot issues. -# -# 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 available if configurable MSRs are enabled. -# -# 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. -# -# 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.4.6 3.4Ghz Intel Core i7 2600 with Win7x64/g++ 4.5.2 85 to 95 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 -#======================================================================= -cpu: model=core2_penryn_t9600, count=1, ips=50000000, reset_on_triple_fault=1, ignore_bad_msrs=1, msrs="msrs.def" -cpu: cpuid_limit_winnt=0 - -#======================================================================= -# CPUID: -# -# This defines features and functionality supported by Bochs emulated CPU. -# The option has no offect if CPU model was selected in CPU option. -# -# MMX: -# Select MMX instruction set support. -# This option exists only if Bochs compiled with BX_CPU_LEVEL >= 5. -# -# APIC: -# Select APIC configuration (LEGACY/XAPIC/XAPIC_EXT/X2APIC). -# 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. -# -# SIMD: -# Select SIMD instructions support. -# Any of NONE/SSE/SSE2/SSE3/SSSE3/SSE4_1/SSE4_2/AVX/AVX2/AVX512 -# could be selected. -# -# This option exists only if Bochs compiled with BX_CPU_LEVEL >= 6. -# The AVX choises exists only if Bochs compiled with --enable-avx option. -# -# SSE4A: -# Select AMD SSE4A instructions support. -# This option exists only if Bochs compiled with BX_CPU_LEVEL >= 6. -# -# MISALIGNED_SSE: -# Select AMD Misaligned SSE mode 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. -# -# SHA: -# Select SHA 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. -# -# ADX: -# Select ADCX/ADOX instructions 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. -# -# XSAVEOPT: -# Select XSAVEOPT instruction support. -# This option exists only if Bochs compiled with BX_CPU_LEVEL >= 6. -# -# AVX_F16C: -# Select AVX float16 convert instructions support. -# This option exists only if Bochs compiled with --enable-avx option. -# -# AVX_FMA: -# Select AVX fused multiply add (FMA) instructions support. -# This option exists only if Bochs compiled with --enable-avx option. -# -# BMI: -# Select BMI1/BMI2 instructions support. -# This option exists only if Bochs compiled with --enable-avx option. -# -# XOP: -# Select AMD XOP instructions support. -# This option exists only if Bochs compiled with --enable-avx option. -# -# FMA4: -# Select AMD four operand FMA instructions support. -# This option exists only if Bochs compiled with --enable-avx option. -# -# TBM: -# Select AMD Trailing Bit Manipulation (TBM) instructions support. -# This option exists only if Bochs compiled with --enable-avx option. -# -# X86-64: -# Enable x86-64 and long mode support. -# This option exists only if Bochs compiled with x86-64 support. -# -# 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. -# -# SMEP: -# Enable Supervisor Mode Execution Protection (SMEP) support. -# This option exists only if Bochs compiled with BX_CPU_LEVEL >= 6. -# -# SMAP: -# Enable Supervisor Mode Access Prevention (SMAP) support. -# This option exists only if Bochs compiled with BX_CPU_LEVEL >= 6. -# -# MWAIT: -# Select MONITOR/MWAIT instructions support. -# This option exists only if Bochs compiled with --enable-monitor-mwait. -# -# VMX: -# Select VMX extensions emulation support. -# This option exists only if Bochs compiled with --enable-vmx option. -# -# SVM: -# Select AMD SVM (Secure Virtual Machine) extensions emulation support. -# This option exists only if Bochs compiled with --enable-svm option. -# -# 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. -# -# LEVEL: -# Set emulated CPU level information returned by CPUID. Default value is -# determined by configure option --enable-cpu-level. Currently supported -# values are 5 (for Pentium and similar processors) and 6 (for P6 and -# later processors). -# -# FAMILY: -# Set model information returned by CPUID. Default family value determined -# by configure option --enable-cpu-level. -# -# MODEL: -# Set model information returned by CPUID. Default model value is 3. -# -# STEPPING: -# Set stepping information returned by CPUID. Default stepping value is 3. -#======================================================================= -#cpuid: x86_64=1, mmx=1, sep=1, simd=sse4_2, apic=xapic, aes=1, movbe=1, xsave=1 -#cpuid: family=6, model=0x1a, stepping=5 - -#======================================================================= -# 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=512, host=256 - -#======================================================================= -# 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 default ROM BIOS is usually loaded -# starting at address 0xfffe0000, and it is exactly 128k long. The legacy -# version of the Bochs BIOS is usually loaded starting at address 0xffff0000, -# and it is exactly 64k long. -# You can 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 is optional, since it can be calculated from image size. -# The Bochs BIOS currently supports only the option "fastboot" to skip the -# boot menu delay. -#======================================================================= -romimage: file=$BXSHARE/BIOS-bochs-latest, options=fastboot -#romimage: file=$BXSHARE/bios.bin-1.13.0 # http://www.seabios.org/SeaBIOS -#romimage: file=mybios.bin, address=0xfff80000 # 512k at memory top - -#======================================================================= -# VGAROMIMAGE -# You now need to load a VGA ROM BIOS into C0000. -#======================================================================= -vgaromimage: file=$BXSHARE/VGABIOS-lgpl-latest -#vgaromimage: file=bios/VGABIOS-lgpl-latest-cirrus -#vgaromimage: file=$BXSHARE/vgabios-cirrus.bin-1.13.0 # http://www.seabios.org/SeaVGABIOS -#vgaromimage: file=bios/VGABIOS-elpin-2.40 - -#======================================================================= -# 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=/path/file1.img, address=0x0010000 -#optramimage2: file=/path/file2.img, address=0x0020000 -#optramimage3: file=/path/file3.img, address=0x0030000 -#optramimage4: file=/path/file4.img, address=0x0040000 - -#======================================================================= -# VGA: -# This defines parameters related to the VGA display -# -# EXTENSION -# 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, 'cirrus' for Cirrus SVGA support and -# 'voodoo' for Voodoo Graphics support (see 'voodoo' option). -# -# UPDATE_FREQ -# This parameter specifies the number of display updates per second. -# The VGA update timer by default uses the realtime engine with a value -# of 5. This parameter can be changed at runtime. -# -# REALTIME -# If set to 1 (default), the VGA timer is based on realtime, otherwise it -# is driven by the cpu and depends on the ips setting. If the host is slow -# (low ips, update_freq) and the guest uses HLT appropriately, setting this -# to 0 and "clock: sync=none" may improve the responsiveness of the guest -# GUI when the guest is otherwise idle. -# -# DDC -# This parameter defines the behaviour of the DDC emulation that returns -# the monitor EDID data. By default the 'builtin' values for 'Bochs Screen' -# are used. Other choices are 'disabled' (no DDC emulation) and 'file' -# (read monitor EDID from file / path name separated with a colon). -# Examples: -# vga: extension=cirrus, update_freq=10, ddc=builtin -#======================================================================= -#vga: extension=vbe, update_freq=5, realtime=1, ddc=file:monitor.bin - -#======================================================================= -# VOODOO: -# This defines the Voodoo Graphics emulation (experimental). Currently -# supported models are 'voodoo1', 'voodoo2', 'banshee' and 'voodoo3'. The -# Voodoo2 support is not yet complete, but almost usable. The Banshee and -# Voodoo3 support is under construction, but basically usable. The 2D/3D cards -# require an external VGA BIOS the vga extension option to be set to 'voodoo'. -# If the i440BX PCI chipset is selected, they can be assigned to AGP (slot #5). -# The gui screen update timing for all models is controlled by the related 'vga' -# options. -# -# Examples: -# voodoo: enabled=1, model=voodoo2 -#======================================================================= -#voodoo: enabled=1, model=voodoo1 - -#======================================================================= -# KEYBOARD: -# This defines parameters related to the emulated keyboard -# -# TYPE: -# Type of keyboard return by a "identify keyboard" command to the -# keyboard controller. 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. -# -# SERIAL_DELAY: -# Approximate time in microseconds that it takes one character to -# be transferred from the keyboard to controller over the serial path. -# -# 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. -# -# KEYMAP: -# This enables a remap of a physical localized keyboard to a -# virtualized us keyboard, as the PC architecture expects. -# -# 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", "power", "print", "right", "scrlck", "shift", "space", "tab", "up" -# and "win". - -# Examples: -# keyboard: type=mf, serial_delay=200, paste_delay=100000 -# keyboard: keymap=gui/keymaps/x11-pc-de.map -# keyboard: user_shortcut=ctrl-alt-del -#======================================================================= -#keyboard: type=mf, serial_delay=250 - -#======================================================================= -# 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', 'serial_msys' (one com port requires -# setting 'mode=mouse') 'inport' and 'bus' (if present). To connect a mouse -# to a USB port, see the 'usb_uhci', 'usb_ohci', 'usb_ehci' or 'usb_xhci' -# options (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'. -# -# Examples: -# mouse: enabled=1 -# mouse: type=imps2, enabled=1 -# mouse: type=serial, enabled=1 -# mouse: enabled=0, toggle=ctrl+f10 -#======================================================================= -mouse: enabled=0 - -#======================================================================= -# PCI: -# This defines the parameters to set up the Bochs PCI emulation: -# -# ENABLED: -# If Bochs is compiled with PCI support, it is enabled by default. -# -# CHIPSET: -# Currently the chipsets i430FX, i440FX and i440BX (limited) are supported and -# the default is i440FX. -# -# SLOTx: -# It is possible to specify the devices connected to PCI slots. Up to 5 slots -# are available. For combined PCI/ISA devices assigning to slot is mandatory -# if the PCI model should be emulated (cirrus, ne2k and pcivga). Setting up -# slot for PCI-only devices is also supported, but they are auto-assigned if -# not specified (e1000, es1370, pcidev, pcipnic, usb_ehci, usb_ohci, usb_xhci, -# voodoo). All device models except the network devices ne2k and e1000 can be -# used only once in the slot configuration. In case of the i440BX chipset, the -# slot #5 is the AGP slot. Currently only the 'voodoo' device can be assigned -# to AGP. -# -# ADVOPTS: -# With the advanced PCI options it is possible to control the behaviour of the -# PCI chipset. These options can be specified as comma-separated values. -# By default the "Bochs i440FX" chipset enables the ACPI and HPET devices, but -# original i440FX doesn't support them. The options 'noacpi' and 'nohpet' make -# it possible to disable them. The option 'noagp' disables the incomplete AGP -# subsystem of the i440BX chipset. -# -# Example: -# pci: enabled=1, chipset=i440fx, slot1=pcivga, slot2=ne2k, advopts=noacpi -#======================================================================= -pci: enabled=1, chipset=i440fx - -#======================================================================= -# 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. -# -# RTC_SYNC: -# If this option is enabled together with the realtime synchronization, -# the RTC runs at realtime speed. This feature is disabled by default. -# -# TIME0: -# Specifies the start (boot) time of the virtual machine. Use a time -# value as returned by the time(2) system call or a string as returned -# by the ctime(3) 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="Mon Jan 1 00:00:00 1990" # 631148400 -# clock: sync=realtime, time0=938581955 # Wed Sep 29 07:12:35 1999 -# clock: sync=realtime, time0="Sat Jan 1 00:00:00 2000" # 946681200 -# clock: sync=none, time0=1 # Now (localtime) -# clock: sync=none, time0=utc # Now (utc/gmt) -# -# Default value are sync=none, rtc_sync=0, time0=local -#======================================================================= -#clock: sync=none, time0=local - -#======================================================================= -# CMOSIMAGE: -# This defines a binary image file with size 128 bytes 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 - -#======================================================================= -# 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 - -#======================================================================= -# 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="HelloOS.iso", 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|dll|sparse|vmware3|vmware4] -# [undoable|growing|volatile|vpc|vbox|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 [auto|cmos|none] -# 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=10M.sample, cylinders=306, heads=4, spt=17 -# 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="HelloOS.iso" -#ata0-master: type=disk, mode=flat, path="30M.sample", cylinders=615, heads=6, spt=17 -#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=D:, status=inserted -#ata0-slave: type=cdrom, path=/dev/cdrom, status=inserted -#ata0-slave: type=cdrom, path="drive", status=inserted -#ata0-slave: type=cdrom, path=/dev/rcd0d, 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 - -#======================================================================= -# 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/null -log: bochsout.txt - -#======================================================================= -# LOGPREFIX: -# This handles the format of the string prepended to each log line. -# You may use those special tokens : -# %t : 11 decimal digits timer tick -# %i : 8 hexadecimal digits of 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 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 exit Bochs ('fatal'), 'ask', -# 'warn', 'report' or 'ignore'. The choices 'ask' and 'warn' are not supported -# by all guis, since they should bring up a dialog box. The 'warn' dialog is -# designed to confirm errors and the 'ask' dialog is usually used for panics -# and asks the user how to proceed. -# -# It is also possible to specify the 'action' to do for each Bochs facility -# separately (e.g. crash on panics from everything except the cdrom, and only -# report those). See the 'log function' module list in the user documentation. -# -# 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=ignore, pci=report # report BX_DEBUG from module 'pci' - -#======================================================================= -# 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' mode 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). 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 and changeable at runtime), 'raw' (use the -# real serial port - partly implemented on 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/ttyp9 - - -#======================================================================= -# 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). The output file can be changed at runtime. -# -# Examples: -# parport1: enabled=1, file="parport.out" -# parport2: enabled=1, file="/dev/lp0" -# parport1: enabled=0 -#======================================================================= -parport1: enabled=1, file="parport.out" - -#======================================================================= -# SOUND: -# This defines the lowlevel sound driver(s) for the wave (PCM) input / output -# and the MIDI output feature and (if necessary) the devices to be used. -# It can have several of the following properties. -# All properties are in the format sound: property=value -# -# waveoutdrv: -# This defines the driver to be used for the waveout feature. -# Possible values are 'file' (all wave data sent to file), 'dummy' (no -# output) and the platform-dependant drivers 'alsa', 'oss', 'osx', 'sdl' -# and 'win'. -# waveout: -# This defines the device to be used for wave output (if necessary) or -# the output file for the 'file' driver. -# waveindrv: -# This defines the driver to be used for the wavein feature. -# Possible values are 'dummy' (recording silence) and platform-dependent -# drivers 'alsa', 'oss', 'sdl' and 'win'. -# wavein: -# This defines the device to be used for wave input (if necessary). -# midioutdrv: -# This defines the driver to be used for the MIDI output feature. -# Possible values are 'file' (all MIDI data sent to file), 'dummy' (no -# output) and platform-dependent drivers 'alsa', 'oss', 'osx' and 'win'. -# midiout: -# This defines the device to be used for MIDI output (if necessary). -# driver: -# This defines the driver to be used for all sound features with one -# property. Possible values are 'default' (platform default) and all -# other choices described above. Overriding one or more settings with -# the specific driver parameter is possible. -# -# Example for different drivers: -# sound: waveoutdrv=sdl, waveindrv=alsa, midioutdrv=dummy -#======================================================================= -# sound: driver=default, waveout=/dev/dsp. wavein=, midiout= - -#======================================================================= -# SPEAKER: -# This defines the PC speaker output mode. In the 'sound' mode the beep -# is generated by the square wave generator which is a part of the -# lowlevel sound support. In this mode the 'volume' parameter can be used -# to set the output volume (0 - 15). The 'system' mode is only available on -# Linux and Windows. On Linux /dev/console is used for output and on Windows -# the Beep() function. The 'gui' mode forwards the beep to the related -# gui methods (currently only used by the Carbon gui). -#======================================================================= -speaker: enabled=1, mode=sound, volume=15 - -#======================================================================= -# SB16: -# This defines the SB16 sound emulation. It can have several of the -# following properties. -# All properties are in the format sb16: property=value -# -# enabled: -# This optional property controls the presence of the SB16 emulation. -# The emulation is turned on unless this property is used and set to 0. -# midimode: This parameter specifies what to do with the MIDI output. -# 0 = no output -# 1 = output to device specified with the sound option (system dependent) -# 2 = MIDI or raw data output to file (depends on file name extension) -# 3 = dual output (mode 1 and 2 at the same time) -# midifile: This is the file where the midi output is stored (midimode 2 or 3). -# wavemode: This parameter specifies what to do with the PCM output. -# 0 = no output -# 1 = output to device specified with the sound option (system dependent) -# 2 = VOC, WAV or raw data output to file (depends on file name extension) -# 3 = dual output (mode 1 and 2 at the same time) -# wavefile: This is the file where the wave output is stored (wavemode 2 or 3). -# 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 -# log: The file to write the sb16 emulator messages to. -# 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 modes: -# sb16: midimode=2, midifile="output.mid", wavemode=1 # MIDI to file -# sb16: midimode=1, wavemode=3, wavefile="output.wav" # wave to file and device -#======================================================================= -#sb16: midimode=1, wavemode=1, loglevel=2, log=sb16.log, dmatimer=600000 - -#======================================================================= -# ES1370: -# This defines the ES1370 sound emulation (recording and playback - except -# DAC1+DAC2 output at the same time). The parameter 'enabled' controls the -# presence of the device. The wave and MIDI output can be sent to device, file -# or both using the parameters 'wavemode', 'wavefile', 'midimode' and -# 'midifile'. See the description of these parameters at the SB16 directive. -# -# Examples: -# es1370: enabled=1, wavemode=1 # use 'sound' parameters -# es1370: enabled=1, wavemode=2, wavefile=output.voc # send output to file -#======================================================================= -#es1370: enabled=1, wavemode=1 - -#======================================================================= -# ne2k: NE2000 compatible ethernet adapter -# -# Format: -# ne2k: card=CARD, enabled=1, type=TYPE, ioaddr=IOADDR, irq=IRQ, mac=MACADDR, -# ethmod=MODULE, ethdev=DEVICE, script=SCRIPT, bootrom=BOOTROM -# -# CARD: This is the zero-based card number to configure with this ne2k config -# line. Up to 4 devices are supported now (0...3). If not specified, the -# following parameters apply to card #0. -# -# TYPE: This is the card type to emulate ("isa" or "pci"). If not specified, -# card #0 defaults to "pci" if assigned to a pci slot. For the additional cards -# the type parameter should be set up. -# -# 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 or set the type to 'pci'. -# -# 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. -# The 'socket' module uses this parameter to specify the UDP port for -# receiving packets and (optional) the host to connect. -# -# 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. -# The 'slirp' module uses this parameter to specify a config file for -# setting up an alternative IP configuration or additional features. -# The 'vnet' module also uses this parameter to specify a config file similar -# to slirp, but with only a few settings. -# -# BOOTROM: The bootrom value is optional, and is the name of the ROM image -# to load. Note that this feature is only implemented for the PCI version of -# the NE2000. -# -# 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. -# vde: Virtual Distributed Ethernet -# vnet: ARP, ICMP-echo(ping), DHCP, DNS, FTP and TFTP are simulated. -# The virtual host uses 192.168.10.1. -# DHCP assigns 192.168.10.15 to the guest. -# FTP/TFTP using the 'ethdev' value for the root directory. -# TFTP doesn't overwrite files, DNS for server and client only. -# socket: Connect up to 6 Bochs instances with external program 'bxhub' -# (simulating an ethernet hub). It provides the same services as the -# 'vnet' module and assigns IP addresses like 'slirp' (10.0.2.x). -# -#======================================================================= -# ne2k: ioaddr=0x300, irq=9, mac=fe:fd:00:00:00:01, ethmod=fbsd, ethdev=en0 #macosx -# ne2k: ioaddr=0x300, irq=9, mac=b0:c4:20:00:00:00, ethmod=fbsd, ethdev=xl0 -# ne2k: ioaddr=0x300, irq=9, mac=b0:c4:20:00:00:00, ethmod=linux, ethdev=eth0 -# ne2k: ioaddr=0x300, irq=9, mac=b0:c4:20:00:00:01, ethmod=win32, ethdev=MYCARD -# 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" -# ne2k: mac=b0:c4:20:00:00:01, ethmod=socket, ethdev=40000 # use localhost -# ne2k: mac=b0:c4:20:00:00:01, ethmod=socket, ethdev=mymachine:40000 -# ne2k: mac=b0:c4:20:00:00:01, ethmod=slirp, script=slirp.conf, bootrom=ne2k_pci.rom - -#======================================================================= -# pcipnic: Bochs/Etherboot pseudo-NIC -# -# Format: -# pcipnic: enabled=1, mac=MACADDR, ethmod=MODULE, ethdev=DEVICE, script=SCRIPT, -# bootrom=BOOTROM -# -# The pseudo-NIC accepts the same syntax (for mac, ethmod, ethdev, script, -# bootrom) and supports the same networking modules as the NE2000 adapter. -#======================================================================= -#pcipnic: enabled=1, mac=b0:c4:20:00:00:00, ethmod=vnet - -#======================================================================= -# e1000: Intel(R) 82540EM Gigabit Ethernet adapter -# -# Format: -# e1000: card=CARD, enabled=1, mac=MACADDR, ethmod=MODULE, ethdev=DEVICE, -# script=SCRIPT, bootrom=BOOTROM -# -# The E1000 accepts the same syntax (for card, mac, ethmod, ethdev, script, -# bootrom) and supports the same networking modules as the NE2000 adapter. -# It also supports up to 4 devices selected with the card parameter. -#======================================================================= -#e1000: enabled=1, mac=52:54:00:12:34:56, ethmod=slirp, script=slirp.conf - -#======================================================================= -# 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', 'keyboard', -# 'disk', 'cdrom', 'floppy', 'hub' and 'printer'). -# -# 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. If the -# keyboard is selected, all key events are sent to the USB device. -# -# To connect a disk image as a USB hardisk you can use the 'disk' device. Use -# the 'path' option in the optionsX parameter to specify the path to the image -# separated with a colon. To use other disk image modes similar to ATA disks -# the syntax 'path:mode:filename' must be used (see below). -# -# To emulate a USB cdrom you can use the 'cdrom' device and the path to an -# ISO image or raw device name can be set with the 'path' option in the -# optionsX parameter also separated with a colon. An option to insert/eject -# media is available in the runtime configuration. -# -# To emulate a USB floppy you can use the 'floppy' device and the path to a -# floppy image can be set with the 'path' option in the optionsX parameter -# separated with a colon. To use the VVFAT image mode similar to the legacy -# floppy the syntax 'path:vvfat:directory' must be used (see below). -# 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 use the 'ports' -# option in the optionsX parameter with 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 the 'file' option with the optionsX parameter. -# The current code appends the PCL code to the file if the file already existed. -# The output file can be changed at runtime. -# -# The optionsX parameter can be used to assign specific options to the device -# connected to the corresponding USB port. The option 'speed' can be used to set -# the speed reported by device ('low', 'full', 'high' or 'super'). The available -# speed choices depend on both HC and device. The option 'debug' turns on debug -# output for the device at connection time. The option 'pcap' turns on packet -# logging in PCAP format. -# For the USB 'disk' device the optionsX parameter can be used to specify an -# alternative redolog file (journal) of some image modes. For 'vvfat' mode USB -# disks the optionsX parameter can be used to specify the disk size (range -# 128M ... 128G). If the size is not specified, it defaults to 504M. -# For the USB 'floppy' device the optionsX parameter can be used to specify an -# alternative device ID to be reported. Currently only the model "teac" is -# supported (can fix hw detection in some guest OS). The USB floppy also -# accepts the parameter "write_protected" with valid values 0 and 1 to select -# the access mode (default is 0). -#======================================================================= -#usb_uhci: enabled=1 -#usb_uhci: port1=mouse, port2=disk, options2="path:usbstick.img" -#usb_uhci: port1=hub, options1="ports:6, pcap:outfile.pcap" -#usb_uhci: port2=disk, options2="path:undoable:usbdisk.img, journal:u.redolog" -#usb_uhci: port2=disk, options2=""path:usbdisk2.img, sect_size:1024" -#usb_uhci: port2=disk, options2="path:vvfat:vvfat, debug, speed:full" -#usb_uhci: port2=cdrom, options2="path:image.iso" -#usb_uhci: port1=printer, options1="file:printdata.bin" -#usb_uhci: port2=floppy, options2="path:vvfat:diskette, model:teac" - -#======================================================================= -# USB_OHCI: -# This option controls the presence of the USB OHCI host controller with a -# 2-port hub. The portX parameter accepts the same device types with the same -# syntax as the UHCI controller (see above). The optionsX parameter is also -# available on OHCI. -#======================================================================= -#usb_ohci: enabled=1 -#usb_ohci: enabled=1, port1=printer:usbprinter.bin - -#======================================================================= -# USB_EHCI: -# This option controls the presence of the USB EHCI host controller with a -# 6-port hub. The portX parameter accepts the same device types with the -# same syntax as the UHCI controller (see above). The optionsX parameter is -# also available on EHCI. -#======================================================================= -#usb_ehci: enabled=1 - -#======================================================================= -# USB_XHCI: -# This option controls the presence of the USB xHCI host controller with a -# 4-port hub. The portX parameter accepts the same device types with the -# same syntax as the UHCI controller (see above). The optionsX parameter is -# also available on xHCI. NOTE: port 1 and 2 are USB3 and only support -# super-speed devices, but port 3 and 4 are USB2 and support speed settings -# low, full and high. -#======================================================================= -#usb_xhci: enabled=1 - -#======================================================================= -# PCIDEV: -# PCI host device mapping -# WARNING: This Bochs feature is not maintained yet and may fail. -#======================================================================= -#pcidev: vendor=0x1234, device=0x5678 - -#======================================================================= -# GDBSTUB: -# Enable GDB stub. See user documentation for details. -# Default value is enabled=0. -# WARNING: This Bochs feature is not maintained yet and may fail. -#======================================================================= -#gdbstub: enabled=0, port=1234, text_base=0, data_base=0, bss_base=0 - -#======================================================================= -# 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 - -#======================================================================= -# 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" - -#print_timestamps: 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 - -#======================================================================= -# fullscreen: ONLY IMPLEMENTED ON AMIGA -# Request that Bochs occupy the entire screen instead of a -# window. -# -# Examples: -# fullscreen: enabled=0 -# fullscreen: enabled=1 -#======================================================================= -#fullscreen: enabled=0 -#screenmode: name="sample" - -#======================================================================= -# for Macintosh, use the style of pathnames in the following -# examples. -# -# vgaromimage: :bios:VGABIOS-elpin-2.40 -# romimage: file=:bios:BIOS-bochs-latest, address=0xf0000 -# floppya: 1_44=[fd:], status=inserted -#======================================================================= - -#======================================================================= -# MEGS -# Set the number of Megabytes of physical memory you want to emulate. -# The default is 32MB, most OS's won't need more than that. -# The maximum amount of memory supported is 2048Mb. -# The 'MEGS' option is deprecated. Use 'MEMORY' option instead. -#======================================================================= -#megs: 256 -#megs: 128 -#megs: 64 -#megs: 32 -#megs: 16 -#megs: 8 -megs: 1024 diff --git a/.gitignore b/.gitignore index 334735e..d2359a2 100644 --- a/.gitignore +++ b/.gitignore @@ -9,13 +9,16 @@ bochsout.txt bimg !bimg/ *.dSYM -iso/ +build_dir/ HelloOS *.s~ *.i +.gdbinit # Prerequisites *.d +.DS_Store +.vscode/ # Object files *.o diff --git a/Makefile b/Makefile index 9a47921..2a0c7eb 100644 --- a/Makefile +++ b/Makefile @@ -1,23 +1,28 @@ MAKEFLAGS = --no-print-directory +export BASE_DIR=$(shell pwd) +export TARGET_ISO=HelloOS.iso +export CONFIG_x86_64=y +export CC=gcc +export AS=as +export LD=ld +export HIDE=@ +export DEBUG=-g -SRC := arch/x86/boot kernel mm drivers -all: clean iso +HelloOS: + $(HIDE)make -C arch -iso: build - ld -b elf64-x86-64 -z muldefs -o kernel.elf -Map=./kernel.map -T link.lds $(shell find $(SRC) -name "*.o") - @bash build_iso.sh +clean: + $(HIDE)make -C arch clean -build: $(SRC) - @for s in $(SRC); do \ - make -C $$s build || exit 1; \ - done +cleanall: + $(HIDE)make -C arch cleanall -clean: $(SRC) - @for s in $(SRC); do \ - make -C $$s clean || exit 1; \ - done - rm -rf *.elf *.iso *.map +run: + qemu-system-x86_64 -m 1G -cdrom arch/$(TARGET_ISO) -curses -qemu-run: - qemu-system-x86_64 -m 2G HelloOS.iso +debug: + qemu-system-x86_64 -m 1G -cdrom arch/$(TARGET_ISO) -s -S -curses + +kill: + @ps aux | grep [q]emu | awk '{print $$2}' | xargs kill diff --git a/README.md b/README.md index 79d3ac2..8a20783 100644 --- a/README.md +++ b/README.md @@ -1,67 +1,2 @@ -# HelloOS -基于 x86_64 指令集的实验性操作系统。 - -## 构建 -目前基于 debian/ubuntu 进行构建: - -1. 安装依赖 - -```bash -$ apt install -y make gcc grub git xorriso -``` - -2. 代码拉取 - -```bash -$ git clone git@github.com:BitInit/HelloOS.git -``` - -3. 构建镜像 - -```bash -$ cd HelloOS - -$ make -``` - -在目录项目主目录下,`HelloOS.iso` 为构建好的镜像文件,`kernel.elf` 为构建好的内核文件。 - -## 进度 - -- [x] grub 启动引导 - -- [x] 基于位图的内存管理 - -- [ ] 内存管理改造成伙伴算法 - -- [ ] 支持 slab - -- [x] 基于 8259A PIC 的中断处理 - -- [ ] 基于 APIC 的中断处理 - -- [x] 基于 8042 的键盘驱动 - -- [x] 基于 `sysenter` 与 `sysexit` 指令的系统调用 - -- [ ] posix 支持 - -- [ ] 进程调度 - -- [ ] 多核处理器支持 - -- [ ] 磁盘驱动 - -- [ ] 支持 FAT32 文件系统 - -- [ ] shell 命令解析器 - -- [ ] 移植 ls/cat/cp 等常用工具 - -- [ ] 支持 risc-v 指令集 - - -## 参考资料 - -* [《x86汇编语言:从实模式到保护模式》](https://book.douban.com/subject/20492528/) -* [《一个64位操作系统的设计与实现》](https://book.douban.com/subject/30222325/) \ No newline at end of file +## HelloOS +以 Linux kernel 2.6.26 源码为模版,实验性从零到一完成一个操作系统 diff --git a/arch/Makefile b/arch/Makefile new file mode 100644 index 0000000..5748167 --- /dev/null +++ b/arch/Makefile @@ -0,0 +1,38 @@ +kernel_target=kernel.elf +SRCS = $(BASE_DIR)/init $(BASE_DIR)/kernel $(BASE_DIR)/mm $(BASE_DIR)/lib +ifeq ($(CONFIG_x86_64), y) + SRCS += $(BASE_DIR)/arch/x86 + lds = $(BASE_DIR)/arch/x86/boot/vmlinux.lds +else + $(HIDE)echo "unkown arch..." +endif + +$(TARGET_ISO): clean $(kernel_target) + $(HIDE)rm -rf build_dir + $(HIDE)mkdir -p build_dir/boot/grub + $(HIDE)cp $(kernel_target) build_dir/boot + + $(HIDE)echo 'set timeout=0' > build_dir/boot/grub/grub.cfg + $(HIDE)echo 'set default=0' >> build_dir/boot/grub/grub.cfg + $(HIDE)echo 'menuentry "HelloOS" {' >> build_dir/boot/grub/grub.cfg + $(HIDE)echo ' multiboot2 /boot/kernel.elf "HelloOS"' >> build_dir/boot/grub/grub.cfg + $(HIDE)echo '}' >> build_dir/boot/grub/grub.cfg + + $(HIDE)grub-mkrescue -o $(TARGET_ISO) build_dir + $(HIDE)rm -rf build_dir + +$(kernel_target): compile + $(HIDE)$(LD) -b elf64-x86-64 -z muldefs -o $(kernel_target) -Map=./kernel.map -T $(lds) $(shell find $(SRCS) -name "*.o") + +compile: + $(HIDE)for dir in $(SRCS); do \ + make -C $$dir compile || exit 1; \ + done + +clean: + $(HIDE)rm -rf $(kernel_target) $(TARGET_ISO) kernel.map + +cleanall: clean + $(HIDE)for dir in $(SRCS); do \ + make -C $$dir clean || exit 1; \ + done \ No newline at end of file diff --git a/arch/x86/Makefile b/arch/x86/Makefile new file mode 100644 index 0000000..874d8c1 --- /dev/null +++ b/arch/x86/Makefile @@ -0,0 +1,17 @@ +-include $(BASE_DIR)/scripts/config.mk + +x86_srcs = $(wildcard ./boot/*.c) $(wildcard ./kernel/*.c) $(wildcard ./*.c) +x86_objs = $(patsubst %.c, %.o, $(x86_srcs)) + +x86_asm_srcs = $(wildcard ./boot/*.S) $(wildcard ./kernel/*.S) +x86_asm_tmp_srcs = $(patsubst %.S, %.i, $(x86_asm_srcs)) +x86_asm_objs = $(patsubst %.S, %.o, $(x86_asm_srcs)) + +compile: $(x86_asm_objs) $(x86_objs) + +$(x86_objs): $(x86_srcs) +$(x86_asm_objs): $(x86_asm_srcs) + +clean: + $(HIDE)rm -rf $(x86_objs) $(x86_asm_objs) $(x86_asm_tmp_srcs) + diff --git a/arch/x86/boot/Makefile b/arch/x86/boot/Makefile deleted file mode 100644 index f32834b..0000000 --- a/arch/x86/boot/Makefile +++ /dev/null @@ -1,17 +0,0 @@ -ASFLAGS = --64 -CFLAGS = -I../../../include --static -fno-pie -fno-builtin -fno-stack-protector -m64 -OBJS = multiboot2.o - -all: clean build - -build: $(OBJS) - -multiboot2.o: multiboot2.S - @gcc -E $(CFLAGS) $< > multiboot2.i - @as $(ASFLAGS) -o $@ multiboot2.i - -%.o: %.c - @gcc -c $(CFLAGS) -o $@ $< - -clean: - @rm -rf *.i *.o diff --git a/arch/x86/boot/header.S b/arch/x86/boot/header.S new file mode 100644 index 0000000..99bed53 --- /dev/null +++ b/arch/x86/boot/header.S @@ -0,0 +1,25 @@ +#define ASM_FILE +#include +#include + +.section .text.head +.global startup +.extern startup_64 + +.code32 +startup: + jmp startup_64 + +.align 8 +multiboot_header: + .long MULTIBOOT2_HEADER_MAGIC /* magic number (multiboot 2) */ + .long MULTIBOOT_ARCHITECTURE_I386 /* architecture 0 (protected mode i386) */ + .long multiboot_header_end - multiboot_header /* header length */ + .long -(MULTIBOOT2_HEADER_MAGIC + MULTIBOOT_ARCHITECTURE_I386 + (multiboot_header_end - multiboot_header)) + + /* required end tag */ + .align 8 + .short MULTIBOOT_HEADER_TAG_END /* type */ + .short 0 /* flags */ + .long 8 /* size */ +multiboot_header_end: diff --git a/arch/x86/boot/multiboot2.S b/arch/x86/boot/multiboot2.S deleted file mode 100644 index 5e2d3dd..0000000 --- a/arch/x86/boot/multiboot2.S +++ /dev/null @@ -1,248 +0,0 @@ -#define ASM_FILE 1 -#include "multiboot2.h" - -#ifdef KERN_VBE_MODE -#define FRAMEBUFFER_WIDTH 1024 -#define FRAMEBUFFER_HEIGHT 768 -#define FRAMEBUFFER_BPP 24 -#endif /* KERN_VBE_MODE */ - -.code32 -.section .bs.text -.globl _start -_start: - jmp multiboot_entry - -.align 8 -multiboot_header: - .long MULTIBOOT2_HEADER_MAGIC # magic number (multiboot 2) - .long MULTIBOOT_ARCHITECTURE_I386 # architecture 0 (protected mode i386) - .long multiboot_header_end - multiboot_header # header length - # checksum - .long -(MULTIBOOT2_HEADER_MAGIC + MULTIBOOT_ARCHITECTURE_I386 + (multiboot_header_end - multiboot_header)) - # insert optional multiboot tags here - -#ifdef KERN_VBE_MODE - .align 8 - tag_framebuffer: - .short MULTIBOOT_HEADER_TAG_FRAMEBUFFER - .short MULTIBOOT_HEADER_TAG_OPTIONAL - .long tag_framebuffer_end - tag_framebuffer - .long FRAMEBUFFER_WIDTH # screen width - .long FRAMEBUFFER_HEIGHT # screen height - .long FRAMEBUFFER_BPP # bit per pixel - tag_framebuffer_end: -#endif /* KERN_VBE_MODE */ - - # required end tag - .align 8 - .short MULTIBOOT_HEADER_TAG_END # type - .short 0 # flags - .long 8 # size -multiboot_header_end: - -multiboot_entry: - cli - # the magic value - mov %eax, mb2_magic - # the pointer to the Multiboot information structure - mov %ebx, mb2_info - - # 允许 PAE - mov %cr4, %eax - or $(1<<5), %eax - mov %eax, %cr4 - - /* 设置临时页表 */ - # 顶级页目录表 - mov $pml4, %eax - mov $pdpt, %ebx - or $0x07, %ebx - mov %ebx, 0(%eax) - mov %ebx, 2048(%eax) /* 一个页地址占8B,则为 256*8 */ - # 页目录指针表 - mov $pdpt, %eax - mov $pd, %ebx - or $0x07, %ebx - mov %ebx, 0(%eax) - # 页目录表 - mov $512, %ecx - mov $pd, %eax - mov $0x87, %ebx -.pd_loop: - mov %ebx, 0(%eax) - add $0x200000, %ebx - add $0x08, %eax - loop .pd_loop - - # 设置 CR3 - mov $pml4, %eax - mov %eax, %cr3 - - # 切换到 long 模式 - mov $0xC0000080, %ecx - rdmsr - or $(1<<8), %eax - wrmsr - - # 开启分页 - mov %cr0, %eax - or $(1<<31), %eax - mov %eax, %cr0 - - # 重新设置 GDT - mov $gdt64_pointer64, %eax - lgdt 0(%eax) - # 跳转到 64 位代码执行 - jmp $0x8, $_start64 - hlt - ret - -.extern kernel_start -.code64 -go_to_kernel: - .quad kernel_start -_start64: - # 配置 IDT - lidt idt_pointer64(%rip) -setup_IDT: - leaq ignore_int(%rip), %rdx - movq $(0x08 << 16), %rax - movw %dx, %ax - movq $(0x8E00 << 32), %rcx - addq %rcx, %rax - movl %edx, %ecx - shrl $16, %ecx - shlq $48, %rcx - addq %rcx, %rax - shrq $32, %rdx - leaq IDT_Table(%rip), %rdi - mov $256, %rcx -rp_sidt: - movq %rax, (%rdi) - movq %rdx, 8(%rdi) - addq $0x10, %rdi - dec %rcx - jne rp_sidt - - # 更新 - mov $0x10, %rax - mov %rax, %ds - mov %rax, %es - mov %rax, %fs - mov %rax, %gs - mov %rax, %ss - # 设置栈地址 - mov _stack_start(%rip), %rsp - -SetUp_TSS64: - leaq TSS64_Table(%rip), %rdx - xorq %rax, %rax - xorq %rcx, %rcx - movq $0x89, %rax - shlq $40, %rax - movl %edx, %ecx - shrl $24, %ecx - shlq $56, %rcx - addq %rcx, %rax - xorq %rcx, %rcx - movl %edx, %ecx - andl $0xffffff, %ecx - shlq $16, %rcx - addq %rcx, %rax - addq $103, %rax - leaq GDT_Table(%rip), %rdi - movq %rax, 80(%rdi) //tss segment offset - shrq $32, %rdx - movq %rdx, 88(%rdi) //tss+1 segment offset - - movq go_to_kernel(%rip), %rax - pushq $0x08 - pushq %rax - lretq - -.extern IRQ_nothing -go_to_irp_nothing: - .quad IRQ_nothing -ignore_int: - cld - pushq %rax - pushq %rbx - pushq %rcx - pushq %rdx - pushq %rbp - pushq %rdi - pushq %rsi - - pushq %r8 - pushq %r9 - pushq %r10 - pushq %r11 - pushq %r12 - pushq %r13 - pushq %r14 - pushq %r15 - - movq %es, %rax - pushq %rax - movq %ds, %rax - pushq %rax - - movq $0x10, %rax - movq %rax, %ds - movq %rax, %es - - movq go_to_irp_nothing(%rip), %rax - pushq $0x08 - pushq %rax - lretq - -/* - * 临时页表,4KB/页 - */ -.section .bs.data -.align 0x1000 -.global pml4 -pml4: /* 顶级页目录表 */ - .skip 0x1000 -pdpt: /* 页目录指针表*/ - .skip 0x1000 -pd: /* 页目录表 */ - .skip 0x1000 - -.align 16 -.globl GDT_Table -GDT_Table: - .quad 0x0000000000000000 /*0 NULL descriptor 00*/ - .quad 0x0020980000000000 /*1 KERNEL Code 64-bit Segment 08*/ - .quad 0x0000920000000000 /*2 KERNEL Data 64-bit Segment 10*/ - .quad 0x0000000000000000 /*3 USER Code 32-bit Segment 18*/ - .quad 0x0000000000000000 /*4 USER Data 32-bit Segment 20*/ - .quad 0x0020f80000000000 /*5 USER Code 64-bit Segment 28*/ - .quad 0x0000f20000000000 /*6 USER Data 64-bit Segment 30*/ - .quad 0x00cf9a000000ffff /*7 KERNEL Code 32-bit Segment 38*/ - .quad 0x00cf92000000ffff /*8 KERNEL Data 32-bit Segment 40*/ - .fill 10,8,0 /*10 ~ 11 TSS (jmp one segment <9>) in long-mode 128-bit 50*/ -gdt64_pointer64: - .short gdt64_pointer64-GDT_Table-1 - .quad GDT_Table - -.global IDT_Table -IDT_Table: - .fill 512, 8, 0 -idt_pointer64: - .short idt_pointer64-IDT_Table-1 - .quad IDT_Table - -.global TSS64_Table -TSS64_Table: - .fill 13, 8, 0 -TSS64_END: - -.globl mb2_magic -mb2_magic: .quad 0x00 -.globl mb2_info -mb2_info: .quad 0x00 - -_stack_start: - .quad init_task_union + 32768 diff --git a/arch/x86/boot/vmlinux.lds b/arch/x86/boot/vmlinux.lds new file mode 100644 index 0000000..c9a704b --- /dev/null +++ b/arch/x86/boot/vmlinux.lds @@ -0,0 +1,50 @@ +LOAD_OFFSET = 0xffffffff80000000; +OUTPUT_FORMAT("elf64-x86-64", "elf64-x86-64", "elf64-x86-64") +OUTPUT_ARCH(i386:x86-64) +ENTRY(startup) +SECTIONS +{ + . = 16M; + .boot : { + *(.text.head) + *(.data.head) + } + + . += LOAD_OFFSET; + _text = .; + .text : AT(ADDR(.text) - LOAD_OFFSET) { + *(.text) + *(.text.*) + } + _etext = . ; + + .data : AT(ADDR(.data) - LOAD_OFFSET) { + _data = . ; + *(.data) + *(.data.*) + _edata = . ; + } + + _rodata = . ; + .rodata : AT(ADDR(.rodata) - LOAD_OFFSET) { + *(.rodata) /* read-only data */ + *(.rodata.*) + } + _erodata = . ; + + __bss_start = .; + .bss : AT(ADDR(.bss) - LOAD_OFFSET) { + _bss = . ; + *(.bss) + *(.bss.*) + *(COMMON) + . = ALIGN(8); + _end_before_pgt = . ; + . = ALIGN(4096); + pgtable = . ; + . = . + 4096 * 6; + _ebss = .; + } + __bss_stop = .; + _end = .; +} \ No newline at end of file diff --git a/arch/x86/kernel/e820.c b/arch/x86/kernel/e820.c new file mode 100644 index 0000000..3794a8c --- /dev/null +++ b/arch/x86/kernel/e820.c @@ -0,0 +1,85 @@ +#include +#include + +#include +#include + +struct e820map e820; + +static void early_panic(char *msg) { + early_printk(msg); + early_printk("\npanic in e820"); + __asm__("hlt"); +} + +static void e820_print_map(char *who) { + int i; + + for (i = 0; i < e820.nr_map; i++) { + printk(KERN_INFO " %s: %016Lx - %016Lx ", who, + (unsigned long long) e820.map[i].addr, + (unsigned long long) + (e820.map[i].addr + e820.map[i].size)); + switch (e820.map[i].type) { + case E820_RAM: + printk(KERN_CONT "(usable)\n"); + break; + case E820_RESERVED: + printk(KERN_CONT "(reserved)\n"); + break; + case E820_ACPI: + printk(KERN_CONT "(ACPI data)\n"); + break; + case E820_NVS: + printk(KERN_CONT "(ACPI NVS)\n"); + break; + default: + printk(KERN_CONT "type %u\n", e820.map[i].type); + break; + } + } +} + +static int copy_e820_map(struct e820entry *biosmap, int nr_map) { + if (nr_map < 2) { + return -1; + } + + do { + uint64_t start = biosmap->addr; + uint64_t size = biosmap->size; + uint64_t end = start + size; + uint32_t type = biosmap->type; + + /* Overflow in 64 bits? Ignore the memory map. */ + if (start > end) + return -1; + int x = e820.nr_map; + + if (x == E820MAX) { + printk(KERN_ERR "Ooops! Too many entries in the memory map!\n"); + return; + } + + e820.map[x].addr = start; + e820.map[x].size = size; + e820.map[x].type = type; + e820.nr_map++; + } while (biosmap++, --nr_map); + return 0; +} + +char *machine_specific_memory_setup() { + char *who = "BIOS-e820"; + + // e820 数组中,可能存在某些内存段重复,需要将重复的部分分离; + // 而我们暂不处理这种情况,认为 multiboot2 中的内存段不存在重复。 + // 复制 e820 信息 + if (copy_e820_map(boot_params.e820_map, boot_params.e820_entries) < 0) { + early_panic("Cannot find a valid memory map"); + } + printk(KERN_INFO "BIOS-provided physical RAM map:\n"); + + e820_print_map(who); + return who; +} \ No newline at end of file diff --git a/arch/x86/kernel/early_printk.c b/arch/x86/kernel/early_printk.c new file mode 100644 index 0000000..968ca5f --- /dev/null +++ b/arch/x86/kernel/early_printk.c @@ -0,0 +1,59 @@ +#include + +#include +#include + +#include +#include + +#define VGABASE (PAGE_OFFSET + 0xb8000) +static long max_ypos = 25, max_xpos = 80; +static long current_ypos = 25, current_xpos; + +void early_vga_write(struct console *con, const char *str, unsigned n) { + char c; + int i, k, j; + + while ((c = *str++) != '\0' && n-- > 0) { + // 向上滚动一行 + if (current_ypos >= max_ypos) { + for (k = 1, j = 0; k < max_ypos; k++, j++) { + for (i = 0; i < max_xpos; i++) { + writew(readw((void*)(VGABASE+2*(max_xpos*k+i))), (void*)(VGABASE + 2*(max_xpos*j + i))); + } + } + // 将最后一行设置空 + for (i = 0; i < max_xpos; i++) + writew(0x720, (void*)(VGABASE + 2*(max_xpos*j + i))); + current_ypos = max_ypos-1; + } + if (c == '\n') { + current_xpos = 0; + current_ypos++; + } else if (c != '\r') { + writew(((0x7 << 8) | (unsigned short) c), (void*)(VGABASE + 2*(max_xpos*current_ypos + current_xpos++))); + if (current_xpos >= max_xpos) { + current_xpos = 0; + current_ypos++; + } + } + } +} + +static struct console early_vga_console = { + .name = "earlyvga", + .write = early_vga_write +}; + +static struct console *early_console = &early_vga_console; + +void early_printk(const char *fmt, ...) { + char buf[512]; + int n; + va_list ap; + + va_start(ap, fmt); + n = vscnprintf(buf, 512, fmt, ap); + early_console->write(early_console, buf, n); + va_end(ap); +} \ No newline at end of file diff --git a/arch/x86/kernel/head64.c b/arch/x86/kernel/head64.c new file mode 100644 index 0000000..e0bed19 --- /dev/null +++ b/arch/x86/kernel/head64.c @@ -0,0 +1,56 @@ +#include + +#include +#include +#include + +#include +#include + +extern uint64_t mb2_info; + +void clear_bss() { + memset(__bss_start, 0, + (unsigned long) __bss_stop - (unsigned long) __bss_start); +} + +static void mem_info(struct multiboot_tag *tag) { + struct multiboot_tag_mmap *mmap = (struct multiboot_tag_mmap*) tag; + struct multiboot_mmap_entry *entry = mmap->entries; + + uint32_t i = 0; + while ((uint8_t*)entry < (uint8_t*)mmap + mmap->size) { + boot_params.e820_map[i].addr = entry->addr; + boot_params.e820_map[i].size = entry->len; + boot_params.e820_map[i].type = entry->type; + + i++; + entry = (struct multiboot_mmap_entry*)((uint8_t*)entry + mmap->entry_size); + } + boot_params.e820_entries = i; +} + +void parse_sys_info() { + struct multiboot_tag *tag; + for (tag = (struct multiboot_tag*)(mb2_info + MULTIBOOT_TAG_ALIGN); + tag->type != MULTIBOOT_TAG_TYPE_END; + tag = (struct multiboot_tag*)((multiboot_uint8_t *)tag + ((tag->size + 7) & ~7))) { + switch (tag->type) { + case MULTIBOOT_TAG_TYPE_MMAP: + mem_info(tag); + break; + default: + break; + } + } +} + +void x86_64_start_kernel() { + early_printk("x86_64_start_kernel running\n"); + // bss 段清零 + clear_bss(); + // 解析系统信息 + parse_sys_info(); + + start_kernel(); +} \ No newline at end of file diff --git a/arch/x86/kernel/head_64.S b/arch/x86/kernel/head_64.S new file mode 100644 index 0000000..ce9c57a --- /dev/null +++ b/arch/x86/kernel/head_64.S @@ -0,0 +1,177 @@ +#include +#include +#include +#include + +.code32 +.section .text.head +.global startup_64 +.extern print +startup_64: + mov %ebx, mb2_info + + /* 开启 PAE */ + movl %cr4, %eax + btsl $5, %eax + movl %eax, %cr4 + + /* 设置顶级页目录表 */ + movl $(init_level4_pgt - __START_KERNEL_map), %eax + movl %eax, %cr3 + + /* 开启 long 模式 */ + mov $0xC0000080, %ecx + rdmsr + or $(1<<8), %eax + wrmsr + + /* 开启分页 */ + mov %cr0, %eax + or $(1<<31), %eax + mov %eax, %cr0 + + movl $head_cpu_gdt_descr, %eax + lgdt 0(%eax) + jmp $__KERNEL_CS, $secondary_startup_64 + +.code64 +secondary_startup_64: + /* 设置初始任务栈 */ + movq init_rsp(%rip),%rsp + + pushq $0 + popfq + + /* + * 重新设置 gdt descriptor, + * 因为后续低地址空间是用户空间 + */ + lgdt cpu_gdt_descr(%rip) + + mov $__KERNEL_DS, %ax + mov %ax, %ds + mov %ax, %ss + mov %ax, %es + mov %ax, %fs + mov %ax, %gs + +.extern x86_64_start_kernel + movq $x86_64_start_kernel, %rax + pushq $0 + pushq $__KERNEL_CS + pushq %rax + lretq + hlt + +ENTRY(init_rsp) + .quad init_thread_union+THREAD_SIZE-8 +ENTRY(mb2_info) + .quad 0x00 + +.text +.code64 + +.balign PAGE_SIZE +#define NEXT_PAGE(name) \ + .balign PAGE_SIZE; \ +ENTRY(name) + +#define PMDS(START, PERM, COUNT) \ + i = 0 ; \ + .rept (COUNT) ; \ + .quad (START) + (i << 21) + (PERM) ; \ + i = i + 1 ; \ + .endr + +NEXT_PAGE(init_level4_pgt) + .quad level3_ident_pgt - __START_KERNEL_map + _KERNPG_TABLE + .fill 257,8,0 + .quad level3_ident_pgt - __START_KERNEL_map + _KERNPG_TABLE + .fill 252,8,0 + /* (2^48-(2*1024*1024*1024))/(2^39) = 511 */ + .quad level3_kernel_pgt - __START_KERNEL_map + _PAGE_TABLE + +NEXT_PAGE(level3_ident_pgt) + .quad level2_ident_pgt - __START_KERNEL_map + _KERNPG_TABLE + .fill 511,8,0 + +NEXT_PAGE(level3_kernel_pgt) + .fill 510,8,0 + /* (2^48-(2*1024*1024*1024)-((2^39)*511))/(2^30) = 510 */ + .quad level2_kernel_pgt - __START_KERNEL_map + _KERNPG_TABLE + .quad level2_fixmap_pgt - __START_KERNEL_map + _PAGE_TABLE + +NEXT_PAGE(level2_fixmap_pgt) + .fill 506,8,0 + .quad level1_fixmap_pgt - __START_KERNEL_map + _PAGE_TABLE + /* 8MB reserved for vsyscalls + a 2MB hole = 4 + 1 entries */ + .fill 5,8,0 + +NEXT_PAGE(level1_fixmap_pgt) + .fill 512,8,0 + +NEXT_PAGE(level2_ident_pgt) + /* Since I easily can, map the first 1G. + * Don't set NX because code runs from these pages. + */ + PMDS(0, __PAGE_KERNEL_LARGE_EXEC, PTRS_PER_PMD) + +NEXT_PAGE(level2_kernel_pgt) + /* + * 512 MB kernel mapping. We spend a full page on this pagetable + * anyway. + * + * The kernel code+data+bss must not be bigger than that. + * + * (NOTE: at +512MB starts the module area, see MODULES_VADDR. + * If you want to increase this then increase MODULES_VADDR + * too.) + */ + PMDS(0, __PAGE_KERNEL_LARGE_EXEC|_PAGE_GLOBAL, KERNEL_IMAGE_SIZE/PMD_SIZE) + +NEXT_PAGE(level2_spare_pgt) + .fill 512,8,0 + +#undef PMDS +#undef NEXT_PAGE + +ENTRY(phys_base) + /* This must match the first entry in level2_kernel_pgt */ + .quad 0x0000000000000000 + + .section .data.head + .align 16 +head_cpu_gdt_descr: + .word gdt_end-cpu_gdt_table-1 + .quad cpu_gdt_table - __START_KERNEL_map + + .data + .align 16 + .globl cpu_gdt_descr +cpu_gdt_descr: + .word gdt_end-cpu_gdt_table-1 +gdt: + .quad cpu_gdt_table + +ENTRY(cpu_gdt_table) + .quad 0x0000000000000000 /* NULL descriptor */ + .quad 0x00cf9b000000ffff /* __KERNEL32_CS */ + .quad 0x00af9b000000ffff /* __KERNEL_CS */ + .quad 0x00cf93000000ffff /* __KERNEL_DS */ + .quad 0x00cffb000000ffff /* __USER32_CS */ + .quad 0x00cff3000000ffff /* __USER_DS, __USER32_DS */ + .quad 0x00affb000000ffff /* __USER_CS */ + .quad 0x0 /* unused */ + .quad 0,0 /* TSS */ + .quad 0,0 /* LDT */ + .quad 0,0,0 /* three TLS descriptors */ + .quad 0x0000f40000000000 /* node/CPU stored in limit */ +gdt_end: + +ENTRY(idt_table) + .skip 256 * 16 + + .section .bss.page_aligned, "aw", @nobits + .align PAGE_SIZE +ENTRY(empty_zero_page) + .skip PAGE_SIZE \ No newline at end of file diff --git a/arch/x86/kernel/init_task.c b/arch/x86/kernel/init_task.c new file mode 100644 index 0000000..5de5e3c --- /dev/null +++ b/arch/x86/kernel/init_task.c @@ -0,0 +1,8 @@ +#include +#include + +union thread_union init_thread_union + __attribute__((__section__(".data.init_task"))) = + { INIT_THREAD_INFO(init_task) }; + + diff --git a/arch/x86/kernel/setup.c b/arch/x86/kernel/setup.c new file mode 100644 index 0000000..3248a1f --- /dev/null +++ b/arch/x86/kernel/setup.c @@ -0,0 +1,13 @@ +#include + +#include + +struct boot_params boot_params; + +void memory_setup() { + machine_specific_memory_setup(); +} + +void setup_arch() { + memory_setup(); +} \ No newline at end of file diff --git a/build_iso.sh b/build_iso.sh deleted file mode 100644 index fb2969a..0000000 --- a/build_iso.sh +++ /dev/null @@ -1,31 +0,0 @@ -#!/bin/bash - -HOST_OS=`uname -s` -if [ "$HOST_OS" != "Linux" ]; then - echo "Currently only supports Linux system." - exit -fi - -GRUB_PATH="$(dirname $(which grub-file))" - -# creating root directory of iso and removing all files -ISO_PATH="$(dirname $0)/iso" -mkdir -p $ISO_PATH -rm -rf ${ISO_PATH}/* - -ISO_BOOT="${ISO_PATH}/boot" -ISO_BOOT_GRUB="${ISO_BOOT}/grub" -mkdir -p $ISO_BOOT_GRUB - -cp kernel.elf ${ISO_BOOT}/kernel.elf - -# set grub.cfg -touch "${ISO_BOOT_GRUB}/grub.cfg" -echo 'set timeout=0 -set default=0 -menuentry "HelloOS" { - multiboot2 /boot/kernel.elf "KERNEL" -}' >${ISO_BOOT_GRUB}/grub.cfg - -${GRUB_PATH}/grub-mkrescue -o HelloOS.iso ${ISO_PATH} -rm -rf ${ISO_PATH} diff --git a/docs/QA.md b/docs/QA.md index 7bd1a13..6b1bbb6 100644 --- a/docs/QA.md +++ b/docs/QA.md @@ -1,4 +1,4 @@ -Q: **lretq 模拟远程调用,方法:** +## lretq 模拟远程调用 ```assembly pushq 0x08 # cs pushq %rax # ip @@ -9,9 +9,32 @@ pushq %rax # ip lretq ``` -**如何识别是否设置了 cs 寄存器?** +## 关于 gcc -mcmodel 使用 +在编译下面代码时: +``` c +void x86_64_start_kernel() { + early_printk("hello world"); -A:在段间访问的时候才用设置 cs 寄存器。 - ---- + start_kernel(); +} +``` +出现了 `relocation truncated to fit: R_X86_64_32 against .rodata'` 问题,反编译后的目标文件 `objdump -dra xx.o`: +``` +000000000000000b : + b: f3 0f 1e fa endbr64 + f: 55 push %rbp + 10: 48 89 e5 mov %rsp,%rbp + 13: bf 00 00 00 00 mov $0x0,%edi + 14: R_X86_64_32 .rodata + 18: b8 00 00 00 00 mov $0x0,%eax + 1d: e8 00 00 00 00 call 22 + 1e: R_X86_64_PLT32 early_printk-0x4 + 22: b8 00 00 00 00 mov $0x0,%eax + 27: e8 00 00 00 00 call 2c + 28: R_X86_64_PLT32 start_kernel-0x4 + 2c: 90 nop + 2d: 5d pop %rbp + 2e: c3 ret +``` +字符串常量 `hello world` 存储在 `.rodata` 段中,但使用的是 `R_X86_64_32`,解决方法是在编译该源文件时,使用 `gcc -mcmodel xx`。 diff --git a/drivers/Makefile b/drivers/Makefile deleted file mode 100644 index 547e027..0000000 --- a/drivers/Makefile +++ /dev/null @@ -1,13 +0,0 @@ -SOURCE := $(shell find . -name "*.c") -OBJS := $(SOURCE:%.c=%.o) -CFLAGS = -c -I../include --static \ - -mcmodel=large -fno-pie -fno-builtin \ - -fno-stack-protector -m64 - -build: $(OBJS) - -$(OBJS):%.o:%.c - gcc $(CFLAGS) -o $@ $< - -clean: - rm -rf $(OBJS) *.o \ No newline at end of file diff --git a/drivers/ata/ata.c b/drivers/ata/ata.c deleted file mode 100644 index 17ee1c5..0000000 --- a/drivers/ata/ata.c +++ /dev/null @@ -1,135 +0,0 @@ -#include "ata.h" -#include "lib.h" -#include "kstring.h" -#include "printk.h" -#include "types.h" -void read_sectors_ATA_PIO(uint32_t target_address, uint32_t LBA, uint8_t sector_count); -void write_sectors_ATA_PIO(uint32_t LBA, uint8_t sector_count, uint32_t* bytes); - -void ata_init() { - // io_out8(PORT_DISK1_ALT_STA_CTL, 0); - - // while(io_in8(PORT_DISK1_STATUS_CMD) & DISK_STATUS_BUSY); - // kerr_printf("Read One Sector Starting:%02x\n",io_in8(PORT_DISK1_STATUS_CMD)); - - // // io_out8(PORT_DISK1_DEVICE, 0x0); - // io_out8(PORT_DISK1_ERR_FEATURE, 0); - // io_out8(PORT_DISK1_SECTION_CNT, 1); - // io_out8(PORT_DISK1_SECTION_LOW, 0); - // io_out8(PORT_DISK1_SECTION_MID, 0); - // io_out8(PORT_DISK1_SECTION_HIGH, 0); - - // io_out8(PORT_DISK1_STATUS_CMD, 0x30); - - // while(!(io_in8(PORT_DISK1_STATUS_CMD) & DISK_STATUS_REQ)); - // kerr_printf("Send CMD:%02x\n",io_in8(PORT_DISK1_STATUS_CMD)); - - // unsigned char buf[512]; - // memset(buf, 0xAA, 512); - // port_outsw(PORT_DISK1_DATA, buf, 256); - - uint32_t bwrite[128]; - memset(bwrite, 0xABCDEF12, 128); - write_sectors_ATA_PIO(0x0, 1, bwrite); - - uint32_t buf[128]; - read_sectors_ATA_PIO(buf, 0x0, 1); - for (int i = 0; i < 10; i++) { - kerr_printf("%x ", buf[i]&0xff); - kerr_printf("%x ", (buf[i]>>8)&0xff); - } - kerr_printf("\n"); -} - -void ata_handler_read(unsigned long nr, unsigned long r) { - // struct Disk_Identify_Info info; - // // kprintf("Origin Serial Number: "); - // // for (int i = 0; i < 10; i++) { - // // kerr_printf("%x%x", ((info.Serial_Number[i]>>8)&0xff), (info.Serial_Number[i] & 0xff)); - // // } - // // kprintf("\n"); - // port_insw(PORT_DISK1_DATA, &info, 256); - - // kprintf("Serial Number: "); - // for (int i = 0; i < 10; i++) { - // kerr_printf("%x%x", ((info.Serial_Number[i]>>8)&0xff), (info.Serial_Number[i] & 0xff)); - // } - // kprintf("\n"); - - // int i = 0; - // unsigned char a[512]; - // port_insw(PORT_DISK1_DATA, &a, 256); - // kerr_printf("Read One Sector Finished:%02x\n",io_in8(PORT_DISK1_STATUS_CMD)); - // for(i = 0; i<10; i++) - // kerr_printf("%02x ",a[i]); -} - -void ata_handler_write(unsigned long nr, unsigned long r) { - kerr_printf("write success!!!!!\n"); -} - - -#define STATUS_BSY 0x80 -#define STATUS_RDY 0x40 -#define STATUS_DRQ 0x08 -#define STATUS_DF 0x20 -#define STATUS_ERR 0x01 - -//This is really specific to out OS now, assuming ATA bus 0 master -//Source - OsDev wiki -static void ATA_wait_BSY(); -static void ATA_wait_DRQ(); -void read_sectors_ATA_PIO(uint32_t target_address, uint32_t LBA, uint8_t sector_count) -{ - - ATA_wait_BSY(); - io_out8(0x1F6,0xE0 | ((LBA >>24) & 0xF)); - io_out8(0x1F2,sector_count); - io_out8(0x1F3, (uint8_t) LBA); - io_out8(0x1F4, (uint8_t)(LBA >> 8)); - io_out8(0x1F5, (uint8_t)(LBA >> 16)); - io_out8(0x1F7,0x20); //Send the read command - - uint16_t *target = (uint16_t*) target_address; - - for (int j =0;j>24) & 0xF)); - io_out8(0x1F2,sector_count); - io_out8(0x1F3, (uint8_t) LBA); - io_out8(0x1F4, (uint8_t)(LBA >> 8)); - io_out8(0x1F5, (uint8_t)(LBA >> 16)); - io_out8(0x1F7,0x30); //Send the write command - - for (int j =0;j + +struct boot_params { + __u32 e820_entries; + struct e820entry e820_map[E820MAX]; +}; + +extern struct boot_params boot_params; + +#endif \ No newline at end of file diff --git a/include/asm/desc.h b/include/asm/desc.h new file mode 100644 index 0000000..1b8d22d --- /dev/null +++ b/include/asm/desc.h @@ -0,0 +1,67 @@ +#ifndef _ASM_X86_DESC_H +#define _ASM_X86_DESC_H + +#include +#include + +#include + +#define PTR_LOW(x) ((unsigned long long)(x) & 0xFFFF) +#define PTR_MIDDLE(x) (((unsigned long long)(x) >> 16) & 0xFFFF) +#define PTR_HIGH(x) ((unsigned long long)(x) >> 32) + +extern gate_desc idt_table[]; + +struct gate_struct64 { + uint16_t offset_low; + uint16_t segment; + unsigned ist : 3, zero0 : 5, type : 5, dpl : 2, p : 1; + uint16_t offset_middle; + uint32_t offset_high; + uint32_t zero1; +} __attribute__((packed)); + +typedef struct gate_struct64 gate_desc; + +enum { + GATE_INTERRUPT = 0xE, + GATE_TRAP = 0xF, + GATE_CALL = 0xC, + GATE_TASK = 0x5, +}; + +static inline void pack_gate(gate_desc *gate, unsigned type, unsigned long func, + unsigned dpl, unsigned ist, unsigned seg) { + gate->offset_low = PTR_LOW(func); + gate->segment = __KERNEL_CS; + gate->ist = ist; + gate->p = 1; + gate->dpl = dpl; + gate->zero0 = 0; + gate->zero1 = 0; + gate->type = type; + gate->offset_middle = PTR_MIDDLE(func); + gate->offset_high = PTR_HIGH(func); +} + +static inline void write_idt_entry(gate_desc *idt, int entry, + const gate_desc *gate) { + memcpy(&idt[entry], gate, sizeof(*gate)); +} + +static inline void _set_gate(int gate, unsigned type, void *addr, + unsigned dpl, unsigned ist, unsigned seg) { + gate_desc s; + pack_gate(&s, type, (unsigned long)addr, dpl, ist, seg); + /* + * does not need to be atomic because it is only done once at + * setup time + */ + write_idt_entry(idt_table, gate, &s); +} + +static inline void set_intr_gate(unsigned int n, void *addr) { + _set_gate(n, GATE_INTERRUPT, addr, 0, 0, __KERNEL_CS); +} + +#endif \ No newline at end of file diff --git a/include/asm/div64.h b/include/asm/div64.h new file mode 100644 index 0000000..1a77fd9 --- /dev/null +++ b/include/asm/div64.h @@ -0,0 +1,14 @@ +#ifndef _ASM_DIV64_H +#define _ASM_DIV64_H + +#include + +# define do_div(n,base) ({ \ + uint32_t __base = (base); \ + uint32_t __rem; \ + __rem = ((uint64_t)(n)) % __base; \ + (n) = ((uint64_t)(n)) / __base; \ + __rem; \ + }) + +#endif \ No newline at end of file diff --git a/include/asm/e820.h b/include/asm/e820.h new file mode 100644 index 0000000..204d0f3 --- /dev/null +++ b/include/asm/e820.h @@ -0,0 +1,25 @@ +#ifndef _ASM_E820_H +#define _ASM_E820_H + +#include + +#define E820MAX 128 + +#define E820_RAM 1 +#define E820_RESERVED 2 +#define E820_ACPI 3 +#define E820_NVS 4 + +struct e820entry { + __u64 addr; /* start of memory segment */ + __u64 size; /* size of memory segment */ + __u32 type; /* type of memory segment */ +} __attribute__((packed)); + +struct e820map { + __u32 nr_map; + struct e820entry map[E820MAX]; +}; + +extern struct e820map e820; +#endif \ No newline at end of file diff --git a/include/asm/io.h b/include/asm/io.h new file mode 100644 index 0000000..a8c42b9 --- /dev/null +++ b/include/asm/io.h @@ -0,0 +1,56 @@ +#ifndef _ASM_X86_IO_H +#define _ASM_X86_IO_H + +#include + +static inline __u8 __readb(const volatile void *addr) +{ + return *(volatile __u8 *)addr; +} + +static inline __u16 __readw(const volatile void *addr) +{ + return *(volatile __u16 *)addr; +} + +static inline __u32 __readl(const volatile void *addr) +{ + return *(volatile __u32 *)addr; +} + +static inline __u64 __readq(const volatile void *addr) +{ + return *(volatile __u64 *)addr; +} + +#define readb(x) __readb(x) +#define readw(x) __readw(x) +#define readl(x) __readl(x) +#define readq(x) __readq(x) + +static inline void __writel(__u32 b, volatile void *addr) +{ + *(volatile __u32 *)addr = b; +} + +static inline void __writeq(__u64 b, volatile void *addr) +{ + *(volatile __u64 *)addr = b; +} + +static inline void __writeb(__u8 b, volatile void *addr) +{ + *(volatile __u8 *)addr = b; +} + +static inline void __writew(__u16 b, volatile void *addr) +{ + *(volatile __u16 *)addr = b; +} + +#define writeq(val, addr) __writeq((val), (addr)) +#define writel(val, addr) __writel((val), (addr)) +#define writew(val, addr) __writew((val), (addr)) +#define writeb(val, addr) __writeb((val), (addr)) + +#endif \ No newline at end of file diff --git a/include/multiboot2.h b/include/asm/multiboot2.h similarity index 100% rename from include/multiboot2.h rename to include/asm/multiboot2.h diff --git a/include/asm/page.h b/include/asm/page.h new file mode 100644 index 0000000..9b01070 --- /dev/null +++ b/include/asm/page.h @@ -0,0 +1,36 @@ +#ifndef _ASM_X86_PAGE_H +#define _ASM_X86_PAGE_H + +#include + +/* + * 页面大小等 + */ +#define PAGE_SHIFT 12 +#define PAGE_SIZE (_AC(1,UL) << PAGE_SHIFT) +#define PAGE_MASK (~(PAGE_SIZE-1)) +#define PAGE_OFFSET _AC(0xffff810000000000, UL) + +#define THREAD_ORDER 1 +#define THREAD_SIZE (PAGE_SIZE << THREAD_ORDER) + +#define PMD_SHIFT 21 +#define PTRS_PER_PMD 512 +#define PMD_SIZE (_AC(1, UL) << PMD_SHIFT) +#define PMD_MASK (~(PMD_SIZE - 1)) + +#define __PHYSICAL_START 0x200000 +#define __START_KERNEL_map _AC(0xffffffff80000000, UL) +#define __START_KERNEL (__START_KERNEL_map + __PHYSICAL_START) + +/* + * 内核镜像限制为 512MB + */ +#define KERNEL_IMAGE_SIZE (512 * 1024 * 1024) +#define KERNEL_IMAGE_START _AC(0xffffffff80000000, UL) + +#define __pa(x) ((unsigned long)(x)-PAGE_OFFSET) +#define __va(x) ((void *)((unsigned long)(x)+PAGE_OFFSET)) + + +#endif \ No newline at end of file diff --git a/include/asm/pgtable.h b/include/asm/pgtable.h new file mode 100644 index 0000000..052f142 --- /dev/null +++ b/include/asm/pgtable.h @@ -0,0 +1,75 @@ +#ifndef _ASM_X86_PGTABLE_H +#define _ASM_X86_PGTABLE_H + +#define FIRST_USER_ADDRESS 0 + +#define _PAGE_BIT_PRESENT 0 /* is present */ +#define _PAGE_BIT_RW 1 /* writeable */ +#define _PAGE_BIT_USER 2 /* userspace addressable */ +#define _PAGE_BIT_PWT 3 /* page write through */ +#define _PAGE_BIT_PCD 4 /* page cache disabled */ +#define _PAGE_BIT_ACCESSED 5 /* was accessed (raised by CPU) */ +#define _PAGE_BIT_DIRTY 6 /* was written to (raised by CPU) */ +#define _PAGE_BIT_FILE 6 +#define _PAGE_BIT_PSE 7 /* 4 MB (or 2MB) page */ +#define _PAGE_BIT_PAT 7 /* on 4KB pages */ +#define _PAGE_BIT_GLOBAL 8 /* Global TLB entry PPro+ */ +#define _PAGE_BIT_UNUSED1 9 /* available for programmer */ +#define _PAGE_BIT_UNUSED2 10 +#define _PAGE_BIT_UNUSED3 11 +#define _PAGE_BIT_PAT_LARGE 12 /* On 2MB or 1GB pages */ +#define _PAGE_BIT_NX 63 /* No execute: only valid after cpuid check */ + +#define _PAGE_PRESENT (_AC(1, L)<<_PAGE_BIT_PRESENT) +#define _PAGE_RW (_AC(1, L)<<_PAGE_BIT_RW) +#define _PAGE_USER (_AC(1, L)<<_PAGE_BIT_USER) +#define _PAGE_PWT (_AC(1, L)<<_PAGE_BIT_PWT) +#define _PAGE_PCD (_AC(1, L)<<_PAGE_BIT_PCD) +#define _PAGE_ACCESSED (_AC(1, L)<<_PAGE_BIT_ACCESSED) +#define _PAGE_DIRTY (_AC(1, L)<<_PAGE_BIT_DIRTY) +#define _PAGE_PSE (_AC(1, L)<<_PAGE_BIT_PSE) /* 2MB page */ +#define _PAGE_GLOBAL (_AC(1, L)<<_PAGE_BIT_GLOBAL) /* Global TLB entry */ +#define _PAGE_UNUSED1 (_AC(1, L)<<_PAGE_BIT_UNUSED1) +#define _PAGE_UNUSED2 (_AC(1, L)<<_PAGE_BIT_UNUSED2) +#define _PAGE_UNUSED3 (_AC(1, L)<<_PAGE_BIT_UNUSED3) +#define _PAGE_PAT (_AC(1, L)<<_PAGE_BIT_PAT) +#define _PAGE_PAT_LARGE (_AC(1, L)<<_PAGE_BIT_PAT_LARGE) + +#define _PAGE_NX (_AC(1, ULL) << _PAGE_BIT_NX) + +#define _PAGE_TABLE (_PAGE_PRESENT | _PAGE_RW | _PAGE_USER | \ + _PAGE_ACCESSED | _PAGE_DIRTY) +#define _KERNPG_TABLE (_PAGE_PRESENT | _PAGE_RW | _PAGE_ACCESSED | \ + _PAGE_DIRTY) + +#define _PAGE_CHG_MASK (PTE_MASK | _PAGE_PCD | _PAGE_PWT | \ + _PAGE_ACCESSED | _PAGE_DIRTY) + +#define _PAGE_CACHE_MASK (_PAGE_PCD | _PAGE_PWT) +#define _PAGE_CACHE_WB (0) +#define _PAGE_CACHE_WC (_PAGE_PWT) +#define _PAGE_CACHE_UC_MINUS (_PAGE_PCD) +#define _PAGE_CACHE_UC (_PAGE_PCD | _PAGE_PWT) + +#define PAGE_NONE __pgprot(_PAGE_PROTNONE | _PAGE_ACCESSED) +#define PAGE_SHARED __pgprot(_PAGE_PRESENT | _PAGE_RW | _PAGE_USER | \ + _PAGE_ACCESSED | _PAGE_NX) + +#define PAGE_SHARED_EXEC __pgprot(_PAGE_PRESENT | _PAGE_RW | \ + _PAGE_USER | _PAGE_ACCESSED) +#define PAGE_COPY_NOEXEC __pgprot(_PAGE_PRESENT | _PAGE_USER | \ + _PAGE_ACCESSED | _PAGE_NX) +#define PAGE_COPY_EXEC __pgprot(_PAGE_PRESENT | _PAGE_USER | \ + _PAGE_ACCESSED) +#define PAGE_COPY PAGE_COPY_NOEXEC +#define PAGE_READONLY __pgprot(_PAGE_PRESENT | _PAGE_USER | \ + _PAGE_ACCESSED | _PAGE_NX) +#define PAGE_READONLY_EXEC __pgprot(_PAGE_PRESENT | _PAGE_USER | \ + _PAGE_ACCESSED) + +#define __PAGE_KERNEL_EXEC \ + (_PAGE_PRESENT | _PAGE_RW | _PAGE_DIRTY | _PAGE_ACCESSED) +#define __PAGE_KERNEL_LARGE_EXEC (__PAGE_KERNEL_EXEC | _PAGE_PSE) + + +#endif \ No newline at end of file diff --git a/include/asm/posix_types_64.h b/include/asm/posix_types_64.h new file mode 100644 index 0000000..1496968 --- /dev/null +++ b/include/asm/posix_types_64.h @@ -0,0 +1,9 @@ +#ifndef _ASM_X86_64_POSIX_TYPES_H +#define _ASM_X86_64_POSIX_TYPES_H + +typedef unsigned long __kernel_size_t; +typedef long __kernel_ssize_t; + +typedef long __kernel_ptrdiff_t; + +#endif \ No newline at end of file diff --git a/include/asm/segment.h b/include/asm/segment.h new file mode 100644 index 0000000..fb76c07 --- /dev/null +++ b/include/asm/segment.h @@ -0,0 +1,9 @@ +#ifndef _ASM_SEGMENT_H +#define _ASM_SEGMENT_H + +#define __KERNEL_CS 0x10 +#define __KERNEL_DS 0x18 + +#define __KERNEL32_CS 0x08 + +#endif \ No newline at end of file diff --git a/include/asm/setup.h b/include/asm/setup.h new file mode 100644 index 0000000..073dbc1 --- /dev/null +++ b/include/asm/setup.h @@ -0,0 +1,6 @@ +#ifndef _ASM_X86_SETUP_H +#define _ASM_X86_SETUP_H + +char *machine_specific_memory_setup(); + +#endif \ No newline at end of file diff --git a/include/asm/string.h b/include/asm/string.h new file mode 100644 index 0000000..6d885ca --- /dev/null +++ b/include/asm/string.h @@ -0,0 +1,7 @@ +#ifndef _ASM_X86_STRING_H +#define _OS_STRING_H + +#include + + +#endif \ No newline at end of file diff --git a/include/asm/thread_info.h b/include/asm/thread_info.h new file mode 100644 index 0000000..39be49e --- /dev/null +++ b/include/asm/thread_info.h @@ -0,0 +1,12 @@ +#ifndef _ASM_X86_THREAD_INFO_H +#define _ASM_X86_THREAD_INFO_H + +struct thread_info { + +}; + +#define INIT_THREAD_INFO(tsk) \ +{ \ +} + +#endif \ No newline at end of file diff --git a/include/asm/types.h b/include/asm/types.h new file mode 100644 index 0000000..0934e4c --- /dev/null +++ b/include/asm/types.h @@ -0,0 +1,7 @@ +#ifndef _ASM_X86_TYPES_H +#define _ASM_X86_TYPES_H + +#include +#include + +#endif \ No newline at end of file diff --git a/include/ata.h b/include/ata.h deleted file mode 100644 index 9ce7715..0000000 --- a/include/ata.h +++ /dev/null @@ -1,339 +0,0 @@ -#ifndef _HELLOOS_ATA_H -#define _HELLOOS_ATA_H - -#define PORT_DISK0_DATA 0x1f0 -#define PORT_DISK0_ERR_FEATURE 0x1f1 -#define PORT_DISK0_SECTION_CNT 0x1f2 -#define PORT_DISK0_SECTION_LOW 0x1f3 -#define PORT_DISK0_SECTION_MID 0x1f4 -#define PORT_DISK0_SECTION_HIGH 0x1f5 -#define PORT_DISK0_DEVICE 0x1f6 -#define PORT_DISK0_STATUS_CMD 0x1f7 -#define PORT_DISK0_ALT_STA_CTL 0x3f6 - -#define PORT_DISK1_DATA 0x170 -#define PORT_DISK1_ERR_FEATURE 0x171 -#define PORT_DISK1_SECTION_CNT 0x172 -#define PORT_DISK1_SECTION_LOW 0x173 -#define PORT_DISK1_SECTION_MID 0x174 -#define PORT_DISK1_SECTION_HIGH 0x175 -#define PORT_DISK1_DEVICE 0x176 -#define PORT_DISK1_STATUS_CMD 0x177 -#define PORT_DISK1_ALT_STA_CTL 0x376 - -#define DISK_STATUS_BUSY (1 << 7) -#define DISK_STATUS_READY (1 << 6) -#define DISK_STATUS_SEEK (1 << 4) -#define DISK_STATUS_REQ (1 << 3) -#define DISK_STATUS_ERROR (1 << 0) - -struct Disk_Identify_Info { - // 0 General configuration bit-significant information - unsigned short General_Config; - - // 1 Obsolete - unsigned short Obsolete0; - - // 2 Specific configuration - unsigned short Specific_Coinfig; - - // 3 Obsolete - unsigned short Obsolete1; - - // 4-5 Retired - unsigned short Retired0[2]; - - // 6 Obsolete - unsigned short Obsolete2; - - // 7-8 Reserved for the CompactFlash Association - unsigned short CompactFlash[2]; - - // 9 Retired - unsigned short Retired1; - - // 10-19 Serial number (20 ASCII characters) - unsigned short Serial_Number[10]; - - // 20-21 Retired - unsigned short Retired2[2]; - - // 22 Obsolete - unsigned short Obsolete3; - - // 23-26 Firmware revision(8 ASCII characters) - unsigned short Firmware_Version[4]; - - // 27-46 Model number (40 ASCII characters) - unsigned short Model_Number[20]; - - // 47 15:8 80h - // 7:0 00h=Reserved - // 01h-FFh = Maximumnumber of logical sectors that shall be transferred per DRQ data block on READ/WRITE MULTIPLE commands - unsigned short Max_logical_transferred_per_DRQ; - - // 48 Trusted Computing feature set options - unsigned short Trusted_Computing_feature_set_options; - - // 49 Capabilities - unsigned short Capabilities0; - - // 50 Capabilities - unsigned short Capabilities1; - - // 51-52 Obsolete - unsigned short Obsolete4[2]; - - // 53 15:8 Free-fall Control Sensitivity - // 7:3 Reserved - // 2 the fields reported in word 88 are valid - // 1 the fields reported in words (70:64) are valid - unsigned short Report_88_70to64_valid; - - // 54-58 Obsolete - unsigned short Obsolete5[5]; - - // 59 15:9 Reserved - // 8 Multiple sector setting is valid - // 7:0 xxh current setting for number of logical sectors that shall be transferred per DRQ data block on READ/WRITE Multiple commands - unsigned short Mul_Sec_Setting_Valid; - - // 60-61 Total number of user addresssable logical sectors for 28bit CMD - unsigned short Addressable_Logical_Sectors_for_28[2]; - - // 62 Obsolete - unsigned short Obsolete6; - - // 63 15:11 Reserved - // 10:8=1 Multiword DMA mode 210 is selected - // 7:3 Reserved - // 2:0=1 Multiword DMA mode 210 and below are supported - unsigned short MultWord_DMA_Select; - - // 64 15:8 Reserved - // 7:0 PIO mdoes supported - unsigned short PIO_mode_supported; - - // 65 Minimum Multiword DMA transfer cycle time per word - unsigned short Min_MulWord_DMA_cycle_time_per_word; - - // 66 Manufacturer`s recommended Multiword DMA transfer cycle time - unsigned short Manufacture_Recommend_MulWord_DMA_cycle_time; - - // 67 Minimum PIO transfer cycle time without flow control - unsigned short Min_PIO_cycle_time_Flow_Control; - - // 68 Minimum PIO transfer cycle time with IORDY flow control - unsigned short Min_PIO_cycle_time_IOREDY_Flow_Control; - - // 69-70 Reserved - unsigned short Reserved1[2]; - - // 71-74 Reserved for the IDENTIFY PACKET DEVICE command - unsigned short Reserved2[4]; - - // 75 Queue depth - unsigned short Queue_depth; - - // 76 Serial ATA Capabilities - unsigned short SATA_Capabilities; - - // 77 Reserved for Serial ATA - unsigned short Reserved3; - - // 78 Serial ATA features Supported - unsigned short SATA_features_Supported; - - // 79 Serial ATA features enabled - unsigned short SATA_features_enabled; - - // 80 Major Version number - unsigned short Major_Version; - - // 81 Minor version number - unsigned short Minor_Version; - - // 82 Commands and feature sets supported - unsigned short Cmd_feature_sets_supported0; - - // 83 Commands and feature sets supported - unsigned short Cmd_feature_sets_supported1; - - // 84 Commands and feature sets supported - unsigned short Cmd_feature_sets_supported2; - - // 85 Commands and feature sets supported or enabled - unsigned short Cmd_feature_sets_supported3; - - // 86 Commands and feature sets supported or enabled - unsigned short Cmd_feature_sets_supported4; - - // 87 Commands and feature sets supported or enabled - unsigned short Cmd_feature_sets_supported5; - - // 88 15 Reserved - // 14:8=1 Ultra DMA mode 6543210 is selected - // 7 Reserved - // 6:0=1 Ultra DMA mode 6543210 and below are suported - unsigned short Ultra_DMA_modes; - - // 89 Time required for Normal Erase mode SECURITY ERASE UNIT command - unsigned short Time_required_Erase_CMD; - - // 90 Time required for an Enhanced Erase mode SECURITY ERASE UNIT command - unsigned short Time_required_Enhanced_CMD; - - // 91 Current APM level value - unsigned short Current_APM_level_Value; - - // 92 Master Password Identifier - unsigned short Master_Password_Identifier; - - // 93 Hardware resset result.The contents of bits (12:0) of this word shall change only during the execution of a hardware reset. - unsigned short HardWare_Reset_Result; - - // 94 Current AAM value - // 15:8 Vendor’s recommended AAM value - // 7:0 Current AAM value - unsigned short Current_AAM_value; - - // 95 Stream Minimum Request Size - unsigned short Stream_Min_Request_Size; - - // 96 Streaming Transger Time-DMA - unsigned short Streaming_Transger_time_DMA; - - // 97 Streaming Access Latency-DMA and PIO - unsigned short Streaming_Access_Latency_DMA_PIO; - - // 98-99 Streaming Performance Granularity (DWord) - unsigned short Streaming_Performance_Granularity[2]; - - // 100-103 Total Number of User Addressable Logical Sectors for 48-bit commands (QWord) - unsigned short Total_user_LBA_for_48_Address_Feature_set[4]; - - // 104 Streaming Transger Time-PIO - unsigned short Streaming_Transfer_Time_PIO; - - // 105 Reserved - unsigned short Reserved4; - - // 106 Physical Sector size/Logical Sector Size - unsigned short Physical_Logical_Sector_Size; - - // 107 Inter-seek delay for ISO-7779 acoustic testing in microseconds - unsigned short Inter_seek_delay; - - // 108-111 World wide name - unsigned short World_wide_name[4]; - - // 112-115 Reserved - unsigned short Reserved5[4]; - - // 116 Reserved for TLC - unsigned short Reserved6; - - // 117-118 Logical sector size (DWord) - unsigned short Words_per_Logical_Sector[2]; - - // 119 Commands and feature sets supported (Continued from words 84:82) - unsigned short CMD_feature_Supported; - - // 120 Commands and feature sets supported or enabled (Continued from words 87:85) - unsigned short CMD_feature_Supported_enabled; - - // 121-126 Reserved for expanded supported and enabled settings - unsigned short Reserved7[6]; - - // 127 Obsolete - unsigned short Obsolete7; - - // 128 Security status - unsigned short Security_Status; - - // 129-159 Vendor specific - unsigned short Vendor_Specific[31]; - - // 160 CFA power mode - unsigned short CFA_Power_mode; - - // 161-167 Reserved for the CompactFlash Association - unsigned short Reserved8[7]; - - // 168 Device Nominal Form Factor - unsigned short Dev_from_Factor; - - // 169-175 Reserved - unsigned short Reserved9[7]; - - // 176-205 Current media serial number (ATA string) - unsigned short Current_Media_Serial_Number[30]; - - // 206 SCT Command Transport - unsigned short SCT_Cmd_Transport; - - // 207-208 Reserved for CE-ATA - unsigned short Reserved10[2]; - - // 209 Alignment of logical blocks within a physical block - unsigned short Alignment_Logical_blocks_within_a_physical_block; - - // 210-211 Write-Read-Verify Sector Count Mode 3 (DWord) - unsigned short Write_Read_Verify_Sector_Count_Mode_3[2]; - - // 212-213 Write-Read-Verify Sector Count Mode 2 (DWord) - unsigned short Write_Read_Verify_Sector_Count_Mode_2[2]; - - // 214 NV Cache Capabilities - unsigned short NV_Cache_Capabilities; - - // 215-216 NV Cache Size in Logical Blocks (DWord) - unsigned short NV_Cache_Size[2]; - - // 217 Nominal media rotation rate - unsigned short Nominal_media_rotation_rate; - - // 218 Reserved - unsigned short Reserved11; - - // 219 NV Cache Options - unsigned short NV_Cache_Options; - - // 220 Write-Read-Verify feature set current mode - unsigned short Write_Read_Verify_feature_set_current_mode; - - // 221 Reserved - unsigned short Reserved12; - - // 222 Transport major version number. - // 0000h or ffffh = device does not report version - unsigned short Transport_Major_Version_Number; - - // 223 Transport Minor version number - unsigned short Transport_Minor_Version_Number; - - // 224-233 Reserved for CE-ATA - unsigned short Reserved13[10]; - - // 234 Minimum number of 512-byte data blocks per DOWNLOAD MICROCODE command for mode 03h - unsigned short Mini_blocks_per_CMD; - - // 235 Maximum number of 512-byte data blocks per DOWNLOAD MICROCODE command for mode 03h - unsigned short Max_blocks_per_CMD; - - // 236-254 Reserved - unsigned short Reserved14[19]; - - // 255 Integrity word - // 15:8 Checksum - // 7:0 Checksum Validity Indicator - unsigned short Integrity_word; -}__attribute__((packed)); - -void ata_init(); - -void ata_handler_read(unsigned long nr, unsigned long r); - -void ata_handler_write(unsigned long nr, unsigned long r); - -#endif \ No newline at end of file diff --git a/include/gate.h b/include/gate.h deleted file mode 100644 index ce8210d..0000000 --- a/include/gate.h +++ /dev/null @@ -1,89 +0,0 @@ -#ifndef _HELLOOS_GATE_H -#define _HELLOOS_GATE_H - -#include "kprint.h" -#include "mm.h" - -struct desc_struct -{ - unsigned char x[8]; -}; - -struct gate_struct -{ - unsigned char x[16]; -}; - -extern struct desc_struct GDT_Table[]; -extern struct gate_struct IDT_Table[]; -extern unsigned int TSS64_Table[26]; - -#define load_TR(n) \ -do{ \ - __asm__ __volatile__( "ltr %%ax" \ - : \ - :"a"(n << 3) \ - :"memory"); \ -} while(0) - -#define _set_gate(gate_selector_addr, attr, ist, code_addr) \ -do { \ - unsigned long __d0, __d1; \ - __asm__ __volatile__ ("movw %%dx, %%ax \n\t" \ - "andq $0x7, %%rcx \n\t" \ - "addq %4, %%rcx \n\t" \ - "shlq $32, %%rcx \n\t" \ - "addq %%rcx, %%rax \n\t" \ - "xorq %%rcx, %%rcx \n\t" \ - "movl %%edx, %%ecx \n\t" \ - "shrq $16, %%rcx \n\t" \ - "shlq $48, %%rcx \n\t" \ - "addq %%rcx, %%rax \n\t" \ - "movq %%rax, %0 \n\t" \ - "shrq $32, %%rdx \n\t" \ - "movq %%rdx, %1 \n\t" \ - :"=m"(*((unsigned long *)(gate_selector_addr))), \ - "=m"(*(1 + (unsigned long *)(gate_selector_addr))), \ - "=&a"(__d0), \ - "=&d"(__d1) \ - :"i"(attr << 8), \ - "3"((unsigned long *)(code_addr)), \ - "2"(0x8 << 16), \ - "c"(ist) \ - :"memory" \ - ); \ -} while(0) - -static inline void set_intr_gate(unsigned int n, unsigned char ist, void *addr) { - _set_gate(PHY2VIR(IDT_Table+n), 0x8E, ist, addr); //P,DPL=0,TYPE=E -} - -static inline void set_trap_gate(unsigned int n,unsigned char ist,void * addr) { - _set_gate(PHY2VIR(IDT_Table+n), 0x8F, ist, addr); //P,DPL=0,TYPE=F -} - -static inline void set_system_gate(unsigned int n,unsigned char ist,void * addr) { - _set_gate(PHY2VIR(IDT_Table+n), 0xEF, ist, addr); //P,DPL=3,TYPE=F -} - -static inline void set_system_intr_gate(unsigned int n,unsigned char ist,void * addr) { - _set_gate(PHY2VIR(IDT_Table+n) , 0xEE, ist, addr); //P,DPL=3,TYPE=E -} - -void set_tss64(unsigned long rsp0, unsigned long rsp1, unsigned long rsp2, - unsigned long ist1, unsigned long ist2, unsigned long ist3, - unsigned long ist4,unsigned long ist5,unsigned long ist6,unsigned long ist7) { - *(unsigned long *)(TSS64_Table+1) = rsp0; - *(unsigned long *)(TSS64_Table+3) = rsp1; - *(unsigned long *)(TSS64_Table+5) = rsp2; - - *(unsigned long *)(TSS64_Table+9) = ist1; // interrupt stack table - *(unsigned long *)(TSS64_Table+11) = ist2; - *(unsigned long *)(TSS64_Table+13) = ist3; - *(unsigned long *)(TSS64_Table+15) = ist4; - *(unsigned long *)(TSS64_Table+17) = ist5; - *(unsigned long *)(TSS64_Table+19) = ist6; - *(unsigned long *)(TSS64_Table+21) = ist7; -} - -#endif \ No newline at end of file diff --git a/include/irq.h b/include/irq.h deleted file mode 100644 index fc13418..0000000 --- a/include/irq.h +++ /dev/null @@ -1,10 +0,0 @@ -#ifndef __HELLOOS_IRQ_H -#define __HELLOOS_IRQ_H - -void init_interrupt(); - -void do_IRQ(unsigned long regs,unsigned long nr); - -void IRQ_nothing(); - -#endif \ No newline at end of file diff --git a/include/keyboard.h b/include/keyboard.h deleted file mode 100644 index 15fc24a..0000000 --- a/include/keyboard.h +++ /dev/null @@ -1,107 +0,0 @@ -#ifndef _HELLOOS_KEYBOARD_H -#define _HELLOOS_KEYBOARD_H - -#include "lib.h" - -#define PORT_KB_DATA 0x60 -#define PORT_KB_STATUS 0x64 -#define PORT_KB_CMD 0x64 - -#define KBCMD_WRITE_CMD 0x60 -#define KBCMD_READ_CMD 0x20 -#define KB_INIT_MODE 0x47 - -#define KB_BUF_SIZE 100 - -struct keyboard_inputbuffer { - unsigned char *p_head; - unsigned char *p_tail; - int count; - unsigned char buf[KB_BUF_SIZE]; -}; - -#define KBSTATUS_IBF 0x02 -#define KBSTATUS_OBF 0x01 -#define wait_kb_write() while(io_in8(PORT_KB_STATUS) & KBSTATUS_IBF) -#define wait_kb_read() while(io_in8(PORT_KB_STATUS) & KBSTATUS_OBF) - -#define NR_SCAN_CODES 0x80 -#define MAP_COLS 2 -#define PAUSEBREAK 1 -#define PRINTSCREEN 2 -#define OTHERKEY 4 -#define FLAG_BREAK 0x80 - -unsigned char pausebreak_scode[] = {0xE1, 0x1D, 0x45, 0xE1, 0x9D, 0xC5}; -unsigned int keycode_map_normal[NR_SCAN_CODES*MAP_COLS] = { - /*ScanCode Unshift Shift*/ - /* 0x00 */ 0, 0, - /* 0x01 */ 0, 0, - /* 0x02 */ '1', '!', - /* 0x03 */ '2', '@', - /* 0x04 */ '3', '#', - /* 0x05 */ '4', '$', - /* 0x06 */ '5', '%', - /* 0x07 */ '6', '^', - /* 0x08 */ '7', '&', - /* 0x09 */ '8', '*', - /* 0x0A */ '9', '(', - /* 0x0B */ '0', ')', - /* 0x0C */ '-', '_', - /* 0x0D */ '=', '+', - /* 0x0E */ 0, 0, - /* 0x0F */ 0, 0, - /* 0x10 */ 'q', 'Q', - /* 0x11 */ 'w', 'W', - /* 0x12 */ 'e', 'E', - /* 0x13 */ 'r', 'R', - /* 0x14 */ 't', 'T', - /* 0x15 */ 'y', 'Y', - /* 0x16 */ 'u', 'U', - /* 0x17 */ 'i', 'I', - /* 0x18 */ 'o', 'O', - /* 0x19 */ 'p', 'P', - /* 0x1A */ '[', '{', - /* 0x1B */ ']', '}', - /* 0x1C */ 0, 0, // enter - /* 0x1D */ 0x1d, 0x1d, // ctrl left - /* 0x1E */ 'a', 'A', - /* 0x1F */ 's', 'S', - /* 0x20 */ 'd', 'D', - /* 0x21 */ 'f', 'F', - /* 0x22 */ 'g', 'G', - /* 0x23 */ 'h', 'H', - /* 0x24 */ 'j', 'J', - /* 0x25 */ 'k', 'K', - /* 0x26 */ 'l', 'L', - /* 0x27 */ ';', ':', - /* 0x28 */ '\'', '"', - /* 0x29 */ '`', '~', - /* 0x2A */ 0x2a, 0x2a, // shift left - /* 0x2B */ '\\', '|', - /* 0x2C */ 'z', 'Z', - /* 0x2D */ 'x', 'X', - /* 0x2E */ 'c', 'C', - /* 0x2F */ 'v', 'V', - /* 0x30 */ 'b', 'B', - /* 0x31 */ 'n', 'N', - /* 0x32 */ 'm', 'M', - /* 0x33 */ ',', '<', - /* 0x34 */ '.', '>', - /* 0x35 */ '/', '?', - /* 0x36 */ 0x36, 0x36, // shirt right - /* 0x37 */ '*', '*', - /* 0x38 */ 0x38, 0x38, // alt left - /* 0x39 */ ' ', ' ', // space - /* 0x3A */ 0, 0, // caps lock - /* 0x3B */ 0, 0, // f1 - /* 0x3C */ 0, 0, // f2 - /* 0x3D */ 0, 0, // f3 - /* 0x3E */ 0, 0, // f4 - /* 0x3F */ 0, 0, // f5 - 0 -}; - -void keyboard_handler(unsigned long nr, unsigned long regs); - -#endif \ No newline at end of file diff --git a/include/kprint.h b/include/kprint.h deleted file mode 100644 index addb9d0..0000000 --- a/include/kprint.h +++ /dev/null @@ -1,29 +0,0 @@ -#ifndef _HELLOOS_KPRINT_H -#define _HELLOOS_KPRINT_H - -#include "printk.h" -#define DEBUG TRUE - -#define kinfo(...) { \ - kprintf("[info] "); \ - kprintf(__VA_ARGS__); \ - } - -#define kdebug(...) { \ - if (DEBUG) { \ - kcolor_printf(WORD_BROWN, "[debug] (%s:%d) ", __FILE__, __LINE__); \ - kcolor_printf(WORD_BROWN, __VA_ARGS__); \ - } \ - } - -#define kwarn(...) { \ - kcolor_printf(WORD_YELLOW, "[warn] "); \ - kcolor_printf(WORD_YELLOW, __VA_ARGS__); \ - } - -#define kerror(...) { \ - kerr_printf("[error] "); \ - kerr_printf(__VA_ARGS__); \ - } - -#endif \ No newline at end of file diff --git a/include/kstring.h b/include/kstring.h deleted file mode 100644 index 8c493c7..0000000 --- a/include/kstring.h +++ /dev/null @@ -1,42 +0,0 @@ -#ifndef _BOOT_STRING_H -#define _BOOT_STRING_H - -#include "types.h" - -/** - * 字符串复制,返回复制数量 - */ -uint32_t strcpy(char *dst, char *src); - -int strlen(char *String); - -char* strncpy(char *dst, char *src, uint32_t n); - -uint8_t strcmp(const char *str1, const char *str2); - -void* memset(void *p, uint8_t val, uint_t n); - -static inline void * memcpy(void *From,void * To,long Num) -{ - int d0,d1,d2; - __asm__ __volatile__ ( "cld \n\t" - "rep \n\t" - "movsq \n\t" - "testb $4,%b4 \n\t" - "je 1f \n\t" - "movsl \n\t" - "1:\ttestb $2,%b4 \n\t" - "je 2f \n\t" - "movsw \n\t" - "2:\ttestb $1,%b4 \n\t" - "je 3f \n\t" - "movsb \n\t" - "3: \n\t" - :"=&c"(d0),"=&D"(d1),"=&S"(d2) - :"0"(Num/8),"q"(Num),"1"(To),"2"(From) - :"memory" - ); - return To; -} - -#endif \ No newline at end of file diff --git a/include/lib.h b/include/lib.h deleted file mode 100644 index 26395f1..0000000 --- a/include/lib.h +++ /dev/null @@ -1,39 +0,0 @@ -#ifndef _HELLOOS_LIB_H -#define _HELLOOS_LIB_H - -#define cli() __asm__ __volatile__("cli \n\t":::"memory") -#define sti() __asm__ __volatile__("sti \n\t":::"memory") -#define nop() __asm__ __volatile__("nop \n\t") -#define port_insw(port, buffer, nr) \ - __asm__ __volatile__("cld;rep;insw;mfence;"::"d"(port),"D"(buffer),"c"(nr):"memory") - -#define port_outsw(port,buffer,nr) \ -__asm__ __volatile__("cld;rep;outsw;mfence;"::"d"(port),"S"(buffer),"c"(nr):"memory") - -#define container_of(ptr, type, member) ({ \ - typeof(((type*)0)->member) *_p = (ptr); \ - (type*)((unsigned long)_p - (unsigned long)&(((type*)0)->member)); \ -}) - -void io_out8(unsigned short port, unsigned char value); - -unsigned char io_in8(unsigned short port); - -void io_out16(unsigned short port, unsigned short value); - -unsigned short io_in16(unsigned short port); - -void io_out32(unsigned short port, unsigned int value); - -unsigned int io_in32(unsigned short port); - -/** - * wrmsr(write model specific)写 msr 寄存器。 - * msr 寄存器(一组64位的寄存器):EDX:EAX 分别组成该寄存器的高 32 位和低 32 位,ECX 指定地址。 - * wrmsr和rdmsr必须在 0 特权级或实模式下执行。 - */ -static inline void wrmsr(unsigned long address,unsigned long value) { - __asm__ __volatile__("wrmsr \n\t"::"d"(value >> 32),"a"(value & 0xffffffff),"c"(address):"memory"); -} - -#endif \ No newline at end of file diff --git a/include/list.h b/include/list.h deleted file mode 100644 index bd2c131..0000000 --- a/include/list.h +++ /dev/null @@ -1,35 +0,0 @@ -#ifndef _HELLOOS_LIST_H -#define _HELLOOS_LIST_H - -struct list_head { - struct list_head *prev; - struct list_head *next; -}; - -static inline void list_init(struct list_head *head) { - head->prev = head; - head->next = head; -} - -static inline void __list_add(struct list_head *new, - struct list_head *prev, - struct list_head *next) { - prev->next = new; - new->next = next; - new->prev = prev; - next->prev = new; -} - -static inline void list_add_tail(struct list_head *new, struct list_head *head) { - __list_add(new, head, head->next); -} - -static inline void list_add_head(struct list_head *new, struct list_head *head) { - __list_add(new, head->prev, head); -} - -static inline struct list_head* list_next(struct list_head *entry) { - return entry->next; -} - -#endif \ No newline at end of file diff --git a/include/mm.h b/include/mm.h deleted file mode 100644 index ed5e83c..0000000 --- a/include/mm.h +++ /dev/null @@ -1,121 +0,0 @@ -#ifndef _HELLOOS_MM_H -#define _HELLOOS_MM_H - -#include "types.h" - -#define KERNEL_VIRADDR 0xffff800000000000 -#define PAGE_4K_SHIFT 12 -#define PAGE_4K_SIZE (1UL << PAGE_4K_SHIFT) -#define PAGE_4K_MASK (~(PAGE_4K_SIZE - 1)) -#define PAGE_4K_ALIGN(addr) (((uint_t)(addr) + PAGE_4K_SIZE - 1) & PAGE_4K_MASK) -#define PHY2VIR(addr) (KERNEL_VIRADDR | ((uint_t)(addr))) -#define VIR2PHY(addr) ((~KERNEL_VIRADDR) & ((uint_t)(addr))) - -typedef struct { - unsigned long pml4t; -} pml4t_t; - -unsigned long *Global_CR3 = NULL; - -#define E820_TYPE_AVAILABLE 1 -#define E820_TYPE_RESERVED 2 -#define E820_TYPE_ACPI_RECLAIMABLE 3 -#define E820_TYPE_NVS 4 -#define E820_TYPE_BADRAM 5 -typedef struct { - uint_t addr; - uint_t len; - uint32_t type; -}__attribute__((packed)) E820_t; - -typedef struct _mm_zone mm_zone_t; - -//struct page attribute (alloc_pages flags) -#define PG_PTable_Maped (1 << 0) -#define PG_Kernel_Init (1 << 1) -#define PG_Referenced (1 << 2) -#define PG_Dirty (1 << 3) -#define PG_Active (1 << 4) -#define PG_Up_To_Date (1 << 5) -#define PG_Device (1 << 6) -#define PG_Kernel (1 << 7) -#define PG_K_Share_To_U (1 << 8) -#define PG_Slab (1 << 9) -typedef struct { - uint_t phy_addr; - uint64_t attribute; - uint_t ref_count; - uint_t age; - mm_zone_t *zone; -} mm_page_t; - -#define ZONE_DMA (1 << 0) -#define ZONE_NORMAL (1 << 1) -#define ZONE_UNMAPED (1 << 2) - -int ZONE_DMA_INDEX = 0; -int ZONE_NORMAL_INDEX = 0; -int ZONE_UNMAPED_INDEX = 0; - -struct _mm_zone { - mm_page_t *pages_group; - uint_t pages_length; - - uint_t zone_start_addr; - uint_t zone_end_addr; - uint_t zone_length; - uint64_t attribute; - - uint_t page_using_count; - uint_t page_free_count; - uint_t total_pages_link; -}; - -typedef struct { - E820_t e820[32]; - uint_t e820_num; - uint_t e820_available_size; - - uint_t *page_bits; - uint_t page_bits_size; - uint_t page_bits_length; - - mm_page_t *pages_struct; - uint_t pages_size; - uint_t pages_length; - - mm_zone_t *zones_struct; - uint_t zones_size; - uint_t zones_length; - - uint_t total_mem_length; // 总内存大小 - uint_t kernel_start_phyaddr; // 内核程序开始物理地址 - uint_t kernel_end_phyaddr; // 内核程序结束物理地址 - uint_t end_of_struct; // 内存管理结构的结束地址 - uint_t start_text, end_text; // 内核代码段 - uint_t start_data, end_data; // 内核数据段 - uint_t start_rodata, end_rodata; // 内核只读数据段 - uint_t start_bss, end_bss; // 内核 bss 段 - uint_t start_stack; // 内核栈 -} global_mm_descriptor_t; - -global_mm_descriptor_t gmdsc; - -void init_memory(); - -unsigned long page_init(mm_page_t *page, uint_t flags); - -mm_page_t* alloc_pages(int zone_select, int n, uint64_t flags); - -static inline uint_t* get_gdt() { - uint_t *tmp; - __asm__ __volatile__( - "movq %%cr3, %0 \n\t" - :"=r"(tmp) - : - :"memory" - ); - return tmp; -} - -#endif \ No newline at end of file diff --git a/include/os/bootmem.h b/include/os/bootmem.h new file mode 100644 index 0000000..9026cbf --- /dev/null +++ b/include/os/bootmem.h @@ -0,0 +1,24 @@ +// 系统启动时,物理内存分配器 +#ifndef _OS_BOOTMEM_H +#define _OS_BOOTMEM_H + +#include + +// 低端内存的最大页帧号 +extern unsigned long max_low_pfn; +// 低端内存的最小页帧号 +extern unsigned long min_low_pfn; + +// 最大内存页 +extern unsigned long max_pfn; + +typedef struct bootmem_data { + unsigned long node_boot_start; // 节点的起始地址,UNMA 中会有多个节点,但我们只支持 NUM,该值为 0 + unsigned long node_low_pfn; // 低端内存的最后一个页帧号 + + void *node_bootmem_map; // 内存 bitmap 地址 + + +} bootmem_data_t; + +#endif \ No newline at end of file diff --git a/include/os/console.h b/include/os/console.h new file mode 100644 index 0000000..5d616b0 --- /dev/null +++ b/include/os/console.h @@ -0,0 +1,9 @@ +#ifndef _OS_CONSOLE_H +#define _OS_CONSOLE_H + +struct console { + char name[16]; + void (*write)(struct console *, const char *, unsigned); +}; + +#endif \ No newline at end of file diff --git a/include/os/const.h b/include/os/const.h new file mode 100644 index 0000000..d2e96fc --- /dev/null +++ b/include/os/const.h @@ -0,0 +1,13 @@ +#ifndef _OS_CONST_H +#define _OS_CONST_H + +#ifdef __ASSEMBLY__ +#define _AC(X,Y) X +#define _AT(T,X) X +#else +#define __AC(X,Y) (X##Y) +#define _AC(X,Y) __AC(X,Y) +#define _AT(T,X) ((T)(X)) +#endif + +#endif \ No newline at end of file diff --git a/include/os/ctype.h b/include/os/ctype.h new file mode 100644 index 0000000..8571a70 --- /dev/null +++ b/include/os/ctype.h @@ -0,0 +1,12 @@ +#ifndef _OS_CTYPE_H +#define _OS_CTYPE_H + +static inline int isdigit(char c) { + return c >= '0' && c <= '9'; +} + +static inline int isalnum(char c) { + return c >= 'a' && c <= 'z' || (c >= 'A' && c <= 'Z'); +} + +#endif \ No newline at end of file diff --git a/include/os/init.h b/include/os/init.h new file mode 100644 index 0000000..71091c6 --- /dev/null +++ b/include/os/init.h @@ -0,0 +1,7 @@ +#ifndef _OS_INIT_H +#define _OS_INIT_H + +void setup_arch(); + + +#endif \ No newline at end of file diff --git a/include/os/ioport.h b/include/os/ioport.h new file mode 100644 index 0000000..f2fdf91 --- /dev/null +++ b/include/os/ioport.h @@ -0,0 +1,6 @@ +#ifndef _OS_IOPORT_H +#define _OS_IOPORT_H + +#include + +#endif \ No newline at end of file diff --git a/include/os/kernel.h b/include/os/kernel.h new file mode 100644 index 0000000..c5d4a2c --- /dev/null +++ b/include/os/kernel.h @@ -0,0 +1,33 @@ +#ifndef _OS_KERNEL_H +#define _OS_KERNEL_H + +#include +#include + +#define KERN_EMERG "<0>" /* system is unusable */ +#define KERN_ALERT "<1>" /* action must be taken immediately */ +#define KERN_CRIT "<2>" /* critical conditions */ +#define KERN_ERR "<3>" /* error conditions */ +#define KERN_WARNING "<4>" /* warning conditions */ +#define KERN_NOTICE "<5>" /* normal but significant condition */ +#define KERN_INFO "<6>" /* informational */ +#define KERN_DEBUG "<7>" /* debug-level messages */ + +#define KERN_CONT "" + +extern void __attribute__((format(printf, 1, 2))) + early_printk(const char *fmt, ...); + +extern int vscnprintf(char *buf, size_t size, const char *fmt, va_list args) + __attribute__ ((format (printf, 3, 0))); + +extern int vsnprintf(char *buf, size_t size, const char *fmt, va_list args) + __attribute__ ((format (printf, 3, 0))); + +// extern int printk(const char * fmt, ...) +// __attribute__((format (printf, 1, 2))); +#define printk(...) { \ + early_printk(__VA_ARGS__); \ +} + +#endif \ No newline at end of file diff --git a/include/os/linkage.h b/include/os/linkage.h new file mode 100644 index 0000000..77e2a03 --- /dev/null +++ b/include/os/linkage.h @@ -0,0 +1,13 @@ +#ifndef _OS_LINKAGE_H +#define _OS_LINKAGE_H + +#define ALIGN .align 4,0x90 + +#ifndef ENTRY +#define ENTRY(name) \ + .globl name; \ + ALIGN; \ + name: +#endif + +#endif \ No newline at end of file diff --git a/include/os/list.h b/include/os/list.h new file mode 100644 index 0000000..a33c957 --- /dev/null +++ b/include/os/list.h @@ -0,0 +1,36 @@ +#ifndef _OS_LIST_H +#define _OS_LIST_H + +struct list_head { + struct list_head *prev, *next; +}; + +#define LIST_HEAD_INIT(name) {&(name), &(name)} + +#define LIST_HEAD(name) \ + struct list_head name = LIST_HEAD_INIT(name) + +static inline void INIT_LIST_HEAD(struct list_head *list) { + list->next = list; + list->prev = list; +} + +static inline void __list_add(struct list_head *entry, + struct list_head *prev, + struct list_head *next) { + next->prev = entry; + entry->next = next; + entry->prev = prev; + prev->next = entry; +} + +static inline void list_add(struct list_head *entry, struct list_head *head) { + __list_add(entry, head, head->next); +} + +static inline void list_add_tail(struct list_head *entry, struct list_head *head) { + __list_add(entry, entry->prev, head); +} + + +#endif \ No newline at end of file diff --git a/include/os/mmzone.h b/include/os/mmzone.h new file mode 100644 index 0000000..e975899 --- /dev/null +++ b/include/os/mmzone.h @@ -0,0 +1,7 @@ +#ifndef _OS_MMZONE_H +#define _OS_MMZONE_H + +#include + + +#endif \ No newline at end of file diff --git a/include/os/sched.h b/include/os/sched.h new file mode 100644 index 0000000..cbb1131 --- /dev/null +++ b/include/os/sched.h @@ -0,0 +1,14 @@ +#ifndef _OS_SCHED_H +#define _OS_SCHED_H + +#include +#include + +union thread_union { + struct thread_info thread_info; + unsigned long stack[THREAD_SIZE/sizeof(unsigned long)]; +}; + +extern union thread_union init_thread_union; + +#endif \ No newline at end of file diff --git a/include/os/start_kernel.h b/include/os/start_kernel.h new file mode 100644 index 0000000..f29daa2 --- /dev/null +++ b/include/os/start_kernel.h @@ -0,0 +1,6 @@ +#ifndef _OS_START_KERNEL_H +#define _OS_START_KERNEL_H + +extern void start_kernel(); + +#endif \ No newline at end of file diff --git a/include/os/string.h b/include/os/string.h new file mode 100644 index 0000000..fb6a359 --- /dev/null +++ b/include/os/string.h @@ -0,0 +1,17 @@ +#ifndef _OS_STRING_H +#define _OS_STRING_H + +#include + +#ifndef __HAVE_ARCH_MEMSET +extern void *memset(void *,int,__kernel_size_t); +#endif +#ifndef __HAVE_ARCH_STRNLEN +extern __kernel_size_t strnlen(const char *,__kernel_size_t); +#endif + +#ifndef __HAVE_ARCH_MEMCPY +extern void* memcpy(void *dest, const void *src, size_t count); +#endif + +#endif \ No newline at end of file diff --git a/include/os/types.h b/include/os/types.h new file mode 100644 index 0000000..ae19c54 --- /dev/null +++ b/include/os/types.h @@ -0,0 +1,26 @@ +#ifndef _OS_TYPES_H +#define _OS_TYPES_H + +#include + +#ifndef _SIZE_T +#define _SIZE_T +typedef __kernel_size_t size_t; +#endif + +#ifndef _SSIZE_T +#define _SSIZE_T +typedef __kernel_ssize_t ssize_t; +#endif + +#ifndef _PTRDIFF_T +#define _PTRDIFF_T +typedef __kernel_ptrdiff_t ptrdiff_t; +#endif + +typedef __u8 uint8_t; +typedef __u16 uint16_t; +typedef __u32 uint32_t; +typedef __u64 uint64_t; + +#endif \ No newline at end of file diff --git a/include/printk.h b/include/printk.h deleted file mode 100644 index 38236f5..0000000 --- a/include/printk.h +++ /dev/null @@ -1,52 +0,0 @@ -/** - * 保护模式下屏幕显示 - */ -#ifndef _HELLOOS_PRINTK_H -#define _HELLOOS_PRINTK_H - -#include "types.h" - -#define VGA_BASE 0xb8000 -#define VGA_END 0xbffff - -#define WORD_RED 0x04 -#define WORD_WHITE 0x07 -#define WORD_BROWN 0x06 -#define WORD_YELLOW 0x0E - -#define ZEROPAD 1 /* pad with zero */ -#define SIGN 2 /* unsigned/signed long */ -#define PLUS 4 /* show plus */ -#define SPACE 8 /* space if plus */ -#define LEFT 16 /* left justified */ -#define SPECIAL 32 /* 0x */ -#define SMALL 64 /* use 'abcdef' instead of 'ABCDEF' */ - -#define is_digit(c) ((c) >= '0' && (c) <= '9') - -#define do_div(n,base) ({ \ -int __res; \ -__asm__("divq %%rcx":"=a" (n),"=d" (__res):"0" (n),"1" (0),"c" (base)); \ -__res; }) - -/** - * 清屏 - */ -void clear_screen(); - -void kprintf(const char *fmt, ...); - -/** - * 打印错误日志 - */ -void kerr_printf(const char *fmt, ...); - -/** - * 带有颜色的信息打印 - * color:高4位背景色,低4位前景色 - */ -void kcolor_printf(uint8_t color, const char *fmt, ...); - -void kerrorf(const char *fmt, ...); - -#endif \ No newline at end of file diff --git a/include/ptrace.h b/include/ptrace.h deleted file mode 100644 index f68c330..0000000 --- a/include/ptrace.h +++ /dev/null @@ -1,31 +0,0 @@ -#ifndef _HELLOOS_PTRACE_H -#define _HELLOOS_PTRACE_H - -struct pt_regs { - unsigned long r15; - unsigned long r14; - unsigned long r13; - unsigned long r12; - unsigned long r11; - unsigned long r10; - unsigned long r9; - unsigned long r8; - unsigned long rbx; - unsigned long rcx; - unsigned long rdx; - unsigned long rsi; - unsigned long rdi; - unsigned long rbp; - unsigned long ds; - unsigned long es; - unsigned long rax; - unsigned long func; - unsigned long errcode; - unsigned long rip; - unsigned long cs; - unsigned long rflags; - unsigned long rsp; - unsigned long ss; -}; - -#endif \ No newline at end of file diff --git a/include/syscall.h b/include/syscall.h deleted file mode 100644 index 17f4992..0000000 --- a/include/syscall.h +++ /dev/null @@ -1,9 +0,0 @@ -#ifndef _HELLOOS_SYSCALL_H -#define _HELLOOS_SYSCALL_H - -#include "task.h" -#include "ptrace.h" - -unsigned long system_call_function(struct pt_regs *regs); - -#endif \ No newline at end of file diff --git a/include/task.h b/include/task.h deleted file mode 100644 index 43dcffe..0000000 --- a/include/task.h +++ /dev/null @@ -1,179 +0,0 @@ -#ifndef _HELLOOS_TASK_H -#define _HELLOOS_TASK_H - -#include "list.h" -#include "mm.h" -#include "gate.h" - -#define CLONE_FS (1 << 0) -#define CLONE_FILES (1 << 1) -#define CLONE_SIGNAL (1 << 2) - -// 进程内存空间分布结构 -struct mm_struct { - pml4t_t *pgd; // page table point - - unsigned long start_code, end_code; // 代码段 - unsigned long start_data, end_data; // 数据段 - unsigned long start_rodata, end_rodata; // 只读数据段 - unsigned long start_brk, end_brk; // 动态内存区(堆) - unsigned long start_stack; // 进程栈空间 -}; - -#define KERNEL_CS (0x08) -#define KERNEL_DS (0x10) -#define USER_CS (0x28) -#define USER_DS (0x30) - -// 进程切换状态信息 -struct thread_struct { - unsigned long rsp0; // 内核层栈基地址 - - unsigned long rip; // 内核层代码指针 - unsigned long rsp; // 内核层当前栈指针 - - unsigned long fs; - unsigned long gs; - - unsigned long cr2; // cr2 控制寄存器 - unsigned long trap_nr; // 异常的异常号 - unsigned long error_code; // 异常错误码 -}; - -// 进程状态 -#define TASK_RUNNING (1 << 0) -#define TASK_INTERRUPTIBLE (1 << 1) -#define TASK_UNINTERRUPTIBLE (1 << 2) -#define TASK_ZOMBIE (1 << 3) -#define TASK_STOPPED (1 << 4) - -#define PF_KTHREAD (1 << 0) - -struct task_struct { - struct list_head list; - volatile long state; - unsigned long flags; - - struct mm_struct *mm; - struct thread_struct *thread; - - unsigned long addr_limit; - - long pid; - long counter; - long signal; - long priority; -}; - -#define STACK_SIZE 32768 // 32KB -union task_union { - struct task_struct task; - unsigned long stack[STACK_SIZE / sizeof(unsigned long)]; -}__attribute__((aligned(8))); - -struct mm_struct init_mm; -struct thread_struct init_thread; - -#define INIT_TASK(tsk) { \ - .state = TASK_INTERRUPTIBLE, \ - .flags = PF_KTHREAD, \ - .mm = &init_mm, \ - .thread = &init_thread, \ - .addr_limit = 0xffff800000000000, \ - .pid = 0, \ - .counter = 1, \ - .signal = 0, \ - .priority = 0 \ -} -union task_union init_task_union __attribute__((section(".data.init_task"))) = {INIT_TASK(init_task_union.task)}; - -#define NR_CPUS 2 -struct task_struct *init_task[NR_CPUS] = {&init_task_union.task,0}; - -struct mm_struct init_mm = {0}; - -struct thread_struct init_thread = { - .rsp0 = (unsigned long)(init_task_union.stack + STACK_SIZE / sizeof(unsigned long)), - .rsp = (unsigned long)(init_task_union.stack + STACK_SIZE / sizeof(unsigned long)), - .fs = KERNEL_DS, - .gs = KERNEL_DS, - .cr2 = 0, - .trap_nr = 0, - .error_code = 0 -}; - -struct tss_struct { - unsigned int reserved0; - unsigned long rsp0; - unsigned long rsp1; - unsigned long rsp2; - unsigned long reserved1; - unsigned long ist1; - unsigned long ist2; - unsigned long ist3; - unsigned long ist4; - unsigned long ist5; - unsigned long ist6; - unsigned long ist7; - unsigned long reserved2; - unsigned short reserved3; - unsigned short iomapbaseaddr; -}__attribute__((packed)); - -#define INIT_TSS \ -{ .reserved0 = 0, \ - .rsp0 = (unsigned long)(init_task_union.stack + STACK_SIZE / sizeof(unsigned long)), \ - .rsp1 = (unsigned long)(init_task_union.stack + STACK_SIZE / sizeof(unsigned long)), \ - .rsp2 = (unsigned long)(init_task_union.stack + STACK_SIZE / sizeof(unsigned long)), \ - .reserved1 = 0, \ - .ist1 = 0xffff800000007c00, \ - .ist2 = 0xffff800000007c00, \ - .ist3 = 0xffff800000007c00, \ - .ist4 = 0xffff800000007c00, \ - .ist5 = 0xffff800000007c00, \ - .ist6 = 0xffff800000007c00, \ - .ist7 = 0xffff800000007c00, \ - .reserved2 = 0, \ - .reserved3 = 0, \ - .iomapbaseaddr = 0 \ -} -struct tss_struct init_tss[NR_CPUS] = { [0 ... NR_CPUS-1] = INIT_TSS }; - -static inline struct task_struct* get_current() { - struct task_struct *current = NULL; - __asm__ __volatile__ ("andq %%rsp, %0 \n\t":"=r"(current):"0"(~32767UL)); - return current; -} - -#define current get_current() - -#define GET_CURRENT \ - "movq %rsp, %rbx \n\t" \ - "andq $-32768,%rbx \n\t" - -#define switch_to(prev, next) \ -do { \ - __asm__ __volatile__ ( "pushq %%rbp \n\t" \ - "pushq %%rax \n\t" \ - "movq %%rsp, %0 \n\t" \ - "movq %2, %%rsp \n\t" \ - "leaq 1f(%%rip), %%rax \n\t" \ - "movq %%rax, %1 \n\t" \ - "pushq %3 \n\t" \ - "jmp __switch_to \n\t" \ - "1: \n\t" \ - "popq %%rax \n\t" \ - "popq %%rbp \n\t" \ - :"=m"(prev->thread->rsp), \ - "=m"(prev->thread->rip) \ - :"m"(next->thread->rsp), \ - "m"(next->thread->rip), \ - "D"(prev), \ - "S"(next) \ - :"memory" \ - ); \ -} while(0) - -void task_init(); - -#endif \ No newline at end of file diff --git a/include/types.h b/include/types.h deleted file mode 100644 index 2f9fada..0000000 --- a/include/types.h +++ /dev/null @@ -1,28 +0,0 @@ -#ifndef _HELLOOS_TPYES_H -#define _HELLOOS_TPYES_H - -#define NULL 0 -#define TRUE 1 -#define FALSE 0 - -typedef unsigned char uint8_t; -typedef char int8_t; - -typedef unsigned short uint16_t; -typedef short int16_t; - -typedef unsigned int uint32_t; -typedef int int32_t; - -typedef unsigned long uint_t; -typedef long int_t; - -typedef unsigned long long uint64_t; -typedef long long int64_t; - -typedef unsigned long uintptr_t; -typedef unsigned long adr_t; - -typedef uint8_t bool_t; - -#endif \ No newline at end of file diff --git a/init/Makefile b/init/Makefile new file mode 100644 index 0000000..fb2df24 --- /dev/null +++ b/init/Makefile @@ -0,0 +1,8 @@ +-include $(BASE_DIR)/scripts/config.mk + +$(c_srcs_obj): $(c_srcs) + +compile: $(c_srcs_obj) + +clean: + $(HIDE)rm -rf $(c_srcs_obj) diff --git a/init/main.c b/init/main.c new file mode 100644 index 0000000..1ebda6f --- /dev/null +++ b/init/main.c @@ -0,0 +1,9 @@ +#include + +void start_kernel() { + + setup_arch(); + + __asm__ __volatile__("hlt"); +} + diff --git a/kernel/Makefile b/kernel/Makefile index 88886ff..f075361 100644 --- a/kernel/Makefile +++ b/kernel/Makefile @@ -1,17 +1,8 @@ -SOURCE := $(shell find . -name "*.c") -OBJS := $(SOURCE:%.c=%.o) -CFLAGS = -c -I../include --static \ - -mcmodel=large -fno-pie -fno-builtin \ - -fno-stack-protector -m64 +-include $(BASE_DIR)/scripts/config.mk -build: $(OBJS) entry.o +$(c_srcs_obj): $(c_srcs) -$(OBJS):%.o:%.c - gcc $(CFLAGS) -o $@ $< - -entry.o: entry.S - @gcc -E $(CFLAGS) $< > entry.i - @as $(ASFLAGS) -o $@ entry.i +compile: $(c_srcs_obj) clean: - rm -rf $(OBJS) *.i *.o \ No newline at end of file + $(HIDE)rm -rf $(c_srcs_obj) \ No newline at end of file diff --git a/kernel/entry.S b/kernel/entry.S deleted file mode 100644 index ac858ec..0000000 --- a/kernel/entry.S +++ /dev/null @@ -1,89 +0,0 @@ -.code64 -.text -.global ret_from_intr -ret_from_intr: - popq %r15 - popq %r14 - popq %r13 - popq %r12 - popq %r11 - popq %r10 - popq %r9 - popq %r8 - popq %rbx - popq %rcx - popq %rdx - popq %rsi - popq %rdi - popq %rbp - - popq %rax - movq %rax, %ds - - popq %rax - movq %rax, %es - - popq %rax - addq $0x10, %rsp - sti - iretq - -.global ret_system_call -ret_system_call: - movq %rax, 0x80(%rsp) - popq %r15 - popq %r14 - popq %r13 - popq %r12 - popq %r11 - popq %r10 - popq %r9 - popq %r8 - popq %rbx - popq %rcx - popq %rdx - popq %rsi - popq %rdi - popq %rbp - popq %rax - movq %rax, %ds - popq %rax - movq %rax, %es - popq %rax - addq $0x38, %rsp - .byte 0x48 - sysexit - -.extern system_call_function -.global system_call -system_call: - sti - subq $0x38, %rsp - cld; - - pushq %rax; - movq %es, %rax; - pushq %rax; - movq %ds, %rax; - pushq %rax; - xorq %rax, %rax; - pushq %rbp; - pushq %rdi; - pushq %rsi; - pushq %rdx; - pushq %rcx; - pushq %rbx; - pushq %r8; - pushq %r9; - pushq %r10; - pushq %r11; - pushq %r12; - pushq %r13; - pushq %r14; - pushq %r15; - movq $0x10, %rdx; - movq %rdx, %ds; - movq %rdx, %es; - movq %rsp, %rdi - callq system_call_function - jmp ret_system_call diff --git a/kernel/irq/irq.c b/kernel/irq/irq.c deleted file mode 100644 index b40678b..0000000 --- a/kernel/irq/irq.c +++ /dev/null @@ -1,150 +0,0 @@ -#include "irq.h" -#include "lib.h" -#include "gate.h" -#include "kprint.h" -#include "keyboard.h" -#include "ata.h" - -#define SAVE_ALL_REGS \ - "cld; \n\t" \ - "pushq %rax; \n\t" \ - "pushq %rax; \n\t" \ - "movq %es, %rax; \n\t" \ - "pushq %rax; \n\t" \ - "movq %ds, %rax; \n\t" \ - "pushq %rax; \n\t" \ - "xorq %rax, %rax;\n\t" \ - "pushq %rbp; \n\t" \ - "pushq %rdi; \n\t" \ - "pushq %rsi; \n\t" \ - "pushq %rdx; \n\t" \ - "pushq %rcx; \n\t" \ - "pushq %rbx; \n\t" \ - "pushq %r8 ; \n\t" \ - "pushq %r9 ; \n\t" \ - "pushq %r10; \n\t" \ - "pushq %r11; \n\t" \ - "pushq %r12; \n\t" \ - "pushq %r13; \n\t" \ - "pushq %r14; \n\t" \ - "pushq %r15; \n\t" \ - "movq $0x10, %rdx;\n\t" \ - "movq %rdx, %ds; \n\t" \ - "movq %rdx, %es; \n\t" - -#define SYMBOL_NAME_STR(X) #X -#define IRQ_NAME2(nr) nr##interrupt(void) -#define IRQ_NAME(nr) IRQ_NAME2(IRQ##nr) - -#define Build_IRQ(nr) \ - void IRQ_NAME(nr); \ - __asm__(SYMBOL_NAME_STR(IRQ) #nr "interrupt: \n\t" \ - "pushq $0x00 \n\t" SAVE_ALL_REGS \ - "movq %rsp, %rdi \n\t" \ - "leaq ret_from_intr(%rip), %rax \n\t" \ - "pushq %rax \n\t" \ - "movq $" #nr ", %rsi \n\t" \ - "jmp do_IRQ \n\t"); -Build_IRQ(0x20); -Build_IRQ(0x21); -Build_IRQ(0x22); -Build_IRQ(0x23); -Build_IRQ(0x24); -Build_IRQ(0x25); -Build_IRQ(0x26); -Build_IRQ(0x27); -Build_IRQ(0x28); -Build_IRQ(0x29); -Build_IRQ(0x2a); -Build_IRQ(0x2b); -Build_IRQ(0x2c); -Build_IRQ(0x2d); -Build_IRQ(0x2e); -Build_IRQ(0x2f); -Build_IRQ(0x30); -Build_IRQ(0x31); -Build_IRQ(0x32); -Build_IRQ(0x33); -Build_IRQ(0x34); -Build_IRQ(0x35); -Build_IRQ(0x36); -Build_IRQ(0x37); - -void (*interrupt_table[24])(void) = { - IRQ0x20interrupt, - IRQ0x21interrupt, - IRQ0x22interrupt, - IRQ0x23interrupt, - IRQ0x24interrupt, - IRQ0x25interrupt, - IRQ0x26interrupt, - IRQ0x27interrupt, - IRQ0x28interrupt, - IRQ0x29interrupt, - IRQ0x2ainterrupt, - IRQ0x2binterrupt, - IRQ0x2cinterrupt, - IRQ0x2dinterrupt, - IRQ0x2einterrupt, - IRQ0x2finterrupt, - IRQ0x30interrupt, - IRQ0x31interrupt, - IRQ0x32interrupt, - IRQ0x33interrupt, - IRQ0x34interrupt, - IRQ0x35interrupt, - IRQ0x36interrupt, - IRQ0x37interrupt, -}; - -void init_interrupt() { - for (int i = 32; i < 56; i++) { - set_intr_gate(i, 0, interrupt_table[i - 32]); - } - - //8259A-master ICW1-4 - io_out8(0x20,0x11); - io_out8(0x21,0x20); - io_out8(0x21,0x04); - io_out8(0x21,0x01); - - // //8259A-slave ICW1-4 - io_out8(0xa0,0x11); - io_out8(0xa1,0x28); - io_out8(0xa1,0x02); - io_out8(0xa1,0x01); - - // //8259A-M/S OCW1 - io_out8(0x21,0x00); - io_out8(0xa1,0x00); - - kinfo("8259A init \n"); - sti(); -} - -void do_IRQ(unsigned long regs, unsigned long nr) { - switch (nr) { - // 键盘中断 - case 0x21: - keyboard_handler(nr, regs); - break; - - case 0x2f: - ata_handler_read(nr, regs); - break; - - case 0x2e: - ata_handler_write(nr, regs); - - default: - break; - } - if (nr != 0x20) - kinfo("\ncode: %x\n", nr); - - io_out8(0x20, 0x20); -} - -void IRQ_nothing() { - -} \ No newline at end of file diff --git a/kernel/kernel.c b/kernel/kernel.c deleted file mode 100644 index d9f16f1..0000000 --- a/kernel/kernel.c +++ /dev/null @@ -1,81 +0,0 @@ -#include "multiboot2.h" -#include "printk.h" -#include "kprint.h" -#include "mm.h" -#include "irq.h" -#include "task.h" -#include "gate.h" -#include "ata.h" - -extern global_mm_descriptor_t gmdsc; -extern multiboot_uint64_t mb2_magic; -extern multiboot_uint64_t mb2_info; -static void parse_sys_info(multiboot_uint64_t mb2_info_addr); - -int kernel_start() { - if (mb2_magic != MULTIBOOT2_BOOTLOADER_MAGIC || mb2_info & 7) { - return -1; - } - // 清屏 - clear_screen(); - load_TR(10); - // 解析系统信息 - parse_sys_info(mb2_info); - - // 初始化内存 - init_memory(); - // mm_page_t *page; - // page = alloc_pages(ZONE_NORMAL, 64, PG_PTable_Maped|PG_Active|PG_Kernel); - // for (int i = 0; i <= 64; i++) { - // kdebug("page:%d attr:%x addr:%x\n", i, (page+i)->attribute, (page+i)->phy_addr); - // } - // uint_t *gdt = get_gdt(); - - // 初始化中断 - init_interrupt(); - - ata_init(); - - task_init(); - - while (1) ; - return 0; -} - -static void _init_memory(struct multiboot_tag *tag); - -static void parse_sys_info(multiboot_uint64_t mb2_info_addr) { - struct multiboot_tag *tag; - for (tag = (struct multiboot_tag*)(mb2_info_addr + MULTIBOOT_TAG_ALIGN); - tag->type != MULTIBOOT_TAG_TYPE_END; - tag = (struct multiboot_tag*)((multiboot_uint8_t *)tag + ((tag->size + 7) & ~7))) { - switch (tag->type) { - case MULTIBOOT_TAG_TYPE_MMAP: - _init_memory(tag); - break; - default: - break; - } - } -} - -static void _init_memory(struct multiboot_tag *tag) { - struct multiboot_tag_mmap *mmap = (struct multiboot_tag_mmap*) tag; - struct multiboot_mmap_entry *entry = mmap->entries; - - uint32_t i = 0, available_size = 0; - while ((uint8_t*)entry < (uint8_t*)mmap + mmap->size) { - gmdsc.e820[i].addr = entry->addr; - gmdsc.e820[i].len = entry->len; - gmdsc.e820[i].type = entry->type; - kprintf("[info] e820 memory: addr:%x len:%d type:%d\n", gmdsc.e820[i].addr, gmdsc.e820[i].len, gmdsc.e820[i].type); - if (gmdsc.e820[i].type == E820_TYPE_AVAILABLE) { - available_size++; - } - i++; - - entry = (struct multiboot_mmap_entry*)((uint8_t*)entry + mmap->entry_size); - } - gmdsc.e820_num = i; - gmdsc.e820_available_size = available_size; -} \ No newline at end of file diff --git a/kernel/lib/lib.c b/kernel/lib/lib.c deleted file mode 100644 index 9b8f774..0000000 --- a/kernel/lib/lib.c +++ /dev/null @@ -1,55 +0,0 @@ -#include "lib.h" - -void io_out8(unsigned short port, unsigned char value) { - __asm__ __volatile__("outb %0, %%dx \n\t" - "mfence \n\t" - : - : "a"(value), "d"(port) - : "memory"); -} - -unsigned char io_in8(unsigned short port) { - unsigned char ret = 0; - __asm__ __volatile__("inb %%dx, %0 \n\t" - "mfence \n\t" - : "=a"(ret) - : "d"(port) - : "memory"); - return ret; -} - -void io_out16(unsigned short port, unsigned short value) { - __asm__ __volatile__("outw %0, %%dx \n\t" - "mfence \n\t" - : - : "a"(value), "d"(port) - : "memory"); -} - -unsigned short io_in16(unsigned short port) { - unsigned short ret = 0; - __asm__ __volatile__("inw %%dx, %0 \n\t" - "mfence \n\t" - : "=a"(ret) - : "d"(port) - : "memory"); - return ret; -} - -void io_out32(unsigned short port, unsigned int value) { - __asm__ __volatile__("outl %0, %%dx \n\t" - "mfence \n\t" - : - : "a"(value), "d"(port) - : "memory"); -} - -unsigned int io_in32(unsigned short port) { - unsigned int ret = 0; - __asm__ __volatile__("inl %%dx, %0 \n\t" - "mfence \n\t" - : "=a"(ret) - : "d"(port) - : "memory"); - return ret; -} \ No newline at end of file diff --git a/kernel/lib/string.c b/kernel/lib/string.c deleted file mode 100644 index fa9bcbe..0000000 --- a/kernel/lib/string.c +++ /dev/null @@ -1,63 +0,0 @@ -#include "kstring.h" - -uint32_t strcpy(char *dst, char *src) { - uint32_t num = 0; - while (*src) { - *(dst++) = *(src++); - num++; - } - return num; -} - -char* strncpy(char *dst, char *src, uint32_t n) { - char *p = dst; - while (n-- > 0) { - *(p++) = *(src++); - } - return dst; -} - -uint8_t strcmp(const char *str1, const char *str2) { - while (*str1 && *str2 && (*str1 == *str2)) { - str1++; - str2++; - } - return *str2 - *str1; -} - -void* memset(void *p, uint8_t val, uint_t n) { - int d0,d1; - unsigned long tmp = val * 0x0101010101010101UL; - __asm__ __volatile__ ( "cld \n\t" - "rep \n\t" - "stosq \n\t" - "testb $4, %b3 \n\t" - "je 1f \n\t" - "stosl \n\t" - "1:\ttestb $2, %b3 \n\t" - "je 2f\n\t" - "stosw \n\t" - "2:\ttestb $1, %b3 \n\t" - "je 3f \n\t" - "stosb \n\t" - "3: \n\t" - :"=&c"(d0),"=&D"(d1) - :"a"(tmp),"q"(n),"0"(n/8),"1"(p) - :"memory" - ); - return p; -} - -int strlen(char *String) { - register int __res; - __asm__ __volatile__ ( "cld \n\t" - "repne \n\t" - "scasb \n\t" - "notl %0 \n\t" - "decl %0 \n\t" - :"=c"(__res) - :"D"(String),"a"(0),"0"(0xffffffff) - : - ); - return __res; -} diff --git a/kernel/printk.c b/kernel/printk.c new file mode 100644 index 0000000..ccf8815 --- /dev/null +++ b/kernel/printk.c @@ -0,0 +1 @@ +#include \ No newline at end of file diff --git a/kernel/printk/printk.c b/kernel/printk/printk.c deleted file mode 100644 index e806551..0000000 --- a/kernel/printk/printk.c +++ /dev/null @@ -1,380 +0,0 @@ -#include "printk.h" -#include "kstring.h" -#include - -#define MAX_ROW 25 -#define MAX_COLUMN 80 - -typedef struct s_cursor { - uint32_t x; - uint32_t y; -} cursor_t; - -__attribute__((section(".data"))) cursor_t cursor; - -void clear_screen() { - uint16_t *p = (uint16_t*)VGA_BASE; - for (int32_t i = 0; i <= MAX_ROW*MAX_COLUMN; i++) { - p[i] = 0; - } - - cursor.x = 0; - cursor.y = 0; - return; -} - -int skip_atoi(const char **s) { - int i=0; - - while (is_digit(**s)) - i = i*10 + *((*s)++) - '0'; - return i; -} - -static char * number(char * str, long num, int base, int size, int precision, int type) { - char c,sign,tmp[50]; - const char *digits = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"; - int i; - - if (type&SMALL) digits = "0123456789abcdefghijklmnopqrstuvwxyz"; - if (type&LEFT) type &= ~ZEROPAD; - if (base < 2 || base > 36) - return 0; - c = (type & ZEROPAD) ? '0' : ' ' ; - sign = 0; - if (type&SIGN && num < 0) { - sign='-'; - num = -num; - } else - sign=(type & PLUS) ? '+' : ((type & SPACE) ? ' ' : 0); - if (sign) size--; - if (type & SPECIAL) - if (base == 16) size -= 2; - else if (base == 8) size--; - i = 0; - if (num == 0) - tmp[i++]='0'; - else while (num!=0) - tmp[i++]=digits[do_div(num,base)]; - if (i > precision) precision=i; - size -= precision; - if (!(type & (ZEROPAD + LEFT))) - while(size-- > 0) - *str++ = ' '; - if (sign) - *str++ = sign; - if (type & SPECIAL) - if (base == 8) - *str++ = '0'; - else if (base==16) - { - *str++ = '0'; - *str++ = digits[33]; - } - if (!(type & LEFT)) - while(size-- > 0) - *str++ = c; - - while(i < precision--) - *str++ = '0'; - while(i-- > 0) - *str++ = tmp[i]; - while(size-- > 0) - *str++ = ' '; - return str; -} - -char* numberk(char *buf, int64_t n, int32_t base) { - if (n < 0 && base != 16) { - *(buf++) = '-'; - n = -n; - } - - register char *p; - char strbuf[64]; - p = &strbuf[64]; - *--p = 0; - - if (n == 0) { - *--p = '0'; - } else { - do { - *--p = "0123456789abcdef"[n % base]; - } while (n /= base); - } - while (*p != 0) { - *buf++ = *p++; - } - return buf; -} - -void print(uint16_t color, char *buf) { - char ch; - while (ch = *(buf++)) { - if (ch == '\n') { - cursor.x = 0; - cursor.y++; - } else if (ch == '\t') { - cursor.x += 4; - } else { - if (cursor.x >= MAX_COLUMN-1) { - cursor.x = 0; - cursor.y++; - } - if (cursor.y >= MAX_ROW) { - // 25 行屏幕全部占完,滚动显示日志 - uint32_t n = (MAX_ROW-1) * MAX_COLUMN * 2; - char *dst = (char*)(VGA_BASE), - *src = (char*)(VGA_BASE + MAX_COLUMN*2); - strncpy(dst, src, n); - cursor.x = 0; - cursor.y = MAX_ROW - 1; - memset((char*)(VGA_BASE) + (MAX_ROW - 1)*MAX_COLUMN*2, 0, MAX_COLUMN*2); - } - uint16_t *p = (uint16_t*)((uint64_t)(VGA_BASE + cursor.y*MAX_COLUMN*2 + cursor.x*2)); - *p = (uint16_t)(color << 8) + ch; - cursor.x++; - } - } - return; -} - -void vsprintf(char *buf, const char *fmt, va_list args) { - // char ch; - // while (ch = *(fmt++)) { - // if (ch == '%') { - // ch = *(fmt++); - // if (ch == 's') { - // char *val = va_arg(args, char*); - // uint64_t n = strcpy(buf, val); - // buf += n; - // } else if (ch == 'd') { - // int64_t val = va_arg(args, int64_t); - // buf = numberk(buf, val, 10); - // } else if (ch == 'x') { - // uint64_t val = va_arg(args, uint64_t); - // *(buf++) = '0'; - // *(buf++) = 'x'; - // buf = numberk(buf, val, 16); - // } - // } else { - // *(buf++) = ch; - // } - // } - char * str,*s; - int flags; - int field_width; - int precision; - int len,i; - - int qualifier; /* 'h', 'l', 'L' or 'Z' for integer fields */ - - for(str = buf; *fmt; fmt++) - { - - if(*fmt != '%') - { - *str++ = *fmt; - continue; - } - flags = 0; - repeat: - fmt++; - switch(*fmt) - { - case '-':flags |= LEFT; - goto repeat; - case '+':flags |= PLUS; - goto repeat; - case ' ':flags |= SPACE; - goto repeat; - case '#':flags |= SPECIAL; - goto repeat; - case '0':flags |= ZEROPAD; - goto repeat; - } - - /* get field width */ - - field_width = -1; - if(is_digit(*fmt)) - field_width = skip_atoi(&fmt); - else if(*fmt == '*') - { - fmt++; - field_width = va_arg(args, int); - if(field_width < 0) - { - field_width = -field_width; - flags |= LEFT; - } - } - - /* get the precision */ - - precision = -1; - if(*fmt == '.') - { - fmt++; - if(is_digit(*fmt)) - precision = skip_atoi(&fmt); - else if(*fmt == '*') - { - fmt++; - precision = va_arg(args, int); - } - if(precision < 0) - precision = 0; - } - - qualifier = -1; - if(*fmt == 'h' || *fmt == 'l' || *fmt == 'L' || *fmt == 'Z') - { - qualifier = *fmt; - fmt++; - } - - switch(*fmt) - { - case 'c': - - if(!(flags & LEFT)) - while(--field_width > 0) - *str++ = ' '; - *str++ = (unsigned char)va_arg(args, int); - while(--field_width > 0) - *str++ = ' '; - break; - - case 's': - - s = va_arg(args,char *); - if(!s) - s = '\0'; - len = strlen(s); - if(precision < 0) - precision = len; - else if(len > precision) - len = precision; - - if(!(flags & LEFT)) - while(len < field_width--) - *str++ = ' '; - for(i = 0;i < len ;i++) - *str++ = *s++; - while(len < field_width--) - *str++ = ' '; - break; - - case 'o': - - if(qualifier == 'l') - str = number(str,va_arg(args,unsigned long),8,field_width,precision,flags); - else - str = number(str,va_arg(args,unsigned int),8,field_width,precision,flags); - break; - - case 'p': - - if(field_width == -1) - { - field_width = 2 * sizeof(void *); - flags |= ZEROPAD; - } - - str = number(str,(unsigned long)va_arg(args,void *),16,field_width,precision,flags); - break; - - case 'x': - - flags |= SMALL; - - case 'X': - - if(qualifier == 'l') - str = number(str,va_arg(args,unsigned long),16,field_width,precision,flags); - else - str = number(str,va_arg(args,unsigned int),16,field_width,precision,flags); - break; - - case 'd': - case 'i': - - flags |= SIGN; - case 'u': - - if(qualifier == 'l') - str = number(str,va_arg(args,unsigned long),10,field_width,precision,flags); - else - str = number(str,va_arg(args,unsigned int),10,field_width,precision,flags); - break; - - case 'n': - - if(qualifier == 'l') - { - long *ip = va_arg(args,long *); - *ip = (str - buf); - } - else - { - int *ip = va_arg(args,int *); - *ip = (str - buf); - } - break; - - case '%': - - *str++ = '%'; - break; - - default: - - *str++ = '%'; - if(*fmt) - *str++ = *fmt; - else - fmt--; - break; - } - - } - *str = '\0'; - return; -} - -void _printf(uint16_t color, const char *fmt, va_list args) { - char buf[512] = {0}; - vsprintf(buf, fmt, args); - print(color, buf); -} - -void kprintf(const char *fmt, ...) { - va_list args; - va_start(args, fmt); - _printf(WORD_WHITE, fmt, args); - va_end(args); -} - -void kerr_printf(const char *fmt, ...) { - va_list args; - va_start(args, fmt); - _printf(WORD_RED, fmt, args); - va_end(args); -} - -void kcolor_printf(uint8_t color, const char *fmt, ...) { - va_list args; - va_start(args, fmt); - _printf(color, fmt, args); - va_end(args); -} - -void kerrorf(const char *fmt, ...) { - va_list args; - va_start(args, fmt); - _printf(WORD_RED, fmt, args); - va_end(args); - while (1) ; - return; -} \ No newline at end of file diff --git a/kernel/sched/task.c b/kernel/sched/task.c deleted file mode 100644 index a703f37..0000000 --- a/kernel/sched/task.c +++ /dev/null @@ -1,184 +0,0 @@ -#include "task.h" -#include "ptrace.h" -#include "kprint.h" -#include "lib.h" -#include "kstring.h" - -extern void ret_from_intr(); -extern void system_call(void); -extern void ret_system_call(void); - -void __switch_to(struct task_struct *prev,struct task_struct *next) { - - init_tss[0].rsp0 = next->thread->rsp0; - - set_tss64(init_tss[0].rsp0, init_tss[0].rsp1, init_tss[0].rsp2, init_tss[0].ist1, init_tss[0].ist2, init_tss[0].ist3, init_tss[0].ist4, init_tss[0].ist5, init_tss[0].ist6, init_tss[0].ist7); - - __asm__ __volatile__("movq %%fs, %0 \n\t":"=a"(prev->thread->fs)); - __asm__ __volatile__("movq %%gs, %0 \n\t":"=a"(prev->thread->gs)); - kinfo("next:%lx\n", next); - - __asm__ __volatile__("movq %0, %%fs \n\t"::"a"(next->thread->fs)); - __asm__ __volatile__("movq %0, %%gs \n\t"::"a"(next->thread->gs)); - - kinfo("prev->thread->rsp0:%#018lx\n",prev->thread->rsp0); - kinfo("next->thread->rsp0:%#018lx\n",next->thread->rsp0); -} - -void user_level_function() { - long ret = 0; - kinfo("user_level_function task is running\n"); - char str[] = "Hello World! \n"; - - __asm__ __volatile__( "leaq sysexit_return_address(%%rip), %%rdx \n\t" - "movq %%rsp, %%rcx \n\t" - "sysenter \n\t" - "sysexit_return_address: \n\t" - :"=a"(ret):"0"(1), "D"(str):"memory"); - - kinfo("user_level_function task called sysenter,ret:%ld\n",ret); - - while(1); -} - -unsigned long do_execve(struct pt_regs * regs) { - regs->rdx = 0x800000; //RIP - regs->rcx = 0xa00000; //RSP - regs->rax = 1; - regs->ds = 0; - regs->es = 0; - kinfo("do_execve task is running\n"); - - memcpy(user_level_function,(void *)0x800000,1024); - - return 0; -} - -unsigned long do_exit(unsigned long code) { - kinfo("exit task is running,arg:%#018lx\n", code); - while(1); -} - -unsigned long init(unsigned long arg) { - struct pt_regs *regs; - - kinfo("init task is running,arg:%#018lx\n",arg); - - current->thread->rip = (unsigned long)ret_system_call; - current->thread->rsp = (unsigned long)current + STACK_SIZE - sizeof(struct pt_regs); - regs = (struct pt_regs *)current->thread->rsp; - - __asm__ __volatile__("movq %1, %%rsp \n\t" - "pushq %2 \n\t" - "jmp do_execve \n\t" - ::"D"(regs),"m"(current->thread->rsp),"m"(current->thread->rip):"memory"); - - return 1; -} - -extern void kernel_thread_func(void); -__asm__ ( -"kernel_thread_func: \n\t" -" popq %r15 \n\t" -" popq %r14 \n\t" -" popq %r13 \n\t" -" popq %r12 \n\t" -" popq %r11 \n\t" -" popq %r10 \n\t" -" popq %r9 \n\t" -" popq %r8 \n\t" -" popq %rbx \n\t" -" popq %rcx \n\t" -" popq %rdx \n\t" -" popq %rsi \n\t" -" popq %rdi \n\t" -" popq %rbp \n\t" -" popq %rax \n\t" -" movq %rax, %ds \n\t" -" popq %rax \n\t" -" movq %rax, %es \n\t" -" popq %rax \n\t" -" addq $0x38, %rsp \n\t" -///////////////////////////////// -" movq %rdx, %rdi \n\t" -" callq *%rbx \n\t" -" movq %rax, %rdi \n\t" -" callq do_exit \n\t" -); - -unsigned long do_fork(struct pt_regs * regs, unsigned long clone_flags, unsigned long stack_start, unsigned long stack_size) { - struct task_struct *tsk = NULL; - struct thread_struct *thd = NULL; - mm_page_t *p = alloc_pages(ZONE_NORMAL, 8, PG_PTable_Maped | PG_Active | PG_Kernel); - - tsk = (struct task_struct*)PHY2VIR(p->phy_addr); - kinfo("struct task_struct address:%#018lx\n", (unsigned long)tsk); - - memset(tsk, 0, sizeof(struct task_struct)+sizeof(struct thread_struct)); - *tsk = *current; - - list_init(&tsk->list); - list_add_tail(&init_task_union.task.list, &tsk->list); - tsk->pid++; - tsk->state = TASK_UNINTERRUPTIBLE; - - thd = (struct thread_struct*)(tsk + 1); - tsk->thread = thd; - - memcpy(regs, (void *)((unsigned long)tsk + STACK_SIZE - sizeof(struct pt_regs)), sizeof(struct pt_regs)); - - thd->rsp0 = (unsigned long)tsk + STACK_SIZE; - thd->rip = regs->rip; - thd->rsp = (unsigned long)tsk + STACK_SIZE - sizeof(struct pt_regs); - - if(!(tsk->flags & PF_KTHREAD)) - thd->rip = regs->rip = (unsigned long)ret_system_call; - - tsk->state = TASK_RUNNING; - return 0; -} - -int kernel_thread(unsigned long (* fn)(unsigned long), unsigned long arg, unsigned long flags) { - struct pt_regs regs; - memset(®s, 0, sizeof(regs)); - - regs.rbx = (unsigned long)fn; - regs.rdx = (unsigned long)arg; - - regs.ds = KERNEL_DS; - regs.es = KERNEL_DS; - regs.cs = KERNEL_CS; - regs.ss = KERNEL_DS; - regs.rflags = (1 << 9); - regs.rip = (unsigned long)kernel_thread_func; - - return do_fork(®s, flags, 0, 0); -} - -void task_init() { - init_mm.pgd = (pml4t_t*) Global_CR3; - init_mm.start_code = gmdsc.start_text; - init_mm.end_code = gmdsc.end_text; - init_mm.start_data = gmdsc.start_data; - init_mm.end_data = gmdsc.end_data; - init_mm.start_rodata = gmdsc.start_rodata; - init_mm.end_rodata = gmdsc.end_rodata; - init_mm.start_brk = 0; - init_mm.end_brk = (unsigned long)PHY2VIR(gmdsc.kernel_end_phyaddr); - init_mm.start_stack = gmdsc.start_stack; - - wrmsr(0x174, KERNEL_CS); - wrmsr(0x175, current->thread->rsp0); - wrmsr(0x176, (unsigned long) system_call); - - set_tss64(init_tss[0].rsp0, init_tss[0].rsp1, init_tss[0].rsp2, init_tss[0].ist1, init_tss[0].ist2, init_tss[0].ist3, init_tss[0].ist4, init_tss[0].ist5, init_tss[0].ist6, init_tss[0].ist7); - init_tss[0].rsp0 = init_thread.rsp0; - - list_init(&init_task_union.task.list); - - kernel_thread(init, 10, CLONE_FS|CLONE_FILES|CLONE_SIGNAL); - - init_task_union.task.state = TASK_RUNNING; - struct task_struct *p = container_of(list_next(¤t->list), struct task_struct, list); - switch_to(current, p); -} \ No newline at end of file diff --git a/kernel/syscall/syscall.c b/kernel/syscall/syscall.c deleted file mode 100644 index 4948324..0000000 --- a/kernel/syscall/syscall.c +++ /dev/null @@ -1,26 +0,0 @@ -#include "syscall.h" -#include "kprint.h" -#include "printk.h" - -#define MAX_SYSTEM_CALL_NR 128 - -unsigned long no_system_call(struct pt_regs *regs) { - kinfo("no_system_call is calling, NR:%#04x\n", regs->rax); - return -1; -} - -unsigned long sys_printf(struct pt_regs *regs) { - kprintf((char*)regs->rdi); - return 0; -} - -typedef unsigned long (*system_call_t)(struct pt_regs *regs); -system_call_t system_call_table[MAX_SYSTEM_CALL_NR] = { - [0] = no_system_call, - [1] = sys_printf, - [2 ... MAX_SYSTEM_CALL_NR-1] = no_system_call -}; - -unsigned long system_call_function(struct pt_regs *regs) { - return system_call_table[regs->rax](regs); -} \ No newline at end of file diff --git a/lib/Makefile b/lib/Makefile new file mode 100644 index 0000000..fb2df24 --- /dev/null +++ b/lib/Makefile @@ -0,0 +1,8 @@ +-include $(BASE_DIR)/scripts/config.mk + +$(c_srcs_obj): $(c_srcs) + +compile: $(c_srcs_obj) + +clean: + $(HIDE)rm -rf $(c_srcs_obj) diff --git a/lib/string.c b/lib/string.c new file mode 100644 index 0000000..c9ac804 --- /dev/null +++ b/lib/string.c @@ -0,0 +1,33 @@ +#include + +#ifndef __HAVE_ARCH_MEMSET +void *memset(void *s, int c, size_t count) { + char *xs = s; + + while (count--) + *xs++ = c; + return s; +} +#endif + +#ifndef __HAVE_ARCH_STRNLEN +__kernel_size_t strnlen(const char *s, __kernel_size_t count) { + const char *sc; + + for (sc = s; count-- && *sc != '\0'; ++sc) + /* nothing */; + return sc - s; +} +#endif + +#ifndef __HAVE_ARCH_MEMCPY +void *memcpy(void *dest, const void *src, size_t count) +{ + char *tmp = dest; + const char *s = src; + + while (count--) + *tmp++ = *s++; + return dest; +} +#endif \ No newline at end of file diff --git a/lib/vsprintf.c b/lib/vsprintf.c new file mode 100644 index 0000000..25a1308 --- /dev/null +++ b/lib/vsprintf.c @@ -0,0 +1,476 @@ +#include + +#include +#include +#include +#include + +#include +#include + +static int skip_atoi(const char **s) { + int i=0; + + while (isdigit(**s)) + i = i*10 + *((*s)++) - '0'; + return i; +} + +int vscnprintf(char *buf, size_t size, const char *fmt, va_list args) { + int i; + + i = vsnprintf(buf,size,fmt,args); + return (i >= size) ? (size - 1) : i; +} + +static char* put_dec_trunc(char *buf, unsigned q) +{ + unsigned d3, d2, d1, d0; + d1 = (q>>4) & 0xf; + d2 = (q>>8) & 0xf; + d3 = (q>>12); + + d0 = 6*(d3 + d2 + d1) + (q & 0xf); + q = (d0 * 0xcd) >> 11; + d0 = d0 - 10*q; + *buf++ = d0 + '0'; /* least significant digit */ + d1 = q + 9*d3 + 5*d2 + d1; + if (d1 != 0) { + q = (d1 * 0xcd) >> 11; + d1 = d1 - 10*q; + *buf++ = d1 + '0'; /* next digit */ + + d2 = q + 2*d2; + if ((d2 != 0) || (d3 != 0)) { + q = (d2 * 0xd) >> 7; + d2 = d2 - 10*q; + *buf++ = d2 + '0'; /* next digit */ + + d3 = q + 4*d3; + if (d3 != 0) { + q = (d3 * 0xcd) >> 11; + d3 = d3 - 10*q; + *buf++ = d3 + '0'; /* next digit */ + if (q != 0) + *buf++ = q + '0'; /* most sign. digit */ + } + } + } + return buf; +} + +static char* put_dec_full(char *buf, unsigned q) +{ + /* BTW, if q is in [0,9999], 8-bit ints will be enough, */ + /* but anyway, gcc produces better code with full-sized ints */ + unsigned d3, d2, d1, d0; + d1 = (q>>4) & 0xf; + d2 = (q>>8) & 0xf; + d3 = (q>>12); + + /* Possible ways to approx. divide by 10 */ + /* gcc -O2 replaces multiply with shifts and adds */ + // (x * 0xcd) >> 11: 11001101 - shorter code than * 0x67 (on i386) + // (x * 0x67) >> 10: 1100111 + // (x * 0x34) >> 9: 110100 - same + // (x * 0x1a) >> 8: 11010 - same + // (x * 0x0d) >> 7: 1101 - same, shortest code (on i386) + + d0 = 6*(d3 + d2 + d1) + (q & 0xf); + q = (d0 * 0xcd) >> 11; + d0 = d0 - 10*q; + *buf++ = d0 + '0'; + d1 = q + 9*d3 + 5*d2 + d1; + q = (d1 * 0xcd) >> 11; + d1 = d1 - 10*q; + *buf++ = d1 + '0'; + + d2 = q + 2*d2; + q = (d2 * 0xd) >> 7; + d2 = d2 - 10*q; + *buf++ = d2 + '0'; + + d3 = q + 4*d3; + q = (d3 * 0xcd) >> 11; /* - shorter code */ + /* q = (d3 * 0x67) >> 10; - would also work */ + d3 = d3 - 10*q; + *buf++ = d3 + '0'; + *buf++ = q + '0'; + return buf; +} +/* No inlining helps gcc to use registers better */ +static char* put_dec(char *buf, unsigned long long num) { + while (1) { + unsigned rem; + if (num < 100000) + return put_dec_trunc(buf, num); + rem = do_div(num, 100000); + buf = put_dec_full(buf, rem); + } +} + +#define ZEROPAD 1 /* pad with zero */ +#define SIGN 2 /* unsigned/signed long */ +#define PLUS 4 /* show plus */ +#define SPACE 8 /* space if plus */ +#define LEFT 16 /* left justified */ +#define SMALL 32 /* Must be 32 == 0x20 */ +#define SPECIAL 64 /* 0x */ + +static char *number(char *buf, char *end, unsigned long long num, int base, int size, int precision, int type) +{ + /* we are called with base 8, 10 or 16, only, thus don't need "G..." */ + static const char digits[16] = "0123456789ABCDEF"; /* "GHIJKLMNOPQRSTUVWXYZ"; */ + + char tmp[66]; + char sign; + char locase; + int need_pfx = ((type & SPECIAL) && base != 10); + int i; + + /* locase = 0 or 0x20. ORing digits or letters with 'locase' + * produces same digits or (maybe lowercased) letters */ + locase = (type & SMALL); + if (type & LEFT) + type &= ~ZEROPAD; + sign = 0; + if (type & SIGN) { + if ((signed long long) num < 0) { + sign = '-'; + num = - (signed long long) num; + size--; + } else if (type & PLUS) { + sign = '+'; + size--; + } else if (type & SPACE) { + sign = ' '; + size--; + } + } + if (need_pfx) { + size--; + if (base == 16) + size--; + } + + /* generate full string in tmp[], in reverse order */ + i = 0; + if (num == 0) + tmp[i++] = '0'; + /* Generic code, for any base: + else do { + tmp[i++] = (digits[do_div(num,base)] | locase); + } while (num != 0); + */ + else if (base != 10) { /* 8 or 16 */ + int mask = base - 1; + int shift = 3; + if (base == 16) shift = 4; + do { + tmp[i++] = (digits[((unsigned char)num) & mask] | locase); + num >>= shift; + } while (num); + } else { /* base 10 */ + i = put_dec(tmp, num) - tmp; + } + + /* printing 100 using %2d gives "100", not "00" */ + if (i > precision) + precision = i; + /* leading space padding */ + size -= precision; + if (!(type & (ZEROPAD+LEFT))) { + while(--size >= 0) { + if (buf < end) + *buf = ' '; + ++buf; + } + } + /* sign */ + if (sign) { + if (buf < end) + *buf = sign; + ++buf; + } + /* "0x" / "0" prefix */ + if (need_pfx) { + if (buf < end) + *buf = '0'; + ++buf; + if (base == 16) { + if (buf < end) + *buf = ('X' | locase); + ++buf; + } + } + /* zero or space padding */ + if (!(type & LEFT)) { + char c = (type & ZEROPAD) ? '0' : ' '; + while (--size >= 0) { + if (buf < end) + *buf = c; + ++buf; + } + } + /* hmm even more zero padding? */ + while (i <= --precision) { + if (buf < end) + *buf = '0'; + ++buf; + } + /* actual digits of result */ + while (--i >= 0) { + if (buf < end) + *buf = tmp[i]; + ++buf; + } + /* trailing space padding */ + while (--size >= 0) { + if (buf < end) + *buf = ' '; + ++buf; + } + return buf; +} + +static char *string(char *buf, char *end, char *s, int field_width, int precision, int flags) { + int len, i; + + if ((unsigned long)s < PAGE_SIZE) + s = ""; + + len = strnlen(s, precision); + + if (!(flags & LEFT)) { + while (len < field_width--) { + if (buf < end) + *buf = ' '; + ++buf; + } + } + for (i = 0; i < len; ++i) { + if (buf < end) + *buf = *s; + ++buf; ++s; + } + while (len < field_width--) { + if (buf < end) + *buf = ' '; + ++buf; + } + return buf; +} + +static char *pointer(const char *fmt, char *buf, char *end, void *ptr, int field_width, int precision, int flags) +{ + flags |= SMALL; + if (field_width == -1) { + field_width = 2*sizeof(void *); + flags |= ZEROPAD; + } + return number(buf, end, (unsigned long) ptr, 16, field_width, precision, flags); +} + +int vsnprintf(char *buf, size_t size, const char *fmt, va_list args) { + unsigned long long num; + int base; + char *str, *end, c; + + int flags; /* flags to number() */ + + int field_width; /* width of output field */ + int precision; /* min. # of digits for integers; max + number of chars for from string */ + int qualifier; /* 'h', 'l', or 'L' for integer fields */ + /* 'z' support added 23/7/1999 S.H. */ + /* 'z' changed to 'Z' --davidm 1/25/99 */ + /* 't' added for ptrdiff_t */ + + str = buf; + end = buf + size; + + /* Make sure end is always >= buf */ + if (end < buf) { + end = ((void *)-1); + size = end - buf; + } + + for (; *fmt ; ++fmt) { + if (*fmt != '%') { + if (str < end) + *str = *fmt; + ++str; + continue; + } + + /* process flags */ + flags = 0; + repeat: + ++fmt; /* this also skips first '%' */ + switch (*fmt) { + case '-': flags |= LEFT; goto repeat; + case '+': flags |= PLUS; goto repeat; + case ' ': flags |= SPACE; goto repeat; + case '#': flags |= SPECIAL; goto repeat; + case '0': flags |= ZEROPAD; goto repeat; + } + + /* get field width */ + field_width = -1; + if (isdigit(*fmt)) + field_width = skip_atoi(&fmt); + else if (*fmt == '*') { + ++fmt; + /* it's the next argument */ + field_width = va_arg(args, int); + if (field_width < 0) { + field_width = -field_width; + flags |= LEFT; + } + } + + /* get the precision */ + precision = -1; + if (*fmt == '.') { + ++fmt; + if (isdigit(*fmt)) + precision = skip_atoi(&fmt); + else if (*fmt == '*') { + ++fmt; + /* it's the next argument */ + precision = va_arg(args, int); + } + if (precision < 0) + precision = 0; + } + + /* get the conversion qualifier */ + qualifier = -1; + if (*fmt == 'h' || *fmt == 'l' || *fmt == 'L' || + *fmt =='Z' || *fmt == 'z' || *fmt == 't') { + qualifier = *fmt; + ++fmt; + if (qualifier == 'l' && *fmt == 'l') { + qualifier = 'L'; + ++fmt; + } + } + + /* default base */ + base = 10; + + switch (*fmt) { + case 'c': + if (!(flags & LEFT)) { + while (--field_width > 0) { + if (str < end) + *str = ' '; + ++str; + } + } + c = (unsigned char) va_arg(args, int); + if (str < end) + *str = c; + ++str; + while (--field_width > 0) { + if (str < end) + *str = ' '; + ++str; + } + continue; + + case 's': + str = string(str, end, va_arg(args, char *), field_width, precision, flags); + continue; + + case 'p': + str = pointer(fmt+1, str, end, + va_arg(args, void *), + field_width, precision, flags); + /* Skip all alphanumeric pointer suffixes */ + while (isalnum(fmt[1])) + fmt++; + continue; + + case 'n': + /* FIXME: + * What does C99 say about the overflow case here? */ + if (qualifier == 'l') { + long * ip = va_arg(args, long *); + *ip = (str - buf); + } else if (qualifier == 'Z' || qualifier == 'z') { + size_t * ip = va_arg(args, size_t *); + *ip = (str - buf); + } else { + int * ip = va_arg(args, int *); + *ip = (str - buf); + } + continue; + + case '%': + if (str < end) + *str = '%'; + ++str; + continue; + + /* integer number formats - set up the flags and "break" */ + case 'o': + base = 8; + break; + + case 'x': + flags |= SMALL; + case 'X': + base = 16; + break; + + case 'd': + case 'i': + flags |= SIGN; + case 'u': + break; + + default: + if (str < end) + *str = '%'; + ++str; + if (*fmt) { + if (str < end) + *str = *fmt; + ++str; + } else { + --fmt; + } + continue; + } + if (qualifier == 'L') + num = va_arg(args, long long); + else if (qualifier == 'l') { + num = va_arg(args, unsigned long); + if (flags & SIGN) + num = (signed long) num; + } else if (qualifier == 'Z' || qualifier == 'z') { + num = va_arg(args, size_t); + } else if (qualifier == 't') { + num = va_arg(args, ptrdiff_t); + } else if (qualifier == 'h') { + num = (unsigned short) va_arg(args, int); + if (flags & SIGN) + num = (signed short) num; + } else { + num = va_arg(args, unsigned int); + if (flags & SIGN) + num = (signed int) num; + } + str = number(str, end, num, base, + field_width, precision, flags); + } + if (size > 0) { + if (str < end) + *str = '\0'; + else + end[-1] = '\0'; + } + /* the trailing null byte doesn't count towards the total */ + return str-buf; +} \ No newline at end of file diff --git a/link.lds b/link.lds deleted file mode 100644 index fe4753f..0000000 --- a/link.lds +++ /dev/null @@ -1,44 +0,0 @@ -OUTPUT_FORMAT("elf64-x86-64","elf64-x86-64","elf64-x86-64") -OUTPUT_ARCH(i386:x86-64) - -ENTRY(_start) -SECTIONS -{ - . = 32M; - _start_kernel = .; - .boot : { - *(.bs*) - . = ALIGN(4096); - } - - VMA = 0xffff800000000000; - . += VMA; - start_text = .; - .text (start_text): AT(start_text - VMA) { *(.text) } - end_text = .; - - . = ALIGN(32768); - start_data = .; - .data (start_data): AT(start_data - VMA) { *(.data) } - end_data = .; - - . = ALIGN(32768); - start_rodata = .; - .rodata (start_rodata): AT(start_rodata - VMA) { *(.rodata) *(.rodata.*) } - end_rodata = .; - - . = ALIGN(32768); - .data.init_task : { *(.data.init_task) } - - . = ALIGN(32768); - start_bss = .; - .bss (start_bss): AT(start_bss - VMA) { *(.bss) } - end_bss = .; - - _end_kernel = . - VMA; - - /DISCARD/ : { - *(.comment) - *(.eh_frame) - } -} \ No newline at end of file diff --git a/mm/Makefile b/mm/Makefile index a1cbb21..9b93ac9 100644 --- a/mm/Makefile +++ b/mm/Makefile @@ -1,13 +1,6 @@ -SOURCE := $(shell find . -name "*.c") -OBJS := $(SOURCE:%.c=%.o) -CFLAGS = -c -I../include --static \ - -mcmodel=large -fno-pie -fno-builtin \ - -fno-stack-protector -m64 +-include $(BASE_DIR)/scripts/config.mk -build: $(OBJS) - -$(OBJS):%.o:%.c - gcc $(CFLAGS) -o $@ $< +compile: $(c_srcs_obj) clean: - rm -rf $(OBJS) \ No newline at end of file + $(HIDE)rm -rf $(c_srcs_obj) \ No newline at end of file diff --git a/mm/alloc.c b/mm/alloc.c deleted file mode 100644 index 8a18817..0000000 --- a/mm/alloc.c +++ /dev/null @@ -1,79 +0,0 @@ -#include "mm.h" -#include "kprint.h" - -mm_page_t* alloc_pages(int zone_select, int n, uint64_t flags) { - int i; - unsigned long page = 0; - - int zone_start = 0; - int zone_end = 0; - - switch(zone_select) - { - case ZONE_DMA: - zone_start = 0; - zone_end = ZONE_DMA_INDEX; - break; - - case ZONE_NORMAL: - zone_start = ZONE_DMA_INDEX; - zone_end = ZONE_NORMAL_INDEX; - break; - - case ZONE_UNMAPED: - zone_start = ZONE_UNMAPED_INDEX; - zone_end = gmdsc.zones_size - 1; - break; - - default: - kerror("alloc_pages error zone_select index\n"); - return NULL; - break; - } - - for(i = zone_start;i <= zone_end; i++) - { - mm_zone_t *z; - unsigned long j; - unsigned long start,end,length; - unsigned long tmp; - - if((gmdsc.zones_struct + i)->page_free_count < n) - continue; - - z = gmdsc.zones_struct + i; - start = z->zone_start_addr >> PAGE_4K_SHIFT; - end = z->zone_end_addr >> PAGE_4K_SHIFT; - length = z->zone_length >> PAGE_4K_SHIFT; - - tmp = 64 - start % 64; - - for(j = start;j <= end;j += j % 64 ? tmp : 64) - { - unsigned long * p = gmdsc.page_bits + (j >> 6); - unsigned long shift = j % 64; - unsigned long k; - for(k = shift;k < 64 - shift;k++) - { - if( !(((*p >> k) | (*(p + 1) << (64 - k))) & (n == 64 ? 0xffffffffffffffffUL : ((1UL << n) - 1))) ) - { - unsigned long l; - page = j + k - 1; - for(l = 0;l < n;l++) - { - mm_page_t *x = gmdsc.pages_struct + page + l; - page_init(x, flags); - } - goto find_free_pages; - } - } - - } - } - - return NULL; - -find_free_pages: - - return (mm_page_t *)(gmdsc.pages_struct + page); -} \ No newline at end of file diff --git a/mm/bootmem.c b/mm/bootmem.c new file mode 100644 index 0000000..e69de29 diff --git a/mm/mm.c b/mm/mm.c deleted file mode 100644 index 1da1a99..0000000 --- a/mm/mm.c +++ /dev/null @@ -1,133 +0,0 @@ -#include "mm.h" -#include "kprint.h" -#include "kstring.h" - -extern char _start_kernel; -extern char _end_kernel; -extern char pml4; -extern char start_text, end_text; -extern char start_data, end_data; -extern char start_rodata, end_rodata; -extern char start_bss, end_bss; - -void page_bitmap_init(uint_t start_addr); -void pages_struct_init(uint_t start_addr); -void zones_struct_init(uint_t start_addr); -void construct_mem_struct(); -unsigned long page_init(mm_page_t *page, uint_t flags); - -void init_memory() { - Global_CR3 = (unsigned long*)PHY2VIR(&pml4); - gmdsc.start_text = (uint_t)&start_text; - gmdsc.end_text = (uint_t)&end_text; - gmdsc.start_data = (uint_t)&start_data; - gmdsc.end_data = (uint_t)&end_data; - gmdsc.start_rodata = (uint_t)&start_rodata; - gmdsc.end_rodata = (uint_t)&end_rodata; - gmdsc.start_bss = (uint_t)&start_bss; - gmdsc.end_bss = (uint_t)&end_bss; - - gmdsc.kernel_start_phyaddr = (uint_t)&_start_kernel; - gmdsc.kernel_end_phyaddr = (uint_t)&_end_kernel; - kinfo("kernel code start_phyaddr:%x end_phyaddr:%x\n", gmdsc.kernel_start_phyaddr, gmdsc.kernel_end_phyaddr); - - uint_t start_addr = PAGE_4K_ALIGN(gmdsc.kernel_end_phyaddr); - page_bitmap_init(start_addr); - - start_addr = PAGE_4K_ALIGN(gmdsc.page_bits + gmdsc.page_bits_length); - pages_struct_init(start_addr); - - start_addr = PAGE_4K_ALIGN(gmdsc.pages_struct + gmdsc.pages_size); - zones_struct_init(start_addr); - - gmdsc.end_of_struct = PAGE_4K_ALIGN(gmdsc.zones_struct + gmdsc.zones_size); - - construct_mem_struct(); -} - -void page_bitmap_init(uint_t start_addr) { - E820_t *e820 = &gmdsc.e820[gmdsc.e820_num-1]; - uint_t total_mem = e820->addr + e820->len; - kdebug("total memory: %d\n", total_mem); - - gmdsc.total_mem_length = total_mem; - gmdsc.page_bits = (uint_t*)start_addr; - gmdsc.page_bits_size = total_mem >> PAGE_4K_SHIFT; - gmdsc.page_bits_length = (((uint_t)(total_mem >> PAGE_4K_SHIFT) + sizeof(uint_t) * 8 - 1) / 8) & ( ~ (sizeof(uint_t) - 1)); - kinfo("page_bitmap start_addr:%x page_bits_size:%d page_bits_length:%d\n", gmdsc.page_bits, gmdsc.page_bits_size, gmdsc.page_bits_length); - memset(gmdsc.page_bits, 0xff, gmdsc.page_bits_length); -} - -void pages_struct_init(uint_t start_addr) { - gmdsc.pages_struct = (mm_page_t*)start_addr; - gmdsc.pages_size = gmdsc.total_mem_length >> PAGE_4K_SHIFT; - gmdsc.pages_length = (gmdsc.pages_size * sizeof(mm_page_t) + sizeof(uint_t) - 1) & ( ~ (sizeof(uint_t) - 1)); - kinfo("pages_struct start_addr:%x pages_size:%d pages_length:%d\n", gmdsc.pages_struct, gmdsc.pages_size, gmdsc.pages_length); - memset(gmdsc.pages_struct, 0x00, gmdsc.pages_length); -} - -void zones_struct_init(uint_t start_addr) { - gmdsc.zones_struct = (mm_zone_t*)start_addr; - gmdsc.zones_size = gmdsc.e820_available_size; - gmdsc.zones_length = (gmdsc.zones_size * sizeof(mm_zone_t) + sizeof(uint_t) - 1) & (~(sizeof(uint_t) - 1)); - kinfo("zones_struct start_addr:%x zones_size:%d zones_length:%d\n", gmdsc.zones_struct, gmdsc.zones_size, gmdsc.zones_length); - memset(gmdsc.zones_struct, 0x00, gmdsc.zones_length); -} - -void construct_mem_struct() { - uint32_t zone_idx = 0; - for (uint32_t i = 0; i < gmdsc.e820_num; i++) { - uint_t start, end; - E820_t *e820 = &gmdsc.e820[i]; - if (e820->type != E820_TYPE_AVAILABLE) continue; - start = PAGE_4K_ALIGN(e820->addr); - end = ((e820->addr + e820->len) >> PAGE_4K_SHIFT) << PAGE_4K_SHIFT; - if (end <= start) continue; - - mm_zone_t *z = gmdsc.zones_struct + zone_idx; - z->zone_start_addr = start; - z->zone_end_addr = end; - z->zone_length = end - start; - z->page_using_count = 0; - z->page_free_count = (end - start) >> PAGE_4K_SHIFT; - z->total_pages_link = 0; - z->attribute = 0; - z->pages_length = (end - start) >> PAGE_4K_SHIFT; - z->pages_group = (mm_page_t*)(gmdsc.pages_struct + (start >> PAGE_4K_SHIFT)); - - mm_page_t *p = z->pages_group; - for (uint32_t j = 0; j < z->pages_length; j++, p++) { - p->zone = z; - p->phy_addr = start + PAGE_4K_SIZE*j; - p->attribute = 0; - p->ref_count = 0; - p->age = 0; - *(gmdsc.page_bits + ((p->phy_addr >> PAGE_4K_SHIFT) >> 6)) ^= 1UL << (p->phy_addr >> PAGE_4K_SHIFT) % 64; - } - zone_idx++; - } - int kernel_start = gmdsc.kernel_start_phyaddr >> PAGE_4K_SHIFT, - kernel_end = VIR2PHY(gmdsc.end_of_struct) >> PAGE_4K_SHIFT; - for (int i = kernel_start; i < kernel_end; i++) { - page_init(gmdsc.pages_struct+i, PG_PTable_Maped|PG_Kernel_Init|PG_Active|PG_Kernel); - } -} - -unsigned long page_init(mm_page_t *page, uint_t flags) { - if (!page->attribute) { - *(gmdsc.page_bits + ((page->phy_addr >> PAGE_4K_SHIFT) >> 6)) |= 1UL << (page->phy_addr >> PAGE_4K_SHIFT) % 64; - page->attribute = flags; - page->ref_count++; - page->zone->page_using_count++; - page->zone->page_free_count--; - page->zone->total_pages_link++; - } else if ((page->attribute&PG_Referenced) || (page->attribute&PG_K_Share_To_U) || (flags&PG_Referenced) || (flags&PG_K_Share_To_U)) { - page->attribute |= flags; - page->ref_count++; - page->zone->total_pages_link++; - } else { - *(gmdsc.page_bits + ((page->phy_addr >> PAGE_4K_SHIFT) >> 6)) |= 1UL << (page->phy_addr >> PAGE_4K_SHIFT) % 64; - page->attribute |= flags; - } - return 0; -} \ No newline at end of file diff --git a/scripts/config.mk b/scripts/config.mk new file mode 100644 index 0000000..a5d66d8 --- /dev/null +++ b/scripts/config.mk @@ -0,0 +1,16 @@ +ASFLAGS=--64 +CFLAGS = -c -I$(BASE_DIR)/include -mcmodel=large --static -fno-pie -fno-builtin -fno-stack-protector -m64 + +c_srcs = $(wildcard ./*.c) +c_srcs_obj = $(patsubst %.c, %.o, $(c_srcs)) + +%.o: %.c + @echo "compile $<" + $(HIDE)$(CC) $(CFLAGS) $(DEBUG) $< -o $@ + +%.o: %.S + @echo "compile $<" + $(HIDE)$(CC) -E $(CFLAGS) $< > $<.i + $(HIDE)$(AS) $(ASFLAGS) -o $@ $<.i + +$(c_srcs_obj): $(c_srcs) \ No newline at end of file