text: 'use strict';(function(){const indexCfg={cache:true};indexCfg.doc={id:'id',field:['title','content'],store:['title','href','section'],};const index=FlexSearch.create('balance',indexCfg);window.bookSearchIndex=index;index.add({'id':0,'href':'/project-halide-website/docs/Getting-Started/','title':"Getting Started",'section':"Docs",'content':"Hello #  "});index.add({'id':1,'href':'/project-halide-website/docs/documentation/','title':"Documentation",'section':"Docs",'content':"HalideOS - Technical Documentation #   github.com/DSC-KIIT/project-halide\nHalideOS is an experimental operating system, written from scratch by the OS team at DSC KIIT. The main motive of this project was to build a basic yet functional operating system from scratch and demonstrate some of the basics of OS theory.\nIf you\u0026rsquo;re new to OS development then please refer the Getting Started section of this website.\nThis part of the website contains technical documentation for some of the important components of HalideOS, the content here will act as an aid to help you understand the source code. HalideOS is written in C++17 with some x86 assembly code for the boot procedure and interrupts.\nThe diagram below represents all the components that come together to make HalideOS work. The best way to understand how Halide does what it does is to read through the source code and keep these docs handy.\n Boot Up #  The boot procedure is implemented in the src/loader.s file. We used the multiboot specification to boot using the GRUB bootloader. After the bootloader transfers control to our OS, we setup the stack so that our C++ code has memory to run on.\nAfter this, the k_main function is called which is the entry point for the kernel.\nKernel #  Implemented in src/kernel.cpp\nAs Halide is a pretty simple OS, all the components comes together in the kernel and are executed from the kernel itself, there is no seperation of user mode and kernel mode. All the further components are imported, initialized and executed from the kernel.\nGlobal Descriptor Table #  Implemented in include/globaldescriptortable.h  and src/globaldescriptortable.cpp\nThese files contain the standard boilerplate code to setup memory segmentation using the Global Descriptor Table. This is explained in more detail in here\nInterrupt Descriptor Table #  Implemented in src/interrupts.h and src/interrupts.cpp. You can read up more about how interrupts work in x86 processors here\nFrameBuffer and Window #  This is an abstraction for the framebuffer device that the BIOS provides us so that we can output text on the screen. You can read more about it here\nThe Window class is just a collection of x and y coordinates with some functions to restrict the cursor on the framebuffer so that the we can divide up the screen and implement a notion of multiple windows. You can read more about it here\nConsole #  Implemented in include/console.h and src/console.cpp\nThis part of the code enables the user to type in commands in the console and get the results. A detailed explaination of the console is given here\nHalide Standard Library #  Implemented in include/halidestdlib.h and src/halidestdlib.cpp\nA set of some standard data structures and functions used to implement features and console commands. You can read about it here\n"});index.add({'id':2,'href':'/project-halide-website/docs/documentation/Console/','title':"Console",'section':"Documentation",'content':"Console Commands in HalideOS #  The console in Halide is pretty simple. Just a while loop that evaluates the the commands entered by the user using a big nested if else, and then defers execution of the command to the proper functions.\n Files: include/console.h and src/console.cpp  The console supports the following commands\n about help greet calculator - A basic command line calculator clear switch console - Switches to the next console  Refer the src/console.cpp file to look at the implementation of these commands. Most of them are pretty simple as they just print text on the framebuffer.\nThe calculator is the only command that does some work, it evaluates the passed expression and returns the results. We implemented a standard infix to postfix converter and evaluated that postfix expression. The calculator is the reason we implemented a stack abstraction in the standard library.\n"});index.add({'id':3,'href':'/project-halide-website/docs/documentation/Frame-Buffer/','title':"Frame Buffer",'section':"Documentation",'content':"The Frame Buffer #  HalideOS uses the APIs provided by the BIOS to display text on the screen. We did not implement drivers for the graphics hardware to keep the code simple. BIOS implements a combination of memory-mapped I/O and I/O ports system to manipulate the screen and display the text.\nMemory Mapped I/O and I/O Ports #  There are usually two different ways to interact with the hardware, memory-mapped I/O and I/O ports.\nIf the hardware uses memory-mapped I/O then you can write to a specific memory address and the hardware will be updated with the new data. One example of this is the framebuffer. For example, if you write the value 0x410F to address 0xB8000, you will see the letter A in white color on a black background, will explain this in later sections.\nIf the hardware uses I/O ports then the assembly code instructions out and in must be used to communicate with the hardware. The instruction out takes two parameters: the address of the I/O port and the data to send. The instruction in takes a single parameter, the address of the I/O port, and returns data from the hardware.\nWhat is the FrameBuffer ? #  The framebuffer is a hardware device that is capable of displaying a buffer of memory on the screen. It has 80 columns and 25 rows, and the row and column indices start at 0 (so rows are labelled 0 - 24). You can think of it as a 2D matrix of 80x25.\nDisplaying Text on the Screen #  The starting address of the memory-mapped I/O for the framebuffer is 0xB8000. The memory is divided into 16 bit cells, where the 16 bits determine both the character, the foreground color and the background color.\nThe highest eight bits is the ASCII value of the character, bit 7 - 4 the background and bit 3 - 0 the foreground, as can be seen in the following figure:\nBit: | 15 14 13 12 11 10 9 8 | 7 6 5 4 | 3 2 1 0 | Content: | ASCII | FG | BG | There are a set of 15 colour codes for foreground and background, these are hardcoded in the driver\nMoving the Cursor #  Moving the cursor of the framebuffer is done via two different I/O ports.\nThe cursor’s position is determined with a 16 bits integer:\n 0 means row zero, column zero 1 means row zero, column one 80 means row one, column zero and so on.  Since the position is 16 bits large, and the out assembly code instruction argument is 8 bits, the position must be sent in two turns, first 8 bits then the next 8 bits.\nThe framebuffer has two I/O ports, one for accepting the data, and one for describing the data being received. Port 0x3D4 is the port that describes the data and port 0x3D5 is for the data itself.\nOn 0x3D4:\n Writing the integer 14 tells the framebuffer to expect the highest 8 bits of the position Writing the integer 15 tells the framebuffer to expect the lowest 8 bits of the position   The FrameBuffer driver in HalideOS #  The driver is encapsulated in the FrameBuffer namespace. It has 2 components, FrameBuffer::Colours namespace has all the hex codes for the supported colours and the FrameBuffer::Writer class has all the functions to manage the cursor and the text on the framebuffer.\n Files : include/frame_buffer.h and src/frame_buffer.cpp Namespaces: FrameBuffer, FrameBuffer::Colours Classes: FrameBuffer::Writer  FrameBuffer::Colours #   All available colours - Click to expand ↕  namespace Colours { static const unsigned char BLACK = (unsigned char)0x0; static const unsigned char BLUE = (unsigned char)0x1; static const unsigned char GREEN = (unsigned char)0x2; static const unsigned char CYAN = (unsigned char)0x3; static const unsigned char RED = (unsigned char)0x4; static const unsigned char MAGENTA = (unsigned char)0x5; static const unsigned char BROWN = (unsigned char)0x6; static const unsigned char LIGHT_GREY = (unsigned char)0x7; static const unsigned char DARK_GREY = (unsigned char)0x8; static const unsigned char LIGHT_BLUE = (unsigned char)0x9; static const unsigned char LIGHT_GREEN = (unsigned char)0xa; static const unsigned char LIGHT_CYAN = (unsigned char)0xb; static const unsigned char LIGHT_RED = (unsigned char)0xc; static const unsigned char LIGHT_MAGENTA = (unsigned char)0xd; static const unsigned char LIGHT_BROWN = (unsigned char)0xe; static const unsigned char WHITE = (unsigned char)0xf; } // namespace Colours     FrameBuffer::Writer #  Functions (all public)\n Writer(const unsigned char \u0026amp;foreground, const unsigned char \u0026amp;background, Window*) void clearLine(unsigned char from, unsigned char to) void clearScreen() void initScreen(const unsigned char \u0026amp;foreground, const unsigned char \u0026amp;background) void setColorTheme(const unsigned char \u0026amp;foreground, const unsigned char \u0026amp;background) void writeString(char *str, unsigned char = FrameBuffer::Colours::WHITE) void writeHex(unsigned char key) void fillRemeaning(char *, bool) void writeAtIndex(int) void switchWindow(Writer \u0026amp;) void clearCursor() void shiftCursor(int, char *) void updateCursor() void Rerender(Window*)  Refer the source code for more details on the implementation.\nReferences #   https://littleosbook.github.io/#output  "});index.add({'id':4,'href':'/project-halide-website/docs/documentation/Keyboard-Driver/','title':"Keyboard Driver",'section':"Documentation",'content':"The Keyboard Driver #  The keyboard driver does the task of reading the input coming from the keyboard and writing it to the screen using the FrameBuffer driver. The keyboard driver uses I/O ports mapped to memory addresses 0x64 and 0x60 to read the data coming from the keyboard.\nEvery time a key on the keyboard is pressed, 0x64 is set and an 8 bit integer is available in 0x60 which is passed to a massive switch case that appropriately writes the text on the screen. The entered text is also stored in a character buffer, the pointer to this buffer is returned when the enter key is pressed.\nThe driver is wrapped in the KEYBOARD_DRIVER namespace with just one function,\n  char *readInput(FrameBuffer::Writer \u0026amp;p, int mode = 1)\nReturns a char* to the entered text while writing those characters to the FrameBuffer::Writer passed.\nmode=1 is normal mode and mode=0 is password mode, just prints *.\n  Refer the source code for more details on the implementation.\n"});index.add({'id':5,'href':'/project-halide-website/docs/documentation/Standard-Library/','title':"Standard Library",'section':"Documentation",'content':"The Standard Library #  The standard library of HalideOS is a set of a few abstractions for some common data structures and utility functions that we used to again and again for the kernel as well as the shell programs.\nAll the classes and the functions are encapsulated in the hldstd namespace for clarity.\n Files: include/halidestdlib.h and src/halidestdlib.cpp Namespaces: hldstd, hldstd::math  Classes  hldstd::string hltstd::stack\u0026lt;T\u0026gt;   Functions Refer below for details on return types with accurate namespaces.\n hldstd::stringCompare hldstd::stringLength hldstd::math::pow hldstd::math::abs     Classes #  hldstd::string #  A regular string class to maintain a character array and it\u0026rsquo;s size, with some conversion functions.\nFunctions\n string(int x); - Contructor to convert int to string string(double x, int digits_after_point); - Constructor to convert double to string string(char *str); - Constructor to convert a raw char* to string string(bool val); - Constructor to convert bool to string string(string \u0026amp;other); - Copy Constructor int size(); - Returns size of the string char at(int i); - Returns the character at index i of the string char *c_ptr(); - Returns a raw char * to the string int to_int(); - Converts the string to int double to_double(); - Converts the string to double   Examples - Click to Expand ↕  #include \u0026lt;halidestdlib.h\u0026gt; // Various ways to construct a hldstd::string hldstd::string a = \u0026#34;From char *\u0026#34;; hldstd::string b = 10; hldstd::string c = false; hldstd::string d(10.21343, 3); hldstd::string e = a; // Utility Functions hldstd::string s = \u0026#34;FooBarBaz\u0026#34;; int s_size = s.size() // returns 9 char s_char = a.at(3) // returns \u0026#39;B\u0026#39; char* s_ptr = s.c_ptr() // returns a pointer to \t// the char array stored in the class  // Conversion hldstd::string i = \u0026#34;1201032\u0026#34;; hldstd::srting j = \u0026#34;1213.21434\u0026#34; int i_int = i.to_int(); // return 1201032 double j_double = j.to_double(); // returns 1213.21434      hldstd::stack\u0026lt;T\u0026gt; #  A standard stack or LIFO list with the standard operations. This is a template class, the stack can hold any data-type T\nFunctions\nAll functions are template functions with \u0026lt;typename T\u0026gt;\n stack(int size, T x); - Constructor to initialise the stack with size and the first element; bool pop(); - false for underflow, true for successful pop bool push(T x); - false for overflow, true for successful push T top(); - Returns the top element of the stack bool isEmpty(); - Check if stack is empty or not.   Examples - Click to Expand ↕  #include \u0026lt;halidestdlib.h\u0026gt; hldstd::stack\u0026lt;int\u0026gt; st(20, 0); st.push(1); st.push(2); st.push(3); st.pop(); int x = st.top(); // returns true bool e = st.isEmpty(); // returns false      Functions #  Some simple mathematical functions are declared in the math namespace.\n int hldstd::stringCompare(char *, char *) - Compare 2 strings from the char pointers int hldstd::stringLength(char *) - Get length of string double hldstd::math::pow(double x, int y) - x^y int hldstd::math::abs(int x) - |x|  "});index.add({'id':6,'href':'/project-halide-website/docs/documentation/Windows/','title':"Windows",'section':"Documentation",'content':"Windows in HalideOS #  We have added support to divide the screen into multiple consoles. It is very similar to diving a linux terminal into multiple parts. This was done using a Window class that is passed to the FrameBuffer::Writer so that it can restrict the movement of the cursor in the limits defined in the Windows class.\n Files: include/windows.h  Its a pretty small class, everything is done in the header file, you can refer the source code to understand what it does.\n"});index.add({'id':7,'href':'/project-halide-website/docs/Getting-Started/Introduction/','title':"Introduction",'section':"Getting Started",'content':"Introduction to Operating Systems Development #  Please proceed with a really good grasp of C/C++ If you landed here then, congratulations! You are about to take on one of the most challenging projects in Software Engineering, that is, Operating System Developement. There are no proper roadmaps, no copy-paste code and lots of theory. You\u0026rsquo;ll be guided solely by passion and you will truly peak once you dive into the depths of OS Dev.\nYou need to be able to understand how hardware works, read and write assembly code to boot up your kernel and fairly good C/C++ code to add other features. It will require time, patience and careful code designs filled with abstractions.\nIf the prerequisites sound overwhelming, maybe this is not the right time for you to get into OS Dev. It\u0026rsquo;s not a week-long project that you can just be done with. It may takes months of work to take care of every possible test case for one typo, one loophole, will be enough to break your system. in short, this is an ongoing process.\nFinally, this is not the guide to make the next Linux or Windows. This is a beginners guide based on our mistakes and learnings as we proceeded to make the experimental Halide OS.\nContents - #   Motivation Rules and Goals Basic Definitions Essential Tools Choose your Development Environment  Motivation #  When you write a program and it runs too slow, but you see nothing wrong with your code, where else will you look for a solution. How will you be able to debug the problem if you don’t know how the operating system works? Are you accessing too many files? Running out of memory and swap is in high usage? But you don’t even know what swap is! Or is I/O blocking?\nWhile the extend and depth of knowledge can be questioned, knowing more than the fundamentals can be critical to how well your program runs and even its structure and flow.\nRules and Goals #  It is not okay to write average code thinking that the computer will take care of it Have a plan. What exactly do you want your system to do? Reach for the stars and maybe you\u0026rsquo;ll land on the moon.\nBasic Definitions #  Operating System #  In the Kingdom of Hardware, the national language is machine code comprising of 0\u0026rsquo;s/1\u0026rsquo;s, on\u0026rsquo;s/off\u0026rsquo;s etc. But since it was useless on its own, it was merged with the Kingdom of Software where everyone spoke various low to high-level languages. This led to mass confusion as the Hardware residents couldn\u0026rsquo;t understand Software residents and vice-versa. To solve this problem, a translator called Operating System was called.\nAn Operating System is a framework that tells your computer how to use its hardware. Specifically, it hides hardware complexity, manages memory and other system resources, schedules and multiplexes processes and threads, provides a basic user interface and application programmer interface, also focussing on isolation and protection. Not every Operating System in the market provides all these functionalities. Therefore you have to be clear with your goals.\nSome popular examples include Windows which has a huge user base, Linux which is lightweight because of small, specific components ( distributions) making it highly customizable but less user-friendly and the BSD triplets for server related tasks.\nKernel #   The kernel is like a traffic cop. It stands between your computer\u0026rsquo;s hardware and the applications that you want to run. It allocates memory, keeps track of file systems on your disk drives, and it divides up time so that each program gets its turn to use your computer\u0026rsquo;s resources.\n Operating systems are mostly about drivers. That\u0026rsquo;s more than 90% of a kernel. So a kernel is the core of an OS that is invisible and the only time you\u0026rsquo;ll see it is when it panics, calls in backup and arrests everyone in case there\u0026rsquo;s a crime going on.\nShell #  A shell is a program which acts as an interface between humans and the kernel. Since we cannot talk to this program directly, we can use commands (command line) or a mouse (file explorer) to perform basic tasks like starting a program, managing files, etc. But where do we write these commands? That\u0026rsquo;s where the Terminal comes in which tells the shell what to do.\nGUI #  A Graphical User Interface is the visible part of an Operating System that helps you modify the features of your Operating System. It does that via graphics as opposed to textual interfaces like the Terminal. A GUI simply redraws parts of the screen depending on the user input solving the blank screen problem found in early Operating Systems. This provides a better user interface.\nEmulation and Virtualization #  Virtualization is like moving into a house that already has basic utilities like plumbing electricity, etc whereas Emulation is where you\u0026rsquo;re basically building a house from scratch.\nThe purpose of an Emulator is to accurately reproduce the behavior of some hardware so as to seek independence from the hardware of the host machine. We want to do this for testing purposes since the primary goal of an Operating System is to be hardware-independent.\nWhile emulated environments require a software bridge to interact with the hardware, Virtualizers access hardware directly. However, despite being the faster option, virtualization is limited to running software that was already capable of running on the underlying hardware.\nEssential tools #  Choose your Development Environment #  GNU/Linux #  Windows #  "});index.add({'id':8,'href':'/project-halide-website/docs/Getting-Started/Required-Knowledge/','title':"Required Knowledge",'section':"Getting Started",'content':"Required Knowledge #    Basic Computer Programming\n  Microprocessor architechture\n  Assembly\n  Memory\n  UNIX/ Linux Experience\n  Version Control\n  "});index.add({'id':9,'href':'/project-halide-website/docs/Getting-Started/Resources-and-Tutorials/','title':"Resources and Tutorials",'section':"Getting Started",'content':"Resources and Tutorials #  A massive list of all sorts of tutorials, books and videos on operating systems.\nWeb #   https://wiki.osdev.org/ http://www.lowlevel.eu/wiki/Hauptseite https://github.com/cfenollosa/os-tutorial  Books #   http://www.cs.bham.ac.uk/~exr/lectures/opsys/10_11/lectures/os-dev.pdf https://littleosbook.github.io/ Operating System Concepts - Galvin and Silberschatz Modern Operating Systems - Andrew Tanenbaum and Herbert Bos Operating Systems: Three Easy Pieces - Andrea C. Arpaci-Dusseau and Remzi H. Arpaci-Dusseau  Videos #   https://www.youtube.com/playlist?list=PLHh55M_Kq4OApWScZyPl5HhgsTJS9MZ6M  "});index.add({'id':10,'href':'/project-halide-website/docs/Getting-Started/Running-Halide/','title':"Running Halide",'section':"Getting Started",'content':"Running HalideOS on your System #  Dependencies #  It is recommended that you used a Linux based operating system for building HalideOS. The C/C++ development tools and ecosystem are much easier to use on a Linux based system.\n g++ - A C++ compiler nasm or as - An x86 assembler ld - The GNU Linker make - GNU Make, a build tool for linux qemu - An x86 Emulator git - For version control A text editor of your choice, we use Visual Studio Code  You can google up how to install these tools for your host operating system. On linux based systems you will mostly install them using your package manager.\n"});})();