Porting revision 256281
1Instructions for porting top to other architectures. 2 3This is still a preliminary document. Suggestions for improvement are 4most welcome. 5 6My address is now "wnl@groupsys.com". 7 8Before you embark on a port, please send me a mail message telling me 9what platform you are porting top to. There are three reasons for 10this: (1) I may already have a port, (2) module naming needs to be 11centralized, (3) I want to loosely track the various porting efforts. 12You do not need to wait for an "okay", but I do want to know that you 13are working on it. And of course, once it is finished, please send me 14the module files so that I can add them to the main distribution! 15 16---------- 17 18There is one set of functions which extract all the information that 19top needs for display. These functions are collected in to one file. 20To make top work on a different architecture simply requires a 21different implementation of these functions. The functions for a 22given architecture "foo" are stored in a file called "m_foo.c". The 23Configure script looks for these files and lets the configurer choose 24one of them. This file is called a "module". The idea is that making 25top work on a different machine only requires one additional file and 26does not require changes to any existing files. 27 28A module template is included in the distribution, called "m-template". 29To write your own module, it is a good idea to start with this template. 30If you architecture is similar to one for which a module already 31exists, then you can start with that module instead. If you do so, 32remember to change the "AUTHOR" section at the top! 33 34The first comment in a module contains information which is extracted 35and used by Configure. This information is marked with words in all 36capitals (such as "SYNOPSIS:" and "LIBS:"). Go look at m-template: it 37is fairly self-explanatory. The text after "LIBS:" (on the same line) 38is extracted and included in the LIBS definition of the Makefile so 39that extra libraries which may be necessary on some machines (such as 40"-lkvm") can be specified in the module. The text after "CFLAGS:" 41(on the same line) is extracted and included as flags in the "CFLAGS" 42definition of the Makefile (thus in every compilation step). This is 43used for rare circumstances only: please don't abuse this hook. 44 45Some operating systems have idiosyncrasies which will affect the form 46and/or content of the information top displays. You may wish to 47document such anomalies in the top man page. This can be done by adding 48a file called m_{modulename}.man (where {modulename} is replaced with 49the name of the module). Configure will automatically add this file to 50the end of the man page. See m_sunos4.man for an example. 51 52A module is concerned with two structures: 53 54The statics struct is filled in by machine_init. Each item is a 55pointer to a list of character pointers. The list is terminated 56with a null pointer. 57 58struct statics 59{ 60 char **procstate_names; /* process state names */ 61 char **cpustate_names; /* cpu state names */ 62 char **memory_names; /* memory information names */ 63}; 64 65The system_info struct is filled in by get_system_info and 66get_process_info. 67 68struct system_info 69{ 70 int last_pid; /* last pid assigned (0 means non-sequential assignment) */ 71 double load_avg[NUM_AVERAGES]; /* see below */ 72 int p_total; /* total number of processes */ 73 int p_active; /* number of procs considered "active" */ 74 int *procstates; /* array of process state counters */ 75 int *cpustates; /* array of cpustate counters */ 76 int *memory; /* memory information */ 77}; 78 79The last three pointers each point to an array of integers. The 80length of the array is determined by the length of the corresponding 81_names array in the statics structure. Furthermore, if an entry in a 82_names array is the empty string ("") then the corresponding value in 83the value array will be skipped over. The display routine displays, 84for example, the string procstate_names[0] then the number 85procstates[0], then procstate_names[1], procstates[1], etc. until 86procstate_names[N] == NULL. This allows for a tremendous amount of 87flexibility in labeling the displayed values. 88 89"procstates" and "memory" are displayed as straight integer values. 90Values in "cpustates" are displayed as a percentage * 10. For 91example, the (integer) value 105 is displayed as 10.5%. 92 93These routines must be defined by the machine dependent module. 94 95int machine_init(struct statics *) 96 97 returns 0 on success and -1 on failure, 98 prints error messages 99 100char *format_header(char *) 101 102 Returns a string which should be used as the header for the 103 process display area. The argument is a string used to label 104 the username column (either "USERNAME" or "UID") and is always 105 8 characters in length. 106 107void get_system_info(struct system_info *) 108 109caddr_t get_process_info(struct system_info *, int, int, int (*func)()) 110 111 returns a handle to use with format_next_process 112 113char *format_next_process(caddr_t, char *(*func)()) 114 115 returns string which describes next process 116 117int proc_compare(caddr_t, caddr_t) 118 119 qsort comparison function 120 121uid_t proc_owner(pid_t) 122 123 Returns the uid owner of the process specified by the pid argument. 124 This function is VERY IMPORTANT. If it fails to do its job, then 125 top may pose a security risk. 126 127 128get_process_info is called immediately after get_system_info. In 129fact, the two functions could be rolled in to one. The reason they 130are not is mostly historical. 131 132Top relies on the existence of a function called "setpriority" to 133change a process's priority. This exists as a kernel call on most 4.3 134BSD derived Unixes. If neither your operating system nor your C 135library supplies such a function, then you will need to add one to the 136module. It is defined as follows: 137 138 int setpriority (int dummy, int who, int niceval) 139 140 For the purposes of top, the first argument is meaningless. 141 The second is the pid and the third is the new nice value. 142 This function should behave just like a kernel call, setting 143 errno and returning -1 in case of an error. This function MUST 144 check to make sure that a non-root user does not specify a nice 145 value less than the process's current value. If it detects such 146 a condition, it should set errno to EACCES and return -1. 147 Other possible ERRNO values: ESRCH when pid "who" does not exist, 148 EPERM when the invoker is not root and not the same as the 149 process owner. 150 151Note that top checks process ownership and should never call setpriority 152when the invoker's uid is not root and not the same as the process's owner 153uid. 154 155 156The file "machine.h" contains definitions which are useful to modules 157and to top.c (such as the structure definitions). You SHOULD NOT need 158to change it when porting to a new platform. 159 160Porting to a new platform should NOT require any changes to existing 161files. You should only need to add m_ files. If you feel you need a 162change in one of the existing files, please contact me so that we can 163discuss the details. I want to keep such changes as general as 164possible. 165 166