AROS Vision
Modern and free Amiga-Compatible Experience on Amiga and PC
Article 14: AmigaOS System Architecture in Depth
Libraries, Devices, Resources and How Applications Access the Operating System
In the previous article, we explored how Exec manages memory, how Chip RAM and Fast RAM differ, and how applications request memory according to their hardware requirements.
Now we will look at another fundamental idea behind AmigaOS:
How does a program actually communicate with the operating system?
When an Amiga program wants to:
open a window
draw graphics
read a file
play sound
communicate through a serial port
access a disk
allocate memory
create tasks
receive keyboard or mouse input
it usually does not manipulate the hardware directly.
Instead, it uses services provided by the operating system.
These services are organized into several important categories:
libraries
devices
resources
handlers
Exec services
Understanding these components reveals one of the most elegant aspects of AmigaOS: its highly modular architecture.
1. AmigaOS Is Built from Components
A simplified view of the system looks like this:
Applications
|
v
+-------------------------+
| AmigaOS Services |
| |
| Libraries |
| Devices |
| Resources |
| Handlers |
+-------------------------+
|
v
+-------------------------+
| Exec |
+-------------------------+
|
v
+-------------------------+
| Hardware |
+-------------------------+
Instead of providing one enormous operating-system interface, AmigaOS divides functionality into specialized components.
For example:
graphics.library
intuition.library
dos.library
utility.library
provide different sets of functions.
Similarly:
trackdisk.device
serial.device
parallel.device
timer.device
provide access to different types of hardware or low-level services.
This modular architecture is one of the defining characteristics of AmigaOS.
2. Exec Is at the Center
At the foundation of AmigaOS is Exec.
Exec is the kernel and provides fundamental services such as:
multitasking
tasks
signals
message ports
memory management
interrupt handling
libraries
devices
resources
Many higher-level AmigaOS components ultimately depend on Exec.
A simplified hierarchy looks like this:
Applications
|
+----------+----------+
| | |
Intuition DOS Graphics
| | |
+----------+----------+
|
Exec
|
Hardware
Exec therefore acts as the foundation upon which much of the operating system is built.
3. What Is an Amiga Library?
A library is a collection of related operating-system functions.
For example:
graphics.library
provides graphics-related functionality.
intuition.library
provides user-interface services.
dos.library
provides many DOS and filesystem-related functions.
Instead of every application implementing these functions independently, applications can call the operating system libraries.
Conceptually:
Application
|
| call function
v
graphics.library
|
v
Amiga graphics system
This saves memory and gives programs a standardized interface to the operating system.
4. Libraries Are Shared
One particularly important characteristic of Amiga libraries is that they can be shared between programs.
Imagine three applications using graphics.library.
Conceptually:
Program A ----</span>
</span>
Program B ------> graphics.library
/
Program C ----/
They do not each need their own complete copy of the graphics system.
Instead, they use the common operating-system library.
This was particularly important on early Amigas where memory was extremely valuable.
A machine with 512 KB or 1 MB of RAM could not afford unnecessary duplication.
5. Opening a Library
Before using most libraries, a traditional Amiga program opens them.
One of the classic Exec functions for this purpose is:
OpenLibrary()
Conceptually:
LibraryBase = OpenLibrary("example.library", version);
For example:
GfxBase = OpenLibrary("graphics.library", 0);
T
he program requests access to the library and receives a pointer to its library base if the operation succeeds.
Conceptually:
Application
|
| OpenLibrary()
v
Exec
|
| find library
v
Requested library
|
v
Library base returned
The program can then call functions belonging to that library.
6. Library Versions
The version parameter is an important part of the Amiga library system.
Suppose a program requires functionality introduced in version 39 of a library.
It can request:
version 39 or newer
If the installed library is too old, the request fails.
This allows software to check whether the operating system provides the capabilities it requires.
Conceptually:
Program requires V39
|
v
Installed library
|
+----+----+
| |
V39+ <V39
| |
OK Fail
This simple mechanism became particularly useful as AmigaOS evolved.
7. Closing a Library
When an application no longer needs a library, it should close it.
The corresponding Exec function is:
CloseLibrary()
A typical lifecycle therefore looks like:
OpenLibrary()
|
v
Use library functions
|
v
CloseLibrary()
This does not necessarily mean that the library immediately disappears from memory.
Other programs may still be using it.
8. Reference Counting
Libraries maintain an open count.
Conceptually:
Program A opens library
Open count = 1
Program B opens library
Open count = 2
Program C opens library
Open count = 3
If Program A closes it:
Open count = 2
The library is still being used.
Only when it is no longer required can the system potentially remove an eligible library from memory.
This is another example of AmigaOS managing scarce resources efficiently.
9. Resident Libraries
Some libraries are already present when the system starts.
Others can be loaded when required.
This is related to the Amiga concept of resident modules.
A resident module contains information that allows Exec to recognize and initialize a system component.
This mechanism is used for several types of operating-system components.
It contributes to the modular structure of AmigaOS because the operating system can discover and initialize components rather than having everything implemented as one monolithic program.
10. How Library Calls Work
Amiga libraries use a mechanism based around a library base and function vectors.
Conceptually:
Library Base
|
+--> Function A
|
+--> Function B
|
+--> Function C
|
+--> Function D
Applications call library functions through this well-defined interface.
On classic 68k AmigaOS systems, these function entries are traditionally associated with negative offsets from the library base.
You may therefore encounter the term:
Library Vector Offset, or LVO.
This mechanism makes libraries more than ordinary files containing functions. They are integrated runtime components of the operating system.
11. Examples of Important Libraries
Some of the most important classic AmigaOS libraries include:
exec.library
Provides fundamental operating-system functions involving:
memory
tasks
signals
message ports
libraries
devices
Exec is special because it forms the core of the operating system.
graphics.library
Provides low-level graphics services such as:
drawing
bitmaps
display structures
fonts and text support
graphical operations
intuition.library
Provides the primary GUI framework:
screens
windows
gadgets
menus
user interface events
dos.library
Provides AmigaDOS-related functionality, including:
files
directories
processes
command execution
filesystem interaction
utility.library
Provides assorted utility functionality useful to applications and other system components.
Together these libraries form a substantial part of the programming interface of AmigaOS.
12. What Is a Device?
A device is another important AmigaOS component.
Libraries usually provide callable functions.
Devices are designed around an asynchronous I/O request model.
A simplified relationship looks like:
Application
|
| I/O request
v
Device
|
v
Hardware or system service
Typical devices include:
trackdisk.device
serial.device
parallel.device
timer.device
console.device
input.device
A device does not necessarily correspond directly to one physical device.
For example, timer.device provides timing services rather than representing a physical peripheral in the conventional sense.
13. Opening a Device
Exec provides a function called:
OpenDevice()
An application creates an appropriate I/O request and opens the desired device.
Conceptually:
Application
|
| OpenDevice()
v
Exec
|
v
Device
After the device has been opened, the program sends I/O commands to it.
14. I/O Requests
Communication with devices commonly uses I/O request structures.
These contain information such as:
the requested command
buffer address
amount of data
result information
message information
Conceptually:
I/O Request
+---------------------+
| Command |
| Data pointer |
| Length |
| Error/result |
| Message information |
+---------------------+
The application prepares the request and sends it to the device.
15. Synchronous and Asynchronous I/O
One of the most interesting aspects of the Amiga device system is its support for asynchronous operations.
A program can perform a synchronous request:
Send request
|
v
Wait
|
v
Operation finishes
|
v
Continue
But it can also initiate an operation and continue doing other work.
Send request
|
+--------------------+
| |
v v
Device works Application continues
| |
+---------+----------+
|
completion
This fits extremely well with the multitasking and message-based design of Exec.
16. DoIO() and SendIO()
Two classic Exec functions illustrate the difference.
DoIO()
Conceptually:
DoIO(request);
The application waits until the operation has completed.
SendIO()
Conceptually:
SendIO(request);
The request can proceed asynchronously.
The application can perform other work and later determine whether the request has finished.
This can be particularly useful for operations that take significant time.
17. Devices and Message Ports
Here we encounter something from our earlier discussion of Exec multitasking.
Message ports are an essential communication mechanism within AmigaOS.
Asynchronous I/O can use a reply port.
Conceptually:
Application
|
| SendIO()
v
Device
|
| performs operation
|
v
Reply message
|
v
Message Port
|
v
Application
This shows how several AmigaOS concepts fit together.
Devices are not isolated mechanisms.
They integrate with:
tasks
signals
messages
message ports
This modular integration is typical of AmigaOS.
18. Example: Reading from a Disk
Suppose a program needs information from a floppy disk.
At a simplified low level, the chain could involve:
Application
|
v
Filesystem/DOS
|
v
trackdisk.device
|
v
Floppy disk hardware
Normally an application reading an ordinary file does not talk directly to trackdisk.device.
It uses DOS filesystem functions.
The filesystem layer handles the necessary lower-level disk interaction.
This distinction is important.
19. Devices Are Not DOS Devices
Amiga terminology can initially be confusing because the word device is used in different contexts.
For example:
trackdisk.device
is an Exec device driver.
But:
DF0:
DH0:
RAM:
SER:
are names used in the AmigaDOS environment.
These concepts are related but they are not identical.
This is an important distinction for understanding AmigaOS internals.
20. What Is a Handler?
AmigaDOS introduces another important component:
handlers.
A handler provides functionality behind certain DOS device names or filesystems.
Conceptually:
Application
|
v
dos.library
|
v
DOS Handler
|
v
Device / filesystem / service
For example, a filesystem handler can provide the filesystem logic used for a disk volume.
DOS communicates with handlers largely through message passing.
Again we see a familiar AmigaOS concept:
Components communicate using messages rather than being tightly combined into one enormous system.
21. Why Handlers Are Powerful
Handlers make the AmigaDOS namespace very flexible.
A DOS-visible entity does not necessarily need to represent an ordinary physical disk.
This allows systems such as:
RAM:
NIL:
CON:
PIPE:
to fit naturally into the DOS environment.
From the application's perspective, many of these services can be accessed through familiar DOS operations.
This provides a powerful abstraction layer.
22. What Is a Resource?
Exec also supports another component type called a resource.
Resources are used for certain low-level system facilities.
Examples on classic systems include:
cia.resource
disk.resource
misc.resource
potgo.resource
Resources differ from normal libraries.
They are generally used for managing shared hardware or low-level system facilities.
23. Opening a Resource
Exec provides:
OpenResource()
A resource can then provide access to a particular system facility.
Unlike normal libraries, resources follow somewhat different management rules.
They are generally intended to remain resident and provide coordination around system hardware or low-level functionality.
Conceptually:
Application/System component
|
v
OpenResource()
|
v
Resource
|
v
Shared hardware
24. Why Resources Are Necessary
Some pieces of hardware cannot simply be controlled independently by multiple programs.
Imagine two programs manipulating the same hardware registers without coordination.
The result could be unpredictable.
A resource can help coordinate access to shared hardware facilities.
The principle is:
Program A ----</span>
</span>
Program B ------> Resource ---> Hardware
/
Program C ----/
Instead of:
Program A ----</span>
Program B ------> Hardware
Program C ----/
The resource acts as a controlled interface.
25. Libraries, Devices and Resources Compared
The three mechanisms can now be compared.
ComponentMain purposeTypical interactionLibraryFunctions and system servicesFunction callsDeviceI/O operationsI/O requestsResourceShared low-level facilitiesResource-specific callsHandlerDOS-visible serviceDOS packets/messages
The boundaries are not simply about hardware versus software.
Instead, each mechanism has a different architectural purpose.
26. Where Are These Components Stored?
On an AmigaOS system you will often encounter directories such as:
LIBS:
DEVS:
L:
These names correspond to assignments in the AmigaDOS filesystem.
Typically:
LIBS:
contains disk-loadable libraries.
DEVS:
contains devices and related system components.
L:
contains handlers and filesystem-related modules.
But an important detail must be remembered:
Not every operating-system component needs to be loaded from a file on disk.
Some components may already reside in ROM or may have been made resident in memory.
The filesystem directories are therefore only part of the complete picture.
27. Why Kickstart Matters
The Amiga's Kickstart ROM contains important parts of the operating system.
When the machine boots, it already has fundamental operating-system components available.
This means the architecture is effectively assembled from:
ROM components
+
disk-loaded components
+
resident components
+
configuration
This is why two Amigas running similar Workbench environments can still have significantly different underlying configurations.
28. A Typical Application's View
Suppose an application wants to create a window and display some graphical content.
At a simplified level:
Application
|
+--> exec.library
| memory, tasks, messages
|
+--> intuition.library
| window and GUI management
|
+--> graphics.library
drawing and display operations
If the program also saves a file:
Application
|
+--> dos.library
|
v
Handler
|
v
Filesystem/device
If it uses serial communication:
Application
|
+--> serial.device
One application may therefore use several different operating-system mechanisms simultaneously.
29. Why the Architecture Is So Modular
This architecture provides several advantages.
Reusability
Applications share common operating-system functionality.
Memory efficiency
System routines do not need to be duplicated inside every program.
Hardware abstraction
Applications can access many services without manipulating hardware registers directly.
Extensibility
New components can be added to the system.
Multitasking
Asynchronous devices and message-based communication work naturally with Exec multitasking.
Compatibility
Versioned interfaces allow programs to check whether required functionality is available.
These properties contributed greatly to the flexibility of AmigaOS.
30. A More Complete Picture of AmigaOS
We can now expand our earlier system model:
Applications
|
+--------------+--------------+
| | |
Libraries Devices DOS
| | |
| | Handlers
| | |
+--------------+--------------+
|
Exec
/ | </span>
/ | </span>
Resources Memory Messages
| /
| /
Hardware
This diagram is simplified, but it reveals the overall philosophy.
AmigaOS is not simply a collection of programs sitting on top of hardware.
It is a network of cooperating components.
31. The Importance of Message
Passing
One theme appears repeatedly throughout AmigaOS:
messages.
We have encountered message passing in:
inter-process communication
message ports
device I/O
DOS handlers
asynchronous operations
This is not accidental.
The Amiga was designed from the beginning as a multitasking computer.
Message-based communication allows independent tasks and system components to cooperate without requiring everything to execute as one tightly coupled program.
32. From Hardware to Application
Consider what happens when an application performs a seemingly simple operation.
The user opens a file.
At a highly simplified level:
Application
|
v
dos.library
|
v
Filesystem/Handler
|
v
Device system
|
v
Hardware
When the program opens a graphical window:
Application
|
v
intuition.library
|
v
graphics.library
|
v
Display system
|
v
Graphics hardware
The programmer is therefore working with layers of abstraction.
Each layer hides some of the complexity below it.
33. Why This Matters to the User
Even if you never program an Amiga, understanding these concepts explains many things you encounter while using the system.
For example, why do directories named:
LIBS:
DEVS:
L:
exist?
Why does software sometimes report:
Could not open xyz.library
or:
Requires version 39 of xyz.library
Why can installing a new library change the capabilities of software?
Why can a filesystem be installed as a separate component?
Why can devices and handlers be added without changing the entire operating system?
All of these behaviors are consequences of the modular architecture we have explored.
34. AmigaOS as a Collection of Cooperative Components
Perhaps the most useful mental model is not:
Application
|
Operating System
|
Hardware
but rather:
Application
|
+------------+------------+
| | |
Library Device DOS
| | |
| Messages Handler
| | |
+------------+------------+
|
Exec
|
+----------+----------+
| | |
Memory Resources
Hardware
The exact relationships are more complicated, but this model captures the philosophy.
AmigaOS is made of small, specialized components that cooperate with each other.
Conclusion
The architecture of AmigaOS is remarkably modular.
At its foundation sits Exec, providing memory management, multitasking, signals, messages and the infrastructure required by many other operating-system components.
On top of that foundation, AmigaOS provides several different mechanisms.
Libraries provide callable system functionality.
OpenLibrary()
CloseLibrary()
Devices provide structured and potentially asynchronous I/O.
OpenDevice()
DoIO()
SendIO()
Resources provide controlled access to certain low-level facilities.
OpenResource()
Handlers extend the DOS environment and make services available through the AmigaDOS namespace.
These mechanisms are tied together by concepts we have already encountered throughout this series:
multitasking
messages
message ports
shared resources
modular components
hardware abstraction
This is one of the reasons AmigaOS remains so interesting from a technical perspective.
Despite running comfortably on computers with extremely small amounts of memory by modern standards, it provided a sophisticated multitasking environment built from reusable and cooperating system components.
And perhaps most importantly, the architecture makes an Amiga easier to understand once its individual parts are revealed.
What initially appears to be one operating system gradually becomes a collection of clearly defined pieces:
Exec, libraries, devices, resources, handlers, filesystems and applications, all working together.