1
README - Erlang/OTP R9C for OSE Delta 4.4 on PowerPC750
2
=========================================================
3
2003-04-03 -- Peter Andersson, support@erlang.ericsson.se
5
Erlang/OTP for OSE Delta on PowerPC750 is based on the R9C release for
6
other platforms such as Unix, Windows and VxWorks.
8
This Erlang release contains a directory named build_erl_ose. Stored
9
in this directory is a tar-file (erl_ose_R9C.tar) which contains
10
make-, configuration- and source files for building a complete
11
Erlang/OSE system for a PowerPC750 target. When the tar-file is
12
unpacked, the following directory structure is created:
14
erl_utils misc. shared code (startup files etc.)
15
lm/erl for building Erlang as an OSE PRH load module
16
lm/ose config. files for building an OSE executable
17
monolith for building Erlang and OSE as a monolith
18
port_progs port program examples
19
drivers driver examples
20
host applications to run on host
24
All applications that can be run on an embedded system (one that
25
doesn't necessarily have access to local disk and has limited RAM) are
26
included in this release. These applications will be added to the list
27
of included OTP applications below once they have passed all
28
associated tests. Hence, an application that is not listed may still
29
work fine, it could well be that this just hasn't been verified
30
yet. Applications that will not be supported on this platform are
31
listed under "Omitted Applications".
33
Included OTP Applications
34
-------------------------
49
For applications using graphical interfaces, only the backend part is
54
All compilers are expected to be run on a cross host. The OSE systems
55
memory capabilities are too restricting to allow native compiling. The
56
expected host system is a Sun Solaris machine, although Erlang
57
compilation may be done on most platforms.
59
Supported boards and configurations
60
-----------------------------------
61
The following boards and configurations are fully supported:
63
* Force PowerCore CPCI-680 with a minimum of 64 Mb memory, OSE
64
powercore680 BSP, OSE Delta 4.4.
66
Hardware floating point support is not yet used in any of the
67
supported configurations.
69
Configuration of OSE Delta
70
--------------------------
71
Erlang/OTP is dependent on the following OSE components:
79
- Board Support Package
80
- Embedded File System
83
The configuration of OSE that has been used for Erlang so far is based
84
on the OSE configuration examples. For details, see the Makefiles and
85
the .con files that are included in the build_erl_ose subdirectories
86
of this release. Some notes:
88
The Erlang Runtime System (ERTS) requires a minimum of 6 Mb RAM (4 Mb
89
heap space plus 2 Mb user signal pool space) to start up and enter
90
idle state. How much memory is required for user applications to
91
function properly must be investigated for each application. It
92
depends on data usage, message buffering etc.
94
ERTS uses a local pool (specified by DEF_BLOCK in osemain.con) for
95
allocating signals. The required size of this pool depends mainly on
96
the behaviour of the Erlang applications. I/O or external
97
communication (e.g. TCP/IP or port communication) uses OSE signals for
98
passing data between OSE processes and hence requires available pool
101
For ERTS to work properly, the following signal sizes (specified by
102
DEF_BLOCK) are recommended: 255, 1066, 4095, 1048575. Recommended
103
stack sizes are: 1023, 8191, 65535, 524288.
105
It is quite possible that the MAXPROCS and MAX_ATTACHED values
106
(ospp.con) need to be larger than default.
108
It may be useful to have somewhere to store an Erlang crash dump
109
file. The best choice is of course to use persistent memory (flash or
110
disk) if available. If there is no local filesystem or NFS,
111
configuring a RAM disk is a good idea.
113
This Erlang/OTP release uses the default OSE error handler
114
implementation supplied by OSE Systems. No automatic restart
115
functionality has been implemented.
117
In the Makefile that comes with the release, the serial ports are
118
configured according to this: COM1 is used for debug printouts by
119
means of the low level dbgprintf driver in OSE (e.g. useful when
120
running the target application from a remote connection), COM2 is used
121
to access a local shell started with EFS (see startefs.c).
123
There are two options for building Erlang for OSE. One is to link ERTS
124
and OSE statically and generate one single executable from the
125
result. The second possibility is to build ERTS separately and use the
126
OSE Program Handler component to load ERTS into memory as a so called
127
load module. However, PRH does not perform dynamic linking, only
128
relocation, as the module is loaded. Therefore the linker must be able
129
to resolve all references as the ERTS load module (the elf-file) is
130
built and hence common OSE and ERTS code is copied, not shared, in
131
this mode. Of course, the load module approach has the advantage that
132
it is possible to upgrade ERTS without stopping OSE.
134
Configuration of Erlang
135
-----------------------
136
The Erlang Runtime System runs as one OSE process, named erts, which
137
in turn spawns and uses a separate process for handling select on
138
sockets. If Erlang is started in interactive mode, two OSE processes
139
are also started for non-blocking I/O. Erlang port programs are also
140
separate OSE processes, started when erlang:open_port/2 is called. All
141
processes are started as OSE background processes for time sharing
144
ERTS starts a separate background OSE process (the Program Server) for
145
handling registration and unregistration of dynamic Erlang linked-in
146
drivers and port programs (implemented as PRH load modules).
148
The Erlang Port Mapper Deamon (EPMD) also runs as a background OSE
149
process. This process is started once, either when Erlang is started
150
for the first time, or explicitly using a shell command.
152
ERTS requires that a block, called erl_block, is defined in
153
osemain.con. Furthermore, when building Erlang and OSE as a monolith,
154
a dummy erl_block process (erl_tmp) should be defined in
155
osemain.con. (ERTS uses the ID of erl_tmp to identify erl_block, see
158
The shell commands implemented in erl.exec.c need to be registered at
159
OSE startup by means of a late start hook, erlHooks, in osemain.con.
161
Environment variables for Erlang should be defined as block variables
162
in osemain.con. The following variables must exist and have correct
165
HOME home directory of the current user
166
ROOTDIR root directory of the Erlang installation
168
The following variables are optional:
170
ERL_CRASH_DUMP crash dump file location (default is CWD)
171
ERL_MAX_PORTS specifies the maximum number of Erlang ports allowed
174
In distributed short name mode, Erlang will use the OSE resolver to
175
look up host information from DNS. There are two ways to let Erlang
176
locate a name server. One is to specify the location of a hosts and a
177
resolv file using variables HOSTSFILE and RESOLVFILE. Second is to
178
specify the IP address of a name server with variable NAMESERVER and
179
domain with variable DOMAIN. To learn the local host name, Erlang will
180
read variable HOSTNAME. If this variable isn't defined, Erlang will
181
read the host name from a name server. Hence, if Erlang is in long
182
name mode, HOSTNAME must be defined.
184
Building and installing Erlang/OTP for OSE Delta
185
------------------------------------------------
186
To build Erlang/OTP for OSE Delta and install it on a target system,
187
the following knowledge is expected:
189
* Building, installing and configuring OSE Delta.
191
* Network (TCP/IP) configuration.
193
* Erlang basic operation and configuration.
195
DIAB is the compiler currently used for compiling and linking, both
196
OSE Delta and Erlang/OTP (with exception for a few files, see known
197
bugs and problems). Gmake or clearmake are the expected make programs.
199
Follow these steps to build a monolith:
201
1. Build the Erlang/OTP release for the target in question
202
(e.g. ose_ppc750) if this has not already been done. Follow separate
203
instructions for this procedure. erl_ose_P9C.tar (mentioned in the
204
introduction) should be located in the build_erl_ose directory after
207
2. Unpack the tar file.
209
3. The monolith directory of the release contains a Makefile and a few
210
configuration and utility files for building an executable. Modify the
211
path to the OSE installation in the Makefile. Run gmake with flag
212
erlopt (normal) or erldbg (debug) to compile the OSE Delta system and
213
configuration files as well as the miscellaneous Erlang utility files
214
(such as erl.exec.c). All object code will be linked and the binary
215
image file (.bin) will be created.
217
4. To install the binary image file on target, use tftp to transfer it
218
from host. Make sure the image file is placed on a start address that
219
corresponds to IMAGE_START in the Makefile.
221
Follow these steps to build an ERTS load module:
223
1-2. Follow monolith step 1-2 above to build the Erlang/OTP release.
225
3. Use the make- and configuration files in the lm/ose directory to
226
build an executable OSE image file (run 'gmake ose').
228
4. Build an Erlang load module separately from OSE by using the same
229
directives as in monolith step 3 above. The make- and configuration
230
files are in the lm/erl directory. A file on elf format will be
231
created rather than a binary image.
233
5. Follow monolith step 4 above to install and start OSE on target.
235
6. On target, connect a tftp archive server (tftp_asf) to PRH and use
236
PRH to load the Erlang load module from the host. Finally start the
237
load module. Note that this does not start Erlang. It must be done
238
explicitly (see instructions below).
240
7. If you are going to build and load Erlang linked-in drivers
241
separately as load modules (see Writing Erlang Linked-in Drivers for
242
OSE Delta below), you need to create an Erlang user library file
243
(liberl_user.a) for the drivers to link with. Run gmake with flag
244
erllib in the lm/erl directory.
246
Starting and Stopping ERTS
247
--------------------------
248
When OSE Delta has been started on target, use the local command shell
249
or a remote Telnet shell to start ERTS. The shell command start_erl
250
spawns the erts process and starts the emulator. start_erl takes any
251
valid Erlang flag as input. Example:
253
$ start_erl -sname erl_ose -kernel raw_files false -master
254
boots@blackbush -loader inet -hosts 134.138.177.125 -setcookie
257
Note the kernel variable raw_files. Setting the value of this variable
258
to false causes the raw option to be ignored in any call to
259
file:open/2. (Opening files in raw mode is impossible if there's no
260
local file system). If the flag is omitted, raw_files defaults to
263
Read the System Principles chapter in the Erlang/OTP System
264
Documentation to learn more about general start flags and, for
265
example, how to start a target slave node without local disk access.
267
ERTS can be started in interactive or embedded mode. This works the
268
same way as for Erlang on any other platform. The same is true for
269
stopping the emulator.
271
If you wish to start the epmd process before starting ERTS, run
272
start_epmd from the shell prompt (otherwise epmd starts with ERTS).
276
For heap memory management, the Erlang emulator uses the elib_malloc
277
library which is released as part of Erlang/OTP. When ERTS is started
278
it reads the block environment variables OSE_EXT_HEAP_SIZE and
279
OSE_EXT_HEAP_ADDR. These variables should be defined in osemain.con
280
and should specify the size of the memory area to be reserved for ERTS
281
and the start address of the same area.
283
The command erl_mem_show may be called from an OSE shell prompt (when
284
ERTS is running) to show information about the current heap memory
287
The start function for the Erlang emulator also reads block variables
288
ERL_HEAP_SIZE and ERL_HEAP_ADDR. If the heap memory for OSE needs to
289
be extended (with heap_extend_heap) before Erlang is started, you may
290
specify the size and start address of a memory area with these
293
Writing Erlang Port Programs for OSE Delta
294
---------------------------------------------------------
295
Port programs need to be implemented differently for OSE Delta than
296
for other platforms. The main reason is that they run as OSE processes
297
and communicate with Erlang by means of OSE signals rather than by
298
sending and receiving data on file descriptors.
300
A port program is started in Erlang by calling function
301
erlang:open_port/2, like this:
303
open_port({spawn,PortProgName}, PortSettings)
305
PortProgName is the name of the port program. For Erlang to recognise
306
a port program, the OSE process entry point must be registered with
307
ERTS. To register a port program that is statically linked with ERTS,
308
declare the entrypoint - which must be the same as the port program
309
name - in erl_user_pgm.c (this file is compiled and linked when
310
building ERTS). For details, see the instructions in the same file. To
311
register a port program which is separately built and is supposed to
312
be loaded by OSE PRH, you need to have the following lines of code in
313
a function being called at the time the module is loaded or started:
315
ERL_PORT_PROG_DECL (<PortProgName>);
316
ERL_PORT_PROG_REG (<PortProgName>);
318
When the port program is no longer to be used, it may be unregistered
321
ERL_PORT_PROG_UNREG(<PortProgName>)
323
The file that uses these macros must include ose_erl_port_prog.h. You
324
will find a static port program example in erl_stat_port_ex.c and an
325
example of a dynamic program in erl_port_ex.c. They are located in the
326
port_progs directory.
328
When open_port/2 is called, ERTS will create and start a new OSE
329
process with the registered name of the port program as entry
330
point. To declare the port program start function, instead of
331
using OS_PROCESS, use:
333
ERL_PORT_PROG(<PortProgName>)
335
The PortSettings argument to open_port/2 is a list that may contain
336
the following settings:
339
{ose_process_type,ProcType}
340
{ose_process_prio,Priority}
346
Atom stream is the only valid communication protocol setting. This is
347
also the default mode if stream is not specified explicitly. ProcType
348
is the atom ose_pri_proc, ose_bg_proc, ose_int_proc, ose_phantom or
349
ose_ti_proc. The emulator starts the port program as an OSE process of
350
the corresponding type. If this setting is not specified, ose_bg_proc
351
(OS_BG_PROC) is used as default. Priority is an integer value
352
0-31. The port program will run as an OSE process with this
353
priority. Default is 20. exit_status may be used to keep a port alive
354
if the port program terminates and to let the connected Erlang process
355
receive a notification about the event. It works as documented in the
356
manual page for module erlang, except the exit status integer value
357
the Erlang process receives contains no information. It's a dummy
358
value. For information on the in, out and binary settings, please see
361
The OSE signal type the port program should use to communicate with
362
ERTS is declared in port_signals.sig. Data sent from an Erlang process
363
is received by the port program in the buf element of the PortData
364
signal. The length of the data is indicated by the element len. The
365
port program will use the same data structure the same way for sending
366
data to an Erlang process (the signals should be sent to the erts
367
process). For examples of this, see the previously mentioned port
368
program example files.
370
Writing Erlang Linked-in Drivers for OSE Delta
371
---------------------------------------------------------
372
Linked-in drivers are implemented in a very similar way for Erlang on
373
OSE Delta as for Erlang on other platforms. Please see the Tutorial
374
section of the Erlang/OTP System Documentation for details. ERTS
375
handles drivers similarly to port programs. The important difference
376
is of course that a port program runs as a separate OSE process, while
377
as a driver is implemented by a set of runtime system callback
380
A driver must register with ERTS for the runtime system to be able to
381
call the driver's initialisation function. If you link the driver
382
statically with ERTS, you should declare the driver name in
383
erl_user_pgm.c (this file is compiled and linked when building
384
ERTS). For details, see the instructions in the same file. To register
385
a driver which is separately built and is supposed to be loaded by OSE
386
PRH, you need to have the following lines of code in a function being
387
called at the time the module is loaded or started:
389
ERL_DRIVER_REG(DriverName);
390
ERL_DRIVER_REG(DriverName);
392
The initialisation function of the driver should look like this:
394
ERL_DRIVER_INIT(DriverName)
396
DRIVER_INTERFACE_INIT();
398
return &driver_entry;
401
The file that uses these macros must include ose_erl_driver.h. Note
402
that it must not include erl_driver.h (which is the common header file
403
for Erlang drivers on other platforms). You will find a static driver
404
example in erl_stat_portdrv_ex.c and a dynamic driver example in
405
erl_portdrv_ex.c. The files are located in the drivers directory.
407
To load a driver from Erlang, call:
409
erl_ddll:load_driver("", DriverName)
411
ERTS will as a result invoke PRH to localise and load a module with
412
name DriverName (from whatever archive server you've previously
413
connected to PRH). If you have a module with an elf extension, don't
414
specify this extension in DriverName. The function will look for
415
DriverName.elf automatically. Note that this function must be also be
416
called for statically linked drivers for Erlang to be able to
417
recognise the driver when open_port/2 is called (see below). There
418
will be no attempt to load a module for a driver that has been
419
registered as static (i.e. declared in erl_user_pgm.c).
421
Drivers are started from Erlang the same way as port programs:
423
open_port({spawn,DriverName}, PortSettings)
425
See the section Writing Erlang Port Programs for OSE Delta above for
426
details. DriverName is the name of the driver as well as the load
427
module (for dynamic drivers).
429
To remove a driver, call:
431
erl_ddll:unload_driver(DriverName)
433
This unregisters the driver and invokes PRH to unload the corresponding
434
load module (if the driver is dynamic).
436
It is possible to load a dynamic driver module from outside of Erlang
437
(e.g. from the OSE shell). However, erl_ddll:load_driver/2 must still
438
always be called before the driver can be started. There is no
439
explicit way to unregister a driver since this is handled by
440
erl_ddll:unload_driver/1, which must always be used to remove a
443
Known Bugs and problems
444
-----------------------
445
The emulator loop, implemented in beam_emu.c, uses a jump table for
446
optimal performance. This requires a compiler extension that e.g. DIAB
447
doesn't provide. For this reason, when compiling ERTS for PPC750, this
448
particular file must be compiled with gcc. Note that this is true for
449
optimized (opt) compilation, not for debug compilation.
451
The emulator files ggc.c and erl_process.c are incorrectly compiled by
452
DIAB for PPC750 if the general optimization switch, -XO, is used. For
453
now, gcc may instead be used for these two files.
455
DIAB's "local static variables optimization" (default when compiling
456
with -XO) screws up addressing of some global variables and needs to
459
A bug in the OSE INET implementation made it impossible to disable the
460
Nagle algorithm. This gave distibuted Erlang bad performance in TCP/IP
461
communication. The bug has been fixed by OSE Systems and a patch
462
exists for OSE Delta v4.4 for PowerPC.