- 论坛徽章:
- 0
|
这里以系统调用sethostname()为例子.
C库中
int sethostname(const char *name ,size_t len)
{
save %sp, -104, %sp
st %i0, [%fp + 0x44]
st %i1, [%fp + 0x48]
ld [%fp + 0x44], %o0 /* 把参数放到%o0, %o1 传下去... */
ld [%fp + 0x48], %o1
mov 0x58, %g1 /* 系统调用号保存到%g1 */
ta 0x10 /* 系统调用的trap号为0x90, ta指令规定会将128 + 参 数写入tbr,所以这里是ta 0x10 */
bcs error /* 如果C 被置起, 跳转 */
mov %o0, %g1 /* 取得返回值 */
mov %g1, %i0 /* 返回给调用者 */
ret
restore
}
系统调用其实就是一种trap. 对应为tbr中tt = 0x90的位置
head.S中,将tbr的0x90处,放了LINUX_SYSCALL_TRAP
#define LINUX_SYSCALL_TRAP \
43 sethi %hi(sys_call_table), %l7; \
44 or %l7, %lo(sys_call_table), %l7; \ /* 把系统调用表的地址放入%l7中 */
45 b linux_sparc_syscall; \
46 rd %psr, %l0;
47
从而跳到entry.S中的
linux_sparc_syscall:
/* Linux native system calls enter here... */
1312 .align 4
1313 .globl linux_sparc_syscall
1314linux_sparc_syscall:
1315 sethi %hi(PSR_SYSCALL), %l4 /* 0x00004000的高20位 -> %l4 . %l4 = 0x00004*/
1316 or %l0, %l4, %l0 /* 进入trap时, %l0硬件自动设为%pc, %l1设为%npc */
/* 把%pc的最低位置1 */
1317 /* Direct access to user regs, must faster. */
1318 cmp %g1, NR_SYSCALLS /* 看系统调用号是否越界 */
1319 bgeu linux_sparc_ni_syscall /* 是..调..这里不管.. */
1320 sll %g1, 2, %l4 /* %g1 %l4, ld [%l7 + %l4], %l7. 这里是取sys_sethostname()的地址到%l7
因为sys_table的表是.long对齐的.所以要左移两位 */
1321 ld [%l7 + %l4], %l7
1322 andcc %l7, 1, %g0 /* 如果%l7的最低位为1话,设置c标记为1 */
1323 bne linux_fast_syscall /*
1324 /* Just do first insn from SAVE_ALL in the delay slot */
1325
1326syscall_is_too_hard:
1327 SAVE_ALL_HEAD
1328 rd %wim, %l3
1329
1330 wr %l0, PSR_ET, %psr
1331 mov %i0, %o0
1332 mov %i1, %o1
1333 mov %i2, %o2
1334
1335 ld [%curptr + TI_FLAGS], %l5
1336 mov %i3, %o3
1337 andcc %l5, _TIF_SYSCALL_TRACE, %g0
1338 mov %i4, %o4
1339 bne linux_syscall_trace
1340 mov %i0, %l5
13412:
1342 call %l7
1343 mov %i5, %o5
1344
13453:
1346 st %o0, [%sp + STACKFRAME_SZ + PT_I0]
本文来自ChinaUnix博客,如果查看原文请点:http://blog.chinaunix.net/u/17526/showart_1716389.html |
|