2889 lines
106 KiB
Text
2889 lines
106 KiB
Text
==Phrack Inc.==
|
|
|
|
Volume 0x0b, Issue 0x3b, Phile #0x03 of 0x12
|
|
|
|
|=---------------------=[ L I N E N O I S E ]=---------------------------=|
|
|
|=-----------------------------------------------------------------------=|
|
|
|=------------------------=[ phrackstaff ]=------------------------------=|
|
|
|
|
|
|
--[ Contents
|
|
|
|
1 - PHRACK Linenoise Introduction
|
|
1.1 PHRACK Oops
|
|
1.2 PHRACK Fakes
|
|
|
|
2 - PHRACK OS Construction
|
|
|
|
3 - PHRACK ninja lockpicking
|
|
|
|
4 - PHRACK sportz: fingerboarding
|
|
|
|
--[ 1 - PHRACK Linenoise Introduction
|
|
|
|
I think you know what linenoise is about. We had the same
|
|
cut & paste Linenoise Introduction in the last 10 issues :)
|
|
|
|
|
|
----[ 1.1 - PHRACK Oops
|
|
|
|
Oops, For the last 17 years we forgot the .txt extension to the
|
|
articles.
|
|
|
|
|
|
Some reader complained about a little mistake in p59-0x01:
|
|
phrack:~# head -20 /usr/include/std-disclaimer.h
|
|
22 lines of the header are actually printed :P
|
|
|
|
The message of the disclaimer remains:
|
|
1) No guarantee on anything.
|
|
2) Nobody is responsible.
|
|
3) Dont blame us if your kids turn into hackerz.
|
|
|
|
|
|
----[ 1.2 - PHRACK Fakes
|
|
|
|
http://www.cafepress.com/cp/store/store.aspx?storeid=phrack
|
|
|
|
That's not us.
|
|
Check out our homepage at http://www.phrack.org for some tshirts.
|
|
|
|
|
|
|
|
|=[ 0x02 ]=-------=[ Methodology For OS Construction ]=------------------=|
|
|
|=-----------------------------------------------------------------------=|
|
|
|=--------------=[ Bill Blunden <wablunden@hotmail.com> ]=---------------=|
|
|
|
|
--[ Contents
|
|
|
|
0 - Introduction
|
|
|
|
1 - The Critical Path
|
|
1.1 Choose a Host Platform
|
|
1.2 Build a Simulator
|
|
1.3 Build a Cross-Compiler
|
|
1.4 Build and Port The OS
|
|
1.5 Bootstrap the Cross-Compiler
|
|
|
|
2 - OS Components
|
|
2.1 Task Model
|
|
2.2 Memory Management
|
|
2.3 I/O interface
|
|
2.4 File System
|
|
2.5 Notes On Security
|
|
|
|
3 - Simple Case Study
|
|
3.1 Host Platform
|
|
3.3 Compiler Issues
|
|
3.4 Booting Up
|
|
3.5 Initializing The OS
|
|
3.6 Building and Deploying
|
|
|
|
4 - References and Credits
|
|
|
|
--[ 0 - Introduction
|
|
|
|
Of the countless number of books on operating system design, there are
|
|
perhaps only three or four, that I know of, which actually discuss how to
|
|
build a fully-functional operating system. Even these books focus so
|
|
narrowly on specific hardware that the essential steps become buried
|
|
under a pile of agonizing minutiae. This is not necessarily a bad thing,
|
|
rather it is an unintended consequence. Operating systems are incredibly
|
|
complicated pieces of software, and dissecting one will yield countless
|
|
details.
|
|
|
|
Nevertheless, my motivation for submitting this article is to provide a
|
|
generic series of steps which can be used to build an OS, from scratch,
|
|
without bias towards a particular hardware vendor.
|
|
|
|
"Geese Uncle Don, how do you build an OS ..."
|
|
|
|
My own understanding of OS construction was rather sketchy until I had the
|
|
privilege of meeting some old fogeys from Control Data. These were people
|
|
who had worked on the CDC 6600 with Seymour Cray. The methodology which I
|
|
am passing on to you was used to build Control Data's SCOPE76 operating
|
|
system. Although some of the engineers that I spoke with are now in their
|
|
70s, I can assure you that the approach they described to me is still very
|
|
useful and relevant.
|
|
|
|
During the many hours that I pestered these CDC veterans for details, I
|
|
heard more than a few interesting war stories. For example, when Control
|
|
Data came out with the 6600, it was much faster than anything IBM was
|
|
selling. The execs at Big Blue were so peeved at being upstaged by Cray
|
|
that they created a paper tiger and told everyone to wait a few months.
|
|
Unfortunately, it worked. Everyone waited for IBM to deliver ( IBM never
|
|
did, those bastards ) and this forced CDC to drop the price of the 6600
|
|
in half in order to attract customers.
|
|
|
|
If you are familiar with IBM's business practices, this type of behavior
|
|
comes as no surprise. Did you know that IBM sold Hollerith tabulators to
|
|
the Nazis during WWII?
|
|
|
|
This article is broken into three parts.
|
|
|
|
Part 1 presents a general approach that may be used to build an operating
|
|
system. I am intentionally going to be ambiguous. I want the approach to
|
|
be useful regardless of which hardware platform you are targeting.
|
|
|
|
For the sake of focusing on the process itself, I delay the finer details
|
|
of construction until Part 2. In Part 2, I present a rough map that can be
|
|
used to determine the order in which the components of the OS should be
|
|
implemented.
|
|
|
|
For the sake of illuminating a few of the issues that a system engineer
|
|
will face during OS implementation, I have included a brief discussion
|
|
of an extended example in part 3. My goal in part 3 is to illustrate some
|
|
of the points that I make in part 1. I have no intention of offering a
|
|
production quality OS, there are already a number of excellent examples
|
|
available. Interested readers can pick up any of the references provided
|
|
at the end of this article.
|
|
|
|
--[ 1 - The Critical Path
|
|
|
|
In the stock market, you typically need money in order to make money.
|
|
Building an OS is the same way: you need an OS in order to build one.
|
|
|
|
Let's call the initial OS, and the hardware that it runs on, the 'host'
|
|
platform. I will refer to the OS to be constructed, and the hardware that
|
|
it will run on, as the 'target' platform.
|
|
|
|
--[ 1.1 - Choose a Host Platform
|
|
|
|
I remember asking a Marine Corp Recon guy once what he thought was the
|
|
most effective small sidearm. His answer: "whichever one you are the most
|
|
familiar with."
|
|
|
|
The same holds true for choosing a host platform. The best host platform
|
|
to use is the one which you are the most familiar with. You are going to
|
|
have to perform some fancy software acrobatics and you will need to be
|
|
intimately familiar with both your host OS and its development tools. In
|
|
some more pathological cases, it may even help to be familiar with the
|
|
machine instruction encoding of your hardware. This will allow you to
|
|
double check what your development tools are spitting out.
|
|
|
|
You may also discover that there are bugs in your initial set of tools,
|
|
and be forced to switch vendors. This is a good reason for picking a host
|
|
platform which is popular enough that their are several tool vendors to
|
|
choose from. For example, during some system work, on Windows, I
|
|
discovered a bug in Microsoft's assembler (MASM). As it happened, MASM
|
|
would refuse to assemble a source file which exceeded a certain number of
|
|
lines. Fortunately, I was able to buy Borland's nifty Turbo Assembler
|
|
(TASM) and forge onward.
|
|
|
|
--[ 1.2 - Build a Simulator
|
|
|
|
Once you've picked a host platform and decided on an appropriate set of
|
|
development tools, you will need to build a simulator that replicates the
|
|
behavior of the target platform's hardware.
|
|
|
|
This can be a lot more work than it sounds. Not only will you have to
|
|
reproduce the bare hardware, but you will also have to mimic the BIOS which
|
|
is burned into the machine's ROM. There are also peripheral devices and
|
|
micro controllers that you will need to replicate.
|
|
|
|
Note: The best way to see if you have implemented a simulator correctly is
|
|
to create an image file of a live partition and see if the simulator will
|
|
run the system loaded on it. For example, if you built an x86 simulator,
|
|
then you could test out an image file of a Linux boot partition.
|
|
|
|
The primary benefit of the simulator is that it will save you from having
|
|
to work in the dark. There is nothing worse than having your machine
|
|
crash and not being able to determine why. Watching your Intel box triple
|
|
fault can be extremely frustrating, primarily because it is almost
|
|
impossible to diagnose the problem once it has occurred. This is
|
|
particularly true during the boot phase, where you haven't built enough
|
|
infrastructure to stream messages to the console.
|
|
|
|
A simulator allows you to see what is happening in a safe, and controlled,
|
|
environment. If your code crashes the simulator, you can insert diagnostic
|
|
procedures to help perform forensic work. You can also run the simulator
|
|
from within the context of a debugger so that you can single-step through
|
|
tricky areas.
|
|
|
|
The alternative is to run your OS code on raw metal, which will basically
|
|
preclude your ability to record the machine's state when it crashes. The
|
|
diagnostic and forensic techniques which you used with the simulator will
|
|
be replaced by purely speculative tactics. This is no fun, trust me.
|
|
|
|
For an excellent example of a simulator, you should take a look at the
|
|
bochs x86 simulator. It is available at:
|
|
|
|
http://sourceforge.net/projects/bochs
|
|
|
|
Once thing that I should mention is that it is best to use bochs in
|
|
conjunction with Linux. This is because bochs works with disk images and
|
|
the Linux 'dd' command is a readily available and easy way to produce
|
|
a disk image. For example, the following command takes a floppy disk and
|
|
produces an image file named floppy.img.
|
|
|
|
dd if=/dev/fd0 of=floppy.img bs=1k
|
|
|
|
Windows does not ship with an equivalent tool. Big surprise.
|
|
|
|
"Back in my day ..."
|
|
|
|
In the old days, creating a simulator was often a necessity because
|
|
sometimes the target hardware had not yet gone into production. In those
|
|
days, a smoke test was truly a smoke test ... they turned on the machines
|
|
and looked for smoke!
|
|
|
|
--[ 1.3 - Build a Cross-Compiler
|
|
|
|
Once you have a simulator built, you should build a cross-compiler.
|
|
Specifically, you will need to construct a compiler which runs on the host
|
|
platform, but generates a binary which is run by the target platform.
|
|
Initially you will use the simulator to run everything that the cross-
|
|
compiler generates. When you feel confident enough with your environment,
|
|
you can start running code directly on the target platform.
|
|
|
|
"Speaking words of wisdom, write in C..."
|
|
|
|
Given that C is the de facto language for doing system work, I would
|
|
highly recommend getting the source code for compiler like gcc and
|
|
modifying the backend. The gcc compiler even comes with documentation
|
|
dedicated to this task, which is why I recommend gcc. There are other
|
|
public C compilers, like small-C, that obey a subset of the ANSI spec
|
|
and may be easier to port.
|
|
|
|
gcc: http://gcc.gnu.org
|
|
small-C: http://www.ddjembedded.com/languages/smallc
|
|
|
|
If you want to be different, I suppose you could find a Pascal or Fortran
|
|
compiler to muck around with. It wouldn't be the first time that someone
|
|
took the less traveled route. During the early years, the Control Data
|
|
engineers invented their own variation of Pascal to construct the
|
|
NOSVE (aka NOSEBLEED) OS. NOSVE was one of those Tower of Babel projects
|
|
that never made it to production. At Control Data, you weren't considered
|
|
a real manager until you had at least one big failure under your belt. I
|
|
bet NOS/VE pushed the manager up to VP status!
|
|
|
|
--[ 1.4 - Build and Port The OS
|
|
|
|
OK, you've done all the prep work. It's time to code the OS proper. The
|
|
finer details of this process are discussed in Part 2. Once you have
|
|
a prototype OS built than runs well on the simulator you will be faced
|
|
with the -BIG- hurdle ... running your code on the actual target hardware.
|
|
|
|
I found that this is a hurdle which you should jump early on. Do a test
|
|
run on the target platform as soon as you have the minimal number of
|
|
working components. Discovering that your code will not boot after 50,000
|
|
lines of effort can be demoralizing.
|
|
|
|
If you were disciplined about designing and testing your simulator, most
|
|
of your problems will probably be with the OS code itself and perhaps
|
|
undocumented features in peripheral hardware controllers. This is where
|
|
investing the time in building a bullet-proof simulator truly pays off.
|
|
Knowing that the simulator does its job will allow you to more accurately
|
|
diagnose problems ... and also save you plenty of sleep.
|
|
|
|
Finally, I would recommend using a boot disk so that you don't put the
|
|
hard drive(s) of your target machine at risk. Even the Linux kernel can
|
|
be made to fit on a single floppy, so for the time being try not to worry
|
|
about binary size constraints.
|
|
|
|
--[ 1.5 - Bootstrap the Cross-Compiler
|
|
|
|
Congratulations. You have gone where only a select few have gone before.
|
|
You've built an operating system. However, wouldn't it be nice to have
|
|
a set of development tools that can be run by your new OS? This can be
|
|
achieved by bootstrapping the existing cross-compiler.
|
|
|
|
Here's how bootstrapping works: You take the source code for your cross-
|
|
compiler and feed it to the cross-compiler on the host platform. The
|
|
cross-compiler digests this source code and produce a new binary that can
|
|
be executed by the target OS. You now have a compiler that runs on the
|
|
target OS and which creates executables that also run on the target OS.
|
|
|
|
Naturally, I am making a few assumptions. Specifically, I am assuming that
|
|
the libraries which the cross-compiler uses are also available on the
|
|
target OS. Compilers spend a lot of time performing string manipulation and
|
|
file I/O. If these supporting routines are not present and supported on the
|
|
target platform, then the newly built compiler is of little utility.
|
|
|
|
--[ 2 - OS Components
|
|
|
|
An OS is a strange sort of program in that it must launch and manage
|
|
itself in addition to launching and managing other programs. Hence, the
|
|
first thing that an operating system needs to do is bootstrap itself and
|
|
then set up its various components so that it can do its job.
|
|
|
|
I would recommend getting your hands on the vendor documentation for
|
|
your hardware. If you are targeting Intel, then you are in luck because
|
|
I explain the x86 boot process in Part 3 of this article.
|
|
|
|
In terms of overall architecture, I would recommend a modular, object-
|
|
oriented, design. This doesn't mean that you have to use C++. Rather, I
|
|
am encouraging you to delineate the various portions of the OS into
|
|
related sets of data and code. Whether or not you use a compiler to
|
|
enforce this separation is up to you. This approach has its advantages
|
|
in that it allows you to create sharply delineated boundaries between
|
|
components. This is good because it allows you to hide/modify each
|
|
subsystem's implementation.
|
|
|
|
Tanenbaum takes this idea to an extreme by making core components, like
|
|
the file system and memory manager, pluggable at runtime. With other
|
|
operating systems, you would have to re-compile the kernel to swap
|
|
core subsystems like the memory manager. With Minix, these components
|
|
can be switched at runtime. Linux has tried to implement something
|
|
similar via loadable kernel modules.
|
|
|
|
As a final aside, you will want to learn the assembly language for the
|
|
target platform's hardware. There are some OS features that are tied
|
|
directly to hardware and cannot be provided without executing a few dozen
|
|
lines of hardware-specific assembler. The Intel instruction set is
|
|
probably one of the most complicated. This is primarily due to historical
|
|
forces that drove Intel to constantly strive for backwards compatibility.
|
|
The binary encoding of Intel instructions is particularly perplexing.
|
|
|
|
Which OS component should you tackle first?
|
|
|
|
In what order should the components be implemented?
|
|
|
|
I would recommend that you implement the different areas of functionality
|
|
in the manner described by the following four sections.
|
|
|
|
--[ 2.1 - Task Model
|
|
|
|
In his book on OS design, Richard Burgess states that you should try to
|
|
start with the task control code, and I would tend to agree with him.
|
|
The task model you choose will impact everything else that you do.
|
|
|
|
First, and foremost, an operating system manages tasks. What is a task? The
|
|
Intel Pentium docs define a process as a "unit of work" (V3 p.6-1).
|
|
|
|
What was that person smoking? It's like saying that a hat is defined as a
|
|
piece of clothing. It doesn't give any insight into the true nature of a
|
|
task. I prefer to think of a task a set of instructions being executed by
|
|
the CPU in conjunction with the machine state which that execution
|
|
produces.
|
|
|
|
Inevitably, the exact definition of a task is spelled out by the operating
|
|
system's source code.
|
|
|
|
The Linux kernel (2.4.18) represents each task by a task_struct
|
|
structure defined in /usr/src/linux/include/linux/sched.h. The kernel's
|
|
collection of processes are aggregated in two ways. First, they are
|
|
indexed in a hash table of pointers:
|
|
|
|
extern struct task_struct *pidhash[PIDHASH_SZ];
|
|
|
|
The task structures are also joined by next_task and prev_task pointers
|
|
to form a doubly-linked list.
|
|
|
|
struct task_struct
|
|
{
|
|
:
|
|
struct task_struct *next_task, *prev_task;
|
|
:
|
|
};
|
|
|
|
You will need to decide if your OS will multi-task, and if so then what
|
|
policy will it apply in order to decide when to switch between tasks
|
|
( switching tasks is also known as a context switch ). Establishing a
|
|
mechanism-policy separation is important because you may decide to change
|
|
the policy later on and you don't want to have to re-write all the
|
|
mechanism code.
|
|
|
|
Context Switch Mechanism:
|
|
-------------------------
|
|
|
|
On the Intel platform, task switching is facilitated by a set of system
|
|
data structures and a series of special instructions. Specifically,
|
|
Intel Pentium class processors have a task register (TR) that is intended
|
|
to be loaded (via the LTR instruction) with a 16-bit segment selector.
|
|
This segment selector indexes a descriptor in the global descriptor table
|
|
(GDT). The information in the descriptor includes the base address and
|
|
size of the task state segment (TSS). The TSS is a state-information
|
|
repository for a task. It includes register state data (EAX, EBX, etc. )
|
|
and keeps track of the memory segments used by a given task. In other
|
|
words, it stores the 'context' of a task.
|
|
|
|
The TR register always holds the segment selector for the currently
|
|
executing task. A task switch is performed by saving the state of
|
|
the existing process in its TSS and then loading the TR with a new
|
|
selector. How this actually occurs, in terms of what facilitates the
|
|
re-loading of TR, is usually related to hardware timers.
|
|
|
|
The majority of multi-tasking systems assign each process a quantum
|
|
of time. The amount of time that a task receives is a policy decision.
|
|
An on-board timer, like the 82C54, can be set up to generate interrupts
|
|
at evenly spaced intervals. Every time these interrupts occur, the kernel
|
|
has an opportunity to check and see if it should perform a task switch.
|
|
If so, an Intel-based OS can then initiate a task switch by executing
|
|
a JMP or CALL instruction to the descriptor, in the GDT, of the task to
|
|
be dispatched. This causes the contents of TR to be changed.
|
|
|
|
Using the timer facilitates what is known as preemptive multitasking.
|
|
In the case of preemptive multitasking, the OS decides which task
|
|
gets to execute in conjunction with a scheduling policy. At the other
|
|
end of the spectrum is cooperative multitasking, where each task decides
|
|
when to yield the CPU to another task.
|
|
|
|
For an exhaustive treatment of task management on Intel, see Intel's
|
|
Pentium manual (Volume 3, Chapter 6).
|
|
|
|
Context Switch Policy:
|
|
----------------------
|
|
|
|
Deciding which process gets the CPU's attention, and for how long, is a
|
|
matter of policy. This policy is implemented by the scheduler. The Linux
|
|
kernel has a scheduler which is implemented by the schedule() function
|
|
located in /usr/src/linux/kernel/sched.c.
|
|
|
|
There are a lot of little details in the schedule() function related to
|
|
handling the scenario where there are multiple processors, and there are
|
|
also a couple of special cases. However, the core actions taken by the
|
|
scheduler are relatively straightforward. The scheduler looks through the
|
|
set of tasks that are eligible to execute. These eligible tasks are
|
|
tracked by the runqueue data structure.
|
|
|
|
The scheduler looks for the task on the runqueue with the highest
|
|
'goodness' value and schedules that task for execution. Goodness is a
|
|
value calculated by the goodness() function. It basically returns a
|
|
value which reflects the need for the task to run.
|
|
|
|
Goodness Spectrum
|
|
-----------------
|
|
-1000: never select this
|
|
0: re-examine entire list of tasks, not just runqueue
|
|
+ve: the larger, the better
|
|
+1000: realtime process, select this.
|
|
|
|
If the highest goodness values of all the tasks in the runqueue is zero,
|
|
then the scheduler takes a step back and looks at all of the tasks, not
|
|
just the ones in runqueue.
|
|
|
|
To give you an idea of how this is implemented, I've included a snippet
|
|
of the schedule() function and some of its more memorable lines:
|
|
|
|
asmlinkage void schedule(void)
|
|
{
|
|
struct schedule_data * sched_data;
|
|
struct task_struct *prev, *next, *p;
|
|
struct list_head *tmp;
|
|
int this_cpu, c;
|
|
:
|
|
:
|
|
/*
|
|
* this is the scheduler proper:
|
|
*/
|
|
|
|
repeat_schedule:
|
|
/*
|
|
* Default process to select..
|
|
*/
|
|
next = idle_task(this_cpu);
|
|
c = -1000;
|
|
list_for_each(tmp, &runqueue_head)
|
|
{
|
|
p = list_entry(tmp, struct task_struct, run_list);
|
|
|
|
if (can_schedule(p, this_cpu))
|
|
{
|
|
int weight = goodness(p, this_cpu, prev->active_mm);
|
|
if (weight > c){ c = weight, next = p; }
|
|
}
|
|
}
|
|
|
|
/* Do we need to re-calculate counters? */
|
|
if (unlikely(!c))
|
|
{
|
|
struct task_struct *p;
|
|
|
|
spin_unlock_irq(&runqueue_lock);
|
|
read_lock(&tasklist_lock);
|
|
for_each_task(p)
|
|
{
|
|
p->counter = (p->counter >> 1) + NICE_TO_TICKS(p->nice);
|
|
}
|
|
read_unlock(&tasklist_lock);
|
|
spin_lock_irq(&runqueue_lock);
|
|
goto repeat_schedule;
|
|
}
|
|
:
|
|
:
|
|
|
|
--[ 2.2 - Memory Management
|
|
|
|
A process both occupies and allocates memory. Once you have a task model
|
|
sketched out, you will need to give it access to a memory management
|
|
subsystem. Make sure to keep the interface to the memory subsystem clean,
|
|
so that you can yank it out and replace it later, if you need to.
|
|
|
|
On an OS level, memory protection is provided by two mechanisms:
|
|
|
|
i- segmentation
|
|
ii- paging
|
|
|
|
You will have to decide whether or not you want to support these two
|
|
features. Paging, in particular, is a hardware intensive task. This means
|
|
that if you do decide to provide paging facilities, porting the OS will
|
|
be difficult at best. According to Tanenbaum, this is the primary reason
|
|
why Minix does not support paging.
|
|
|
|
Segmentation can be enforced by hardware, or can be done manually via a
|
|
sand boxing technique at the kernel level. Almost everyone relies on
|
|
hardware based segmentation because it is faster. Like paging, hardware
|
|
based segmentation will necessarily involve a lot of hardware specific
|
|
code and a healthy dose of assembly language.
|
|
|
|
The MMURTL operating system breaks its virtual address space into three
|
|
segments. There's one code segment for the OS, one code segment for
|
|
applications, and a single data segment. This doesn't exactly protect
|
|
the applications from each other, but it does protect the OS.
|
|
|
|
MMURTL Segment Selector Value
|
|
-------------- --------------
|
|
OS code 0x08
|
|
Apps code 0x18
|
|
Apps data 0x10
|
|
|
|
MMURTL's memory subsystem is actually set up by the boot sector! That's
|
|
correct, I said the boot sector. If you look at the source code in
|
|
bootblok.asm, which Burgess compiles with TASM, you notice that the book
|
|
code does the book keeping necessary to make the transition to protected
|
|
mode. Here are a few relevant snippets from the file.
|
|
|
|
|
|
IDTptr DW 7FFh ;LIMIT 256 IDT Slots
|
|
DD 0000h ;BASE (Linear)
|
|
GDTptr DW 17FFh ;LIMIT 768 slots
|
|
DD 0800h ;BASE (Linear)
|
|
:
|
|
:
|
|
LIDT FWORD PTR IDTptr ;Load Processor ITD Pointer
|
|
LGDT FWORD PTR GDTptr ;Load Processor GDT Pointer
|
|
:
|
|
:
|
|
MOV EAX,CR0 ;Control Register
|
|
OR AL,1 ;Set protected mode bit
|
|
MOV CR0,EAX
|
|
JMP $+2 ;Clear prefetch queue with JMP
|
|
NOP
|
|
NOP
|
|
MOV BX, 10h ;Set up segment registers
|
|
MOV DS,BX
|
|
MOV ES,BX
|
|
MOV FS,BX
|
|
MOV GS,BX
|
|
MOV SS,BX
|
|
|
|
;We define a far jump
|
|
DB 66h
|
|
DB 67h
|
|
DB 0EAh
|
|
DD 10000h
|
|
DW 8h
|
|
; now in protect mode
|
|
|
|
Before he loaded GDTR and IDTR, Burgess loaded the OS into memory so that
|
|
the base address values in the selectors actually point to valid
|
|
global and interrupt descriptor tables. It also saves him from having
|
|
to put these data structures in the boot code, which helps because of
|
|
the 512 byte size limit.
|
|
|
|
Most production operating systems use paging as a way to augment the
|
|
address space which the OS manages. Paging is complicated, and involves
|
|
a lot of dedicated code, and this code frequently executes ... which
|
|
adds up to a tremendous loss in performance. Disk I/O is probably the
|
|
most costly operation an isolated computer can perform. Even with
|
|
the bookkeeping being pushed down to the hardware, paging eats up time.
|
|
|
|
Barry Brey, who is an expert on the Intel chip set, told me that paging on
|
|
Windows eats up about 10% of the execution time. In fact, paging is so
|
|
costly, in terms of execution time, and RAM is so cheap that it is
|
|
often a better idea to buy more memory and turn off paging anyways.
|
|
In light of this, you shouldn't feel like paging is a necessity. If you
|
|
are designing an embedded OS, you won't need paging anyways.
|
|
|
|
Back when primary memory cores were 16KB, and those little magnets were
|
|
big ticket items, paging probably made a whole lot more sense. Today,
|
|
however, buying a couple GB of SDRAM is not uncommon and this causes me
|
|
to speculate that maybe paging is a relic of the past.
|
|
|
|
--[ 2.3 - I/O interface
|
|
|
|
This is the scary part.
|
|
|
|
You now have processes, and they live in memory. But they cannot interact
|
|
with the outside world without connections to I/O devices. Connecting to
|
|
I/O devices is traditionally performed by sections of code called drivers,
|
|
which are traditionally buried in the bowels of the OS. As with other
|
|
components of the OS, you will have to use your assembly language skills.
|
|
|
|
In Intel protected mode, using the BIOS to get data to the screen is not
|
|
an option because the old real-mode way of handling interrupts and
|
|
addressing memory is no longer valid. One way to send messages to the
|
|
screen is to write directly to video memory. Most monitors, even flat
|
|
panels, start up in either VGA 80x25 monochrome text mode or VGA 80x25
|
|
color text mode.
|
|
|
|
memory region real-mode address linear address of buffer
|
|
------------- ----------------- ----------------------
|
|
monochrome text B000[0]:0000 B0000H
|
|
color text B800[0]:0000 B8000H
|
|
|
|
In either case, the screen can display 80 rows and 25 columns worth of
|
|
character data. Each character takes up two bytes in the video RAM memory
|
|
region ( which isn't so bad ... 80x25=2000x2=4000 bytes ). You can place
|
|
a character on the screen by merely altering the contents of video RAM.
|
|
The lower byte holds the ASCII character, and the high byte holds an
|
|
attribute.
|
|
|
|
The attribute bit is organized as follows:
|
|
|
|
bit 7 blink
|
|
---------------
|
|
bit 6
|
|
bit 5 background color ( 0H=black )
|
|
bit 4
|
|
---------------
|
|
bit 3
|
|
bit 2 foreground color ( 0EH=white )
|
|
bit 1
|
|
bit 0
|
|
|
|
To handle multiple screens, you merely create screen buffers and then
|
|
commit the virtual screen to video RAM when you want to see it.
|
|
For example, in protected mode the following code ( written with DJGPP )
|
|
will place a 'J' on the screen.
|
|
|
|
#include <sys/farptr.h>
|
|
#include <go32.h>
|
|
_farpokeb(_dos_ds, 0xB8000, 'J');
|
|
_farpokeb(_dos_ds, 0xB8000+1, 0x0F);
|
|
|
|
When I saw the following snippet of code in Minix's console.c file,
|
|
I knew that Minix used this technique to write to the screen.
|
|
|
|
#define MONO_BASE 0xB0000L /* base of mono video memory */
|
|
#define COLOR_BASE 0xB8000L /* base of color video memory */
|
|
:
|
|
:
|
|
PUBLIC void scr_init(tp)
|
|
tty_t *tp;
|
|
{
|
|
:
|
|
:
|
|
if (color)
|
|
{
|
|
vid_base = COLOR_BASE;
|
|
vid_size = COLOR_SIZE;
|
|
}
|
|
else
|
|
{
|
|
vid_base = MONO_BASE;
|
|
vid_size = MONO_SIZE;
|
|
}
|
|
:
|
|
:
|
|
|
|
Handling I/O to other devices on the Intel platform is no where nearly
|
|
as simple. This is where our old friend the 8259 Programmable Interrupt
|
|
Controller (PIC) comes into play. Recently I have read a lot in Intel
|
|
docs about an advanced PIC (i.e. APIC), but everyone still seems to be
|
|
sticking to the old interrupt controller.
|
|
|
|
The 8259 PIC is the hardware liaison between the hardware and the processor.
|
|
The most common setup involves two 8259 PICs configured in a master-slave
|
|
arrangement. Each PIC has eight interrupt request lines (IRQ lines) that
|
|
receive data from external devices ( i.e. the keyboard, hard drive, etc. ).
|
|
The master 8259 will use its third pin to latch on to the slave 8259
|
|
so that, all told, they provide 15 IRQ lines for external hardware. The
|
|
master 8259 then communicates to the CPU through the CPUs INTR interrupt
|
|
PIN. The slave 8259 uses it's INTR slot to speak to the master on its
|
|
third IRQ line.
|
|
|
|
Normally the BIOS will program the 8259 when then computer boots, but
|
|
to talk to hardware devices in protected mode, the 8259 must be
|
|
re-programmed. This is because the 8259 couples the IRQ lines to
|
|
interrupt signals. Programming the 8259 will make use of the IN and OUT
|
|
instructions. You basically have to send 8-bit values to the 8259's
|
|
interrupt command register (ICR) and interrupt mask register (IMR)
|
|
in a certain order. One wrong move and you triple-fault.
|
|
|
|
My favorite example of programming the 8259 PIC comes from MMURTL. The
|
|
following code is located in INITCODE.INC and is invoked during the
|
|
initialization sequence in MOS.ASM.
|
|
|
|
;=========================================================================
|
|
; This sets IRQ00-0F vectors in the 8259s
|
|
; to be Int20 thru 2F.
|
|
;
|
|
; When the PICUs are initialized, all the hardware interrupts are MASKED.
|
|
; Each driver that uses a hardware interrupt(s) is responsible
|
|
; for unmasking that particular IRQ.
|
|
;
|
|
PICU1 EQU 0020h
|
|
PICU2 EQU 00A0h
|
|
|
|
Set8259 PROC NEAR
|
|
MOV AL,00010001b
|
|
OUT PICU1+0,AL ;ICW1 - MASTER
|
|
jmp $+2
|
|
jmp $+2
|
|
OUT PICU2+0,AL ;ICW1 - SLAVE
|
|
jmp $+2
|
|
jmp $+2
|
|
MOV AL,20h
|
|
OUT PICU1+1,AL ;ICW2 - MASTER
|
|
jmp $+2
|
|
jmp $+2
|
|
MOV AL,28h
|
|
OUT PICU2+1,AL ;ICW2 - SLAVE
|
|
jmp $+2
|
|
jmp $+2
|
|
MOV AL,00000100b
|
|
OUT PICU1+1,AL ;ICW3 - MASTER
|
|
jmp $+2
|
|
jmp $+2
|
|
MOV AL,00000010b
|
|
OUT PICU2+1,AL ;ICW3 - SLAVE
|
|
jmp $+2
|
|
jmp $+2
|
|
MOV AL,00000001b
|
|
OUT PICU1+1,AL ;ICW4 - MASTER
|
|
jmp $+2
|
|
jmp $+2
|
|
OUT PICU2+1,AL ;ICW4 - SLAVE
|
|
jmp $+2
|
|
jmp $+2
|
|
MOV AL,11111010b ;Masked all but cascade/timer
|
|
; MOV AL,01000000b ;Floppy masked
|
|
OUT PICU1+1,AL ;MASK - MASTER (0= Ints ON)
|
|
jmp $+2
|
|
jmp $+2
|
|
MOV AL,11111111b
|
|
; MOV AL,00000000b
|
|
OUT PICU2+1,AL ;MASK - SLAVE
|
|
jmp $+2
|
|
jmp $+2
|
|
RETN
|
|
SET8259 ENDP
|
|
;=========================================================================
|
|
|
|
Note how Burgess performs two NEAR jumps after each OUT instruction. This
|
|
is to give the PIC time to process the command.
|
|
|
|
Writing a driver can be a harrowing experience. This is because drivers
|
|
are nothing less than official members of the kernel memory image. When
|
|
you build a driver, you are building a part of the OS. This means that
|
|
if you incorrectly implement a driver, you could be dooming your system
|
|
to a crash of the worst kind ... death by friendly fire.
|
|
|
|
Building drivers is also fraught with all sorts of vendor-specific byte
|
|
encoding and bit wise acrobatics. The best advise that I can give you is
|
|
to stick to widely-used, commodity, hardware. Once you have a working
|
|
console, you can attempt to communicate with a disk drive and then maybe
|
|
a network card.
|
|
|
|
You might want to consider designing your OS so that drivers can be
|
|
loaded and unloaded at runtime. Having to recompile the kernel to
|
|
accommodate a single driver is a pain. This will confront you with
|
|
creating an indirect calling mechanism so that the OS can invoke the
|
|
driver, even though it does not know in advance where that driver is.
|
|
|
|
The Linux kernel allows code to be added to the kernel at runtime
|
|
via loadable kernel modules (LKMs). These dynamically loadable modules
|
|
are nothing more than ELF object files ( they've been compiled, but
|
|
not officially linked ). There are a number of utilities that can
|
|
be used to manage LKMs. Two of the most common are insmod and rmmod,
|
|
which are used to insert and remove LKMs at runtime.
|
|
|
|
The insmod utility acts as a linker/loader and assimilates the LKM into
|
|
the kernel's memory image. Insmod does this by invoking the init_module
|
|
system call. This is located in /usr/src/linux/kernel/module.c.
|
|
|
|
asmlinkage long
|
|
sys_init_module(const char *name_user, struct module *mod_user){ ...
|
|
|
|
This function, in turn, invokes another function belonging to the LKM
|
|
which also just happens to be named init_module(). Here is a the
|
|
relevant snippet from sys_init_module():
|
|
|
|
/* Initialize the module. */
|
|
atomic_set(&mod->uc.usecount,1);
|
|
mod->flags |= MOD_INITIALIZING;
|
|
if (mod->init && (error = mod->init()) != 0)
|
|
{
|
|
atomic_set(&mod->uc.usecount,0);
|
|
mod->flags &= ~MOD_INITIALIZING;
|
|
if (error > 0) /* Buggy module */
|
|
error = -EBUSY;
|
|
goto err0;
|
|
}
|
|
atomic_dec(&mod->uc.usecount);
|
|
|
|
The LKM's init_module() function, which is pointed to by the kernel code
|
|
above, then invokes a kernel routine to register the LKMs subroutines.
|
|
Here is a simple example:
|
|
|
|
/* Initialize the module - Register the character device */
|
|
int init_module()
|
|
{
|
|
/* Register the character device (atleast try) */
|
|
Major = module_register_chrdev( 0,
|
|
DEVICE_NAME,
|
|
&Fops);
|
|
|
|
/* Negative values signify an error */
|
|
if (Major < 0)
|
|
{
|
|
printk ("%s device failed with %d\n",
|
|
"Sorry, registering the character",
|
|
Major);
|
|
return Major;
|
|
}
|
|
|
|
printk ("%s The major device number is %d.\n",
|
|
"Registeration is a success.",
|
|
Major);
|
|
printk ("If you want to talk to the device driver,\n");
|
|
printk ("you'll have to create a device file. \n");
|
|
printk ("We suggest you use:\n");
|
|
printk ("mknod <name> c %d <minor>\n", Major);
|
|
printk ("You can try different minor numbers %s",
|
|
"and see what happens.\n");
|
|
|
|
return 0;
|
|
}
|
|
|
|
The Unix OS, in an attempt to simply things, treats every device like a
|
|
file. This is done in order to keep the number of system calls down and
|
|
to offer a uniform interface from one hardware subsystem to the next.
|
|
This is an approach worth considering. However, on the other hand, the
|
|
Unix approach have not always gotten a good grade in terms of ease of use.
|
|
Specifically, I have heard complaints about mounting and un-mounting from
|
|
Windows users who migrate to Unix.
|
|
|
|
Note, If you do take the LKM route, you should be careful not to make
|
|
the loadable driver feature into a security flaw.
|
|
|
|
With regard to nuts-and-bolts details, for the Intel platform, I would
|
|
recommend Frank Van Gilluwe's book. If you are not targeting Intel, then
|
|
you have some real digging to do. Get on the phone and the internet and
|
|
contact your hardware vendors.
|
|
|
|
--[ 2.4 - File System
|
|
|
|
You now have processes, in memory, that can talk to the outside world.
|
|
The final step is to give them a way of persisting and organizing data.
|
|
|
|
In general, you will build the file system manager on top of the disk
|
|
drivers that you implemented earlier in the last step. If your OS is
|
|
managing an embedded system, you may not need to implement a file system
|
|
because no disk hardware exists. Even with embedded systems, though, I've
|
|
seen file systems implemented as RAM disks. Even embedded systems
|
|
sometimes need to produce and store log files ....
|
|
|
|
There are several documented files system specifications available to the
|
|
public, like the ext2 file system made famous by Linux. Here is the main
|
|
link for the ext2 implementation:
|
|
|
|
http://e2fsprogs.sourceforge.net/ext2.html
|
|
|
|
The documentation at this site should be sufficient to get you started.
|
|
In particular, there is a document named "Design and Implementation of
|
|
the Second Extended File System" which I found to be a well-rounded
|
|
introduction to ext2.
|
|
|
|
If you have the Linux kernel source and you want to take a look at the
|
|
basic data structures of the ext2fs, then look in:
|
|
|
|
/usr/src/linux/include/linux/ext2_fs.h
|
|
/usr/src/linux/include/linux/ext2_fs_i.h
|
|
|
|
To take a look at the functions that manipulate these data structures,
|
|
take a look in the following directory:
|
|
|
|
/usr/src/linux/fs/ext2
|
|
|
|
In this directory you will see code like:
|
|
|
|
#include <linux/module.h>
|
|
|
|
MODULE_AUTHOR("Remy Card and others");
|
|
MODULE_DESCRIPTION("Second Extended Filesystem");
|
|
MODULE_LICENSE("GPL");
|
|
|
|
in inode.c, and in super.c you will see:
|
|
|
|
EXPORT_NO_SYMBOLS;
|
|
|
|
module_init(init_ext2_fs)
|
|
module_exit(exit_ext2_fs)
|
|
|
|
Obviously, from the previous discussion, you should realize that support
|
|
for ext2fs can be provided by an LKM!
|
|
|
|
Some OS creators, like Burgess, go the way of the MS-DOS FAT file system,
|
|
for the sake of simplicity, and so they didn't have to reformat their
|
|
hard drives. I wouldn't recommend the FAT system. In general, you might
|
|
want to keep in mind that it is a good idea to implement a file system
|
|
which facilitates file ownership and access controls. More on this in the
|
|
next section ...
|
|
|
|
--[ 2.5 - Notes On Security
|
|
|
|
Complexity is the enemy of security. Simple procedures are easy to check
|
|
and police, complicated ones are not. Any certified accountant will tell
|
|
you that our Byzantine tax laws leave all sorts of room for abuse.
|
|
|
|
Software is the same way. Complicated source code has the potential to
|
|
provide all sorts of insidious places for bugs to hide. As operating
|
|
systems have evolved they have become more complicated. According to
|
|
testimony given by a Microsoft executive on Feb. 2, 1999, Windows 98
|
|
consists of over 18 million lines of code. Do you think there is a bug
|
|
in there somewhere? Oh, ... no ... Microsoft wouldn't sell buggy code ...
|
|
|
|
<picture Dr. Evil, a la Austin Powers, saying the previous sentence>
|
|
|
|
Security is not something that you want to add on to your OS when you are
|
|
almost done with it. Security should be an innate part of your system's
|
|
normal operation. Keep this in mind during every phase of construction,
|
|
from task management to the file system manager.
|
|
|
|
In addition, you might consider having a creditable third party perform
|
|
an independent audit of your security mechanisms before you proclaim
|
|
your OS as being 'secure.' For example, the NSA evaluates 'trusted'
|
|
operating systems on a scale from C2 to A1.
|
|
|
|
A 'trusted' OS is just an OS which has security policies in place. The
|
|
salient characteristic of a trusted system is the ranking which the
|
|
NSA gives it. A C2 trusted system has only limited access and
|
|
authentication controls. An A1 trusted system, at the other end of the
|
|
spectrum, has rigorous and mandatory security mechanisms.
|
|
|
|
People who have imaginary enemies are called 'paranoid.' People who have
|
|
enemies that they think are imaginary are called 'victims.' It's often
|
|
hard to tell the two apart until its too late. If I had to trust my
|
|
business to an OS, I would prefer to invest in one that errs on the side
|
|
of paranoia.
|
|
|
|
--[ 3 - Simple Case Study
|
|
|
|
In this section, I present you with some home-brewed system code in an
|
|
effort to highlight some of the issues that I talked about in Part 1.
|
|
|
|
--[ 3.1 - Host Platform
|
|
|
|
For a number of reasons, I decided to take a shortcut and create an OS
|
|
that runs on Intel 8x86 hardware. Cost was one salient issue, and so was
|
|
the fact that there are several potential host operating systems to choose
|
|
from ( Linux, OpenBSD, MMURTL, Windows, etc. ).
|
|
|
|
The primary benefit, however, is that I can avoid ( to an extent ) having
|
|
to build a cross-compiler and simulator from scratch. By having the host
|
|
and target systems run on the same hardware, I was able to take advantage
|
|
of existing tools that generated x86 binaries and emulated x86 hardware.
|
|
|
|
For the sake of appealing to the least common denominator, I decided to
|
|
use Windows as a host OS. Windows, regardless of its failings, happens
|
|
to be have the largest base of users. Almost anyone should be able to
|
|
follow the issues and ideas I discuss in Part 3.
|
|
|
|
One side benefit of choosing Windows is that it ships with its own
|
|
simulator. The DOS Virtual Machine subsystem is basically a crudely
|
|
implemented 8086 simulator. I say 'crude' because it doesn't have the
|
|
number or range of features that bochs provides. I actually tested a lot
|
|
of code within the confines of the DOS VM.
|
|
|
|
--[ 3.2 - Compiler Issues
|
|
|
|
There are dozens of C compilers that run on Windows. I ended up having
|
|
three requirements for choosing one:
|
|
|
|
i- generates raw binary ( i.e. MS .COM file )
|
|
|
|
ii- allow for special in-line instructions (i.e. INT, LGDT )
|
|
|
|
iii- is free
|
|
|
|
Intel PCs boot into real-mode, which means that I will need to start the
|
|
party with a 16-bit compiler. In addition, system code must be raw binary
|
|
so that runtime address fix ups do not have to be manually implemented.
|
|
This is not mandatory, but it would make life much easier.
|
|
|
|
The only commercial compilers that generated 16-bit, raw binary, files
|
|
passed out of fashion years ago ... so I had to do some searching.
|
|
|
|
After trolling the net for compilers, I ended up with the following matrix:
|
|
|
|
compiler decision reason
|
|
-------- -------- ------
|
|
TurboC NO in-line assembly requires TASM ($$$)
|
|
Micro-C YES generates MASM friendly output
|
|
PacificC NO does not support tiny MM (i.e. .COM)
|
|
Borland 4.5C++ NO costs $$$
|
|
VisualC++ 1.52 NO costs $$$
|
|
Watcom NO does not support tiny MM (i.e. .COM)
|
|
DJGPP NO AT&T assembler syntax ( yuck )
|
|
|
|
I Ended up working with Micro-C, even though it does not support the entire
|
|
ANSI standard. The output of Micro-C is assembler and can be fed to MASM
|
|
without to much trouble. Micro-C was created by Dave Dunfield and can be
|
|
found at:
|
|
|
|
ftp://ftp.dunfield.com/mc321pc.zip
|
|
|
|
Don't worry about the MASM dependency. You can now get MASM 6.1 for free
|
|
as a part of the Windows DDK. See the following URL for details:
|
|
|
|
http://www.microsoft.com/ddk/download/98/BINS_DDK.EXE
|
|
http://download.microsoft.com/download/vc15/Update/1/WIN98/EN-US/Lnk563.exe
|
|
|
|
The only downside to obtaining this 'free' version of MASM ( i.e. the
|
|
ML.EXE,ML.err, and LINK.EXE files ) is that they come with zero documents.
|
|
|
|
Ha ha, the internet to the rescue ....
|
|
|
|
http://webster.cs.ucr.edu/Page_TechDocs/MASMDoc
|
|
|
|
By using Micro-C, I am following the advice I gave in Part 1 and sticking
|
|
to the tools that I am skilled with. I grew up using MASM and TASM. I am
|
|
comfortable using them at the command line and reading their listing
|
|
files. Because MASM is the free tool I picked it over TASM, even if it is
|
|
a little buggy.
|
|
|
|
One problem with using most C compilers to create OS code is that they all
|
|
add formatting information to the executable files they generate. For
|
|
example, the current version of Visual C++ creates console binaries that
|
|
obey the Portable Executable (PE) file format. This extra formatting is
|
|
used by the OS program loader at runtime.
|
|
|
|
Compilers also tack on library code to their executables, even when they
|
|
don't need it.
|
|
|
|
Consider a text file named file.c consisting of the code:
|
|
|
|
void main(){}
|
|
|
|
I am going to compile this code as a .COM file using TurboC. Take a look at
|
|
the size of the object file and final binary.
|
|
|
|
C:\DOCS\OS\lab\testTCC>tcc -mt -lt -ln file.c
|
|
C:\DOCS\OS\lab\testTCC>dir
|
|
|
|
. <DIR> 03-29-02 9:26p .
|
|
.. <DIR> 03-29-02 9:26p ..
|
|
FILE C 19 03-30-02 12:07a file.c
|
|
FILE OBJ 184 03-30-02 12:09a FILE.OBJ
|
|
FILE COM 1,742 03-30-02 12:09a file.com
|
|
|
|
|
|
Holy smokes... there's a mother load of ballast that the compiler adds on.
|
|
This is strictly the doing of the compiler and linker. Those bastards!
|
|
|
|
To see how excessive this actually is, let's look at a .COM file which
|
|
is coded in assembler. For example, let's create a file.asm that looks
|
|
like:
|
|
|
|
CSEG SEGMENT
|
|
start:
|
|
ADD ax,ax
|
|
ADD ax,cx
|
|
CSEG ENDS
|
|
end start
|
|
|
|
We can assemble this with MASM
|
|
|
|
C:\DOCS\OS\lab\testTCC>ml /AT file.asm
|
|
C:\DOCS\OS\lab\testTCC>dir
|
|
|
|
. <DIR> 03-29-02 9:26p .
|
|
.. <DIR> 03-29-02 9:26p ..
|
|
FILE OBJ 53 03-30-02 12:27a file.obj
|
|
FILE ASM 67 03-30-02 12:27a file.asm
|
|
FILE COM 4 03-30-02 12:27a file.com
|
|
5 file(s) 187 bytes
|
|
2 dir(s) 7,463.23 MB free
|
|
|
|
|
|
As you can see, the executable is only 4 bytes in size! The assembler
|
|
didn't add anything, unlike the C compiler, which threw in everything but
|
|
the kitchen sink. In all likelihood, the extra space is probably taken
|
|
up by libraries which the linker appends on.
|
|
|
|
The painful truth is, unless you want to build your own backend to a
|
|
C compiler, you will be faced with extra code and data on your OS binary.
|
|
One solution is simply to ignore the additional bytes. Which is to say
|
|
that the OS boot loader will simply skip the formatting stuff and go right
|
|
for the code which you wrote. If you decide to take this route, you might
|
|
want to look at a hex dump of your binary to determine the file offset at
|
|
which your code begins.
|
|
|
|
I escaped dealing with this problem because Micro-C's C compiler (MCC)
|
|
spits out an assembly file instead of object code. This provided me with
|
|
the opportunity to tweak and remove any extra junk before it gets a
|
|
chance to find its way into the executable.
|
|
|
|
However, I still had problems...
|
|
|
|
For example, the MCC compiler would always add extra segments and
|
|
place program elements in them. Variables translated to assembler would
|
|
always be prefixed with these unwanted segments (i.e. OFFSET DGRP:_var ).
|
|
|
|
Take the program:
|
|
|
|
char arr[]={'d','e','v','m','a','n','\0'};
|
|
void main(){}
|
|
|
|
MCC will process this file and spit out:
|
|
|
|
DGRP GROUP DSEG,BSEG
|
|
DSEG SEGMENT BYTE PUBLIC 'IDATA'
|
|
DSEG ENDS
|
|
BSEG SEGMENT BYTE PUBLIC 'UDATA'
|
|
BSEG ENDS
|
|
CSEG SEGMENT BYTE PUBLIC 'CODE'
|
|
ASSUME CS:CSEG, DS:DGRP, SS:DGRP
|
|
EXTRN ?eq:NEAR,?ne:NEAR,?lt:NEAR,?le:NEAR,?gt:NEAR
|
|
EXTRN ?ge:NEAR,?ult:NEAR,?ule:NEAR,?ugt:NEAR,?uge:NEAR
|
|
EXTRN ?not:NEAR,?switch:NEAR,?temp:WORD
|
|
CSEG ENDS
|
|
DSEG SEGMENT
|
|
PUBLIC _arr
|
|
_arr DB 100,101,118,109,97,110,0
|
|
DSEG ENDS
|
|
CSEG SEGMENT
|
|
PUBLIC _main
|
|
_main: PUSH BP
|
|
MOV BP,SP
|
|
POP BP
|
|
RET
|
|
CSEG ENDS
|
|
END
|
|
|
|
Rather than re-work the backend of the compiler, I implemented a more
|
|
immediate solution by creating a hasty post-processor. The alternative
|
|
would have been to manually adjust each assembly file that MCC produced,
|
|
and that was just too much work.
|
|
|
|
The following program ( convert.c ) creates a skeleton .COM program of the
|
|
form:
|
|
|
|
.486
|
|
CSEG SEGMENT BYTE USE16 PUBLIC 'CODE'
|
|
|
|
ORG 100H ; for DOS PSP only, strip and start OS on 0x0000 offset
|
|
|
|
here:
|
|
JMP _main
|
|
|
|
; --> add stuff here <----
|
|
|
|
EXTRN ?eq:NEAR,?ne:NEAR,?lt:NEAR,?le:NEAR,?gt:NEAR
|
|
EXTRN ?ge:NEAR,?ult:NEAR,?ule:NEAR,?ugt:NEAR,?uge:NEAR
|
|
EXTRN ?not:NEAR,?switch:NEAR,?temp:WORD
|
|
|
|
CSEG ENDS
|
|
END here
|
|
|
|
It then picks out the procedures and data elements in the original
|
|
assembly program and places them in the body of the skeleton. Here is the
|
|
somewhat awkward, but effective program that performed this task:
|
|
|
|
/* convert.c------------------------------------------------------------*/
|
|
|
|
#include<stdio.h>
|
|
#include<string.h>
|
|
|
|
/* read a line from fptr, place in buff */
|
|
|
|
int getNextLine(FILE *fptr,char *buff)
|
|
{
|
|
int i=0;
|
|
int ch;
|
|
|
|
ch = fgetc(fptr);
|
|
if(ch==EOF){ buff[0]='\0'; return(0); }
|
|
|
|
while((ch=='\n')||(ch=='\r')||(ch=='\t')||(ch==' '))
|
|
{
|
|
ch = fgetc(fptr);
|
|
if(ch==EOF){ buff[0]='\0'; return(0); }
|
|
}
|
|
|
|
while((ch!='\n')&&(ch!='\r'))
|
|
{
|
|
if(ch!=EOF){ buff[i]=(char)ch; i++; }
|
|
else
|
|
{
|
|
buff[i]='\0';
|
|
return(0);
|
|
}
|
|
|
|
ch = fgetc(fptr);
|
|
}
|
|
|
|
buff[i]='\r';i++;
|
|
buff[i]='\n';i++;
|
|
buff[i]='\0';
|
|
|
|
return(1);
|
|
|
|
}/*end getNextLine*/
|
|
|
|
/* changes DGRP:_variable to CSEG:_variable */
|
|
|
|
void swipeDGRP(char *buff)
|
|
{
|
|
int i;
|
|
i=0;
|
|
while(buff[i]!='\0')
|
|
{
|
|
if((buff[i]=='D')&&
|
|
(buff[i+1]=='G')&&
|
|
(buff[i+2]=='R')&&
|
|
(buff[i+3]=='P'))
|
|
{
|
|
buff[i]='C';buff[i+1]='S';buff[i+2]='E';buff[i+3]='G';
|
|
}
|
|
if((buff[i]=='B')&&
|
|
(buff[i+1]=='G')&&
|
|
(buff[i+2]=='R')&&
|
|
(buff[i+3]=='P'))
|
|
{
|
|
buff[i]='C';buff[i+1]='S';buff[i+2]='E';buff[i+3]='G';
|
|
}
|
|
i++;
|
|
}
|
|
return;
|
|
}/*end swipeDGRP*/
|
|
|
|
void main(int argc, char *argv[])
|
|
{
|
|
FILE *fin;
|
|
FILE *fout;
|
|
|
|
/*MASM allows lines to be 512 chars long, so have upper bound*/
|
|
|
|
char buffer[512];
|
|
char write=0;
|
|
|
|
fin = fopen(argv[1],"rb");
|
|
printf("Opening %s\n",argv[1]);
|
|
fout = fopen("os.asm","wb");
|
|
|
|
fprintf(fout,".486P ; enable 80486 instructions\r\n");
|
|
fprintf(fout,"CSEG SEGMENT BYTE USE16 PUBLIC \'CODE\'\r\n");
|
|
fprintf(fout,";\'USE16\' forces 16-bit offset addresses\r\n");
|
|
fprintf(fout,"ASSUME CS:CSEG, DS:CSEG, SS:CSEG\r\n");
|
|
fprintf(fout,"ORG 100H\r\n");
|
|
fprintf(fout,"here:\r\n");
|
|
fprintf(fout,"JMP _main\r\n\r\n");
|
|
|
|
fprintf(fout,"EXTRN ?eq:NEAR,?ne:NEAR,?lt:NEAR,?le:NEAR,?gt:NEAR\r\n");
|
|
fprintf(fout,"EXTRN ?ge:NEAR,?ult:NEAR,?ule:NEAR,?ugt:NEAR,?uge:NEAR\r\n");
|
|
fprintf(fout,"EXTRN ?not:NEAR,?switch:NEAR,?temp:WORD\r\n\r\n");
|
|
|
|
while(getNextLine(fin,buffer))
|
|
{
|
|
if((buffer[0]=='P')&&
|
|
(buffer[1]=='U')&&
|
|
(buffer[2]=='B')&&
|
|
(buffer[3]=='L')&&
|
|
(buffer[4]=='I')&&
|
|
(buffer[5]=='C')){ fprintf(fout,"\r\n"); write=1;}
|
|
|
|
if((buffer[0]=='D')&&
|
|
(buffer[1]=='S')&&
|
|
(buffer[2]=='E')&&
|
|
(buffer[3]=='G')){ write=0;}
|
|
|
|
if((buffer[0]=='B')&&
|
|
(buffer[1]=='S')&&
|
|
(buffer[2]=='E')&&
|
|
(buffer[3]=='G')){ write=0;}
|
|
|
|
if((buffer[0]=='R')&&
|
|
(buffer[1]=='E')&&
|
|
(buffer[2]=='T')){ fprintf(fout,"%s",buffer); write=0;}
|
|
|
|
if(write)
|
|
{
|
|
swipeDGRP(buffer);
|
|
fprintf(fout,"%s",buffer);
|
|
}
|
|
buffer[0]='\0';
|
|
}
|
|
|
|
fprintf(fout,"CSEG ENDS\r\n");
|
|
fprintf(fout,"END here\r\n");
|
|
|
|
fclose(fin);
|
|
fclose(fout);
|
|
return;
|
|
|
|
}/*end main-------------------------------------------------------------*/
|
|
|
|
--[ 3.3 - Booting Up
|
|
|
|
In the following discussion, I'm going to discuss booting from a floppy
|
|
disk. Booting from a hard drive, CD-ROM, or other storage device is
|
|
typically a lot more complicated due to partitioning and device formatting.
|
|
|
|
OK, the first thing I'm going to do is build a boot program. This program
|
|
has to be small. In fact, it has to be less than 512 bytes in size because
|
|
it has to fit on the very first logical sector of the floppy disk. Most
|
|
1.44 floppy disks have 80 tracks per side and 18 sectors per track. The
|
|
BIOS labels the two sides ( 0,1 ), tracks 0-79, and sectors 1-18.
|
|
|
|
When an Intel machine boots, the BIOS firmware (which resides
|
|
in a ROM chip on the motherboard) will look for a bootable storage
|
|
device. The order in which it does so can be configured on most machines
|
|
via a BIOS startup menu system. If the BIOS finds a boot diskette, it will
|
|
read the diskettes boot sector (Track 0, Side 0 and Sector 1) into memory
|
|
and execute the boot sector code. Some times this code will do nothing
|
|
more than print a message to the screen:
|
|
|
|
Not a boot disk, you are hosed.
|
|
|
|
All 8x86 machines start in real-mode, and the boot sector is loaded into
|
|
memory at the address 0000[0]:7C00 ( or 0x07C00 ) using hexadecimal. Once
|
|
this occurs, the BIOS washes its hands of the booting procedure and we
|
|
are left to our own devices.
|
|
|
|
Many operating systems will have the boot sector load a larger boot
|
|
program, which then loads the OS proper. This is known as a multi-stage
|
|
boot. Large operating systems that have a lot of things to set up,
|
|
a complicated file structure, and flexible configuration, will utilize
|
|
a multi-stage boot loader. A classic example of this is GNU's GRand
|
|
Unified Bootloader ( GRUB ).
|
|
|
|
http://www.gnu.org/software/grub
|
|
|
|
As usual, I am going to take the path of least resistance. I am going to
|
|
have the boot sector directly load my system code. The boot sector assumes
|
|
that the system code will be located directly after the boot sector
|
|
(track 0, side, 0, sector 2 ). This will save me from including special
|
|
data and instructions to read a file system. Finally, because of size
|
|
constraints, all the code in this section will be written in assembler.
|
|
|
|
The boot code follows:
|
|
|
|
;-boot.asm----------------------------------------------------------------
|
|
|
|
.8086
|
|
CSEG SEGMENT
|
|
start:
|
|
|
|
; step 1) load the OS on floppy
|
|
; to location above the
|
|
; existing interrupt table (0-3FF)
|
|
; and BIOS data region (400-7FF)
|
|
|
|
MOV AH,02H ; read command
|
|
MOV AL,10H ; 16 sectors = 8KB of storage to load
|
|
MOV CH,0H ; low 8 bits of track number
|
|
MOV CL,2H ; sector start ( right after boot sector )
|
|
MOV DH,0H ; side
|
|
MOV DL,0H ; drive
|
|
MOV BX,CS
|
|
MOV ES,BX ; segment to load code
|
|
MOV BX,0H
|
|
MOV BX,800H ; offset to load code ( after IVT )
|
|
INT 13H
|
|
|
|
; signal that code was loaded and we are going to jump
|
|
|
|
MOV AH,0EH
|
|
MOV AL,'-'
|
|
INT 10H
|
|
MOV AH,0EH
|
|
MOV AL,'J'
|
|
INT 10H
|
|
MOV AH,0EH
|
|
MOV AL,'M'
|
|
INT 10H
|
|
MOV AH,0EH
|
|
MOV AL,'P'
|
|
INT 10H
|
|
MOV AH,0EH
|
|
MOV AL,'-'
|
|
INT 10H
|
|
|
|
; step 2) jump to the OS
|
|
; bonzai!!!
|
|
|
|
JMP BX
|
|
|
|
CSEG ENDS
|
|
END start
|
|
|
|
;-end file----------------------------------------------------------------
|
|
|
|
This boot loader also assumes that the system code to be loaded lies
|
|
in sectors 2-17 on the first track. As the OS gets bigger ( beyond 8K ),
|
|
extra instructions will be needed to load the additional code. But for now
|
|
lets assume that the code will be less than 8K in size.
|
|
|
|
OK, you should build the above code as a .COM file and burn it on to the
|
|
boot sector. The boot.asm file is assembled via:
|
|
|
|
C:\> ML /AT boot.asm
|
|
|
|
How do you do burn it on to the floppy disk's boot sector?
|
|
|
|
Ah ha! Debug to the rescue. Note, for big jobs I would recommend rawrite.
|
|
This is such a small job that debug will suffice. Not to mention, I have
|
|
nostalgic feeling about debug. I assembled my first program with it; back
|
|
in the 1980s when parachute pants were in.
|
|
|
|
Assuming the boot code has been assembled to a file named boot.COM, here
|
|
is how you would write it to the boot sector of a floppy disk.
|
|
|
|
C:\DOCS\OS\lab\bsector>debug showmsg.com
|
|
-l
|
|
-w cs:0100 0 0 1
|
|
-q
|
|
C:\DOCS\OS\lab\bsector>
|
|
|
|
The 'l' command loads the file to memory starting at CS:0100 hex.
|
|
The 'w' command writes this memory to disk A ( 0 ) starting at sector 0
|
|
and writing a single sector. The 'w' command has the general form:
|
|
|
|
w address drive start-sector #-sectors
|
|
|
|
Note, DOS sees logical sectors ( which start with 0 ), whereas
|
|
physical (BIOS manipulated) sectors always start with 1.
|
|
|
|
If you want to test this whole procedure, assemble the following program
|
|
as a .COM file and burn it on to the boot sector of a diskette with debug.
|
|
|
|
.486
|
|
CSEG SEGMENT
|
|
start:
|
|
MOV AH,0EH
|
|
MOV AL,'-'
|
|
INT 10H
|
|
MOV AH,0EH
|
|
MOV AL,'h'
|
|
INT 10H
|
|
MOV AH,0EH
|
|
MOV AL,'i'
|
|
INT 10H
|
|
MOV AH,0EH
|
|
MOV AL,'-'
|
|
INT 10H
|
|
lp LABEL NEAR
|
|
JMP lp
|
|
CSEG ENDS
|
|
END start
|
|
|
|
This will print '-hi-' to the console and then loop. It's a nice way to
|
|
break the ice and build your confidence. Especially if you've never
|
|
manually meddled with disk sectors.
|
|
|
|
--[ 3.4 - Initializing The OS
|
|
|
|
The boot sector loads the system code binary into memory and then sets
|
|
CS and IP to the first ( lowest ) byte of the code's instructions. My
|
|
system code doesn't do anything more than print a few messages and then
|
|
jump to protected mode. Execution ends in an infinite loop.
|
|
|
|
I wrote the program using real-mode instructions. Intel machines all
|
|
start up in real-mode. It is the responsibility of this initial code to
|
|
push the computer into protected memory mode. Once in protected mode,
|
|
the OS will adjust its segment registers, set up a stack, and establish
|
|
an execution environment for applications ( process table, drivers, etc.).
|
|
|
|
This made life difficult because if I could only go so far using
|
|
real-mode instructions and registers. Eventually, I would need to
|
|
use the extended registers (i.e. EAX ) to access memory higher up.
|
|
|
|
Some compilers won't accept a mixture of 16-bit and 32-bit
|
|
instructions, or they get persnickety and encode instructions incorrectly.
|
|
If you look at the FAR JMP that I make at the end of setUpMemory(), you'll
|
|
notice that I had to code it manually.
|
|
|
|
My situation was even more tenuous because I was fitting everything into a
|
|
single segment. Once I had made the translation to protected mode, there
|
|
wasn't that much that I could do that was very interesting.
|
|
|
|
One solution would be to convert my 16-bit system code into the second
|
|
phase of a multi-stage boot process. In other words, have the system code,
|
|
which was loaded by the boat sector, load a 32-bit binary into memory
|
|
before it makes the transition to protected mode. When the FAR JMP is
|
|
executed, it could send execution to the 32-bit code ... which could then
|
|
take matters from there. If you look at MMURTL, you will see that this
|
|
is exactly what Burgess does. Doh! I just wish I had known sooner.
|
|
|
|
I was excited initially by the thought of being able to leverage the Micro-
|
|
C compiler. However, as you will see, most of the set up work was done
|
|
via in-line assembly. Only small portions were pure C. This is the nature
|
|
of initializing an OS. Key memory and task management functions are
|
|
anchored directly to the hardware, and the best that you can hope for is
|
|
to bury the assembly code deep in the bowels of the OS and wrap everything
|
|
in C.
|
|
|
|
Here is the system code (os.c), in all its glory:
|
|
|
|
/* os.c ----------------------------------------------------------------*/
|
|
|
|
void printBiosCh(ch)
|
|
char ch;
|
|
{
|
|
/*
|
|
ch = BP + savedBP + retaddress = BP + 4 bytes
|
|
*/
|
|
asm "MOV AH,0EH";
|
|
asm "MOV AL,+4[BP]";
|
|
asm "INT 10H";
|
|
return;
|
|
}/*end printBiosCh---------------------------------------*/
|
|
|
|
void printBiosStr(cptr,n)
|
|
char* cptr;
|
|
int n;
|
|
{
|
|
int i;
|
|
for(i=0;i<n;i++){ printBiosCh(cptr[i]); }
|
|
return;
|
|
}/*end printBiosStr--------------------------------------*/
|
|
|
|
void setUpMemory()
|
|
{
|
|
/*going to protected mode is an 6-step dance*/
|
|
|
|
/* step 1) build GDT ( see GDT table in function below )*/
|
|
printBiosCh('1');
|
|
|
|
/*
|
|
step 2) disable interrupts so we can work undisturbed
|
|
( note, once we issue CLI, we cannot use BIOS interrupts
|
|
to print data to the screen )
|
|
*/
|
|
|
|
printBiosCh('2');
|
|
asm "CLI";
|
|
|
|
/*
|
|
step 3) enable A20 address line via keyboard controller
|
|
60H = status port, 64H = control port on 8042
|
|
*/
|
|
|
|
asm "MOV AL,0D1H";
|
|
asm "OUT 64H,AL";
|
|
asm "MOV AL,0DFH";
|
|
asm "OUT 60H,AL";
|
|
|
|
/*
|
|
step 4) execute LGDT instruction to load GDTR with GDT info
|
|
recall GDTR = 48-bits
|
|
= [32-bit base address][16-bit limit]
|
|
HI-bit LO-bit
|
|
*/
|
|
|
|
asm "JMP overRdata";
|
|
asm "gdtr_stuff:";
|
|
asm "gdt_limit DW 0C0H";
|
|
asm "gdt_base DD 0H";
|
|
asm "overRdata:";
|
|
|
|
/*
|
|
copy GDT to 0000[0]:0000 ( linear address is 00000000H )
|
|
makes life easier, so don't have to modify gdt_base
|
|
REP MOVSB moves DS:[SI] to ES:[DI] until CX=0
|
|
*/
|
|
|
|
asm "MOV AX,OFFSET CS:nullDescriptor";
|
|
asm "MOV SI,AX";
|
|
asm "MOV AX,0";
|
|
asm "MOV ES,AX";
|
|
asm "MOV DI,0H";
|
|
asm "MOV CX,0C0H";
|
|
asm "REP MOVSB";
|
|
|
|
asm "LGDT FWORD PTR gdtr_stuff";
|
|
|
|
/* step 5) set first bit in CR0, protected mode bit*/
|
|
|
|
asm "smsw ax";
|
|
asm "or al,1";
|
|
asm "lmsw ax";
|
|
|
|
/*
|
|
step 6) perform a manually coded FAR JUMP
|
|
( MASM would encode it incorrectly in 'USE16' mode )
|
|
*/
|
|
|
|
asm "DB 66H";
|
|
asm "DB 67H";
|
|
asm "DB 0EAH";
|
|
asm "DW OFFSET _loadshell";
|
|
asm "DW 8H";
|
|
|
|
/* end of the line, infinite loop */
|
|
|
|
asm "_loadshell:";
|
|
asm "NOP";
|
|
asm "JMP _loadShell";
|
|
|
|
return;
|
|
}/*end setUpMemory---------------------------------------*/
|
|
|
|
/* our GDT has 3 descriptor (null,code,data)*/
|
|
|
|
void GDT()
|
|
{
|
|
/*
|
|
end up treating the function body as data
|
|
( can treat code as data as long as we don't execute it ;-))
|
|
*/
|
|
|
|
asm "nullDescriptor:";
|
|
asm "NDlimit0_15 dw 0 ; seg. limit";
|
|
asm "NDbaseAddr0_15 dw 0 ; base address";
|
|
asm "NDbaseAddr16_23 db 0 ; base address";
|
|
asm "NDflags db 0 ; segment type and flags";
|
|
asm "NDlimit_flags db 0 ; segment limit and flags";
|
|
asm "NDbaseAddr24_31 db 0 ; final 8 bits of base address";
|
|
|
|
asm "codeDescriptor:";
|
|
asm "CDlimit0_15 dw 0FFFFH";
|
|
asm "CDbaseAddr0_15 dw 0";
|
|
asm "CDbaseAddr16_23 db 0";
|
|
asm "CDflags db 9AH";
|
|
asm "CDlimit_flags db 0CFH";
|
|
asm "CDbaseAddr24_31 db 0";
|
|
|
|
asm "dataDescriptor:";
|
|
asm "DDlimit0_15 dw 0FFFFH";
|
|
asm "DDbaseAddr0_15 dw 0";
|
|
asm "DDbaseAddr16_23 db 0";
|
|
asm "DDflags db 92H";
|
|
asm "DDlimit_flags db 0CFH";
|
|
asm "DDbaseAddr24_31 db 0";
|
|
|
|
return;
|
|
|
|
}/*end GDT-----------------------------------------------*/
|
|
|
|
char startStr[7] = {'S','t','a','r','t','\n','\r'};
|
|
char startMemStr[10] = {'I','n','i','t',' ','m','e','m','\n','\r'};
|
|
char tstack[128];
|
|
|
|
void main()
|
|
{
|
|
/*set up temp real-mode stack*/
|
|
asm "MOV AX,CS";
|
|
asm "MOV SS,AX";
|
|
asm "MOV AX, OFFSET CSEG:_tstack";
|
|
asm "ADD AX,80H";
|
|
asm "MOV SP,AX";
|
|
|
|
/*successfully made JMP to OS from boot loader*/
|
|
printBiosStr(startStr,7);
|
|
|
|
/*set up Basic Protected Mode*/
|
|
printBiosStr(startMemStr,10);
|
|
setUpMemory();
|
|
|
|
return;
|
|
}/*end main-------------------------------------------------------------*/
|
|
|
|
|
|
--[ 3.5 - Building and Deploying
|
|
|
|
Because the OS was written in C and in-line assembler, the build
|
|
process involved three distinct steps. First, I compiled my system code to
|
|
assembly with:
|
|
|
|
mcp os.c | mcc > osPre.asm
|
|
|
|
Note, mcp is Micro-C's pre-processor.
|
|
|
|
Chuck it all in one 16-bit segment:
|
|
|
|
convert osPre.asm
|
|
|
|
Once I had an .ASM file in my hands, I assembled it:
|
|
|
|
ML /Fllist.txt /AT /Zm -c osPre.asm
|
|
|
|
Note how I've had to use the /Zm option so that I can assemble code that
|
|
obeys conventions intended for earlier versions of MASM. This step is
|
|
typically where the problems occurred. Needless to say, I became tired of
|
|
fixing up segment prefixes rather quickly and that is what led me to
|
|
write convert.c.
|
|
|
|
Finally, after a few tears, I linked the OS object file to one of Micro-C's
|
|
object files.
|
|
|
|
LINK os.obj PC86RL_T.OBJ /TINY
|
|
|
|
If you look back at convert.c, you'll see a whole load of EXTRN directives.
|
|
All of these imported symbols are math libraries that are located in the
|
|
PC86RL_T.OBJ file.
|
|
|
|
If you have a copy of NASM on your machine, you can verify your work with
|
|
the following command:
|
|
|
|
ndisasmw -b 16 os.com
|
|
|
|
This will dump a disassembled version of the code to the screen. If you
|
|
want a more permanent artifact, then use the listing file option when you
|
|
invoke ML.EXE:
|
|
|
|
ML /AT /Zm /Fl -c os.asm
|
|
|
|
Once you have the OS and boot sector code built. You should burn them on
|
|
to the boot floppy. You can do so with the DOS debug utility.
|
|
|
|
C:\DOCS\OS\lab\final>debug boot.com
|
|
-l
|
|
-w cs:0100 0 0 1
|
|
-q
|
|
|
|
C:\DOCS\OS\lab\final>debug os.com
|
|
-l
|
|
-w cs:0100 0 1 2
|
|
-q
|
|
|
|
After that, you just boot with the floppy disk and hang on!
|
|
|
|
I hope this article gave you some ideas to experiment with. Good luck
|
|
and have fun.
|
|
|
|
"Contrasting this modest effort [of Seymour Cray in his laboratory to
|
|
build the CDC 6600] with 34 people including the janitor with our vast
|
|
development activities, I fail to understand why we have lost our
|
|
industry leadership position by letting someone else offer the world's
|
|
most powerful computer."
|
|
-Thomas J. Watson, IBM President, 1965
|
|
|
|
"It seems Mr. Watson has answered his own question."
|
|
-Seymour Cray
|
|
|
|
--[ 4 - References and Credits
|
|
|
|
[1] Operating Systems: Design And Implementation,
|
|
Andrew S. Tanenbaum, Prentice Hall, ISBN: 0136386776
|
|
This book explains how the Minix operating system functions.
|
|
Linux was originally Linus's attempt at creating a production
|
|
quality version of Minix. Minix is an Intel OS.
|
|
|
|
[2] MMURTL V1.0, Richard A. Burgess, Sensory Publishing, ISBN: 1588530000
|
|
MMURTL is another Intel OS. Unlike Tanenbaum, Burgess dives
|
|
into more sophisticated topics, like memory paging. Another
|
|
thing I admire about Burgess is that he'll answer your e-mail
|
|
without getting snooty like Tanenbaum. If Minix gave birth to
|
|
Linux, then MMURTL may also be reincarnated as the next big thing.
|
|
|
|
[3] Dissecting DOS, Michael Podanoffsky, Addison-Wesley Pub,
|
|
ISBN: 020162687X
|
|
In this book, Podanoffsky describes a DOS clone named RxDOS.
|
|
RxDOS is presented as a real-mode OS and is written entirely
|
|
in assembly code.
|
|
|
|
[4] FreeDOS Kernel, Pat Villani, CMP Books, ISBN: 0879304367
|
|
Another DOS clone ... but this one is written in C, whew!
|
|
|
|
[5] Virtual Machine Design and Implementation In C/C++, Bill Blunden,
|
|
Wordware Publishing, ISBN: 1556229038
|
|
Yes, it's time for the self-plug. Writing a VM is really only a
|
|
hop, skip, and a jump, from writing a simulator. My book presents
|
|
all the information in this article and a whole lot more. This
|
|
includes a complete virtual machine, assembler, and debugger.
|
|
|
|
[6] Linux Core Kernel Commentary, 2nd Edition, Scott Andrew Maxwell,
|
|
The Coriolis Group; ISBN: 1588801497
|
|
This is an annotated stroll through the task and memory management
|
|
source code of Linux.
|
|
|
|
[7] The Design and Implementation of the 4.4BSD Operating System,
|
|
Marshall Kirk McKusick (Editor), Keith Bostic, Michael J. Karels (Editor)
|
|
Addison-Wesley Pub Co; ISBN: 0201549794
|
|
These guys are all deep geeks. If you don't believe me, look
|
|
at the group photo on the inside cover. This book is a
|
|
comprehensive overview of the FreeBSD OS.
|
|
|
|
[8] The Undocumented PC : A Programmer's Guide, Frank Van Gilluwe,
|
|
Addison-Wesley Pub, ISBN: 0201479508
|
|
If you're doing I/O on Intel, it truly helps to have this book.
|
|
|
|
[9] Control Data Corporation
|
|
There are a numerous old fogeys from Control Data that I
|
|
would like to thank for offering their help and advice.
|
|
Control Data was killed by its management, but there
|
|
were a handful of gifted engineers, like Cray, who made sure
|
|
that some of the good ideas found a home.
|
|
|
|
[10] IBM and the Holocaust: The Strategic Alliance Between Nazi Germany
|
|
and America's Most Powerful Corporation, Edwin Black,
|
|
Three Rivers Press; ISBN: 0609808990
|
|
I originally heard about this through one of Dave Emory's
|
|
radio broadcasts. Mae Brussell would agree ... profit at
|
|
any cost is not a good thing.
|
|
|
|
I would like to thank George Matkovitz, who wrote the first message-based
|
|
kernel in the world, and Mike Adler, a compiler wizard who was there
|
|
when Cray whipped IBM for sharing their thoughts and experiences with me.
|
|
|
|
<EOF>
|
|
|
|
|
|
|=[ 0x03 ]=--------------------------------------------------------------=|
|
|
|
|
L O C K P I C K I N G
|
|
BY
|
|
/< n i g h t m a r e
|
|
|
|
As per usual, I accept no responsibility for your actions using this
|
|
file; It is only here to show how locksmiths gain access when keys are
|
|
missing or broken.
|
|
|
|
|
|
CONTENTS
|
|
|
|
INTRODUCTION
|
|
1 The warded Lock
|
|
2 Pin-tumbler lock and wafer locks
|
|
3 Wafer locks
|
|
4 The tension wrench turning tool
|
|
5 Raking pin-tumbler locks and wafer cylinder locks
|
|
6 Picking locks without a Turning tool
|
|
7 The lock gun
|
|
9 Pure picking
|
|
10 Opening locks without picking
|
|
11 Rapping open locks
|
|
12 TOOLS AND APPARATUS
|
|
|
|
|
|
|
|
|
|
INTRODUCTION
|
|
|
|
The main purpose of writing this work is to provide the modern student with
|
|
an up-to-date, accurate book to enable him to explore the fascinating
|
|
subject of lock picking. In by gone years, people who were drawn to magic of
|
|
the lock, were tempted to 'pick locks', and were confronted by obstacles to
|
|
protect the lock, such as devices which would shoot steel barbs into the
|
|
picker's hands. vicious toothed jaws were employed to cut off the thiefs
|
|
fingers. perhaps the most fearsome lock pick deterrent was a devilish device
|
|
which would fire a bullet if the locking mechanism was tampered with.
|
|
|
|
Books and manuscripts over the years change hands.
|
|
Unfortunately, in the case of this type of work, it could fall into the
|
|
wrong hands. However unlike such works as '1001 ways to have fun with a
|
|
Frankfurter', the person who is merely curious will find this work tiresome
|
|
and unpalatable, leaving the true enthusiasts to explore the teasing allure
|
|
of the lock. This unique animal who has ingenuity and patience to follow
|
|
through the fascinating study, will be rewarded in the knowledge that he is
|
|
in the elite company that I salute in this work. for the people who argue
|
|
books on this subject should not be written, I would like to point out that
|
|
a villain who wishes to gain entry into a property in happier with a brick
|
|
than a pick.
|
|
|
|
Have fun and enjoy your new hobby or trade !
|
|
|
|
|
|
CHAPTER 1: THE WARDED LOCK
|
|
|
|
Probably the best place to begin this book is at the point at which mass
|
|
lock manufacture began, with the WARDED LOCK. These locks are generally of
|
|
simple construction, These are of simple construction and generally, and
|
|
therefore recommended for the beginner. The dictionary defines 'ward' as 'to
|
|
guard, keep away, or to fend off', which in reality is exactly what the lock
|
|
does.
|
|
(See FIG. 1.) The small circular section is the ward with the wrong type of
|
|
key attempting to open the lock. Ti is quite obvious that if this key were
|
|
to be turned, its turning path would be halted by the protruding ward.
|
|
|
|
___________ ____ __________ ____
|
|
________ ) / \ \ ______ ) / \ \
|
|
| _| | | | <-Wards | [ | | |
|
|
|[ \____/ Bit -> |__[ \____/
|
|
|
|
FIG. 1 FIG. 2
|
|
|
|
FIG. 2 shows the correct key which will open the warded lock.
|
|
It has just the right cuts on the bit to miss the wards. warded locks are
|
|
found in many forms. FIG. 3 is a normal key, with an intricate patterned bit
|
|
which would open an old and beautifully designed, elaborate ward lock. At
|
|
this point, I would like to say that key collecting had become a hobby for
|
|
many people. Since keys are quite easy to come by, a nice display can soon
|
|
be obtained.
|
|
|
|
__
|
|
/ \__.,-,________
|
|
\__/--.,-,--------'
|
|
[]
|
|
[[
|
|
Normal Key
|
|
|
|
FIG. 3
|
|
|
|
the security of the warded lock was further enhanced by the shape of the key
|
|
hole, preventing entry to everything apart from the correct key. the
|
|
extravagant shapes, in both the wards and the key holes, are the only
|
|
problems which we must overcome in picking open the warded lock. we do this
|
|
by inserting a pick, which is much thinner than the lock's keyhole, or by
|
|
using a skeleton key. FIG. 5 shows this best in the case of the skeleton
|
|
key, which would open the same lock which is in our FIG. 3. This skeleton
|
|
key has been cut from a blank. The area which would fool the locks ward's
|
|
has been removed, forming the new key. For the complete newcomer the world
|
|
of locks, I should explain that the word 'blank' is the name given to the
|
|
key before it is cut to the desired shape.
|
|
|
|
______ __.__________
|
|
| /\ | __ __ __ __|
|
|
| || | ' _|| ||_
|
|
| \\ | |.-' '-.|
|
|
| // | || ||
|
|
| C| | skeleton|'-. .-'|
|
|
| || | key '--' '--'
|
|
|______|
|
|
|
|
FIG. 4 FIG. 5
|
|
|
|
|
|
FIG. 6 looks inside a typical warded padlock. It is clear that, because of
|
|
the wards which obstruct the turning, only the correct key (as shown) will
|
|
open this lock. it is guarded by six, close-fitting wards, and also by the
|
|
small, thin keyhole.
|
|
|
|
|
|
_____
|
|
/ ___ \
|
|
__/ / \ \__
|
|
| \___/ |
|
|
\ /
|
|
\____ ____/
|
|
/ \
|
|
______| |______
|
|
| __ ( ) __ |
|
|
.---> | (__| | | |__) |
|
|
| | < > |
|
|
Wards ---|---> | ====| |==== |
|
|
| | ( ) |
|
|
'---> | =====|_ _|===== |
|
|
| [[[[(_____)]]]] |
|
|
| (_) |
|
|
|_________________|
|
|
Y Y
|
|
| |
|
|
Opening spring
|
|
|
|
FIG. 7 shows how we overcome this lock with a key that has been skeletoned,
|
|
and which will now open this and many others.
|
|
This has been achieved by removing all the projections other than the end
|
|
which comes into contact with the spring-opening point.
|
|
Take a look and make sure you read and understand this before moving on.
|
|
|
|
__
|
|
_ __nn_n/ \_
|
|
(_| |______ o_:
|
|
_ __ _\__/
|
|
U UU U
|
|
|
|
FIG. 7
|
|
|
|
FIG. 8 is a warded pick in it's most simple form - a coil spring with it's
|
|
end bend and flattened. If the coil is of suitable diameter, it will fit
|
|
onto the end of your index finger. This forms, as it were, an extension of
|
|
your finger, and you will find that it is a highly sensitive tool to fell
|
|
the layout of the interior and so find and trigger the mechanism. This
|
|
sensitive manipulation can be achieved only with practice. If the spring
|
|
pick becomes weak or bent simply pull out a new length from the coil and you
|
|
have a brand new tool.
|
|
|
|
Before we move on, I would suggest that you build up a large set of picks
|
|
of different sizes.
|
|
|
|
________________________________________
|
|
| ____ |
|
|
| /\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/ | |
|
|
|________________________________________|
|
|
Coil Spring
|
|
|
|
FIG. 8
|
|
Look inside as many locks as possible -- it's the finest way of becoming a
|
|
lock expert. picking locks is a true art form and even more difficult than
|
|
learning to play a musical instrument proficiently.
|
|
|
|
Here is a useful lock picking set to make:
|
|
____
|
|
/ \_____________|
|
|
\____/ |
|
|
____
|
|
/ \_____________.
|
|
\____/ '
|
|
____
|
|
/ \___________._.
|
|
\____/ ' '
|
|
____
|
|
/ \_____________
|
|
\____/ |
|
|
____
|
|
/ \___________|_|
|
|
\____/ | |
|
|
____
|
|
/ \____________.-
|
|
\____/ '-
|
|
FIG. 9
|
|
|
|
|
|
In summing up the subject of warded locks, I would say that once you have
|
|
clearly understood that the wards simply guard the opening, and also that
|
|
the actual shape of the keyhole prevents the wrong key entering, you are
|
|
well on the right path to becoming a total master at this type of lock.
|
|
start looking for warded locks: they are usually older locks or at the cheap
|
|
end of the market.
|
|
|
|
The most difficult task before the novice must be to identify the particular
|
|
type of lock he is trying to pick. Is the lock a WAFER or PIN-TUMBLER? Or,
|
|
in the case of the raw beginner, is the lock a LEVER or PIN-TUMBLER? There
|
|
is no simple answer. The ability to identify the particular types comes only
|
|
with practice and study.
|
|
Open up as many old locks as you can and study the principles, LOOKING ALL
|
|
THE TIME FOR WEAK POINTS which are built into the design. Believe me, ALL
|
|
locks have weak points.
|
|
|
|
|
|
CHAPTER 2: PIN TUMBLER and WAFER LOCKS
|
|
|
|
As in all lock picking, it is an advantage that the student is fully
|
|
conversant with the basic operation of the lock. In the case of the
|
|
PIN-TUMBLER and WAFER it is absolutely vital. The number of times I have
|
|
read leading works on the subject, and then asked myself if I would fully
|
|
understand how the lock worked from their description ! each book I read
|
|
failed to explain accurately and precisely how these locks work and can be
|
|
picked. what follows is my own humble effort to right this wrong. You
|
|
yourself must judge if I have obtained this objective.
|
|
|
|
When we first look at this type of lock, it would appear that all
|
|
necessary to insert a small implement into the keyway and give it a turn for
|
|
the device to open. plainly this is not the case, as we can see when we take
|
|
a closer look at FIG. 10 This is a typical PIN-TUMBLER lock, and generally
|
|
consists of pairs of bottom pins made from brass and with the top drivers
|
|
formed in steel. Commonly, five pairs of pins are found. in the smaller,
|
|
cheaper models, four are more common.
|
|
|
|
______________________________
|
|
\ K
|
|
| | | | | | / E
|
|
| | | | \ Y [|] Upper tumbler pin
|
|
^ ^ / H [^] Lower tumbler pin
|
|
^ ^ ^ ^ ^ ^ \ O [-] Cylinder wall
|
|
/ L This is a greatly simplified
|
|
\ E drawing
|
|
______________________________/
|
|
|
|
FIG. 10
|
|
|
|
|
|
_______
|
|
Shear Line / ___ \
|
|
- - - - -| |///| | <-- Springs
|
|
/ |[ ]|<-\----- Top Drivers
|
|
Plug\ \ @ /<-/----- Bottom Pins
|
|
\___|___/
|
|
Key
|
|
|
|
FIG. 11
|
|
|
|
_______
|
|
Shear Line / ___ \
|
|
- - - - -| |///| |
|
|
/ |[ ]| /\
|
|
\ / / / <-- Plug Turning
|
|
\___///_/
|
|
|
|
FIG. 11a
|
|
|
|
|
|
________
|
|
/ \
|
|
Shearing Line --> __ _ ___ _ ___ _ ___ / \ A
|
|
/ _ _ _ _ _ \/ /\ \
|
|
/ |_||_||_||_||_| ___/\ \/ / K
|
|
\ / \/\/\/\/\/\/\____\/ / E
|
|
\____________________/\__________/ Y
|
|
|
|
FIG. 12
|
|
|
|
FIG. 11 is the end-view of the arrangement. Each of the locks shown in FIGS.
|
|
10, 11 and 12 are ready to open, since in each case they have been given the
|
|
right key ready to turn the plug.
|
|
FIG. 12 shows each of the five bottom brass pins settled into it's own notch
|
|
along the key. This ha the effect of bringing the point between the drivers
|
|
and the pins EXACTLY to the same height. ONLY THE PROPER KEY WILL ALIGN ALL
|
|
FIVE PINS AT THIS HEIGHT, WHICH WE CALL THE SHEAR OR SHEARING LINE, AT THE
|
|
SAME TIME. All five pins must be in line together, and, when we have this
|
|
state of affairs, the plug will turn opening the lock. FIG. 11a shows the
|
|
plug starting to turn. FIG. 11 is an end-view, and shows the shaded plug
|
|
ready to turn. Make sure you fully understand this before you go on. Most
|
|
students fail to understand that the bottom brass pins TURN WITH THE PLUG.
|
|
FIG. 13 shows this. the top holding drivers stay put in the chambers in the
|
|
outer case. Remember that the bottom pins must turn with the plug because
|
|
they are contained within unit. It is important to know that if only one
|
|
notch on the key is even SLIGHTLY wrong, too high or too low, the plug would
|
|
be prevented from turning, just one pin, sitting into this plug from the
|
|
outer case, has such an amazing strength that it would be impossible to snap
|
|
-- such is the power of each little pin.
|
|
|
|
|
|
:::::
|
|
___ ##### <-- Top Drivers
|
|
/ \ooooo Plug Turning |
|
|
\___/===== <'
|
|
OOOOO <-- Bottom pins
|
|
|
|
FIG. 13
|
|
|
|
I have cut away the plug in FIG. 13 and the pins can clearly be seen in the
|
|
turning motion. With all the required points within the lock aligned, the
|
|
plug must and will turn. However, let us take a look at what would happen if
|
|
the wrong key were inserted. FIG. 14 shows this, with the top drivers, still
|
|
inside the plugs, preventing it from turning. The wrong key is just as bad
|
|
as no key, and the lock stays locked.
|
|
|
|
Chambers
|
|
______/___|___\______
|
|
| / | \ |
|
|
| \/ V \/ |
|
|
| __ __ __ |
|
|
--------| __ | | | | | | |-------- <-- Shear line
|
|
Plug --> _|_| |_| |_| |_| |_|_
|
|
[ | | | | | | | | | | ]
|
|
[ | '--' '--' '--' '--' | ]
|
|
[ | .--. .--. .--. .--. | ]
|
|
[ | '--' '--' '--' '--' | ]
|
|
[_|_____________________|_]
|
|
'---------------------'
|
|
FIG. 14
|
|
|
|
FIG. 15 is the end-view, showing the top driver inside the plug, preventing
|
|
the turning, and the driver just below the shearing line. I have already
|
|
said that these little drivers are manufactured from steel and are very
|
|
strong indeed, overcoming any force that a normal wrong key or instrument
|
|
could present. even if there were only one little driver inside the plug, it
|
|
would still be unable to rotate, or be snapped at the shear line. Now
|
|
multiply that strength by five, and I am sure that you will understand it's
|
|
almost superhuman strength. Before I move on I must explain that there a no
|
|
skeleton keys which will magically open this lock, or it's brother the
|
|
WAFER.
|
|
|
|
Note top drivers are inside plug
|
|
______ preventing any turning
|
|
/______\
|
|
// == \\
|
|
|| == ||
|
|
|| () ||
|
|
Shearing line --> -----||-[||]-||-----
|
|
|| [==] ||
|
|
\\__##__// ## - Bottom pins
|
|
\______/ [==] Plug
|
|
|
|
FIG. 15
|
|
|
|
The turning tool replaces the bottom part of the key, and the pick replaces
|
|
the notches on the key. Just think of the turning tool as part of the key,
|
|
and the pick as the notches. Once you have all the points inside the line,
|
|
only a small amount of light pressure is needed to turn the plug. Most books
|
|
on the subject stress that too much pressure is wrong. FIG. 20 shows the top
|
|
driver inside the chamber binding on three points, because the tension is
|
|
too great. Trial and error seems to be the only true way, with only light
|
|
turning applied.
|
|
|
|
|
|
Chapter 3: WAFER LOCKS
|
|
|
|
FIG. 16 shows a single-sided wafer lock. This type of lock contains WAFERS
|
|
instead of pins and drivers, and is known as a DISC-TUMBLER instead of a pin
|
|
tumbler. the wafers, five as in a pin-tumbler, are held in place by a small,
|
|
light spring, as shown (left hand side) of FIGS. 16 and 17. FIG. 16 shows
|
|
the lock closed, and FIG. 17 open. The wafer lock is best opened by RAKING,
|
|
which is explained later in this work.
|
|
|
|
|
|
|
|
|
|
________ ________
|
|
/ __ \ / __ \
|
|
=| / \ | =| / \ |
|
|
=| | | | =| | | |
|
|
/_ \__/ | /_ \__/ |
|
|
\__ __/ \__ __/
|
|
--.\__/.-- __ \__/ __
|
|
'----' '____'
|
|
Locked Unlocked
|
|
|
|
FIG. 16 FIG. 17
|
|
|
|
|
|
Chapter 4: THE TENSION WRENCH TURNING TOOL
|
|
|
|
Probably the single most important factor in lock manipulation is the use of
|
|
the TENSION WRENCH which I prefer to call the TURNING TOOL. perhaps if it
|
|
had been given this name in the first place, hundreds of aspiring locksmiths
|
|
would have had greater instant success. I maintain that the word 'tension'
|
|
implies that great pressure has to be exerted by this tool. Add to this the
|
|
word 'wrench' and totally the wrong impression is given. in order that you
|
|
will fully understand the use of this turning tool, I will explain it's
|
|
simple function. FIG. 18 shows an normal pin-tumbler or wafer key; FIG. 19
|
|
shows the key cut away. This bottom section is now a turning tool. the
|
|
reality is that the notches along the key would lift the bottom pins level
|
|
with the shearing line, and the part beneath would turn the plug.
|
|
|
|
|
|
|
|
|
|
|
|
____ ____ ,_^^,^,-.-^.
|
|
/ \,_^^,^,-.-^. / \/'_____________
|
|
\____/-----------' \____/---------------' <-- Turning tool
|
|
|
|
FIG. 18 FIG. 19
|
|
|
|
|
|
The turning tool replaces the bottom part of the key, and the pick replaces
|
|
the notches on the key. Just think of the turning tool as part of the key,
|
|
and the picks as the notches. Once you have all of the points inside the
|
|
line, only a small amount of light pressure is needed to turn the plug. Most
|
|
books on the subject stress that too much pressure is wrong. The student
|
|
must first know why too much tension is wrong. FIG. 20 shows the top driver
|
|
inside the chamber binding on the tree points, because the tension is too
|
|
great. Trial and error seems to be the only true way, with only light
|
|
turning applied
|
|
|
|
___________
|
|
| ------. <|----Spring
|
|
| .-----' | Top chamber
|
|
| '-----. |
|
|
| .-----' |
|
|
| _'--_____ | Binding
|
|
|| || |
|
|
|| || V
|
|
______|| ||______
|
|
------.|_________|.------ Shear line
|
|
| | <-- Binding
|
|
|
|
|
|
|
|
FIG. 20
|
|
|
|
If you are raking open a lock, no real pressure need be applied because the
|
|
pins and wafers MUST be free to bounce into line with the shearing line. if
|
|
too much pressure is used, it prevents this as shown in FIG. 20. Multiply
|
|
the one shown by, and you can imagine the lock is well and truly bound
|
|
tight. I have used a lot of words in trying to say what has not been put in
|
|
print before.
|
|
|
|
|
|
|
|
|
--------------'
|
|
|
|
|
|
|
.--------------'
|
|
| TURNING TOOLS
|
|
|
|
FIG. 21
|
|
|
|
The turning tools are shown in FIG. 21. Once again, I get onto my high
|
|
horse, and say that it is not necessary to have lots of different turning
|
|
tools in your kit. it is complete nonsense to have light, medium and heavy
|
|
tools. Further confusing the is the term used to rigidity of the different
|
|
types. This is termed the 'weight', but most of my students mistakenly
|
|
assume the actual weight is important to the turning potential. the best is
|
|
to choose a medium weight tension wrench and from then on call it a turning
|
|
tool. If I am not careful I will change the whole lock picking vocabulary.
|
|
|
|
The best and easiest wafer or pin-tumbler locks to open are the ones which
|
|
contain the smaller pin or wafer sizes together in the same lock, i.e. small
|
|
pins in each chamber and ideally all about the same length. When this state
|
|
exists, the method to open the lock is by RAKING.
|
|
|
|
|
|
Chapter 5: RAKING PIN-TUMBLER AND WAFER CYLINDER LOCKS
|
|
|
|
The first plan of attack on any lock of this type, whether it is a padlock
|
|
protected with this locking arrangement, a door on a car or a house, is to
|
|
try raking. the turning tool fits into the bottom section of the keyway, as
|
|
shown in FIG. 22, with just the weight of your finger. No visible bend
|
|
should be seen on the tool, otherwise it will be found impossible to pick
|
|
open the lock with this method.
|
|
|
|
|
|
________________________
|
|
/ \ the tools got to
|
|
/ \ be at 45 DEG.
|
|
/ ______ \ parallel like
|
|
\ / n \ / so: //
|
|
\ ********@____/ /
|
|
\ / / *** the pick
|
|
\ / / / turning tool
|
|
\____/_______________/
|
|
|
|
FIG. 22
|
|
|
|
Using the picks shown in FIG. 23, we rake the lock, as we shall explain
|
|
later, starting with pick number one and working up through until you open
|
|
the lock. Perhaps, before we get down to the actual method of raking, we had
|
|
better take a close look at the make-up of this tool, known as a RAKE. Look
|
|
again at FIG. 23. Notice that 1B is just the same as 1A except that it has
|
|
been cut in half, giving the half double ball. 1C is a silhouette of them
|
|
both.
|
|
|
|
If we look closely at 2A, 2B and 2C, we find they are arranged just the
|
|
same as the first group. 3A, 3B and 3C are know as DIAMONDS because of their
|
|
shape. There seems to be no reason for A, B and C in each of the groups 1, 2
|
|
and 3 other than, in the case of the diamonds, for use in smaller locks.
|
|
Don't let the different sizes bother you, but just use whatever you have in
|
|
your set.
|
|
|
|
RAKING TOOLS
|
|
|
|
FIG. 23
|
|
|
|
1A 1B 1C
|
|
|
|
|
- | /
|
|
| /| \
|
|
/ \ / \ / \
|
|
| | | | | |
|
|
| | | | | |
|
|
| | | | | |
|
|
| | | | | |
|
|
| | | | | |
|
|
|_| |_| |_|
|
|
|
|
Double Half Silhouette
|
|
Ball Double Double
|
|
Rake Ball Rake Ball Rake
|
|
|
|
2A 2B 2C
|
|
o
|
|
| o /
|
|
/\ \ |
|
|
/ \ / \ / \
|
|
| | | | | |
|
|
| | | | | |
|
|
| | | | | |
|
|
| | | | | |
|
|
| | | | | |
|
|
|__| |_| |_|
|
|
|
|
Full single Half Single Silhouette
|
|
Ball Rake Ball Rake Single Ball Rake
|
|
|
|
3A 3B 3C
|
|
< <| _ |>
|
|
| <| | /_| || Handy
|
|
| /| | || || Double
|
|
/| / | /| 4 || || Ended
|
|
| | | | | | || || Rake
|
|
| | | | | | || ||
|
|
| | | | | | || ||
|
|
| | | | | | / \ ||
|
|
| | | | | | | | \\
|
|
|_| |_| |_| /____\ //
|
|
|
|
3 Diamond Rakes
|
|
|
|
In FIG. 23 I have included a number 4, which is sometimes mistaken by
|
|
students for a raking tool, but which is, in fact, a broken key extractor,
|
|
and has nothing to do with raking. I have shown it's end in close up in the
|
|
illustration so that there can be no mistake. The number 5 is a double-ended
|
|
rake, which combines on one end a diamond and on the other a silhouette
|
|
double ball.
|
|
|
|
HOW RAKING WORKS
|
|
|
|
While we are taking a close look at things, it is a good time to do the
|
|
same thing with the action of raking, in order that you will fully
|
|
understand how it works. Select any of the number 1 raking tools (FIG. 23),
|
|
and insert it into the lock so that it touches the back of the lock and is
|
|
in contact with the back bottom pin of the lock. The pick is then drawn from
|
|
the back of the lock very quickly (see FIG. 24).
|
|
|
|
|
|
Rake is pulled out
|
|
causing top driver
|
|
and bottom pin to
|
|
===== ===== ===== ===== ===== vibrate about the
|
|
===== ===== ===== ===== ===== shear line.
|
|
.---.
|
|
.---. .---. .---. .---. | ^ |
|
|
| | | | | | | | | | |
|
|
Shearing | | | | | | | | | V | Shearing
|
|
Line ______ '---' '---' '---' '---' '---' _____ Line
|
|
.---. .---. .---. .---. .---.
|
|
Front of | | | | | | | | | ^ | Back
|
|
Lock '---' '---' '---' '---' '-v-'_ of the
|
|
/-\_________________________________________/ \
|
|
(______________________________________________/
|
|
Rake being pulled out
|
|
<---------------
|
|
|
|
This action has the effect of causing all the pins, which have been in
|
|
contact momentarily with the rake's passage out of the cylinder to vibrate,
|
|
each pin lifts the top driver out of the plug with this vibrating momentum
|
|
given> The whole thing is really a bit hit and miss, because some of the top
|
|
drivers will be out will others are still holding the plug. We must repeat
|
|
with the same rake about twenty times, and only if unsuccessful then move on
|
|
to another, following the pattern outlined in FIG. 23.
|
|
|
|
When we rake a lock, we are raising the pins inside the lock to the shear
|
|
line. moving through the different shaped picks varies the pattern of the
|
|
lift as the tool is repeatedly drawn out. The pins and drivers are bouncing
|
|
about the shear line, just waiting to please you and be at the right height
|
|
to open as you turn with your turning tool, which has been in place
|
|
throughout. I MUST STRESS THAT THE TURNING TOOL HAS NOT BEEN EXERTING A
|
|
CONSTANT TURNING PRESSURE, OTHERWISE THE PINS WOULD BIND, AS SHOWN IN FIG.
|
|
20. The pressure exerted is best described as a pulsating one. Gentle
|
|
pressure must only be on as the rake is leaving the lock on the way out. No
|
|
pressure is on as the pins are vibrating. The pins vibrate and the pulsating
|
|
turning tool turns the plug, so opening the lock. If too much pressure is
|
|
applied at the opening wrong moment, binding takes place and picking is
|
|
impossible.
|
|
|
|
Normally, I first test a lock by inserting my Turing tool into the lock,
|
|
turning it in both directions. Any slight movement tells me a few things
|
|
about the locks without actually seeing inside it. If has a lot of movement
|
|
in each direction, then it is going to be an easy lock to open. Its general
|
|
condition tells me if it is an old, worn or cheap lock. if you find little
|
|
movement an the lock is known to be a good one, then it is going to take a
|
|
little longer or require another technique.
|
|
|
|
|
|
Chapter 6: PICKING LOCKS WITHOUT A TURNING TOOL
|
|
|
|
A useful tip, for those long practice sessions or demonstrations, is to bend
|
|
the connecting cam downwards as shown in FIG. 25. If the lock is held as
|
|
shown in FIG. 26 you will find that it eliminates the use of the turning
|
|
tool. My advice to the beginner is to try raking with the index finger,
|
|
pulsating on the lock's cam.
|
|
|
|
|
|
_
|
|
( )----------.
|
|
| |__________|____
|
|
| | )_
|
|
| | )
|
|
| | )____
|
|
| | LOCK )---.|
|
|
| | _) ^||
|
|
| | ___) / ||
|
|
| | | / '' <-- Cam
|
|
(_)-----------' BEND
|
|
|
|
FIG. 25
|
|
|
|
_
|
|
/ \____ Finger provides
|
|
/ \ \_) <----- turning
|
|
/___/-\ \
|
|
/ / (__)
|
|
_||_
|
|
(____)
|
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
|
FIG. 26 '' Pick held in other hand
|
|
|
|
Another practice tip is to remove two sets of pins and drivers, leaving
|
|
three sets within the lock, thereby reducing the strength and making it a
|
|
little easier to manipulate.
|
|
|
|
Chapter 7: THE LOCK GUN
|
|
|
|
This useful tool is really a super raking device. pulling the trigger causes
|
|
the needle probes to flick upwards, and this has the effect of bouncing the
|
|
pins about the shearing line. this tool is capable of producing a continuous
|
|
vibration of the pins, making picking easy. It is a useful tool, and a nice
|
|
addition to your toolkit. The gun is shown in FIG. 27.
|
|
|
|
|
|
|
|
_______/\
|
|
<.|- \__
|
|
\ \_______
|
|
\ |_/
|
|
/ . _____| =[]
|
|
/ | \\ \
|
|
/ / \\ \__
|
|
/ . / (|
|
|
|_____/ .------
|
|
Lock Gun |
|
|
|
|
FIG. 27
|
|
|
|
|
|
Chapter 8: THE LOCK MASTER
|
|
|
|
Before we leave raking, perhaps we had better look at my own invention, the
|
|
LOCK MASTER, which has certain advantages over the lock gun, and even more
|
|
disadvantages. That said, its main advantage is a big one -- it completely
|
|
eliminates the need for a turning tool. Its bottom section has its own
|
|
turning tool built in. FIG. 28 shows the tool. the top is flicked with the
|
|
index finger nail, and the probe is returned to the horizontal by means of
|
|
two small springs. the finger snaps away while the master is twisted, again
|
|
in the pulsating fashion. The main disadvantage is that you have to have
|
|
different LOCK MASTERS for different size lock.
|
|
|
|
|
|
________________
|
|
/----------#-(.)-\-
|
|
___________#_(.)_
|
|
(______________ )____ Lock Master
|
|
/\__) \
|
|
| |
|
|
\________/
|
|
|
|
FIG. 28
|
|
|
|
|
|
Chapter 9: PURE PICKING
|
|
|
|
I like to think of my next section as 'pure picking', because that is
|
|
precisely what we do. Each pin is lifted in turn, lifting the driver clear
|
|
of the plug. Remember that earlier I advised the beginner to remove a couple
|
|
of set of pins and drivers. This is perhaps when you will find this most
|
|
useful. Turning is applied by the turning tool, or my own bent cam motion.
|
|
The HOOK PICKS shown in FIG. 29 are used.
|
|
|
|
|
|
Pure picking
|
|
-------------------
|
|
--. \ Top __ __ __
|
|
| | Chambers |==||==||==|
|
|
/ \ / \ '-------> |==||==||--|
|
|
| | | | ____|--||--|'--|___ <--- Shear Line
|
|
| | | | '--''--'.__.
|
|
| | | | .--..--.| |
|
|
| | | | '--''--''--'
|
|
| | | | ( )_______________
|
|
| | | | \_______________/
|
|
| | | | ___________________
|
|
| | | | Hook lifting Pin to
|
|
'-' '-' Shearing Line
|
|
|
|
Hook Picks
|
|
FIG. 30
|
|
|
|
FIG. 30
|
|
|
|
It requires a fair measure of practice, and even more patience, but the
|
|
rewards once you are a master of this technique are more than words can
|
|
convey. Using whatever method you choose to turn the plug, FIG. 30 shows the
|
|
pick lifting the pins one at a time until they are pushed out of the plug
|
|
into the top chambers. All the time, a very gentle turning motion has been
|
|
applied by means of the turning tool. FIG. 31 shows the lock set to open.
|
|
|
|
|
|
|
|
|
|
Set to open
|
|
___ ___ ___
|
|
| = || = || = |
|
|
|.-.||.-.||.-.| Notice how the
|
|
Shear line ___|'-'||'-'||'-'|___ bottom pins line
|
|
_ _ _ <--------- up precisely on
|
|
| | | | | | the shear line
|
|
'-' '-' '-'
|
|
|
|
FIG. 31
|
|
|
|
|
|
|
|
____________
|
|
U----(____________) Small
|
|
____________
|
|
\----(____________) Medium
|
|
____________
|
|
|____(____________) Large
|
|
|
|
Three sizes of Hook Picks
|
|
|
|
FIG. 32
|
|
|
|
Use the correct size of hook pick, by first trying the smallest. see FIG.
|
|
32. Practice this, and you will have a gem.
|
|
|
|
|
|
Chapter 10: OPENING LOCKS WITHOUT ACTUAL PICKING
|
|
|
|
FIG. 33 some points of attack which you will find convenient, and which have
|
|
been unknowingly built into the lock's construction by the manufacturer. The
|
|
method is known as shimming. FIG. 34 shows a collection of springs and
|
|
probes. go along to your local watchmaker and obtain as many as you can. Add
|
|
to this blades from junior hacksaws, coping and fretsaws and you will soon
|
|
have a fine collection.
|
|
|
|
FIG. 33
|
|
________ X
|
|
X / ______ \ /
|
|
\ / / \ \
|
|
\__/ /________\ \__
|
|
|\ |_|_------ | | |
|
|
| |_,-.----.#| | |
|
|
X----|--| ||_.--._||=| |
|
|
| '-' .-''-. |=| |
|
|
| | | |=| |
|
|
| | | |=| |
|
|
| '----' '=' |
|
|
|__________________|
|
|
|
|
Old Clock springs
|
|
_____________ ________________ _________________
|
|
|_____________| [________________]'-----------------' Small,Med,Large
|
|
|
|
Saw Blades
|
|
____________\_
|
|
______________) -----------------, __________________
|
|
\ VVVVVVVVVVVVVVVVV vvvvvvvvvvvvvvvvvv'
|
|
FIG. 34
|
|
|
|
Taking advantage of the lock's weak points, we insert our clock spring or
|
|
saw blade between the point where the two halves of the lock case meet, or
|
|
down the side of the shackle, following the line of the bow, and so pushing
|
|
back the spring-loaded bolt.
|
|
|
|
|
|
CHAPTER 11: RAPPING OPEN LOCKS
|
|
|
|
Look at my FIG. 35, which shows a pin-tumbler lock about to be opened by
|
|
rapping. the blow must be sharp but not heavy.
|
|
|
|
___ Sharp
|
|
| | Blow
|
|
FIG. 35 _| |_
|
|
\ / Pins
|
|
\ / __ line up
|
|
\ / | | on the
|
|
________V_____| | Shear Line
|
|
Blow causes | __ _ _ _ _ |
|
|
the pins and | |==||=|=|=|=| |
|
|
drivers to |-|V ||V|V|V|V|___| Shearing
|
|
vibrate -----| |^ ||^|^|^|^| |-------
|
|
| |V ||V|V|V|V| | Line
|
|
| |--||-|-|-|-| |
|
|
| '--''-'-'-'-' |
|
|
'______________ |
|
|
| |
|
|
|__|
|
|
|
|
How Rapping works
|
|
|
|
The blow should be only to the point shown. It has the effect of causing
|
|
the pins to vibrate and to split at the shearing line, as in raking and the
|
|
lock gun methods. Just as in the other methods, we use the turning tool
|
|
together with the pulsating movement. Try rapping open a spring-loaded bow
|
|
(shackle) padlock before you try a pin-tumbler or wafer lock. (See FIG. 36)
|
|
|
|
______
|
|
/,^--. \
|
|
__ __/ /
|
|
/ \___/ / /
|
|
/ ---. __ \
|
|
/ _/ ( \
|
|
/ C. / \
|
|
\ \\ (o) / <--- Sharp blow at this
|
|
\ \, | / point opens the lock
|
|
\___________/
|
|
|
|
Vibration causes lock to open like magic
|
|
|
|
|
|
TOOLS AND APPARATUS
|
|
FOR USE IN LOCK PICKING
|
|
|
|
1 Small vice, from watchmaker's suppliers, with 2" jaws.
|
|
2 A selection of small files, from watchmaker's suppliers.
|
|
3 A junior hacksaw from hardware stores.
|
|
4 A selection of saw blades, from hardware stores.
|
|
5 Leaf gauges, from a garage.
|
|
6 Piano wire, from music shop.
|
|
7 Lock picks, from locksmiths.
|
|
8 Old clock springs, from local watchmaker.
|
|
9 Wire cutters, from hardware stores.
|
|
10 Collection of blank keys, from locksmiths.
|
|
11 Lock gun from locksmiths.
|
|
12 Oil, from hardware stores.
|
|
13 Lots of old locks, from friends.
|
|
14 Pencil torch.
|
|
15 Strong magnifying glass.
|
|
16 Patience, and a bottomless coffee pot.
|
|
|
|
Get together as many locks of all types as possible. ask your friends if
|
|
they can find you any old locks for which they have lost the keys. After
|
|
experimenting with the locks, open them up to find out how they work. This
|
|
is the finest way to becoming a true lock expert.
|
|
|
|
If you are beaten by a particular lock, dont despair. I know the feeling
|
|
all to well. it's back to the drawing board, or, more correctly, the
|
|
workshop. Open it up, study it's workings, then re-assemble. always LOOK FOR
|
|
ITS WEAK POINTS. believe me, it will have some; you just have to look long
|
|
enough and hard enough. Locks are like a chain, as strong as the weakest
|
|
link.
|
|
|
|
|=[ 0x04 ]=--------------------------------------------------------------=|
|
|
|
|
Spyke's Beginner Guide 2
|
|
|
|
FFF III N N GGG EEE RRR BBB OOO AAA RRR DD III N N GGG
|
|
F I NN N G E R R B B O O A A R R D D I NN N G
|
|
FFF I N NN G EEE RRR BBB O O AAA RRR D D I N NN G
|
|
F I N N G G E RR B B O O A A RR D D I N N G G
|
|
F III N N GGG EEE R R BBB OOO A A R R DD III N N GGG
|
|
~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-
|
|
|
|
(Like anyone wants to know..
|
|
Just somin' to do in your
|
|
Spare time!)
|
|
|
|
~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-
|
|
|
|
Sections
|
|
--------
|
|
|
|
1. How to perform ollies
|
|
2. How to perform Backflips
|
|
3. How to perform shuv-its (in air)
|
|
4. How to perform Grinds
|
|
4.1 Boardslide
|
|
4.2 Darkslide
|
|
5. How to get a fingerboard
|
|
|
|
~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-
|
|
|
|
Section : 1. How to perform ollies
|
|
==================================
|
|
|
|
The ollie is possibly the first fingerboarding trick in
|
|
which you should learn. It allows you to pop your finger-
|
|
board into the air with your fingers allowing you to jump
|
|
Onto OR over (small) objects.
|
|
the first part of the ollie is to put you fingers in the
|
|
correct possition (as you can see in {Fig. A}) with one
|
|
finger flat on the tail and another right behind were the
|
|
trucks are on the top.
|
|
|
|
{Fig. A}
|
|
Key
|
|
-------
|
|
F=Finger \=Left Tail 0=Wheel
|
|
/=Right Tail ^=Trucks _=Part of deck
|
|
|
|
\____F__________F/
|
|
^0^ ^0^
|
|
|
|
Next you hit the tail (with the finger that is placed on
|
|
on the tail) lift hand and push forwards.
|
|
After practice you //should// be able to get the board
|
|
into the air a few inchs ({Fig. B}).
|
|
|
|
{Fig. B}
|
|
|
|
|
|
|
0\F
|
|
\
|
|
\
|
|
\
|
|
\
|
|
0\_F
|
|
|
|
|
|
~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-
|
|
|
|
Section : 2. How to perform Backflips
|
|
=====================================
|
|
|
|
The back flip on a finger board if diffurent to a backflip
|
|
on a skateboard in the way that your fingers do not flip
|
|
360 degrees verticly (That would break your wrist) but they
|
|
hover above the board while it flips.
|
|
Firstly put your fingers into the ollie postition (Shown
|
|
above in {Fig. A}), and hit the tail hard. Quickly lift
|
|
your fingers up into the air and the board //should// flip
|
|
in the air verticaly. Now for the hard bit : wait until
|
|
the board flips 360 degrees then drop your fingers so it
|
|
lands the correct way up,this movemnt has to be farely
|
|
fast to work.
|
|
|
|
|
|
~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-
|
|
|
|
Section : 3. How to perform shuv-its (in Air)
|
|
=============================================
|
|
|
|
The shuv-it (in Air) is were you ollie your board so
|
|
it spins 180 degrees horizontaly.
|
|
To do this trick you must place your fingers in the ollie
|
|
postition but with the tail-finger on the side on the board,
|
|
not the middle (Shown in {Fig. C}), next you ollie but when
|
|
you hit the tail you also turn you hand a little bit.
|
|
|
|
{Fig. C}
|
|
|
|
______________________F
|
|
/ . . . . \
|
|
| . .F . . |
|
|
\_______________________/
|
|
|
|
|
|
When the board is (hopefully) spinning in the air hit it
|
|
down after it has made a full 180 degree turn.
|
|
|
|
~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-
|
|
|
|
Section : 4. How to perform Grinds
|
|
==================================
|
|
|
|
To grind, ollie the board onto the edge of somthing OR
|
|
onto a pencil of bar.
|
|
|
|
Section : 4.1 Boardslide
|
|
------------------------
|
|
|
|
Ollie the board and turn it 90 degrees in the air
|
|
onto a thin object/edge of somthing then, push smoothly
|
|
across (Refer to {Fig. D}), to land push the board off
|
|
the object and turn 90 degrees back to the orginal
|
|
position.
|
|
|
|
{Fig. D}
|
|
|
|
|
|
_
|
|
/F\
|
|
|. .|
|
|
|. .|
|
|
| |
|
|
-------| |-------
|
|
-------| |--------Grinding Object
|
|
| F |
|
|
|. .|
|
|
|. .|
|
|
\_/
|
|
|
|
Section : 4.2 Darkslide
|
|
-----------------------
|
|
|
|
The darkslide is a grinding trick were you flip the board
|
|
upside down, grind it upside down, then flip it the
|
|
correct way up. It is technically an upside-down
|
|
Boardslide.
|
|
Firstly put your fingers into an ollie postition and move
|
|
the board towards the grinding objects, when you are close
|
|
annouf to ollie onto it, flip your board 180 degrees so
|
|
it is upside down, and push it onto the grinding object.
|
|
Push it forwards assuming pressure to the front, when you
|
|
get to the end of the grinding object attemp to flip the
|
|
board the correct way up.
|
|
|
|
|
|
Section : 5 How to get a fingerboard
|
|
====================================
|
|
|
|
Search in some local shops near you or buy them online from:
|
|
|
|
http://www.skateboard.com/techdeckshop/
|
|
|
|
|=[ EOF ]=---------------------------------------------------------------=|
|