diff --git a/.gitignore b/.gitignore deleted file mode 100644 index c13f0bc..0000000 --- a/.gitignore +++ /dev/null @@ -1,486 +0,0 @@ -# ---> C++ -# Prerequisites -*.d - -# Compiled Object files -*.slo -*.lo -#*.o -*.obj - -# Precompiled Headers -*.gch -*.pch - -# Compiled Dynamic libraries -*.so -*.dylib -*.dll - -# Fortran module files -*.mod -*.smod - -# Compiled Static libraries -*.lai -*.la -*.a -*.lib - -# Executables -*.exe -*.out -*.app - -# ---> Eclipse -.metadata -bin/ -tmp/ -*.tmp -*.bak -*.swp -*~.nib -local.properties -.settings/ -.loadpath -.recommenders - -# External tool builders -.externalToolBuilders/ - -# Locally stored "Eclipse launch configurations" -*.launch - -# PyDev specific (Python IDE for Eclipse) -*.pydevproject - -# CDT-specific (C/C++ Development Tooling) -.cproject - -# CDT- autotools -.autotools - -# Java annotation processor (APT) -.factorypath - -# PDT-specific (PHP Development Tools) -.buildpath - -# sbteclipse plugin -.target - -# Tern plugin -.tern-project - -# TeXlipse plugin -.texlipse - -# STS (Spring Tool Suite) -.springBeans - -# Code Recommenders -.recommenders/ - -# Annotation Processing -.apt_generated/ -.apt_generated_test/ - -# Scala IDE specific (Scala & Java development for Eclipse) -.cache-main -.scala_dependencies -.worksheet - -# Uncomment this line if you wish to ignore the project description file. -# Typically, this file would be tracked if it contains build/dependency configurations: -#.project - -# ---> VisualStudio -## Ignore Visual Studio temporary files, build results, and -## files generated by popular Visual Studio add-ons. -## -## Get latest from https://github.com/github/gitignore/blob/master/VisualStudio.gitignore - -# User-specific files -*.rsuser -*.suo -*.user -*.userosscache -*.sln.docstates - -# User-specific files (MonoDevelop/Xamarin Studio) -*.userprefs - -# Mono auto generated files -mono_crash.* - -# Build results -[Dd]ebug/ -[Dd]ebugPublic/ -[Rr]elease/ -[Rr]eleases/ -x64/ -x86/ -[Ww][Ii][Nn]32/ -[Aa][Rr][Mm]/ -[Aa][Rr][Mm]64/ -bld/ -[Bb]in/ -[Oo]bj/ -[Ll]og/ -[Ll]ogs/ - -# Visual Studio 2015/2017 cache/options directory -.vs/ -# Uncomment if you have tasks that create the project's static files in wwwroot -#wwwroot/ - -# Visual Studio 2017 auto generated files -Generated\ Files/ - -# MSTest test Results -[Tt]est[Rr]esult*/ -[Bb]uild[Ll]og.* - -# NUnit -*.VisualState.xml -TestResult.xml -nunit-*.xml - -# Build Results of an ATL Project -[Dd]ebugPS/ -[Rr]eleasePS/ -dlldata.c - -# Benchmark Results -BenchmarkDotNet.Artifacts/ - -# .NET Core -project.lock.json -project.fragment.lock.json -artifacts/ - -# ASP.NET Scaffolding -ScaffoldingReadMe.txt - -# StyleCop -StyleCopReport.xml - -# Files built by Visual Studio -*_i.c -*_p.c -*_h.h -*.ilk -*.meta -*.obj -*.iobj -*.pch -*.pdb -*.ipdb -*.pgc -*.pgd -*.rsp -*.sbr -*.tlb -*.tli -*.tlh -*.tmp -*.tmp_proj -*_wpftmp.csproj -*.log -*.tlog -*.vspscc -*.vssscc -.builds -*.pidb -*.svclog -*.scc - -# Chutzpah Test files -_Chutzpah* - -# Visual C++ cache files -ipch/ -*.aps -*.ncb -*.opendb -*.opensdf -*.sdf -*.cachefile -*.VC.db -*.VC.VC.opendb - -# Visual Studio profiler -*.psess -*.vsp -*.vspx -*.sap - -# Visual Studio Trace Files -*.e2e - -# TFS 2012 Local Workspace -$tf/ - -# Guidance Automation Toolkit -*.gpState - -# ReSharper is a .NET coding add-in -_ReSharper*/ -*.[Rr]e[Ss]harper -*.DotSettings.user - -# TeamCity is a build add-in -_TeamCity* - -# DotCover is a Code Coverage Tool -*.dotCover - -# AxoCover is a Code Coverage Tool -.axoCover/* -!.axoCover/settings.json - -# Coverlet is a free, cross platform Code Coverage Tool -coverage*.json -coverage*.xml -coverage*.info - -# Visual Studio code coverage results -*.coverage -*.coveragexml - -# NCrunch -_NCrunch_* -.*crunch*.local.xml -nCrunchTemp_* - -# MightyMoose -*.mm.* -AutoTest.Net/ - -# Web workbench (sass) -.sass-cache/ - -# Installshield output folder -[Ee]xpress/ - -# DocProject is a documentation generator add-in -DocProject/buildhelp/ -DocProject/Help/*.HxT -DocProject/Help/*.HxC -DocProject/Help/*.hhc -DocProject/Help/*.hhk -DocProject/Help/*.hhp -DocProject/Help/Html2 -DocProject/Help/html - -# Click-Once directory -publish/ - -# Publish Web Output -*.[Pp]ublish.xml -*.azurePubxml -# Note: Comment the next line if you want to checkin your web deploy settings, -# but database connection strings (with potential passwords) will be unencrypted -*.pubxml -*.publishproj - -# Microsoft Azure Web App publish settings. Comment the next line if you want to -# checkin your Azure Web App publish settings, but sensitive information contained -# in these scripts will be unencrypted -PublishScripts/ - -# NuGet Packages -*.nupkg -# NuGet Symbol Packages -*.snupkg -# The packages folder can be ignored because of Package Restore -**/[Pp]ackages/* -# except build/, which is used as an MSBuild target. -!**/[Pp]ackages/build/ -# Uncomment if necessary however generally it will be regenerated when needed -#!**/[Pp]ackages/repositories.config -# NuGet v3's project.json files produces more ignorable files -*.nuget.props -*.nuget.targets - -# Nuget personal access tokens and Credentials -nuget.config - -# Microsoft Azure Build Output -csx/ -*.build.csdef - -# Microsoft Azure Emulator -ecf/ -rcf/ - -# Windows Store app package directories and files -AppPackages/ -BundleArtifacts/ -Package.StoreAssociation.xml -_pkginfo.txt -*.appx -*.appxbundle -*.appxupload - -# Visual Studio cache files -# files ending in .cache can be ignored -*.[Cc]ache -# but keep track of directories ending in .cache -!?*.[Cc]ache/ - -# Others -ClientBin/ -~$* -*~ -*.dbmdl -*.dbproj.schemaview -*.jfm -*.pfx -*.publishsettings -orleans.codegen.cs - -# Including strong name files can present a security risk -# (https://github.com/github/gitignore/pull/2483#issue-259490424) -#*.snk - -# Since there are multiple workflows, uncomment next line to ignore bower_components -# (https://github.com/github/gitignore/pull/1529#issuecomment-104372622) -#bower_components/ - -# RIA/Silverlight projects -Generated_Code/ - -# Backup & report files from converting an old project file -# to a newer Visual Studio version. Backup files are not needed, -# because we have git ;-) -_UpgradeReport_Files/ -Backup*/ -UpgradeLog*.XML -UpgradeLog*.htm -ServiceFabricBackup/ -*.rptproj.bak - -# SQL Server files -*.mdf -*.ldf -*.ndf - -# Business Intelligence projects -*.rdl.data -*.bim.layout -*.bim_*.settings -*.rptproj.rsuser -*- [Bb]ackup.rdl -*- [Bb]ackup ([0-9]).rdl -*- [Bb]ackup ([0-9][0-9]).rdl - -# Microsoft Fakes -FakesAssemblies/ - -# GhostDoc plugin setting file -*.GhostDoc.xml - -# Node.js Tools for Visual Studio -.ntvs_analysis.dat -node_modules/ - -# Visual Studio 6 build log -*.plg - -# Visual Studio 6 workspace options file -*.opt - -# Visual Studio 6 auto-generated workspace file (contains which files were open etc.) -*.vbw - -# Visual Studio LightSwitch build output -**/*.HTMLClient/GeneratedArtifacts -**/*.DesktopClient/GeneratedArtifacts -**/*.DesktopClient/ModelManifest.xml -**/*.Server/GeneratedArtifacts -**/*.Server/ModelManifest.xml -_Pvt_Extensions - -# Paket dependency manager -.paket/paket.exe -paket-files/ - -# FAKE - F# Make -.fake/ - -# CodeRush personal settings -.cr/personal - -# Python Tools for Visual Studio (PTVS) -__pycache__/ -*.pyc - -# Cake - Uncomment if you are using it -# tools/** -# !tools/packages.config - -# Tabs Studio -*.tss - -# Telerik's JustMock configuration file -*.jmconfig - -# BizTalk build output -*.btp.cs -*.btm.cs -*.odx.cs -*.xsd.cs - -# OpenCover UI analysis results -OpenCover/ - -# Azure Stream Analytics local run output -ASALocalRun/ - -# MSBuild Binary and Structured Log -*.binlog - -# NVidia Nsight GPU debugger configuration file -*.nvuser - -# MFractors (Xamarin productivity tool) working folder -.mfractor/ - -# Local History for Visual Studio -.localhistory/ - -# BeatPulse healthcheck temp database -healthchecksdb - -# Backup folder for Package Reference Convert tool in Visual Studio 2017 -MigrationBackup/ - -# Ionide (cross platform F# VS Code tools) working folder -.ionide/ - -# Fody - auto-generated XML schema -FodyWeavers.xsd - -# VS Code files for those working on multiple tools -.vscode/* -!.vscode/settings.json -!.vscode/tasks.json -!.vscode/launch.json -!.vscode/extensions.json -*.code-workspace - -# Local History for Visual Studio Code -.history/ - -# Windows Installer files from build outputs -*.cab -*.msi -*.msix -*.msm -*.msp - -# JetBrains Rider -.idea/ -*.sln.iml - diff --git a/SysBoot/makeall.bat b/SysBoot/makeall.bat new file mode 100644 index 0000000..0d28bf6 --- /dev/null +++ b/SysBoot/makeall.bat @@ -0,0 +1,16 @@ +@echo off +set nasm_path=C:\nasm +set djgpp_path=C:\DJGPP\bin + +@echo ***************** CTA Bootloader ***************** +@echo. + +:Stage1 + cd stage1 + call make.bat + cd.. + +:Stage2 + cd stage2 + call make.bat + cd.. \ No newline at end of file diff --git a/stage1/bootload.bin b/SysBoot/stage1/BOOTLOAD.BIN similarity index 100% rename from stage1/bootload.bin rename to SysBoot/stage1/BOOTLOAD.BIN diff --git a/stage1/bootload.asm b/SysBoot/stage1/bootload.asm similarity index 100% rename from stage1/bootload.asm rename to SysBoot/stage1/bootload.asm diff --git a/SysBoot/stage1/make.bat b/SysBoot/stage1/make.bat new file mode 100644 index 0000000..aa718bf --- /dev/null +++ b/SysBoot/stage1/make.bat @@ -0,0 +1,23 @@ +@echo off +set nasm_path=C:\nasm +set djgpp_path=C:\DJGPP\bin + +goto build + +:error + @echo. + @echo There have been build errors. Building halted. + @pause + exit + +:build + @echo Compiling stage 1... + del bootload.bin + %nasm_path%\nasm.exe -f bin bootload.asm -o bootload.bin + +:check + if not exist bootload.bin goto error + +:copy + @echo Writing stage 1 to floppy boot sector... + debug bootload.bin <..\..\scripts\stage1d >nul \ No newline at end of file diff --git a/SysBoot/stage2/MAKE.BAT b/SysBoot/stage2/MAKE.BAT new file mode 100644 index 0000000..fc0dc23 --- /dev/null +++ b/SysBoot/stage2/MAKE.BAT @@ -0,0 +1,24 @@ +@echo off +set nasm_path=C:\nasm +set djgpp_path=C:\DJGPP\bin + +goto build + +:error + @echo. + @echo There have been build errors. Building halted. + @pause + exit + +:build + + @echo Compiling stage 2... + del stage2.cta + %nasm_path%\nasm.exe -f bin stage2.asm -o stage2.cta + +:test + if not exist stage2.cta goto error + +:copy + @echo Copying stage 2 to floppy... + copy stage2.cta A:\stage2.cta >nul \ No newline at end of file diff --git a/SysBoot/stage2/STAGE2.CTA b/SysBoot/stage2/STAGE2.CTA new file mode 100644 index 0000000..7931fd0 Binary files /dev/null and b/SysBoot/stage2/STAGE2.CTA differ diff --git a/SysBoot/stage2/a20.inc b/SysBoot/stage2/a20.inc new file mode 100644 index 0000000..a839634 --- /dev/null +++ b/SysBoot/stage2/a20.inc @@ -0,0 +1,55 @@ + + +;******************************************** +; Enable A20 address line +; +; OS Development Series +;******************************************** + +bits 16 ; real mode 16 bit code + +_EnableA20: + + cli + + call a20wait + mov al,0xAD + out 0x64,al + + call a20wait + mov al,0xD0 + out 0x64,al + + call a20wait2 + in al,0x60 + push eax + + call a20wait + mov al,0xD1 + out 0x64,al + + call a20wait + pop eax + or al,2 + out 0x60,al + + call a20wait + mov al,0xAE + out 0x64,al + + call a20wait + sti + ret + +a20wait: + in al,0x64 + test al,2 + jnz a20wait + ret + + +a20wait2: + in al,0x64 + test al,1 + jz a20wait2 + ret diff --git a/SysBoot/stage2/bootinfo.inc b/SysBoot/stage2/bootinfo.inc new file mode 100644 index 0000000..1c40976 --- /dev/null +++ b/SysBoot/stage2/bootinfo.inc @@ -0,0 +1,40 @@ + +;******************************************************* +; +; bootinfo.inc +; multiboot information structure +; +; OS Development Series +;******************************************************* + +%ifndef __BOOTINFO_INC_67343546FDCC56AAB872_INCLUDED__ +%define __BOOTINFO_INC_67343546FDCC56AAB872_INCLUDED__ + +struc multiboot_info + .flags resd 1 + .memoryLo resd 1 + .memoryHi resd 1 + .bootDevice resd 1 + .cmdLine resd 1 + .mods_count resd 1 + .mods_addr resd 1 + .syms0 resd 1 + .syms1 resd 1 + .syms2 resd 1 + .mmap_length resd 1 + .mmap_addr resd 1 + .drives_length resd 1 + .drives_addr resd 1 + .config_table resd 1 + .bootloader_name resd 1 + .apm_table resd 1 + .vbe_control_info resd 1 + .vbe_mode_info resd 1 + .vbe_mode resw 1 + .vbe_interface_seg resw 1 + .vbe_interface_off resw 1 + .vbe_interface_len resw 1 +endstruc + + +%endif diff --git a/stage2/common.inc b/SysBoot/stage2/common.inc similarity index 100% rename from stage2/common.inc rename to SysBoot/stage2/common.inc diff --git a/stage2/fat12.inc b/SysBoot/stage2/fat12.inc similarity index 72% rename from stage2/fat12.inc rename to SysBoot/stage2/fat12.inc index f2a120b..c490509 100644 --- a/stage2/fat12.inc +++ b/SysBoot/stage2/fat12.inc @@ -141,41 +141,40 @@ FindFile: ; parm/ ES:SI => File to load ; parm/ EBX:BP => Buffer to load file to ; ret/ AX => -1 on error, 0 on success -; ret/ CX => number of sectors read ;******************************************* LoadFile: - xor ecx, ecx ; size of file in sectors + xor ecx, ecx ; size of file in sectors push ecx .FIND_FILE: - push bx ; BX=>BP points to buffer to write to; store it for later + push bx ; BX=>BP points to buffer to write to; store it for later push bp - call FindFile ; find our file. ES:SI contains our filename - cmp ax, -1 - jne .LOAD_IMAGE_PRE - pop bp - pop bx - pop ecx - mov ax, -1 + call FindFile ; find our file. ES:SI contains our filename + cmp ax, -1 + jne .LOAD_IMAGE_PRE + pop bp + pop bx + pop ecx + mov ax, -1 ret .LOAD_IMAGE_PRE: - sub edi, ROOT_OFFSET - sub eax, ROOT_OFFSET + sub edi, ROOT_OFFSET + sub eax, ROOT_OFFSET ; get starting cluster - push word ROOT_SEG ;root segment loc - pop es - mov dx, WORD [es:di + 0x001A]; DI points to file entry in root directory table. Refrence the table... - mov WORD [cluster], dx ; file's first cluster - pop bx ; get location to write to so we dont screw up the stack - pop es - push bx ; store location for later again + push word ROOT_SEG ;root segment loc + pop es + mov dx, WORD [es:di + 0x001A] ; DI points to file entry in root directory table. Refrence the table... + mov WORD [cluster], dx ; file's first cluster + pop bx ; get location to write to so we dont screw up the stack + pop es + push bx ; store location for later again push es call LoadFAT @@ -183,56 +182,60 @@ LoadFile: ; load the cluster - mov ax, WORD [cluster] ; cluster to read - pop es ; bx:bp=es:bx - pop bx + mov ax, WORD [cluster] ; cluster to read + pop es ; bx:bp=es:bx + pop bx call ClusterLBA - xor cx, cx + xor cx, cx mov cl, BYTE [bpbSectorsPerCluster] + call ReadSectors - pop ecx - inc ecx ; add one more sector to counter + + pop ecx + inc ecx push ecx + push bx push es - mov ax, FAT_SEG ;start reading from fat - mov es, ax - xor bx, bx + + mov ax, FAT_SEG ;start reading from fat + mov es, ax + xor bx, bx ; get next cluster - mov ax, WORD [cluster] ; identify current cluster - mov cx, ax ; copy current cluster - mov dx, ax - shr dx, 0x0001 ; divide by two - add cx, dx ; sum for (3/2) + mov ax, WORD [cluster] ; identify current cluster + mov cx, ax ; copy current cluster + mov dx, ax ; copy current cluster + shr dx, 0x0001 ; divide by two + add cx, dx ; sum for (3/2) - mov bx, 0 ;location of fat in memory - add bx, cx - mov dx, WORD [es:bx] - test ax, 0x0001 ; test for odd or even cluster - jnz .ODD_CLUSTER + mov bx, 0 ;location of fat in memory + add bx, cx + mov dx, WORD [es:bx] + test ax, 0x0001 ; test for odd or even cluster + jnz .ODD_CLUSTER .EVEN_CLUSTER: - and dx, 0000111111111111b ; take low 12 bits - jmp .DONE + and dx, 0000111111111111b ; take low 12 bits + jmp .DONE .ODD_CLUSTER: - shr dx, 0x0004 ; take high 12 bits + shr dx, 0x0004 ; take high 12 bits .DONE: - mov WORD [cluster], dx - cmp dx, 0x0ff0 ; test for end of file marker - jb .LOAD_IMAGE + mov WORD [cluster], dx + cmp dx, 0x0ff0 ; test for end of file marker + jb .LOAD_IMAGE .SUCCESS: - pop es - pop bx - pop ecx - xor ax, ax + pop es + pop bx + pop ecx + xor ax, ax ret %endif ;__FAT12_INC_67343546FDCC56AAB872_INCLUDED__ diff --git a/stage2/floppy16.inc b/SysBoot/stage2/floppy16.inc similarity index 99% rename from stage2/floppy16.inc rename to SysBoot/stage2/floppy16.inc index 5893a6a..48779ca 100644 --- a/stage2/floppy16.inc +++ b/SysBoot/stage2/floppy16.inc @@ -114,4 +114,8 @@ ReadSectors: loop .MAIN ; read next sector ret + + + + %endif ;__FLOPPY16_INC_67343546FDCC56AAB872_INCLUDED__ diff --git a/stage2/gdt.inc b/SysBoot/stage2/gdt.inc similarity index 100% rename from stage2/gdt.inc rename to SysBoot/stage2/gdt.inc diff --git a/SysBoot/stage2/memory.inc b/SysBoot/stage2/memory.inc new file mode 100644 index 0000000..a78605c --- /dev/null +++ b/SysBoot/stage2/memory.inc @@ -0,0 +1,175 @@ + +;************************************************* +; Memory.inc +; -Basic memory routines +; +; OS Development Series +;************************************************* + +%ifndef __MEMORY_INC_67343546FDCC56AAB872_INCLUDED__ +%define __MEMORY_INC_67343546FDCC56AAB872_INCLUDED__ + +bits 16 + +;-------------------------------------------- +; Memory map entry structure +;-------------------------------------------- + +struc MemoryMapEntry + .baseAddress resq 1 + .length resq 1 + .type resd 1 + .acpi_null resd 1 +endstruc + +;--------------------------------------------- +; Get memory map from bios +; /in es:di->destination buffer for entries +; /ret bp=entry count +;--------------------------------------------- + +BiosGetMemoryMap: + pushad + xor ebx, ebx + xor bp, bp ; number of entries stored here + mov edx, 'PAMS' ; 'SMAP' + mov eax, 0xe820 + mov ecx, 24 ; memory map entry struct is 24 bytes + int 0x15 ; get first entry + jc .error + cmp eax, 'PAMS' ; bios returns SMAP in eax + jne .error + test ebx, ebx ; if ebx=0 then list is one entry long; bail out + je .error + jmp .start +.next_entry: + mov edx, 'PAMS' ; some bios's trash this register + mov ecx, 24 ; entry is 24 bytes + mov eax, 0xe820 + int 0x15 ; get next entry +.start: + jcxz .skip_entry ; if actual returned bytes is 0, skip entry +.notext: + mov ecx, [es:di + MemoryMapEntry.length] ; get length (low dword) + test ecx, ecx ; if length is 0 skip it + jne short .good_entry + mov ecx, [es:di + MemoryMapEntry.length + 4]; get length (upper dword) + jecxz .skip_entry ; if length is 0 skip it +.good_entry: + inc bp ; increment entry count + add di, 24 ; point di to next entry in buffer +.skip_entry: + cmp ebx, 0 ; if ebx return is 0, list is done + jne .next_entry ; get next entry + jmp .done +.error: + stc +.done: + popad + ret + +;--------------------------------------------- +; Get memory size for >64M configuations (32 bit) +; ret\ ax=KB between 1MB and 16MB +; ret\ bx=number of 64K blocks above 16MB +; ret\ bx=0 and ax= -1 on error +;--------------------------------------------- + +BiosGetMemorySize64MB_32Bit: + push ecx + push edx + xor ecx, ecx + xor edx, edx + mov ax, 0xe881 + int 0x15 + jc .error + cmp ah, 0x86 ;unsupported function + je .error + cmp ah, 0x80 ;invalid command + je .error + jcxz .use_ax ;bios may have stored it in ax,bx or cx,dx. test if cx is 0 + mov ax, cx ;its not, so it should contain mem size; store it + mov bx, dx + +.use_ax: + pop edx ;mem size is in ax and bx already, return it + pop ecx + ret + +.error: + mov ax, -1 + mov bx, 0 + pop edx + pop ecx + ret + +;--------------------------------------------- +; Get memory size for >64M configuations +; ret\ ax=KB between 1MB and 16MB +; ret\ bx=number of 64K blocks above 16MB +; ret\ bx=0 and ax= -1 on error +;--------------------------------------------- + +BiosGetMemorySize64MB: + push ecx + push edx + xor ecx, ecx + xor edx, edx + mov ax, 0xe801 + int 0x15 + jc .error + cmp ah, 0x86 ;unsupported function + je .error + cmp ah, 0x80 ;invalid command + je .error + jcxz .use_ax ;bios may have stored it in ax,bx or cx,dx. test if cx is 0 + mov ax, cx ;its not, so it should contain mem size; store it + mov bx, dx + +.use_ax: + pop edx ;mem size is in ax and bx already, return it + pop ecx + ret + +.error: + mov si, msgNotSupported + call Puts16 + mov ax, -1 + mov bx, 0 + pop edx + pop ecx + ret + +;--------------------------------------------- +; Get amount of contiguous KB from addr 0 +; ret\ ax=KB size from address 0 +;--------------------------------------------- + +BiosGetMemorySize: + int 0x12 + ret + +;--------------------------------------------- +; Get contiguous exetended memory size +; ret\ ax=KB size above 1MB; ax= -1 on error +;--------------------------------------------- + +BiosGetExtendedMemorySize: + mov ax, 0x88 + int 0x15 + jc .error + test ax, ax ; if size=0 + je .error + cmp ah, 0x86 ;unsupported function + je .error + cmp ah, 0x80 ;invalid command + je .error + ret +.error: + mov ax, -1 + ret + + +msgNotSupported db 0x0A, 0x0D, "BiosGetMemorySize64MB: function not supported.",0x0A, 0x0D, 0x00 + +%endif diff --git a/SysBoot/stage2/stage2.asm b/SysBoot/stage2/stage2.asm new file mode 100644 index 0000000..6c52bca --- /dev/null +++ b/SysBoot/stage2/stage2.asm @@ -0,0 +1,172 @@ + +;******************************************************* +; +; Stage2.asm +; Stage2 Bootloader +; +; OS Development Series +;******************************************************* + +bits 16 + +org 0x500 + +jmp main ; go to start + +;******************************************************* +; Preprocessor directives +;******************************************************* + +%include "stdio.inc" ; basic i/o routines +%include "gdt.inc" ; Gdt routines +%include "a20.inc" ; A20 enabling +%include "fat12.inc" ; FAT12 driver. Kinda :) +%include "common.inc" +;%include "bootinfo.inc" +%include "memory.inc" + +;******************************************************* +; Data Section +;******************************************************* + +msgFailure db 0x0D, 0x0A, "FATAL ERROR: Kernel file KERNEL.CTA missing or corrupt. Press Any Key to Reboot.", 0x0D, 0x0A, 0x0A, 0x00 + +boot_info: + multiboot_info_flags dd 0 + multiboot_info_memoryLo dd 0 + multiboot_info_memoryHi dd 0 + multiboot_info_bootDevice dd 0 + multiboot_info_cmdLine dd 0 + multiboot_info_mods_count dd 0 + multiboot_info_mods_addr dd 0 + multiboot_info_syms0 dd 0 + multiboot_info_syms1 dd 0 + multiboot_info_syms2 dd 0 + multiboot_info_mmap_length dd 0 + multiboot_info_mmap_addr dd 0 + multiboot_info_drives_length dd 0 + multiboot_info_drives_addr dd 0 + multiboot_info_config_table dd 0 + multiboot_info_bootloader_name dd 0 + multiboot_info_apm_table dd 0 + multiboot_info_vbe_control_info dd 0 + multiboot_info_vbe_mode_info dw 0 + multiboot_info_vbe_interface_seg dw 0 + multiboot_info_vbe_interface_off dw 0 + multiboot_info_vbe_interface_len dw 0 + +main: + + ;-------------------------------; + ; Setup segments and stack ; + ;-------------------------------; + + cli ; clear interrupts + xor ax, ax ; null segments + mov ds, ax + mov es, ax + mov ax, 0x0000 ; stack begins at 0x9000-0xffff + mov ss, ax + mov sp, 0xFFFF + sti ; enable interrupts + + mov [multiboot_info_bootDevice], dl + + call _EnableA20 + call InstallGDT + sti + + xor eax, eax + xor ebx, ebx + call BiosGetMemorySize64MB + + mov word [multiboot_info_memoryHi], bx + mov word [multiboot_info_memoryLo], ax + + mov eax, 0x0 + mov ds, ax + mov di, 0x1000 + call BiosGetMemoryMap + mov dword [multiboot_info_mmap_addr], 0x1000 + xor eax, eax + mov ax, bp + mov dword [multiboot_info_mmap_length], eax + + + call LoadRoot + mov ebx, 0 + mov ebp, IMAGE_RMODE_BASE + mov esi, ImageName + call LoadFile ; load our file + mov dword [ImageSize], ecx + cmp ax, 0 + je EnterStage3 + mov si, msgFailure + call Puts16 + mov ah, 0 + int 0x16 ; await keypress + int 0x19 ; warm boot computer + + ;-------------------------------; + ; Go into pmode ; + ;-------------------------------; + +EnterStage3: + + cli ; clear interrupts + mov eax, cr0 ; set bit 0 in cr0--enter pmode + or eax, 1 + mov cr0, eax + + jmp CODE_DESC:Stage3 ; far jump to fix CS. Remember that the code selector is 0x8! + + ; Note: Do NOT re-enable interrupts! Doing so will triple fault! + ; We will fix this in Stage 3. + +;****************************************************** +; ENTRY POINT FOR STAGE 3 +;****************************************************** + +bits 32 + +BadImage db "FATAL ERROR: Kernel file KERNEL.CTA missing or corrupt. Press Any Key to Reboot.", 0 + +Stage3: + + ;-------------------------------; + ; Set registers ; + ;-------------------------------; + + mov ax, DATA_DESC ; set data segments to data selector (0x10) + mov ds, ax + mov ss, ax + mov es, ax + mov esp, 90000h ; stack begins from 90000h + + +CopyImage: + mov eax, dword [ImageSize] + movzx ebx, word [bpbBytesPerSector] + mul ebx + mov ebx, 4 + div ebx + cld + mov esi, IMAGE_RMODE_BASE + mov edi, IMAGE_PMODE_BASE + mov ecx, eax + rep movsd ; copy image to its protected mode address + + mov eax, 0x2badb002 ; multiboot specs say eax should be this + mov ebx, 0 + +;edx=8 + + push dword boot_info + push dword [ImageSize] + + jmp CODE_DESC:IMAGE_PMODE_BASE ; Execute Kernel + add esp, 4 + + cli + hlt + \ No newline at end of file diff --git a/stage2/stdio.inc b/SysBoot/stage2/stdio.inc similarity index 61% rename from stage2/stdio.inc rename to SysBoot/stage2/stdio.inc index b1aa7d4..d5e7eef 100644 --- a/stage2/stdio.inc +++ b/SysBoot/stage2/stdio.inc @@ -21,6 +21,7 @@ ; -Prints a null terminated string ; DS=>SI: 0 terminated string ;************************************************; +tmpStr db " ", 0x0D, 0x0A, 0x00 bits 16 @@ -38,6 +39,44 @@ Puts16Done: ret ; we are done, so return +PutINT: + pusha ; save registers + + mov cx, 0 + .init: + mov bx, cx + add bx, tmpStr + mov [bx], byte ' ' + inc cx + + cmp cx, 31 + jne .init + + + mov cx, 31 ; initialize counter + + .loop: + mov dx, 0 + mov bx, 0x0A + div bx ; ax = ax/10, dx = ax%10 + mov bx, cx + add bx, tmpStr + add dl, '0' + mov [bx], dl + + sub cx, 1 + + cmp ax, 0 ; when done, ax = 0; + je .done + + jmp .loop + + .done: + mov si, tmpStr + call Puts16 + popa + ret + ;========================================================== ; ; 32 Bit Protected Mode Routines @@ -48,7 +87,7 @@ bits 32 %define VIDMEM 0xB8000 ; video memory %define COLS 80 ; width and height of screen %define LINES 25 -%define CHAR_ATTRIB 63 ; character attribute (White text on light blue background) +%define CHAR_ATTRIB 14 ; character attribute (White text on black background) _CurX db 0 ; current x/y location _CurY db 0 @@ -61,85 +100,53 @@ _CurY db 0 Putch32: - pusha ; save registers - mov edi, VIDMEM ; get pointer to video memory - - ;-------------------------------; - ; Get current position ; - ;-------------------------------; + pusha + mov edi, VIDMEM xor eax, eax ; clear eax - ;-------------------------------- - ; Remember: currentPos = x + y * COLS! x and y are in _CurX and _CurY. - ; Because there are two bytes per character, COLS=number of characters in a line. - ; We have to multiply this by 2 to get number of bytes per line. This is the screen width, - ; so multiply screen with * _CurY to get current line - ;-------------------------------- + ; y * screen width - mov ecx, COLS*2 ; Mode 7 has 2 bytes per char, so its COLS*2 bytes per line - mov al, byte [_CurY] ; get y pos - mul ecx ; multiply y*COLS - push eax ; save eax--the multiplication + mov ecx, COLS*2 ; Mode 7 has 2 bytes per char, so its COLS*2 bytes per line + mov al, byte [_CurY] ; get y pos + mul ecx ; multiply y*COLS + push eax ; save eax--the multiplication - ;-------------------------------- - ; Now y * screen width is in eax. Now, just add _CurX. But, again remember that _CurX is relative - ; to the current character count, not byte count. Because there are two bytes per character, we - ; have to multiply _CurX by 2 first, then add it to our screen width * y. - ;-------------------------------- + ; now add _CurX * 2 - mov al, byte [_CurX] ; multiply _CurX by 2 because it is 2 bytes per char - mov cl, 2 - mul cl - pop ecx ; pop y*COLS result - add eax, ecx + mov al, byte [_CurX] ; multiply _CurX by 2 because it is 2 bytes per char + mov cl, 2 + mul cl + pop ecx ; pop y*COLS result + add eax, ecx - ;------------------------------- - ; Now eax contains the offset address to draw the character at, so just add it to the base address - ; of video memory (Stored in edi) - ;------------------------------- + ; add the position to draw to the base of vid memory - xor ecx, ecx - add edi, eax ; add it to the base address + xor ecx, ecx + add edi, eax ; add it to the base address - ;-------------------------------; - ; Watch for new line ; - ;-------------------------------; + ; watch for new line cmp bl, 0x0A ; is it a newline character? je .Row ; yep--go to next row - ;-------------------------------; - ; Print a character ; - ;-------------------------------; + ; print the character mov dl, bl ; Get character mov dh, CHAR_ATTRIB ; the character attribute mov word [edi], dx ; write to video display - ;-------------------------------; - ; Update next position ; - ;-------------------------------; + ; go to next location inc byte [_CurX] ; go to next character -; cmp byte [_CurX], COLS ; are we at the end of the line? -; je .Row ; yep-go to next row jmp .done ; nope, bail out - ;-------------------------------; - ; Go to next row ; - ;-------------------------------; - .Row: mov byte [_CurX], 0 ; go back to col 0 inc byte [_CurY] ; go to next row - ;-------------------------------; - ; Restore registers & return ; - ;-------------------------------; - .done: - popa ; restore registers and return + popa ret ;**************************************************; @@ -150,11 +157,7 @@ Putch32: Puts32: - ;-------------------------------; - ; Store registers ; - ;-------------------------------; - - pusha ; save registers + pusha push ebx ; copy the string address pop edi @@ -187,9 +190,6 @@ Puts32: ; Update hardware cursor ; ;-------------------------------; - ; Its more efficiant to update the cursor after displaying - ; the complete string because direct VGA is slow - mov bh, byte [_CurY] ; get current position mov bl, byte [_CurX] call MovCur ; update cursor @@ -203,20 +203,20 @@ Puts32: ; parm/ bh = Y pos ; parm/ bl = x pos ;**************************************************; + + bits 32 MovCur: - pusha ; save registers (aren't you getting tired of this comment?) + pusha ;-------------------------------; ; Get current position ; ;-------------------------------; - ; Here, _CurX and _CurY are relitave to the current position on screen, not in memory. - ; That is, we don't need to worry about the byte alignment we do when displaying characters, - ; so just follow the forumla: location = _CurX + _CurY * COLS + ; location = _CurX + _CurY * COLS xor eax, eax mov ecx, COLS @@ -270,7 +270,6 @@ ClrScr32: mov ah, CHAR_ATTRIB mov al, ' ' rep stosw - mov byte [_CurX], 0 mov byte [_CurY], 0 popa @@ -287,12 +286,10 @@ bits 32 GotoXY: pusha - mov [_CurX], al ; just set the current position + mov [_CurX], al mov [_CurY], ah popa ret - - %endif ;__STDIO_INC_67343546FDCC56AAB872_INCLUDED__ diff --git a/kernel/compile.bat b/SysCore/compile.bat similarity index 56% rename from kernel/compile.bat rename to SysCore/compile.bat index dcc17a1..4c16378 100644 --- a/kernel/compile.bat +++ b/SysCore/compile.bat @@ -6,18 +6,15 @@ rem NASM and DJGPP executable paths: set nasm_path=C:\nasm set djgpp_path=C:\DJGPP\bin -@echo on rem Compile loader -%nasm_path%\nasm.exe -f aout -o %loader_name%.o %loader_name%.asm +@echo on +%nasm_path%\nasm.exe -f aout -o ./objects/%loader_name%.o %loader_name%.asm +@echo off +@echo. rem Compile main Kernel -%djgpp_path%\gcc.exe -Wall -O -fstrength-reduce -fomit-frame-pointer -finline-functions -nostdinc -fno-builtin -I./include -c -o main.o main.c +@echo on +%djgpp_path%\gcc.exe -Wall -O -fstrength-reduce -fomit-frame-pointer -nostdinc -fno-builtin -I./include -c -o ./objects/main.o main.c +@echo off rem OTHER GCC/NASM SOURCES GO HERE -@echo on -%djgpp_path%\ld -T link.ld -o kernel.bin %loader_name%.o main.o -@echo . -@echo Done! - @pause -copy KERNEL.BIN C:\SHARE -copy KERNEL.BIN A:\KERNEL.CTA \ No newline at end of file diff --git a/SysCore/debug/BIOS-bochs-latest b/SysCore/debug/BIOS-bochs-latest new file mode 100644 index 0000000..5e94170 Binary files /dev/null and b/SysCore/debug/BIOS-bochs-latest differ diff --git a/SysCore/debug/OSDev.log b/SysCore/debug/OSDev.log new file mode 100644 index 0000000..ae243d1 --- /dev/null +++ b/SysCore/debug/OSDev.log @@ -0,0 +1,292 @@ +00000000000i[ ] Bochs x86 Emulator 2.4.5 +00000000000i[ ] Build from CVS snapshot, on April 25, 2010 +00000000000i[ ] System configuration +00000000000i[ ] processors: 1 (cores=1, HT threads=1) +00000000000i[ ] A20 line support: yes +00000000000i[ ] CPU configuration +00000000000i[ ] level: 6 +00000000000i[ ] SMP support: no +00000000000i[ ] APIC support: yes +00000000000i[ ] FPU support: yes +00000000000i[ ] MMX support: yes +00000000000i[ ] 3dnow! support: no +00000000000i[ ] SEP support: yes +00000000000i[ ] SSE support: sse2 +00000000000i[ ] XSAVE support: no +00000000000i[ ] AES support: no +00000000000i[ ] MOVBE support: no +00000000000i[ ] x86-64 support: yes +00000000000i[ ] 1G paging support: no +00000000000i[ ] MWAIT support: no +00000000000i[ ] VMX support: no +00000000000i[ ] Optimization configuration +00000000000i[ ] RepeatSpeedups support: yes +00000000000i[ ] Trace cache support: yes +00000000000i[ ] Fast function calls: yes +00000000000i[ ] Devices configuration +00000000000i[ ] ACPI support: yes +00000000000i[ ] NE2000 support: yes +00000000000i[ ] PCI support: yes, enabled=yes +00000000000i[ ] SB16 support: yes +00000000000i[ ] USB support: yes +00000000000i[ ] VGA extension support: vbe cirrus +00000000000i[MEM0 ] allocated memory at 027B0020. after alignment, vector=027B1000 +00000000000i[MEM0 ] 32.00MB +00000000000i[MEM0 ] mem block size = 0x00100000, blocks=32 +00000000000i[MEM0 ] rom at 0xe0000/131072 ('BIOS-bochs-latest') +00000000000i[MEM0 ] rom at 0xc0000/40448 ('VGABIOS-lgpl-latest') +00000000000i[CMOS ] Using local time for initial clock +00000000000i[CMOS ] Setting initial clock to: Sat Jul 03 09:26:48 2010 (time0=1278138408) +00000000000i[DMA ] channel 4 used by cascade +00000000000i[DMA ] channel 2 used by Floppy Drive +00000000000i[FDD ] fd0: 'ctaos.img' ro=0, h=2,t=80,spt=18 +00000000000i[PCI ] 440FX Host bridge present at device 0, function 0 +00000000000i[PCI ] PIIX3 PCI-to-ISA bridge present at device 1, function 0 +00000000000i[MEM0 ] Register memory access handlers: 0x000a0000 - 0x000bffff +00000000000i[WGUI ] Desktop Window dimensions: 1366 x 768 +00000000000i[WGUI ] Number of Mouse Buttons = 5 +00000000000i[WGUI ] IME disabled +00000000000i[MEM0 ] Register memory access handlers: 0xe0000000 - 0xe0ffffff +00000000000i[CLVGA] VBE Bochs Display Extension Enabled +00000000000i[CLVGA] interval=50000 +00000000000i[ ] init_dev of 'unmapped' plugin device by virtual method +00000000000i[ ] init_dev of 'biosdev' plugin device by virtual method +00000000000i[ ] init_dev of 'speaker' plugin device by virtual method +00000000000i[ ] init_dev of 'extfpuirq' plugin device by virtual method +00000000000i[ ] init_dev of 'gameport' plugin device by virtual method +00000000000i[ ] init_dev of 'pci_ide' plugin device by virtual method +00000000000i[PCI ] PIIX3 PCI IDE controller present at device 1, function 1 +00000000000i[ ] init_dev of 'acpi' plugin device by virtual method +00000000000i[PCI ] ACPI Controller present at device 1, function 3 +00000000000i[ ] init_dev of 'ioapic' plugin device by virtual method +00000000000i[IOAP ] initializing I/O APIC +00000000000i[MEM0 ] Register memory access handlers: 0xfec00000 - 0xfec00fff +00000000000i[ ] init_dev of 'keyboard' plugin device by virtual method +00000000000i[KBD ] will paste characters every 1000 keyboard ticks +00000000000i[ ] init_dev of 'harddrv' plugin device by virtual method +00000000000i[HD ] Using boot sequence floppy, none, none +00000000000i[HD ] Floppy boot signature check is enabled +00000000000i[ ] init_dev of 'serial' plugin device by virtual method +00000000000i[SER ] com1 at 0x03f8 irq 4 +00000000000i[ ] init_dev of 'parallel' plugin device by virtual method +00000000000i[PAR ] parallel port 1 at 0x0378 irq 7 +00000000000i[ ] register state of 'unmapped' plugin device by virtual method +00000000000i[ ] register state of 'biosdev' plugin device by virtual method +00000000000i[ ] register state of 'speaker' plugin device by virtual method +00000000000i[ ] register state of 'extfpuirq' plugin device by virtual method +00000000000i[ ] register state of 'gameport' plugin device by virtual method +00000000000i[ ] register state of 'pci_ide' plugin device by virtual method +00000000000i[ ] register state of 'acpi' plugin device by virtual method +00000000000i[ ] register state of 'ioapic' plugin device by virtual method +00000000000i[ ] register state of 'keyboard' plugin device by virtual method +00000000000i[ ] register state of 'harddrv' plugin device by virtual method +00000000000i[ ] register state of 'serial' plugin device by virtual method +00000000000i[ ] register state of 'parallel' plugin device by virtual method +00000000000i[SYS ] bx_pc_system_c::Reset(HARDWARE) called +00000000000i[CPU0 ] cpu hardware reset +00000000000i[APIC0] allocate APIC id=0 (MMIO enabled) to 0xfee00000 +00000000000i[CPU0 ] CPUID[0x00000000]: 00000003 756e6547 6c65746e 49656e69 +00000000000i[CPU0 ] CPUID[0x00000001]: 00000f20 00000800 00002000 078bfbff +00000000000i[CPU0 ] CPUID[0x00000002]: 00410601 00000000 00000000 00000000 +00000000000i[CPU0 ] CPUID[0x00000003]: 00000000 00000000 00000000 00000000 +00000000000i[CPU0 ] CPUID[0x00000004]: 00000000 00000000 00000000 00000000 +00000000000i[CPU0 ] CPUID[0x80000000]: 80000008 00000000 00000000 00000000 +00000000000i[CPU0 ] CPUID[0x80000001]: 00000000 00000000 00000101 2a100800 +00000000000i[CPU0 ] CPUID[0x80000002]: 20202020 20202020 20202020 6e492020 +00000000000i[CPU0 ] CPUID[0x80000003]: 286c6574 50202952 69746e65 52286d75 +00000000000i[CPU0 ] CPUID[0x80000004]: 20342029 20555043 20202020 00202020 +00000000000i[CPU0 ] CPUID[0x80000006]: 00000000 42004200 02008140 00000000 +00000000000i[CPU0 ] CPUID[0x80000007]: 00000000 00000000 00000000 00000000 +00000000000i[CPU0 ] CPUID[0x80000008]: 00003020 00000000 00000000 00000000 +00000000000i[ ] reset of 'unmapped' plugin device by virtual method +00000000000i[ ] reset of 'biosdev' plugin device by virtual method +00000000000i[ ] reset of 'speaker' plugin device by virtual method +00000000000i[ ] reset of 'extfpuirq' plugin device by virtual method +00000000000i[ ] reset of 'gameport' plugin device by virtual method +00000000000i[ ] reset of 'pci_ide' plugin device by virtual method +00000000000i[ ] reset of 'acpi' plugin device by virtual method +00000000000i[ ] reset of 'ioapic' plugin device by virtual method +00000000000i[ ] reset of 'keyboard' plugin device by virtual method +00000000000i[ ] reset of 'harddrv' plugin device by virtual method +00000000000i[ ] reset of 'serial' plugin device by virtual method +00000000000i[ ] reset of 'parallel' plugin device by virtual method +00000003305i[BIOS ] $Revision: 1.247 $ $Date: 2010/04/04 19:33:50 $ +00000200000i[WGUI ] dimension update x=720 y=400 fontheight=16 fontwidth=9 bpp=8 +00000318042i[KBD ] reset-disable command received +00000444800i[VBIOS] VGABios $Id: vgabios.c,v 1.69 2009/04/07 18:18:20 vruppert Exp $ +00000444871i[CLVGA] VBE known Display Interface b0c0 +00000444903i[CLVGA] VBE known Display Interface b0c5 +00000447828i[VBIOS] VBE Bios $Id: vbe.c,v 1.62 2009/01/25 15:46:25 vruppert Exp $ +00000760517i[BIOS ] Starting rombios32 +00000761014i[BIOS ] Shutdown flag 0 +00000761695i[BIOS ] ram_size=0x02000000 +00000762173i[BIOS ] ram_end=32MB +00000802745i[BIOS ] Found 1 cpu(s) +00000822014i[BIOS ] bios_table_addr: 0x000fbc18 end=0x000fcc00 +00000822117i[PCI ] 440FX PMC write to PAM register 59 (TLB Flush) +00001149814i[PCI ] 440FX PMC write to PAM register 59 (TLB Flush) +00001477742i[P2I ] PCI IRQ routing: PIRQA# set to 0x0b +00001477763i[P2I ] PCI IRQ routing: PIRQB# set to 0x09 +00001477784i[P2I ] PCI IRQ routing: PIRQC# set to 0x0b +00001477805i[P2I ] PCI IRQ routing: PIRQD# set to 0x09 +00001477815i[P2I ] write: ELCR2 = 0x0a +00001478700i[BIOS ] PIIX3/PIIX4 init: elcr=00 0a +00001486658i[BIOS ] PCI: bus=0 devfn=0x00: vendor_id=0x8086 device_id=0x1237 class=0x0600 +00001489220i[BIOS ] PCI: bus=0 devfn=0x08: vendor_id=0x8086 device_id=0x7000 class=0x0601 +00001491621i[BIOS ] PCI: bus=0 devfn=0x09: vendor_id=0x8086 device_id=0x7010 class=0x0101 +00001491851i[PIDE ] new BM-DMA address: 0xc000 +00001492555i[BIOS ] region 4: 0x0000c000 +00001494865i[BIOS ] PCI: bus=0 devfn=0x0b: vendor_id=0x8086 device_id=0x7113 class=0x0680 +00001495103i[ACPI ] new irq line = 11 +00001495117i[ACPI ] new irq line = 9 +00001495147i[ACPI ] new PM base address: 0xb000 +00001495161i[ACPI ] new SM base address: 0xb100 +00001495189i[PCI ] setting SMRAM control register to 0x4a +00001659283i[CPU0 ] Enter to System Management Mode +00001659293i[CPU0 ] RSM: Resuming from System Management Mode +00001823313i[PCI ] setting SMRAM control register to 0x0a +00001832484i[BIOS ] MP table addr=0x000fbcf0 MPC table addr=0x000fbc20 size=0xd0 +00001834543i[BIOS ] SMBIOS table addr=0x000fbd00 +00001836931i[BIOS ] ACPI tables: RSDP addr=0x000fbe20 ACPI DATA addr=0x01ff0000 size=0x988 +00001840169i[BIOS ] Firmware waking vector 0x1ff00cc +00001851282i[PCI ] 440FX PMC write to PAM register 59 (TLB Flush) +00001852126i[BIOS ] bios_table_cur_addr: 0x000fbe44 +00014041543i[BIOS ] Booting from 0000:7c00 +00019105039i[KBD ] setting typematic info +00019105052i[KBD ] setting delay to 500 mS (unused) +00019105052i[KBD ] setting repeat rate to 10.9 cps (unused) +00019105085i[KBD ] Switched to scancode set 2 +00019105160i[KBD ] keyboard: scan convert turned off +00019184168e[CPU0 ] interrupt(): gate.type(1) != {5,6,7,14,15} +00019184168e[CPU0 ] interrupt(): gate descriptor is not valid sys seg (vector=0x0d) +00019184168e[CPU0 ] interrupt(): gate.type(1) != {5,6,7,14,15} +00019184168i[CPU0 ] CPU is in protected mode (active) +00019184168i[CPU0 ] CS.d_b = 32 bit +00019184168i[CPU0 ] SS.d_b = 32 bit +00019184168i[CPU0 ] EFER = 0x00000000 +00019184168i[CPU0 ] | RAX=00000000000011a5 RBX=0000000000001116 +00019184168i[CPU0 ] | RCX=000000000010a977 RDX=0000000000000eea +00019184168i[CPU0 ] | RSP=000000000008ffc8 RBP=0000000000003000 +00019184168i[CPU0 ] | RSI=00000000000000ff RDI=0000000000105001 +00019184168i[CPU0 ] | R8=0000000000000000 R9=0000000000000000 +00019184168i[CPU0 ] | R10=0000000000000000 R11=0000000000000000 +00019184168i[CPU0 ] | R12=0000000000000000 R13=0000000000000000 +00019184168i[CPU0 ] | R14=0000000000000000 R15=0000000000000000 +00019184168i[CPU0 ] | IOPL=0 id vip vif ac vm RF nt of df IF tf sf zf AF PF cf +00019184168i[CPU0 ] | SEG selector base limit G D +00019184168i[CPU0 ] | SEG sltr(index|ti|rpl) base limit G D +00019184168i[CPU0 ] | CS:0008( 0001| 0| 0) 00000000 ffffffff 1 1 +00019184168i[CPU0 ] | DS:0010( 0002| 0| 0) 00000000 ffffffff 1 1 +00019184168i[CPU0 ] | SS:0010( 0002| 0| 0) 00000000 ffffffff 1 1 +00019184168i[CPU0 ] | ES:0010( 0002| 0| 0) 00000000 ffffffff 1 1 +00019184168i[CPU0 ] | FS:0010( 0002| 0| 0) 00000000 ffffffff 1 1 +00019184168i[CPU0 ] | GS:0010( 0002| 0| 0) 00000000 ffffffff 1 1 +00019184168i[CPU0 ] | MSR_FS_BASE:0000000000000000 +00019184168i[CPU0 ] | MSR_GS_BASE:0000000000000000 +00019184168i[CPU0 ] | RIP=00000000001030d7 (00000000001030d7) +00019184168i[CPU0 ] | CR0=0x60000011 CR2=0x0000000000000000 +00019184168i[CPU0 ] | CR3=0x00000000 CR4=0x00000000 +00019184168i[CPU0 ] 0x00000000001030d7>> jnz .-25 (0x001030c0) : 75E7 +00019184168e[CPU0 ] exception(): 3rd (13) exception with no resolution, shutdown status is 00h, resetting +00019184168i[SYS ] bx_pc_system_c::Reset(HARDWARE) called +00019184168i[CPU0 ] cpu hardware reset +00019184168i[APIC0] allocate APIC id=0 (MMIO enabled) to 0xfee00000 +00019184168i[CPU0 ] CPUID[0x00000000]: 00000003 756e6547 6c65746e 49656e69 +00019184168i[CPU0 ] CPUID[0x00000001]: 00000f20 00000800 00002000 078bfbff +00019184168i[CPU0 ] CPUID[0x00000002]: 00410601 00000000 00000000 00000000 +00019184168i[CPU0 ] CPUID[0x00000003]: 00000000 00000000 00000000 00000000 +00019184168i[CPU0 ] CPUID[0x00000004]: 00000000 00000000 00000000 00000000 +00019184168i[CPU0 ] CPUID[0x80000000]: 80000008 00000000 00000000 00000000 +00019184168i[CPU0 ] CPUID[0x80000001]: 00000000 00000000 00000101 2a100800 +00019184168i[CPU0 ] CPUID[0x80000002]: 20202020 20202020 20202020 6e492020 +00019184168i[CPU0 ] CPUID[0x80000003]: 286c6574 50202952 69746e65 52286d75 +00019184168i[CPU0 ] CPUID[0x80000004]: 20342029 20555043 20202020 00202020 +00019184168i[CPU0 ] CPUID[0x80000006]: 00000000 42004200 02008140 00000000 +00019184168i[CPU0 ] CPUID[0x80000007]: 00000000 00000000 00000000 00000000 +00019184168i[CPU0 ] CPUID[0x80000008]: 00003020 00000000 00000000 00000000 +00019184168i[ ] reset of 'unmapped' plugin device by virtual method +00019184168i[ ] reset of 'biosdev' plugin device by virtual method +00019184168i[ ] reset of 'speaker' plugin device by virtual method +00019184168i[ ] reset of 'extfpuirq' plugin device by virtual method +00019184168i[ ] reset of 'gameport' plugin device by virtual method +00019184168i[ ] reset of 'pci_ide' plugin device by virtual method +00019184168i[ ] reset of 'acpi' plugin device by virtual method +00019184168i[ ] reset of 'ioapic' plugin device by virtual method +00019184168i[ ] reset of 'keyboard' plugin device by virtual method +00019184168i[ ] reset of 'harddrv' plugin device by virtual method +00019184168i[ ] reset of 'serial' plugin device by virtual method +00019184168i[ ] reset of 'parallel' plugin device by virtual method +00019187474i[BIOS ] $Revision: 1.247 $ $Date: 2010/04/04 19:33:50 $ +00019502059i[KBD ] reset-disable command received +00019628817i[VBIOS] VGABios $Id: vgabios.c,v 1.69 2009/04/07 18:18:20 vruppert Exp $ +00019628888i[CLVGA] VBE known Display Interface b0c0 +00019628920i[CLVGA] VBE known Display Interface b0c5 +00019631845i[VBIOS] VBE Bios $Id: vbe.c,v 1.62 2009/01/25 15:46:25 vruppert Exp $ +00019944534i[BIOS ] Starting rombios32 +00019945031i[BIOS ] Shutdown flag 0 +00019945712i[BIOS ] ram_size=0x02000000 +00019946190i[BIOS ] ram_end=32MB +00019986786i[BIOS ] Found 1 cpu(s) +00020006055i[BIOS ] bios_table_addr: 0x000fbc18 end=0x000fcc00 +00020006158i[PCI ] 440FX PMC write to PAM register 59 (TLB Flush) +00020333855i[PCI ] 440FX PMC write to PAM register 59 (TLB Flush) +00020661783i[P2I ] PCI IRQ routing: PIRQA# set to 0x0b +00020661804i[P2I ] PCI IRQ routing: PIRQB# set to 0x09 +00020661825i[P2I ] PCI IRQ routing: PIRQC# set to 0x0b +00020661846i[P2I ] PCI IRQ routing: PIRQD# set to 0x09 +00020661856i[P2I ] write: ELCR2 = 0x0a +00020662741i[BIOS ] PIIX3/PIIX4 init: elcr=00 0a +00020670699i[BIOS ] PCI: bus=0 devfn=0x00: vendor_id=0x8086 device_id=0x1237 class=0x0600 +00020673261i[BIOS ] PCI: bus=0 devfn=0x08: vendor_id=0x8086 device_id=0x7000 class=0x0601 +00020675662i[BIOS ] PCI: bus=0 devfn=0x09: vendor_id=0x8086 device_id=0x7010 class=0x0101 +00020676596i[BIOS ] region 4: 0x0000c000 +00020678906i[BIOS ] PCI: bus=0 devfn=0x0b: vendor_id=0x8086 device_id=0x7113 class=0x0680 +00020679144i[ACPI ] new irq line = 11 +00020679158i[ACPI ] new irq line = 9 +00020679230i[PCI ] setting SMRAM control register to 0x4a +00020843324i[CPU0 ] Enter to System Management Mode +00020843334i[CPU0 ] RSM: Resuming from System Management Mode +00021007354i[PCI ] setting SMRAM control register to 0x0a +00021016525i[BIOS ] MP table addr=0x000fbcf0 MPC table addr=0x000fbc20 size=0xd0 +00021018584i[BIOS ] SMBIOS table addr=0x000fbd00 +00021020972i[BIOS ] ACPI tables: RSDP addr=0x000fbe20 ACPI DATA addr=0x01ff0000 size=0x988 +00021024210i[BIOS ] Firmware waking vector 0x1ff00cc +00021035323i[PCI ] 440FX PMC write to PAM register 59 (TLB Flush) +00021036167i[BIOS ] bios_table_cur_addr: 0x000fbe44 +00033225716i[BIOS ] Booting from 0000:7c00 +00038289036i[KBD ] setting typematic info +00038289049i[KBD ] setting delay to 500 mS (unused) +00038289049i[KBD ] setting repeat rate to 10.9 cps (unused) +00038289082i[KBD ] Switched to scancode set 2 +00038289157i[KBD ] keyboard: scan convert turned off +00220440000p[WGUI ] >>PANIC<< POWER button turned off. +00220440000i[CPU0 ] CPU is in protected mode (active) +00220440000i[CPU0 ] CS.d_b = 32 bit +00220440000i[CPU0 ] SS.d_b = 32 bit +00220440000i[CPU0 ] EFER = 0x00000000 +00220440000i[CPU0 ] | RAX=0000000000000700 RBX=000000000008ffa0 +00220440000i[CPU0 ] | RCX=00000000000b8000 RDX=00000000000bf01c +00220440000i[CPU0 ] | RSP=000000000008ff20 RBP=0000000000003000 +00220440000i[CPU0 ] | RSI=0000000000008000 RDI=0000000000000028 +00220440000i[CPU0 ] | R8=0000000000000000 R9=0000000000000000 +00220440000i[CPU0 ] | R10=0000000000000000 R11=0000000000000000 +00220440000i[CPU0 ] | R12=0000000000000000 R13=0000000000000000 +00220440000i[CPU0 ] | R14=0000000000000000 R15=0000000000000000 +00220440000i[CPU0 ] | IOPL=0 id vip vif ac vm rf nt of df if tf sf zf af pf cf +00220440000i[CPU0 ] | SEG selector base limit G D +00220440000i[CPU0 ] | SEG sltr(index|ti|rpl) base limit G D +00220440000i[CPU0 ] | CS:0008( 0001| 0| 0) 00000000 ffffffff 1 1 +00220440000i[CPU0 ] | DS:0010( 0002| 0| 0) 00000000 ffffffff 1 1 +00220440000i[CPU0 ] | SS:0010( 0002| 0| 0) 00000000 ffffffff 1 1 +00220440000i[CPU0 ] | ES:0010( 0002| 0| 0) 00000000 ffffffff 1 1 +00220440000i[CPU0 ] | FS:0010( 0002| 0| 0) 00000000 ffffffff 1 1 +00220440000i[CPU0 ] | GS:0010( 0002| 0| 0) 00000000 ffffffff 1 1 +00220440000i[CPU0 ] | MSR_FS_BASE:0000000000000000 +00220440000i[CPU0 ] | MSR_GS_BASE:0000000000000000 +00220440000i[CPU0 ] | RIP=0000000000102a49 (0000000000102a49) +00220440000i[CPU0 ] | CR0=0x60000011 CR2=0x0000000000000000 +00220440000i[CPU0 ] | CR3=0x00000000 CR4=0x00000000 +00220440000i[CPU0 ] 0x0000000000102a49>> jmp .-2 (0x00102a49) : EBFE +00220440000i[CMOS ] Last time is 1278138462 (Sat Jul 03 09:27:42 2010) +00220440000i[ ] restoring default signal behavior +00220440000i[CTRL ] quit_sim called with exit code 1 diff --git a/SysCore/debug/VGABIOS-lgpl-latest b/SysCore/debug/VGABIOS-lgpl-latest new file mode 100644 index 0000000..a6c56a5 Binary files /dev/null and b/SysCore/debug/VGABIOS-lgpl-latest differ diff --git a/SysCore/debug/bochs_config.bxrc b/SysCore/debug/bochs_config.bxrc new file mode 100644 index 0000000..abd891d --- /dev/null +++ b/SysCore/debug/bochs_config.bxrc @@ -0,0 +1,14 @@ +# ROM and VGA BIOS images --------------------------------------------- + +romimage: file=BIOS-bochs-latest, address=0xe0000 +vgaromimage: file=VGABIOS-lgpl-latest + +# boot from floppy using our disk image ------------------------------- + +floppya: 1_44=ctaos.img, status=inserted + +# logging and reporting ----------------------------------------------- + +log: OSDev.log # All errors and info logs will output to OSDev.log +error: action=report +info: action=report \ No newline at end of file diff --git a/SysCore/debug/ctaos.img b/SysCore/debug/ctaos.img new file mode 100644 index 0000000..d83008f Binary files /dev/null and b/SysCore/debug/ctaos.img differ diff --git a/SysCore/hal/cmos/cmos.c b/SysCore/hal/cmos/cmos.c new file mode 100644 index 0000000..4a05ac8 --- /dev/null +++ b/SysCore/hal/cmos/cmos.c @@ -0,0 +1,92 @@ +#include +#include +#include "cmos.h" + +volatile byte i86_cmos_data[128]; + +void i86_cmos_write () +{ + byte i; + for (i = 0; i < 128; i++) { + //asm volatile ("cli"); + outportb(0x70, i); + iowait(); + outportb(0x71, i86_cmos_data[i]); + //asm volatile ("sti"); + } +} + +void i86_cmos_read () +{ + byte i; + for (i = 0; i < 128; i++) { + //asm volatile ("cli"); + outportb(0x70, i); + iowait(); + i86_cmos_data[i] = inportb(0x71); + //asm volatile ("sti"); + } +} + +void i86_cmos_read_clock(TIME* tim) +{ + i86_cmos_read(); + + if ((i86_cmos_data[0x0b]&4)==0) // BCD = true; + { + tim->seconds = (i86_cmos_data[0x00]%16) + 10*(i86_cmos_data[0x00]/16); + tim->minutes = (i86_cmos_data[0x02]%16) + 10*(i86_cmos_data[0x02]/16); + if ((i86_cmos_data[0x0b]&2)==0) { // AM/PM + if (i86_cmos_data[0x04]&80) { // pm + tim->hours = ((i86_cmos_data[0x04]-0x80)%16) + 10*((i86_cmos_data[0x04]-0x80)/16); + tim->am_pm = 1; + } + else { // am + tim->hours = (i86_cmos_data[0x04]%16) + 10*(i86_cmos_data[0x04]/16); + tim->am_pm = 0; + } + } + else { // 24 hours + tim->hours = (i86_cmos_data[0x04]%16) + 10*(i86_cmos_data[0x04]/16); + if (tim->hours > 12) { + tim->am_pm = 1; + tim->hours -= 12; + } + else tim->am_pm = 0; + } + + tim->weekday = (i86_cmos_data[0x06]%16) + 10*(i86_cmos_data[0x06]/16); + tim->day = (i86_cmos_data[0x07]%16) + 10*(i86_cmos_data[0x07]/16); + tim->month = (i86_cmos_data[0x08]%16) + 10*(i86_cmos_data[0x08]/16); + tim->year = (i86_cmos_data[0x09]%16) + 10*(i86_cmos_data[0x09]/16); + tim->century = (i86_cmos_data[0x32]%16) + 10*(i86_cmos_data[0x32]/16); + } + + else {//BCD = false; + tim->seconds = i86_cmos_data[0x00]; + tim->minutes = i86_cmos_data[0x02]; + if ((i86_cmos_data[0x0b]&2)==0) { // AM/PM + if (i86_cmos_data[0x04]&80) { // pm + tim->hours = i86_cmos_data[0x04]-0x80; + tim->am_pm = 1; + } + else { // am + tim->hours = i86_cmos_data[0x04]; + tim->am_pm = 0; + } + } + else { // 24 hours + tim->hours = i86_cmos_data[0x02]; + if (tim->hours > 12) { + tim->am_pm = 1; + tim->hours -= 12; + } + else tim->am_pm = 0; + } + tim->weekday = i86_cmos_data[0x06]; + tim->day = i86_cmos_data[0x07]; + tim->month = i86_cmos_data[0x08]; + tim->year = i86_cmos_data[0x09]; + tim->century = i86_cmos_data[0x32]; + } +} diff --git a/SysCore/hal/cmos/cmos.h b/SysCore/hal/cmos/cmos.h new file mode 100644 index 0000000..afc2a1b --- /dev/null +++ b/SysCore/hal/cmos/cmos.h @@ -0,0 +1,10 @@ +#ifndef __CMOS_H +#define __CMOS_H + +extern volatile byte i86_cmos_data[128]; + +extern void i86_cmos_write (); +extern void i86_cmos_read (); +extern void i86_cmos_read_clock (TIME *tim); + +#endif \ No newline at end of file diff --git a/SysCore/hal/cmos/compile.bat b/SysCore/hal/cmos/compile.bat new file mode 100644 index 0000000..661bb3d --- /dev/null +++ b/SysCore/hal/cmos/compile.bat @@ -0,0 +1,18 @@ +@echo off +rem The name of the loader assembly file (without extension, must be .asm): +set loader_name=loader + +rem NASM and DJGPP executable paths: +set nasm_path=C:\nasm +set djgpp_path=C:\DJGPP\bin +set objpath=../../objects +set incpath=../../include + +@echo on +%djgpp_path%\gcc.exe -Wall -O -fstrength-reduce -fomit-frame-pointer -nostdinc -fno-builtin -I%incpath% -c -o %objpath%/cmos.o cmos.c + +@echo off +@echo . +@echo Done! + +@pause diff --git a/SysCore/hal/compile.bat b/SysCore/hal/compile.bat new file mode 100644 index 0000000..657741e --- /dev/null +++ b/SysCore/hal/compile.bat @@ -0,0 +1,43 @@ +@echo off + +set loader_name=loader +set nasm_path=C:\nasm +set djgpp_path=C:\DJGPP\bin + + +@echo ***************** CTA KERNEL ***************** + +:KernelEntry + @echo. + @echo Building Kernel entry... + @echo * Compiling kernel loader... + %nasm_path%\nasm.exe -f aout -o ./objects/%loader_name%.o %loader_name%.asm + + @echo * Compiling kernel main... + %djgpp_path%\gcc.exe -Wall -O -fstrength-reduce -fomit-frame-pointer -nostdinc -fno-builtin -I./include -c -o ./objects/main.o main.c + + +:KernelSTDLIB + cd lib + call compile.bat + cd.. + +:KernelMemoryManager + cd memory + call compile.bat + cd.. + + +rem here go other sources: + +rem here go other sources ^ + +:Finish + cd objects + @echo Linking... + %djgpp_path%\ld -T link.ld + @echo. + + echo Copying to floppy drive... + copy KERNEL.BIN A:\KERNEL.CTA + cd.. \ No newline at end of file diff --git a/SysCore/hal/cpu/compile.bat b/SysCore/hal/cpu/compile.bat new file mode 100644 index 0000000..ee6f8eb --- /dev/null +++ b/SysCore/hal/cpu/compile.bat @@ -0,0 +1,18 @@ +@echo off +rem The name of the loader assembly file (without extension, must be .asm): +set loader_name=loader + +rem NASM and DJGPP executable paths: +set nasm_path=C:\nasm +set djgpp_path=C:\DJGPP\bin +set objpath=../../objects +set incpath=../../include + +@echo on +%djgpp_path%\gcc.exe -Wall -O -fstrength-reduce -fomit-frame-pointer -nostdinc -fno-builtin -I%incpath% -c -o %objpath%/cpu.o cpu.c + +@echo off +@echo . +@echo Done! + +@pause diff --git a/SysCore/hal/cpu/cpu.c b/SysCore/hal/cpu/cpu.c new file mode 100644 index 0000000..aa12acf --- /dev/null +++ b/SysCore/hal/cpu/cpu.c @@ -0,0 +1,35 @@ +#include +#include "cpu.h" +#include "../gdt/gdt.h" +#include "../idt/idt.h" +#define cpuid(in, a, b, c, d) __asm__("cpuid": "=a" (a), "=b" (b), "=c" (c), "=d" (d) : "a" (in)); + + + +// initializes cpu resources +void i86_cpu_initialize() +{ + // initialize processor tables + i86_gdt_install(); + i86_idt_install(); +} + +void i86_cpu_shutdown() +{ + +} + +char* i86_cpu_get_vender() +{ + static char vender[13]; + dword unused, arr[3]; + int i; + + cpuid(0, unused, arr[0], arr[2], arr[1]); + + for (i=0; i<12; i++) + vender[i] = (arr[i/4]>>(i%4*8)) && 0xFF; + + vender[12] = 0; + return vender; +} \ No newline at end of file diff --git a/SysCore/hal/cpu/cpu.h b/SysCore/hal/cpu/cpu.h new file mode 100644 index 0000000..8caf72c --- /dev/null +++ b/SysCore/hal/cpu/cpu.h @@ -0,0 +1,29 @@ +#ifndef _CPU_H_INCLUDED +#define _CPU_H_INCLUDED +//**************************************************************************** +//** +//** cpu.h +//** +//** This is the processor interface. Everything outside of this module +//** must use this interface when working on processor data. +//** +//** A processor is a module that manages the very basic data structures +//** and data within the system. The processor interface provides the interface +//** for managing processors, processor cores, accessing processor structures, +//** and more +//** +//**************************************************************************** + +#include +#include + +//! initialize the processors +extern void i86_cpu_initialize (); + +//! shutdown the processors +extern void i86_cpu_shutdown (); + +//! get cpu vender +extern char* i86_cpu_get_vender (); + +#endif diff --git a/SysCore/hal/gdt/compile.bat b/SysCore/hal/gdt/compile.bat new file mode 100644 index 0000000..fe3a0e1 --- /dev/null +++ b/SysCore/hal/gdt/compile.bat @@ -0,0 +1,19 @@ +@echo off +rem The name of the loader assembly file (without extension, must be .asm): +set loader_name=loader + +rem NASM and DJGPP executable paths: +set nasm_path=C:\nasm +set djgpp_path=C:\DJGPP\bin +set objpath=../../objects +set incpath=../../include + +@echo on +%nasm_path%\nasm.exe -f aout -o %objpath%/gdt_asm.o gdt.asm +%djgpp_path%\gcc.exe -Wall -O -fstrength-reduce -fomit-frame-pointer -nostdinc -fno-builtin -I%incpath% -c -o %objpath%/gdt.o gdt.c + +@echo off +@echo . +@echo Done! + +@pause diff --git a/SysCore/hal/gdt/gdt.asm b/SysCore/hal/gdt/gdt.asm new file mode 100644 index 0000000..5b75ce9 --- /dev/null +++ b/SysCore/hal/gdt/gdt.asm @@ -0,0 +1,20 @@ +bits 32 +; !!! GDT !!! +; This will set up our new segment registers. We need to do +; something special in order to set CS. We do what is called a +; far jump. A jump that includes a segment as well as an offset. +; This is declared in C as 'extern void gdt_flush();' + +global _i86_gdt_flush ; Allows the C code to link to this +extern _gp ; Says that '_gp' is in another file +_i86_gdt_flush: + lgdt [_gp] ; Load the GDT with our '_gp' which is a special pointer + mov ax, 0x10 ; 0x10 is the offset in the GDT to our data segment + mov ds, ax + mov es, ax + mov fs, ax + mov gs, ax + mov ss, ax + jmp 0x08:flush2 ; 0x08 is the offset to our code segment: Far jump! +flush2: + ret ; Returns back to the C code! diff --git a/kernel/kernel/gdt.c b/SysCore/hal/gdt/gdt.c similarity index 59% rename from kernel/kernel/gdt.c rename to SysCore/hal/gdt/gdt.c index 12638ec..b773104 100644 --- a/kernel/kernel/gdt.c +++ b/SysCore/hal/gdt/gdt.c @@ -1,36 +1,17 @@ -#include - -/* Defines a GDT entry. We say packed, because it prevents the -* compiler from doing things that it thinks is best: Prevent -* compiler "optimization" by packing */ -struct gdt_entry -{ - unsigned short limit_low; - unsigned short base_low; - unsigned char base_middle; - unsigned char access; - unsigned char granularity; - unsigned char base_high; -} __attribute__((packed)); - -/* Special pointer which includes the limit: The max bytes -* taken up by the GDT, minus 1. Again, this NEEDS to be packed */ -struct gdt_ptr -{ - unsigned short limit; - unsigned int base; -} __attribute__((packed)); +/****************************************************************** + * gdt.c - GLOBAL DESCRIPTOR TABLE * + * Contains function prototypes for setting up the GDT * + ******************************************************************/ +#define MAX_DESCRIPTORS 3 +#include "gdt.h" /* Our GDT, with 3 entries, and finally our special GDT pointer */ struct gdt_entry gdt[3]; struct gdt_ptr gp; -/* This will be a function in start.asm. We use this to properly -* reload the new segment registers */ -extern void gdt_flush(); /* Setup a descriptor in the Global Descriptor Table */ -void gdt_set_gate(int num, unsigned long base, unsigned long limit, unsigned char access, unsigned char gran) +void i86_gdt_set_gate(int num, unsigned long base, unsigned long limit, unsigned char access, unsigned char gran) { /* Setup the descriptor base address */ gdt[num].base_low = (base & 0xFFFF); @@ -46,33 +27,39 @@ void gdt_set_gate(int num, unsigned long base, unsigned long limit, unsigned cha gdt[num].access = access; } +struct gdt_entry* i86_gdt_get_gate(int num) +{ + if (num>MAX_DESCRIPTORS) return 0; + return &gdt[num]; +} + /* Should be called by main. This will setup the special GDT * pointer, set up the first 3 entries in our GDT, and then * finally call gdt_flush() in our assembler file in order * to tell the processor where the new GDT is and update the * new segment registers */ -void gdt_install() +void i86_gdt_install() { /* Setup the GDT pointer and limit */ gp.limit = (sizeof(struct gdt_entry) * 3) - 1; - gp.base = &gdt; + gp.base = (unsigned int)&gdt; /* Our NULL descriptor */ - gdt_set_gate(0, 0, 0, 0, 0); + i86_gdt_set_gate(0, 0, 0, 0, 0); /* The second entry is our Code Segment. The base address * is 0, the limit is 4GBytes, it uses 4KByte granularity, * uses 32-bit opcodes, and is a Code Segment descriptor. * Please check the table above in the tutorial in order * to see exactly what each value means */ - gdt_set_gate(1, 0, 0xFFFFFFFF, 0x9A, 0xCF); + i86_gdt_set_gate(1, 0, 0xFFFFFFFF, 0x9A, 0xCF); /* The third entry is our Data Segment. It's EXACTLY the * same as our code segment, but the descriptor type in * this entry's access byte says it's a Data Segment */ - gdt_set_gate(2, 0, 0xFFFFFFFF, 0x92, 0xCF); + i86_gdt_set_gate(2, 0, 0xFFFFFFFF, 0x92, 0xCF); /* Flush out the old GDT and install the new changes! */ - gdt_flush(); + i86_gdt_flush(); } \ No newline at end of file diff --git a/SysCore/hal/gdt/gdt.h b/SysCore/hal/gdt/gdt.h new file mode 100644 index 0000000..d593f99 --- /dev/null +++ b/SysCore/hal/gdt/gdt.h @@ -0,0 +1,39 @@ +/****************************************************************** + * gdt.h - GLOBAL DESCRIPTOR TABLE * + * Contains structures and function declarations for GDT * + ******************************************************************/ + +#ifndef __GDT_H +#define __GDT_H + +/* Defines a GDT entry. We say packed, because it prevents the +* compiler from doing things that it thinks is best: Prevent +* compiler "optimization" by packing */ +struct gdt_entry +{ + unsigned short limit_low; + unsigned short base_low; + unsigned char base_middle; + unsigned char access; + unsigned char granularity; + unsigned char base_high; +} __attribute__((packed)); + +/* Special pointer which includes the limit: The max bytes +* taken up by the GDT, minus 1. Again, this NEEDS to be packed */ +struct gdt_ptr +{ + unsigned short limit; + unsigned int base; +} __attribute__((packed)); + + +/* This will be a function in start.asm. We use this to properly +* reload the new segment registers */ +extern void i86_gdt_flush(); +extern void i86_gdt_set_gate(int num, unsigned long base, unsigned long limit, unsigned char access, unsigned char gran); +extern struct gdt_entry* i86_gdt_get_gate(int num); + +extern void i86_gdt_install(); + +#endif \ No newline at end of file diff --git a/SysCore/hal/hal.c b/SysCore/hal/hal.c new file mode 100644 index 0000000..ffcccfa --- /dev/null +++ b/SysCore/hal/hal.c @@ -0,0 +1,184 @@ +#include +#include +#include +#include "cpu/cpu.h" +#include "gdt/gdt.h" +#include "idt/idt.h" +#include "pic/pic.h" +#include "pit/pit.h" +#include "cmos/cmos.h" +#include "irq/irq.h" +#include "isrs/isrs.h" +#include "keyboard/keyus.h" + +// initialize hardware devices +void i86_hal_initialize () { + + // initialize motherboard controllers and system timer + i86_cpu_initialize (); // (install GDT, IDT) + i86_isrs_install(); // (install ISR handler) + i86_irq_install(); // (install IRQ handler) + + // install PIT and system clock; pit at 100 Hz + i86_kb_install_partone(); + i86_cmos_read_clock((TIME*)&_internal_clock); + i86_pit_install (100); + i86_kb_install_parttwo(); + + // enable interrupts + i86_start_interrupts(); + +} + +// shutdown hardware devices +int i86_hal_shutdown () { + + i86_cpu_shutdown (); + return 0; +} + +void reboot() +{ + unsigned char good = 0x02; + while ((good & 0x02) != 0) + good = inportb(0x64); + outportb(0x64, 0xFE); + __asm__ __volatile__ ("hlt"); +} + +//! notifies hal interrupt is done +/*inline void interruptdone (unsigned int intno) { + + //! insure its a valid hardware irq + if (intno > 16) + return; + + //! test if we need to send end-of-interrupt to second pic + if (intno >= 8) + i86_pic_send_command (0x20, 0xA1); + + //! always send end-of-interrupt to primary pic + i86_pic_send_command (0x20, 0x21); +} +*/ + +//! output sound to speaker +void sound (unsigned frequency) { + + //! sets frequency for speaker. frequency of 0 disables speaker + outportb (0x61, 3 | (byte)(frequency<<2) ); +} + + + + +//! sets new interrupt vector +/*void _cdecl setvect (int intno, void (_cdecl far &vect) ( ) ) { + + //! install interrupt handler! This overwrites prev interrupt descriptor + i86_install_ir (intno, I86_IDT_DESC_PRESENT | I86_IDT_DESC_BIT32, + 0x8, vect); +} + + +//! returns current interrupt vector +void (_cdecl far * _cdecl getvect (int intno)) ( ) { + + //! get the descriptor from the idt + idt_descriptor* desc = i86_get_ir (intno); + if (!desc) + return 0; + + //! get address of interrupt handler + uint32_t addr = desc->baseLo | (desc->baseHi << 16); + + //! return interrupt handler + I86_IRQ_HANDLER irq = (I86_IRQ_HANDLER)addr; + return irq; +} + +*/ +//! returns cpu vender +const char* get_cpu_vender () { + + return i86_cpu_get_vender(); +} + + +/*************************************************************************************** + * Keyboard Routines * + ***************************************************************************************/ +char getch() +{ + kb_key alpha = getkey(); + return alpha.character; +} + +char scancode_to_ascii(byte scancode, byte status) +{ + if ((status&1) || (status&2)) return kbdus_map_shift[scancode]; + else return kbdus_map[scancode]; +} + +byte get_key_status (byte scancode) +{ + if (scancode&0xF0) return kb_lights_status&0x0F; + else if (scancode&0x80) return kb_modifier_status&0x7F; + + return i86_kb_get_key(scancode); +} + +/*************************************** + * Set repeat rate/delay * + *************************************** + Values for inter-character delay (bits 4-0) + (characters per second; default is 10.9) + | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 + ----+----+----+----+----+----+----+----+---- + 0 |30.0|26.7|24.0|21.8|20.0|18.5|17.1|16.0 + 8 |15.0|13.3|12.0|10.9|10.0|9.2 |8.6 |8.0 + 16 |7.5 |6.7 |6.0 |5.5 |5.0 |4.6 |4.3 |4.0 + 24 |3.7 |3.3 |3.0 |2.7 |2.5 |2.3 |2.1 |2.0 + + Values for delay: + (miliseconds; default is 500) + 0 | 1 | 2 | 3 + -----+-----+-----+----- + 250 | 500 | 750 | 1000 + + ***************************************/ +void kb_set_repeat(float rate, int delay){ + float rates[] = {30.0, 26.7, 24.0, 21.8, 20.0, 18.5, 17.1, 16.0, 15.0, 13.3, 12.0, + 10.9, 10.0, 9.2, 8.6, 8.0, 7.5, 6.7, 6.0, 5.5, 5.0, 4.6, 4.3, 4.0, + 3.7, 3.3, 3.0, 2.7, 2.5, 2.3, 2.1, 2.0} ; + + + byte r,d; + + for (r = 0; rate != rates[r] && r < 32; r++) + if (rate==32) return; + + switch(delay) { + case 250: d = 0; break; + case 500: d = 1; break; + case 750: d = 2; break; + case 1000: d = 3; break; + default: return; + } + + i86_kb_set_repeat(r,d); +} + + +/*************************************** + * Set keyboard LEDs * + *************************************** + +-----------+-------+-------+--------+ + | Bits 7-3 | Bit 2 | Bit 1 | Bit 0 | + | 0 | Caps | Num | Scroll | + |(reserved) | lock | lock | lock | + +-----------+-------+-------+--------+ + ***************************************/ +void kb_set_LEDs(byte status) { + i86_kb_set_LEDs(status); +} diff --git a/SysCore/hal/idt/compile.bat b/SysCore/hal/idt/compile.bat new file mode 100644 index 0000000..7127f06 --- /dev/null +++ b/SysCore/hal/idt/compile.bat @@ -0,0 +1,19 @@ +@echo off +rem The name of the loader assembly file (without extension, must be .asm): +set loader_name=loader + +rem NASM and DJGPP executable paths: +set nasm_path=C:\nasm +set djgpp_path=C:\DJGPP\bin +set objpath=../../objects +set incpath=../../include + +@echo on +%nasm_path%\nasm.exe -f aout -o %objpath%/idt_asm.o idt.asm +%djgpp_path%\gcc.exe -Wall -O -fstrength-reduce -fomit-frame-pointer -nostdinc -fno-builtin -I%incpath% -c -o %objpath%/idt.o idt.c + +@echo off +@echo . +@echo Done! + +@pause diff --git a/SysCore/hal/idt/idt.asm b/SysCore/hal/idt/idt.asm new file mode 100644 index 0000000..cf7a29a --- /dev/null +++ b/SysCore/hal/idt/idt.asm @@ -0,0 +1,9 @@ +bits 32 + +; !!! IDT !!! +; Loads the IDT defined in '_idtp' +global _i86_idt_load +extern _idtp +_i86_idt_load: + lidt [_idtp] + ret diff --git a/kernel/kernel/idt.c b/SysCore/hal/idt/idt.c similarity index 63% rename from kernel/kernel/idt.c rename to SysCore/hal/idt/idt.c index e719dec..8126fc0 100644 --- a/kernel/kernel/idt.c +++ b/SysCore/hal/idt/idt.c @@ -1,20 +1,9 @@ +/****************************************************************** + * idt.h - INTERRUPT DESCRIPTOR TABLE * + * Contains structures and function declarations for IDT * + ******************************************************************/ #include - -/* Defines an IDT entry */ -struct idt_entry -{ - unsigned short base_lo; - unsigned short sel; - unsigned char always0; - unsigned char flags; - unsigned short base_hi; -} __attribute__((packed)); - -struct idt_ptr -{ - unsigned short limit; - unsigned int base; -} __attribute__((packed)); +#include "idt.h" /* Declare an IDT of 256 entries. Although we will only use the * first 32 entries in this tutorial, the rest exists as a bit @@ -25,12 +14,9 @@ struct idt_ptr struct idt_entry idt[256]; struct idt_ptr idtp; -/* This exists in 'start.asm', and is used to load our IDT */ -extern void idt_load(); - /* Use this function to set an entry in the IDT. Alot simpler * than twiddling with the GDT ;) */ -void idt_set_gate(unsigned char num, unsigned long base, unsigned short sel, unsigned char flags) +void i86_idt_set_gate(unsigned char num, unsigned long base, unsigned short sel, unsigned char flags) { /* The interrupt routine's base address */ idt[num].base_lo = (base & 0xFFFF); @@ -43,20 +29,21 @@ void idt_set_gate(unsigned char num, unsigned long base, unsigned short sel, uns idt[num].flags = flags; } +struct idt_entry* i86_idt_get_gate(unsigned char num) +{ + return &idt[num]; +} + /* Installs the IDT */ -void idt_install() +void i86_idt_install() { /* Sets the special IDT pointer up, just like in 'gdt.c' */ idtp.limit = (sizeof (struct idt_entry) * 256) - 1; - idtp.base = &idt; + idtp.base = (unsigned int)&idt; /* Clear out the entire IDT, initializing it to zeros */ - memset(&idt, 0, sizeof(struct idt_entry) * 256); - - /* Add any new ISRs to the IDT here using idt_set_gate */ - - + memset (&idt, 0, sizeof(struct idt_entry) * 256); /* Points the processor's internal register to the new IDT */ - idt_load(); + i86_idt_load(); } diff --git a/SysCore/hal/idt/idt.h b/SysCore/hal/idt/idt.h new file mode 100644 index 0000000..3604635 --- /dev/null +++ b/SysCore/hal/idt/idt.h @@ -0,0 +1,32 @@ +/****************************************************************** + * idt.h - INTERRUPT DESCRIPTOR TABLE * + * Contains structures and function declarations for IDT * + ******************************************************************/ + +#ifndef __IDT_H +#define __IDT_H + +/* Defines an IDT entry */ +struct idt_entry +{ + unsigned short base_lo; + unsigned short sel; + unsigned char always0; + unsigned char flags; + unsigned short base_hi; +} __attribute__((packed)); + +struct idt_ptr +{ + unsigned short limit; + unsigned int base; +} __attribute__((packed)); + + +/* This exists in 'start.asm', and is used to load our IDT */ +extern void i86_idt_load(); +extern void i86_idt_set_gate(unsigned char num, unsigned long base, unsigned short sel, unsigned char flags); +extern struct idt_entry* i86_idt_get_gate(unsigned char num); +extern void i86_idt_install(); + +#endif \ No newline at end of file diff --git a/SysCore/hal/irq/compile.bat b/SysCore/hal/irq/compile.bat new file mode 100644 index 0000000..eb0b6d1 --- /dev/null +++ b/SysCore/hal/irq/compile.bat @@ -0,0 +1,19 @@ +@echo off +rem The name of the loader assembly file (without extension, must be .asm): +set loader_name=loader + +rem NASM and DJGPP executable paths: +set nasm_path=C:\nasm +set djgpp_path=C:\DJGPP\bin +set objpath=../../objects +set incpath=../../include + +@echo on +%nasm_path%\nasm.exe -f aout -o %objpath%/irq_asm.o irq.asm +%djgpp_path%\gcc.exe -Wall -O -fstrength-reduce -fomit-frame-pointer -nostdinc -fno-builtin -I%incpath% -c -o %objpath%/irq.o irq.c + +@echo off +@echo . +@echo Done! + +@pause diff --git a/SysCore/hal/irq/irq.asm b/SysCore/hal/irq/irq.asm new file mode 100644 index 0000000..286f7de --- /dev/null +++ b/SysCore/hal/irq/irq.asm @@ -0,0 +1,159 @@ +bits 32 + +; !!! IRQ !!! +global _i86_irq0 +global _i86_irq1 +global _i86_irq2 +global _i86_irq3 +global _i86_irq4 +global _i86_irq5 +global _i86_irq6 +global _i86_irq7 +global _i86_irq8 +global _i86_irq9 +global _i86_irq10 +global _i86_irq11 +global _i86_irq12 +global _i86_irq13 +global _i86_irq14 +global _i86_irq15 + +; 32: IRQ0 +_i86_irq0: + cli + push byte 0 + push byte 32; Note that these don't push an error code on the stack: + ; We need to push a dummy error code + jmp irq_common_stub + +; 33: IRQ1 +_i86_irq1: + cli + push byte 0 + push byte 33 + jmp irq_common_stub + +; 34: IRQ2 +_i86_irq2: + cli + push byte 0 + push byte 34 + jmp irq_common_stub + +; 35: IRQ3 +_i86_irq3: + cli + push byte 0 + push byte 35 + jmp irq_common_stub + +; 36: IRQ4 +_i86_irq4: + cli + push byte 0 + push byte 36 + jmp irq_common_stub + +; 37: IRQ5 +_i86_irq5: + cli + push byte 0 + push byte 37 + jmp irq_common_stub + +; 38: IRQ6 +_i86_irq6: + cli + push byte 0 + push byte 38 + jmp irq_common_stub + +; 39: IRQ7 +_i86_irq7: + cli + push byte 0 + push byte 39 + jmp irq_common_stub + +; 40: IRQ8 +_i86_irq8: + cli + push byte 0 + push byte 40 + jmp irq_common_stub +; 41: IRQ9 +_i86_irq9: + cli + push byte 0 + push byte 41 + jmp irq_common_stub + +; 42: IRQ10 +_i86_irq10: + cli + push byte 0 + push byte 42 + jmp irq_common_stub + +; 43: IRQ11 +_i86_irq11: + cli + push byte 0 + push byte 43 + jmp irq_common_stub + +; 44: IRQ12 +_i86_irq12: + cli + push byte 0 + push byte 44 + jmp irq_common_stub + +; 45: IRQ13 +_i86_irq13: + cli + push byte 0 + push byte 45 + jmp irq_common_stub + +; 46: IRQ14 +_i86_irq14: + cli + push byte 0 + push byte 46 + jmp irq_common_stub + +; 47: IRQ15 +_i86_irq15: + cli + push byte 0 + push byte 47 + jmp irq_common_stub + +extern _i86_irq_handler + +; This is a stub that we have created for IRQ based ISRs. This calls +; '_i86_irq_handler' in our C code. We need to create this in an 'irq.c' +irq_common_stub: + pusha + push ds + push es + push fs + push gs + mov ax, 0x10 + mov ds, ax + mov es, ax + mov fs, ax + mov gs, ax + mov eax, esp + push eax + mov eax, _i86_irq_handler + call eax + pop eax + pop gs + pop fs + pop es + pop ds + popa + add esp, 8 + iret diff --git a/SysCore/hal/irq/irq.c b/SysCore/hal/irq/irq.c new file mode 100644 index 0000000..edfe3d8 --- /dev/null +++ b/SysCore/hal/irq/irq.c @@ -0,0 +1,79 @@ +#include +#include "../idt/idt.h" +#include "../pic/pic.h" +#include "irq.h" +/* This array is actually an array of function pointers. We use +* this to handle custom IRQ handlers for a given IRQ */ +void *irq_routines[16] = +{ + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0 +}; + +/* This installs a custom IRQ handler for the given IRQ */ +void i86_irq_install_handler (int irq, void (*handler)(ISR_stack_regs *r)) +{ + irq_routines[irq] = handler; +} + +void i86_irq_uninstall_handler (int irq) +{ + irq_routines[irq] = 0; +} + + + +/* We first remap the interrupt controllers, and then we install +* the appropriate ISRs to the correct entries in the IDT. This +* is just like installing the exception handlers */ +void i86_irq_install() +{ + i86_pic_remap(32,40); + + i86_idt_set_gate(32, (unsigned)i86_irq0, 0x08, 0x8E); + i86_idt_set_gate(33, (unsigned)i86_irq1, 0x08, 0x8E); + i86_idt_set_gate(34, (unsigned)i86_irq2, 0x08, 0x8E); + i86_idt_set_gate(35, (unsigned)i86_irq3, 0x08, 0x8E); + i86_idt_set_gate(36, (unsigned)i86_irq4, 0x08, 0x8E); + i86_idt_set_gate(37, (unsigned)i86_irq5, 0x08, 0x8E); + i86_idt_set_gate(38, (unsigned)i86_irq6, 0x08, 0x8E); + i86_idt_set_gate(39, (unsigned)i86_irq7, 0x08, 0x8E); + i86_idt_set_gate(40, (unsigned)i86_irq8, 0x08, 0x8E); + i86_idt_set_gate(41, (unsigned)i86_irq9, 0x08, 0x8E); + i86_idt_set_gate(42, (unsigned)i86_irq10, 0x08, 0x8E); + i86_idt_set_gate(43, (unsigned)i86_irq11, 0x08, 0x8E); + i86_idt_set_gate(44, (unsigned)i86_irq12, 0x08, 0x8E); + i86_idt_set_gate(45, (unsigned)i86_irq13, 0x08, 0x8E); + i86_idt_set_gate(46, (unsigned)i86_irq14, 0x08, 0x8E); + i86_idt_set_gate(47, (unsigned)i86_irq15, 0x08, 0x8E); +} + +/* Each of the IRQ ISRs point to this function, rather than +* the 'fault_handler' in 'isrs.c'. The IRQ Controllers need +* to be told when you are done servicing them, so you need +* to send them an "End of Interrupt" command (0x20). There +* are two 8259 chips: The first exists at 0x20, the second +* exists at 0xA0. If the second controller (an IRQ from 8 to +* 15) gets an interrupt, you need to acknowledge the +* interrupt at BOTH controllers, otherwise, you only send +* an EOI command to the first controller. If you don't send +* an EOI, you won't raise any more IRQs */ +void i86_irq_handler (ISR_stack_regs *r) +{ + /* This is a blank function pointer */ + void (*handler)(ISR_stack_regs *r); + + /* Find out if we have a custom handler to run for this + * IRQ, and then finally, run it */ + handler = irq_routines[r->int_no - 32]; + if (handler) handler(r); + + /* If the IDT entry that was invoked was greater than 40 + * (meaning IRQ8 - 15), then we need to send an EOI to + * the slave controller */ + if (r->int_no >=40) outportb(0x0A, 0x20); + + /* In either case, we need to send an EOI to the master + * interrupt controller too */ + outportb(0x20, 0x20); +} diff --git a/SysCore/hal/irq/irq.h b/SysCore/hal/irq/irq.h new file mode 100644 index 0000000..a2bb50c --- /dev/null +++ b/SysCore/hal/irq/irq.h @@ -0,0 +1,29 @@ +#ifndef __IRQ_H +#define __IRQ_H + +/* These are own ISRs that point to our special IRQ handler +* instead of the regular 'fault_handler' function */ + +extern void i86_irq0(); +extern void i86_irq1(); +extern void i86_irq2(); +extern void i86_irq3(); +extern void i86_irq4(); +extern void i86_irq5(); +extern void i86_irq6(); +extern void i86_irq7(); +extern void i86_irq8(); +extern void i86_irq9(); +extern void i86_irq10(); +extern void i86_irq11(); +extern void i86_irq12(); +extern void i86_irq13(); +extern void i86_irq14(); +extern void i86_irq15(); + +extern void i86_irq_install_handler (int irq, void (*handler)(ISR_stack_regs *r)); +extern void i86_irq_uninstall_handler (int irq); +extern void i86_irq_install(); +extern void i86_irq_handler (ISR_stack_regs *r); + +#endif \ No newline at end of file diff --git a/SysCore/hal/isrs/BSOD.c b/SysCore/hal/isrs/BSOD.c new file mode 100644 index 0000000..b3a2638 --- /dev/null +++ b/SysCore/hal/isrs/BSOD.c @@ -0,0 +1,79 @@ +#include +#include + +char *exception_messages[] = { + "Division By Zero Exception", + "Debug Exception", + "Non Maskable Interrupt Exception", + "Breakpoint Exception", + "Into Detected Overflow Exception", + "Out of Bounds Exception", + "Invalid Opcode Exception", + "No Coprocessor", + "Double Fault Exception", + "Coprocessor Segment Overrun Exception", + "Bad TSS Exception", + "Segment Not Present Exception", + "Stack Fault Exception", + "General Protection Fault Exception", + "Page Fault Exception", + "Unknown Interrupt Exception", + "Coprocessor Fault Exception", + "Alignment Check Exception", + "Machine Check Exception", + "Reserved Exception", + "Reserved Exception", + "Reserved Exception", + "Reserved Exception", + "Reserved Exception", + "Reserved Exception", + "Reserved Exception", + "Reserved Exception", + "Reserved Exception", + "Reserved Exception", + "Reserved Exception", + "Reserved Exception" +}; + + +void _STOP_ERROR_SCREEN (ISR_stack_regs *r) +{ + set_default_colors (0x01, 0x0F); clrscr(); + puts (" Blue Screen Of Death\n"); + int i; for (i = 79; i>=0; i--) putc('='); + puts_pos_font (15, 2, "A fatal error has occured, CTA OS has been halted.", 0x01, 0x0C); + puts_pos_font (10, 4, "gs", 0x01, 0x0B); put_hex_pos(15, 4, r->gs); + puts_pos_font (10, 5, "fs", 0x01, 0x0B); put_hex_pos(15, 5, r->fs); + puts_pos_font (10, 6, "es", 0x01, 0x0B); put_hex_pos(15, 6, r->es); + puts_pos_font (10, 7, "ds", 0x01, 0x0B); put_hex_pos(15, 7, r->ds); + + puts_pos_font (40, 4, "edi", 0x01, 0x0B); put_hex_pos(45, 4, r->edi); + puts_pos_font (40, 5, "esi", 0x01, 0x0B); put_hex_pos(45, 5, r->esi); + puts_pos_font (40, 6, "ebp", 0x01, 0x0B); put_hex_pos(45, 6, r->ebp); + puts_pos_font (40, 7, "esp", 0x01, 0x0B); put_hex_pos(45, 7, r->esp); + + puts_pos_font (10, 9, "eax", 0x01, 0x0B); put_hex_pos(15, 9, r->eax); + puts_pos_font (10, 10, "ebx", 0x01, 0x0B); put_hex_pos(15, 10, r->ebx); + puts_pos_font (40, 9, "ecx", 0x01, 0x0B); put_hex_pos(45, 9, r->ecx); + puts_pos_font (40, 10, "edx", 0x01, 0x0B); put_hex_pos(45, 10, r->edx); + + puts_pos_font (10, 12, "int_no", 0x01, 0x0B); put_hex_pos(17, 12, r->int_no); + puts_pos_font (10, 14, "Error code:", 0x01, 0x0B); put_hex_pos(24, 14, r->err_code); + puts_pos_font (10, 15, "Error msg: ", 0x01, 0x0B); puts_pos(24, 15, exception_messages[r->int_no]); + + puts_pos_font (10, 17, "eip", 0x01, 0x0B); put_hex_pos(17, 17, r->eip); + puts_pos_font (10, 18, "cs", 0x01, 0x0B); put_hex_pos(17, 18, r->cs); + puts_pos_font (10, 19, "eflags", 0x01, 0x0B); put_hex_pos(17, 19, r->eflags); + puts_pos_font (10, 20, "useresp", 0x01, 0x0B); put_hex_pos(17, 20, r->useresp); + puts_pos_font (10, 21, "ss", 0x01, 0x0B); put_hex_pos(17, 21, r->ss); + + puts_pos_font (29, 24, "!!! System Halted !!!", 0x01, 0x0C); +} + +/*void _STOP_ERROR_SCREEN (ISR_stack_regs *r) +{ + puts_pos_font (30, 24, "Stop error 0x", 0x01, 0x0B); put_hex_pos(37, 24, r->int_no); + puts_pos(50, 24, exception_messages[r->int_no]); + + puts_pos_font (5, 24, "!!! System Halted !!!", 0x01, 0x0C); +}*/ \ No newline at end of file diff --git a/SysCore/hal/isrs/compile.bat b/SysCore/hal/isrs/compile.bat new file mode 100644 index 0000000..fba4632 --- /dev/null +++ b/SysCore/hal/isrs/compile.bat @@ -0,0 +1,20 @@ +@echo off +rem The name of the loader assembly file (without extension, must be .asm): +set loader_name=loader + +rem NASM and DJGPP executable paths: +set nasm_path=C:\nasm +set djgpp_path=C:\DJGPP\bin +set objpath=../../objects +set incpath=../../include + +@echo on +%nasm_path%\nasm.exe -f aout -o %objpath%/isrs_asm.o isrs.asm +%djgpp_path%\gcc.exe -Wall -O -fstrength-reduce -fomit-frame-pointer -nostdinc -fno-builtin -I%incpath% -c -o %objpath%/isrs.o isrs.c +%djgpp_path%\gcc.exe -Wall -O -fstrength-reduce -fomit-frame-pointer -nostdinc -fno-builtin -I%incpath% -c -o %objpath%/BSOD.o BSOD.c + +@echo off +@echo . +@echo Done! + +@pause diff --git a/SysCore/hal/isrs/isrs.asm b/SysCore/hal/isrs/isrs.asm new file mode 100644 index 0000000..ce19ae0 --- /dev/null +++ b/SysCore/hal/isrs/isrs.asm @@ -0,0 +1,217 @@ +bits 32 + +; !!! ISRs !!! +global _i86_isr0 +global _i86_isr1 +global _i86_isr2 +global _i86_isr3 +global _i86_isr4 +global _i86_isr5 +global _i86_isr6 +global _i86_isr7 +global _i86_isr8 +global _i86_isr9 +global _i86_isr10 +global _i86_isr11 +global _i86_isr12 +global _i86_isr13 +global _i86_isr14 +global _i86_isr15 +global _i86_isr16 +global _i86_isr17 +global _i86_isr18 +global _i86_isr19 +global _i86_isr20 +global _i86_isr21 +global _i86_isr22 +global _i86_isr23 +global _i86_isr24 +global _i86_isr25 +global _i86_isr26 +global _i86_isr27 +global _i86_isr28 +global _i86_isr29 +global _i86_isr30 +global _i86_isr31 + +_i86_isr0: + cli + push byte 0; A normal ISR stub that pops a dummy error code to keep a + ; uniform stack frame + push byte 0 + jmp isr_common_stub +_i86_isr1: + cli + push byte 0 + push byte 1 + jmp isr_common_stub +_i86_isr2: + cli + push byte 0 + push byte 2 + jmp isr_common_stub +_i86_isr3: + cli + push byte 0 + push byte 3 + jmp isr_common_stub +_i86_isr4: + cli + push byte 0 + push byte 4 + jmp isr_common_stub +_i86_isr5: + cli + push byte 0 + push byte 5 + jmp isr_common_stub +_i86_isr6: + cli + push byte 0 + push byte 6 + jmp isr_common_stub +_i86_isr7: + cli + push byte 0 + push byte 7 + jmp isr_common_stub +_i86_isr8: + cli + push byte 8 + jmp isr_common_stub +_i86_isr9: + cli + push byte 0 + push byte 9 + jmp isr_common_stub +_i86_isr10: + cli + push byte 10 + jmp isr_common_stub +_i86_isr11: + cli + push byte 11 + jmp isr_common_stub +_i86_isr12: + cli + push byte 12 + jmp isr_common_stub +_i86_isr13: + cli + push byte 13 + jmp isr_common_stub +_i86_isr14: + cli + push byte 14 + jmp isr_common_stub +_i86_isr15: + cli + push byte 0 + push byte 15 + jmp isr_common_stub +_i86_isr16: + cli + push byte 0 + push byte 16 + jmp isr_common_stub +_i86_isr17: + cli + push byte 0 + push byte 17 + jmp isr_common_stub +_i86_isr18: + cli + push byte 0 + push byte 18 + jmp isr_common_stub +_i86_isr19: + cli + push byte 0 + push byte 19 + jmp isr_common_stub +_i86_isr20: + cli + push byte 0 + push byte 20 + jmp isr_common_stub +_i86_isr21: + cli + push byte 0 + push byte 21 + jmp isr_common_stub +_i86_isr22: + cli + push byte 0 + push byte 22 + jmp isr_common_stub +_i86_isr23: + cli + push byte 0 + push byte 23 + jmp isr_common_stub +_i86_isr24: + cli + push byte 0 + push byte 24 + jmp isr_common_stub +_i86_isr25: + cli + push byte 0 + push byte 25 + jmp isr_common_stub +_i86_isr26: + cli + push byte 0 + push byte 26 + jmp isr_common_stub +_i86_isr27: + cli + push byte 0 + push byte 27 + jmp isr_common_stub +_i86_isr28: + cli + push byte 0 + push byte 28 + jmp isr_common_stub +_i86_isr29: + cli + push byte 0 + push byte 29 + jmp isr_common_stub +_i86_isr30: + cli + push byte 0 + push byte 30 + jmp isr_common_stub +_i86_isr31: + cli + push byte 0 + push byte 31 + jmp isr_common_stub + +extern _i86_fault_handler + +isr_common_stub: + pusha + push ds + push es + push fs + push gs + mov ax, 0x10 ; Load the Kernel Data Segment descriptor! + mov ds, ax + mov es, ax + mov fs, ax + mov gs, ax + mov eax, esp ; Push us the stack + push eax + mov eax, _i86_fault_handler + call eax ; A special call, preserves the 'eip' register + pop eax + pop gs + pop fs + pop es + pop ds + popa + add esp, 8 ; Cleans up the pushed error code and pushed ISR number + iret ; pops 5 things at once: CS, EIP, EFLAGS, SS, and ESP! diff --git a/SysCore/hal/isrs/isrs.c b/SysCore/hal/isrs/isrs.c new file mode 100644 index 0000000..9e0e756 --- /dev/null +++ b/SysCore/hal/isrs/isrs.c @@ -0,0 +1,70 @@ +#include +#include "isrs.h" +#include "../idt/idt.h" + +extern void _STOP_ERROR_SCREEN(ISR_stack_regs *); +/* This is a very repetitive function... it's not hard, it's +* just annoying. As you can see, we set the first 32 entries +* in the IDT to the first 32 ISRs. We can't use a for loop +* for this, because there is no way to get the function names +* that correspond to that given entry. We set the access +* flags to 0x8E. This means that the entry is present, is +* running in ring 0 (kernel level), and has the lower 5 bits +* set to the required '14', which is represented by 'E' in +* hex. */ +void i86_isrs_install() +{ + i86_idt_set_gate(0, (unsigned)i86_isr0, 0x08, 0x8E); + i86_idt_set_gate(1, (unsigned)i86_isr1, 0x08, 0x8E); + i86_idt_set_gate(2, (unsigned)i86_isr2, 0x08, 0x8E); + i86_idt_set_gate(3, (unsigned)i86_isr3, 0x08, 0x8E); + i86_idt_set_gate(4, (unsigned)i86_isr4, 0x08, 0x8E); + i86_idt_set_gate(5, (unsigned)i86_isr5, 0x08, 0x8E); + i86_idt_set_gate(6, (unsigned)i86_isr6, 0x08, 0x8E); + i86_idt_set_gate(7, (unsigned)i86_isr7, 0x08, 0x8E); + i86_idt_set_gate(8, (unsigned)i86_isr8, 0x08, 0x8E); + i86_idt_set_gate(9, (unsigned)i86_isr9, 0x08, 0x8E); + i86_idt_set_gate(10, (unsigned)i86_isr10, 0x08, 0x8E); + i86_idt_set_gate(11, (unsigned)i86_isr11, 0x08, 0x8E); + i86_idt_set_gate(12, (unsigned)i86_isr12, 0x08, 0x8E); + i86_idt_set_gate(13, (unsigned)i86_isr13, 0x08, 0x8E); + i86_idt_set_gate(14, (unsigned)i86_isr14, 0x08, 0x8E); + i86_idt_set_gate(15, (unsigned)i86_isr15, 0x08, 0x8E); + i86_idt_set_gate(16, (unsigned)i86_isr16, 0x08, 0x8E); + i86_idt_set_gate(17, (unsigned)i86_isr17, 0x08, 0x8E); + i86_idt_set_gate(18, (unsigned)i86_isr18, 0x08, 0x8E); + i86_idt_set_gate(19, (unsigned)i86_isr19, 0x08, 0x8E); + i86_idt_set_gate(20, (unsigned)i86_isr20, 0x08, 0x8E); + i86_idt_set_gate(21, (unsigned)i86_isr21, 0x08, 0x8E); + i86_idt_set_gate(22, (unsigned)i86_isr22, 0x08, 0x8E); + i86_idt_set_gate(23, (unsigned)i86_isr23, 0x08, 0x8E); + i86_idt_set_gate(24, (unsigned)i86_isr24, 0x08, 0x8E); + i86_idt_set_gate(25, (unsigned)i86_isr25, 0x08, 0x8E); + i86_idt_set_gate(26, (unsigned)i86_isr26, 0x08, 0x8E); + i86_idt_set_gate(27, (unsigned)i86_isr27, 0x08, 0x8E); + i86_idt_set_gate(28, (unsigned)i86_isr28, 0x08, 0x8E); + i86_idt_set_gate(29, (unsigned)i86_isr29, 0x08, 0x8E); + i86_idt_set_gate(30, (unsigned)i86_isr30, 0x08, 0x8E); + i86_idt_set_gate(31, (unsigned)i86_isr31, 0x08, 0x8E); +} + + + +/* All of our Exception handling Interrupt Service Routines will +* point to this function. This will tell us what exception has +* happened! Right now, we simply halt the system by hitting an +* endless loop. All ISRs disable interrupts while they are being +* serviced as a 'locking' mechanism to prevent an IRQ from +* happening and messing up kernel data structures */ +void i86_fault_handler(ISR_stack_regs *r) +{ + /* Is this a fault whose number is from 0 to 31? */ + if (r->int_no < 32) + { + _STOP_ERROR_SCREEN(r); + /* Display the description for the Exception that occurred.*/ + + /* Put on the BSOD screen*/ + for (;;); + } +} diff --git a/SysCore/hal/isrs/isrs.h b/SysCore/hal/isrs/isrs.h new file mode 100644 index 0000000..64b6312 --- /dev/null +++ b/SysCore/hal/isrs/isrs.h @@ -0,0 +1,40 @@ +#ifndef __ISRS_H +#define __ISRS_H + +extern void i86_isr0(); +extern void i86_isr1(); +extern void i86_isr2(); +extern void i86_isr3(); +extern void i86_isr4(); +extern void i86_isr5(); +extern void i86_isr6(); +extern void i86_isr7(); +extern void i86_isr8(); +extern void i86_isr9(); +extern void i86_isr10(); +extern void i86_isr11(); +extern void i86_isr12(); +extern void i86_isr13(); +extern void i86_isr14(); +extern void i86_isr15(); +extern void i86_isr16(); +extern void i86_isr17(); +extern void i86_isr18(); +extern void i86_isr19(); +extern void i86_isr20(); +extern void i86_isr21(); +extern void i86_isr22(); +extern void i86_isr23(); +extern void i86_isr24(); +extern void i86_isr25(); +extern void i86_isr26(); +extern void i86_isr27(); +extern void i86_isr28(); +extern void i86_isr29(); +extern void i86_isr30(); +extern void i86_isr31(); + +extern void i86_isrs_install(); +extern void i86_fault_handler(ISR_stack_regs *r); + +#endif \ No newline at end of file diff --git a/SysCore/hal/keyboard/compile.bat b/SysCore/hal/keyboard/compile.bat new file mode 100644 index 0000000..41d9f5d --- /dev/null +++ b/SysCore/hal/keyboard/compile.bat @@ -0,0 +1,18 @@ +@echo off +rem The name of the loader assembly file (without extension, must be .asm): +set loader_name=loader + +rem NASM and DJGPP executable paths: +set nasm_path=C:\nasm +set djgpp_path=C:\DJGPP\bin +set objpath=../../objects +set incpath=../../include + +@echo on +%djgpp_path%\gcc.exe -Wall -O -fstrength-reduce -fomit-frame-pointer -nostdinc -fno-builtin -I%incpath% -c -o %objpath%/keyus.o keyus.c + +@echo off +@echo . +@echo Done! + +@pause diff --git a/kernel/keyboard/key_list.txt b/SysCore/hal/keyboard/key_list.txt similarity index 100% rename from kernel/keyboard/key_list.txt rename to SysCore/hal/keyboard/key_list.txt diff --git a/SysCore/hal/keyboard/keyboard.h b/SysCore/hal/keyboard/keyboard.h new file mode 100644 index 0000000..465d7f6 --- /dev/null +++ b/SysCore/hal/keyboard/keyboard.h @@ -0,0 +1,133 @@ + +#define KB_KEY_LSHIFT 0x81 // 1000 0001 +#define KB_KEY_RSHIFT 0X82 // 1000 0010 +#define KB_KEY_LALT 0X84 // 1000 0100 +#define KB_KEY_RALT 0x88 // 1000 1000 +#define KB_KEY_LCTRL 0x90 // 1001 0000 +#define KB_KEY_RCTRL 0xA0 // 1010 0000 +#define KB_KEY_FSHIFT 0xC0 // 1100 0000 +extern volatile byte kb_modifier_status; + +#define KB_PREFIX_GRAY 0x01 // Gray +#define KB_PREFIX_BREAK 0x02 // Break code +#define KB_PREFIX_PAUSE 0x04 // Pause/break key +#define KB_PREFIX_PAUSE1 0x08 // Recieved first byte from pause/break +extern volatile byte kb_prefix; + +#define KB_KEY_SCROLL 0xF1 // 1111 0001 +#define KB_KEY_NUM 0xF2 // 1111 0010 +#define KB_KEY_CAPS 0xF4 // 1111 0100 +extern volatile byte kb_lights_status; + +extern byte kb_scancode_set; +#define KB_KEY_PAUSE 0x00 +#define KB_KEY_F9 0x01 +#define KB_KEY_F7 0x02 +#define KB_KEY_F5 0X03 +#define KB_KEY_F3 0x04 +#define KB_KEY_F1 0x05 +#define KB_KEY_F2 0x06 +#define KB_KEY_F12 0x07 +#define KB_KEY_PRINTSCRN 0x08 +#define KB_KEY_F10 0x09 +#define KB_KEY_F8 0x0A +#define KB_KEY_F6 0x0B +#define KB_KEY_F4 0x0C +#define KB_KEY_TAB 0x0D +#define KB_KEY_TILDA 0x0E +#define KB_KEY_Q 0x15 +#define KB_KEY_1 0x16 +#define KB_KEY_Z 0x1A +#define KB_KEY_S 0x1B +#define KB_KEY_A 0x1C +#define KB_KEY_W 0x1D +#define KB_KEY_2 0x1E +#define KB_KEY_LWIN 0x1F +#define KB_KEY_C 0x21 +#define KB_KEY_X 0x22 +#define KB_KEY_D 0x23 +#define KB_KEY_E 0x24 +#define KB_KEY_4 0x25 +#define KB_KEY_3 0x26 +#define KB_KEY_RWIN 0x27 +#define KB_KEY_SPACE 0x29 +#define KB_KEY_V 0x2A +#define KB_KEY_F 0x2B +#define KB_KEY_T 0x2C +#define KB_KEY_R 0x2D +#define KB_KEY_5 0x2E +#define KB_KEY_MENU 0x2F +#define KB_KEY_N 0x31 +#define KB_KEY_B 0x32 +#define KB_KEY_H 0x33 +#define KB_KEY_G 0x34 +#define KB_KEY_Y 0x35 +#define KB_KEY_6 0x36 +#define KB_KEY_M 0x3A +#define KB_KEY_J 0x3B +#define KB_KEY_U 0x3C +#define KB_KEY_7 0x3D +#define KB_KEY_8 0x3E +#define KB_KEY_COMMA 0x41 +#define KB_KEY_K 0x42 +#define KB_KEY_I 0x43 +#define KB_KEY_O 0x44 +#define KB_KEY_0 0x45 +#define KB_KEY_9 0x46 +#define KB_KEY_PERIOD 0x49 +#define KB_KEY_SLASH 0x4A +#define KB_KEY_L 0x4B +#define KB_KEY_SEMICOLON 0x4C +#define KB_KEY_P 0x4D +#define KB_KEY_DASH 0x4E +#define KB_KEY_APOSTROPHE 0x52 +#define KB_KEY_LBRACKET 0x54 +#define KB_KEY_EQUAL 0x55 +#define KB_KEY_NUMPAD_ENTER 0x59 +#define KB_KEY_ENTER 0x5A +#define KB_KEY_RBRACKET 0x5B +#define KB_KEY_BACKSLASH 0x5D +#define KB_KEY_END 0x5E +#define KB_KEY_LEFT 0x5F +#define KB_KEY_HOME 0x60 +#define KB_KEY_INSERT 0x61 +#define KB_KEY_DELETE 0x62 +#define KB_KEY_DOWN 0x63 +#define KB_KEY_RIGHT 0x64 +#define KB_KEY_UP 0x65 +#define KB_KEY_BACKSPACE 0x66 +#define KB_KEY_PGDOWN 0x67 +#define KB_KEY_PGUP 0x68 +#define KB_KEY_NUMPAD_1 0x69 +#define KB_KEY_NUMPAD_SLASH 0x6A +#define KB_KEY_NUMPAD_4 0x6B +#define KB_KEY_NUMPAD_7 0x6C +#define KB_KEY_NUMPAD_0 0x70 +#define KB_KEY_NUMPAD_COLON 0x71 +#define KB_KEY_NUMPAD_2 0x72 +#define KB_KEY_NUMPAD_5 0x73 +#define KB_KEY_NUMPAD_6 0x74 +#define KB_KEY_NUMPAD_8 0x75 +#define KB_KEY_ESC 0x76 +#define KB_KEY_F11 0x78 +#define KB_KEY_NUMPAD_PLUS 0x79 +#define KB_KEY_NUMPAD_3 0x7A +#define KB_KEY_NUMPAD_MINUS 0x7B +#define KB_KEY_NUMPAD_ASTERISK 0x7C +#define KB_KEY_NUMPAD_9 0x7D + + +typedef struct { + byte status; + byte lights; + byte scancode; + byte character; +} kb_key; + + +extern char getch(); +extern kb_key get_key(); +extern scancode_to_ascii(byte scancode); +extern byte get_key_status(byte scancode); +extern void kb_set_repeat(float rate, int delay); +extern void kb_set_LEDs(byte status); \ No newline at end of file diff --git a/kernel/keyboard/keyus.c b/SysCore/hal/keyboard/keyus.c similarity index 51% rename from kernel/keyboard/keyus.c rename to SysCore/hal/keyboard/keyus.c index 392a4ff..e5313e7 100644 --- a/kernel/keyboard/keyus.c +++ b/SysCore/hal/keyboard/keyus.c @@ -1,31 +1,42 @@ +#include +#include #include "keyus.h" +#include "../irq/irq.h" -// kb_key_return 4-byte structure -typedef struct { - byte status; - byte lights; - byte scancode; - byte character; -} kb_key; +extern void reboot(); -byte kb_array[16]; -volatile static byte kb_newdata; +const char kbdus_map[] = { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, '\t', '`', 0, + 0, 0, 0, 0, 0, 'q', '1', 0, 0, 0, 'z', 's', 'a', 'w', '2', 0, + 0, 'c', 'x', 'd', 'e', '4', '3', 0, 0, ' ', 'v', 'f', 't', 'r', '5', 0, + 0, 'n', 'b', 'h', 'g', 'y', '6', 0, 0, 0, 'm', 'j', 'u', '7', '8', 0, + 0, ',', 'k', 'i', 'o', '0', '9', 0, 0, '.', '/', 'l', ';', 'p', '-', 0, + 0, 0, '\'', 0, '[', '=', 0, 0, 0, '\n', '\n', ']', 0, '\\', 0, 0, + 0, 0, 0x7F, 0, 0, 0, '\b', 0, 0, '1', '/', '4', '7', 0, 0, 0, + '0', '.', '2', '5', '6', '8', 0, 0, 0, '+', '3', '-', '*', '9', 0, 0 + }; -/*********DEBUG**************/ -void kb_print_binary(int x, int y, byte what) -{ - char arr[9]; int i; - for (i = 7; i>=0; i--, what/=2) - arr[i] = (what%2) + '0'; - - arr[8] = 0; - - puts_pos(x,y,arr); +const char kbdus_map_shift[] = { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, '\t', '~', 0, + 0, 0, 0, 0, 0, 'Q', '!', 0, 0, 0, 'Z', 'S', 'A', 'W', '@', 0, + 0, 'C', 'X', 'D', 'E', '$', '#', 0, 0, ' ', 'V', 'F', 'T', 'R', '%', 0, + 0, 'N', 'B', 'H', 'G', 'Y', '^', 0, 0, 0, 'M', 'J', 'U', '&', '*', 0, + 0, '<', 'K', 'I', 'O', ')', '(', 0, 0, '>', '?', 'L', ':', 'P', '_', 0, + 0, 0, '\"', 0, '{', '+', 0, 0, 0, '\n', '\n', '}', 0, '|', 0, 0, + 0, 0, 0x7F, 0, 0, 0, '\b', 0, 0, '1', '/', '4', '7', 0, 0, 0, + '0', '.', '2', '5', '6', '8', 0, 0, 0, '+', '3', '-', '*', '9', 0, 0 + }; -} -/*********DEBUG**************/ -void kb_set_key(byte scancode, byte val) +volatile byte kb_array[16]; +volatile byte kb_newdata; +volatile byte kb_modifier_status; +volatile byte kb_prefix; +volatile byte kb_lights_status; +byte kb_scancode_set; + + +void i86_kb_set_key(byte scancode, byte val) { byte pos = scancode/8; byte offset = scancode%8; @@ -37,7 +48,7 @@ void kb_set_key(byte scancode, byte val) else kb_array[pos] &= 0xFF - (1<3 || delay>31) return; + + byte out = rate<<5 | delay; + while ((inportb(0x64)&2) != 0); + outportb(0x60, 0xF3); + while ((inportb(0x64)&2) != 0); + outportb(0x60, out); +} + + +/*************************************** + * Set keyboard LEDs * + *************************************** + +-----------+-------+-------+--------+ + | Bits 7-3 | Bit 2 | Bit 1 | Bit 0 | + | 0 | Caps | Num | Scroll | + |(reserved) | lock | lock | lock | + +-----------+-------+-------+--------+ + ***************************************/ +void i86_kb_set_LEDs(byte status) +{ + while ((inportb (0x64)&2)!=0); + outportb (0x60, 0xED); + + while ((inportb (0x64)&2)!=0); + outportb (0x60, status); +} + +/*************************************** + * Set scancode set * + *************************************** + 0 Get current scancode set + 1 Set to scancode set 1 + 2 Set to scancode set 2 + 3 Set to scancode set 3 + ***************************************/ +void i86_kb_set_scancodeset(byte set) +{ + if (set>3) return; + + while ((inportb (0x64)&2)!=0); + outportb (0x60, 0xF0); + + while ((inportb (0x64)&2)!=0); + outportb (0x60, set); + + kb_scancode_set = set; +} + +byte i86_kb_get_scancodeset() { + return kb_scancode_set; +} + +void i86_kb_waitin() +{ + int fail_safe=200000; + while ((inportb(0x64)&2)!=0 && fail_safe>0) fail_safe--; +} + +void i86_kb_waitout() +{ + int fail_safe=200000; + while ((inportb(0x64)&1)==0 && fail_safe>0) fail_safe--; +} + + +void i86_kb_install_partone() +{ + i86_irq_install_handler(1, i86_kb_handler);// instali handler + i86_kb_waitin(); outportb(0x60, 0xFF); // Reset kb + + // Initialize variables + kb_newdata = 0; + kb_modifier_status = 0; + kb_prefix = 0; + kb_lights_status = 0; + kb_scancode_set = 0; + +} + + +int i86_kb_install_parttwo() +{ + int ret = 0; + + // Wait for BAT test results + byte temp; + do temp = inportb(0x60); + while (temp!=0xAA && temp!=0xFC); + + if (temp == 0xFC) ret = -1; + + // Set new repeat rate + i86_kb_set_repeat(1, 11); + + // Set scancode set 2 + i86_kb_set_scancodeset(2); // Set new scancode set + + i86_kb_waitin(); + outportb(0x64, 0x20); // Get "Command byte" + + do { temp = inportb(0x60); + } while (temp==0xFA || temp==0xAA); + + temp &= 0xFF - (1<<6); // Set bit6 to 0: disable conversion + i86_kb_waitin(); outportb(0x64, 0x60); // Function to write cmd byte + i86_kb_waitin(); outportb(0x60, temp); // Send it + memset((void*)kb_array, 0, 16); + + return ret; + +} diff --git a/SysCore/hal/keyboard/keyus.h b/SysCore/hal/keyboard/keyus.h new file mode 100644 index 0000000..6b608c7 --- /dev/null +++ b/SysCore/hal/keyboard/keyus.h @@ -0,0 +1,28 @@ +#ifndef __KEYUS_H +#define __KEYUS_H + +extern const char kbdus_map[0x80]; +extern const char kbdus_map_shift[0x80]; + +extern volatile byte kb_modifier_status; +extern volatile byte kb_prefix; +extern volatile byte kb_lights_status; +extern byte kb_scancode_set; + +extern void i86_kb_set_key(byte scancode, byte val); +extern void i86_kb_set_LEDs(byte status); +extern void i86_kb_set_repeat(byte rate, byte delay); +extern void i86_kb_set_scancodeset(byte set); +extern byte i86_kb_get_key(byte scancode); +extern void i86_kb_handler(ISR_stack_regs *r); +extern kb_key getkey(); +extern void i86_kb_set_repeat(byte rate, byte delay); +extern void i86_kb_set_LEDs(byte status); +extern void i86_kb_set_scancodeset(byte set); +extern byte i86_kb_get_scancodeset(); +extern void i86_kb_waitin(); +extern void i86_kb_waitout(); +extern void i86_kb_install_partone(); +extern int i86_kb_install_parttwo(); + +#endif \ No newline at end of file diff --git a/SysCore/hal/makeall.bat b/SysCore/hal/makeall.bat new file mode 100644 index 0000000..f34925b --- /dev/null +++ b/SysCore/hal/makeall.bat @@ -0,0 +1,109 @@ +@echo off +set nasm_path=C:\nasm +set djgpp_path=C:\DJGPP\bin + +@echo Building Hardware Abstraction Layer... +set objpath=..\objects +set incpath=../include +del %objpath%\hal.o +%djgpp_path%\gcc.exe -Wall -O -fstrength-reduce -fomit-frame-pointer -nostdinc -fno-builtin -I%incpath% -c -o %objpath%/hal.o hal.c +if not exist %objpath%\hal.o goto error + +set objpath=..\..\objects +set incpath=../../include + +goto cmos + +:error + @echo. + @echo There have been build errors. Building halted. + @pause + exit + +:cmos + cd cmos + @echo * Compiling CMOS... + del %objpath%\cmos.o + %djgpp_path%\gcc.exe -Wall -O -fstrength-reduce -fomit-frame-pointer -nostdinc -fno-builtin -I%incpath% -c -o %objpath%/cmos.o cmos.c + if not exist %objpath%\cmos.o goto error + cd.. + +:cpu + cd cpu + @echo * Compiling Central Processing Unit... + del %objpath%\cpu.o + %djgpp_path%\gcc.exe -Wall -O -fstrength-reduce -fomit-frame-pointer -nostdinc -fno-builtin -I%incpath% -c -o %objpath%/cpu.o cpu.c + if not exist %objpath%\cpu.o goto error + + cd.. + +:gdt + cd gdt + @echo * Compiling Global Descriptor Table... + del %objpath%\gdt.o + del %objpath%\gdt_asm.o + %nasm_path%\nasm.exe -f aout -o %objpath%/gdt_asm.o gdt.asm + %djgpp_path%\gcc.exe -Wall -O -fstrength-reduce -fomit-frame-pointer -nostdinc -fno-builtin -I%incpath% -c -o %objpath%/gdt.o gdt.c + if not exist %objpath%\gdt.o goto error + if not exist %objpath%\gdt_asm.o goto error + cd.. + +:idt + cd idt + @echo * Compiling Interrupt Descriptor Table... + del %objpath%\idt.o + del %objpath%\idt_asm.o + %nasm_path%\nasm.exe -f aout -o %objpath%/idt_asm.o idt.asm + %djgpp_path%\gcc.exe -Wall -O -fstrength-reduce -fomit-frame-pointer -nostdinc -fno-builtin -I%incpath% -c -o %objpath%/idt.o idt.c + if not exist %objpath%\idt.o goto error + if not exist %objpath%\idt_asm.o goto error + cd.. + +:irq + cd irq + @echo * Compiling Interrupt ReQuests... + del %objpath%\irq.o + del %objpath%\irq_asm.o + %nasm_path%\nasm.exe -f aout -o %objpath%/irq_asm.o irq.asm + %djgpp_path%\gcc.exe -Wall -O -fstrength-reduce -fomit-frame-pointer -nostdinc -fno-builtin -I%incpath% -c -o %objpath%/irq.o irq.c + if not exist %objpath%\irq.o goto error + if not exist %objpath%\irq_asm.o goto error + cd.. + +:isrs + cd isrs + @echo * Compiling Interrupt Service Routines... + del %objpath%\isrs_asm.o + del %objpath%\isrs.o + del %objpath%\BSOD.o + %nasm_path%\nasm.exe -f aout -o %objpath%/isrs_asm.o isrs.asm + %djgpp_path%\gcc.exe -Wall -O -fstrength-reduce -fomit-frame-pointer -nostdinc -fno-builtin -I%incpath% -c -o %objpath%/isrs.o isrs.c + %djgpp_path%\gcc.exe -Wall -O -fstrength-reduce -fomit-frame-pointer -nostdinc -fno-builtin -I%incpath% -c -o %objpath%/BSOD.o BSOD.c + if not exist %objpath%\isrs_asm.o goto error + if not exist %objpath%\isrs.o goto error + if not exist %objpath%\BSOD.o goto error + cd.. + +:keyboard + cd keyboard + @echo * Compiling KEYBOARD... + del %objpath%\keyus.o + %djgpp_path%\gcc.exe -Wall -O -fstrength-reduce -fomit-frame-pointer -nostdinc -fno-builtin -I%incpath% -c -o %objpath%/keyus.o keyus.c + if not exist %objpath%\keyus.o goto error + cd.. + +:pic + cd pic + @echo * Compiling Programmable Interrupt Controller... + del %objpath%\pic.o + %djgpp_path%\gcc.exe -Wall -O -fstrength-reduce -fomit-frame-pointer -nostdinc -fno-builtin -I%incpath% -c -o %objpath%/pic.o pic.c + if not exist %objpath%\pic.o goto error + cd.. + +:pit + cd pit + @echo * Compiling Programmable Interval Timer... + del %objpath%\pit.o + %djgpp_path%\gcc.exe -Wall -O -fstrength-reduce -fomit-frame-pointer -nostdinc -fno-builtin -I%incpath% -c -o %objpath%/pit.o pit.c + if not exist %objpath%\pit.o goto error + cd.. \ No newline at end of file diff --git a/SysCore/hal/pic/compile.bat b/SysCore/hal/pic/compile.bat new file mode 100644 index 0000000..b2579f0 --- /dev/null +++ b/SysCore/hal/pic/compile.bat @@ -0,0 +1,18 @@ +@echo off +rem The name of the loader assembly file (without extension, must be .asm): +set loader_name=loader + +rem NASM and DJGPP executable paths: +set nasm_path=C:\nasm +set djgpp_path=C:\DJGPP\bin +set objpath=../../objects +set incpath=../../include + +@echo on +%djgpp_path%\gcc.exe -Wall -O -fstrength-reduce -fomit-frame-pointer -nostdinc -fno-builtin -I%incpath% -c -o %objpath%/pic.o pic.c + +@echo off +@echo . +@echo Done! + +@pause diff --git a/SysCore/hal/pic/pic.c b/SysCore/hal/pic/pic.c new file mode 100644 index 0000000..e283009 --- /dev/null +++ b/SysCore/hal/pic/pic.c @@ -0,0 +1,23 @@ +#include +#include "pic.h" + +void i86_pic_remap(int pic1, int pic2) +{ + // Send ICW1 + outportb(0x20, 0x11); + outportb(0xA0, 0x11); + + // send ICW2 + outportb(0x21, pic1); // remap pics + outportb(0xA1, pic2); + + // send ICW3 + outportb(0x21, 4); + outportb(0xA1, 2); + + // Send ICW4 + outportb(0x21, 0x01); + outportb(0xA1, 0x01); + + outportb(0x21, 0x00); +} diff --git a/SysCore/hal/pic/pic.h b/SysCore/hal/pic/pic.h new file mode 100644 index 0000000..72285d8 --- /dev/null +++ b/SysCore/hal/pic/pic.h @@ -0,0 +1,6 @@ +#ifndef _PIC_H +#define _PIC_H + +extern void i86_pic_remap(int pic1, int pic2); + +#endif \ No newline at end of file diff --git a/SysCore/hal/pit/compile.bat b/SysCore/hal/pit/compile.bat new file mode 100644 index 0000000..fb9bf7d --- /dev/null +++ b/SysCore/hal/pit/compile.bat @@ -0,0 +1,18 @@ +@echo off +rem The name of the loader assembly file (without extension, must be .asm): +set loader_name=loader + +rem NASM and DJGPP executable paths: +set nasm_path=C:\nasm +set djgpp_path=C:\DJGPP\bin +set objpath=../../objects +set incpath=../../include + +@echo on +%djgpp_path%\gcc.exe -Wall -O -fstrength-reduce -fomit-frame-pointer -nostdinc -fno-builtin -I%incpath% -c -o %objpath%/pit.o pit.c + +@echo off +@echo . +@echo Done! + +@pause diff --git a/SysCore/hal/pit/pit.c b/SysCore/hal/pit/pit.c new file mode 100644 index 0000000..5e24e22 --- /dev/null +++ b/SysCore/hal/pit/pit.c @@ -0,0 +1,56 @@ +#include +#include +#include "../irq/irq.h" +#include "pit.h" + +volatile unsigned int _pit_ticks = 0; +volatile unsigned int _pit_frequency = 0; +unsigned char _pit_init = 0; +volatile TIME _internal_clock; + + +void i86_pit_set_frequency(int frequency) +{ + int divisor = 1193180/frequency; // Calculate the divisor + outportb(0x43, 0x36); // Set our command byte 0x36 + outportb(0x40, divisor&0xFF); // Set low byte + outportb(0x40, divisor>>8); // Set high byte + _pit_frequency = frequency; +} + +void i86_pit_handler(ISR_stack_regs *r) +{ + _pit_ticks++; // count tick + if (_pit_ticks % _pit_frequency == 0) + _CLOCK_INC((TIME*)&_internal_clock); // update internal clock +} + +unsigned int i86_pit_set_tick_count(unsigned int i) +{ + unsigned int r = _pit_ticks; + _pit_ticks = i; + return r; +} + +unsigned int i86_pit_get_tick_count() +{ + return _pit_ticks; +} +unsigned int i86_pit_get_frequency() +{ + return _pit_frequency; +} + +void i86_pit_install(int freq) +{ + i86_irq_install_handler(0, i86_pit_handler); + i86_pit_set_frequency(freq); + _pit_ticks = 0; + _pit_init = 1; + +} + +unsigned char i86_pit_is_initialized() +{ + return _pit_init; +} diff --git a/SysCore/hal/pit/pit.h b/SysCore/hal/pit/pit.h new file mode 100644 index 0000000..93c3d28 --- /dev/null +++ b/SysCore/hal/pit/pit.h @@ -0,0 +1,17 @@ +#ifndef __PIT_H +#define __PIT_H + +#include +extern volatile unsigned int _pit_ticks; +extern volatile unsigned int _pit_frequency; +extern volatile TIME _internal_clock; + +extern void i86_pit_handler(ISR_stack_regs *r); +extern void i86_pit_set_frequency(int frequency); +extern unsigned int i86_pit_set_tick_count(unsigned int i); +extern unsigned int i86_pit_get_tick_count(); +extern unsigned int i86_pit_get_frequency(); +extern void i86_pit_install(int freq); +extern unsigned char i86_pit_is_initialized(); + +#endif \ No newline at end of file diff --git a/SysCore/include/_null.h b/SysCore/include/_null.h new file mode 100644 index 0000000..8d731bf --- /dev/null +++ b/SysCore/include/_null.h @@ -0,0 +1,30 @@ + +#ifndef __NULL_H +#define __NULL_H + +/****************************** + * _null.h * + * - NULL declaration * + ******************************/ + +#if defined (_MSC_VER) && (_MSC_VER >= 1020) +# pragma once +#endif + +#ifdef NULL +#undef NULL +#endif + +#ifdef __cplusplus +extern "C" +{ +/* standard NULL declaration */ +#define NULL 0 +} +#else +/* standard NULL declaration */ +#define NULL (void*)0 +#endif + + +#endif diff --git a/SysCore/include/bootinfo.h b/SysCore/include/bootinfo.h new file mode 100644 index 0000000..5b0599c --- /dev/null +++ b/SysCore/include/bootinfo.h @@ -0,0 +1,39 @@ +#ifndef _BOOTINFO_H +#define _BOOTINFO_H +//**************************************************************************** +//** bootinfo.h +//**************************************************************************** + +#include + +//! multiboot info structure passed from boot loader + +typedef struct { + + uint32_t m_flags; + uint32_t m_memoryLo; + uint32_t m_memoryHi; + uint32_t m_bootDevice; + uint32_t m_cmdLine; + uint32_t m_modsCount; + uint32_t m_modsAddr; + uint32_t m_syms0; + uint32_t m_syms1; + uint32_t m_syms2; + uint32_t m_mmap_length; + uint32_t m_mmap_addr; + uint32_t m_drives_length; + uint32_t m_drives_addr; + uint32_t m_config_table; + uint32_t m_bootloader_name; + uint32_t m_apm_table; + uint32_t m_vbe_control_info; + uint32_t m_vbe_mode_info; + uint16_t m_vbe_mode; + uint32_t m_vbe_interface_addr; + uint16_t m_vbe_interface_len; +} multiboot_info ; + + +#endif + diff --git a/SysCore/include/cctype b/SysCore/include/cctype new file mode 100644 index 0000000..7ce3762 --- /dev/null +++ b/SysCore/include/cctype @@ -0,0 +1,9 @@ +// cerrno standard header + +#ifndef _CSTDCTYPE_ +#define _CSTDCTYPE_ +#include + +#endif /* _CSTDCTYPE_ */ + + diff --git a/SysCore/include/conio.h b/SysCore/include/conio.h new file mode 100644 index 0000000..ecae7b6 --- /dev/null +++ b/SysCore/include/conio.h @@ -0,0 +1,30 @@ +#ifndef __CONIO_H +#define __CONIO_H +#define _ATTRIB 0x0F + +extern byte default_background, default_foreground; +extern char hex[16]; + +extern void itoa (int value, char *string, unsigned int radix); +extern int printf(const char* str, ...); +extern int abs(int x); +extern void graphics_init(); +extern void text_mode_cursor(int x, int y); +extern void set_default_colors(byte back, byte fore); +extern void clrscr(); +extern void scroll(int n); +extern void prev_line(); +extern void next_line(); +extern void putc_pos_font(int x, int y, char c, byte back, byte fore); +extern void putc_pos(int x, int y, char c); +extern void putc_font(char c, byte back, byte fore); +extern void putc(char c); +extern void puts_pos_font(int x, int y, const char *str, byte back, byte fore); +extern void puts_pos(int x, int y, const char *str); +extern void puts(const char *str); +extern void puts_font(const char *str, byte back, byte fore); +extern void put_hex(unsigned int alpha); +extern void put_hex_pos(int x, int y, unsigned int alpha); +extern void put_bin (int x, int y, byte xz); + +#endif \ No newline at end of file diff --git a/SysCore/include/crtdefs.h b/SysCore/include/crtdefs.h new file mode 100644 index 0000000..42c63aa --- /dev/null +++ b/SysCore/include/crtdefs.h @@ -0,0 +1,50 @@ +#ifndef _CRTDEFS_H +#define _CRTDEFS_H + +/****************************** + * crtdefs.h * + * - basic definitions * + ******************************/ + +#if !defined (CRT_EXPORTS) && !defined (CRT_IMPORTS) +#define CRT_EXPORTS +#endif + +#undef far +#undef near +#undef pascal + +#define far +#define near + +#ifdef _WIN32 +#if (!defined(_MAC)) && ((_MSC_VER >= 800) || defined(_STDCALL_SUPPORTED)) +#define pascal __stdcall +#else +#define pascal +#endif +#endif + +#ifdef _MAC +#ifndef _CRTLIB +#define _CRTLIB __cdecl +#endif +#ifdef _68K_ +#ifndef __pascal +#define __pascal +#endif +#endif +#elif defined( _WIN32) +#if (_MSC_VER >= 800) || defined(_STDCALL_SUPPORTED) +#ifndef _CRTLIB +#define _CRTLIB __stdcall +#endif +#else +#ifndef _CRTLIB +#define _CRTLIB +#endif +#endif +#endif + + +#endif diff --git a/SysCore/include/cstdarg b/SysCore/include/cstdarg new file mode 100644 index 0000000..37ccae7 --- /dev/null +++ b/SysCore/include/cstdarg @@ -0,0 +1,7 @@ +// cerrno standard header + +#ifndef _CSTDARG_ +#define _CSTDARG_ +#include + +#endif /* _CSTDARG_ */ diff --git a/SysCore/include/cstdint b/SysCore/include/cstdint new file mode 100644 index 0000000..7629317 --- /dev/null +++ b/SysCore/include/cstdint @@ -0,0 +1,9 @@ +// cerrno standard header + +#ifndef _CSTDINT_ +#define _CSTDINT_ +#include + +#endif /* _CSTDINT_ */ + + diff --git a/SysCore/include/cstring b/SysCore/include/cstring new file mode 100644 index 0000000..beb9135 --- /dev/null +++ b/SysCore/include/cstring @@ -0,0 +1,9 @@ +// cstring standard header + +#ifndef _CSTDSTRING_ +#define _CSTDSTRING_ +#include + +#endif /* _CSTDINT_ */ + + diff --git a/SysCore/include/ctype.h b/SysCore/include/ctype.h new file mode 100644 index 0000000..23beb48 --- /dev/null +++ b/SysCore/include/ctype.h @@ -0,0 +1,55 @@ +#ifndef __CTYPE_H +#define __CTYPE_H + +/****************************** + * ctype.h * + * - character macros * + ******************************/ + +#ifdef _MSC_VER +// Get rid of conversion warnings +#pragma warning (disable:4244) +#endif + +#ifdef __cplusplus +extern "C" +{ +#endif + +extern char _ctype[]; + +/* Constants */ + +#define CT_UP 0x01 /* upper case */ +#define CT_LOW 0x02 /* lower case */ +#define CT_DIG 0x04 /* digit */ +#define CT_CTL 0x08 /* control */ +#define CT_PUN 0x10 /* punctuation */ +#define CT_WHT 0x20 /* white space (space/cr/lf/tab) */ +#define CT_HEX 0x40 /* hex digit */ +#define CT_SP 0x80 /* hard space (0x20) */ + +/* Basic macros */ + +#define isalnum(c) ((_ctype + 1)[(unsigned)(c)] & (CT_UP | CT_LOW | CT_DIG)) +#define isalpha(c) ((_ctype + 1)[(unsigned)(c)] & (CT_UP | CT_LOW)) +#define iscntrl(c) ((_ctype + 1)[(unsigned)(c)] & (CT_CTL)) +#define isdigit(c) ((_ctype + 1)[(unsigned)(c)] & (CT_DIG)) +#define isgraph(c) ((_ctype + 1)[(unsigned)(c)] & (CT_PUN | CT_UP | CT_LOW | CT_DIG)) +#define islower(c) ((_ctype + 1)[(unsigned)(c)] & (CT_LOW)) +#define isprint(c) ((_ctype + 1)[(unsigned)(c)] & (CT_PUN | CT_UP | CT_LOW | CT_DIG | CT_SP)) +#define ispunct(c) ((_ctype + 1)[(unsigned)(c)] & (CT_PUN)) +#define isspace(c) ((_ctype + 1)[(unsigned)(c)] & (CT_WHT)) +#define isupper(c) ((_ctype + 1)[(unsigned)(c)] & (CT_UP)) +#define isxdigit(c) ((_ctype + 1)[(unsigned)(c)] & (CT_DIG | CT_HEX)) +#define isascii(c) ((unsigned)(c) <= 0x7F) +#define toascii(c) ((unsigned)(c) & 0x7F) +#define tolower(c) (isupper(c) ? c + 'a' - 'A' : c) +#define toupper(c) (islower(c) ? c + 'A' - 'a' : c) + +#ifdef __cplusplus +} +#endif + + +#endif diff --git a/SysCore/include/hal.h b/SysCore/include/hal.h new file mode 100644 index 0000000..60ac986 --- /dev/null +++ b/SysCore/include/hal.h @@ -0,0 +1,180 @@ +#ifndef _HAL_H +#define _HAL_H + +#include +#include +#define far +#define near + +#define i86_start_interrupts() __asm__ __volatile__ ("sti"); +#define i86_clear_interrupts() __asm__ __volatile__ ("cli"); + +extern volatile TIME _internal_clock; + +// initialize hardware abstraction layer +extern void i86_hal_initialize (); + +// shutdown hardware abstraction layer +extern int i86_hal_shutdown (); + +//! notifies hal interrupt is done +//extern void interruptdone (unsigned int intno); + +//! output sound to speaker +extern void sound (unsigned frequency); + +//! read byte from device using port mapped io +//extern unsigned char inportb (unsigned short _port); + +//! write byte to device through port mapped io +//extern void outportb (unsigned short _port, unsigned char _data); + +//! sets new interrupt vector +//extern void setvect (int intno, void ( far &vect) ( ) ); + +//! returns current interrupt vector +//extern void ( far * getvect (int intno)) ( ); + +//! returns cpu vender +extern const char* get_cpu_vender (); + +extern void reboot(); + + +/********************************************************************** + * KEYBOARD STUFF * + **********************************************************************/ +#define KB_KEY_LSHIFT 0x81 // 1000 0001 +#define KB_KEY_RSHIFT 0X82 // 1000 0010 +#define KB_KEY_LALT 0X84 // 1000 0100 +#define KB_KEY_RALT 0x88 // 1000 1000 +#define KB_KEY_LCTRL 0x90 // 1001 0000 +#define KB_KEY_RCTRL 0xA0 // 1010 0000 +#define KB_KEY_FSHIFT 0xC0 // 1100 0000 +extern volatile byte kb_modifier_status; + +#define KB_PREFIX_GRAY 0x01 // Gray +#define KB_PREFIX_BREAK 0x02 // Break code +#define KB_PREFIX_PAUSE 0x04 // Pause/break key +#define KB_PREFIX_PAUSE1 0x08 // Recieved first byte from pause/break +extern volatile byte kb_prefix; + +#define KB_KEY_SCROLL 0xF1 // 1111 0001 +#define KB_KEY_NUM 0xF2 // 1111 0010 +#define KB_KEY_CAPS 0xF4 // 1111 0100 +extern volatile byte kb_lights_status; + +extern byte kb_scancode_set; +#define KB_KEY_PAUSE 0x00 +#define KB_KEY_F9 0x01 +#define KB_KEY_F7 0x02 +#define KB_KEY_F5 0X03 +#define KB_KEY_F3 0x04 +#define KB_KEY_F1 0x05 +#define KB_KEY_F2 0x06 +#define KB_KEY_F12 0x07 +#define KB_KEY_PRINTSCRN 0x08 +#define KB_KEY_F10 0x09 +#define KB_KEY_F8 0x0A +#define KB_KEY_F6 0x0B +#define KB_KEY_F4 0x0C +#define KB_KEY_TAB 0x0D +#define KB_KEY_TILDA 0x0E +#define KB_KEY_Q 0x15 +#define KB_KEY_1 0x16 +#define KB_KEY_Z 0x1A +#define KB_KEY_S 0x1B +#define KB_KEY_A 0x1C +#define KB_KEY_W 0x1D +#define KB_KEY_2 0x1E +#define KB_KEY_LWIN 0x1F +#define KB_KEY_C 0x21 +#define KB_KEY_X 0x22 +#define KB_KEY_D 0x23 +#define KB_KEY_E 0x24 +#define KB_KEY_4 0x25 +#define KB_KEY_3 0x26 +#define KB_KEY_RWIN 0x27 +#define KB_KEY_SPACE 0x29 +#define KB_KEY_V 0x2A +#define KB_KEY_F 0x2B +#define KB_KEY_T 0x2C +#define KB_KEY_R 0x2D +#define KB_KEY_5 0x2E +#define KB_KEY_MENU 0x2F +#define KB_KEY_N 0x31 +#define KB_KEY_B 0x32 +#define KB_KEY_H 0x33 +#define KB_KEY_G 0x34 +#define KB_KEY_Y 0x35 +#define KB_KEY_6 0x36 +#define KB_KEY_M 0x3A +#define KB_KEY_J 0x3B +#define KB_KEY_U 0x3C +#define KB_KEY_7 0x3D +#define KB_KEY_8 0x3E +#define KB_KEY_COMMA 0x41 +#define KB_KEY_K 0x42 +#define KB_KEY_I 0x43 +#define KB_KEY_O 0x44 +#define KB_KEY_0 0x45 +#define KB_KEY_9 0x46 +#define KB_KEY_PERIOD 0x49 +#define KB_KEY_SLASH 0x4A +#define KB_KEY_L 0x4B +#define KB_KEY_SEMICOLON 0x4C +#define KB_KEY_P 0x4D +#define KB_KEY_DASH 0x4E +#define KB_KEY_APOSTROPHE 0x52 +#define KB_KEY_LBRACKET 0x54 +#define KB_KEY_EQUAL 0x55 +#define KB_KEY_NUMPAD_ENTER 0x59 +#define KB_KEY_ENTER 0x5A +#define KB_KEY_RBRACKET 0x5B +#define KB_KEY_BACKSLASH 0x5D +#define KB_KEY_END 0x5E +#define KB_KEY_LEFT 0x5F +#define KB_KEY_HOME 0x60 +#define KB_KEY_INSERT 0x61 +#define KB_KEY_DELETE 0x62 +#define KB_KEY_DOWN 0x63 +#define KB_KEY_RIGHT 0x64 +#define KB_KEY_UP 0x65 +#define KB_KEY_BACKSPACE 0x66 +#define KB_KEY_PGDOWN 0x67 +#define KB_KEY_PGUP 0x68 +#define KB_KEY_NUMPAD_1 0x69 +#define KB_KEY_NUMPAD_SLASH 0x6A +#define KB_KEY_NUMPAD_4 0x6B +#define KB_KEY_NUMPAD_7 0x6C +#define KB_KEY_NUMPAD_0 0x70 +#define KB_KEY_NUMPAD_COLON 0x71 +#define KB_KEY_NUMPAD_2 0x72 +#define KB_KEY_NUMPAD_5 0x73 +#define KB_KEY_NUMPAD_6 0x74 +#define KB_KEY_NUMPAD_8 0x75 +#define KB_KEY_ESC 0x76 +#define KB_KEY_F11 0x78 +#define KB_KEY_NUMPAD_PLUS 0x79 +#define KB_KEY_NUMPAD_3 0x7A +#define KB_KEY_NUMPAD_MINUS 0x7B +#define KB_KEY_NUMPAD_ASTERISK 0x7C +#define KB_KEY_NUMPAD_9 0x7D + + +typedef struct { + byte status; + byte lights; + byte scancode; + byte character; +} kb_key; + + +extern char getch(); +extern kb_key getkey(); +extern char scancode_to_ascii(byte scancode, byte status); +extern byte get_key_status(byte scancode); +extern void kb_set_repeat(float rate, int delay); +extern void kb_set_LEDs(byte status); + +#endif \ No newline at end of file diff --git a/SysCore/include/regs.h b/SysCore/include/regs.h new file mode 100644 index 0000000..492ee1f --- /dev/null +++ b/SysCore/include/regs.h @@ -0,0 +1,100 @@ +#ifndef _REGS_H_INCLUDED +#define _REGS_H_INCLUDED +//**************************************************************************** +//** +//** regs.h +//** +//** processor register structures and declarations. This interface abstracts +//** register names behind a common, portable interface +//** +//**************************************************************************** + +//============================================================================ +// INTERFACE REQUIRED HEADERS +//============================================================================ + +#include + +//============================================================================ +// INTERFACE DEFINITIONS / ENUMERATIONS / SIMPLE TYPEDEFS +//============================================================================ +//============================================================================ +// INTERFACE CLASS PROTOTYPES / EXTERNAL CLASS REFERENCES +//============================================================================ +//============================================================================ +// INTERFACE STRUCTURES / UTILITY CLASSES +//============================================================================ + +//! 32 bit registers +typedef struct { + uint32_t eax, ebx, ecx, edx, esi, edi, ebp, esp, eflags; + uint8_t cflag; +} _R32BIT; + +//! 16 bit registers +typedef struct { + uint16_t ax, bx, cx, dx, si, di, bp, sp, es, cs, ss, ds, flags; + uint8_t cflag; +} _R16BIT ; + +//! 16 bit registers expressed in 32 bit registers +typedef struct { + uint16_t ax, axh, bx, bxh, cx, cxh, dx, dxh; + uint16_t si, di, bp, sp, es, cs, ss, ds, flags; + uint8_t cflags; +} _R16BIT32 ; + +//! 8 bit registers +typedef struct { + uint8_t al, ah, bl, bh, cl, ch, dl, dh; +} _R8BIT; + +//! 8 bit registers expressed in 32 bit registers +typedef struct { + uint8_t al, ah; uint16_t axh; + uint8_t bl, bh; uint16_t bxh; + uint8_t cl, ch; uint16_t cxh; + uint8_t dl, dh; uint16_t dxh; +} _R8BIT32; + +//! 8 and 16 bit registers union +typedef union { + _R16BIT x; + _R8BIT h; +}_INTR16; + +//! 32 bit, 16 bit and 8 bit registers union +typedef union { + _R32BIT x; + _R16BIT32 l; + _R8BIT32 h; +} _INTR32; + +/* This defines what the stack looks like after an ISR was running */ +typedef struct +{ + unsigned int gs, fs, es, ds; /* pushed the segs last */ + unsigned int edi, esi, ebp, esp, ebx, edx, ecx, eax; /* pushed by 'pusha' */ + unsigned int int_no, err_code; /* our 'push byte #' and ecodes do this */ + unsigned int eip, cs, eflags, useresp, ss; /* pushed by the processor automatically */ +} ISR_stack_regs; + + +//============================================================================ +// INTERFACE DATA DECLARATIONS +//============================================================================ +//============================================================================ +// INTERFACE FUNCTION PROTOTYPES +//============================================================================ +//============================================================================ +// INTERFACE OBJECT CLASS DEFINITIONS +//============================================================================ +//============================================================================ +// INTERFACE TRAILING HEADERS +//============================================================================ +//**************************************************************************** +//** +//** END regs.h +//** +//**************************************************************************** +#endif diff --git a/SysCore/include/size_t.h b/SysCore/include/size_t.h new file mode 100644 index 0000000..7e4b1cc --- /dev/null +++ b/SysCore/include/size_t.h @@ -0,0 +1,23 @@ +#ifndef __SIZE_T_H +#define __SIZE_T_H + +/************************************ + * size_t.h * + * - Standard C/C++ size_t type * + ************************************/ + +#ifdef __cplusplus +extern "C" +{ +#endif + +/* standard size_t type */ +typedef unsigned size_t; + +#ifdef __cplusplus +} +#endif + + + +#endif diff --git a/SysCore/include/stdarg.h b/SysCore/include/stdarg.h new file mode 100644 index 0000000..257f25b --- /dev/null +++ b/SysCore/include/stdarg.h @@ -0,0 +1,46 @@ +#ifndef __STDARG_H +#define __STDARG_H + + +/****************************** + * [filename] * + * - [description] * + ******************************/ + +// INTERFACE REQUIRED HEADERS +#include + + +// INTERFACE DEFINITIONS / ENUMERATIONS / SIMPLE TYPEDEFS +#ifdef __cplusplus +extern "C" +{ +#endif + +/* width of stack == width of int */ +#define STACKITEM int + +/* round up width of objects pushed on stack. The expression before the +& ensures that we get 0 for objects of size 0. */ +#define VA_SIZE(TYPE) \ + ((sizeof(TYPE) + sizeof(STACKITEM) - 1) \ + & ~(sizeof(STACKITEM) - 1)) + +/* &(LASTARG) points to the LEFTMOST argument of the function call +(before the ...) */ +#define va_start(AP, LASTARG) \ + (AP=((va_list)&(LASTARG) + VA_SIZE(LASTARG))) + +/* nothing for va_end */ +#define va_end(AP) + +#define va_arg(AP, TYPE) \ + (AP += VA_SIZE(TYPE), *((TYPE *)(AP - VA_SIZE(TYPE)))) + +#ifdef __cplusplus +} +#endif + + + +#endif diff --git a/SysCore/include/stdint.h b/SysCore/include/stdint.h new file mode 100644 index 0000000..3338763 --- /dev/null +++ b/SysCore/include/stdint.h @@ -0,0 +1,163 @@ + +#ifndef _STDINT_H +#define _STDINT_H + +#define __need_wint_t +#define __need_wchar_t + + +/*************************************** + * stdint.h * + * - Standard C++ integral types * + ***************************************/ + +/* 7.18.1.1 Exact-width integer types */ +typedef signed char int8_t; +typedef unsigned char uint8_t; +typedef short int16_t; +typedef unsigned short uint16_t; +typedef int int32_t; +typedef unsigned uint32_t; +typedef long long int64_t; +typedef unsigned long long uint64_t; + +/* 7.18.1.2 Minimum-width integer types */ +typedef signed char int_least8_t; +typedef unsigned char uint_least8_t; +typedef short int_least16_t; +typedef unsigned short uint_least16_t; +typedef int int_least32_t; +typedef unsigned uint_least32_t; +typedef long long int_least64_t; +typedef unsigned long long uint_least64_t; + +/* 7.18.1.3 Fastest minimum-width integer types + * Not actually guaranteed to be fastest for all purposes + * Here we use the exact-width types for 8 and 16-bit ints. + */ +typedef char int_fast8_t; +typedef unsigned char uint_fast8_t; +typedef short int_fast16_t; +typedef unsigned short uint_fast16_t; +typedef int int_fast32_t; +typedef unsigned int uint_fast32_t; +typedef long long int_fast64_t; +typedef unsigned long long uint_fast64_t; + +/* 7.18.1.4 Integer types capable of holding object pointers */ +typedef int intptr_t; +typedef unsigned uintptr_t; + +/* 7.18.1.5 Greatest-width integer types */ +typedef long long intmax_t; +typedef unsigned long long uintmax_t; + +/* 7.18.2 Limits of specified-width integer types */ +#if !defined ( __cplusplus) || defined (__STDC_LIMIT_MACROS) + +/* 7.18.2.1 Limits of exact-width integer types */ +#define INT8_MIN (-128) +#define INT16_MIN (-32768) +#define INT32_MIN (-2147483647 - 1) +#define INT64_MIN (-9223372036854775807LL - 1) + +#define INT8_MAX 127 +#define INT16_MAX 32767 +#define INT32_MAX 2147483647 +#define INT64_MAX 9223372036854775807LL + +#define UINT8_MAX 0xff /* 255U */ +#define UINT16_MAX 0xffff /* 65535U */ +#define UINT32_MAX 0xffffffff /* 4294967295U */ +#define UINT64_MAX 0xffffffffffffffffULL /* 18446744073709551615ULL */ + +/* 7.18.2.2 Limits of minimum-width integer types */ +#define INT_LEAST8_MIN INT8_MIN +#define INT_LEAST16_MIN INT16_MIN +#define INT_LEAST32_MIN INT32_MIN +#define INT_LEAST64_MIN INT64_MIN + +#define INT_LEAST8_MAX INT8_MAX +#define INT_LEAST16_MAX INT16_MAX +#define INT_LEAST32_MAX INT32_MAX +#define INT_LEAST64_MAX INT64_MAX + +#define UINT_LEAST8_MAX UINT8_MAX +#define UINT_LEAST16_MAX UINT16_MAX +#define UINT_LEAST32_MAX UINT32_MAX +#define UINT_LEAST64_MAX UINT64_MAX + +/* 7.18.2.3 Limits of fastest minimum-width integer types */ +#define INT_FAST8_MIN INT8_MIN +#define INT_FAST16_MIN INT16_MIN +#define INT_FAST32_MIN INT32_MIN +#define INT_FAST64_MIN INT64_MIN + +#define INT_FAST8_MAX INT8_MAX +#define INT_FAST16_MAX INT16_MAX +#define INT_FAST32_MAX INT32_MAX +#define INT_FAST64_MAX INT64_MAX + +#define UINT_FAST8_MAX UINT8_MAX +#define UINT_FAST16_MAX UINT16_MAX +#define UINT_FAST32_MAX UINT32_MAX +#define UINT_FAST64_MAX UINT64_MAX + +/* 7.18.2.4 Limits of integer types capable of holding + object pointers */ +#define INTPTR_MIN INT32_MIN +#define INTPTR_MAX INT32_MAX +#define UINTPTR_MAX UINT32_MAX + +/* 7.18.2.5 Limits of greatest-width integer types */ +#define INTMAX_MIN INT64_MIN +#define INTMAX_MAX INT64_MAX +#define UINTMAX_MAX UINT64_MAX + +/* 7.18.3 Limits of other integer types */ +#define PTRDIFF_MIN INT32_MIN +#define PTRDIFF_MAX INT32_MAX + +#define SIG_ATOMIC_MIN INT32_MIN +#define SIG_ATOMIC_MAX INT32_MAX + +#define SIZE_MAX UINT32_MAX + +#ifndef WCHAR_MIN /* also in wchar.h */ +#define WCHAR_MIN 0 +#define WCHAR_MAX ((wchar_t)-1) /* UINT16_MAX */ +#endif + +/* + * wint_t is unsigned short for compatibility with MS runtime + */ +#define WINT_MIN 0 +#define WINT_MAX ((wint_t)-1) /* UINT16_MAX */ + +#endif /* !defined ( __cplusplus) || defined __STDC_LIMIT_MACROS */ + + +/* 7.18.4 Macros for integer constants */ +#if !defined ( __cplusplus) || defined (__STDC_CONSTANT_MACROS) + +/* 7.18.4.1 Macros for minimum-width integer constants */ + +#define INT8_C(val) ((int8_t) + (val)) +#define UINT8_C(val) ((uint8_t) + (val##U)) +#define INT16_C(val) ((int16_t) + (val)) +#define UINT16_C(val) ((uint16_t) + (val##U)) + +#define INT32_C(val) val##L +#define UINT32_C(val) val##UL +#define INT64_C(val) val##LL +#define UINT64_C(val) val##ULL + +/* 7.18.4.2 Macros for greatest-width integer constants */ +#define INTMAX_C(val) INT64_C(val) +#define UINTMAX_C(val) UINT64_C(val) + +#endif /* !defined ( __cplusplus) || defined __STDC_CONSTANT_MACROS */ + + + +#endif diff --git a/SysCore/include/string.h b/SysCore/include/string.h new file mode 100644 index 0000000..54a553f --- /dev/null +++ b/SysCore/include/string.h @@ -0,0 +1,46 @@ +#ifndef _STRING_H +#define _STRING_H +//**************************************************************************** +//** +//** [string.h] +//** - Standard C String routines +//** +//**************************************************************************** +//============================================================================ +// INTERFACE REQUIRED HEADERS +//============================================================================ + +#include + +//============================================================================ +// INTERFACE DEFINITIONS / ENUMERATIONS / SIMPLE TYPEDEFS +//============================================================================ +//============================================================================ +// INTERFACE CLASS PROTOTYPES / EXTERNAL CLASS REFERENCES +//============================================================================ +//============================================================================ +// INTERFACE STRUCTURES / UTILITY CLASSES +//============================================================================ +//============================================================================ +// INTERFACE DATA DECLARATIONS +//============================================================================ +//============================================================================ +// INTERFACE FUNCTION PROTOTYPES +//============================================================================ + +extern size_t strlen (const char *str); +extern int strcmp(const char *pStr1, const char *pStr2); + +//============================================================================ +// INTERFACE OBJECT CLASS DEFINITIONS +//============================================================================ +//============================================================================ +// INTERFACE TRAILING HEADERS +//============================================================================ +//**************************************************************************** +//** +//** END [string.h] +//** +//**************************************************************************** + +#endif diff --git a/SysCore/include/sys/declarat.h b/SysCore/include/sys/declarat.h new file mode 100644 index 0000000..8b9c97f --- /dev/null +++ b/SysCore/include/sys/declarat.h @@ -0,0 +1,21 @@ +#ifndef __DECLARAT_H +#define __DECLARAT_H + +// Data type declarations +typedef unsigned char byte; +typedef unsigned short word; +typedef unsigned int dword; + +// Functions +void system_init(); + +void isrs_install(); + +void irq_install_handler(int irq, void (*handler)(ISR_stack_regs *r)); +void irq_uninstall_handler(int irq); +void irq_install(); +void kb_handler(ISR_stack_regs *r); +void reboot(); +void kb_waitin(); + +#endif \ No newline at end of file diff --git a/SysCore/include/system.h b/SysCore/include/system.h new file mode 100644 index 0000000..106fdf6 --- /dev/null +++ b/SysCore/include/system.h @@ -0,0 +1,40 @@ +/******************************************************************* + * system.c - Basic system functions and variables declaration * + *******************************************************************/ +#ifndef __SYSTEM_H +#define __SYSTEM_H +#include + +#define true 1 +#define false 0 + +// Data type declarations +typedef unsigned char byte; +typedef unsigned short word; +typedef unsigned int dword; + +extern byte *TextVideoRam; +extern volatile int cursor_x, cursor_y; +extern int current_mode_width; +extern int current_mode_height; + +extern void *memcpy(void *dest, const void *src, int count); +extern void *memset(void *dest, char val, int count); +extern unsigned short *memsetw(unsigned short *dest, unsigned short val, int count); + +extern byte inportb (word _port); +extern byte inb (word _port); + +static inline void outportb (word _port, byte _data) { + __asm__ __volatile__ ("outb %1, %0" : : "dN" (_port), "a" (_data)); +} +static inline void outb (word _port, byte _data) { + __asm__ __volatile__ ("outb %1, %0" : : "dN" (_port), "a" (_data)); +} + +static inline void iowait() { + asm volatile ("outb %al, $0x80"); +} + + +#endif \ No newline at end of file diff --git a/SysCore/include/time.h b/SysCore/include/time.h new file mode 100644 index 0000000..33eecaa --- /dev/null +++ b/SysCore/include/time.h @@ -0,0 +1,25 @@ +#ifndef __TIME_C +#define __TIME_C + +extern const char* clock_months[13]; +extern const char* clock_weekdays[8]; +extern byte clock_months_len[13]; + +typedef struct { + byte seconds; + byte minutes; + byte hours; + byte weekday; + byte day; + byte month; + byte year; + byte century; + byte am_pm; + +} TIME; + +extern void _CLOCK_INC(TIME *tim); + +//extern char* asctime (TIME time); + +#endif \ No newline at end of file diff --git a/SysCore/include/va_list.h b/SysCore/include/va_list.h new file mode 100644 index 0000000..2eaabc8 --- /dev/null +++ b/SysCore/include/va_list.h @@ -0,0 +1,52 @@ +#ifndef __VA_LIST_H +#define __VA_LIST_H +//**************************************************************************** +//** +//** va_list.h +//** - varable length parameter definition +//** +//**************************************************************************** +//============================================================================ +// INTERFACE REQUIRED HEADERS +//============================================================================ +//============================================================================ +// INTERFACE DEFINITIONS / ENUMERATIONS / SIMPLE TYPEDEFS +//============================================================================ + +#ifdef __cplusplus +extern "C" +{ +#endif + +/* va list parameter list */ +typedef unsigned char *va_list; + +#ifdef __cplusplus +} +#endif + +//============================================================================ +// INTERFACE CLASS PROTOTYPES / EXTERNAL CLASS REFERENCES +//============================================================================ +//============================================================================ +// INTERFACE STRUCTURES / UTILITY CLASSES +//============================================================================ +//============================================================================ +// INTERFACE DATA DECLARATIONS +//============================================================================ +//============================================================================ +// INTERFACE FUNCTION PROTOTYPES +//============================================================================ +//============================================================================ +// INTERFACE OBJECT CLASS DEFINITIONS +//============================================================================ +//============================================================================ +// INTERFACE TRAILING HEADERS +//============================================================================ +//**************************************************************************** +//** +//** END va_list.h +//** +//**************************************************************************** + +#endif diff --git a/SysCore/lib/compile.bat b/SysCore/lib/compile.bat new file mode 100644 index 0000000..91ab1d4 --- /dev/null +++ b/SysCore/lib/compile.bat @@ -0,0 +1,40 @@ +@echo off + +rem NASM and DJGPP executable paths: +set nasm_path=C:\nasm +set djgpp_path=C:\DJGPP\bin +set objpath=..\objects +set incpath=../include + +@echo Building Kernel Standard Libraries... + +del %objpath%\system.o +del %objpath%\string.o +del %objpath%\conio.o +del %objpath%\time.o + +goto build +:error + @echo. + @echo There have been build errors. Building halted. + @pause + exit + +:build + @echo * Compiling SYSTEM.C ... + %djgpp_path%\gcc.exe -Wall -O -fstrength-reduce -fomit-frame-pointer -nostdinc -fno-builtin -I%incpath% -c -o %objpath%/system.o system.c + + @echo * Compiling STRING.C ... + %djgpp_path%\gcc.exe -Wall -O -fstrength-reduce -fomit-frame-pointer -nostdinc -fno-builtin -I%incpath% -c -o %objpath%/string.o string.c + + @echo * Compiling CONIO.C ... + %djgpp_path%\gcc.exe -Wall -O -fstrength-reduce -fomit-frame-pointer -nostdinc -fno-builtin -I%incpath% -c -o %objpath%/conio.o conio.c + + @echo * Compiling TIME.C ... + %djgpp_path%\gcc.exe -Wall -O -fstrength-reduce -fomit-frame-pointer -nostdinc -fno-builtin -I%incpath% -c -o %objpath%/time.o time.c + +:check + if not exist %objpath%\system.o goto error + if not exist %objpath%\string.o goto error + if not exist %objpath%\conio.o goto error + if not exist %objpath%\time.o goto error diff --git a/kernel/include/conio.h b/SysCore/lib/conio.c similarity index 51% rename from kernel/include/conio.h rename to SysCore/lib/conio.c index b2718b1..0864238 100644 --- a/kernel/include/conio.h +++ b/SysCore/lib/conio.c @@ -1,12 +1,32 @@ +#include +#include +#include #include - -#ifndef __CONIO_H -#define __CONIO_H -#define _ATTRIB 0x0F +#include byte default_background, default_foreground; char hex[] = "0123456789ABCDEF"; +const static char base_chars[] = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"; + +int abs(int x) +{ + return (x>0) ? (x) : (x*-1); +} + +void graphics_init() +{ + // Detect if color/monochrome screen + char c = (*(volatile unsigned short*)0x410)&0x30; + if (c==0x30) TextVideoRam = (byte *)0xb0000; + else TextVideoRam = (byte *)0xb8000; + + // Reset cursor, use 80x25 text video mode + current_mode_width = 80; + current_mode_height = 25; + cursor_x = cursor_y = 0; + +} // Change cursor position @@ -101,12 +121,55 @@ void putc(char c) if (cursor_x >= current_mode_width) next_line(); if (c == '\n') {next_line(); return;}; + if (c == '\r') {cursor_x = 0; return; }; TextVideoRam[2*(cursor_y*current_mode_width+cursor_x)] = c; cursor_x++; } +// Unsigned INT to ASCII +void uitoa (unsigned int value, char *string, int radix) +{ + if (radix == 1 || radix>36) return; + + // Calculate how much space needed for number + int len, temp = abs(value); + for (len = 0; temp > 0; len++) temp/=radix; + if (len == 0) len = 1; + + string[len] = 0; + for (len--; len >=0; len-- ) { + string[len] = base_chars[value%radix]; + value/=radix; + } +} + +// Signed INT to ASCII +void itoa (int value, char *string, unsigned int radix) +{ + if (radix < 2 || radix>36) return; + + // Calculate how much space needed for number + int len, temp = abs(value); + for (len = 0; temp > 0; len++) temp/=radix; + if (len == 0) len = 1; + + //Add a space for '-' + if (value<0) { + len++; string[0] = '-'; + value = abs(value); + } + + string[len] = 0; + for (len--; len >0; len-- ) { + string[len] = base_chars[value%radix]; + value/=radix; + } +} + + + // Put string on screen in specified position; can use different font colors -void puts_pos_font(int x, int y, char *str, byte back, byte fore) +void puts_pos_font(int x, int y, const char *str, byte back, byte fore) { int i; for (i = 0; str[i] != 0; i++) @@ -115,20 +178,20 @@ void puts_pos_font(int x, int y, char *str, byte back, byte fore) } // Put string on screen in specified position; use default font colors -void puts_pos(int x, int y, char *str) +void puts_pos(int x, int y, const char *str) { int i; for (i = 0; str[i] != 0; i++) putc_pos(x+i, y, str[i]); } -void puts(char *str) +void puts(const char *str) { int i; for (i = 0; str[i] != 0; i++) putc(str[i]); } -void puts_font(char *str, byte back, byte fore) +void puts_font(const char *str, byte back, byte fore) { int i; for (i = 0; str[i] != 0; i++) @@ -167,6 +230,55 @@ void put_bin (int x, int y, byte xz) } puts_pos (x, y, arr); } + + +int printf(const char* str, ...) +{ + if (!str) return 0; - -#endif \ No newline at end of file + va_list args; + va_start (args, str); + size_t i, len = strlen(str); + for (i = 0; i < len; i++) + switch (str[i]) { + case '%': + switch (str[i+1]) { + // Character + case 'c': {char c = va_arg (args, char); + putc(c); i++; break;} + // String + case 's': {int* c = (int*) va_arg (args, char*); + puts((const char*)c); i++; break;} + // Integers + case 'd': + case 'i': {int c = va_arg(args, int); + char temp[32]; + itoa(c, temp, 10); + puts(temp); + i++; break;} + // Integers - hex + case 'X': + case 'x': {int c = va_arg(args, int); + char temp[32]; + uitoa(c, temp, 16); + puts(temp); + i++; break;} + + // Integers - unsigned + case 'u': { int c = va_arg(args, unsigned int); + char temp[32]; + uitoa(c, temp, 10); + puts(temp); + i++; break; + } + + default: va_end(args); return 1; + }; + break; + default: putc(str[i]); break; + } + + va_end(args); + return i; +} + diff --git a/SysCore/lib/string.c b/SysCore/lib/string.c new file mode 100644 index 0000000..937ec2c --- /dev/null +++ b/SysCore/lib/string.c @@ -0,0 +1,23 @@ +#include + +size_t strlen (const char *str) +{ + size_t i; + for (i = 0; *str!=0; str++) i++; + return i; +} + +int strcmp(const char *pStr1, const char *pStr2) +{ + char c1, c2; + int v; + + do { + c1 = *pStr1++; + c2 = *pStr2++; + /* the casts are necessary when pStr1 is shorter & char is signed */ + v = (unsigned int)c1 - (unsigned int)c2; + } while ((v == 0) && (c1 != '\0')); + + return v; +} diff --git a/SysCore/lib/system.c b/SysCore/lib/system.c new file mode 100644 index 0000000..7b13fee --- /dev/null +++ b/SysCore/lib/system.c @@ -0,0 +1,44 @@ +/****************************************************************** + * system.c - Basic system functions * + ******************************************************************/ + +#include + +byte *TextVideoRam; +volatile int cursor_x, cursor_y; +int current_mode_width; +int current_mode_height; + +void *memcpy(void *dest, const void *src, int count) +{ + const char *sp = (const char *)src; + char *dp = (char *)dest; + for(; count != 0; count--) *dp++ = *sp++; + return dest; +} + +void *memset(void *dest, char val, int count) +{ + char *temp = (char *)dest; + for( ; count != 0; count--) *temp++ = val; + return dest; +} + +unsigned short *memsetw(unsigned short *dest, unsigned short val, int count) +{ + unsigned short *temp = (unsigned short *)dest; + for( ; count != 0; count--) *temp++ = val; + return dest; +} + + +byte inportb (word _port) { + byte rv; + __asm__ __volatile__ ("inb %1, %0" : "=a" (rv) : "dN" (_port)); + return rv; +} +byte inb (word _port) { + byte rv; + __asm__ __volatile__ ("inb %1, %0" : "=a" (rv) : "dN" (_port)); + return rv; +} \ No newline at end of file diff --git a/SysCore/lib/time.c b/SysCore/lib/time.c new file mode 100644 index 0000000..d88c147 --- /dev/null +++ b/SysCore/lib/time.c @@ -0,0 +1,80 @@ +#include +#include + +const char* clock_months[] = {0, + "January", "February", "March", "April", "May", "June", + "July", "August", "September", "October", "November", "December"}; +const char* clock_weekdays[] = {0, + "Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"}; + +byte clock_months_len[] = { + 0, + 31, // January + 28, // February + 31, // March + 30, // April + 31, // May + 30, // June + 31, // July + 31, // August + 30, // September + 31, // October + 30, // November + 31 // December +}; + +void _CLOCK_INC(TIME *tim) +{ + // New minute + if (++tim->seconds > 59) { + tim->seconds = 0; + // New hour + if (++tim->minutes > 59) { + tim->minutes = 0; + tim->hours++; + if (tim->hours == 12 && tim->am_pm == 1) { // 11:59pm -> 0:00am + tim->hours = 0; tim->am_pm = 0; + // New day + tim->weekday = 1+(tim->weekday%7); + // Leap years + if ((tim->day==28) && (tim->month==2)) { tim->day++; return; } + // New month + if (++tim->day > clock_months_len[tim->month]) { + tim->day = 1; + // New year + if (++tim->month>12) { + tim->month = 1; + // New century + if (++tim->year > 99) { tim->year = 0; tim->century++;} + } + } + } + else if (tim->hours == 12 && tim->am_pm == 0) tim->am_pm = 1; // 11:59am -> 12:00pm + else if (tim->hours == 13 && tim->am_pm == 1) tim->hours = 1; // 12:59pm -> 1:59pm + } + } +} + + +/* ASCTIME Formats: **************************************************************** +* 1 W = weekday, M = month, D = day, H = Hour, M = Minute, S = Second, Y = year) * +* A = AM/PM * +* 2 Use capital letter for one letter/digit; else, use lower * +* * +* Example: asctime (time, "Today is: %W3 %D2 %m") * +* Result: Today is: Mon 22 June * +************************************************************************************/ + +/*char* asctime (TIME time, char* format) +{ + char str[100]; + int l = strlen(format), i; + byte special = 0; + + for (i=0; i +#include +#include +#include +#include +#include +#include "memory/mmngr_ph.h" +#include "shell/shell.c" + +//! format of a memory region +typedef struct { + + uint32_t startLo; + uint32_t startHi; + uint32_t sizeLo; + uint32_t sizeHi; + uint32_t type; + uint32_t acpi_3_0; +} memory_region ; + +//! different memory regions (in memory_region.type) +char* strMemoryTypes[] = { + "", + "Available", //memory_region.type==0 + "Reserved", //memory_region.type==1 + "ACPI Reclaim", //memory_region.type==2 + "ACPI NVS Memory" //memory_region.type==3 +}; + +extern dword _code; +extern dword _data; +extern dword _bss; +extern dword _end; + +void k_init(multiboot_info* bootinfo) +{ + // Start by zero-ing the bss + memset(&_bss, 0, &_end - &_bss); + + // Initialize HAL + i86_hal_initialize(); + + // Initialize Graphics + graphics_init(); + + // cleanup the console screen + set_default_colors (0x07, 0x04); + clrscr(); + + + // Start memory manager + uint32_t memSize = 1024 + bootinfo->m_memoryLo + bootinfo->m_memoryHi*64; + memory_region* memMap = (memory_region*)0x1000; + pmmngr_init (memSize, (uint32_t)&_end); + + unsigned int i; + + for (i=0; (memMap[i].sizeHi != 0 || memMap[i].sizeLo != 0) && i<3; ++i) + if (memMap[i].type==1) pmmngr_init_region (memMap[i].startLo, memMap[i].sizeLo); + +} + +void k_main(uint32_t kernel_size, multiboot_info* bootinfo) +{ + k_init(bootinfo); + apps_osver(); + + shell(); + + for(;;); +} \ No newline at end of file diff --git a/SysCore/makeall.bat b/SysCore/makeall.bat new file mode 100644 index 0000000..92e0b25 --- /dev/null +++ b/SysCore/makeall.bat @@ -0,0 +1,59 @@ +@echo off + +set loader_name=loader +set nasm_path=C:\nasm +set djgpp_path=C:\DJGPP\bin + + +@echo ***************** CTA KERNEL ***************** + +goto KernelEntry + +:error + @echo. + @echo There have been build errors. Building halted. + @pause + exit + +:KernelEntry + del objects\%loader_name%.o + del objects\main.o + + @echo. + @echo Building Kernel entry... + @echo * Compiling kernel loader... + %nasm_path%\nasm.exe -f aout -o ./objects/%loader_name%.o %loader_name%.asm + + @echo * Compiling kernel main... + %djgpp_path%\gcc.exe -Wall -O -fstrength-reduce -fomit-frame-pointer -nostdinc -fno-builtin -I./include -c -o ./objects/main.o main.c + if not exist objects\%loader_name%.o goto error + if not exist objects\main.o goto error + + @echo. + +:KernelSTDLIB + cd lib + rem call compile.bat + cd.. + +:KernelMemoryManager + cd memory + call compile.bat + cd.. + +rem here go other sources: + +rem here go other sources ^ + +:Finish + cd objects + @echo Linking... + del kernel.bin + %djgpp_path%\ld -T link.ld + if not exist kernel.bin goto error + + @echo. + + echo Copying to floppy drive... + copy KERNEL.BIN A:\KERNEL.CTA >nul + cd.. \ No newline at end of file diff --git a/SysCore/makeallh.bat b/SysCore/makeallh.bat new file mode 100644 index 0000000..f00da90 --- /dev/null +++ b/SysCore/makeallh.bat @@ -0,0 +1,66 @@ +@echo off + +set loader_name=loader +set nasm_path=C:\nasm +set djgpp_path=C:\DJGPP\bin + + +@echo ***************** CTA KERNEL ***************** + +goto KernelEntry + +:error + @echo. + @echo There have been build errors. Building halted. + @pause + exit + +:KernelEntry + del objects\%loader_name%.o + del objects\main.o + + @echo. + @echo Building Kernel entry... + @echo * Compiling kernel loader... + %nasm_path%\nasm.exe -f aout -o ./objects/%loader_name%.o %loader_name%.asm + + @echo * Compiling kernel main... + %djgpp_path%\gcc.exe -Wall -O -fstrength-reduce -fomit-frame-pointer -nostdinc -fno-builtin -I./include -c -o ./objects/main.o main.c + if not exist objects\%loader_name%.o goto error + if not exist objects\main.o goto error + + @echo. + +:KernelSTDLIB + cd lib + call compile.bat + @echo. + cd.. + +:KernelMemoryManager + cd memory + call compile.bat + @echo. + cd.. + +:KernelHAL + cd hal + call makeall.bat + cd.. + +rem here go other sources: + +rem here go other sources ^ + +:Finish + cd objects + @echo Linking... + del kernel.bin + %djgpp_path%\ld -T link.ld + if not exist kernel.bin goto error + + @echo. + + echo Copying to floppy drive... + copy KERNEL.BIN A:\KERNEL.CTA >nul + cd.. \ No newline at end of file diff --git a/SysCore/memory/compile.bat b/SysCore/memory/compile.bat new file mode 100644 index 0000000..606c418 --- /dev/null +++ b/SysCore/memory/compile.bat @@ -0,0 +1,28 @@ +@echo off + +rem NASM and DJGPP executable paths: +set nasm_path=C:\nasm +set djgpp_path=C:\DJGPP\bin +set objpath=..\objects +set incpath=../include +goto build + +:error + @echo. + @echo There have been build errors. Building halted. + @pause + exit + +:build + @echo Building Memory Manager... + + del %objpath%\mmngr_cr.o + del %objpath%\mmngr_ph.o + + @echo * Compiling Physical Memory Manager... + %nasm_path%\nasm.exe -f aout -o %objpath%/mmngr_cr.o mmngr_cr.asm + %djgpp_path%\gcc.exe -Wall -O -fstrength-reduce -fomit-frame-pointer -nostdinc -fno-builtin -I%incpath% -c -o %objpath%/mmngr_ph.o mmngr_ph.c + +:check + if not exist %objpath%\mmngr_cr.o goto error + if not exist %objpath%\mmngr_ph.o goto error diff --git a/SysCore/memory/mmngr_cr.asm b/SysCore/memory/mmngr_cr.asm new file mode 100644 index 0000000..58375db --- /dev/null +++ b/SysCore/memory/mmngr_cr.asm @@ -0,0 +1,29 @@ +bits 32 + +global _read_cr0 +_read_cr0: + mov eax, cr0 + retn + +global _write_cr0 +_write_cr0: + push ebp + mov ebp, esp + mov eax, [ebp+8] + mov cr0, eax + pop ebp + retn + +global _read_cr3 +_read_cr3: + mov eax, cr3 + retn + +global _write_cr3 +_write_cr3: + push ebp + mov ebp, esp + mov eax, [ebp+8] + mov cr3, eax + pop ebp + retn diff --git a/SysCore/memory/mmngr_ph.c b/SysCore/memory/mmngr_ph.c new file mode 100644 index 0000000..907f1a6 --- /dev/null +++ b/SysCore/memory/mmngr_ph.c @@ -0,0 +1,204 @@ +/****************************************************** + * Physical Memory Manager * + ******************************************************/ +#include +#include +#include "mmngr_ph.h" + +#define PMMNGR_BLOCK_SIZE 4096 // block size (4k) +#define PMMNGR_BLOCK_ALIGN PMMNGR_BLOCK_SIZE // block alignment + +struct memory_stack_entry{ + word low; + byte high; +} __attribute__ ((__packed__)); +typedef struct memory_stack_entry mstack; + +static uint32_t _mmngr_memory_size=0; // size of physical memory +static uint32_t _mmngr_used_blocks=0; // number of blocks currently in use +static uint32_t _mmngr_max_blocks=0; // maximum number of available memory blocks +static uint32_t _mmngr_index = 0; + +static mstack* _mmngr_memory_stack= 0; // memory stack + +inline mstack mstack_pop () +{ + mstack temp; + temp.low = _mmngr_memory_stack[--_mmngr_index].low; + temp.high = _mmngr_memory_stack[_mmngr_index].high; + _mmngr_used_blocks++; + + _mmngr_memory_stack[_mmngr_index].low = 0xFFFF; + _mmngr_memory_stack[_mmngr_index].high = 0xFF; + + return temp; +} + + +inline void mstack_push (const mstack *block) +{ + if (block->low == 0 && block-> high == 0) return; + + _mmngr_memory_stack[_mmngr_index].low = block->low; + _mmngr_memory_stack[_mmngr_index].high = block->high; + + _mmngr_index++; + _mmngr_used_blocks--; +} + + +inline byte mstack_test (const mstack *block) +{ + uint32_t i; + for (i = 0; i < _mmngr_index; i++) + if (_mmngr_memory_stack[i].low == block->low && _mmngr_memory_stack[i].high == block->high) return 1; + + return 0; +} + +byte pmmngr_test_block (uint32_t block) +{ + mstack temp; + temp.low = block & 0xFFFF; + temp.high = (block>>16) & 0xFF; + + return mstack_test(&temp); +} + +void pmmngr_free_block(void* address) +{ + // Calculate block + mstack block; + uint32_t temp = (uint32_t)address / PMMNGR_BLOCK_SIZE; + block.low = temp & 0xFFFF; + block.high = (temp>>16) & 0xFF; + + // Push it + mstack_push (&block); +} + + +void* pmmngr_alloc_block() +{ + if (_mmngr_index == 0) return 0;// Out of memory + // pop a block + mstack block = mstack_pop(); + + // Calculate and return address; + void* address; + uint32_t temp = block.low | (block.high<<16); + address = (void *)(temp * PMMNGR_BLOCK_SIZE); + + return address; +} + + +void pmmngr_init (size_t memSize, uint32_t stack) { + + _mmngr_memory_size = memSize; + _mmngr_memory_stack = (mstack*) stack; + _mmngr_max_blocks = (_mmngr_memory_size*1024) / PMMNGR_BLOCK_SIZE; + _mmngr_used_blocks = _mmngr_max_blocks; + _mmngr_index = 0; + + // By default, all of memory is in use +} + +void pmmngr_init_region (physical_addr base, size_t size) { + + mstack block; + + + unsigned int count = size / PMMNGR_BLOCK_SIZE; + unsigned int start = base / PMMNGR_BLOCK_SIZE; + + for (; count!=0; count--) { + block.low = (start + count) & 0xFFFF; + block.high = ((start + count) << 16) & 0xFF; + mstack_push(&block); + + } + +} + +void pmmngr_deinit_region (physical_addr base, size_t size) { + unsigned int start = base / PMMNGR_BLOCK_SIZE; + unsigned int count = size / PMMNGR_BLOCK_SIZE; + int temp; + + unsigned int i; + unsigned int j; + + // Find free blocks in the area and zero them + for (i = 0; i < _mmngr_index; i++) { + temp = (_mmngr_memory_stack[i].high << 16) | _mmngr_memory_stack[i].low; + if (temp >=start && temp < start+count) + { _mmngr_memory_stack[i].high = 0; + _mmngr_memory_stack[i].low = 0; + } + } + + // Eliminate zero blocks + for (i = 0; i<_mmngr_index; i++) + if (_mmngr_memory_stack[i].high == 0 && _mmngr_memory_stack[i].low == 0) + { + // Find next non-zero + for (j = i; _mmngr_memory_stack[j].high == 0 && _mmngr_memory_stack[j].low == 0; j++) + if (j == _mmngr_index-1) { + j = 0; break; } + + if (j == 0) { + _mmngr_index = i; + break; + } + + _mmngr_memory_stack[i].high = _mmngr_memory_stack[j].high; + _mmngr_memory_stack[i].low = _mmngr_memory_stack[j].low; + _mmngr_memory_stack[j].high = 0; + _mmngr_memory_stack[j].low = 0; + + } +} + + +size_t pmmngr_get_memory_size () { + return _mmngr_memory_size; +} + +uint32_t pmmngr_get_block_count () { + return _mmngr_max_blocks; +} + +uint32_t pmmngr_get_use_block_count () { + return _mmngr_used_blocks; +} + +uint32_t pmmngr_get_free_block_count () { + return _mmngr_index; +} + +uint32_t pmmngr_get_block_size () { + return PMMNGR_BLOCK_SIZE; +} + +void pmmngr_paging_enable (byte b) { + uint32_t temp; + + temp = read_cr0(); + // Enable + if (b) temp |= 0x80000000; + else temp &= ~0x80000000; + + write_cr0(temp); +} + + +byte pmmngr_is_paging () { + uint32_t temp = read_cr0(); + return ((temp&0x80000000)>0); +} + +mstack* pmmngr_get_stack_addr() +{ + return _mmngr_memory_stack; +} \ No newline at end of file diff --git a/SysCore/memory/mmngr_ph.h b/SysCore/memory/mmngr_ph.h new file mode 100644 index 0000000..6d61f49 --- /dev/null +++ b/SysCore/memory/mmngr_ph.h @@ -0,0 +1,33 @@ + +#ifndef _MMNGR_PHYS_H +#define _MMNGR_PHYS_H + +#include +#include + + +#define pmmngr_load_PDBR(addr) write_cr3(addr) +#define pmmngr_get_PDBR() read_cr3() + +// physical address +typedef unsigned physical_addr; + +extern uint32_t read_cr0(); +extern uint32_t read_cr3(); +extern void write_cr0(uint32_t data); +extern void write_cr3(uint32_t data); +extern void pmmngr_free_block(void* address); // releases a memory block +extern void* pmmngr_alloc_block (); // allocates a single memory block +extern void pmmngr_init (size_t memSize, uint32_t stack); // initialize the physical memory manager +extern void pmmngr_init_region (physical_addr base, size_t size); // enables a physical memory region for use +extern void pmmngr_deinit_region (physical_addr base, size_t size); // disables a physical memory region as in use (unuseable) +extern size_t pmmngr_get_memory_size (); // returns amount of physical memory the manager is set to use +extern uint32_t pmmngr_get_use_block_count (); // returns number of blocks currently in use +extern uint32_t pmmngr_get_free_block_count (); // returns number of blocks not in use +extern uint32_t pmmngr_get_block_count (); // returns number of memory blocks +extern uint32_t pmmngr_get_block_size (); // returns default memory block size in bytes +extern void pmmngr_paging_enable (byte b); // enable or disable paging +extern byte pmmngr_is_paging (); // test if paging is enabled + +extern byte pmmngr_test_block (uint32_t block); +#endif diff --git a/SysCore/memory/pde.c b/SysCore/memory/pde.c new file mode 100644 index 0000000..ddb6aac --- /dev/null +++ b/SysCore/memory/pde.c @@ -0,0 +1,26 @@ +#include + +void pt_entry_add_attrib (pt_entry* entry, unsigned mask) { + *entry |= mask; +} + + void pt_entry_del_attrib (pt_entry* entry, unsigned mask) { + *entry &= ~mask; +} + + void pt_entry_set_frame (pt_entry* entry, unsigned address) { + *entry &= ~_I86_PTE_FRAME; + *entry |= address & _I86_PTE_FRAME; + } + + unsigned pt_entry_get_frame (pt_entry entry) { + return entry&_I86_PTE_FRAME; +} + + unsigned char pt_entry_is_present (pt_entry entry) { + return ( (entry & _I86_PTE_PRESENT) > 0 ); + } + + unsigned char pt_entry_is_writable (pt_entry entry) { + return ( (entry & _I86_PTE_WRITABLE) > 0 ); +} \ No newline at end of file diff --git a/SysCore/memory/pde.h b/SysCore/memory/pde.h new file mode 100644 index 0000000..24434ad --- /dev/null +++ b/SysCore/memory/pde.h @@ -0,0 +1,27 @@ +#ifndef __PAGE_DIRECTORY_ENTRY_ +#define __PAGE_DIRECTORY_ENTRY_ + +enum __PAGE_FLAGS { + _I86_PTE_PRESENT = 1, + _I86_PTE_WRITABLE = 2, + _I86_PTE_USER = 4, + _I86_PTE_WRITETHROUGH = 8, + _I86_PTE_NOT_CACHEABLE = 0x10, + _I86_PTE_ACCESSED = 0x20, + _I86_PTE_DIRTY = 0x40, + _I86_PTE_PAT = 0x80, + _I86_PTE_CPU_GLOBAL = 0x100, + _I86_PTE_LV4_GLOBAL = 0x200, + _I86_PTE_FRAME = 0x7FFFF000 + }; + +typedef unsigned pt_entry; + +extern void pt_entry_add_attrib (pt_entry* entry, unsigned mask); +extern void pt_entry_del_attrib (pt_entry* entry, unsigned mask); +extern void pt_entry_set_frame (pt_entry* entry, unsigned address); +extern unsigned pt_entry_get_frame (pt_entry entry); + +extern unsigned char pt_entry_is_present (pt_entry entry); +extern unsigned char pt_entry_is_writable (pt_entry entry); +#endif \ No newline at end of file diff --git a/SysCore/memory/pte.c b/SysCore/memory/pte.c new file mode 100644 index 0000000..4f7bad8 --- /dev/null +++ b/SysCore/memory/pte.c @@ -0,0 +1,26 @@ +#include + +void pt_entry_add_attrib (pt_entry* entry, unsigned mask) { + *entry |= mask; +} + + void pt_entry_del_attrib (pt_entry* entry, unsigned mask) { + *entry &= ~mask; +} + + void pt_entry_set_frame (pt_entry* entry, unsigned address) { + *entry &= ~_I86_PTE_FRAME; + *entry |= address & _I86_PTE_FRAME; + } + + unsigned pt_entry_get_frame (pt_entry entry) { + return entry&_I86_PTE_FRAME; +} + + unsigned char pt_entry_is_present (pt_entry entry) { + return ( (entry & _I86_PTE_PRESENT) > 0 ); + } + + unsigned char pt_entry_is_writable (pt_entry entry) { + return ( (entry & _I86_PTE_WRITABLE) > 0 ); +} \ No newline at end of file diff --git a/SysCore/memory/pte.h b/SysCore/memory/pte.h new file mode 100644 index 0000000..a09cc8a --- /dev/null +++ b/SysCore/memory/pte.h @@ -0,0 +1,27 @@ +#ifndef __PAGE_TABLE_ENTRY_ +#define __PAGE_TABLE_ENTRY_ + +enum __PAGE_FLAGS { + _I86_PTE_PRESENT = 1, + _I86_PTE_WRITABLE = 2, + _I86_PTE_USER = 4, + _I86_PTE_WRITETHROUGH = 8, + _I86_PTE_NOT_CACHEABLE = 0x10, + _I86_PTE_ACCESSED = 0x20, + _I86_PTE_DIRTY = 0x40, + _I86_PTE_PAT = 0x80, + _I86_PTE_CPU_GLOBAL = 0x100, + _I86_PTE_LV4_GLOBAL = 0x200, + _I86_PTE_FRAME = 0x7FFFF000 + }; + +typedef unsigned pt_entry; + +extern void pt_entry_add_attrib (pt_entry* entry, unsigned mask); +extern void pt_entry_del_attrib (pt_entry* entry, unsigned mask); +extern void pt_entry_set_frame (pt_entry* entry, unsigned address); +extern unsigned pt_entry_get_frame (pt_entry entry); + +extern unsigned char pt_entry_is_present (pt_entry entry); +extern unsigned char pt_entry_is_writable (pt_entry entry); +#endif \ No newline at end of file diff --git a/SysCore/objects/BSOD.O b/SysCore/objects/BSOD.O new file mode 100644 index 0000000..328c971 Binary files /dev/null and b/SysCore/objects/BSOD.O differ diff --git a/SysCore/objects/CMOS.O b/SysCore/objects/CMOS.O new file mode 100644 index 0000000..7118849 Binary files /dev/null and b/SysCore/objects/CMOS.O differ diff --git a/SysCore/objects/CONIO.O b/SysCore/objects/CONIO.O new file mode 100644 index 0000000..2d9e5f0 Binary files /dev/null and b/SysCore/objects/CONIO.O differ diff --git a/SysCore/objects/CPU.O b/SysCore/objects/CPU.O new file mode 100644 index 0000000..b140ffb Binary files /dev/null and b/SysCore/objects/CPU.O differ diff --git a/SysCore/objects/GDT.O b/SysCore/objects/GDT.O new file mode 100644 index 0000000..41e6f7e Binary files /dev/null and b/SysCore/objects/GDT.O differ diff --git a/SysCore/objects/GDT_ASM.O b/SysCore/objects/GDT_ASM.O new file mode 100644 index 0000000..957aa74 Binary files /dev/null and b/SysCore/objects/GDT_ASM.O differ diff --git a/SysCore/objects/HAL.O b/SysCore/objects/HAL.O new file mode 100644 index 0000000..982a289 Binary files /dev/null and b/SysCore/objects/HAL.O differ diff --git a/SysCore/objects/IDT.O b/SysCore/objects/IDT.O new file mode 100644 index 0000000..2b639a5 Binary files /dev/null and b/SysCore/objects/IDT.O differ diff --git a/SysCore/objects/IDT_ASM.O b/SysCore/objects/IDT_ASM.O new file mode 100644 index 0000000..02122a5 Binary files /dev/null and b/SysCore/objects/IDT_ASM.O differ diff --git a/SysCore/objects/IRQ.O b/SysCore/objects/IRQ.O new file mode 100644 index 0000000..604fce8 Binary files /dev/null and b/SysCore/objects/IRQ.O differ diff --git a/SysCore/objects/IRQ_ASM.O b/SysCore/objects/IRQ_ASM.O new file mode 100644 index 0000000..17d82dc Binary files /dev/null and b/SysCore/objects/IRQ_ASM.O differ diff --git a/SysCore/objects/ISRS.O b/SysCore/objects/ISRS.O new file mode 100644 index 0000000..49d9b47 Binary files /dev/null and b/SysCore/objects/ISRS.O differ diff --git a/SysCore/objects/ISRS_ASM.O b/SysCore/objects/ISRS_ASM.O new file mode 100644 index 0000000..6fd98da Binary files /dev/null and b/SysCore/objects/ISRS_ASM.O differ diff --git a/SysCore/objects/KERNEL.BIN b/SysCore/objects/KERNEL.BIN new file mode 100644 index 0000000..4d61829 Binary files /dev/null and b/SysCore/objects/KERNEL.BIN differ diff --git a/SysCore/objects/KEYUS.O b/SysCore/objects/KEYUS.O new file mode 100644 index 0000000..068c974 Binary files /dev/null and b/SysCore/objects/KEYUS.O differ diff --git a/SysCore/objects/LOADER.O b/SysCore/objects/LOADER.O new file mode 100644 index 0000000..61dae5b Binary files /dev/null and b/SysCore/objects/LOADER.O differ diff --git a/SysCore/objects/MAIN.O b/SysCore/objects/MAIN.O new file mode 100644 index 0000000..d9c212a Binary files /dev/null and b/SysCore/objects/MAIN.O differ diff --git a/SysCore/objects/MMNGR_CR.O b/SysCore/objects/MMNGR_CR.O new file mode 100644 index 0000000..0a9dec7 Binary files /dev/null and b/SysCore/objects/MMNGR_CR.O differ diff --git a/SysCore/objects/MMNGR_PH.O b/SysCore/objects/MMNGR_PH.O new file mode 100644 index 0000000..c77b59f Binary files /dev/null and b/SysCore/objects/MMNGR_PH.O differ diff --git a/SysCore/objects/PIC.O b/SysCore/objects/PIC.O new file mode 100644 index 0000000..5e3d159 Binary files /dev/null and b/SysCore/objects/PIC.O differ diff --git a/SysCore/objects/PIT.O b/SysCore/objects/PIT.O new file mode 100644 index 0000000..dd35372 Binary files /dev/null and b/SysCore/objects/PIT.O differ diff --git a/SysCore/objects/STRING.O b/SysCore/objects/STRING.O new file mode 100644 index 0000000..e669893 Binary files /dev/null and b/SysCore/objects/STRING.O differ diff --git a/SysCore/objects/SYSTEM.O b/SysCore/objects/SYSTEM.O new file mode 100644 index 0000000..e6e8ce5 Binary files /dev/null and b/SysCore/objects/SYSTEM.O differ diff --git a/SysCore/objects/TIME.O b/SysCore/objects/TIME.O new file mode 100644 index 0000000..52241f7 Binary files /dev/null and b/SysCore/objects/TIME.O differ diff --git a/SysCore/objects/compile.bat b/SysCore/objects/compile.bat new file mode 100644 index 0000000..c34f0d7 --- /dev/null +++ b/SysCore/objects/compile.bat @@ -0,0 +1,16 @@ +@echo off +rem The name of the loader assembly file (without extension, must be .asm): +set loader_name=loader + +rem NASM and DJGPP executable paths: +set nasm_path=C:\nasm +set djgpp_path=C:\DJGPP\bin + +@echo on +%djgpp_path%\ld -T link.ld +@echo off +@echo. +@echo Done! + +@pause +copy KERNEL.BIN A:\KERNEL.CTA \ No newline at end of file diff --git a/SysCore/objects/link.ld b/SysCore/objects/link.ld new file mode 100644 index 0000000..ab49a73 --- /dev/null +++ b/SysCore/objects/link.ld @@ -0,0 +1,50 @@ +OUTPUT_FORMAT("binary") +ENTRY(start) +INPUT("loader.o", + "main.o", + "BSOD.o", + "cmos.o", + "conio.o", + "cpu.o", + "gdt.o", + "gdt_asm.o", + "hal.o", + "idt.o", + "idt_asm.o", + "irq.o", + "irq_asm.o", + "isrs.o", + "isrs_asm.o", + "mmngr_cr.o", + "mmngr_ph.o", + "keyus.o", + "pic.o", + "pit.o", + "string.o", + "system.o", + "time.o" +) +OUTPUT(kernel.bin) +phys = 0x00100000; +SECTIONS +{ + .text phys : AT(phys) { + __code = .; + *(.text) + *(.rodata) + . = ALIGN(4096); + } + .data : AT(phys + (__data - __code)) + { + __data = .; + *(.data) + . = ALIGN(4096); + } + .bss : AT(phys + (__bss - __code)) + { + __bss = .; + *(.bss) + . = ALIGN(4096); + } + __end = .; +} \ No newline at end of file diff --git a/SysCore/shell/apps.h b/SysCore/shell/apps.h new file mode 100644 index 0000000..33d6de2 --- /dev/null +++ b/SysCore/shell/apps.h @@ -0,0 +1,196 @@ +const char *apps_lst[] = { + "", + "reboot", + "osver", + "time", + "place", + "cls", + "memory", + "help", + "cpu_info", + "mem_alloc", //0 + "mem_free", //1 + "mem_stat", + "mem_test", //2 + }; +int apps_count = 13; + + + +unsigned int atox(const char* str) +{ + unsigned int temp = 0; + int i; unsigned int digit = 0; + + for (i = 0; str[i]!=0; i++) { + + if (str[i] >= '0' && str[i] <= '9') digit = str[i] - '0'; + else if (str[i] >= 'A' && str[i] <= 'F') digit = str[i] - 'A' + 10; + else if (str[i] >= 'a' && str[i] <= 'f') digit = str[i] - 'a' + 10; + else break; + + temp = temp*16 + digit; + } + + return temp; +} + +unsigned int atoui(const char* str) +{ + unsigned int temp = 0; + int i; + + for (i = 0; str[i] >= '0' && str[i] <= '9' ; i++) + temp = temp*10 + (str[i] - '0'); + + return temp; +} + + + +void apps_osver() +{ + printf ("CTA 32bit Operating System v0.1"); + printf ("\n(c) CTA 2010\n"); +} + +void apps_time() +{ + printf ("Today is %s, %u of %s, %u%u.\n", clock_weekdays[_internal_clock.weekday], + (unsigned int) _internal_clock.day, clock_months[_internal_clock.month], + (unsigned int) _internal_clock.century, (unsigned int) _internal_clock.year); + + printf ("Now is %u:%u:%u.\n", (unsigned int) _internal_clock.hours, + (unsigned int) _internal_clock.minutes, (unsigned int) _internal_clock.seconds); +} + +void apps_place() +{ + printf ("On your desk, if you didn't notice... \n"); +} + +void apps_clrscr() +{ + clrscr(); +} + +void apps_memory(const int pn, const char* param[]) +{ + if (pn<3) { + printf ("Correct syntax: memory [start_address] [end_address] (in hex)\n"); + return; + } + + byte *start, *end; + start = (byte *) atox (param[1]); + end = (byte *) atox (param[2]); + byte* count; + + while (start <= end) { + put_hex ((unsigned int) start); puts(": "); + + for (count = start; count < start+16; count++) { + putc(hex[*count/16]); putc(hex[*count%16]); + putc(' '); + } + puts(" "); + for (count = start; count < start+16; count++) { + if (*count < 32) putc('.'); + else putc(*count); + } + + putc('\n'); + start+=16; + } + + +} + +void apps_help(const int pn, const char* param[]) +{ + int i; + puts ("\n"); + if (pn==1) { + puts("[BeTA]\n"); + puts("Available commands:"); + for (i = 1; i < apps_count; i++) { + puts("\n \t "); puts((char*)apps_lst[i]); + } + puts("\n\nUse help [command] for help on individual commands.\n"); + return; + } + + for (i = 0; strcmp(apps_lst[i], param[1])!=0 && i 1 && strcmp(param[1], "times") == 0) + times = atoui(param[2]); + + uint32_t temp; + for (; times > 0; times--) { + temp = (uint32_t) pmmngr_alloc_block(); + if (temp == 0) { + printf ("Out of memory.\n"); + break; + } + else printf ("New block allocated at address 0x%x\n", temp); + } + return; + } + // Free + case 1: + { if (pn <= 1) { + printf ("Parameter missing: [address (hex)]\n"); + return; + } + + uint32_t temp = atox(param[1]); + pmmngr_free_block ((void*)temp); + printf ("Block containing address 0x%x now free.", temp); + return; + } + // Test + case 2: + { if (pn <= 1) { + printf ("Parameter missing: [block number]"); + return ; } + unsigned int temp = atoui(param[1]); + printf (pmmngr_test_block(temp) ? "Block %u is free.\n" : "Block %u is used.\n", temp); + } + } + +} + + +void apps_memory_status() +{ + printf ("Memory available: %u KB \n", pmmngr_get_memory_size ()); + printf ("Total blocks: %u Used: %u Free: %u\n", pmmngr_get_block_count (), pmmngr_get_use_block_count (), pmmngr_get_free_block_count ()); + printf ("Block size: %u bytes\nPaging is ", pmmngr_get_block_size()); + printf ( pmmngr_is_paging() ? "enabled.\n" : "disabled.\n"); +} \ No newline at end of file diff --git a/kernel/shell/shell.c b/SysCore/shell/shell.c similarity index 80% rename from kernel/shell/shell.c rename to SysCore/shell/shell.c index 9f6220d..87bb81a 100644 --- a/kernel/shell/shell.c +++ b/SysCore/shell/shell.c @@ -8,7 +8,7 @@ void get_str(char *str, int len) int i; for (i = 0; inul + if errorlevel 5 goto floppy_yes + + @echo Insert a floppy disk, and press any key to continue. + @pause >nul + goto floppy_no + + +:floppy_yes + @echo Formatting disk... + format A: /q nul + @echo. + +:bootloader + cd SysBoot + @echo. + call makeall.bat + cd.. + +:kernel + cd SysCore + call makeallh.bat + cd.. + +@echo ************************ Done ************************ +@echo. \ No newline at end of file diff --git a/kernel/clock/cmos.h b/kernel/clock/cmos.h deleted file mode 100644 index a8dba18..0000000 --- a/kernel/clock/cmos.h +++ /dev/null @@ -1,25 +0,0 @@ -volatile static byte cmos_data[128]; - -void cmos_write () -{ - byte i; - for (i = 0; i < 128; i++) { - //asm volatile ("cli"); - outportb(0x70, i); - iowait(); - outportb(0x71, cmos_data[i]); - //asm volatile ("sti"); - } -} - -void cmos_read () -{ - byte i; - for (i = 0; i < 128; i++) { - //asm volatile ("cli"); - outportb(0x70, i); - iowait(); - cmos_data[i] = inportb(0x71); - //asm volatile ("sti"); - } -} \ No newline at end of file diff --git a/kernel/clock/pictimer.c b/kernel/clock/pictimer.c deleted file mode 100644 index 9846d4a..0000000 --- a/kernel/clock/pictimer.c +++ /dev/null @@ -1,76 +0,0 @@ -#include -#include "time.c" -int timer_ticks = 0; -int timer_hz; - -void timer_phase(int hz) -{ - int divisor = 1193180/hz; // Calculate the divisor - outportb(0x43, 0x36); // Set our command byte 0x36 - outportb(0x40, divisor&0xFF); // Set low byte - outportb(0x40, divisor>>8); // Set high byte - timer_hz = hz; -} - -void clock_show (int uptime_secs) -{ - int i; - for (i=0;i<80;i++) putc_pos_font (i, 0, ' ', 0x02, 0x0F); - puts_pos_font (64, 0, "Uptime:", 0x02, 0x0E); - - unsigned int uptime; - - uptime = uptime_secs%60; // Seconds - uptime += 100* ((uptime_secs/60)%60); // Minutes - uptime += 10000*(uptime_secs/3600); // Hours - - for (i=79;i>71;i--) { - if (i==77 || i==74) { - if (uptime_secs%2==0) putc_pos_font(i, 0, ':', 0x02, 0x0F); - else putc_pos_font(i, 0, ' ', 0x02, 0x0F); - } - else { - putc_pos_font(i, 0, (uptime%10)+'0', 0x02, 0x0F); - uptime/=10; - } - } - - // PRINT CURRENT TIME - uptime = clock.seconds; // Seconds - uptime += 100* clock.minutes; // Minutes - uptime += 10000*clock.hours; // Hours - - for (i=9;i>1;i--) { - if (i==7 || i==4) { - if (uptime_secs%2==0) putc_pos_font(i, 0, ':', 0x02, 0x0F); - else putc_pos_font(i, 0, ' ', 0x02, 0x0F); - } - else { - putc_pos_font(i,0, (uptime%10)+'0', 0x02, 0x0F); - uptime/=10; - } - } - if (clock.am_pm==0) puts_pos_font(10, 0, "am", 0x02, 0x0F); - else puts_pos_font(10, 0, "pm", 0x02, 0x0F); - - // PRINT DATE - putc_pos_font(32, 0, (clock.day/10)+'0', 0x02, 0x0E); - putc_pos_font(33, 0, (clock.day%10)+'0', 0x02, 0x0E); - puts_pos_font(35, 0, (char*)clock_months[clock.month], 0x02, 0x0F); - putc_pos_font(35+strlen(clock_months[clock.month])+1, 0, (clock.century/10)+'0', 0x02, 0x0E); - putc_pos_font(35+strlen(clock_months[clock.month])+2, 0, (clock.century%10)+'0', 0x02, 0x0E); - putc_pos_font(35+strlen(clock_months[clock.month])+3, 0, (clock.year/10)+'0', 0x02, 0x0E); - putc_pos_font(35+strlen(clock_months[clock.month])+4, 0, (clock.year%10)+'0', 0x02, 0x0E); - -} - - -void timer_handler(regs *r) -{ - timer_ticks++; - - if (timer_ticks % timer_hz == 0) { - clock_show (timer_ticks / timer_hz); - clock_inc(); - } -} \ No newline at end of file diff --git a/kernel/clock/time.c b/kernel/clock/time.c deleted file mode 100644 index 5b0e3a2..0000000 --- a/kernel/clock/time.c +++ /dev/null @@ -1,143 +0,0 @@ -#ifndef __TIME_C -#define __TIME_C - -#include "cmos.h" - -static const char* clock_months[] = {0, - "January", "February", "March", "April", "May", "June", - "July", "August", "September", "October", "November", "December"}; -static const char* clock_weekdays[] = {0, - "Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"}; - -byte clock_months_len[] = { - 0, - 31, // January - 28, // February - 31, // March - 30, // April - 31, // May - 30, // June - 31, // July - 31, // August - 30, // September - 31, // October - 30, // November - 31 // December -}; - -typedef struct { - byte seconds; - byte minutes; - byte hours; - byte weekday; - byte day; - byte month; - byte year; - byte century; - byte am_pm; - -} TIME; -volatile static TIME clock; - -void RTC_get_time() -{ - cmos_read(); - - if ((cmos_data[0x0b]&4)==0) // BCD = true; - { - clock.seconds = (cmos_data[0x00]%16) + 10*(cmos_data[0x00]/16); - clock.minutes = (cmos_data[0x02]%16) + 10*(cmos_data[0x02]/16); - if ((cmos_data[0x0b]&2)==0) { // AM/PM - if (cmos_data[0x04]&80) { // pm - clock.hours = ((cmos_data[0x04]-0x80)%16) + 10*((cmos_data[0x04]-0x80)/16); - clock.am_pm = 1; - } - else { // am - clock.hours = (cmos_data[0x04]%16) + 10*(cmos_data[0x04]/16); - clock.am_pm = 0; - } - } - else { // 24 hours - clock.hours = (cmos_data[0x04]%16) + 10*(cmos_data[0x04]/16); - if (clock.hours > 12) { - clock.am_pm = 1; - clock.hours -= 12; - } - else clock.am_pm = 0; - } - - clock.weekday = (cmos_data[0x06]%16) + 10*(cmos_data[0x06]/16); - clock.day = (cmos_data[0x07]%16) + 10*(cmos_data[0x07]/16); - clock.month = (cmos_data[0x08]%16) + 10*(cmos_data[0x08]/16); - clock.year = (cmos_data[0x09]%16) + 10*(cmos_data[0x09]/16); - clock.century = (cmos_data[0x32]%16) + 10*(cmos_data[0x32]/16); - } - - else {//BCD = false; - clock.seconds = cmos_data[0x00]; - clock.minutes = cmos_data[0x02]; - if ((cmos_data[0x0b]&2)==0) { // AM/PM - if (cmos_data[0x04]&80) { // pm - clock.hours = cmos_data[0x04]-0x80; - clock.am_pm = 1; - } - else { // am - clock.hours = cmos_data[0x04]; - clock.am_pm = 0; - } - } - else { // 24 hours - clock.hours = cmos_data[0x02]; - if (clock.hours > 12) { - clock.am_pm = 1; - clock.hours -= 12; - } - else clock.am_pm = 0; - } - clock.weekday = cmos_data[0x06]; - clock.day = cmos_data[0x07]; - clock.month = cmos_data[0x08]; - clock.year = cmos_data[0x09]; - clock.century = cmos_data[0x32]; - } - // Leap years - if (clock.year % 4 == 0) clock_months_len[2]=29; - -} - -void clock_inc() -{ - // New minute - if (++clock.seconds > 59) { - clock.seconds = 0; - // New hour - if (++clock.minutes > 59) { - clock.minutes = 0; - clock.hours++; - if (clock.hours == 12 && clock.am_pm == 1) { // 11:59pm -> 0:00am - clock.hours = 0; clock.am_pm = 0; - // New day - clock.weekday = 1+(clock.weekday%7); - // New month - if (++clock.day > clock_months_len[clock.month]) { - clock.day = 1; - // New year - if (++clock.month>12) { - clock.month = 1; - // New century - if (++clock.year > 99) { - clock.year = 0; - clock.century++; - } - } - } - } - else if (clock.hours == 12 && clock.am_pm == 0) // 11:59am -> 12:00pm - clock.am_pm = 1; - else if (clock.hours == 13 && clock.am_pm == 1) // 12:59pm -> 1:59pm - clock.hours = 1; - } - } -} - -#endif \ No newline at end of file diff --git a/kernel/console.o b/kernel/console.o deleted file mode 100644 index 33bd1c5..0000000 Binary files a/kernel/console.o and /dev/null differ diff --git a/kernel/include/sys/declarat.h b/kernel/include/sys/declarat.h deleted file mode 100644 index 28fa675..0000000 --- a/kernel/include/sys/declarat.h +++ /dev/null @@ -1,40 +0,0 @@ -// Data type declarations -typedef unsigned char byte; -typedef unsigned short word; -typedef unsigned int dword; - -/* This defines what the stack looks like after an ISR was running */ -typedef struct -{ - unsigned int gs, fs, es, ds; /* pushed the segs last */ - unsigned int edi, esi, ebp, esp, ebx, edx, ecx, eax; /* pushed by 'pusha' */ - unsigned int int_no, err_code; /* our 'push byte #' and ecodes do this */ - unsigned int eip, cs, eflags, useresp, ss; /* pushed by the processor automatically */ -} regs; - - -// Functions -void system_init(); -void *memcpy(void *dest, const void *src, int count); -void *memset(void *dest, char val, int count); -unsigned short *memsetw(unsigned short *dest, unsigned short val, int count); -int strlen (const char *str); -byte inportb (word _port); -byte inb (word _port); -void outportb (word _port, byte _data); -void outb (word _port, byte _data) ; - -void gdt_set_gate(int num, unsigned long base, unsigned long limit, unsigned char access, unsigned char gran); -void gdt_install(); - -void idt_set_gate(unsigned char num, unsigned long base, unsigned short sel, unsigned char flags); -void idt_install(); - -void isrs_install(); - -void irq_install_handler(int irq, void (*handler)(regs *r)); -void irq_uninstall_handler(int irq); -void irq_install(); -void kb_handler(regs *r); -void reboot(); -void kb_waitin(); \ No newline at end of file diff --git a/kernel/include/system.h b/kernel/include/system.h deleted file mode 100644 index 9ba8159..0000000 --- a/kernel/include/system.h +++ /dev/null @@ -1,85 +0,0 @@ -#ifndef __SYSTEM_H -#define __SYSTEM_H -#include - -#define true 1 -#define false 0 - -byte *TextVideoRam; -volatile static int cursor_x, cursor_y; -int current_mode_width; -int current_mode_height; - -void *memcpy(void *dest, const void *src, int count) -{ - const char *sp = (const char *)src; - char *dp = (char *)dest; - for(; count != 0; count--) *dp++ = *sp++; - return dest; -} - -void *memset(void *dest, char val, int count) -{ - char *temp = (char *)dest; - for( ; count != 0; count--) *temp++ = val; - return dest; -} - -unsigned short *memsetw(unsigned short *dest, unsigned short val, int count) -{ - unsigned short *temp = (unsigned short *)dest; - for( ; count != 0; count--) *temp++ = val; - return dest; -} - - -// strlen -- Get lenght of str -int strlen (const char *str) -{ - int i; - for (i = 0; *str!=0; str++) i++; - return i; -} - -int strcmp(const char *pStr1, const char *pStr2) -{ - char c1, c2; - int v; - - do { - c1 = *pStr1++; - c2 = *pStr2++; - /* the casts are necessary when pStr1 is shorter & char is signed */ - v = (unsigned int)c1 - (unsigned int)c2; - } while ((v == 0) && (c1 != '\0')); - - return v; -} - - - -byte inportb (word _port) { - byte rv; - __asm__ __volatile__ ("inb %1, %0" : "=a" (rv) : "dN" (_port)); - return rv; -} -byte inb (word _port) { - byte rv; - __asm__ __volatile__ ("inb %1, %0" : "=a" (rv) : "dN" (_port)); - return rv; -} - -static inline void iowait() { - asm volatile ("outb %al, $0x80"); -} - - -void outportb (word _port, byte _data) { - __asm__ __volatile__ ("outb %1, %0" : : "dN" (_port), "a" (_data)); -} -void outb (word _port, byte _data) { - __asm__ __volatile__ ("outb %1, %0" : : "dN" (_port), "a" (_data)); -} - - -#endif \ No newline at end of file diff --git a/kernel/kernel.bin b/kernel/kernel.bin deleted file mode 100644 index a50d6ed..0000000 Binary files a/kernel/kernel.bin and /dev/null differ diff --git a/kernel/kernel/epilogue.c b/kernel/kernel/epilogue.c deleted file mode 100644 index 8c7c267..0000000 --- a/kernel/kernel/epilogue.c +++ /dev/null @@ -1,8 +0,0 @@ -void reboot() -{ - unsigned char good = 0x02; - while ((good & 0x02) != 0) - good = inportb(0x64); - outportb(0x64, 0xFE); - __asm__ __volatile__ ("hlt"); -} \ No newline at end of file diff --git a/kernel/kernel/irq.c b/kernel/kernel/irq.c deleted file mode 100644 index e86a83e..0000000 --- a/kernel/kernel/irq.c +++ /dev/null @@ -1,125 +0,0 @@ -#include - -/* These are own ISRs that point to our special IRQ handler -* instead of the regular 'fault_handler' function */ - -extern void irq0(); -extern void irq1(); -extern void irq2(); -extern void irq3(); -extern void irq4(); -extern void irq5(); -extern void irq6(); -extern void irq7(); -extern void irq8(); -extern void irq9(); -extern void irq10(); -extern void irq11(); -extern void irq12(); -extern void irq13(); -extern void irq14(); -extern void irq15(); - -/* This array is actually an array of function pointers. We use -* this to handle custom IRQ handlers for a given IRQ */ -void *irq_routines[16] = -{ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0 -}; - -/* This installs a custom IRQ handler for the given IRQ */ -void irq_install_handler (int irq, void (*handler)(regs *r)) -{ - irq_routines[irq] = handler; -} - -void irq_uninstall_handler (int irq) -{ - irq_routines[irq] = 0; -} - - -/* Normally, IRQs 0 to 7 are mapped to entries 8 to 15. This -* is a problem in protected mode, because IDT entry 8 is a -* Double Fault! Without remapping, every time IRQ0 fires, -* you get a Double Fault Exception, which is NOT actually -* what's happening. We send commands to the Programmable -* Interrupt Controller (PICs - also called the 8259's) in -* order to make IRQ0 to 15 be remapped to IDT entries 32 to -* 47 */ -void irq_remap(int pic1, int pic2) -{ - // Send ICW1 - outportb(0x20, 0x11); - outportb(0xA0, 0x11); - - // send ICW2 - outportb(0x21, pic1); // remap pics - outportb(0xA1, pic2); - - // send ICW3 - outportb(0x21, 4); - outportb(0xA1, 2); - - // Send ICW4 - outportb(0x21, 0x01); - outportb(0xA1, 0x01); - - outportb(0x21, 0x00); -} - -/* We first remap the interrupt controllers, and then we install -* the appropriate ISRs to the correct entries in the IDT. This -* is just like installing the exception handlers */ -void irq_install() -{ - irq_remap(32,40); - - idt_set_gate(32, (unsigned)irq0, 0x08, 0x8E); - idt_set_gate(33, (unsigned)irq1, 0x08, 0x8E); - idt_set_gate(34, (unsigned)irq2, 0x08, 0x8E); - idt_set_gate(35, (unsigned)irq3, 0x08, 0x8E); - idt_set_gate(36, (unsigned)irq4, 0x08, 0x8E); - idt_set_gate(37, (unsigned)irq5, 0x08, 0x8E); - idt_set_gate(38, (unsigned)irq6, 0x08, 0x8E); - idt_set_gate(39, (unsigned)irq7, 0x08, 0x8E); - idt_set_gate(40, (unsigned)irq8, 0x08, 0x8E); - idt_set_gate(41, (unsigned)irq9, 0x08, 0x8E); - idt_set_gate(42, (unsigned)irq10, 0x08, 0x8E); - idt_set_gate(43, (unsigned)irq11, 0x08, 0x8E); - idt_set_gate(44, (unsigned)irq12, 0x08, 0x8E); - idt_set_gate(45, (unsigned)irq13, 0x08, 0x8E); - idt_set_gate(46, (unsigned)irq14, 0x08, 0x8E); - idt_set_gate(47, (unsigned)irq15, 0x08, 0x8E); -} - -/* Each of the IRQ ISRs point to this function, rather than -* the 'fault_handler' in 'isrs.c'. The IRQ Controllers need -* to be told when you are done servicing them, so you need -* to send them an "End of Interrupt" command (0x20). There -* are two 8259 chips: The first exists at 0x20, the second -* exists at 0xA0. If the second controller (an IRQ from 8 to -* 15) gets an interrupt, you need to acknowledge the -* interrupt at BOTH controllers, otherwise, you only send -* an EOI command to the first controller. If you don't send -* an EOI, you won't raise any more IRQs */ -void irq_handler (regs *r) -{ - /* This is a blank function pointer */ - void (*handler)(regs *r); - - /* Find out if we have a custom handler to run for this - * IRQ, and then finally, run it */ - handler = irq_routines[r->int_no - 32]; - if (handler) handler(r); - - /* If the IDT entry that was invoked was greater than 40 - * (meaning IRQ8 - 15), then we need to send an EOI to - * the slave controller */ - if (r->int_no >=40) outportb(0x0A, 0x20); - - /* In either case, we need to send an EOI to the master - * interrupt controller too */ - outportb(0x20, 0x20); -} diff --git a/kernel/kernel/isrs.c b/kernel/kernel/isrs.c deleted file mode 100644 index fa1ef02..0000000 --- a/kernel/kernel/isrs.c +++ /dev/null @@ -1,162 +0,0 @@ -#include - -extern void isr0(); -extern void isr1(); -extern void isr2(); -extern void isr3(); -extern void isr4(); -extern void isr5(); -extern void isr6(); -extern void isr7(); -extern void isr8(); -extern void isr9(); -extern void isr10(); -extern void isr11(); -extern void isr12(); -extern void isr13(); -extern void isr14(); -extern void isr15(); -extern void isr16(); -extern void isr17(); -extern void isr18(); -extern void isr19(); -extern void isr20(); -extern void isr21(); -extern void isr22(); -extern void isr23(); -extern void isr24(); -extern void isr25(); -extern void isr26(); -extern void isr27(); -extern void isr28(); -extern void isr29(); -extern void isr30(); -extern void isr31(); - -/* This is a very repetitive function... it's not hard, it's -* just annoying. As you can see, we set the first 32 entries -* in the IDT to the first 32 ISRs. We can't use a for loop -* for this, because there is no way to get the function names -* that correspond to that given entry. We set the access -* flags to 0x8E. This means that the entry is present, is -* running in ring 0 (kernel level), and has the lower 5 bits -* set to the required '14', which is represented by 'E' in -* hex. */ -void isrs_install() -{ - idt_set_gate(0, (unsigned)isr0, 0x08, 0x8E); - idt_set_gate(1, (unsigned)isr1, 0x08, 0x8E); - idt_set_gate(2, (unsigned)isr2, 0x08, 0x8E); - idt_set_gate(3, (unsigned)isr3, 0x08, 0x8E); - idt_set_gate(4, (unsigned)isr4, 0x08, 0x8E); - idt_set_gate(5, (unsigned)isr5, 0x08, 0x8E); - idt_set_gate(6, (unsigned)isr6, 0x08, 0x8E); - idt_set_gate(7, (unsigned)isr7, 0x08, 0x8E); - idt_set_gate(8, (unsigned)isr8, 0x08, 0x8E); - idt_set_gate(9, (unsigned)isr9, 0x08, 0x8E); - idt_set_gate(10, (unsigned)isr10, 0x08, 0x8E); - idt_set_gate(11, (unsigned)isr11, 0x08, 0x8E); - idt_set_gate(12, (unsigned)isr12, 0x08, 0x8E); - idt_set_gate(13, (unsigned)isr13, 0x08, 0x8E); - idt_set_gate(14, (unsigned)isr14, 0x08, 0x8E); - idt_set_gate(15, (unsigned)isr15, 0x08, 0x8E); - idt_set_gate(16, (unsigned)isr16, 0x08, 0x8E); - idt_set_gate(17, (unsigned)isr17, 0x08, 0x8E); - idt_set_gate(18, (unsigned)isr18, 0x08, 0x8E); - idt_set_gate(19, (unsigned)isr19, 0x08, 0x8E); - idt_set_gate(20, (unsigned)isr20, 0x08, 0x8E); - idt_set_gate(21, (unsigned)isr21, 0x08, 0x8E); - idt_set_gate(22, (unsigned)isr22, 0x08, 0x8E); - idt_set_gate(23, (unsigned)isr23, 0x08, 0x8E); - idt_set_gate(24, (unsigned)isr24, 0x08, 0x8E); - idt_set_gate(25, (unsigned)isr25, 0x08, 0x8E); - idt_set_gate(26, (unsigned)isr26, 0x08, 0x8E); - idt_set_gate(27, (unsigned)isr27, 0x08, 0x8E); - idt_set_gate(28, (unsigned)isr28, 0x08, 0x8E); - idt_set_gate(29, (unsigned)isr29, 0x08, 0x8E); - idt_set_gate(30, (unsigned)isr30, 0x08, 0x8E); - idt_set_gate(31, (unsigned)isr31, 0x08, 0x8E); -} - - char *exception_messages[] = { - "Division By Zero Exception", - "Debug Exception", - "Non Maskable Interrupt Exception", - "Breakpoint Exception", - "Into Detected Overflow Exception", - "Out of Bounds Exception", - "Invalid Opcode Exception", - "No Coprocessor", - "Double Fault Exception", - "Coprocessor Segment Overrun Exception", - "Bad TSS Exception", - "Segment Not Present Exception", - "Stack Fault Exception", - "General Protection Fault Exception", - "Page Fault Exception", - "Unknown Interrupt Exception", - "Coprocessor Fault Exception", - "Alignment Check Exception", - "Machine Check Exception", - "Reserved Exception", - "Reserved Exception", - "Reserved Exception", - "Reserved Exception", - "Reserved Exception", - "Reserved Exception", - "Reserved Exception", - "Reserved Exception", - "Reserved Exception", - "Reserved Exception", - "Reserved Exception", - "Reserved Exception" -}; - - -/* All of our Exception handling Interrupt Service Routines will -* point to this function. This will tell us what exception has -* happened! Right now, we simply halt the system by hitting an -* endless loop. All ISRs disable interrupts while they are being -* serviced as a 'locking' mechanism to prevent an IRQ from -* happening and messing up kernel data structures */ -void fault_handler(regs *r) -{ - /* Is this a fault whose number is from 0 to 31? */ - if (r->int_no < 32) - { - /* Display the description for the Exception that occurred.*/ - - // Put on the BSOD screen - set_default_colors (0x01, 0x0F); clrscr(); - puts (" Blue Screen Of Death\n"); - int i; for (i = 79; i>=0; i--) putc('='); - puts_pos_font (15, 2, "A fatal error has occured, CTA OS has been halted.", 0x01, 0x0C); - puts_pos_font (10, 4, "gs", 0x01, 0x0B); put_hex_pos(15, 4, r->gs); - puts_pos_font (10, 5, "fs", 0x01, 0x0B); put_hex_pos(15, 5, r->fs); - puts_pos_font (10, 6, "es", 0x01, 0x0B); put_hex_pos(15, 6, r->es); - puts_pos_font (10, 7, "ds", 0x01, 0x0B); put_hex_pos(15, 7, r->ds); - - puts_pos_font (40, 4, "edi", 0x01, 0x0B); put_hex_pos(45, 4, r->edi); - puts_pos_font (40, 5, "esi", 0x01, 0x0B); put_hex_pos(45, 5, r->esi); - puts_pos_font (40, 6, "ebp", 0x01, 0x0B); put_hex_pos(45, 6, r->ebp); - puts_pos_font (40, 7, "esp", 0x01, 0x0B); put_hex_pos(45, 7, r->esp); - - puts_pos_font (10, 9, "eax", 0x01, 0x0B); put_hex_pos(15, 9, r->eax); - puts_pos_font (10, 10, "ebx", 0x01, 0x0B); put_hex_pos(15, 10, r->ebx); - puts_pos_font (40, 9, "ecx", 0x01, 0x0B); put_hex_pos(45, 9, r->ecx); - puts_pos_font (40, 10, "edx", 0x01, 0x0B); put_hex_pos(45, 10, r->edx); - - puts_pos_font (10, 12, "int_no", 0x01, 0x0B); put_hex_pos(17, 12, r->int_no); - puts_pos_font (10, 14, "Error code:", 0x01, 0x0B); put_hex_pos(24, 14, r->err_code); - puts_pos_font (10, 15, "Error msg: ", 0x01, 0x0B); puts_pos(24, 15, exception_messages[r->int_no]); - - puts_pos_font (10, 17, "eip", 0x01, 0x0B); put_hex_pos(17, 17, r->eip); - puts_pos_font (10, 18, "cs", 0x01, 0x0B); put_hex_pos(17, 18, r->cs); - puts_pos_font (10, 19, "eflags", 0x01, 0x0B); put_hex_pos(17, 19, r->eflags); - puts_pos_font (10, 20, "useresp", 0x01, 0x0B); put_hex_pos(17, 20, r->useresp); - puts_pos_font (10, 21, "ss", 0x01, 0x0B); put_hex_pos(17, 21, r->ss); - - puts_pos_font (29, 24, "!!! System Halted !!!", 0x01, 0x0C); - for (;;); - } -} diff --git a/kernel/kernel/memory.c b/kernel/kernel/memory.c deleted file mode 100644 index b5d21e7..0000000 --- a/kernel/kernel/memory.c +++ /dev/null @@ -1,4 +0,0 @@ -extern unsigned long* read_cr0(); -extern unsigned long* read_cr3(); -extern void write_cr0(unsigned long* alpha); -extern void write_cr3(unsigned long* alpha); \ No newline at end of file diff --git a/kernel/kernel/prologue.c b/kernel/kernel/prologue.c deleted file mode 100644 index f0eb980..0000000 --- a/kernel/kernel/prologue.c +++ /dev/null @@ -1,61 +0,0 @@ -#include -#include "gdt.c" -#include "idt.c" -#include "isrs.c" -#include "irq.c" - -void system_init() -{ - // Detect if color/monochrome screen - char c = (*(volatile unsigned short*)0x410)&0x30; - if (c==0x30) TextVideoRam = (byte *)0xb0000; - else TextVideoRam = (byte *)0xb8000; - - // Reset cursor, use 80x25 text video mode - current_mode_width = 80; - current_mode_height = 25; - cursor_x = cursor_y = 0; - - // Install GDT, IDT, ISRs and IRQs; Enable interrupts - gdt_install(); - idt_install(); - isrs_install(); - irq_install(); - RTC_get_time(); - __asm__ __volatile__ ("sti"); - - // Install PIT timer - timer_ticks = 0; - timer_phase (100); - irq_install_handler(0, timer_handler); - - // Install keyboard (part 1): install IRQ1 and start BAT test - kb_modifier_status = 0; - irq_install_handler(1, kb_handler); - kb_waitin(); outportb(0x60, 0xFF); // Reset kb - - - // other drivers come here!!; - - - - // Install keyboard (part 2): BAT test results & set repeat rates - byte temp; - do temp = inportb(0x60); - while (temp!=0xAA && temp!=0xFC); - // KB failed BAT TEST - if (temp == 0xFC) puts_font("\nKeyboard error: failed BAT test.", 0x07, 0x0C); - kb_set_repeat(1, 11); - - // Install keyboard (part 3): set scancode set 2 - kb_set_scancodeset(2); // Set new scancode set - - kb_waitin(); outportb(0x64, 0x20); // Get "Command byte" - do { temp = inportb(0x60); - } while (temp==0xFA || temp==0xAA); - - temp &= 0xFF - (1<<6); // Set bit6 to 0: disable conversion - kb_waitin(); outportb(0x64, 0x60); // Function to write cmd byte - kb_waitin(); outportb(0x60, temp); // Send it - memset(kb_array, 0, 16); -} \ No newline at end of file diff --git a/kernel/keyboard/keyb.c b/kernel/keyboard/keyb.c deleted file mode 100644 index 3ab763c..0000000 --- a/kernel/keyboard/keyb.c +++ /dev/null @@ -1,60 +0,0 @@ - - -void kb_test() -{ - byte temp=0, secs=0; - - puts("\nTHIS WILL TEST FEW COMMANDS OF THE PS/2 KEYBOARD.\n"); - - - puts("\nEcho... "); - while ((inportb(0x64)&2)!=0); - outportb(0x60, 0xEE); -/* while ((inportb(0x64)&1)!=0); - temp = inportb(0x60); - putc_font('[', 0x07, 0x02); - putc_font(hex[temp/16], 0x07, 0x02); - putc_font(hex[temp%16], 0x07, 0x02); - putc_font(']', 0x07, 0x02);*/ - - - puts("\nSet LEDs - SCROLL on... "); - while ((inportb(0x64)&2)!=0); - outportb(0x60, 0xED); -/* while ((inportb(0x64)&2)!=0); - outportb(0x60, 1); - while ((inportb(0x64)&1)!=0); - temp = inportb(0x60);*/ - putc_font('[', 0x07, 0x02); - putc_font(hex[temp/16], 0x07, 0x02); - putc_font(hex[temp%16], 0x07, 0x02); - putc_font(']', 0x07, 0x02); - - - puts("\nGet current scancode set... "); - while ((inportb(0x64)&2)!=0); - outportb(0x60, 0xF0); - while ((inportb(0x64)&2)!=0); - outportb(0x60, 0); - -/* while ((inportb(0x64)&1)!=0); - temp = inportb(0x60); - putc_font('[', 0x07, 0x02); - putc_font(hex[temp/16], 0x07, 0x02); - putc_font(hex[temp%16], 0x07, 0x02); - putc_font(']', 0x07, 0x02);*/ - - - puts("\nTurning on 2 leds (don't know which ones :P)... "); - while ((inportb(0x64)&2)!=0); - outportb(0x60, 0xED); - while ((inportb(0x64)&2)!=0); - outportb(0x60, (byte)1|2); - /* while ((inportb(0x64)&1)!=0); - temp = inportb(0x60); - putc_font('[', 0x07, 0x02); - putc_font(hex[temp/16], 0x07, 0x02); - putc_font(hex[temp%16], 0x07, 0x02); - putc_font(']', 0x07, 0x02);*/ - -} \ No newline at end of file diff --git a/kernel/keyboard/keyus.h b/kernel/keyboard/keyus.h deleted file mode 100644 index 7b26dc4..0000000 --- a/kernel/keyboard/keyus.h +++ /dev/null @@ -1,137 +0,0 @@ -void kb_set_LEDs(byte status); -void kb_set_repeat(byte rate, byte delay); -void kb_set_scancodeset(byte set); - -char kbdus_map[] = { - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, '\t', '`', 0, - 0, 0, 0, 0, 0, 'q', '1', 0, 0, 0, 'z', 's', 'a', 'w', '2', 0, - 0, 'c', 'x', 'd', 'e', '4', '3', 0, 0, ' ', 'v', 'f', 't', 'r', '5', 0, - 0, 'n', 'b', 'h', 'g', 'y', '6', 0, 0, 0, 'm', 'j', 'u', '7', '8', 0, - 0, ',', 'k', 'i', 'o', '0', '9', 0, 0, '.', '/', 'l', ';', 'p', '-', 0, - 0, 0, '\'', 0, '[', '=', 0, 0, 0, '\n', '\n', ']', 0, '\\', 0, 0, - 0, 0, 0x7F, 0, 0, 0, '\b', 0, 0, '1', '/', '4', '7', 0, 0, 0, - '0', '.', '2', '5', '6', '8', 0, 0, 0, '+', '3', '-', '*', '9', 0, 0 - }; - -char kbdus_map_shift[] = { - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, '\t', '~', 0, - 0, 0, 0, 0, 0, 'Q', '!', 0, 0, 0, 'Z', 'S', 'A', 'W', '@', 0, - 0, 'C', 'X', 'D', 'E', '$', '#', 0, 0, ' ', 'V', 'F', 'T', 'R', '%', 0, - 0, 'N', 'B', 'H', 'G', 'Y', '^', 0, 0, 0, 'M', 'J', 'U', '&', '*', 0, - 0, '<', 'K', 'I', 'O', ')', '(', 0, 0, '>', '?', 'L', ':', 'P', '_', 0, - 0, 0, '\"', 0, '{', '+', 0, 0, 0, '\n', '\n', '}', 0, '|', 0, 0, - 0, 0, 0x7F, 0, 0, 0, '\b', 0, 0, '1', '/', '4', '7', 0, 0, 0, - '0', '.', '2', '5', '6', '8', 0, 0, 0, '+', '3', '-', '*', '9', 0, 0 - }; -/* kb_modifier_status: - BIT | Description - ----+----------------------------------- - 0 | Left Shift - 1 | Right Shift - 2 | Left Alt - 3 | Right Alt - 4 | Left CTRL - 5 | Right CTRL - 6 | Fake Shift */ -byte kb_modifier_status; - -/* kb_modifier_status: - BIT | Description - ----+----------------------------------- - 0 | Gray - 1 | Break code - 2 | 0xE1 (pause/break) - 3 | Recieved first byte from pause/break */ -byte kb_prefix; - -/* kb_lights_status - BIT | Description - ----+----------------------------------- - 0 | SCROLLOCK - 1 | NUMLOCK - 2 | CAPSLOCK */ -byte kb_lights_status; -byte kb_scancode_set; - - -/*************************************** - * Set repeat rate/delay * - *************************************** - Values for inter-character delay (bits 4-0) - (characters per second; default is 10.9) - | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 - ----+----+----+----+----+----+----+----+---- - 0 |30.0|26.7|24.0|21.8|20.0|18.5|17.1|16.0 - 8 |15.0|13.3|12.0|10.9|10.0|9.2 |8.6 |8.0 - 16 |7.5 |6.7 |6.0 |5.5 |5.0 |4.6 |4.3 |4.0 - 24 |3.7 |3.3 |3.0 |2.7 |2.5 |2.3 |2.1 |2.0 - - Values for delay: - (miliseconds; default is 500) - 0 | 1 | 2 | 3 - -----+-----+-----+----- - 250 | 500 | 750 | 1000 - - ***************************************/ -void kb_set_repeat(byte rate, byte delay) -{ - if (rate>3 || delay>31) return; - - byte out = rate<<5 | delay; - while ((inportb(0x64)&2) != 0); - outportb(0x60, 0xF3); - while ((inportb(0x64)&2) != 0); - outportb(0x60, out); -} - - -/*************************************** - * Set keyboard LEDs * - *************************************** - +-----------+-------+-------+--------+ - | Bits 7-3 | Bit 2 | Bit 1 | Bit 0 | - | 0 | Caps | Num | Scroll | - |(reserved) | lock | lock | lock | - +-----------+-------+-------+--------+ - ***************************************/ -void kb_set_LEDs(byte status) -{ - while ((inportb (0x64)&2)!=0); - outportb (0x60, 0xED); - - while ((inportb (0x64)&2)!=0); - outportb (0x60, status); -} - -/*************************************** - * Set scancode set * - *************************************** - 0 Get current scancode set - 1 Set to scancode set 1 - 2 Set to scancode set 2 - 3 Set to scancode set 3 - ***************************************/ -void kb_set_scancodeset(byte set) -{ - //If ask for current scancode, tell kb handler what to expect - if (set==0) kb_scancode_set = 4; - - while ((inportb (0x64)&2)!=0); - outportb (0x60, 0xF0); - - while ((inportb (0x64)&2)!=0); - outportb (0x60, set); -} - - -void kb_waitin() -{ - int fail_safe=200000; - while ((inportb(0x64)&2)!=0 && fail_safe>0) fail_safe--; -} - -void kb_waitout() -{ - int fail_safe=200000; - while ((inportb(0x64)&1)==0 && fail_safe>0) fail_safe--; -} \ No newline at end of file diff --git a/kernel/link.ld b/kernel/link.ld deleted file mode 100644 index 1699422..0000000 --- a/kernel/link.ld +++ /dev/null @@ -1,25 +0,0 @@ -OUTPUT_FORMAT("binary") -ENTRY(start) -phys = 0x00100000; -SECTIONS -{ - .text phys : AT(phys) { - code = .; - *(.text) - *(.rodata) - . = ALIGN(4096); - } - .data : AT(phys + (data - code)) - { - data = .; - *(.data) - . = ALIGN(4096); - } - .bss : AT(phys + (bss - code)) - { - bss = .; - *(.bss) - . = ALIGN(4096); - } - end = .; -} \ No newline at end of file diff --git a/kernel/loader.asm b/kernel/loader.asm deleted file mode 100644 index eba57f1..0000000 --- a/kernel/loader.asm +++ /dev/null @@ -1,478 +0,0 @@ -[BITS 32] -global start -start: mov esp, _sys_stack ; This points the stack to our new stack area - jmp stublet - - -; This part MUST be 4byte aligned, so we solve that issue using 'ALIGN 4' -ALIGN 4 -mboot: - ; Multiboot macros to make a few lines later more readable - MULTIBOOT_PAGE_ALIGN equ 1<<0 - MULTIBOOT_MEMORY_INFO equ 1<<1 - MULTIBOOT_AOUT_KLUDGE equ 1<<16 - MULTIBOOT_HEADER_MAGIC equ 0x1BADB002 - MULTIBOOT_HEADER_FLAGS equ MULTIBOOT_PAGE_ALIGN | MULTIBOOT_MEMORY_INFO | MULTIBOOT_AOUT_KLUDGE - MULTIBOOT_CHECKSUM equ -(MULTIBOOT_HEADER_MAGIC + MULTIBOOT_HEADER_FLAGS) - EXTERN code, bss, end - - ; This is the GRUB Multiboot header. A boot signature - dd MULTIBOOT_HEADER_MAGIC - dd MULTIBOOT_HEADER_FLAGS - dd MULTIBOOT_CHECKSUM - - ; AOUT kludge - must be physical addresses. Make a note of these: - ; The linker script fills in the data for these ones! - dd mboot - dd code - dd bss - dd end - dd start - -; This is an endless loop here. Make a note of this: Later on, we -; will insert an 'extern _main', followed by 'call _main', right -; before the 'jmp $'. -stublet: - extern _main - call _main - jmp $ - - -; !!! GDT !!! -; This will set up our new segment registers. We need to do -; something special in order to set CS. We do what is called a -; far jump. A jump that includes a segment as well as an offset. -; This is declared in C as 'extern void gdt_flush();' - -global _gdt_flush ; Allows the C code to link to this -extern _gp ; Says that '_gp' is in another file -_gdt_flush: - lgdt [_gp] ; Load the GDT with our '_gp' which is a special pointer - mov ax, 0x10 ; 0x10 is the offset in the GDT to our data segment - mov ds, ax - mov es, ax - mov fs, ax - mov gs, ax - mov ss, ax - jmp 0x08:flush2 ; 0x08 is the offset to our code segment: Far jump! -flush2: - ret ; Returns back to the C code! - - -; !!! IDT !!! -; Loads the IDT defined in '_idtp' -global _idt_load -extern _idtp -_idt_load: - lidt [_idtp] - ret - -; !!! ISRs !!! -global _isr0 -global _isr1 -global _isr2 -global _isr3 -global _isr4 -global _isr5 -global _isr6 -global _isr7 -global _isr8 -global _isr9 -global _isr10 -global _isr11 -global _isr12 -global _isr13 -global _isr14 -global _isr15 -global _isr16 -global _isr17 -global _isr18 -global _isr19 -global _isr20 -global _isr21 -global _isr22 -global _isr23 -global _isr24 -global _isr25 -global _isr26 -global _isr27 -global _isr28 -global _isr29 -global _isr30 -global _isr31 - -_isr0: - cli - push byte 0; A normal ISR stub that pops a dummy error code to keep a - ; uniform stack frame - push byte 0 - jmp isr_common_stub -_isr1: - cli - push byte 0 - push byte 1 - jmp isr_common_stub -_isr2: - cli - push byte 0 - push byte 2 - jmp isr_common_stub -_isr3: - cli - push byte 0 - push byte 3 - jmp isr_common_stub -_isr4: - cli - push byte 0 - push byte 4 - jmp isr_common_stub -_isr5: - cli - push byte 0 - push byte 5 - jmp isr_common_stub -_isr6: - cli - push byte 0 - push byte 6 - jmp isr_common_stub -_isr7: - cli - push byte 0 - push byte 7 - jmp isr_common_stub -_isr8: - cli - push byte 8 - jmp isr_common_stub -_isr9: - cli - push byte 0 - push byte 9 - jmp isr_common_stub -_isr10: - cli - push byte 10 - jmp isr_common_stub -_isr11: - cli - push byte 11 - jmp isr_common_stub -_isr12: - cli - push byte 12 - jmp isr_common_stub -_isr13: - cli - push byte 13 - jmp isr_common_stub -_isr14: - cli - push byte 14 - jmp isr_common_stub -_isr15: - cli - push byte 0 - push byte 15 - jmp isr_common_stub -_isr16: - cli - push byte 0 - push byte 16 - jmp isr_common_stub -_isr17: - cli - push byte 0 - push byte 17 - jmp isr_common_stub -_isr18: - cli - push byte 0 - push byte 18 - jmp isr_common_stub -_isr19: - cli - push byte 0 - push byte 19 - jmp isr_common_stub -_isr20: - cli - push byte 0 - push byte 20 - jmp isr_common_stub -_isr21: - cli - push byte 0 - push byte 21 - jmp isr_common_stub -_isr22: - cli - push byte 0 - push byte 22 - jmp isr_common_stub -_isr23: - cli - push byte 0 - push byte 23 - jmp isr_common_stub -_isr24: - cli - push byte 0 - push byte 24 - jmp isr_common_stub -_isr25: - cli - push byte 0 - push byte 25 - jmp isr_common_stub -_isr26: - cli - push byte 0 - push byte 26 - jmp isr_common_stub -_isr27: - cli - push byte 0 - push byte 27 - jmp isr_common_stub -_isr28: - cli - push byte 0 - push byte 28 - jmp isr_common_stub -_isr29: - cli - push byte 0 - push byte 29 - jmp isr_common_stub -_isr30: - cli - push byte 0 - push byte 30 - jmp isr_common_stub -_isr31: - cli - push byte 0 - push byte 31 - jmp isr_common_stub - -extern _fault_handler - -isr_common_stub: - pusha - push ds - push es - push fs - push gs - mov ax, 0x10 ; Load the Kernel Data Segment descriptor! - mov ds, ax - mov es, ax - mov fs, ax - mov gs, ax - mov eax, esp ; Push us the stack - push eax - mov eax, _fault_handler - call eax ; A special call, preserves the 'eip' register - pop eax - pop gs - pop fs - pop es - pop ds - popa - add esp, 8 ; Cleans up the pushed error code and pushed ISR number - iret ; pops 5 things at once: CS, EIP, EFLAGS, SS, and ESP! - - -; !!! IRQ !!! -global _irq0 -global _irq1 -global _irq2 -global _irq3 -global _irq4 -global _irq5 -global _irq6 -global _irq7 -global _irq8 -global _irq9 -global _irq10 -global _irq11 -global _irq12 -global _irq13 -global _irq14 -global _irq15 - -; 32: IRQ0 -_irq0: - cli - push byte 0 - push byte 32; Note that these don't push an error code on the stack: - ; We need to push a dummy error code - jmp irq_common_stub - -; 33: IRQ1 -_irq1: - cli - push byte 0 - push byte 33 - jmp irq_common_stub - -; 34: IRQ2 -_irq2: - cli - push byte 0 - push byte 34 - jmp irq_common_stub - -; 35: IRQ3 -_irq3: - cli - push byte 0 - push byte 35 - jmp irq_common_stub - -; 36: IRQ4 -_irq4: - cli - push byte 0 - push byte 36 - jmp irq_common_stub - -; 37: IRQ5 -_irq5: - cli - push byte 0 - push byte 37 - jmp irq_common_stub - -; 38: IRQ6 -_irq6: - cli - push byte 0 - push byte 38 - jmp irq_common_stub - -; 39: IRQ7 -_irq7: - cli - push byte 0 - push byte 39 - jmp irq_common_stub - -; 40: IRQ8 -_irq8: - cli - push byte 0 - push byte 40 - jmp irq_common_stub -; 41: IRQ9 -_irq9: - cli - push byte 0 - push byte 41 - jmp irq_common_stub - -; 42: IRQ10 -_irq10: - cli - push byte 0 - push byte 42 - jmp irq_common_stub - -; 43: IRQ11 -_irq11: - cli - push byte 0 - push byte 43 - jmp irq_common_stub - -; 44: IRQ12 -_irq12: - cli - push byte 0 - push byte 44 - jmp irq_common_stub - -; 45: IRQ13 -_irq13: - cli - push byte 0 - push byte 45 - jmp irq_common_stub - -; 46: IRQ14 -_irq14: - cli - push byte 0 - push byte 46 - jmp irq_common_stub - -; 47: IRQ15 -_irq15: - cli - push byte 0 - push byte 47 - jmp irq_common_stub - -extern _irq_handler - -; This is a stub that we have created for IRQ based ISRs. This calls -; '_irq_handler' in our C code. We need to create this in an 'irq.c' -irq_common_stub: - pusha - push ds - push es - push fs - push gs - mov ax, 0x10 - mov ds, ax - mov es, ax - mov fs, ax - mov gs, ax - mov eax, esp - push eax - mov eax, _irq_handler - call eax - pop eax - pop gs - pop fs - pop es - pop ds - popa - add esp, 8 - iret - - -[global _read_cr0] -_read_cr0: - mov eax, cr0 - retn - -[global _write_cr0] -_write_cr0: - push ebp - mov ebp, esp - mov eax, [ebp+8] - mov cr0, eax - pop ebp - retn - -[global _read_cr3] -_read_cr3: - mov eax, cr3 - retn - -[global _write_cr3] -_write_cr3: - push ebp - mov ebp, esp - mov eax, [ebp+8] - mov cr3, eax - pop ebp - retn - - - -SECTION .bss - resb 8192 ; This reserves 8KBytes of memory here -_sys_stack: \ No newline at end of file diff --git a/kernel/loader.o b/kernel/loader.o deleted file mode 100644 index 9e620cd..0000000 Binary files a/kernel/loader.o and /dev/null differ diff --git a/kernel/main.c b/kernel/main.c deleted file mode 100644 index 623bb3c..0000000 --- a/kernel/main.c +++ /dev/null @@ -1,18 +0,0 @@ -#include -#include -#include "clock/pictimer.c" -#include "keyboard/keyus.c" -#include "kernel/prologue.c" -#include "kernel/epilogue.c" -#include "shell/shell.c" - -int main() -{ - system_init(); - - shell(); - - // do nothing - for(;;); - return 0; -} \ No newline at end of file diff --git a/kernel/main.o b/kernel/main.o deleted file mode 100644 index c776921..0000000 Binary files a/kernel/main.o and /dev/null differ diff --git a/kernel/shell/apps.h b/kernel/shell/apps.h deleted file mode 100644 index cf2adb5..0000000 --- a/kernel/shell/apps.h +++ /dev/null @@ -1,122 +0,0 @@ -const char *apps_lst[] = { - "", - "reboot", - "osver", - "date", - "place", - "cls", - "memory" - }; -int apps_count = 7; - -void apps_osver() -{ - puts("CTA OS v0.1"); - puts("\n(c) CTA 2010.\n"); -} - -void apps_date() -{ - puts("Today is "); - puts((char*)clock_weekdays[clock.weekday]); - puts(", "); putc((clock.day/10)+'0'); - putc((clock.day%10)+'0'); - puts(" "); puts((char*)clock_months[clock.month]); - puts(" "); putc((clock.century/10)+'0'); - putc((clock.century%10)+'0'); - putc((clock.year/10)+'0'); - putc((clock.year%10)+'0'); - putc('\n'); -} - -void apps_place() -{ - puts("On your desk, if you didn't notice... \n"); -} - -void apps_clrscr() -{ - clrscr(); -} - -void apps_memory(const int pn, const char* param[]) -{ - if (pn<3) { - puts ("Correct syntax: memory [start_address] [end_address] (in hex)\n"); - return; - } - - byte *start, *end; - byte l1 = strlen(param[1]), l2 = strlen(param[2]); - unsigned int a; - int i; byte *count; - - a = 0; - for(i = 0; i < l1; i++) { - switch (param[1][i]) { - case 'a': - case 'A': a = a*16 + 10; break; - case 'b': - case 'B': a = a*16 + 11; break; - case 'c': - case 'C': a = a*16 + 12; break; - case 'd': - case 'D': a = a*16 + 13; break; - case 'e': - case 'E': a = a*16 + 14; break; - case 'f': - case 'F': a = a*16 + 15; break; - - default: if (!(param[1][i]>='0' && param[1][i]<='9')) { - puts ((char*)param[1]); puts(" is not a valid hex address.\n"); - return; - } - a = a*16 + (param[1][i] - '0'); - break; - } - } - start = (byte *)a; - - a = 0; - for(i = 0; i < l2; i++) { - switch (param[2][i]) { - case 'a': - case 'A': a = a*16 + 10; break; - case 'b': - case 'B': a = a*16 + 11; break; - case 'c': - case 'C': a = a*16 + 12; break; - case 'd': - case 'D': a = a*16 + 13; break; - case 'e': - case 'E': a = a*16 + 14; break; - case 'f': - case 'F': a = a*16 + 15; break; - - default: if (!(param[2][i]>='0' && param[2][i]<='9')) { - puts ((char*)param[2]); puts(" is not a valid hex address.\n"); - return; - } - a = a*16 + (param[2][i] - '0'); - break; - } - } - end = (byte *)a; - - while (start <= end) { - put_hex ((unsigned int) start); puts(": "); - - for (count = start; count < start+16; count++) { - putc(hex[*count/16]); putc(hex[*count%16]); - putc(' '); - } - puts(" "); - for (count = start; count < start+16; count++) - putc(*count); - - putc('\n'); - start+=16; - } - - -} \ No newline at end of file diff --git a/scripts/format b/scripts/format new file mode 100644 index 0000000..8d03dab --- /dev/null +++ b/scripts/format @@ -0,0 +1,3 @@ + + +n diff --git a/scripts/stage1d b/scripts/stage1d new file mode 100644 index 0000000..8667502 --- /dev/null +++ b/scripts/stage1d @@ -0,0 +1,2 @@ +w 100 0 0 1 +q diff --git a/stage1/MAKE.PIF b/stage1/MAKE.PIF deleted file mode 100644 index e4ad688..0000000 Binary files a/stage1/MAKE.PIF and /dev/null differ diff --git a/stage1/make.bat b/stage1/make.bat deleted file mode 100644 index 05cd83b..0000000 --- a/stage1/make.bat +++ /dev/null @@ -1,18 +0,0 @@ -@echo off -set nasm_path=C:\nasm -set djgpp_path=C:\DJGPP\bin -set drive=0 - -@echo on -%nasm_path%\nasm.exe -f bin bootload.asm -o bootload.bin - -@echo. -@echo Press any key to copy to (fd%drive%), or CTRL+C to stop. -@pause >nul - -@echo off -@echo w 100 %drive% 0 1 >f.tmp -@echo q>>f.tmp - -debug bootload.bin nul - -@echo off -copy stage2.cta A:\stage2.cta \ No newline at end of file diff --git a/stage2/a20.inc b/stage2/a20.inc deleted file mode 100644 index f50e445..0000000 --- a/stage2/a20.inc +++ /dev/null @@ -1,103 +0,0 @@ - -;******************************************** -; Enable A20 address line -; -; OS Development Series -;******************************************** - -%ifndef __A20_INC_67343546FDCC56AAB872_INCLUDED__ -%define __A20_INC_67343546FDCC56AAB872_INCLUDED__ - -bits 16 - -;---------------------------------------------- -; Enables a20 line through keyboard controller -;---------------------------------------------- - -EnableA20_KKbrd: - - cli - push ax - mov al, 0xdd ; send enable a20 address line command to controller - out 0x64, al - pop ax - ret - -;-------------------------------------------- -; Enables a20 line through output port -;-------------------------------------------- - -EnableA20_KKbrd_Out: - - cli - pusha - - call wait_input - mov al,0xAD - out 0x64,al ; disable keyboard - call wait_input - - mov al,0xD0 - out 0x64,al ; tell controller to read output port - call wait_output - - in al,0x60 - push eax ; get output port data and store it - call wait_input - - mov al,0xD1 - out 0x64,al ; tell controller to write output port - call wait_input - - pop eax - or al,2 ; set bit 1 (enable a20) - out 0x60,al ; write out data back to the output port - - call wait_input - mov al,0xAE ; enable keyboard - out 0x64,al - - call wait_input - popa - sti - ret - - ; wait for input buffer to be clear - -wait_input: - in al,0x64 - test al,2 - jnz wait_input - ret - - ; wait for output buffer to be clear - -wait_output: - in al,0x64 - test al,1 - jz wait_output - ret - -;-------------------------------------- -; Enables a20 line through bios -;-------------------------------------- - -EnableA20_Bios: - pusha - mov ax, 0x2401 - int 0x15 - popa - ret - -;------------------------------------------------- -; Enables a20 line through system control port A -;------------------------------------------------- - -EnableA20_SysControlA: - push ax - mov al, 2 - out 0x92, al - pop ax - ret - -%endif diff --git a/stage2/stage2.asm b/stage2/stage2.asm deleted file mode 100644 index 1ead0de..0000000 --- a/stage2/stage2.asm +++ /dev/null @@ -1,158 +0,0 @@ - -;******************************************************* -; -; Stage2.asm -; Stage2 Bootloader -; -; OS Development Series -;******************************************************* - -bits 16 - -; Remember the memory map-- 0x500 through 0x7bff is unused above the BIOS data area. -; We are loaded at 0x500 (0x50:0) - -org 0x500 - -jmp main ; go to start - -;******************************************************* -; Preprocessor directives -;******************************************************* - -%include "stdio.inc" ; basic i/o routines -%include "Gdt.inc" ; Gdt routines -%include "A20.inc" ; A20 enabling -%include "Fat12.inc" ; FAT12 driver. Kinda :) -%include "common.inc" - -;******************************************************* -; Data Section -;******************************************************* - -msgFailure db 0x0A, 0x0D, "FATAL ERROR: MISSING OR CORRUPT KERNEL.CTA", 0x0A, 0x0D, "Press any key to reboot...", 0x0D, 0x0A, 0x00 - -;******************************************************* -; STAGE 2 ENTRY POINT -; -; -Store BIOS information -; -Load Kernel -; -Install GDT; go into protected mode (pmode) -; -Jump to Stage 3 -;******************************************************* - -main: - - ;-------------------------------; - ; Setup segments and stack ; - ;-------------------------------; - - cli ; clear interrupts - xor ax, ax ; null segments - mov ds, ax - mov es, ax - mov ax, 0x0 ; stack begins at 0x9000-0xffff - mov ss, ax - mov sp, 0xFFFF - sti ; enable interrupts - - ;-------------------------------; - ; Install our GDT ; - ;-------------------------------; - - call InstallGDT ; install our GDT - - ;-------------------------------; - ; Enable A20 ; - ;-------------------------------; - - call EnableA20_KKbrd_Out - - ;-------------------------------; - ; Initialize filesystem ; - ;-------------------------------; - - call LoadRoot ; Load root directory table - - ;-------------------------------; - ; Load Kernel ; - ;-------------------------------; - - mov ebx, 0 ; BX:BP points to buffer to load to - mov bp, IMAGE_RMODE_BASE - mov si, ImageName ; our file to load - call LoadFile ; load our file - mov dword [ImageSize], ecx ; save size of kernel - cmp ax, 0 ; Test for success - je EnterStage3 ; yep--onto Stage 3! - mov si, msgFailure ; Nope--print error - call Puts16 - mov ah, 0 - int 0x16 ; await keypress - int 0x19 ; warm boot computer - cli ; If we get here, something really went wong - hlt - - ;-------------------------------; - ; Go into pmode ; - ;-------------------------------; - -EnterStage3: - - cli ; clear interrupts - mov eax, cr0 ; set bit 0 in cr0--enter pmode - or eax, 1 - mov cr0, eax - - jmp CODE_DESC:Stage3 ; far jump to fix CS. Remember that the code selector is 0x8! - - ; Note: Do NOT re-enable interrupts! Doing so will triple fault! - ; We will fix this in Stage 3. - -;****************************************************** -; ENTRY POINT FOR STAGE 3 -;****************************************************** - -bits 32 - -Stage3: - - ;-------------------------------; - ; Set registers ; - ;-------------------------------; - - mov ax, DATA_DESC ; set data segments to data selector (0x10) - mov ds, ax - mov ss, ax - mov es, ax - mov esp, 90000h ; stack begins from 90000h - - ;-------------------------------; - ; Copy kernel to 1MB ; - ;-------------------------------; - -CopyImage: - mov eax, dword [ImageSize] - movzx ebx, word [bpbBytesPerSector] - mul ebx - mov ebx, 4 - div ebx - cld - mov esi, IMAGE_RMODE_BASE - mov edi, IMAGE_PMODE_BASE - mov ecx, eax - rep movsd ; copy image to its protected mode address - - ;---------------------------------------; - ; Execute Kernel ; - ;---------------------------------------; - - jmp CODE_DESC:IMAGE_PMODE_BASE; jump to our kernel! Note: This assumes Kernel's entry point is at 1 MB - - ;---------------------------------------; - ; Stop execution ; - ;---------------------------------------; - - cli - hlt - diff --git a/stage2/stage2.cta b/stage2/stage2.cta deleted file mode 100644 index 128a53c..0000000 Binary files a/stage2/stage2.cta and /dev/null differ