Skip to main content

skip to main content

developerWorks  >  Linux  >

Technical guide for porting applications from Solaris to Linux, Version 1.0

Isn't Linux a lot like Solaris? Not if you're porting an application.

developerWorks
Document options

Document options requiring JavaScript are not displayed


Rate this page

Help us improve this content


Level: Intermediate

Lee Cheng (chenglc@us.ibm.com), Technical Consultant, IBM 
Wayne Huang (huangw@us.ibm.com), Senior Solutions Enablement Architect , IBM 
Paul Sutera (psutera@us.ibm.com), Programmer, IBM 
Nam Keung (namkeung@us.ibm.com), Senior Programmer, IBM 

12 Feb 2002

Solaris and Linux are loosely related to Unix, so they ought to be a lot alike, right? Not so - the differences pose a great many "gotchas." Let this technical porting guide show you the ropes for porting your Solaris application to the Linux platform.

Porting overview

The porting process itself is reasonably simple:

  1. Clean up the code and header files and remove architectural dependencies and nonstandard practices.
  2. Compile the code and fix problems found during compile time.
  3. Fix segment faults and unaligned accesses, if necessary.
  4. Recompile the code and repeat the above process, if necessary.



Back to top


Porting guidelines

Porting a Solaris application requires at least two platforms: one source platform and one (or more) Linux target platforms. When porting an application to run on a Linux target platform, you should consider a number of factors:

  • Which Linux target platform is to be ported to? For example, Linux is supported on various hardware platforms and the byte ordering is based on the target system (such as big endian and little endian). Which Linux distribution and kernel version is to be used? (Red Hat, TurboLinux, Caldera, SuSE, and so on)?
  • Must all hardware requirements be supported on the Linux target platform? For example, is there a dependency on a third-party network card? Do you need to support the network and storage requirements?
  • Are all required third-party packages (such as class libraries), middleware software, application server tools, and application development tools available on the Linux target platform? Does the target platform support the same (or compatible) versions of those products?
  • Is anything being changed as part of the port to the target platform? For example, is the application being changed to use a different database system?
  • Does a 32-bit Solaris application need to be ported to the 64-bit Linux platform?
  • Does the Solaris application take advantage of processor affinity? Solaris has kernel hooks, a library, and command line tools for assigning processes to particular processor sets. There is no equivalent in Linux.
  • Is a single common source code base required? For example, do you need to support multiple platforms?
  • Understanding the application architecture will ease the porting process. For example, is this a client-server model or an n-tier application component? You need to decide which software component to port first.

An exercise is truly a port if the hardware and operating systems are the only things that are changed. You can use different methods to achieve the objective. The following options describe two steps in the porting approach:

  • Option A: Because Linux is also supported on the Sparc platform, the modified code can be tested and performed on the Sparc platform before being moved to the Linux target platform. Sun includes a comprehensive set of freely available software with the Solaris operating environment, providing interoperability and commonality across both Linux and Solaris environments. The Sun development tools make it easier to create compatible source code, help migrate crucial utility code to avoid rewrites, and reduce setup time. This option helps the developer with limited Linux experience to port the Solaris source code to Linux target platforms. The following web sites provide the Solaris GNU tools:
  • Option B: Move the code to the Linux target platform. Compare testing results against the Solaris platform to prove that the operation is correct. The modified code must either be endian neutral or must use conditional compilations to support the little-endian platform.

To start the port, checkpoint the Solaris source code and test it to ensure it is in the correct operation. The checkpoint should include full recompile, rebuild, and test cycles. Most often, the code does not behave correctly on the Linux target system because a buggy software update was installed in the original source tree. Thus, the claim often heard when porting ("It works OK on the source system!") cannot be trusted unless you have tested it yourself.

The following resources can also help you perform the Linux port:



Back to top


Porting Procedures

The following suggestions are not the only way to port a Solaris application to a Linux environment. With your own porting experience, you can create an individual approach.

Choose the porting development platform

Sparc platform: This approach allows an easy migration for Solaris developers to port a Linux application to a different target platform. The first step is to modify the porting code on the Solaris platform because Sun provides common library and build environments to streamline the process of developing source code that is compatible across Linux and Solaris operating environments. These tools include how-to-guides:

After you test and build the Linux application on the Solaris platform, you can move to the Linux target platform. This approach has the following advantages:

  • It minimizes the number of changes making them more understandable and manageable as well as easier to propagate.
  • It minimizes the number of new problems created during the port.
  • Every change fixes something that is known to be a problem.

Linux target platform: Experienced Linux developers can modify the code to be ported on the Linux target platform. You need to make sure to install the right version of libraries and compilers such as gcc, tcl/tk, glib, GNOME, and KDE.

Use the grep command

After you identify your porting development platform, you need to search for the following, which are likely to cause porting problems in the source code:

  • Regular expressions
  • Macros for printf, sprintf, scanf, and sscanf routines
  • Structures and unions that may change the data alignment
  • The #else .... #endif statements
  • The system header files (such as limits.h, types.h, and so on)

After searching for the potential problems, you need to decide whether you want to maintain a single source code base for supporting multiple platforms (Solaris, Linux, and others).

Identify potential problems

After using the grep command, you also need to check for inefficient or non-portable code. The following list helps to identify the porting issues:

  • Identify source code and library incompatibilities.
  • Enforce stricter type-checking rules than the compiler enforces.
  • Identify potential problems with variables.
  • Identify potential problems with functions.
  • Identify problems with flow control.
  • Identify legal constructions that may produce errors or inefficiencies.
  • Identify unused variable and function declarations.
  • Identify possibly non-portable code.

Use a porting tool

The following tools are either available or under development:

  • The Porting Manager is a Perl script that takes as input a source code tree. It scans the C/C++ code for Solaris-only APIs and flags them. It also provides documentation on how you might port a Solaris API to an equivalent API for Linux. The scanning is table driven (a table of APIs to check for and flags are provided with the tool). It generates the list of APIs that the tool checks for. It also checks for include files and some #pragmas. Porting Manager has a GUI front end and, because it is written in Perl, it runs on Solaris as well as Linux and presumably anywhere that Perl runs.
  • DeveloperWorks Solaris-to-Linux porting tool is a Web application that checks the APIs used by a Solaris application for compatibility on Linux. The following web site provides access to the web application tool:

    ibm.com/developerworks/linux/tools/l-solar.html
  • MigraTEC porting suite is from MigraTEC, a company that specializes in tools for migrating applications from one platform to another. The porting suite includes the Migration WorkBench, which provides a complete Solaris-to-Linux API map.

Fix problems identified at compile time

It is not unusual to go through several iterations before a clean compile is produced. Ensure that you invoke the -Wall option to catch all the warnings.

Test and debug the program

You can use the gdb tool to debug the modified code. For more information on gdb, see the GNU gdb debugger.



Back to top


Comparing Linux and Solaris

This section discusses the directories, file systems, signals, endian issues, system-derived data types, and absolute address.

Directories

The layout of Linux directories has been standardized. Each directory has a well-defined role. A typical Solaris and Linux installation will create the directories as presented in the following table:

Solaris Directories Functions Linux Directories Functions
/binUser commands./bin Contains binaries needed during and after boot-up by normal users.
/boot Contains the files needed by the LILO loader to start the boot-up process. The kernel files reside in the /boot.
/devContains symbolic links entries in /devices where most of the actual device entries are made./devContains the actual block, character, and other devices files that point to devices, such as fd0 (the first floppy drive) and hda1 (the first partition on the first hard drive).
/devicesFor each actual device in the system, there should be an entry created in this directory.
/etcMiscellaneous commands, network configuration files and scripts, and so on./etcReserved for configuration files that are local to your machine. No binaries are put in /etc. The X-Windows configuration file, XF86Config, is stored in /etc/X11.
/homeUsually for user home directories./homeUsually for user home directories.
/kernelContains kernel modules.The corresponding kernel files are found in /boot and /lib modules.
/optApplications packages.
/platformPlatform specific Unix and device drivers for booting.
/procContains information about active processes, and threads, and also provides an interface to control these processes and threads. Each process directory has file entries that contain kernel structures for that process./procContains a filesystem view into the kernel. There are directories for each process and, in addition, there are directories and files that correspond to system counters and limits.
/libContains only those libraries that are needed to execute the binaries in /bin and /sbin. The /lib/modules contains the loadable kernel modules.
/lost&found
/mntThe mount point for temporary mounts by the system administrator.
/rootThis is the root user's home directory and typically does not have any important files in it beyond profile information for the root user.
/sbinSystem control commands, for example mount and umount./sbinExecutables used only by the root user, and only those executables needed to mount /usr and perform system recovery operations.
/tmpAlso a special filesystem mapped to system memory. /tmpSame as Solaris system
/usrCompiler, administrative./usrLocation where most application software gets installed.
/varIncludes lpd and mail spools. Also used by various applications that need to record log files, such as system messages./varIncludes lpd and mail spools. Also used by various applications that need to record log files.

File Systems

Several types of filesystems are available for Linux. Each filesystem type has its own format and set of characteristics (such as filename length, maximum file size, and so on). Linux also supports several third-party filesystem types such as the MS-DOS filesystem. The following table lists the various filesystem types available for Linux:

File System Type Name Comment
Second Extended Filesystemext2fsMost common Linux filesystem
Third Extended Filesystem ext3fs Journaling for ext2fs
Extended Filesystem ext Superseded by ext2fs
Minix Filesystem minix Original Minix filesystem
Xia Filesystem Xia Similar to ext2
UMSDOS Filesystem umsdos Used for installing Linux on a DOS partition
MS-DOS Filesystem msdos Uses tp to process MS-DOS files
/proc Filesystem proc Provides system information
System V Filesystem sysv Used for accessing System V
HPFS Filesystem hpfs Read-only access for HPFS partition
Journal Filesystem jfs Journaled file system
ReiserFS Filesystem reiserFs Uses a variant on classical balanced tree algorithms

The most commonly used filesystem type is the Second Extended Filesystem, or ext2fs. The ext2fs is one of the most efficient and flexible of the filesystems; it allows filenames up to 256 characters and filesystem sizes of up to 4 terabytes. You can also upgrade the ext2fs to ext3fs. In the file /proc/filesystems, you can find which filesystems your kernel currently supports.

Endian issues

The SPARC architecture is big endian (BE) and it has forward byte ordering. Bit 0 is the least-significant bit, and byte 0 is the most-significant byte. Note that endian issues are not a problem when porting from Solaris to pSeries or IBM eServer zSeries since these are all BE platforms. Intel x86 architectures are little endian (LE) and byte 0 is the least-significant byte (LSB). Figure 1 illustrates the byte ordering on the BE and LE representations:


Figure 1. Big-Endian and Little-Endian Addresses

Data type mismatch

When a 4-byte integer is treated as data element of integer data type, the individual bits and bytes in the integer are viewed in opposite orders by LE and BE:

int a=0x11121314;
char b, *ptr;
ptr= (char *) &a;	     // pointer ptr points to a
b= ptr[1];		     // b is 0x13 in LE and 0x12 in BE

An endian neutral solution will resolve the byte ordering between LE and BE.

#define INTB16TO23(a) ((a>>16) & 0xff)
b= INTB16TO23(a);		// b is 0x12 in BE and LE

Network communication

If data with multibyte values is being transferred between BE and LE systems, then it is simply a matter of providing code that swaps the bytes. For the network communication, functions such as the htons() and ntohs() are also used to convert the port number to network byte order.

General endian solution guide

  • Use an endian-neutral solution to resolve data type mismatches.
  • Use macros and directives.

    To make the code portable, you can use macro and conditional compile directives as followed:

    #define BIG_ENDIAN         0
    #define LITTLE_ENDIAN      1
    #define BYTE_ORDER	BIG_ENDIAN

  • Use a compile time option.

    Another option to implement this is to define the value of BYTE_ORDER on the compile command line. You can change the makefile only to build your application, or you can use the GCC compile option to select the appropriate endian-specific code segment.

Signals

Linux accepts four default actions as a signal: ignore it, stop the process, terminate the process, or generate a core dump after termination of the process. Linux supports nearly every signal provided by System V, BSD, and POSIX, with the following exceptions:

  • SIGEMT, SIGINFO, and SIGSYS are not supported.
  • SIGABRT and SIGIOT are identical.
  • SIGIO, SIGPOLL, and SIGURG are identical.
  • SIGBUS is defined as SIGUNUSED. Technically, there is no "bus error"' in the Linux environment.

The following web site provides more details on Linux signals:

http://www.linux-mag.com/2000-01/compile_01.html

http://www.linuxhq.com/guides/LPG/

Note: POSIX.1 defines only SA_NOCLDSTOP. When porting applications that use sigaction, you may have to modify the values of sa_flags to get the appropriate behavior.

Solaris has sig2str() and str2sig() APIs which are used for signal name conversion back and forth from a signal to a string. Because Linux does not support these APIs, the following code does not work for porting:

#include<signal.h>
#include<stdlib.h>
#include<stdio.h>

int main(int argc, char **argv)
{
	char signame[SIG2STR_MAX];
	sig2str(atoll(argv[1]), signame);
	printf("Received signal = %s \n", signame);
	return 0;
}

Here's the corrected code for porting to Linux:

#include<signal.h>
#include<stdlib.h>
#include<stdio.h>

int main(int argc, char **argv)
{
	const char *str
	int signo_ = atoll(argv[1]);
	str = sys_siglist[signo_];
	printf ("Received signal = %s \n", str);
	return 0;
}

The following table lists the commonly used signals for the Solaris and the Linux operating systems.

Solaris Solaris Default Action Linux Linux Default Action
SIGHUP Terminate SIGHUP Ignore
SIGINT Terminate SIGINT Ignore
SIGQUIT Terminate, core SIGQUIT Terminate, core
SIGILL Terminate, core SIGILL Terminate, core
SIGTRAP Terminate, core SIGTRAP Ignore
SIGABRT Terminate, core SIGABRT Terminate, core
SIGEMT Terminate, core SIGEMT Not supported on Linux
SIGFPE Terminate, core SIGFPE Terminate, core
SIGKILL Terminate SIGKILL Terminate
SIGBUS Terminate, core SIGBUS Terminate, core
SIGSEGV Terminate, core SIGSEGV Terminate, core
SIGSYS Terminate, core SIGSYS Not supported on Linux
SIGPIPE Terminate SIGPIPE Ignore
SIGALRM Terminate SIGALRM Ignore
SIGTERM Terminate SIGTERM Terminate
SIGUSR1 Terminate SIGUSR1 Ignore
SIGUSR2 Terminate SIGUSR2 Ignore
SIGCHLD Ignore SIGCHLD Ignore
SIGPWR Ignore SIGPWR Ignore
SIGWINCH Ignore SIGWINCH Process stop
SIGURG Ignore SIGURG Ignore
SIGPOLL Terminate SIGPOLL Not supported on Linux
SIGSTOP Process stop SIGSTOP Process stop
SIGSTP Process stop SIGSTP Process stop
SIGCONT Ignore SIGCONT Ignore
SIGTTIN Process stop SIGTTIN Process stop
SIGTTOU Process stop SIGTTOU Process stop
SIGVTALRM Terminate SIGVTALRM Terminate, core
SIGPROF Terminate SIGPROF Ignore
SIGXCPU Terminate, core SIGXCPU Terminate, core
SIGXFSZ Terminate, core SIGXFSZ Terminate, core
SIGWAITING Ignore SIGWAITING Not supported on Linux
SIGLWP Ignore SIGLWP Not supported on Linux
SIGFREEZE Ignore SIGFREEZE Not supported on Linux
SIGTHAW Ignore SIGTHAW Not supported on Linux
SIGCANCEL Ignore SIGCANCEL Not supported on Linux
SIGRTMIN Terminate SIGRTMIN Not supported on Linux
SIGRTMAX Terminate SIGRTMAX Not supported on Linux

System-derived data types

System-derived data types can have different byte sizes. A derived data type is one that is defined with typedef as a derivated or structure of existing base types. The following sections compare the most common system-derived data types for Solaris and Linux.

  • Data types gid_t, mode_t, pid_t and uid_t

    The data type gid_t is used to represent the group ID of a user, while the uid_t is used for the user ID. The data type mode_t is used to indicate the mode of a file, while the pid_t is used to identify the different processes with unique numbers.

    OS gid_t mode_t pid_t uid_t
    Solarislongunsigned longlonglong
    Linuxunsigned intunsigned intintunsigned int
  • Size_t, ssize_t, and wint_t

    The data types size_t and ssize_t should be used in conjunction with the size of objects in memory and to return a count of bytes or an error indication. The data type of wint_t is required to represent the wide character code value as well as the end-of-file marker when a program uses multibyte and wide character subroutines.

    OS size_t ssize_t wint_t
    Solarisunsigned intintlong
    Linuxunsigned longintunsigned int

Absolute addresses

Each platform is likely to use different memory locations for the program stack, system libraries, heap, and so on. Therefore, a hard-coded address is already a poor bet for portability to other systems. Some addressing schemes also ignore high-order bits, so a hard-coded address of 0x80000000 (high-order bit on) would be translated to 0x00000000, which is possibly illegal and definitely not intended. In generating addresses, arithmetic operations on addresses may also turn on high-order bits.

If an application uses an absolute address that causes a segmentation violation or other errors, it must be changed. /proc/<pid>/map shows how an active process uses storage ranges within its address space. If the code must use absolute addresses, this map can be used to find address ranges that are not already reserved.



Back to top


Some application development tools

C/C++ application infrastructure

Operating SystemsRed Hat Linux V7.1
SuSE V 7.2 (Intel)
Runtime Librariesglibc V2.2

C/C++ application tooling

Analysis and DesignRational Rose
IDE IBM WebSphere Studio Application Developer with C/C++ Plug-in
Metrowerks CodeWarrior
Low-Level Edit/Compile/Debug GNU Compiler Collection V3.0
GNU GDB Debugger V5.0
Insure++ V5.2
Build GNU make V3.79
Automake
Packaging RPM V4.02
Test DejaGnu
TETWare Professional V1.3
Performance Tuning and BenchmarkingGNU Profiler V2.9.1
LmBench
Source Code ManagementRational ClearCase
AccuRev/CM V2.6
RCS and CVS
Maintenance and Defect Checking Rational ClearQuest Client
GNATS V3.113
Bugzilla

Java application tooling

Analysis and DesignRational Rose, ObjectDomain 2.5
IDEIdera Jsync 1.50
AnyJ
NetBeans Developer 2.1
Source Navigator
JVMSUN JVM
IBM JVM
CompilerJikes
Performance toolsOptimizeit
Source Code ManagementRational ClearCase
Maintenance and Defect CheckingRational ClearQuest Client


Back to top


The Solaris make vs. the GNU make

Both the Solaris make and the GNU make define the same basic set of suffixes and implicit rules. The following targets, macros, and variables are the same:

  • Targets: .DEFAULT, .IGNORE, .PRECIOUS, .SILENT, and .SUFFIX
  • Internal macros: $*, $%, $?, $<, $@, $$@, $(F), and $(D)
  • Predefined macros: ar, as, cc, ld, lex, lint, m2c, pc, rm -f, and yacc
  • Environment variable: MAKEFLAGS
  • Variables: CC, CFLAGS, CPPFLAGS, FC, FFLAGS, LEX, LFLAGS, YACC, YFLAGS, LD, and LDFLAGS

Note: % is partially supported by the GNU make. Only the first % gets replaced.

Here's the example:

#Begin Makefile
FOO=abc def
BAR=$(FOO:%=dir1/%.o  dir1/%_cltn.o)
BAR2=$(FOO:%=dir1/%.o) $(FOO:%=dir1/%_cltn.o)

all:
@echo FOO is $(FOO)
@echo BAR is $(BAR)
@echo BAR2 is $(BAR2)

#end Makefile

On Sun, the make command prints:

FOO is abc def
BAR is dir1/abc.o dir1/abc_cltn.o dir1/def.o dir1/def_cltn.o
BAR2 is dir1/abc.o dir1/def.o dir1/abc_cltn.o dir1/def_cltn.o

On Linux with GNU, the make command prints:

FOO is abc def
BAR is dir1/abc.o dir1/%_cltn.o dir1/def.o dir1/%_cltn.o
BAR2 is dir1/abc.o dir1/def.o dir1/abc_cltn.o dir1/def_cltn.o

To work around this difference, you need to change the code as follows:

                    BAR = $(FOO:%=dir1/%.o)
BAR += $(FOO:%=dir/%_cltn.o)
BAR2 = $(FOO:%=dir/%.o)
BAR2 += ${FOO:%=dir1/%_cltn.o)
                

Suffixes for make

Built-in suffix rules provided with the make allow developers to simplify makefile greatly. The following tables for single and double suffixes contain the default inference rules for the Solaris and the GNU make commands.

Single suffix inference rule

Suffix Make Single Suffix Rule
.cSolaris$(CC) $(CFLAGS) $(CPPFLAGS) $(LDFLAGS) -o $@ $< $(LDLIBD)
GNU$(CC) $(CFLAGS) $(CPPFLAGS) $(LDFLAGS) $(TARGET_ARCH) $^ $(LOADLIBES)
$(LDLIBS) -o $@
.CSolaris$(CCC) $(CCFLAGS) $(CPPFLAGS) $(LDFLAGS) -o $@ $< $(LDLIBS)
GNU$(CXX) $(CXXFLAGS) $(CPPFLAGS) $(LDFLAGS) $(TARGET_ARCH) $^
$(LOADLIBES) $(LDLIBS)
-o $@
.cc Solaris$(CCC) $(CCFLAGS) $(CPPFLAGS) $(LDFLAGS) -o $@ $< $(LDLIBS)
GNU$(CXX) $(CXXFLAGS) $(CPPFLAGS) $(TARGET_ARCH) -c $(LOADLIBES)
$(LDLIBS) -o $@
.fSolaris$(FC) $(FFLAGS) $(LDFLAGS) -o $@ $< $(LDLIBS)
GNU $(FC) $(FFLAGS) $(LDFLAGS) $(TARGET_ARCH) $^ $(LOADLIBES)$(LDLIBS) -o $@
.F Solaris $(FC) $(FFLAGS) $(LDFLAGS) -o $@ $< $(LDLIBS)
GNU$(FC) $(FFLAGS) $(LDFLAGS) $(TARGET_ARCH) $^ $(LOADLIBES)$(LDLIBS) -o $@
.modSolaris$(M2C) $(M2FLAGS) $(MODFLAGS)-o $@ -e $@ $<
GNU$(M2C) $(M2FLAGS) $(MODFLAGS) $(TARGET_ARCH) -o $@ -e $@ $^
.pSolaris$(PC) $(PFLAGS) $(CPPFLAGS) $(LDFLAGS) -o $@ $< $(LDLIBS)
GNU$(PC) $(PFLAGS) $(CPPFLAGS) $(LDFLAGS) $(TARGET_ARCH) $^
$(LOADLIBES) $(LDLIBS) -o $@
.r Solaris$(FC) $(FFLAGS) $(RFLAGS) $(LDFLAGS) -o $@ $< $(LDLIBS)
GNU$(FC) $(FFLAGS) $(RFLAGS) $(LDFLAGS) $(TARGET_ARCH) $^
$(LOADLIBES) $(LDLIBS) -o $@
.sh Solaris $(RM) $@
cat $<>$@
chmod -x $@
GNU cat $<>$@
chmod a+x $@

Double suffix inference rules

Suffix Make Double Suffix Rule
.c.oSolaris$(CC) $(CFLAGS) $(CPPFLAGS) -c $(OUTPUT_OPTION) $<
GNU $(CC) $(CFLAGS) $(CPPFLAGS) $(TARGET_ARCH) -c
$(OUTPUT_OPTION) $<
.c.ln Solaris $(LINT) $(LINTFLAGS) $(CPPFLAGS) $(OUTPUT_OPTION) -c $<
GNU $(LINT) $(LINTFLAGS) $(CPPFLAGS) $(TARGET_ARCH) -C$* $<
.cc.o Solaris $(CCC) $(CCFLAGS) $(CPPFLAGS) -c $(OUTPUT_OPTION) $<
GNU $(CXX) $(CXXFLAGS) $(CPPFLAGS) $(TARGET_ARCH) -c
$(OUTPUT_OPTION) $<
.C.o Solaris $(CC) $(CFLAGS) $(CPPFLAGS) -c $(OUTPUT_OPTION) $<
GNU $(CXX) $(CXXFLAGS) $(CPPFLAGS) $(TARGET_ARCH) -c$(OUTPUT_OPTION) $<
.def.sym Solaris $(M2C) $(M2FLAGS) $(DEFFLAGS) -o $@ $<
GNU $(M2C) $(M2FLAGS) $(DEFFLAGS) $(TARGET_ARCH) -o $@ $<
.f.o Solaris $(FC) $(FFLAGS) -c $(OUTPUT_OPTION) $<
GNU $(FC) $(FFLAGS) $(TARGET_ARCH) -c $(OUTPUT_OPTION) $<
.F.o Solaris $(FC) $(FFLAGS) $(CPPFLAGS) -c $(OUTPUT_OPTIONS) $<
GNU $(FC) $(FFLAGS) $(CPPFLAGS) $(TARGET_ARCH) -c$(OUTPUT_OPTION) $<
.l.c Solaris $(RM) $@
$(LEX) $(LFLAGS) -t $< > $@
GNU @$(RM) $@
$(LEX) $(LFLAGS) -t $< > $@
.l.ln Solaris $(RM) $*.c
$(LEX) $(LFLAGS) -t $< > $*.c
$(LINT) $(LINTFLAGS) $(CPPFLAGS) -o $@ -i $*.c
$(RM) $*.c
GNU @$(RM) $*.c
$(LEX) $(LFLAGS) -t $< > $*.c
$(LINT) $(LINTFLAGS) $(CPPFLAGS) $(TARGET_ARCH) -i $*.c -o $@
$(RM) $*.c
.mod.o Solaris $(M2C) $(M2FLAGS) $(MODFLAGS) -o $@ $<
GNU $(M2C) $(M2FLAGS) $(MODFLAGS) $(TARGET_ARCH) -o $@ $<
.r.o Solaris $(COMPILE.r) $(OUTPUT_OPTION) $<
GNU $(FC) $(FFLAGS) $(RFLAGS) $(TARGET_ARCH) -c $(OUTPUT_OPTION)$<
.s.o Solaris $(AS) $(ASFLAGS) -o $@ $<
GNU $(AS) $(ASFLAGS) $(TARGET_MACH) -o $@ $<
.S.o Solaris $(AS) $(ASFLAGS) -o $@ $<
GNU $(CC) $(ASFLAGS) $(CPPFLAGS) $(TARGET_MACH) -c -o $@ $<
.y.c Solaris $(YACC) $(YFLAGS) $<
mv y.tab.c $@
GNU $(YACC) $(YFLAGS) $<
mv -f y.tab.c $@
.y.ln Solaris $(YACC) $(YFLAGS) $<
$(LINT) $(LINTFLAGS) $(CPPFLAGS) -o $@ -i y.tab.c$
(RM) y.tab.c
GNU $(YACC) $(YFLAGS) $<
$(LINT) $(LINTFLAGS) $(CPPFLAGS) $(TARGET_ARCH) -C$* y.tab.c
$(RM) y.tab.c


Back to top


Options of the C compilers

Both the Sun Workshop (Forte) compiler and the GCC support the extended C language. The extensions of the Sun Workshop compiler are almost equivalent to the GCC. The extensions are exclusively in the form of #pragmas. GCC generally does not use #pragmas, but when the -Wall option is used, it warns about ignored #pragmas.

The -m486 option on the GCC, which is used to compile binaries for x486 machines, merely changes certain optimizations. There is a version of GCC that optimizes well for the 586, but it is quite unreliable especially at high optimization settings. For the Pentium GCC, see:

ftp://tsx-11.mit.edu/pub/linux/ALPHA/pentium-gcc/.

For the pSeries and the RS/6000, using the '-mcpu' option will disable the '-mpower' or '-mpowerpc' option. The recommended option is to use '-mcpu=common' by default.

For the SPARC, using the '-mcpu' option will also select the architecture for the machine type.

The GNU C library is also thread-aware. When you link to the threading library libpthread (which is done with the - pthread command line parameter to gcc), certain functions in libc.so will be overridden by functions in the threading library.

The following table contains the common options for the C compilers on Solaris and the GNU GCC.

Sun Workshop GCC Description
-# -v Turns on verbose mode, showing each component as it is invoked.
-Xa -ansi Specifies compliance with the ANSI/ISO standard. The GCC supports all ISO C89 programs. You can use '-std' to specify the particular version of ISO C.
-xinline -finline-functions Inlines only those functions specified.
-p -p Generates extra code to write profile information suitable for the analysis program prof.
-xa -ax Generates extra code to write profile information for basic blocks, which will record the number of times each basic block is executed.
-xspace -O0 Does not optimize.
-xunroll= -finroll_loops Performs the optimization of loop unrolling only for loops in which the number of iterations can be determined at compile time or run time.
-xtarget = name -b=machine The argument machine specifies the target machine for compilation. In addition, each of these target machine types can have its own special options, starting with 'm', to choose among various hardware models or configurations.
-xo -O, -O1, -O2, -O3, -Os Controls various sorts of optimizations.
-O Same as above Controls various sorts of optimizations.
-xmaxopt Ensures that GCC does not use #pragma.
-xnolib -nostdlib Does not link any libraries by default.
-fsingle -fsingle-precision-constant Treats floating point constant as single precision constant instead of implicitly converting it to double precision
-C -C Tells the preprocessor not to discard comments. Used with the '-E' option.
-xtrigraphs -trigraphs Supports ISO C trigraphs.
-E -E Preprocess all C source files specified and outputs the results to standard output or to the specified output file.
-xM -M Runs only the preprocessor on the named C programs, requesting that it generate makefile dependencies and send the result to the standard output.
-xpg -pg Generates extra code to write profile information suitable for the analysis program gprof.
-c -c Directs the compiler to suppress linking with ld and to produce the .o file for each source file.
-o -o Names the output file.
-S -S Directs cc to produce an assembly source file but not to assemble the program.
-xtemp TMPDIR Specifies the directory to use for temporary files if the TMPDIR environment is set.
-xhelp=f -help Displays online help information.
-xtime -time Reports the CPU time taken by each subprocess in the compilation sequence.
-w -q Suppresses compiler warnings.
-erroff= %none -W Displays the warning messages.
-errwarn -Werror Makes all warnings into errors.


Back to top


Linker invocation

Both the Sun and the GNU linker accept numerous options. The following table explains the most common options of the SPARCworks linker to the functionality of the GNU linker.

Solaris Workshop gld Option Description
-a -static Enables the default behavior in the static mode and prevents linking with the shared libraries. The linker is creating executable and undefined symbols causing error messages. GNU ld has the option -static that also enables this behavior..
-b Achieves the equivalent of the GNU linker by not compiling the source code with the option -fPIC/-fpic..
-g -g Produces debugging information in the operating system's native format..
-G -shared Generates a shared object. The equivalent for the GNU linker is -shared..
-m (-M) Prints a linker map. The -M option prints something comparable but with a different format and slightly different content..
-s -S/-s Achieves the equivalent of the -s option by using -S with the GNU linker, which removes only the debugging information..
-h name -soname name Sets name as the shared object's name. With the GNU linker, the option -soname must be used..
-o filename -o filename Places output in a file. This applies regardless of the type of output being produced. The default is to put an executable file in `a.out`..
-L directory -Ldir Adds directory dir to the list of directories. .
-R path -rpath path Specifies the search direction to the runtime linker. The GNU linker uses the option -rpath. .

Every Linux shared library is assigned a special name, called a soname, which includes the name of the library and a version number. Unless you have a particular reason, do not link against a specific version of a library. Always use the standard -l libname option to the C compiler or the linker. The linker will look for the file lib libname.so, which will be the symlink to the correct version of the library.

GCC options specific to the pSeries and RS/6000

Option Description.
-fPIC Generates position-independent code (PIC) suitable for use in a shared library.
-mpower,-mno-power,-mpowerpc,-mno-powerpc,-mnpowerpc64,-mno-powerpc64 Specifies that GCC will generate instructions for different architectures.
-mcpu=cpu_type Sets the architecture type, register usage, choice of mnemonics, and instruction scheduling parameter for the machine type.
-mtune=cpu_type Sets the instruction scheduling parameter for the machine type.
-mlittle Compiles code for the Power PC processor in little endian mode.
-mbig Compiles code for the Power PC processor in big endian mode.
-mcall-linux Compiles code for the Power PC Linux-based GNU system.


Back to top


Solaris Thread Library (STL)

Applications written for Solaris often use nonstandard proprietary functions that can make porting to Linux difficult. A provisional STL is supported on Linux (Intel platform) to ease the migration of these applications. It provides implementations of Solaris threads APIs that are layered upon the POSIX threads library. The STL is a component of the Solaris Compatibility Libraries (SCL) and is freely available in open-source format as part of the SCL. This is available from a Compaq-sponsored Sourceforge project at:

http://sourceforge.net/projects/sctl

Limitation

The following functions are not supported in the SCL STL:

  • Support for system-wide synchronization objects
  • Duplication of each thread when a fork() occurs

For developers to use the STL library, you need to be aware of the threads limitation and problems. For example, POSIX thread suspend and thread continue are not supported. A paper on STL titled "Building an Open-Source Solaris-Compatible Threads Library" (Proceedings of the FREENIX, June 2001) contains more detailed information and implementation notes. You can get a copy of the paper from the following web site:

http://www.opensource.compaq.com/the_source/linux_papers/scl_solaris.htm

It is hoped that the future Linux version of STL can support other Linux target platforms (RS/6000, power PC, and so on).



Back to top


System interfaces

This section discusses Solaris threaded applications, Solaris POSIX threaded applications, the Solaris threads library vs. the POSIX threads library, and support for interfaces and definitions.

Solaris threaded applications

Applications that use the Solaris threads programming interface (API) are generally non-portable, for example, thr_create(), mutex_lock(), cond_signal(), and others.The main areas of Solaris thread functions that are not supported in POSIX threads are the follwing:

  • Daemon threads (thr_create)
  • Joining any thread (Solaris allows you join any thread with a tid 0)
  • Thread suspend and thread continue

Porting an application that uses Solaris threads to Linux will require some degree of work if any of the preceding features are required. Otherwise, mapping Solaris threads APIs to POSIX threads APIs is straightforward.

It is not recommended to mix the STL and POSIX threads API calls. If possible, you should use the native library, as this will give you the greatest level of control over your threads.

The following table compares the Solaris threads API to the POSIX threads API.

Solaris Threads API Linux POSIX Threads API Operation
thr_create() pthread_create() Creates a new thread of control.
thr_exit() pthread_exit() Terminates the execution of the calling thread.
thr_getprio() pthread_getschedparam() Retrieves a thread's priority parameters.
thr_getspecific() pthread_getspecific() Binds a new thread-specific value to the key.
thr_join() pthread_join() Suspends the calling thread until the target thread completes.
thr_keycreate() pthread_key_create() Creates a key that locates data specific to a thread.
thr_kill() pthread_kill() Sends a signal to another thread.
thr_self() pthread_self() Returns the thread ID of the calling process.
thr_setprio() pthread_setschedparam() Modifies a thread's priority parameters.
thr_setspecific() pthread_setspecific() Binds a new thread-specific value to the key.
thr_sigsetmask() pthread_sigmask() Changes or examines the calling thread's signal mask.
thr_yield() sched_yield() Makes the current thread yield to another thread.
thr_setconcurrency() pthread_setconcurrency() Sets thread concurrency level.
thr_getconcurrency() pthread_getconcurrency() Gets thread concurrency level.
thr_setspecific() pthread_setspecific() Sets the thread-specific data key.
thr_getspecific() pthread_getspecific() Gets the thread-specific data key.
thr_suspend Not Supported Suspends the execution of the specified thread.
thr_continue Not Supported Resumes the execution of a suspended thread.

Note: The POSIX standard provides no mechanism by which a thread, A, can suspend the execution of another thread, B, without cooperation from thread B. The only way to implement the suspend or restart mechanism is to have thread B periodically check some global variable for a suspend request and then suspend itself on a condition variable, which another thread can signal later to restart B.

Solaris POSIX threaded applications

Solaris POSIX threaded applications provide a fairly straightforward port to Linux with some exceptions in the process sharing capabilities.

Solaris threads library vs. POSIX threads library

Linux supports the POSIX 1003.1c. Solaris supports both the POSIX 1003.1c and the proprietary semaphore API. The following table maps the proprietary Sun routines to the POSIX 1003.1c API implemented in Linux.

One major difference between the Solaris and the Linux interface is that Solaris defines these functions in libthread while on Linux they are in libpthread .

Solaris Library (lib thread) Linux POSIX Library (libp thread) Operation
sema_destroy() sem_destroy() Destroys the semaphore state.
sema_init() sem_init() Initializes a semaphore.
sema_post() sem_post() Increments a semaphore.
sema_wait() sem_wait() Blocks on semaphore count.
sema_trywait() sem_trywait() Decrements semaphore count.
mutex_destroy() pthread_mutex_destroy() Destroys or disables the state associated with the mutex object.
mutex_init() pthread_mutex_init() Initializes the mutex variable.
mutex_lock() pthread_mutex_lock() Locks the mutex object and blocks until the mutex object is free.
mutex_unlock() pthread_mutex_unlock() Releases the mutex object.
cond_broadcast() pthread_cond_broadcast() Unblocks all threads waiting on the condition variable.
cond_destroy() pthread_cond_destroy() Destroys any state associated with the condition variable.
cond_init() pthread_cond_init() Initializes a condition variable.
cond_signal() pthread_cond_signal() Unblocks the next thread waiting on the condition variable.
cond_wait() pthread_cond_wait() Blocks on a condition variable and releases it at the end.
rwlock_init() pthread_rwlock_init() Initializes a read-write lock.
rwlock_destroy() pthread_rwlock_destroy() Locks a read-write lock.
rw_rdlock() pthread_rwlock_rdlock() Reads the lock on a read-write lock.
rw_wrlock() pthread_rwlock_wrlock() Writes the lock on a read-write lock.
rw_unlock() pthread_rwlock_unlock() Unlocks a read-write lock.
rw_tryrdlock() pthread_rwlock_tryrdlock() Reads the lock with a non blocking read-write lock.
rw_trywrlock() pthread_rwlock_trywrlock() Writes the lock with a non blocking read-write lock.

To use the read/write lock extensions to POSIX threads, when compiling you must define:

_XOPEN_SOURCE=500

before including the <pthread.h> header-file, in addition to defining:

_POSIX_C_SOURCE=199506L

Linux threads do not implement process-shared mutexes, conditions, and semaphores. The goal of this extension is to allow different processes (with different address spaces) to synchronize through mutexes, conditions, or semaphores allocated in shared memory (either SVR4 shared memory segments or mapped mmap() files). For example, calls to pthread_mutex_attr_setpshared, pthread_rwlockattr_setpshared, and pthread_condattr_setpshared will fail if PTHREAD_PROCESS_SHARED is set in the respective flag arguments that can be passed to these functions.

When porting from platforms that support process sharing with these functions, you must rewrite the application if the PTHREAD_PROCESS_SHARED flag is set, because the Linux kernel will return -1 if this flag is used in the above functions. For mutexes and simple lock-unlock type semaphores and condition variables, the pthread* calls would have to be replaced with user-written code. Until suitable Linux kernel support is available, you should use traditional interprocess communications to synchronize different processes: System V semaphores and message queues, pipes, or sockets.



Back to top


Support for interfaces and definitions

Linux is written using a hierarchy of interfaces and definitions. Using the default interface, _GNU_SOURCE, applications are able to make use of all the compiler features. This provides the most convenient programming environment. The following macros are also needed in a conforming environment:

  • _POSIX_SOURCE
  • _XOPEN_SOURCE
  • _POSIX_C_SOURCE
  • _UNIX_STD


Back to top


Miscellaneous hints and tips

Following is useful information not covered in the preceding sections.

Syntax of make

Always put a tab the beginning of a command, not spaces. And don't use a tab before any other line. If you use spaces where you should use tabs or vice versa, the makefile does not work.

Use the gcc fPIC flag instead of the -fpic flag

The -fPIC flag generates position-independent code that can be linked and loaded at any address.

Dependency tools for gcc ++ to generate information for makefile

-M Generates make dependencies.
-MM Similar to -M, but ignores system header files.
-MD Similar to -M, but puts output in a .d file.
-MMD Similar to -MD, but ignores system header files.
-MG Treats missing header files as generated files.

Option not to use lD to do linking

Just use the compiler front end to do linking:

gcc -o progname foo.o bar.o main.o

The gcc front end will insert all the right modules for proper linking. Adding the -v parameter also allows you to see the details of the gcc operation.

Check the dynamic load library

Use ldd to invoke executables; it dumps their library dependencies.

Use LD_LIBRARY_PATH

A Linux system searches only /lib and /usr/lib by default. If a shared library that is linked into your program is installed outside those directories, it will not be found and the system will refuse to run the program.

One option is to use the -W1, -rpath option when linking the program. The other option is to set the LD_LIBRARY_PATH environment variable when running the program.

Memory allocation

Always use the malloc() for memory allocation instead of using other system calls.

Missing libsocket in Linux

For Solaris, makefile contains the -lsocket library flag, yet libsocket.* appears not to exist in Linux as it does in Solaris. There is no need to link any particular libraries because they are linked automatically. Just take the -lsocket out of the makefile.

Avoid the incorrect quote symbol

A common mistake is to use the apostrophe symbol (') instead of the backtick symbol (`) to compile the program. Simply press the key to the left of '1' and you will get a (`). For example:

gcc -Wall -o intro intro.c `gtk-config -cflags -libs`

Link some libraries statically and others dynamically

Use the following:

gcc -o some-program some-program.c -Xlinker 
     -Bstatic -llib1 -lib2 -Xlinker   -Bdynamic -llib3

Hardcoded constants

Avoid hardcoding the size of a datatype; use sizeof() instead. Avoid hardcoding constants with malloc(). Use sizof((void *) to get the appropriate pointer size.

Data alignment

Most processors require every data item in memory to be aligned on 2-, 4-, or 8-byte boundaries; otherwise, they may suffer performance degradation by having to perform multiple read operations, or they may have to raise a hardware exception so that the operating system will handle it, with additional performance degradation.

To solve this misalignment problem, the GCC compiler adds filler bytes called padding immediately before every misaligned item to ensure that it is aligned properly on the correct boundary. Although the padding bytes added by the compiler are invisible to the application code, they do exist and can cause the layout of a data structure in memory to differ from what is expected.

Porting thr_suspend

Notice that thr_suspend() is inherently dangerous and prone to race conditions. For one thing, there is no control on where the target thread will actually stop: it can very well be stopped in the middle of a critical section, even while holding mutexes. For these reasons, you'd be much better off using mutexes and conditions instead.

ANSI compliant

The following examples are non ANSI compliant code, but the examples work in the Solaris Forte compiler:

Const reference

#include<iostream>
class test
{
public:
// Using a constant ref. to a variable whose value can be changed
void test1 ( char & const newEvent) { cout << newEvent << endl;};
};

int main()
{
test t;
char * const ptr="A";
t.test1(*ptr);
return 0;
}

You will get the following error if you compile with g++:

Error "discarding "const" applied to a reference"

The const char & is a reference to constant value; char const & the reference is constant but the value of the reference is not constant.

Following is the corrected code:

void test1 ( char const & newEvent) { cout << newEvent << endl;};

Undefined reference

The following code sample contains an undefined reference:

                error" ANSI C++ forbids declaration 'ABC' with no type"
error" (S)  undefined reference to A::x"
#include<iostream>
class test
{
    public:
	     A(int q) { x=q;}
	     ABC(int y);
    private:
	     static int x;
};
A::ABC(int z)
{
    cout << z << endl;
}
int main()
{
    A test(10);
    test.ABC(20);
    return 0;
}

Following is the corrected code:

#include<iostream>
class test
{
    public:
	     A(int q) { x=q;}
	     int ABC(int y);
    private:
	     static int x;
};
int A;;x=1;
int A::ABC(int z)
{
    cout << z << endl;
}
int main()
{
    A test(10);
    test.ABC(20);
    return 0;
}

Get file descriptor from the fstream object

On Solaris, you use the fstream::rdbuf().fd() method to get file descriptor from the fstream object. But the method fd() is not available for the basic_filebuf class on Linux. This is the non- standard C++ code.

For standard C++ code, first open the file with open (Posix) and get a file descriptor fd. Then open a FILE object, call it myfile, with fdopen(fd) (Posix). Then create a filebuf object, call it mybuf, with mybuf(myfile) (conforming extension). You can then associate that buffer with an ifstream or ofstream object str by calling its member function str.rdbuf(mybuf) (Standard C++).



Back to top


Target Hardware Platforms

Sparc

Many distributors provide Linux for Sun's Sparc architecture. Sun is positioning Solaris as the software soul mate of Linux and the open source movement. Sun has an accommodation strategy for Linux and programs for migrating Linux applications to Solaris, but Sun does not support or endorse any specific Linux distributions.

pSeries

IBM has taken on an active role in the Linux PowerPC community. Development for the latest generation of processors, the POWER3 and POWER4, requires additional features, which have been added to the Linux 2.4 kernel.

SuSE Version 7.1 with Linux 2.4 kernel is the first to release the support of the RS/6000 systems, including the B50, 150, F50, 170, 260, 270, and p640 models.

Yellow Dog Linux also has a PowerPC distribution that supports RS/6000 systems. TurboLinux and Red Hat also released the PPC Versions.

The latest version, Linux 2.4, is reported to scale well with the four to six processors in an SMP system. This version works well with pSeries and RS/6000 systems such as B50, 150, 260, 270 and p640 as well as the upcoming 1- to 6-way p620 and p660 systems. For the Linux for pSeries System Guide, see:

ibm.com/servers/eserver/pseries/linux/

The following have packages for Linux on pSeries:

  • Enhydra Java/XML
  • Application Server by Lutris
  • Myrinet scalable cluster interconnect by Myricom
  • Pro Fortran for PowerPC/Linux by Absoft
  • CodeWarrior for Linux by Metrowerks

Any application can be developed in Linux and deployed either on pSeries running native Linux or on AIX using the AIX Affinity with Linux technology. When developed and deployed, Linux based applications are native AIX applications, which means that they can achieve the same scalability and performance as any other AIX application. However, you cannot run Linux on the pSeries without recompiling Linux for the pSeries. Similarly, applications developed on Linux for the pSeries do not run in binary form on AIX. Linux for pSeries and AIX have source code compatibility. For additional information on Linux for pSeries, see:

ibm.com/servers/eserver/pseries/linux/

zSeries

The consolidation of large server farms onto zSeries mainframes enables customers to have lower administration and energy expenses due to uniform server structures and a reduced number of servers. IBM supports Linux for zSeries on hardware such as the z900 and Linux for S/390 on S/390 processors such as the G5, G6, and Multiprise 3000. Distributions are currently available from SuSE, TurboLinux, and Red Hat.

Supported applications and languages are increasing rapidly and are too numerous for a complete list. These include C/C++, perl, tcl, python, scheme, Regina (Rexx), and Java JDK 1.3. Databases include MySQL, Postgres, DB2 UDB, and DB2 Connect. Middleware includes Websphere 3.5, MQ Client, Tivoli, and Apache. Some distributions support Linux kernel 2.4, HiperSockets support, Logical Volume Manager, and journaling filesystem ReiserFS. A downloadable 64-bit kernel is available for beta testing. For a Web page detailing available applications, see:

ibm.com/servers/eserver/zseries/solutions/s390da/linuxproduct.html

For additional information on areas of porting specific to Linux on S/390 and Linux on zSeries, see:

ibm.comwww.ibm.com/developerworks/eserver/articles/linux_s390/

ibm.com/servers/eserver/zseries/os/linux

xSeries

Almost all the Linux distributions (RedHat, Caldera, Mandrake, SuSE, Debian, TurboLinux, and so on) are being supported on the Intel platform. However, Linux on the Intel desktop has not met with much success whereas it has carved a niche in the server market.

IBM e-Business Hosting is adding Red Hat Linux 6.2 to its suite of supported operating systems for the server hardware. This new offering consists of a base service element and a set of additional value added, rate card elements that customers can choose from to enable, manage, monitor, and secure their Linux eBusiness servers. The offering for the server environment is as follows:

  • Operating system: Red Hat Linux 6.2
  • Supported server hardware: IBM Netfinity Models 3500, 4500, 5000, 5100, 5500, 5600, 6000R, 7000, 7100
  • Availability monitoring services: Ping and URL monitoring
  • Management services: In-depth monitoring capabilities and enhanced event filtering at the source will provide reactive and proactive monitoring and intelligent alert notifications. An optional console will provide a graphical representation of the customer's application environment across all servers in real time mode for an overall holistic end-to-end view. Visual alert notifications capture "point in time" data, and an event viewer assists the end user with quick problem determination and resolution. There is also short term historical reporting for trending analysis. You can customize all views and save them from session to session.
  • Security services: Weekly vulnerability scans of approximately 2,500 of the most commonly used services and popular backdoor ports on managed servers target IP-address using the NSA scanner. Services are performed through the Internet for devices with Internet addresses. The scanning service will be configured (filtered) according to the security controls defined by IBM and will flag vulnerabilities. The security assessment team will review the scan to ensure that jobs executed properly. Reports are provided to the IBM site manager (or to designated support personnel) for review so that they can take appropriate action.
  • Backup and Restore Services: Implements processes to provide backups and restores of customer data in a managed shared data environment. Provisions will also be made for dedicated backup and restore resources, based on customer requirements. Additional Band R services include Offsite Storage, Storage Assist, Dedicated B and R services, and Library Portioning.

For additional information on Linux for the xSeries, see:

ibm.com/servers/eserver/linux/xseries/



Resources

Learn
  • Want more? The developerWorks eServer™ zone hosts hundreds of informative articles and introductory, intermediate, and advanced tutorials on the eServer brand.

  • The IBM developerWorks team hosts hundreds of technical briefings around the world which you can attend at no charge.

Discuss


About the authors

Lee Cheng currently works as a Senior Consultant for pSeries and AIX software vendors. She provides support to them in the areas of application benchmarks, performance tuning, application porting, and internationalization. Before joining the RS/6000 ISV Technical Support group, she was a developer for compilers and the AIX system management component. She holds an MS in Computer Science from the University of Kentucky. Lee can be reached at chenglc@us.ibm.com.


Wayne Huang is a Senior Solutions Enablement Architect with a focus on e-business and server system OS cross-industry support. He provides IBM middleware and pSeries UNIX expertise to ISVs and developers in the areas of application design, problem determination, system performance tuning, and application benchmarks. He holds a Master of Science degree in Computer Science from the University of Texas at Austin. You can reach him at huangw@us.ibm.com.


Paul Sutera is a programmer who has worked in the area of evaluating and porting applications to the IBM zSeries mainframe since 1995. His current assignment involves helping customers and vendors with building and deploying applications and other packages to Linux on zSeries and z/OS Unix System Services. He has been a programmer with IBM since 1984. You can contact him at psutera@us.ibm.com.


Nam Keung works as a Senior Programmer at IBM. Nam works in the area of AIX communication development, AIX multimedia, SOM/DSOM development, and Java performance. His current assignment involves helping Independent Software Vendors (ISVs) in application design, deploying applications, performance tuning, and education for the pSeries platform. You can contact Nam at namkeung@us.ibm.com.




Rate this page


Please take a moment to complete this form to help us better serve you.



YesNoDon't know
 


 


12345
Not
useful
Extremely
useful
 


Back to top