uadmin 55
schrock 56
utssys 57
fdsync 58
注:
15. 第4步,需要在/etc/name_to_sysnum里添加一个相应的系统调用号。其实这时主要的工作已完成,已能够写一个应用程式调用执行新的系 统调用了,但这个教程实际上是要讲述集成一个系统调用所需做的任何步骤,当然也就不能忽略这些细节了。
16. /etc/name_to_sysnum实际上是为dtrace(1M)和truss(1)之类的程式提供了一个系统调用名字和系统调用号之间的影射关 系。在这里,需要修改Intel和SPARC两 个版本的文档。
5. truss(1)
Truss does fancy decoding of system call arguments. In order to do this, we need to maintain a table in truss that describes the type of each argument for every syscall. This table is found in systable.c. Since our syscall takes a single string, we add the following entry:
{"ioctl", 3, DEC, NOV, DEC, IOC, IOA}, /* 54 */
{"uadmin", 3, DEC, NOV, DEC, DEC, DEC}, /* 55 */
{"schrock", 1, DEC, NOV, STG}, /* 56 */
{"utssys", 4, DEC, NOV, HEX, DEC, UTS, HEX}, /* 57 */
{"fdsync", 2, DEC, NOV, DEC, FFG}, /* 58 */
Don't worry too much about the different constants. But be sure to
read up(攻读)
on the truss source code if you're adding a complicated system call.
注:
17. 第5步,为了让truss(1)命令能够解释出新加的系统调用的参数,需要在systable.c文
件中的systable中
增加一条相应的记录。
18. systable实
际上是truss(1)维护的一个表结构,用来描述系统调用的入口参数个数,返回值和入口参数的输出表示形式,其定义如下:
const struct systable systable[] = {
{ NULL, 8, HEX, HEX, HEX, HEX, HEX, HEX, HEX, HEX, HEX, HEX},
{"_exit", 1, DEC, NOV, DEC}, /* 1 */
{"forkall", 0, DEC, NOV}, /* 2 */
{"read", 3, DEC, NOV, DEC, IOB, UNS}, /* 3 */
{"write", 3, DEC, NOV, DEC, IOB, UNS}, /* 4 */
{"open", 3, DEC, NOV, STG, OPN, OCT}, /* 5 */
..............
{"cladm", 3, DEC, NOV, CLC, CLF, HEX}, /* 253 */
{ NULL, 8, HEX, HEX, HEX, HEX, HEX, HEX, HEX, HEX, HEX, HEX},
{"umount2", 2, DEC, NOV, STG, MTF}, /* 255 */
{ NULL, -1, DEC, NOV},
};
能够看到,其中每一行实际上对应一个系统调用的描述,对应着结构体systable,
其定义如下:
struct systable {
const char *name; /* name of system call */
short nargs; /* number of arguments */
char rval[2]; /* return value types */
char arg[8]; /* argument types */
};
所以systable这
张表每行的第1个值对应调用名,第2个对应参数个数,第3,4对应返回值的描述,剩下8个值对应调用的入口参数描述。通过这样的描述,truss(1)就
知道每个系统调用的入口参数和返回值格式,并正确的输出了,新增的系统调用对应的记录为:
{"schrock", 1, DEC, NOV, STG}, /* 56 */
如前所述,再结合print.h中 对DEC,NOV,STG的定义,就知道这一行的含义了。
6. proc_names.c
This is the file that gets missed the most often when adding a new syscall. Libproc uses the table in proc_names.c to translate between system call numbers and names. Why it doesn't make use of /etc/name_to_sysnum is anybody's guess, but for now you have to update the systable array in this file:
"ioctl", /* 54 */
"uadmin", /* 55 */
"schrock", /* 56 */
"utssys", /* 57 */
"fdsync", /* 58 */
注:
19. 第6步,为确保Libproc能正确识别新加的系统调用,需要在proc_names.c增加对应的行,这一步是经常容易被遗漏的。至于Libproc为何不用/etc/name_to_sysnum而另外定义一个系统调用名和调用号的影射关系,恐怕只有作者知道了。
20. Libproc是Solaris提供的一组访问proc文档系统的接口,proc(1)中介绍的一组命令使用了这组接口。这组接口位于libproc.so动态链接库,关于proc文档系统,能够参考proc(4)。
7. Putting it all together
Finally, everything is in place. We can test our system call with a simple program:
#include <sys/syscall.h>
int
main(int argc, char **argv)
{
syscall(SYS_schrock, "OpenSolaris Rules!");
return (0);
}
If we run this on our system, we'll see the following output on the console:
June 14 13:42:21 halcyon genunix: WARNING: OpenSolaris Rules!
Because we did all the extra work, we can actually observe the behavior using truss(1), mdb(1), or dtrace(1M)
文章整理:西部数码--专业提供域名注册、虚拟主机服务
http://www.west263.com
以上信息与文章正文是不可分割的一部分,如果您要转载本文章,请保留以上信息,谢谢!




