Subversion Repositories HelenOS-doc

Compare Revisions

Ignore whitespace Rev 132 → Rev 133

/design/trunk/src/ch_ds.xml
2,7 → 2,7
<chapter id="ds">
<?dbhtml filename="ds.html"?>
 
<title>Data structures</title>
<title>Data Structures</title>
 
<para>There is lots of data that either flows through various HelenOS
subsystems or is stored directly by them. Each subsystem uses its own data
/design/trunk/src/ch_hardware.xml
72,7 → 72,7
 
<para>It might be desirable for a device driver to temporarily disable
preemption. Tasks that can do this are required to have the
CAP_PREEMPT_CONTROL capability. Preemption could be theoretically disabled
<constant>CAP_PREEMPT_CONTROL</constant> capability. Preemption could be theoretically disabled
by disabling interrupts on the current processor, but disabling preemption
is more lightweight as interrupt processing remains enabled.</para>
</section>
/design/trunk/src/ap_arch.xml
2,14 → 2,14
<appendix id="archspecs">
<?dbhtml filename="arch.html"?>
 
<title>Architecture specific notes</title>
<title>Architecture Specific Notes</title>
 
<section>
<title>AMD64/Intel EM64T</title>
 
<para>The AMD64 architecture is a 64-bit extension of the older IA-32
<para>The amd64 architecture is a 64-bit extension of the older ia32
architecture. Only 64-bit applications are supported. Creating this port
was relatively easy, because it shares a lot of common code with IA-32
was relatively easy, because it shares a lot of common code with ia32
platform. However, the 64-bit extension has some specifics, which made the
porting interesting.</para>
 
16,7 → 16,7
<section>
<title>Virtual Memory</title>
 
<para>The AMD64 architecture uses standard processor defined 4-level
<para>The amd64 architecture uses standard processor defined 4-level
page mapping of 4KB pages. The NX(no-execute) flag on individual pages
is fully supported.</para>
</section>
24,7 → 24,7
<section>
<title>TLB-only Paging</title>
 
<para>All memory on the AMD64 architecture is memory mapped, if the
<para>All memory on the amd64 architecture is memory mapped, if the
kernel needs to access physical memory, a mapping must be created.
During boot process the boot loader creates mapping for the first 20MB
of physical memory. To correctly initialize the page mapping system, an
46,7 → 46,7
<section>
<title>Mapping of Physical Memory</title>
 
<para>The AMD64 ABI document describes several modes of program layout.
<para>The amd64 ABI document describes several modes of program layout.
The operating system kernel should be compiled in a
<emphasis>kernel</emphasis> mode - the kernel is located in the negative
2 gigabytes (0xffffffff80000000-0xfffffffffffffffff) and can access data
71,13 → 71,13
<title>Fast SYSCALL/SYSRET Support</title>
 
<para>The entry point for system calls was traditionally a speed problem
on IA32 architecture. AMD64 supports a SYSCALL/SYSRET instructions. Upon
encountering SYSCALL instruction, the processor changes privilege mode
and transfers control to an address stored in machine specific register.
Unlike other similar instructions it does not change stack to a known
kernel stack, which must be done by the syscall entry routine. A hidden
part of a GS register is provided to support the entry routine with data
needed for switching to kernel stack.</para>
on the ia32 architecture. The amd64 supports SYSCALL/SYSRET
instructions. Upon encountering the SYSCALL instruction, the processor
changes privilege mode and transfers control to an address stored in
machine specific register. Unlike other similar instructions it does not
change stack to a known kernel stack, which must be done by the syscall
entry routine. A hidden part of a GS register is provided to support the
entry routine with data needed for switching to kernel stack.</para>
</section>
 
<section>
93,30 → 93,31
</section>
 
<section>
<title>Intel IA32</title>
<title>Intel IA-32</title>
 
<para>The IA32 architecture uses 4K pages and processor supported 2-level
page tables. Along with AMD64 It is one of the 2 architectures that fully
supports SMP configurations. IA32 is mostly similar to AMD64, it even
shares a lot of code. The debugging support is the same as with AMD64. The
thread local storage uses GS register.</para>
<para>The ia32 architecture uses 4K pages and processor supported 2-level
page tables. Along with amd64 It is one of the 2 architectures that fully
supports SMP configurations. The architecture is mostly similar to amd64,
it even shares a lot of code. The debugging support is the same as with
amd64. The thread local storage uses GS register.</para>
</section>
 
<section>
<title>MIPS32</title>
<title>32-bit MIPS</title>
 
<para>Both little and big endian kernels are supported. In order to test
different page size it was set to 16K. The MIPS architecture is TLB-only,
the kernel simulates 2-level page tables. On processors that support it,
lazy FPU context switching is implemented.</para>
different page sizes, the mips32 page size was set to 16K. The mips32
architecture is TLB-only, the kernel simulates 2-level page tables. On
processors that support it, lazy FPU context switching is
implemented.</para>
 
<section>
<title>Thread Local Storage</title>
 
<para>The thread local storage support in compilers is a relatively
recent phenomena. The standardization of such support for MIPS platform
is very new and even the newest versions of GCC cannot generate 100%
correct code. Because of some weird MIPS processor variants, it was
recent phenomena. The standardization of such support for the mips32
platform is very new and even the newest versions of GCC cannot generate
100% correct code. Because of some weird MIPS processor variants, it was
decided, that the TLS pointer will be gathered not from some of the free
registers, but a special instruction was devised and the kernel is
supposed to emulate it. HelenOS expects that the TLS pointer is in the
/design/trunk/src/ch_scheduling.xml
79,27 → 79,27
of synchronous context switches, because it is a natural vehicle not
only for changes in control flow, but also for switching between two
kernel stacks. Two functions figure in a synchronous context switch
implementation: <code>context_save</code> and
<code>context_restore</code>. Note that these two functions break the
implementation: <code>context_save()</code> and
<code>context_restore()</code>. Note that these two functions break the
natural perception of the linear C code execution flow starting at
function's entry point and ending on one of the function's exit
points.</para>
 
<para>When the <code>context_save</code> function is called, the
<para>When the <code>context_save()</code> function is called, the
synchronous context is saved in a memory structure passed to it. After
executing <code>context_save</code>, the caller is returned 1 as a
executing <code>context_save()</code>, the caller is returned 1 as a
return value. The execution of instructions continues as normally until
<code>context_restore</code> is called. For the caller, it seems like
<code>context_restore()</code> is called. For the caller, it seems like
the call never returns<footnote>
<para>Which might be a source of problems with variable liveliness
after <code>context_restore</code>.</para>
after <code>context_restore()</code>.</para>
</footnote>. Nevertheless, a synchronous register context, which is
saved in a memory structure passed to <code>context_restore,</code> is
saved in a memory structure passed to <code>context_restore()</code>, is
restored, thus transfering the control flow to the place of occurrence
of the corresponding call to <code>context_save</code>. From the
of the corresponding call to <code>context_save()</code>. From the
perspective of the caller of the corresponding
<code>context_save</code>, it looks as though a return from
<code>context_save</code>. However, this time a return value of 0 is
<code>context_save()</code>, it looks like a return from
<code>context_save()</code>. However, this time a return value of 0 is
returned.</para>
</section>
</section>
136,7 → 136,7
<constant>Sleeping</constant> state by going to sleep or enters the
<constant>Exiting</constant> state when it reaches termination. When the
thread exits, its kernel structure usually stays in memory, until the
thread is detached by another thread using <code>thread_detach</code>
thread is detached by another thread using <code>thread_detach()</code>
function. Terminated but undetached threads are in the
<constant>Undead</constant> state. When the thread is detached or
detaches itself during its life, it is destroyed in the
207,7 → 207,7
<title>Scheduler Operation</title>
 
<para>The scheduler is invoked either explicitly when a thread calls the
<code>scheduler</code> function (e.g. goes to sleep or merely wants to
<code>scheduler()</code> function (e.g. goes to sleep or merely wants to
relinquish the processor for a while) or implicitly on a periodic basis
when the generic clock interrupt preempts the current thread. After its
invocation, the scheduler saves the synchronous register context of the
225,9 → 225,9
queues from lower towards higher indices and looks for a thread. If the
visited run queue is empty, it simply searches the next run queue. If it
is known in advance that there are no ready threads waiting for
execution, <code>find_best_thread</code> interruptibly halts the
execution, <code>find_best_thread()</code> interruptibly halts the
processor or busy waits until some threads arrive. This process repeats
until <code>find_best_thread</code> succeeds.</para>
until <code>find_best_thread()</code> succeeds.</para>
 
<para>After the best thread is chosen, the scheduler switches to the
thread's task and memory management context. Finally, the saved