Precompiled RMIOS libraries, header files and required scripts are provided
as part of the release.
RMIOS的库,头文件和所要求的脚本都被发布出来。
Unless one is enhancing the functionality of RMIOS,
there is no need for compiling RMIOS source code.
除非要提升RMIOS的功能,没有必要编译RMIOS的源代码。
Module Names:
(a) RMIOS kernel and modules : rmios_lib, rmios_modules
(b) RMIOS reference applications: rmios_apps
(c) Precompiled libs, headers &
scripts : Consult your local installation directory
RMIOS的模块名字:
a : RMIOS的内核和模块
b : RMIOS的参考应用程序
c : 预编译的库,头文件和脚本
------------------------------------------------------------------------
Structure and Utility of Precompiled libraries, header files and scripts
预编译的库,头文件和脚本的结构和功能
--------------------------------------------
Installation directory ($RMIOS_LIB)
|
|-> lib
| |
| |-> librmios.a
|
|-> include
| |-> *.h
|
|-> scripts
|
|-> Makefile.mk
|-> ld.phoenix.S
|-> msgring
|-> pagesize
librmios.a: makes up the bulk of RMIOS services such as drivers,
interrupt support, filesystem and other services.
include:
headers files containing data structures and functions exposed by RMIOS
scripts: 包含有数据结构和函数的头文件
Makefile.mk : Contains the definitions of commonly used variables 定义了通用的变量
ld.phoenix.S : default linker script that controls the layout of RMIOS
executable 控制RMIOS可执行布局的默认链接脚本
msgring : parser for message ring configuration files 消息环的配置文件的剖析器
pagesize : executable that determines the best alignment boundaries
of data segment of rmios applications 执行 决定RMIOS应用程序数据段的最好线程界限
NOTE: The above scripts define and gather variables, make targets and
scripts that are normally common to all applications. One can
always override the use of above scripts, by setting the
appropriate variables. Please refer next section
’ HOWTO: Compile, Link RMIOS Applications’ for details.
NOTE: To be able to link RMIOS applications with the above, it is important
to set environment variable’RMIOS_MODULES’ to the installation directory
为安装目录设置环境变量’RMIOS_MODULES’是非常有必要的。
----------------------------------------
HOWTO: Compile, Link RMIOS Applications
如何编译 链接RMIOS的应用程序
----------------------------------------
(a) Set the environment variable RMIOS_LIB to the directory containing the
above precompiled libraries, header files and scripts
设置RMIOS_LIB 到包含有libraries, header files and scripts的目录下
(b) Set the environment variable RMIOS_MODULES to the directory containing
the precompiled-libraries of Pth, PAPI and Ext2fs.
设置环境变量RMIOS_MODULES到包含有Pth, PAPI and Ext2fs的目录。
(c) To link in the required modules, the names of the modules must be
specified either in the Makefile of the application or on the command
line as:
想要被应用程序链接的模块,要写到makefile中或者命令行中。比如:
modules="module_one module_two ... module_n" make ...
For example, if papi and Pth needs to be linked in with the application,
the make must be run as
如果 papi and Pth 要被应用程序链接,要这么运行:
modules="pth perfctr papi" make
(d) To compile and create RMIOS applications, the Makefile should include
$(RMIOS_LIB)/scripts/Makefile.mk and define (at least) the following
variable and target
为了编译和创建RMIOS的应用程序,Makefile应该包含$(RMIOS_LIB)/scripts/Makefile.mk 并且定义至少如下的变量和目标:
OBJS - object files of source files to be included in the executable
The benefit of defining this variable is that ’make’ recognizes
this variables and triggers default rules for generating objects
if and only if no explicit rule is specified for generating object
files.
For applications that need to initialize message ring, it is
mandatory to specify the object file ’msgring.o’. Hence,
应用程序要想初始化消息环,制定目标文件msgring.o是很必须的。
OBJS = msgring.o <other object files>
<target name>: msgring $(LINKER_SCRIPT) $(OBJS)
<tab>$(LD) $(LINKFLAGS) /
$(LIBRARIES_START) /
$(OBJS) /
<additional libraries to be linked in> /
$(LIBRARIES_END) /
-o <executable>
(e) Although default variables are defined in $(RMIOS_LIB)/scripts/Makefile.mk
for commonly used variables, one might need to override them frequently.
Following are those variables, the values they can assume and the default
values.
NOTE: Should any variable need to be overridden, it must be defined before
$(RMIOS_LIB)/scripts/Makefile.mk is included.
mode -
values : {kuseg, kseg0}
default : kuseg
notes : This defines the memory segment the application is meant for.
Please consult other documents for differences and relative
benefits and limitations of the two memory segments
HEAPSIZE -
values : multiple of 2MB
default : 8MB
notes : size of the heap segment for each instance of an application
INCLUDES -
values : paths of header files to be included
default : newlib headers and those bundled under RMIOS
notes :
LINKFLAGS -
values : paths of additional libraries to be linked in and other
linker flags
default : newlib and precompiled RMIOS libraries
notes :
CFLAGS -
values : additional flags to be passed to preprocessor or compiler
default : 03 optimization flags and others
notes :
MSGRING_CFG -
values : file name containing message ring configuration
default : msgring.cfg
notes : though the variable has a default name, the default file
itself is not present and has to be present in the
application directory.
LINKER_SCRIPT_IN
values : name of the linker script
default : $(RMIOS_LIB)/scripts/ld.phoenix.S
notes : The default linker script must be used as it has been
crafted to suit the loader. Notes on the capabilities
and requirements of the loader will be released later
so that any linker script confirming to those specs can
be used in place of the default one
----------------------------------------
HOWTO: Run RMIOS Applications
如何去运行
----------------------------------------
To run RMI OS compiled in "kuseg" segment on multiple cpus, use
the "userapp_os -m 0xfffffff0" command from the bootloader. The bootloader
elfloads this binary, sets up TLBs for the address translations and kicks of
RMI OS on 28 virtual CPUS. CPU 0 does not run RMI OS and is available to run
the ’shell’, that provides interface for launching RMIOS applications. Linux
or any other OS can then be run on CPU 0. See the following item for details.
在多cpu上运行编译 kuseg 段的RMIOS,使用bootloader的"userapp_os -m 0xfffffff0"命令。
bootloader elf的加载二进制文件,为地址转换设置TLBs,让RMIOS在28个虚拟cpu上活动起来。
cpu0 是不运行rmios的,可以运行shell,shell是用来加载rmios应用程序的接口。
linux或者其他的os可以运行的在cpu 0上。
A new mode called "buddy mode" is
supported where a single image can be shared with multiple threads in kuseg
mode. 这段话什么意思。
Buddy Mode:
RMI_OS now supports passing cpu_masks for applications launched on RMI_OS.
Bootloader and RMI_OS have changes to support passing cpu_masks with
’userapp_os’ command. RMI_OS now uses 32MB of private memory per instance
in KUSEG mode. We have also added an ’override’ option to ’userapp_os’
command to be able to run threads in cpu0. If thread 0 of cpu 0 is
specified with the override option, the bootloader shell is no longer
available after that command.
RMIOS 现在支持为加载在RMIOS上的应用程序传递cpu_masks 。bootloader和rmios已经可以在
KUSEG模式下,使用命令 userapp_os 支持传递cpu_masks了。
RMIOS现在对KUSEG模式下的每个线程都使用32MB的私有内存。
可以添加一个 override的选项到userapp_os命令中,这样cpu0 就可以运行线程了。
如果cpu0 的线程0 被override选项所确定,那么bootloader shell就不能再运行了。
Note that, 2 variables in RMI_OS, namely ’master_cpu’ and ’buddy_cpu_mask’
are set during initialization and are available in the ’main’ function.
They reflect the arguments used to the userapp* commands.
userapp_os -m 0x10 -b 0xfffffff0
master cpu = 4, buddies = 0xfffffff0
userapp_os -m 0x30 -b 0xfffffff0
Invalid, cannot specify multiple cpus with a buddy mask
userapp_os -m 0xffffffff
invalid, cannot specify cpu_0 with out the override option
userapp_os -m 0xffffffff -o
32 instances of RMI OS application are run
master cpu = 0, buddies = 0x0
master cpu = 1, buddies = 0x2
master cpu = 2, buddies = 0x4
...
master cpu = 31, buddies = 0x80000000
userapp_os -m 0xfffffff0
28 instances of psb_app is run
master cpu = 4, buddies = 0x10
master cpu = 5, buddies = 0x20
master cpu = 6, buddies = 0x40
...
master cpu = 31, buddies = 0x80000000
userapp
runs the last elfload’ed exe
master cpu = 0, buddies = 0xffffffff
----------------------
Command Line Arguments
----------------------
Applications running in Linux environment have access to command line
arguments in the variables ’argc’, ’argv’, and ’envp’. A similar interface
is provided to RMIOS applications through the variables ’g_argc’, ’g_argv’
and ’g_envp’. For instance, if an RMIOS application is launched in KUSEG
segment as:
userapp_os -m 0x10 -b 0xff "arg 1" "arg 2"
rmios applications will find
g_argc = 7
g_argv[0] = "userapp_os"
g_argv[1] = "-m"
g_argv[2] = "0x10"
...
g_argv[6] = "arg 2"
and
g_envp[0] = "BOARD=ARIZONA"
Note: To access above variables, applications must include "psb.h" header file
in which the variables are declared as extern.
-------------------------------------
FEP: Frequently Encountered Problems
-------------------------------------
Under Drafting
1.5.1 Shared Memory Segment
All instances of an application running in KSEG0 memory segment share
all the segments (code, data, stack and heap). However, in KUSEG memory
segment, different instances do not share data, stack and heap segment,
but share the code segment. If KUSEG applications require shared memory,
then shared data must go into the section
".rmios.shmem"
运行在KSEG0内存段的应用程序共享所有的段(代码、数据、栈和堆)。然而,KUSEG内存段,不同的应用程序并不共享数据、栈和堆。
但是共享代码段。如果KUSEG应用程序要求共享内存,那么共享的数据要放到 “.rmios.shmem”中。
This is done by suffixing shared data structures with the macros
"__shared_memory__".
宏“__shared_memory__”作为后缀,可以实现KUSEG应用程序共享内存。
Initialized shared data are initialized with corresponding values,
while uninitialized shared data are set to zero by the loader.
可以用相应的值来初始化共享数据。而loader设置为0,就uninitialized shared data。
#include "cdefs.h"
int shared_data_initialized __shared_memory__ = 5;
int shared_data_uninitialized __shared_memory__;
Upon entry, the application would find the above two variables to
be set to 5 and 0 respectively.
Errata for Releases Prior to 1.3
-------------------------------
In prior releases, two different macros ’__shared_memory__’ and
’__shared_memory_bss__’ and was indicated that the later macro
must be used for uninitialized data and would lead to smaller
executables.
However, it was an error and it has been realized that for user-defined
sections, space is allocated in the elf executable even if the data is
uninitialized. Hence, the two sections corresponding to the above two
macros are collapsed into into one section that contains both shared
initialized and shared uninitialized data. The size of the section equals
the size of shared data.
SUGGESTIONS
-----------
Uninitialized shared data too is allocated space in the executables
leading to bloated binaries. Hence, if there is sizable uninitialized
shared data, it is recommended that memory for such data be allocated
dynamically from the shared heap.
Please consult the subsection ’Memory Allocation’ under RMIOS API Guide
for details on dynamic allocation of shared memory.
1.6 Interrupts 中断
------------------------------------------------------------------------------
Timer Support 定时器支持
------------------------------------------------------------------------------
RMIOS supports basic timer-interrupt support. In the current implementation,
cpu 0 can be programmed to receive interrupts from the PIC, while other CPUs
program the registers ’COUNT’ and ’COMPARE’ to generate interrupts.
支持基本的定时器中断。
cpu0 可以被编程接收来自PIC的中断。其他的cpu编程寄存器’COUNT’和’COMPARE’以产生中断。
Usage:
The above mechanism is already provided as part of RMIOS services. The user
only need to invoke the following routines in the specified order, for timer
interrupts to kick in. The timer interrupt-handler increments the counter
’current_timer_tick’. It starts with an intial value of zero and gets incremented
on every clock tick. It is a 32-bit counter.
Applications typically invoke the routines that start the timer mechanism as
part of the startup process. They can later access the current clock tick by
calling the routine, ’get_current_clocktick()’ which just returns the value of
’current_timer_tick’.
Following are the routines that need to be invoked in that order.
...
#include "interrupt.h"
#include "irq.h"
#include "pic.h"
#include "time.h"
...
int main(int argc, char **argv) {
int i, j;
trap_init();
init_irq();
phoenix_timer_setup();
sti();
...
some variable = get_current_timer_tick();
...
return 0;
}
trap_init(): sets up the exception vectors starting from the location 0x8000 0000.
trap_init():设置来自起始地址 0x8000 0000的异常向量。
init_irq() : sets up the default interrupt handler for all interrupts. Besides,
it also sets up the timer-interrupt handlers for the cpus.
init_irq() : 对所有的中断,设置默认的中断控制器。除此之外,还为cpu设置计时器中断控制器。
phoenix_timer_setup(): This enables the PIC to deliver the timer interrupt to cpu 0.
sti(): enables the interrupts. Since timer is also an interrupt, we need to invoke
this to start receiving timer interrupts.
phoenix_timer_setup(): 这可以让PIC 给cpu 0 传输定时器中断。
sti(): 使中断使能。
因为timer也是一个中断。需要invoke它,以接收timer中断。
The duration of the clock tick can be tuned to different values. Currently, both
cpu 0 (through PIC) and non-zero cpus (throug count-compare registers) receives
timer interrupts every 1 millisecond. For cpu 0, the duration is changed by changing
the value of the variable ’PIC_CLKS_PER_TIMER_TICK’, while for other cpus, the value
of CYCLES_PER_JIFFY is used to control the duration. Both constants are defined in
the file "rmios/include/time.h".