• Stars
    star
    301
  • Rank 137,745 (Top 3 %)
  • Language
    C#
  • License
    BSD 2-Clause "Sim...
  • Created about 7 years ago
  • Updated about 2 years ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

TinyOS in C#

Scott Hanselman's Tiny Virtual Operating System and Abstract Machine in C#

Build status

What is this?

This was the final project for my CST352-Operating Systems class at OIT (Oregon Institute of Technology). The requirements, exactly as they were given to me by the teacher, are in originalassignment.md. The goal of this project was to write a small virtual operating system for an abstract machine that provides a number of basic OS-like services like:

  • Virtual Memory, Demand Paging
  • Input/Output
  • Memory Protection, Shared Memory
  • Registers, Stack, Data, Heap, etc
  • Jump instructions for calling "Functions"
  • And so on…

This is a cute, fun, interesting and completely useless thing. So, don't get your hopes up that you'll get actual work done with it. ­

It's neat however, as it is a study on how I solved a particular problem (this assignment) given a 10 week semester. I was the only student to use C#, and I finished it in 4 weeks, leaving 6 weeks to chill and watch the other students using Java and C++ do their thing.

It's also ironic because I used a high-level OO language like C# to deal with a minute concept like an "Operating System" the might have 256 bytes (bytes, not Kbytes) of memory.

During this process I exercised a good and interesting chunk of the C# language and the .NET Framework. There are some very silly things like the OS's implementation of virtual memory swapping out memory pages as XML. I might take an array of 4 bytes and make an XML file to help them. I hope the irony isn't lost on you. I also commented all the C# with XML and built an ndoc MSDN style help file. So, you might just use this as a learning tool and a pile of sample code.

One Note: I'm an ok programmer, but understand that I whipped this out in several 3am coding sessions, as well as during lectures in class. This is NOT fabulous code, and should be looked upon as interesting, not gospel. I'm sure I've done some very clever things in it, and for each clever thing, there's n stupid things. I'll leave the repair of these stupid things as an exercise to the reader.

Of course, you'll need the .NET Framework to run this, but to really have fun debugging it and stepping through the code you'll need VS.NET. Go read the code and final_project.doc and enjoy!

Scott Hanselman

[email protected]

May 2002

What's the jist?

I started out with some basic OO constructs, a static CPU object, an OS object, objects for Processes, Instructions, etc. A lot of this information is in the Help (CHM) File. Basically it's setup like this:

  • CPU Object – responsible for physical memory (which may be smaller than addressable memory) holding CPU registers and fetching program opcodes and translating them into SystemCalls in the OS, etc.
  • OS Object – Most of the work is here. It has a MemoryManager object who is responsible for the translations between Addressable (Virtual) memory, Process memory and Physical Memory. All Processes access memory from their point of view…they never talk to "physical memory" (Which is just an array of bytes in the CPU object) The scheduler is in the OS object as well as locks, events, and all that good stuff. Each of the 36 opcodes are implemented here and treated as C# delegates…well, now I'm telling you all the good stuff…read the code!
  • Program Object - represents a collection of instructions. Responsible for parsing the files off disk and holding them.
  • Process Object – different than Program as it's an actual running process in the TinyOS. There can be more than one instance of a Process for each Program. (You can run the same program twice, etc) It has a ProcessControlBlock containing Process specific registers, etc.
  • EntryPoint Class – Contains main() and "bootstraps" the whole thing.

The OS is made up, the CPU is made up, the opCodes are made up. This is an exercise to learn about Operating System concepts, and it's not meant to look or act like any specific OS or system.

What does a Program look like?

Here's an example program, specifically the "idle" loop. The idle loop is a process that never ends, it just prints out "20" over and over. I use it to keep the clock running when all the other processes are sleeping.

6        r4, $0                ;move 0 into r4
26       r4                    ;lower our priority TO 0
6        r1, $20               ;move 20 into r1
11       r1                    ;print the number 20
6        r2, $-19              ;back up the ip 19 bytes
13       r2                    ;loop forever (jump back 19)

Programs consist of:

Opcode, [optional param], [other optional param] ;optional comment

So, if we look at:

6        r4, $0                ;move 0 into r4

We see that it's operation 6, which is Movi or "Move Immediate." It moves a constant value into one of our 10 registers. The first param is r4, indicating register 4. The second param is $0. The "$" indicates a constant. So we are the value 0 into register #4. Just like x86 assembly – only not at all. 

So if you look at the comments for this app you can see that it loops forever.

How do run Program(s)

Usage:

OS membytes [files]

For example:

OS 1568 prog1.txt prog2.txt prog3.txt prog1.txt idle.txt

This command line would run the OS with 1568 bytes of virtual (addressable) memory and start up 5 processes. Note that Prog1.txt is specified twice. That means it will have two separate and independent running processes. We also specified the forever running idle.txt. Use CTRL-C to break. The OS has operations for shared memory, locks, and events, so you can setup rudimentary inter-module communication.

Why should I care?

There are 13 other sample apps you can play with. The OS is most interesting when you run it with multiple apps. You can mess with OS.config to setup the amount of memory available to each process, the whole system's physical memory, memory page size etc.

It's interesting from an OS theory point of view if you think about the kinds of experiments you can do like lowering physical memory to something ridiculous like 32 bytes. That will increase page faults and virtual memory swapping. So, the OS can be tuned with the config file.

What are the options in OS.config?

It is certainly possible to give the OS a bad config, like more physical memory than addressable, or a page size that is the same size as physical memory. But, use common sense and play. I've setup it up with reasonable defaults.

Here's a sample OS.config file. The Config has to be in the same directory as the OS.exe. Take a look at the included OS.config, as it has additional XML comments explaining each option.

<configuration>
        <appSettings>
                <addkey="PhysicalMemory"value="384"/>
                <addkey="ProcessMemory"value="384"/>
                <addkey="DumpPhysicalMemory"value="true"/>
                <addkey="DumpInstruction"value="true"/>
                <addkey="DumpRegisters"value="true"/>
                <addkey="DumpProgram"value="true"/>
                <addkey="DumpContextSwitch"value="true"/>
                <addkey="PauseOnExit"value="false"/>
                <addkey="SharedMemoryRegionSize"value="16"/>
                <addkey="NumOfSharedMemoryRegions"value="4"/>
                <addkey="MemoryPageSize"value="16"/>
                <addkey="StackSize"value="16"/>
                <addkey="DataSize"value="16"/>
        </appSettings>
</configuration>

Of note are the Dumpxxx options. With all of these options set to false, the OS only outputs the bare minimum debug information. With them on (I like to have the all on) you'll be able to see the results of each instruction and how they affect registers, physical memory, etc. You'll see physical memory pages swap to disk, memory fragmentation, the instruction pointer increment, and processes take turns on the CPU.

Be sure to turn up the size of screen buffer (usually under "Layout" in the Properties Dialog of your command prompt) to something like 3000 or 9999. This way you'll be able to scroll back and look at the details of your run.

OS 512 prog1.txt > output.txt

You might also try something like this to create a log file, or modify the source to include logging!

What are the available OpCodes?

These are also printed and explain in the Help File as well as Final_Project.doc. When writing a program you use the value, not the text name of the opcode. So, you'd say 2 r1, $1 and NOT addi r1, $1.

Opcode Value(decimal) Format
Incr 1 incr r1(increment value of register 1 by 1 ).
Addi 2 addi r1,$1 is the same as incr r1
addr 3 Addr r1, r2( r1 <= r1 + r2 ).
Pushr 4 Pushr rx (pushes contents of register x onto stack. Decrements sp by 4 ).
Pushi 5 Pushi $x . pushes the constant x onto stack. Sp is decremented by 4 after push.
Movi 6 Movi rx, $y. rx <= y
Movr 7 Movr rx, ry ; rx <= ry
Movmr 8 Movmr rx, ry ; rx <= [ry]
Movrm 9 Movrm rx,ry; [rx] <= ry
Movmm 10 Movmm rx, ry [rx] <= [ry]
Printr 11 Printr r1 ; displays contents of register 1
Printm 12 Printm r1; displays contents of memory whose address is in register 1.
Jmp 13 Jmp r1; control transfers to the instruction whose address is r1 bytes relative to the current instruction. R1 may be negative.
Cmpi 14 Cmpi rx, $y; subtract y from register rx. If rx < y, set sign flag. If rx > y, clear sign flag. If rx == y , set zero flag.
Cmpr 15 The same as cmpi except now both operands are registers.
Jlt 16 Jlt rx; if the sign flag is set, jump to the instruction whose offset is rx bytes from the current instruction.
Jgt 17 Jgt rx; if the sign flag is clear, jump to the instruction whose offset is rx bytes from the current instruction
Je 18 Je rx; if the zero flag is clear, jump to the instruction whose offset is rx bytes from the current instruction.
Call 19 Call r1; call the procedure at offset r1 bytes from the current instruction. The address of the next instruction to execute after a return is pushed on the stack.
Callm 20 Callm r1; call the procedure at offset [r1] bytes from the current instruction. The address of the next instruction to execute after a return is pushed on the stack.
Ret 21 Pop the return address from the stack and transfer control to this instruction.
Alloc 22 Alloc r1, r2; allocate memory of size equal to r1 bytes and return the address of the new memory in r2. If failed, r2 is cleared to 0.
AcquireLock 23 AcquireLock r1; Acquire the operating system lock whose # is provided in the register r1. If the lock is invalid, the instruction is a no-op.
ReleaseLock 24 Releaselock r1; release the operating system lock whose # is provided in the register r1; if the lock is not held by the current process, the instruction is a no-op.
Sleep 25 Sleep r1; Sleep the # of clock cycles as indicated in r1. Another process or the idle process must be scheduled at this point. If the time to sleep is 0, the process sleeps infinitely.
SetPriority 26 SetPriority r1; Set the priority of the current process to the value in register r1; See priorities discussion in Operating system design
Exit 27 Exit. This opcode is executed by a process to exit and be unloaded. Another process or the idle process must now be scheduled.
FreeMemory 28 FreeMemory r1; Free the memory allocated whose address is in r1.
MapSharedMem 29 MapSharedMem r1, r2; Map the shared memory region identified by r1 and return the start address in r2.
SignalEvent 30 SignalEvent r1; Signal the event indicated by the value in register r1.
WaitEvent 31 WaitEvent r1; Wait for the event in register r1 to be triggered. This results in context-switches happening.
Input 32 Input r1; read the next 32-bit value into register r1.
MemoryClear 33 MemoryClear r1, r2; set the bytes starting at address r1 of length r2 bytes to zero.
TerminateProcess 34 TerminateProcess r1; terminate the process whose id is in the register r1.
Popr 35 pop the contents at the top of the stack into register rx which is the operand. Stack pointer is decremented by 4.
popm 36 pop the contents at the top of the stack into the memory operand whose address is in the register which is the operand. Stack pointer is decremented by 4.

Known Issues/Things to Know

  • The OS will look in the current directory for files if no directory is specified.
  • Processes will be loaded and executed in the order they are specified on the command line.
  • There are two idle processes included. idle.txt will run with lowest priority and will print out 20. It will run forever. idle-n.txt will run for n loops (not cycles), specified in the code. As shipped, idle-n will run for 100 loops.
  • Redirecting OS output to a file is convenient: OS 1024 prog1.txt prog2.txt prog3.txt > output.txt
  • OS.config contains many debug flags that can be included to provide insight into non-debug program execution.
  • OS.config contains many options for configuration of memory. It IS possible to feed invalid values into this config file. For example, it's not valid to have a physical memory size larger than addressable memory, or a page size larger than addressable memory, etc. This behavior is appropriate, and is by design.
  • Setting DumpInstruction=true in OS.config will output the a debug print of the executing instruction and the current process id.
  • If an idle process (idle.txt, etc) isn't included, and all running processes sleep or block on a lock, the OS will spin forever looking for an eligible process to run, and will find none. CTRL-C will exit at this point. This behavior is per spec and by design.
  • The OS will create XML swap files in the current for each memory page swapped. These are cleaned up at startup, rather than shutdown, for purposes of exploration.
  • Batch files for testing purposes are included in this directory.

More Repositories

1

firsttimersonly

The Repository for the FirstTimersOnly movement in Open Source. We want projects to reserve some issues for newbies.
CSS
639
star
2

WindowsTerminalHere

a .inf file for a right click Explorer "windows terminal here" for Windows Terminal until it's supported directly
223
star
3

PowerPointToOBSSceneSwitcher

A .NET core based scene switcher than connects to OBS and changes scenes based note meta data. Put "OBS:Your Scene Name" as the first line in your notes and ensure the OBS Web Sockets Server is running and this app will change your scene as you change your PowerPoint slides
C#
215
star
4

babysmash

The BabySmash game for small kids. Download and run for free at https://www.babysmash.com
C#
212
star
5

Windows-Wifi-Manager

Windows Wifi Manager
C#
156
star
6

SmallestDotNet

SmallestDotNet - SmallestDotNet.com is a single page site that does one thing. It tells you the smallest, easiest download you'd need to get the .NET Framework on your system.
C#
130
star
7

RemoveDotNetCoreSDKInstallers

Removes all the NET Core SDK Installers
PowerShell
101
star
8

TerminalAttractMode

Given a Profile and folder name, rotates the background of a Terminal
PowerShell
99
star
9

dasblog

The old, wonderful, and scalable DasBlog Blogging Engine
C#
93
star
10

ama

Ask me anything
88
star
11

AsteroidsGame

Asteroids Game generated by Scott and Mark Learn to Code, commited directly as written, just after BUILD 2023 keynote. Many many thanks to Yanan Cai for her help and prompt engineering.
C#
79
star
12

Psuedoizer

Psuedoizer - Psuedointernationalization Utility
C#
68
star
13

PrettyWindowsTerminalThings

A place for how to make your Windows Terminal Pretty
67
star
14

dotnetcoreunittestingwithcoverageinvscode

dotnetcoreunittestingwithcoverageinvscode
C#
52
star
15

ASP.NET-MVC-and-DbGeography

EditorTemplates and ModelBinder for ASP.NET MVC 4 when using Entity Framework and Spatial Types like DbGeography
JavaScript
48
star
16

LyncAutoAnswer

Lync 2012 Super Simple Auto Answer Video Kiosk with Full Screen
C#
43
star
17

PanTiltZoomSystem

Logitech Conference Camera BCC950 PTZ (Pan-Tilt-Zoom) Spike Attempt. Needs https://github.com/shanselman/Logitech-BCC950-PTZ-Lib to compile
JavaScript
39
star
18

suavebootstrapper

Suave Azure Bootstrapper
Shell
38
star
19

superzeit

Example ASP.NET Core App made as SMALL as possible for deployment to Zeit.co
C#
34
star
20

howtounmute.com

How many engineers does it take to unmute a conference system? A lot. Here's a repo of how to unmute!
32
star
21

RestoreAfterReloadVSIX

"Workspace Reloader" - Visual Studio Plugin that automatically restores open windows after project reloads.
C#
32
star
22

DasKeyboard-Q-NightScout

Hooking up the DasKeyboard Q REST API to change the key colors in response to diabetic's glucose from NightScout
JavaScript
30
star
23

azure-friday

Bicep
27
star
24

shanselman

25
star
25

PowerShellHgGit

An attempt at making PowerShell get along with both PoshHg *and* PoshGit
24
star
26

NightscoutPyPortal

Nightscout display for an AdaFruit PyPortal
Python
23
star
27

DumpPasswordsWindows8

C#
22
star
28

Logitech-BCC950-PTZ-Lib

.NET library for controlling the Logitech BCC950 Pan Tilt Zoom function. Uses https://github.com/shanselman/DirectShowLib-FORK
C#
22
star
29

ThisDevelopersLife-Transcripts

Transcripts in markdown of episodes of the This Developer's Life Podcast
21
star
30

hanselman.com-bugs

A place for you to file issues/bugs that you've found on Scott Hanselman's blog at http://hanselman.com
17
star
31

DotNetInteractiveExamples

Examples on how to use .NET, C#, and F# in Jupyter Notebooks
Jupyter Notebook
15
star
32

CrowPiDotNetCore

Fun .NET Core Raspberry Pi samples for the CrowPi from Elecrow
C#
15
star
33

microsoft-teams-buttons-for-streamdeck

microsoft teams buttons for streamdeck
13
star
34

AzureFridayToJson

Little console app (soon to be azure function) to make an AF XLS into an AF JSON
C#
13
star
35

learninggit

13
star
36

thisdeveloperslife

The This Developer's Life Podcast Web Site - this code sucks, so be aware.
C#
12
star
37

ImageResizeCore

C#
12
star
38

keysleft

The keysleft website
JavaScript
11
star
39

AspNetPersonaId

Example of integrating ASP.NET Membership and Mozilla's Persona ID System
JavaScript
11
star
40

NightscoutDashboard

Jupyter Notebook
10
star
41

DirectShowLib-FORK

Fork of DirectShowNet. It may be abandoned? Hasn't been touched on http://directshownet.sourceforge.net in 2+ years and I needed to a change to AXExtend.cs. I'll continue to try to get an updated drop of the original, but I'll keep this fork if the original goes away.
C#
10
star
42

get-azure

dotnet install tool get-azure --g
C#
9
star
43

nxslt2

Archive of Oleg Tkachenko's disappeared Nxslt2 project.
C#
9
star
44

Hanselminutes-Transcripts

An attempt to get some proper MD transcripts for the Hanselminutes Podcast
8
star
45

BabySmashWindows10

The Windows 10 port of BabySmash!
C#
8
star
46

NightscoutReminder

This is a small app that gets your NightScout SAGE and CAGE and makes a reminder in your Outlook using Microsoft Graph
C#
8
star
47

ObjectToString

C#
8
star
48

march-is-for-makers

The website for MarchIsForMakers.com
HTML
8
star
49

AdaFruitM4MatrixWithNightScout

Code to run an AdaFruit M4 Matrix display with Nightscout to show your Blood Sugar
Python
8
star
50

NightscoutArduinoPlayground

A little Arduino sketch to show the values of a Nightscout diabetes site on a SeeedStudio LCD
Arduino
8
star
51

aspneteverywheredemo

CSS
7
star
52

MakeCodeLaunchAndCopy

Associates with *.uf2 files and when launched, copies the file to the first drive called CPLAYBOOT
C#
7
star
53

SignalRMonkeys

The SignalR Monkeys
JavaScript
6
star
54

allinonetest

JavaScript
6
star
55

crossplatnet

The website for crossplat
CSS
5
star
56

TweetSandwich

A silly app so I can tweet my order to the local Quiznos
C#
5
star
57

sinatrademo

Ruby
5
star
58

azurefridayaggregator

Fixing Azure Friday by calling a new document API
C#
5
star
59

treehousesample

C#
5
star
60

MyNodeAppOnAzure

JavaScript
5
star
61

myhamsterblog

My 8 year old's page about hamsters
HTML
4
star
62

sharp-lzw

Archived copy of https://code.google.com/archive/p/sharp-lzw
C#
4
star
63

emojimadness

C#
4
star
64

PsuedoizerCore

C#
3
star
65

azure-dashboard-chrome-app-bookmark

Google Chrome "app"
3
star
66

tweakorgstaticsite

HTML
3
star
67

FakeNightscoutPebbleEndpoint

Fake Blood Sugar data to feed Pebble or Band Clients
C#
3
star
68

babysmashwebsite

HTML
3
star
69

CRLFExample

2
star
70

threemammals.com

ThreeMammals website
C#
2
star
71

womenwhocodepdxgit

womenwhocodepdxgit Workshop
Python
2
star
72

Hanselminutes-Images

Images from the Hanselminutes Podcast. Crowdsourcing to complete.
2
star
73

hello-aspnet-kube-pi

2
star
74

AngularNuGet

Downloads Angular JS, separates them, makes NuGets
JavaScript
2
star
75

IfFoundLockScreen

Rescued from BitBucket
C#
2
star
76

addmvc3towebforms

Rescued from BitBucket
Pascal
2
star
77

HanselmannTest

For your eyes only ;)
C#
2
star
78

precode-openlivewriter

Copy of Precode Plugin for WLW/OLW from Precode.codeplex.com. Work originally by Anthony Bouch (http://www.58bits.com)
C#
2
star
79

linkedlists

C#
2
star
80

TwineAzureGarageDoor

A basic ASP.NET service for notifying me that my garage is open using the Twine box from Supermechanical
1
star
81

lostphonescreenwebsite

Website for LostPhoneScreen.com
JavaScript
1
star
82

learninggit2

1
star
83

ghcliblogpost

This is a test for my GH CLI Blog post
1
star
84

lwaas

Last Word as a Service
JavaScript
1
star
85

mysupernodesite

just an azure test
JavaScript
1
star
86

nodetest

JavaScript
1
star