2010$BG/(B12$B7n(B07$BF|(B
$B>pJs2J3XN`(B $B%*%Z%l!<%F%#%s%0%7%9%F%`(B II
$BC^GHBg3X(B $B%7%9%F%`>pJs9)3X8&5f2J(B
$B%3%s%T%e!<%?%5%$%(%s%9@l96(B, $BEE;R!&>pJs9)3X7O(B
$B?7>k(B $BLw(B
<yas@is.tsukuba.ac.jp>
$B$3$N%Z!<%8$O!"
http://www.coins.tsukuba.ac.jp/~yas/coins/os2-2010/2010-12-07
$B$"$k$$$O!"
http://www.coins.tsukuba.ac.jp/~yas/
http://www.cs.tsukuba.ac.jp/~yas/
Robert Love: "Linux Kernel Development", Addison-Wesley Professional (2010). ISBN-13: 9780672329463
Claudia Salzberg Rodriguez, Gordon Fischer, and Steven Smolski: "The Linux Kernel Primer: A Top-Down Approach for x86 and PowerPC Architectures", Prentice Hall (2005). ISBN-10: 0131181637
Daniel P. Bovet, Marco Cesati $BCx(B, $B9b66(B $B9@OB(B ($B4FLu(B), $B?yED(B $BM3H~;R(B, $B@6?e(B $B@5L@(B , $B9b?y(B $B>;FD(B , $BJ?>>(B $B2mL&(B , $B0B0f(B $BN49((B($BLu(B) $B>\2r(B Linux$B%+!<%M%k(B $BBh(B3$BHG(B $B%*%i%$%j!
Jonathan Corbet, Alessandro Rubini, Greg Kroah-Hartman ($BCx(B), $B;3:j(B $B9/9((B , $B;3:j(B $BK.;R(B , $BD986(B $B9(<#(B , $BD986(B $BM[;R(B($BLu(B): "Linux$B%G%P%$%9%I%i%$%P(B", $B%*%i%$%j!<%8%c%Q%s(B (2005). ISBN-13: 978-4873112534
$ ls -l hello.rb
-rw-r--r-- 1 yas prof 26 Dec 7 06:35 hello.rb
$ cat hello.rb
printf("hello, world!\n")
$ ruby hello.rb
hello, world!
$
Ruby $B8@8l$N%$%s%?%W%j%?<+?H$O!"(BC $B8@8l$G5-=R$5$l$F$$$k!#(B
$B?^(B? $B%a%?%l%Y%k$N%W%m%0%i%_%s%0(B
$B%W%m%0%i%`!V(Bhello.rb$B!W$NF0$-$rJQ99$9$kJ}K!(B
$ ls -l hello.c
-rw-r--r-- 1 yas prof 44 Dec 7 06:25 hello.c
$ cat hello.c
main()
{
printf("hello, %s!\n","world");
}
$ cc hello.c -o hello
$ ./hello
hello, world!
$
$B?^(B? $B%a%?%l%Y%k$N%W%m%0%i%`$H$7$F$N(BOS$B%+!<%M%k(B
$B%W%m%0%i%`!V(Bhello.c$B!W$NF0$-$rJQ99$9$kJ}K!(B
OS$B%+!<%M%k<+?H$O!"IaDL$O!"%O!<%I%&%'%"$K$h$k%$%s%?%W%j%?(B(CPU$B!"F~=PNO(B)$B$G(B
$B
OS$B%+!<%M%k$X$N%$%s%?%U%'!<%9$O!"%7%9%F%`!&%3!<%k!#(B
== OS$B%+!<%M%k$O!"%7%9%F%`!&%3!<%k$N%$%s%?%W%j%?!#(B
$B"!%7%i%P%9(B
$B"!(BLinux
$B65:`$H$7$F$O!"(BLinux $B$r;H$&!#(B
2010$BG/(B12$B7n8=:_!"3XN`$G$O
$B?^(B? OS$B$N9=B$(B
$B%W%m%0%i%`!&%3!<%I$N>l=j(B$B%7%9%F%`%3!<%k$NNc!'(B
$B%7%9%F%`%3!<%k$H%i%$%V%i%j$N8+J,$1J}!J(BUnix$BJT!K(B
$BF1$8(BUnix$B7O(BOS$B$G$b!":Y$+$$=j$G%7%9%F%`!&%3!<%k$H%i%$%V%i%j$,F~$lBX$o$C$F(B $B$$$k$3$H$b$"$k!#(B
$B%7%9%F%`!&%3!<%k$O!"%H%i%C%WL?Na!J(Btrap instruction$B!K$r4^$`!#(B $B$=$NItJ,$O!"%"%;%s%V%j8@8l!#(B
$B%i%$%V%i%j4X?t$O!"BgItJ,$O#C8@8l$G=q$+$l$F$$$k!#(B printf() $B$N%=!<%9!&%W%m%0%i%`$,$"$k!#(B
$B#C8@8l$G5-=R$7$?%W%m%0%i%`$O!"J8K!$5$($"$C$F$$$l$P(B $B%3%s%Q%$%k$O$G$-$k!#(B $B%i%$%V%i%j4X?t$d%7%9%F%`%3!<%k$,$J$$$HF0:n$7$J$$!#(B
$BF0E*%j%s%/$r9T$&;~$K$O!"6&M-%i%$%V%i%j(B(shared library) $B$r;H$$!"%a%b%j$N@aLs$r$9$k!#(B
Microsoft Windows $B$G$O!"%7%9%F%`%3!<%k$H%i%$%V%i%j$N6hJL$,4uGv!#(B Win32 API$B!#(B3000$B0J>e!#(B Unix $B$N%7%9%F%`%3!<%k$O!"(B300$BDxEY!#(B
main()
{
printf("hello, %s!\n","world");
}
$ ls hello*
hello.c
$ make hello
cc hello.c -o hello
hello.c: In function 'main':
hello.c:3: warning: incompatible implicit declaration of built-in function 'printf'
$ ./hello
hello, world!
$ gcc -S hello.c
hello.c: In function 'main':
hello.c:3: warning: incompatible implicit declaration of built-in function 'printf'
$ ls hello*
hello hello.c hello.s
$
gcc -S file.c$B!W$G!"DL>o$O:o=|$5$l$k%"%;%s%V%j8@8l$N=PNO$,(B
$B;D$5$l$k!#(B
.file "hello.c" .section .rodata .LC0: .string "world" .LC1: .string "hello, %s!\n" .text .globl main .type main, @function main: leal 4(%esp), %ecx andl $-16, %esp pushl -4(%ecx) pushl %ebp movl %esp, %ebp pushl %ecx subl $20, %esp movl $.LC0, 4(%esp) movl $.LC1, (%esp) call printf addl $20, %esp popl %ecx popl %ebp leal -4(%ecx), %esp ret .size main, .-main .ident "GCC: (GNU) 4.1.2 20080704 (Red Hat 4.1.2-48)" .section .note.GNU-stack,"",@progbits
$B!c>JN,!d(B
28: int
29: __printf (const char *format, ...)
30: {
31: va_list arg;
32: int done;
33:
34: va_start (arg, format);
35: done = vfprintf (stdout, format, arg);
36: va_end (arg);
37:
38: return done;
39: }
$B!c>JN,!d(B
42: ldbl_strong_alias (__printf, printf);
PRINTF(3) Linux Programmer's Manual PRINTF(3)
NAME
printf, fprintf, sprintf, snprintf, vprintf, vfprintf, vsprintf,
vsnprintf - formatted output conversion
SYNOPSIS
...
int printf(const char *format, ...);
int fprintf(FILE *stream, const char *format, ...);
...
int vfprintf(FILE *stream, const char *format, va_list ap);
...
DESCRIPTION
...
The functions vprintf(), vfprintf(), vsprintf(), vsnprintf() are equiv-
alent to the functions printf(), fprintf(), sprintf(), snprintf(),
respectively, except that they are called with a va_list instead of a
variable number of arguments. These functions do not call the va_end
macro. Consequently, the value of ap is undefined after the call. The
application should call va_end(ap) itself afterwards.
...
WRITE(2) Linux Programmer's Manual WRITE(2)
NAME
write - write to a file descriptor
SYNOPSIS
#include <unistd.h>
ssize_t write(int fd, const void *buf, size_t count);
DESCRIPTION
write() writes up to count bytes to the file referenced by the file
descriptor fd from the buffer starting at buf. POSIX requires that a
read() which can be proved to occur after a write() has returned
returns the new data. Note that not all file systems are POSIX con-
forming.
RETURN VALUE
On success, the number of bytes written are returned (zero indicates
nothing was written). On error, -1 is returned, and errno is set
appropriately. If count is zero and the file descriptor refers to a
regular file, 0 may be returned, or an error could be detected. For a
special file, the results are not portable.
ERRORS
EAGAIN Non-blocking I/O has been selected using O_NONBLOCK and the
write would block.
EBADF fd is not a valid file descriptor or is not open for writing.
...
http://kernel.org/ $B$KJ]B8$5$l$F$$$k!#(B
$BE83+$N;EJ}(B
$ bzip2 -d < linux-X.Y.Z.tar.bz2 | tar xf -
~yas/os2/linux-2.6.36/ $B$KE83+$7$?$b$N$,$"$k!#(B
| $B%G%#%l%/%H%j(B | $B@bL@(B |
|---|---|
| Documentation | $B%I%-%e%a%s%H(B |
| arch | $B%"!<%-%F%/%A%c0MB8(B |
| block | $B%V%m%C%/F~=PNOAX(B |
| crypto | $B0E9f2=(B |
| drivers | $B%G%P%$%9!&%I%i%$%P(B |
| firmware | $B%U%!!<%`%&%'%"(B |
| fs | VFS(Virtual File System)$B$H%U%!%$%k!&%7%9%F%`(B |
| include | $B%+!<%M%kMQ$N%X%C%@!&%U%!%$%k(B |
| init | $B5/F0$H=i4|2=(B(initialization) |
| ipc | $B%W%m%;%94VDL?.(B(interprocess communication) |
| kernel | $B%+!<%M%k$NCf?4ItJ,(B |
| lib | $B%X%k%Q(B |
| mm | $B%a%b%j4IM}(B(memory management) |
| net | $B%M%C%H%o!<%/(B |
| samples | $B%5%s%W%k%3!<%I(B |
| scripts | $B%+!<%M%k$N%3%s%Q%$%k$KI,MW$J%9%/%j%W%H(B |
| security | Lnux Security Module |
| sound | $B%5%&%s%I!&%5%V%7%9%F%`(B |
| tools | $B%+!<%M%k3+H/MQ$N%D!<%k(B |
| usr | $B5/F0D>8e$K%f!<%66u4V$G |
| virt | $B2>A[2=%$%s%U%i(B |
linux-2.6.36/arch/x86/include/asm/unistd_32.h
... 8: #define __NR_restart_syscall 0 9: #define __NR_exit 1 10: #define __NR_fork 2 11: #define __NR_read 3 12: #define __NR_write 4 13: #define __NR_open 5 14: #define __NR_close 6 15: #define __NR_waitpid 7 16: #define __NR_creat 8 17: #define __NR_link 9 18: #define __NR_unlink 10 19: #define __NR_execve 11 20: #define __NR_chdir 12 ... 346: #define __NR_fanotify_init 338 347: #define __NR_fanotify_mark 339 348: #define __NR_prlimit64 340 ... 352: #define NR_syscalls 341 ...
1: ENTRY(sys_call_table) 2: .long sys_restart_syscall /* 0 - old "setup()" system call, used for restarting */ 3: .long sys_exit 4: .long ptregs_fork 5: .long sys_read 6: .long sys_write 7: .long sys_open /* 5 */ 8: .long sys_close 9: .long sys_waitpid 10: .long sys_creat 11: .long sys_link 12: .long sys_unlink /* 10 */ ... 340: .long sys_fanotify_init 341: .long sys_fanotify_mark 342: .long sys_prlimit64 /* 340 */
sys_ $B$G;O$^$k!#(B
$B%f!<%66u4V$N%7%9%F%`!&%3!<%k$HJ6$l$J$$$h$&$K$9$k$?$a!#(B
$BNc(B: $B%f!<%6$N(B write() $B%7%9%F%`!&%3!<%k$O!"%+!<%M%kFb$N(B
sys_write() $B$H$$$&4X?t$G=hM}$5$l$k!#(B
408: SYSCALL_DEFINE3(write, unsigned int, fd, const char __user *, buf,
409: size_t, count)
410: {
411: struct file *file;
412: ssize_t ret = -EBADF;
413: int fput_needed;
414:
415: file = fget_light(fd, &fput_needed);
416: if (file) {
417: loff_t pos = file_pos_read(file);
418: ret = vfs_write(file, buf, count, &pos);
419: file_pos_write(file, pos);
420: fput_light(file, fput_needed);
421: }
422:
423: return ret;
424: }
$B$3$NDj5A$O!"0J2<$N$h$&$KE83+$5$l$k!#(B
asmlinkage long sys_write(unsigned int fd, const char __user *buf,
size_t count)
{
$B>JN,(B
}
E $B$G;O(B
$B$^$kL>A0!J%^%/%m!K$,IU$1$i$l$F$$$k!#(B
$BDj5A$O!"(B
<errno.h> (include/asm-generic/errno-base.h) $BEy$K4^$^$l$F$$(B
$B$k!#(B
sys_xxx() $B$O!"@.8y$9$k$H(B
$B@5$NCM$rJV$9!#(B
$B%(%i!<$,H/@8$9$k$H!"%+!<%M%kFb$G$O!"%(%i!<(B
$BHV9f$rIi$NCM$K$7$?$b$N$rJV$9!#(B
... 4: #define EPERM 1 /* Operation not permitted */ 5: #define ENOENT 2 /* No such file or directory */ 6: #define ESRCH 3 /* No such process */ 7: #define EINTR 4 /* Interrupted system call */ 8: #define EIO 5 /* I/O error */ 9: #define ENXIO 6 /* No such device or address */ 10: #define E2BIG 7 /* Argument list too long */ 11: #define ENOEXEC 8 /* Exec format error */ 12: #define EBADF 9 /* Bad file number */ 13: #define ECHILD 10 /* No child processes */ ...
188: #define SYSCALL_DEFINE0(name) asmlinkage long sys_##name(void) ... 191: #define SYSCALL_DEFINE1(name, ...) SYSCALL_DEFINEx(1, _##name, __VA_ARGS__) 192: #define SYSCALL_DEFINE2(name, ...) SYSCALL_DEFINEx(2, _##name, __VA_ARGS__) 193: #define SYSCALL_DEFINE3(name, ...) SYSCALL_DEFINEx(3, _##name, __VA_ARGS__) 194: #define SYSCALL_DEFINE4(name, ...) SYSCALL_DEFINEx(4, _##name, __VA_ARGS__) 195: #define SYSCALL_DEFINE5(name, ...) SYSCALL_DEFINEx(5, _##name, __VA_ARGS__) 196: #define SYSCALL_DEFINE6(name, ...) SYSCALL_DEFINEx(6, _##name, __VA_ARGS__) ... 223: #define SYSCALL_DEFINEx(x, sname, ...) \ 224: __SYSCALL_DEFINEx(x, sname, __VA_ARGS__) ... 245: #define __SYSCALL_DEFINEx(x, name, ...) \ 246: asmlinkage long sys##name(__SC_DECL##x(__VA_ARGS__))
sys_$B!W(B $B$H$$$&%W%l%U%#%C%/%9$,IU$1$i$l$k!#(B
$B!V(B##$B!W(B $B$O!"(BC$B%W%j%W%m%;%C%5$NL?Na$G!"J8;zNs$N7k9g$r0UL#$9$k!#(B
$B?^(B? hello world $B%W%m%0%i%`$G$N%7%9%F%`!&%3!<%k$N
$ strace ./hello
execve("./hello", ["./hello"], [/* 38 vars */]) = 0
brk(0) = 0x83a3000
access("/etc/ld.so.preload", R_OK) = -1 ENOENT (No such file or directory)
open("/etc/ld.so.cache", O_RDONLY) = 3
fstat64(3, {st_mode=S_IFREG|0644, st_size=169180, ...}) = 0
mmap2(NULL, 169180, PROT_READ, MAP_PRIVATE, 3, 0) = 0xb7f67000
close(3) = 0
open("/lib/libc.so.6", O_RDONLY) = 3
read(3, "\177ELF\1\1\1\0\0\0\0\0\0\0\0\0\3\0\3\0\1\0\0\0\340_\222\0004\0\0\0"..., 512) = 512
fstat64(3, {st_mode=S_IFREG|0755, st_size=1689640, ...}) = 0
mmap2(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xb7f66000
mmap2(0x910000, 1410500, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0x910000
mmap2(0xa63000, 12288, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x152) = 0xa63000
mmap2(0xa66000, 9668, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0xa66000
close(3) = 0
mmap2(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xb7f65000
set_thread_area({entry_number:-1 -> 6, base_addr:0xb7f656c0, limit:1048575, seg_32bit:1, contents:0, read_exec_only:0, limit_in_pages:1, seg_not_present:0, useable:1}) = 0
mprotect(0xa63000, 8192, PROT_READ) = 0
mprotect(0x83d000, 4096, PROT_READ) = 0
munmap(0xb7f67000, 169180) = 0
fstat64(1, {st_mode=S_IFCHR|0620, st_rdev=makedev(136, 1), ...}) = 0
mmap2(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xb7f90000
write(1, "hello, world!\n", 14hello, world!
) = 14
exit_group(14) = ?
$
$ ./hello
hello, world!
$ ltrace ./hello
__libc_start_main(0x80483a4, 1, 0xbf8d3764, 0x80483f0, 0x80483e0
printf("hello, %s!\n", "world"hello, world!
) = 14
+++ exited (status 14) +++
$
$ gdb hello
$B>JN,(B
(gdb) b main
# $B%V%l!<%/%]%$%s%H$N@_Dj(B
Breakpoint 1 at 0x80483b2
(gdb) r
# $BJN,(B/hello
Breakpoint 1, 0x080483b2 in main ()
(gdb) b write
# $B%V%l!<%/%]%$%s%H$N@_Dj(B
Breakpoint 2 at 0x9d2b80
(gdb) c
# $Bbt
# $B%P%C%/%H%l!<%9(B
#0 0x009d2b80 in write () from /lib/libc.so.6
$B>JN,(B
#6 0x0094c271 in vfprintf () from /lib/libc.so.6
#7 0x00955e83 in printf () from /lib/libc.so.6
#8 0x080483c9 in main ()
(gdb) c
# $B
$B"!$=$NB>$N%W%m%;%9$rD4$Y$k%3%^%s%I(B
- ktrace (FreeBSD, MacOSX 10.4)
- dtrace, dtruss (Solaris, MacOSX 10.5$B0J9_(B)
- truss (Solaris, System V Unix)
$B"#%/%$%:(B1
$B%7%9%F%`%3!<%k$H(BLinux$B%+!<%M%k$N%=!<%9(B
$B!zLdBj(B(101) $B%7%9%F%`!&%3!<%k$H%i%$%V%i%j4X?t$N6&DLE@(B
C$B8@8l$G%W%m%0%i%`$r:n@.$9$k>l9g!"%7%9%F%`!&%3!<%k$H%i%$%V%i%j4X?t$N6&DL(B
$BE@$r=R$Y$J$5$$!#(B
$B!zLdBj(B(102) $B%7%9%F%`!&%3!<%k$H%i%$%V%i%j4X?t$NAj0cE@(B
$B%7%9%F%`!&%3!<%k$H%i%$%V%i%j4X?t$NAj0cE@$r=R$Y$J$5$$!#(B
$B!zLdBj(B(103) close()$B%7%9%F%`%3!<%k$N0z?t$H7k2L(B
close() $B%7%9%F%`!&%3!<%k$N%^%K%e%"%k$K$O!"
CLOSE(2) Linux Programmer's Manual CLOSE(2)
NAME
close - close a file descriptor
SYNOPSIS
#include <unistd.h>
int close(int fd);
DESCRIPTION
close() closes a file descriptor, so that it no longer refers to any
file and may be reused. Any record locks (see fcntl(2)) held on the
file it was associated with, and owned by the process, are removed
(regardless of the file descriptor that was used to obtain the lock).
...
$B$3$N%7%9%F%`!&%3!<%k$r=hM}$9$k4X?t$,%+!<%M%k$NCf$G$I$N$h$&$KDj5A$5$l$F(B
$B$$$k$+!"$=$N35N,(B($B0z?t$H7k2L$N@k8@(B)$B$r<($7$J$5$$!#4X?t$NFbMF$O6u$G$h$$!#(B
$B%^%/%m$rMxMQ$7$F$bMxMQ$7$J$/$F$b$I$A$i$G$b$h$$!#(B
$B0z?t$H7k2L$N@k8@(B
{
/*$BFbMF(B*/
}