LoIS
|
The Loader Introductory System
|
A Tutorial on Operating System Implementation
|
version 0.1.1
|
11 June 2002
|
last modified 8 December 2002
|
Copyright (C) Joseph Osako 2002.
|
Contents
|
Since the late 1980s, there has been a growing number of programmers
and who have been experimenting with designing and coding their own operating
systems, a trend which has accelerated with the increasing acceptance of
alternative, Open Source systems such as Linux and FreeBSD. Driven by
curiosity, dissatisfaction with the existing systems, or the ambition to
make a mark on the computer world, thousands of would-be OS designers have
delved into the arcana of the x86 platform, hoping to create a new vision
of how computers can be made to work.
Sadly, the vast majority of these potential Dennis Ritchies soon find themselves lost in a maze of confusing, incomplete and often contradictory information about OS design in general and the PC platform in particular. Finding even the most basic information can an arduous process. Worse, Many programmers often jump into the process too quickly, expecting to work out the details as the go along. Many quickly get bogged down by the minutiae of the project, unable to even find the information they need, while others charge headlong into one seemingly impenetrable obstacle after another until their enthusiam fails. The most common pitfall in writing an operating system for the PC is in the boot loader, the very first part of a system that runs on startup. Nearly every OS coder falls into the alluring assumption that, as the start of the system's operation, the boot loader is also the logical place for the OS designer to begin coding. This, sadly, is usually a grave error: the boot loader is deceptively complex for so small a fragment of code, and requires finely honed skills that few other parts of an OS call for. The boot loader, far from being the key to an OS project, is often it's tomb. While it is a necessary part of a free-standing system, the boot loader bears little relationship to the system as a whole, being concerned only with the very earliest stages of operation. Given it's minimal importance to the overall operation, it is rarely wise to invest a large amount of effort into the boot loader, yet the difficulties it presents are often far greater than those of the more elaborate constructs that make up the rest of an operating system. With the rise of general-purpose boot loaders such as GRUB, it is no longer even a required step in OS design; yet nearly all OS designers insist on writing a unique boot loader for their system, often with the result that the effort comes grinding to a halt. Furthermore, even for developers who use an existing loader, it is still important for them to understand the details of the boot process, in order to start their kernel up from the boot loader. It was to address these issues that LoIS (Loader Introductory System) has been created. It is meant as a thorough, step-by-step tutorial explaining how a basic boot loader runs, what it must do and cannot do, and how it relates to the system as a whole. To this end, we will go through the process writing, testing and debugging a working boot loader and a simple operating system for it to load and initialize. The LoIS OS, while small, will be a fully functional multitasking kernel with a simple user shell and support for the FAT12 file system. While it is primarily meant to demonstrate the boot loader, it will go well beyond that goal. The greatest emphasis will be placed on clarity of the code. To this end, the entire LoIS system is being coded in the manner of Literate Programming, in which code and documentation exist intertwined. Each example is meant to build upon those previous. The importance of continuous, rigorous testing is also emphasized; all code examples are running parts of the system at some stage of it's development, and carefully tested for correctness. LoIS itself is envisioned as one of a series of tutorials covering OS and language implementation in close detail. The initial version of LoIS runs entirely in 'real mode', the original operating mode of the x86 family of processors. A later tutorial, building on the experience gained in LoIS, will demonstrate the process of setting up a protected mode system, while a third will show the use of GRUB as a boot loader. LoIS itself is not, however, a complete course on operating systems design. It is meant, first and foremost, to address the need for a comprehensive, detailed explanation of the low-level details of the IA-32 platform; as such, it uses only the simplest approaches to important questions such as task scheduling and deadlock prevention. The essays in this series would best be used along with a more general text on systems programming, as a lab manual or vade mecum. It is certainly not meant as a paradigm which later OS developers should follow! Nonetheless, it is felt that, by taking 'the hard way' through the process, it would make it easier for the readers to then apply themselves to more productive approaches when the actually begin working on designs of their own. |
When a PC computer is turned on from an off position, there are no programs
loaded into the main random access memory (RAM). In order for the computer to
being working, it is necessary for it to have a program fixed permanently in
Read Only Memory (ROM) which can perform most basic functions of testing and
initializing the system. It is possible to design a system that does not need
any more of an operating system than that; many early home computers worked
in just this fashion. Unfortunately, a completely ROM OS would be unacceptably
rigid, and difficult to fix if any bugs arose.
In order to allow for a more flexible approach, it is necessary to allow the system to read it's OS software from a floppy disk or similarly modifiable medium. However, the ROM is still limited in what it can load to start with; it can only load up a small fraction of the full system. the software on the disk has to complete the process of loading the system as a whole, sometimes in several stages. The process of loading up the operating system this way is called bootstrapping (from the metaphor of 'lifting yourself up by your own boot straps'), or booting for short. The program that the ROM loads is called a bootstrap loader, or just boot loader, and the area at the beginning of the disk which the ROM loads it from is called the boot sector. |
When an x86 PC starts from power on, or after a reset, it begins by trying to run the instructions beginning at absolute memory location 0xFF000. This is a hardwired behavior in the CPU itself, which cannot be changed. In the PC, this location is the beginning of the ROM BIOS, a fixed area of memory holding non-volatile (i.e., it doesn't go away when the power is turned off) software and data. This software is the first program the system runs every time it is restarted, and it performs all of the tasks needed to get the system ready to operate: it tests the hardware, it reads the information needed to find and initialize the peripherals, and finnally, it begins the process of starting the operating system by loading and running the boot sector. |
The first operation which the system runs is the Power On Self-Test (POST). |
TBD |
TBD |
It should be clear by now that the development of an Operating System is far
beyond the scope of a novice programmer. It is assumed that the reader has a
suitable understanding of basic programming concepts, and is well-versed in
the use of one or more existing operating systems. A background in assembly
language programming on the x86 platform is valuable, but the material is
presented in a manner such that a careful reader should be able to follow the
material with only a basic knowledge of the intruction set and the memory
models. An understanding of PC hardware is useful, but not necessary, as most
specific systems used are described in detail in the text.
It is highly recommended that the reader review a text on the general subject of operating system theory and design before reading this text. Because this text concentrates on implementation, rather than theory, some familiarity with OS design concepts is assumed in places. An effort has been made to use simple, familiar models for all major design issues where possible. |
While the authors have tried to avoid any serious bias in the operating system used for cross-development, it is nonetheless the case that the material is presented with the expectation that most readers will be using some flavor of either Microsoft Windows or Linux, those being the most common operating systems at the time of this writing. Where necessary, the text will specify which system a given piece of information is relevant to, and will try to support both Windows and Linux equally. The majority of material given for Linux should be applicable (with perhaps some minor adjustments) to most other Unix or Unix-like systems. |
Unless specified otherwise, all code presented in this project is written in x86 assembly language, specifically the dialect used by the Netwide Assembler (NASM). The decision to use an exclusively assembly-based software base has many reasons, not the least of which is simplicity: of all the languages one could use to write an OS, only assembly language is an absolute requisite. By sticking to assembly language throughout, it is hoped that the project will retain a coherency that could be otherwise lost. |
NASM is an open source program, and distributed under the GNU General Public License v. 2. A copy of NASM, with full license and documentation, is bundled with the downloadeable version of LoIS. Current versions and further information can be obtained at the NASM Project home page, http://nasm.sourceforge.net/. This address is subject to change without notice. |
TBD |
This document has been prepared using the techniques of Literate Programming,
a programming methodology developed by Dr. Donald Knuth at Stanford University.
It strives to improve the quality of both code and documentation by presenting
programs as prose, with the intention of requiring the writer/programmer to
explain in depth the code as it is being created. The writer is expected to
use markup to indicate which parts of the document at text and which are code.
From this parent document, the LP tools can then extract and rearrange (tangle)
the source code, and mark up (weave) the final reader's document for
typesetting.
The specific LP toolset used is FunnelWeb, developed by William Ross of Rocksoft. It is unusual among LP tools in that it is programming-language independent, and that it will produce HTML markup for Web design as well as TeX typesetting markup. It is for these qualities, as well as its stability and through documentation, that it was chosen for this project. Versions of FunnelWeb exist on Windows, MacOS, Linux, and FreeBSD platforms. |
FunnelWeb 3.2 is bundled with the downloadable version of LoIS. More recent versions and full package documentation can be obtained from author Ross Williams' Funnelweb page, http://www.ross.net/funnelweb/. This address is subject to change without notice. |
User's looking to install the FunnelWeb software for use should refer to
the FunnelWeb User's Manual for detailed instructions.
To use FunnelWeb to produce both the HTML formatted documentation and the NASM source code for the LoIS system, the following command line string should be used: fw +ULoIS.html Lois.fw |
An effort has been made to ensure that all source code is correct and accurate, but in any project such as this errors and bugs will inevitably arise. All assembly language source code presented, when weaved using FunnelWeb, have been tested and successful assembled using NASM 0.98, and run under BOCHS 2.0 prerelease 2. Due to unforseeable variances in different systems, this code cannot be guaranteed to run on all PC-compatible hardware platforms. |
Unless specificed otherwise, all documents and source code of the LoIS Project
are copyrighted under the GNU General Public License, version 2. Copies of the
source code and documentation may be freely distributed and modified, as
according the the provisions therein.
To this end, every program generated by LoIS will include the following boilerplate comments: |
1. Legal Disclaimer[M]={
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; LoIS - A tutorial on Boot Loading for the IA-32 PC
; Copyright (C) 2002 Joseph Osako Jr.
;
; This program is free software; you can redistribute it and/or modify
; it under the terms of the GNU General Public License as published by
; the Free Software Foundation; either version 2 of the License, or
; (at your option) any later version.
;
; This program is distributed in the hope that it will be useful,
; but WITHOUT ANY WARRANTY; without even the implied warranty of
; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
; GNU General Public License for more details.
;
}
Now that we have established the basic concepts of the boot process, we can begin to implement it. The first step is to write a version that will load correctly, and enter a infinite loop. We will call this program 'LoIS-0.asm', for LoIS version 0.0; later versions will be 'LoIS-1.asm' for LoIS 0.1, 'LoIS-2.asm' for LoIS 0.2, and so forth. We shall begin by laying out an outline of the program as shown below: |
2. File: LoIS-0.asm={
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;; LoIS-0.asm
;;; Joseph Osako 13 July 2002
;;;
Version 0.0 Program Goals
Legal Disclaimer
Set the Instruction Bit Width
Set the Origin of the Bootstrap Code
Begin the Program Code
Exit
Boot Block Footer
}
The first two parts, the header and program goals, give the name of program and the programmer(s) who worked on it. Following this is a brief statement of the design intentions for the current version: |
3. Version 0.0 Program Goals={
;; Goals:
;; - demonstrate the absolute minimum requirements of a boot sector
;; - create a simple boot program that goes into an infinite loop
}
The remaining sections will be explained in detail below. |
Before it can begin generating any code, NASM has to know certain things about the program you are assembling. In this case, all this means is that you have to tell it to generate 16 bit instructions, instead of 32-bit instructions. This can be done using the BITS directive. |
4. Set the Instruction Bit Width[M]={
[BITS 16]
}
5. Begin the Program Code[M]={
;***************************************************
; start
; This is the beginning of the boot block code.
start:
}
The code segment (CS) register points to the first memory location in the segment containing the actual program instructions. The BIOS by default initializes the code segment to 0000, so that the complete address of the entry point is 0000:7C00. That is to say, when the boot program starts, the Instruction Pointer reads 0x7C00, and the CS register read 0000. However, the assembler does not know what kind of program we are writing, and where it will start, In order to keep track of where the labels are in memory, we have to inform it of the starting point. To do this we use the ORG directive (short for ORiGin): |
6. Set the Origin of the Bootstrap Code[M]={
[ORG 0x7C00]
}
This informs the assembler to count the memory locations starting from 0x7C00
instead of from 0x0000.
The actual assembly code is simply a loop that jumps back on itself; the SHORT directive means it should jump relative to the address of the instruction, rather than to a fixed address in the segment. The dollar sign ('$') is a special directive meaning 'the address of current instruction'. |
7. Exit[M]={
jmp SHORT $
}
We have now finished all of the actual code of the boot block program, and are almost ready to assemble our code. One detail still remains, however. Most, but not all, PCs check the last two bytes of a boot sector for a special code, the bootable disk signature, before trying to boot from it. Without it, the PC assumes that the floppy is a data disk, and returns a 'no operating system' message or somthing similar. So wee need to add this special code to our disk: |
8. Bootable Disk Signature={
bootsig dw 0xAA55
}
(the DW directive means 'Define Word', and allows you to define variables
two bytes at a time. There is also a DD or Define Doubleword, which
defines chunks of 4 bytes at a time.)
There is only one problem: how do we make sure that it get put into the last two bytes of the sector? The easiest way is to simply fill the space between the end of the data and the last two bytes with zeroes: |
9. Space Filler={
space times (0x0200 - 2) - ($-$$) db 0
}
What this does is it defines the label 'space' as a variable whose size is the difference between the beginning of the label and the beginning of the code ('$$'), subtracted from 0x200 (512 decimal) minus 2. This, followed by the boot signature, gives us the footer or end of the boot block. |
10. Boot Block Footer[M]={
;;;;;;;;;;;;;;;;;;;;
; Boot Block footer - fills all but the last two bytes
; with zeroes, and then includes the boot signature
Space Filler
Bootable Disk Signature
}
This is what the whole boot program looks like:
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;; LoIS-0.asm ;;; Joseph Osako 13 July 2002 ;;; ;; Goals: ;; - demonstrate the absolute minimum requirements of a boot sector ;; - create a simple boot program that goes into an infinite loop ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; LoIS - A tutorial on Boot Loading for the IA-32 PC ; Copyright (C) 2002 Joseph Osako Jr. ; ; This program is free software; you can redistribute it and/or modify ; it under the terms of the GNU General Public License as published by ; the Free Software Foundation; either version 2 of the License, or ; (at your option) any later version. ; ; This program is distributed in the hope that it will be useful, ; but WITHOUT ANY WARRANTY; without even the implied warranty of ; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ; GNU General Public License for more details. ; [BITS 16] [ORG 0x7C00] ;*************************************************** ; start ; This is the beginning of the boot block code. start: jmp SHORT $ ;;;;;;;;;;;;;;;;;;;; ; Boot Block footer - fills all but the last two bytes ; with zeroes, and then includes the boot signature space times (0x0200 - 2) - ($-$$) db 0 bootsig dw 0xAA55 |
In order to test the boot loader, we must first convert it into a binary file
using a program called an assembler. The assembler reads in the assembly
language instructions and generates binary machine code from them. The
specific assembler which LoIS uses is Netwide Assembler, or NASM. In order
to assemble the program using NASM, you would have to enter at the command
line:
nasm -fbin LoIS-0.asmThis will generate an output file named 'LoIS-0' in raw binary format (specified by the option '-fbin'). This file can then be tested using the BOCHS emulator by copying the data into a clean boot.img file. In Windows, enter at the prompt, copy a.img boot.img partcopy LoIS-0 0 200 boot.img 0in Linux, the equivalent command would be cp a.img boot.img dd if=LoIS-0 of=boot.img bs=512 count=1In either case, you should then edit the BOCHS rc file (bochsrc.txt or .bochsrc, as appropriate) so that the floppy information reads floppya: 1_44="boot.img", status=insertedNow, when you run BOCHS, it should run your bootsector in boot.img. Once you have this working in BOCHS, you can copy it to a floppy disk and try to run it on an actual computer (using a computer other than the one you use to develop you software on is advisable). This can be done in Windows by the command partcopy LoIS-0 0 200 -f0or in Linux with dd if=LoIS-0 of=/dev/fd0 bs=512 count=1Once the raw image has been written to the disk's boot sector, shut down and reboot the computer with the disk inserted (make sure that your BIOS is set to trying booting from the floppy disk first, before trying to boot off of the hard drive). It should run the program and do... well, nothing. A pretty disappointing result for all that work, isn't it? What is really needed is a way for the boot program to show that it is working. This is what will be done in the next chapter. |
In testing the first version of the boot program, we ran into a serious problem: it didn't do anything. Except by checking the post-mortem dump in the BOCHS output file, there was no way of telling that it was working. To fix this problem, we'll now change the program so that it prints out a simple message before stopping. Along the way, we'll see what is needed in order to work with strings of data, how to set up the segment registers, and how to call the ROM BIOS functions. |
11. File: LoIS-1.asm={
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;; LoIS-1.asm
;;; Joseph Osako 13 July 2002
;;;
Version 0.1.0 Program Goals
Legal Disclaimer
Constant Declarations
Set the Instruction Bit Width
Set the Origin of the Bootstrap Code
Jump to the Starting Point
Begin the Program Code
Initialize the Segment Registers
Print Message to the Screen
Exit
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; data
Bootup Message
Boot Block Footer
}
The goals in this version are only slightly more involved that the previous version: |
12. Version 0.1.0 Program Goals={
;; Goals:
;; - show how to set the code segment and instruction pointer
;; - show how to set the data segment register
;; - demonstrate how to declare constants and set aside space
;; for variables
;; - print a simple message upon boot up and halt
}
When the system starts up, the BIOS has to run several different routines before passing control back to the boot loader. Usually, this means that the code segment (CS) is still set to the base of memory (0000) when the boot loader starts. Unfortunately, not all BIOSes do this, and if your boot block runs one one of these computers expecting it to be set, it may cause the bootup to fail when it tries to use an NEAR label. Thus, it is a good idea to intentionally reset the CS register. To do this, you perform a FAR jump to the start: label. |
13. Jump to the Starting Point={
JMP 0000:start
}
In addition to the code, the boot block contains data the boot program
needs in order to run. Since the code and data are all in the same
segment, the easiest way to handle the data segment (DS) register
is to set it to equal the CS register.
However, there remains one problem; you can't move values directly from one segment register to another! This is one of the peculiarities of the x86 design that many programmers run into trouble with. In order to get around it, you have to move the value of the CS into one of the general purpose registers first, and then from there copy the value to the DS: |
14. Initialize the Segment Registers[M]+={
mov ax, cs
mov ds, ax ; set DS == CS
}
Now that we've made sure we can read our data, we need write the part that prints the data, and to define the data itself. |
The data we want to use is simple: the string "Hello, World!". To define it, we use a directive called DB, which stands for Define Byte. The definition for our string is: |
15. Bootup Message[M]={
message db "Booting LoIS", EOL
}
You'll notice that after the message string, there is another piece
of data added as well without a label, EOL. This byte, called a
delimiter, is used to let the print function know when it has reached
the end of the string, and to stop printing. It is a common practice
that should be familiar to most C programmers.
But what is EOL? In this case, it is simply 0x00 (zero). This is the same convention that C uses, and it convenient for our purposes, for reasons that will be explained shortly. However, NASM does not have a constant named EOL built into it; to let the assembler know what it means, we need to use yet another directive, called EQU (short for EQUate or EQUals). The definition for EOL is: |
16. Constant Declarations[M]+={
EOL equ 0x00 ;end of line marker
}
These two directives differ in one crucial way: EQU declares a constant name, which is replaced by it's value at assemble time, while DB and its relative RESB (REServe Byte) set aside a section of memory to hold the value it is initialized with. This is very important to remember, as it means that a the name of a DBed location is in fact a type of label, the same as those used for jumps and loops. it also means that the data takes up actual memory space at the point in the instruction/data stream it is defined at. This makes it potentially very dangerous to mix code and data declarations carelessly, as it could result in the CPU trying to interpret you data as instructions, usually with unpredictable results. |
Now we have come to the part you've been waiting for: print the "Hello, World!" string. Fortunately, the hard work of writing a function to put characters on the screen do has already been done for you, in the ROM BIOS. We can use a BIOS routine which writes to the screen one character at a time and moves the cursor forward, as if it were an old-fashioned teletype machine. |
To call the BIOS function, we need to use what is called an interrupt. This is a special instruction that says to the CPU, 'drop everything and take care of this right now'. These calls are referred to as 'soft' interrupts, as opposed to 'hard' interupts, which are messages to the CPU from peripherals such as the hard disk or the keyboard. Every interrupt has a 1 byte code number. When the interrupt occurs, the CPU looks up that number in a table located in the first 256 bytes of memory, and jumps to the function (called an interrupt handler) that the table entry points to. Before the BIOS loads the boot sector, it initializes some interrupts to point to useful functions in the BIOS, so that programmers can use them and not have to reinvent the wheel every time they need to use the floppy drive or the text screen. But why use the interrupts? Why not just provide a list of function call locations for the programmers to use? The reason is that the system designers over time have had to modify the BIOS, fixing bugs and adding new features. As a result, the locations of the functions have changed with each new revision of the BIOS. If the programmers called the BIOS directly, every program would have to different from every ROM revision, and it would be impossible to write programs that worked on all models and types of PC. By using the interrupts, which are initialized at run time, the system can give a fixed location to call the routines from, while allowing the BIOS to be updated and changed as need. Later, when we discuss operating system calls from application software, we'll see how this can be applied to the OS as well. Most of the video functions in the BIOS are reached through interrupt 0x10. Since there are only 256 interrupts, and there are many more functions that the BIOS needs to provide, it is also neccessary to pass the interrupt handler an additional function code, which is put in AH register (the upper byte of the AX register). To make the code easier to read, let's add these two codes to the constant definitions along with the one for EOL: |
17. Constant Declarations[M]+={
VBIOS equ 0x10 ; BIOS interrupt vector for video services
ttype equ 0x0E ; insert character in AL as if screen were teletype
}
The value of ttype still needs to be put into AH, however. Also, The BIOS routine needs one more argument to work: the location of the character to print. This is passed to it in the SI register, a special register used as a String Index. |
18. BIOS Arguments[M]={
mov ah, ttype ; set function to 'teletype mode'
mov si, message ; set SI to point to the first character in 'message'
}
We are now ready to begin the printing loop itself (whew!). Like most loops, this one has three parts, a conditional, an action, and an exit. Together with the argument settings, they make up the print routine: |
19. Print Message to the Screen={
BIOS Arguments
printloop:
Conditional
Action
jmp short printloop
endstring:
}
The conditional section tests to see if the character pointed to by SI is equal to EOL. if it is, it jumps to the exit; otherwise, it continues with the loop. |
20. Conditional={
mov al, [si] ; update byte to print
cmp al, EOL ; test that it isn't EOL
jz endstring
}
The action part simply calls the BIOS interrupt and increments SI by one, |
21. Action={
int VBIOS ; put character in AL at next cursor position
inc si
}
after which the loop continues. |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;; LoIS-1.asm ;;; Joseph Osako 13 July 2002 ;;; ;; Goals: ;; - show how to set the code segment and instruction pointer ;; - show how to set the data segment register ;; - demonstrate how to declare constants and set aside space ;; for variables ;; - print a simple message upon boot up and halt ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; LoIS - A tutorial on Boot Loading for the IA-32 PC ; Copyright (C) 2002 Joseph Osako Jr. ; ; This program is free software; you can redistribute it and/or modify ; it under the terms of the GNU General Public License as published by ; the Free Software Foundation; either version 2 of the License, or ; (at your option) any later version. ; ; This program is distributed in the hope that it will be useful, ; but WITHOUT ANY WARRANTY; without even the implied warranty of ; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ; GNU General Public License for more details. ; EOL equ 0x00 ;end of line marker VBIOS equ 0x10 ; BIOS interrupt vector for video services ttype equ 0x0E ; insert character in AL as if screen were teletype [BITS 16] [ORG 0x7C00] JMP 0000:start ;*************************************************** ; start ; This is the beginning of the boot block code. start: mov ax, cs mov ds, ax ; set DS == CS mov ah, ttype ; set function to 'teletype mode' mov si, message ; set SI to point to the first character in 'message' printloop: mov al, [si] ; update byte to print cmp al, EOL ; test that it isn't EOL jz endstring int VBIOS ; put character in AL at next cursor position inc si jmp short printloop endstring: jmp SHORT $ ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; data message db "Booting LoIS", EOL ;;;;;;;;;;;;;;;;;;;; ; Boot Block footer - fills all but the last two bytes ; with zeroes, and then includes the boot signature space times (0x0200 - 2) - ($-$$) db 0 bootsig dw 0xAA55 |
This will proceed in much the same way that testing the first version did, except that the name 'LoIS-0' should be changed to 'LoIS-1' in every command line. The result will be that, on start up, the boot program will write the words, 'Loading LoIS' on the first line after the BIOS startup messages. At last the result of the work done up until now can be seen, and it is clear that the program does indeed work. With this, we now have one of the basic tools needed to to proceed with building a true boot loader. However, our printing program has a problem: it only prinst out that one fixed message. What we are going to need is a way to print out arbitrary messages as we need them: a string printing function, in other words. This will be our next step. |
TBD |
TBD |
GNU GENERAL PUBLIC LICENSE Version 2, June 1991 Copyright (C) 1989, 1991 Free Software Foundation, Inc. 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. Preamble The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change free software--to make sure the software is free for all its users. This General Public License applies to most of the Free Software Foundation's software and to any other program whose authors commit to using it. (Some other Free Software Foundation software is covered by the GNU Library General Public License instead.) You can apply it to your programs, too. When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for this service if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs; and that you know you can do these things. To protect your rights, we need to make restrictions that forbid anyone to deny you these rights or to ask you to surrender the rights. These restrictions translate to certain responsibilities for you if you distribute copies of the software, or if you modify it. For example, if you distribute copies of such a program, whether gratis or for a fee, you must give the recipients all the rights that you have. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights. We protect your rights with two steps: (1) copyright the software, and (2) offer you this license which gives you legal permission to copy, distribute and/or modify the software. Also, for each author's protection and ours, we want to make certain that everyone understands that there is no warranty for this free software. If the software is modified by someone else and passed on, we want its recipients to know that what they have is not the original, so that any problems introduced by others will not reflect on the original authors' reputations. Finally, any free program is threatened constantly by software patents. We wish to avoid the danger that redistributors of a free program will individually obtain patent licenses, in effect making the program proprietary. To prevent this, we have made it clear that any patent must be licensed for everyone's free use or not licensed at all. The precise terms and conditions for copying, distribution and modification follow. GNU GENERAL PUBLIC LICENSE TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 0. This License applies to any program or other work which contains a notice placed by the copyright holder saying it may be distributed under the terms of this General Public License. The "Program", below, refers to any such program or work, and a "work based on the Program" means either the Program or any derivative work under copyright law: that is to say, a work containing the Program or a portion of it, either verbatim or with modifications and/or translated into another language. (Hereinafter, translation is included without limitation in the term "modification".) Each licensee is addressed as "you". Activities other than copying, distribution and modification are not covered by this License; they are outside its scope. The act of running the Program is not restricted, and the output from the Program is covered only if its contents constitute a work based on the Program (independent of having been made by running the Program). Whether that is true depends on what the Program does. 1. You may copy and distribute verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice and disclaimer of warranty; keep intact all the notices that refer to this License and to the absence of any warranty; and give any other recipients of the Program a copy of this License along with the Program. You may charge a fee for the physical act of transferring a copy, and you may at your option offer warranty protection in exchange for a fee. 2. You may modify your copy or copies of the Program or any portion of it, thus forming a work based on the Program, and copy and distribute such modifications or work under the terms of Section 1 above, provided that you also meet all of these conditions: a) You must cause the modified files to carry prominent notices stating that you changed the files and the date of any change. b) You must cause any work that you distribute or publish, that in whole or in part contains or is derived from the Program or any part thereof, to be licensed as a whole at no charge to all third parties under the terms of this License. c) If the modified program normally reads commands interactively when run, you must cause it, when started running for such interactive use in the most ordinary way, to print or display an announcement including an appropriate copyright notice and a notice that there is no warranty (or else, saying that you provide a warranty) and that users may redistribute the program under these conditions, and telling the user how to view a copy of this License. (Exception: if the Program itself is interactive but does not normally print such an announcement, your work based on the Program is not required to print an announcement.) These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Program, and can be reasonably considered independent and separate works in themselves, then this License, and its terms, do not apply to those sections when you distribute them as separate works. But when you distribute the same sections as part of a whole which is a work based on the Program, the distribution of the whole must be on the terms of this License, whose permissions for other licensees extend to the entire whole, and thus to each and every part regardless of who wrote it. Thus, it is not the intent of this section to claim rights or contest your rights to work written entirely by you; rather, the intent is to exercise the right to control the distribution of derivative or collective works based on the Program. In addition, mere aggregation of another work not based on the Program with the Program (or with a work based on the Program) on a volume of a storage or distribution medium does not bring the other work under the scope of this License. 3. You may copy and distribute the Program (or a work based on it, under Section 2) in object code or executable form under the terms of Sections 1 and 2 above provided that you also do one of the following: a) Accompany it with the complete corresponding machine-readable source code, which must be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, b) Accompany it with a written offer, valid for at least three years, to give any third party, for a charge no more than your cost of physically performing source distribution, a complete machine-readable copy of the corresponding source code, to be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, c) Accompany it with the information you received as to the offer to distribute corresponding source code. (This alternative is allowed only for noncommercial distribution and only if you received the program in object code or executable form with such an offer, in accord with Subsection b above.) The source code for a work means the preferred form of the work for making modifications to it. For an executable work, complete source code means all the source code for all modules it contains, plus any associated interface definition files, plus the scripts used to control compilation and installation of the executable. However, as a special exception, the source code distributed need not include anything that is normally distributed (in either source or binary form) with the major components (compiler, kernel, and so on) of the operating system on which the executable runs, unless that component itself accompanies the executable. If distribution of executable or object code is made by offering access to copy from a designated place, then offering equivalent access to copy the source code from the same place counts as distribution of the source code, even though third parties are not compelled to copy the source along with the object code. 4. You may not copy, modify, sublicense, or distribute the Program except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense or distribute the Program is void, and will automatically terminate your rights under this License. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance. 5. You are not required to accept this License, since you have not signed it. However, nothing else grants you permission to modify or distribute the Program or its derivative works. These actions are prohibited by law if you do not accept this License. Therefore, by modifying or distributing the Program (or any work based on the Program), you indicate your acceptance of this License to do so, and all its terms and conditions for copying, distributing or modifying the Program or works based on it. 6. Each time you redistribute the Program (or any work based on the Program), the recipient automatically receives a license from the original licensor to copy, distribute or modify the Program subject to these terms and conditions. You may not impose any further restrictions on the recipients' exercise of the rights granted herein. You are not responsible for enforcing compliance by third parties to this License. 7. If, as a consequence of a court judgment or allegation of patent infringement or for any other reason (not limited to patent issues), conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot distribute so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not distribute the Program at all. For example, if a patent license would not permit royalty-free redistribution of the Program by all those who receive copies directly or indirectly through you, then the only way you could satisfy both it and this License would be to refrain entirely from distribution of the Program. If any portion of this section is held invalid or unenforceable under any particular circumstance, the balance of the section is intended to apply and the section as a whole is intended to apply in other circumstances. It is not the purpose of this section to induce you to infringe any patents or other property right claims or to contest validity of any such claims; this section has the sole purpose of protecting the integrity of the free software distribution system, which is implemented by public license practices. Many people have made generous contributions to the wide range of software distributed through that system in reliance on consistent application of that system; it is up to the author/donor to decide if he or she is willing to distribute software through any other system and a licensee cannot impose that choice. This section is intended to make thoroughly clear what is believed to be a consequence of the rest of this License. 8. If the distribution and/or use of the Program is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Program under this License may add an explicit geographical distribution limitation excluding those countries, so that distribution is permitted only in or among countries not thus excluded. In such case, this License incorporates the limitation as if written in the body of this License. 9. The Free Software Foundation may publish revised and/or new versions of the General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Program specifies a version number of this License which applies to it and "any later version", you have the option of following the terms and conditions either of that version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of this License, you may choose any version ever published by the Free Software Foundation. 10. If you wish to incorporate parts of the Program into other free programs whose distribution conditions are different, write to the author to ask for permission. For software which is copyrighted by the Free Software Foundation, write to the Free Software Foundation; we sometimes make exceptions for this. Our decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally. NO WARRANTY 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. END OF TERMS AND CONDITIONS How to Apply These Terms to Your New Programs If you develop a new program, and you want it to be of the greatest possible use to the public, the best way to achieve this is to make it free software which everyone can redistribute and change under these terms. To do so, attach the following notices to the program. It is safest to attach them to the start of each source file to most effectively convey the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. <one line to give the program's name and a brief idea of what it does.> Copyright (C) <year> <name of author> This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA Also add information on how to contact you by electronic and paper mail. If the program is interactive, make it output a short notice like this when it starts in an interactive mode: Gnomovision version 69, Copyright (C) year name of author Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. This is free software, and you are welcome to redistribute it under certain conditions; type `show c' for details. The hypothetical commands `show w' and `show c' should show the appropriate parts of the General Public License. Of course, the commands you use may be called something other than `show w' and `show c'; they could even be mouse-clicks or menu items--whatever suits your program. You should also get your employer (if you work as a programmer) or your school, if any, to sign a "copyright disclaimer" for the program, if necessary. Here is a sample; alter the names: Yoyodyne, Inc., hereby disclaims all copyright interest in the program `Gnomovision' (which makes passes at compilers) written by James Hacker. <signature of Ty Coon>, 1 April 1989 Ty Coon, President of Vice This General Public License does not permit incorporating your program into proprietary programs. If your program is a subroutine library, you may consider it more useful to permit linking proprietary applications with the library. If this is what you want to do, use the GNU Library General Public License instead of this License. |