....................................................................................................................... 3
1. Linux..................................................................................................... 7
1.1. Linux...................................................................................7
1.1.1. Linux Unix....................... 8
1.1.2. ........................10
1.1.3. ..................................................................11
1.1.4. .............................................................................................12
1.2. ..............................................................................................................14
1.2.1. .............................................................................................. 14
1.2.2. ...............................................................................17
1.2.3. .............................................................18
1.2.4. diff patch................................................................................ 21
1.3. ............................................................................................. 22
2. Linux................................................................................ 24
2.1. ......................................................................................... 24
2.1.1. Linux.....................................................................24
2.1.2. ..................................................... 28
2.2. Linux........................................................................ 31
2.2.1. .....................................................................................31
2.2.2. .......................................................33
2.2.3. ......................................................................... 37
2.3. ......................................................................................................... 40
2.3.1. Linux.....................................................................................40
2.3.2. .......................................................... 47
2.3.3. ........................................................... 51
2.4. (VFS)..........................................................55
2.4.1. VFS...................................................................................... 55
2.4.2. .................................................................. 62
2.5. procfs................................................................................ 73
2.5.1. /proc/........................................................................................... 73
2.5.2. procfs..........................................................................................75
2.6. ............................................................................................. 80
.................................................................................................................82
....................................................................... 84
, ,
Windows Microsoft. ,
, Windows
. , 60-
XX , ,
,
. , , Unix,
. Unix
. ,
,
, .
, . [17]
,
Linux?
:
1. .
, Unix
.
Lions' Commentary on Unix ( 1977 ),
, Unix.
. , Unix
,
,
. [17]
, ,
,
, ,
.
. [3]
2. .
. , ,
.
. ,
.
, C, Cobol
4
Fortran, ,
.
, ,
,
. [3]
Linux .
: , ,
" , ".
, ,
,
, .
,
Linux Novell.
,
,
.
,
,
.
.
:
Linux.
,
.
1. Linux
1.1. Linux
Linux
Unix, Bell Laboratories AT&T. 1969
Unix
Linux ,
: Intel, Intel IA-64, AMD x86-64, PowerPC, Compaq Alpha, SPARC
.
Linux Unix,
Unix, API Unix ( POSIX),
Unix,
(, *BSD). , ,
Linux , ,
Unix.
Linux, Linux,
GPL. , Linux
GNU/Linux,
, GNU (GNU's Not Unix
). Linux,
, . [10, 17]
1.1.1. Linux Unix
API,
Unix .
.
,
. Unix
(MMU, Memory Management Unit);
. Linux
- Unix, ,
. Linux
Unix: [10]
8
. Linux
.
0.99 -. [8]
.
Linux
(SMP). Unix SMP,
.
Linux .
, .
Unix Solaris,
IRIX, Unix.
Linux :
.
, .
Linux Unix,
(, STREAMS).
Linux GNU C.
C ISO C99,
(
static inline), (
asm()), ( likely() unlikely()
;
) . [14]
Linux . , GNU/Linux
()
, () ,
. , , Red Hat
, Slackware
9
. [18]
Linux 2.6.18.
1.1.2.
. : [10]
C.
.
.
, , . ,
lib/string.c.
.
,
.
, .
: ,
.
, .
. ,
.
,
( )
static. [16] ,
.
10
. ,
8 32- 16 64 -.
. - , C,
.
1.1.3.
,
1.1. :
COPYING
MAINTAINERS
CREDITS
, Makefile .
1.1 Linux 2.6.18
arch
block
crypto
API
Documentation
drivers
fs
VFS
include
init
ipc
kernel
( .)
lib
mm
net
scripts
security
Linux
11
sound
usr
1.1.4.
, Linux ,
.
.
, .
.
.
.
( "Hello, world").
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/init.h>
void sayHello()
{
printk(KERN_INFO"Hello, world\n");
}
EXPORT_SYMBOL(sayHello);
static int __init hello_init(void)
{
sayHello();
return 0;
}
static void __exit hello_exit(void)
{
12
printk(KERN_INFO"Goodbye, world\n");
}
module_init(hello_init);
module_exit(hello_exit);
MODULE_LICENSE("GPL");
, static int __init.
.
, static void __exit.
printk()
( 2.6.18 8
, include/linux/kernel.h).
, /var/log/messages.
, ,
, .
linux/module.h.
linux/kernel.h printk(),
KERN_INFO. linux/init.h
__init __exit.
C EXPORT_SYMBOL()
. ,
. EXPORT_SYMBOL_GPL()
, ,
GPL. sayHello()
. MODULE_LICENSE()
, .
GPL (,
). [2, 10]
13
1.2.
1.2.1.
Linux 2.6.18.
1
Linux.
make.
linux-2.6.18.tar.bz2,
( /usr/src/)
tar (,
):
tar -C /usr/src/ -xjvf linux-2.6.18.tar.bz2
/usr/src/linux-2.6.18/:
cd /usr/src/linux-2.6.18/
make defconfig " "
. ,
make menuconfig.
make README.
, ,
IDE "Device
Drivers -> ATA/ATAPI/MFM/RLL support -> PCI IDE chipset support" (
make defconfig VIA82CXXX). "File systems"
(
ext2).
14
make. ,
make -j2. -j2
( ).
, make modules_install
/lib/modules/2.6.18/kernel/.
make -j2
make modules_install
arch/i386/boot/bzImage.
System.map , ,
. [11]
/boot/:
cp ./arch/i386/boot/bzImage /boot/vmlinuz-2.6.18
cp ./System.map /boot/System.map-2.6.18
(,
, ), ram-
. ram-
-, chroot
(, RAID).
[11] ram- mkinitrd.
mkinitrd .
Fedora Core, Mandriva:
mkinitrd /boot/initrd-2.6.18 2.6.18
openSUSE ( System.map):
mkinitrd -k /boot/vmlinuz-2.6.18 -M /boot/System.map-2.6.18 -i /boot/initrd2.6.18
man mkinitrd.
( LILO
GRUB) .
15
,
.
2.6.x.
2.4.x make. 2.4.x
2.6.x, .
Slackware
Linux,
.
( )
QEMU VMware.
: (/dev/hda1),
(/dev/hda2), ext2 (
). QEMU
( VMware) IDE: "Device Drivers
-> ATA/ATAPI/MFM/RLL support -> PCI IDE chipset support -> Intel PIIXn
chipset support".
20 .
, " ", ram
, .
mcedit .
Slackware Linux LILO.
16
hello.c. Makefile :
obj-m += hello.o
Makefile hello.c .
:
make -C /usr/src/linux-2.6.18 SUBDIRS=$PWD modules
( /usr/src/). -C make,
17
-
(
). make ,
hello.ko.
insmod < > (
insmod hello.ko).
/proc/modules. rmmod
< > (rmmod hello.ko).
.
,
sayHello().
1.2.3.
3
hello.
Linux
"kbuild". , ,
"Kernel hacking".
Kconfig*.
arch/i386/Kconfig.debug :
config MYKERNEL
bool "My kernel modules"
default y
help
This is my kernel modules
18
if MYKERNEL
config MYKERNEL_SAYHELLO
bool "sayHello() function"
default y
help
Simple function sayHello() that say "Hello, world".
endif
"Kernel hacking"
CONFIG_MYKERNEL ( Kconfig* CONFIG_).
, ,
if MYKERNEL. .config.
bool , : Y/N.
tristate , : Y/N/M.
default .
:
Y .
, , ,
,
.
M
.
N .
, ,
.
( hello.c) c Makefile kernel/hello/
. kernel/Makefile :
obj-$(CONFIG_MYKERNEL_SAYHELLO) += hello/
hello Y M,
CONFIG_MYKERNEL_SAYHELLO,
19
Y M . , M,
hello.ko make modules_install
/lib/modules/2.6.18/kernel/. ,
Makefile kernel/,
kernel/hello/ :
/lib/modules/2.6.18/kerne/kernel/hello/hello.ko
. , Fedora Core 6,
Linux 2.6.18, 2.6.18-1.2798.fc6
.
CONFIG_HELLO tristate.
:
tristate "sayHello() function"
default m
arch/i386/Kconfig.debug.
, kernel/hello/Kconfig
. arch/i386/Kconfig.debug
:
source "kernel/hello/Kconfig"
20
Kconfig*
.
Makefile',
Makefile.
EXTRAVERSION,
, uname -r ( ) 2.6.18-mykernel.
1.2.4. diff patch
(patch).
diff ,
patch. ,
: ,
. , /usr/src/.
diff :
diff -ruN linux-2.6.18/ linux-2.6.18-2/ > mykernel.patch
-r ,
.
-u
diff.
. -N , ,
, .
diff :
diff -u linux-2.6.18/file linux-2.6.18-2/file > file.patch
diff ,
. . ,
, patch
(
/usr/src/linux-2.6.18/):
patch -p1 < /usr/src/mykernel.patch
21
/usr/src/. -p1 ,
,
.
, ,
.
diffstat ,
( ).
:
diffstat -p1 /usr/src/mykernel.patch
(Linux Kernel
Mailing List, lkml). patch ,
diff, .
,
,
mykernel.patch
, , "Kernel
hacking". ,
, i386, Alpha SPARC.
i386.
"Processor type
and features -> Processor family -> 386" "Processor type and features ->
Subarchitecture type -> PC-compatible".
1.3.
1
Linux
Unix- .
1.1 ,
,
.
22
1.2
, ,
.
23
2. Linux
2.1.
2.1.1. Linux
, ,
,
, . ,
.
.
,
.
(Application Programming Interface, API).
,
, . POSIX,
WinAPI API. API
, .
, Linux FreeBSD
POSIX (Linux 100% POSIX 1003.1 [9]),
, FreeBSD,
Linux .
.
C.
, printf()
24
write(),
( ).
printf()
printf()
C
write()
C
write()
. 2.1. , C
printf()
C
API- POSIX. strace
,
( ). [10]
( Linux syscall)
long.
.
errno.
errno
perror(), , ,
.
getuid() ( kernel/timer.c),
uid :
asmlinkage long sys_getuid(void)
{
return current->uid;
}
25
asmlinkage ,
.
long. getuid() sys_getuid().
, Linux.
Linux
(syscall number).
, .
. Linux
2.6.18 318 i386 (
NR_syscalls).
include/asm/unistd.h.
include/asm-i386/unistd.h
asm/
asm-i386/.
Linux " " ("not implemented")
sys_ni_syscall(), , ,
, -ENOSYS ,
.
.
(syscall table). ,
sys_call_table. i386
( )
arch/i386/kernel/syscall_table.S. [10]
26
,
, .
:
(exception),
.
(system call heandler)
system_call()
arch/i386/kernel/entry.S).
,
. i386
eax. eax
. system_call()
NR_syscalls.
NR_syscalls, -ENOSYS,
:
call *sys_call_table(,%eax,4)
.
. i386 ebx, ecx,
edx, esi, edi .
,
, .
.
i386 eax. [10]
27
2.1.2.
1
.
.
THREAD_SIZE,
include/asm/thread_info.h. .
#include <asm/thread_info.h>
asmlinkage long sys_getstsize(void)
{
return THREAD_SIZE;
}
.
.
arch/i386/kernel/new_calls.c. ,
. ,
new_calls.c ,
arch/i386/kernel/Makefile
obj-y += new_calls.o
arch/i386/kernel/syscall_table.S. ,
( ,
i386). .
.long sys_tee
/* 315 */
28
.long sys_vmsplice
.long sys_move_pages
.long sys_ getstsize
unistd.h
include/asm/unistd.h).
#define __NR_tee
315
#define __NR_vmsplice
316
#define __NR_move_pages
317
318
NR_syscalls (
1).
#define NR_syscalls 319
.
C.
Linux syscall(),
. syscall()
,
. syscall() 4.0BSD
( man 2 syscall).
sys/syscall.h.
#include <sys/syscall.h>
, open(),
.
29
, , ,
.
# gcc getstsize.c -o getstsize; ./getstsize
Kernel stack size = 8192 bytes
getstsize.c .
new_calls.c .
Linux (, gcc).
[6, 13].
mcedit
mc).
2.2. Linux
2.2.1.
. ,
, (MMU)
. MMU
.
. 32-
4 , 64- 8 .
, 32- 1
262.144 .
31
page
page,
include/linux/mm.h. , page
, . ,
, ,
. 40 .
1 262.144 * 40 = 10.485.760 ,
10 . [10]
-
.
.
.
.
, :
(DMA,
Direct Memory Access) .
, .
.
ZONE_DMA. , DMA.
ZONE_NORMAL.
. i386
ZONE_DMA 16 , ZONE_HIGHMEM ,
32
kfree(NULL)
. :
struct some * p;
p = kmalloc(sizeof(some), GFP_KERNEL);
if (!p)
/* */
33
else {
/*- */
kfree(p);
}
vmalloc() vfree()
vmalloc() include/linux/vmalloc.h.
size .
NULL.
void *vmalloc(unsigned long size)
kmalloc(), ,
, .
vmalloc() kmalloc(),
, vmalloc(),
. TLB (.
" "). vmalloc()
. ,
vmalloc().
vmalloc(),
vfree() ( include/linux/vmalloc.h):
void vfree(void *addr)
, addr,
vmalloc(). .
gfp_mask
:
. ,
.
34
. , .
. .
include/linux/gfp.h.
2.1
__GFP_WAIT
__GFP_HIGH
__GFP_IO
__GFP_FS
__GFP_COLD
,
(cache cold)
__GFP_NOWARN
__GFP_REPEAT
__GFP_NOFAIL
__GFP_NORETRY
__GFP_COMP
(compound)
.
__GFP_ZERO
, ,
2.2
__GFP_DMA
ZONE_DMA
__GFP_HIGHMEM
ZONE_HIGHMEM
ZONE_NORMAL
2.3
35
GFP_ATOMIC
GFP_NOIO
,
/
GFP_NOFS
/,
,
GFP_KERNEL
.
,
GFP_USER
.
GFP_HIGHUSER ZONE_HIGHMEM,
GFP_DMA
ZONE_DMA
2.4
GFP_ATOMIC
__GFP_HIGH
GFP_NOIO
__GFP_WAIT
GFP_NOFS
__GFP_WAIT | __GFP_IO
GFP_KERNEL
GFP_USER
__GFP_WAIT
__GFP_IO
__GFP_FS
__GFP_IO
__GFP_FS
__GFP_HARDWALL
GFP_HIGHUSER __GFP_WAIT
__GFP_HARDWALL | __GFP_HIGHMEM
GFP_DMA
__GFP_DMA
36
GFP_KERNEL. .
GFP_KERNEL swap.
GFP_NOIO
/. GFP_NOFS /,
.
/.
GFP_DMA ,
ZONE_DMA. . [10]
2.2.3.
1
upper(),
, ,
.
: ,
, ,
, .
asmlinkage long sys_upper(char *src, char *dst, int len)
{
int i;
char *buff;
buff = (char *)kmalloc(len, GFP_KERNEL);
memset(buff, 0, len);
copy_from_user(buff, src, len);
for (i = 0; i < len; i++)
37
( ).
, 97
122 (0x61 0x7A ):
.
( )
copy_to_user().
(
), ( )
.
copy_from_user copy_to_user()
include/asm-i386/uacces.h.
( "asm").
.
#include <asm/uacces.h>
kfree().
38
arch/i386/kernel/new_calls.c.
2.1 " ".
2
,
upper() .
C:
#include <sys/syscall.h>
#include <stdio.h>
#define __NR_upper 319
int main(int argc, char *argv[])
{
char *s1, *s2;
int len, ret;
if (argc > 1)
s1 = argv[1];
else
s1 = "This Is (1234) Default TEST String";
len = strlen(s1);
s2 = (char *)malloc(len);
memset(s2, 0, len);
printf("Input string: %s\n", s1);
ret = syscall(__NR_upper, s1, s2, len);
printf("Output string: %s\n", s2);
return 0;
39
}
s1.
( argc 1),
s1 ,
, , ("This
Is (1234) Default TEST String").
s1 s2,
upper().
# gcc upper.c -o upper; ./upper
Input string: This Is (1234) Default TEST String
Output string: THIS IS (1234) DEFAULT TEST STRING
# ./upper HeLlo
Input string: HeLlo
Output string: HELLO
upper.c .
new_calls.c .
3 " ".
upper()
. .
2.3.
2.3.1. Linux
Linux :
.
.
(task). (kernel thread)
40
, .
. ,
, ,
.
:
. ,
,
. ,
. Linux
,
.
.
Linux ( Unix )
fork() ( ),
.
, fork(), (,
parent), (, child).
fork() ,
.
- .
exec*()
.
exit(),
. ,
,
.
, (task list).
41
task_struct,
include/linux/sched.h,
. 1,7
32- , .
pid,
.
Linux Unix 32768 (
/proc/sys/kernel/pid_max).
Linux .
init (pid = 1).
(sibling).
task_struct
, . ,
. current .
.
state task_struct .
:
TASK_RUNNING (runnable).
,
.
TASK_INTERRUPTIBLE
, sleeping).
. ,
TASK_RUNNING.
.
TASK_UNINTERRUPTIBLE
TASK_INTERRUPTIBLE,
.
,
.
, TASK_INTERRUPTIBLE.
TASK_ZOMBIE ,
,
, wait4().
TASK_STOPPED .
, . ,
SIGSTOP, SIGTSTP, SIGTTOU,
, .
43
.
__set_task_state(). i386
include/linux/sched.h:
#define __set_task_state(tsk, state_value)
44
dup_task_struct().
.
.
tgid.
,
, .
.
do_fork(). copy_process()
, .
, do_fork,
.
2.5.
2.5 do_fork()
CLONE_FILES
CLONE_FS
CLONE_IDLETASK
PID (
(idle) )
CLONE_NEWNS
(. 2.4.1)
45
CLONE_PARENT
CLONE_PTRACE
( )
CLONE_SIGHAND
CLONE_THREAD
CLONE_UNTRACED
CLONE_PTRACE
CLONE_STOP
TASK_STOPPED
CLONE_VM
,
, kernel_thread() (
arch/i386/process.c):
int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags);
fn, arg.
do_fork() flags:
return do_fork(flags | CLONE_VM | CLONE_UNTRACED, 0, ®s, 0,
NULL, NULL);
:
, ,
.
46
.
, exit() ( C
main()).
: ,
, . ,
do_exit() (
kernel/exit.c).
do_exit() .
. release_task()
. ,
, ""
( ) init.
init
. [10]
2.3.2.
,
.
.
.
"Segmentation Fault" ( Windows
"Access violation at adress[0000:0000]").
: [10, 16]
. , ,
(text section).
47
.
, ,
(data section).
).
, ,
BSS (bss section).
(heap). , ,
malloc() .
, .
. 1.1.
.
, .
mm_struct,
include/linux/sched.h, .
mm_struct
mmlist. init_mm init.
mmlist_nr.
mm
task_struct.
copy_mm().
CLONE_VM (
), .
:
48
oldmm = current->mm; /* */
if (clone_flags & CLONE_VM) { /* CLONE_VM*/
atomic_inc(&oldmm->mm_users); /* 1*/
mm = oldmm; /* */
goto good_mm;
}
good_mm:
tsk->mm = mm; /* */
, mmput(),
mm_users .
mm_users , mmdrop(),
mm_count. mm_count
, free_mm(),
.
( mm NULL),
.
, ,
.
, ,
NULL,
.
,
, . ,
.
49
:
; () .
,
.
Linux
( ,
):
1. (page
global directory, PGD). pgd_t
( unsigned long). PGD
, PMD.
2. () (page middle direcory)
pmd_t. PMD
PTE.
3.
(page table entry) pte_t.
.
(
). pgd
.
( ).
,
.
50
(translation
lookaside
buffer,
TLB),
.
TLB.
,
. [10]
mm_struct
( pgd)
pgt_t
pmd_t
pte_t
pgt_t
pmd_t
pte_t
pgt_t
pmd_t
pte_t
pgt_t
pmd_t
pte_t
pgt_t
pmd_t
pte_t
pgt_t
pmd_t
pte_t
pgt_t
pmd_t
pte_t
pgt_t
pmd_t
pte_t
pgt_t
pmd_t
pte_t
pgt_t
pmd_t
pte_t
page
. 2.2. .
2.3.3.
,
: PID, UID, .
.
PID
, .
, PID
( init, Linux ).
mm_struct
active_mm .
51
task_struct
mm_struct
include/linux/sched.h. vm_area_struct
include/linux/mm.h:
#include <linux/sched.h>
#include <linux/mm.h>
init (
Linux ).
, pid_t. pid_t
include/linux/types.h.
#include <linux/types.h>
static int nr = 1;
int. ,
. ,
: byte, short, ushort, int, uint, long, ulong, charp (),
bool, invbool.
module_param(nr,
int,
0000)
(,
pid.
pid_t.
struct task_struct *task;
task = find_task_by_pid((pid_t)nr);
task. , PID ,
pid state :
printk(KERN_INFO "taskinfo: Process %d information:\n", task->pid);
printk(KERN_INFO "taskinfo: STATE %u\n", (u32)task->state);
active_mm unsigned long.
start_code end_code , start_data end_data
, start_brk brk "".
(_ _). mm_struct
active_mm.
struct mm_struct *a_mm;
a_mm = task->active_mm;
a_mm. , ,
:
printk(KERN_INFO "taskinfo: START CODE SEGMENT ADDRESS
0x%08X\n", (u32)a_mm->start_code);
printk(KERN_INFO "taskinfo:
0x%08X\n", (u32)a_mm->end_code);
printk(KERN_INFO "taskinfo: CODE SEGMENT LENGTH 0x%08X\n",
(u32)(a_mm->end_code a_mm->start_code));
53
mmap
active_mm unsigned long. vm_start vm_end.
struct vm_area_struct
. mmap (task>active_mm->mmap).
struct vm_area_struct *vma;
vma = task->active_mm->mmap;
vm_start vm_end
vma.
printk(KERN_INFO "taskinfo: START MEMORY AREA ADDRESS
0x%08X\n", (u32)vma->vm_start);
printk(KERN_INFO "taskinfo:
0x%08X\n", (u32)vma->vm_end);
, , ,
(vm_end vm_start):
printk(KERN_INFO "taskinfo: MEMORY AREA LENGTH 0x%08X\n",
(u32)(vma->vm_end vma->vm_start));
,
nr.
nr, .
insmod taskinfo.ko nr=<pid>
/var/log/messages.
, ,
:
cat /var/log/messages | grep taskinfo: | tail -n 21
54
21 ,
"taskinfo:". taskinfo.c .
,
init ( ).
. ,
, Linux,
.
2.4. (VFS)
2.4.1. VFS
(Virtual File System),
(Virtual File Switch)
, .
VFS,
.
VFS , open(), read()
write(),
. ,
,
: VFS ,
. Unix.
, .
55
,
" ", " " .
. ,
.
, write(f, &buf,
len) len buf , f.
sys_write() (
fs/read_write.c),
, , f.
sys_write() VFS vfs_write()
( fs/read_write.c),
, (file->f_op->write()).
2.3.
write()
sys_write()
vfs_write()
f_op->write()
VFS
2.3. write().
VFS
VFS
. ,
:
, .
VFS:
(superblock),
.
(inode), .
(dentry),
.
56
. dentry ,
. dentry ,
dentry.
(file), ,
.
VFS
, :
super_operations ( ).
include/linux/fs.h. ,
.
inode_operations ( ).
include/linux/fs.h. ,
.
dentry_operations ( ).
include/linux/dcache.h. ,
.
file_operations ( ).
include/linux/fs.h. ,
.
,
,
VFS.
, ,
.
superblock
57
" " (,
procfs) .
super_block,
include/linux/fs.h.
alloc_super() .
s_op ,
super_operations. s_op
, . , ,
,
.
sb->s_op->write_super(sb);
sb . write_super()
, ,
. .
C++ :
sb.write_super();
Linux C,
.
inode
inode ,
( Unix ).
Unix inode VFS
. (FAT, HPFS),
.
inode inode,
include/linux/fs.h. ,
,
58
.
,
(NULL). i_op .
dentry
Unix. , ls
: /bin/ls. bin, ls , bin
, .
. VFS
, : ,
, .
VFS
(directory entry dentry). dentry . /,
bin, ls .
VFS dentry " ".
dentry dentry,
include/linux/dcache.h. dentry
d_op. dentry
.
,
dentry . dentry
dcache (Dentry Cache) :
dentry,
( i_dentry inode).
dentry.
:
. ,
( ).
59
- ( dentry_hashtable) - ( d_hash
dentry_operations),
dentry.
file
,
. open()
close().
file,
.
file, include/linux/fs.h. file
.
dentry,
inode, .
file f_op.
60
VFS
file_system_type, include/linux/fs.h.
.
vfsmount.
,
, include/linux/mount.h.
, ,
.
,
, : fs_struct, files_struct
namespace.
fs_struct
include/linux/fs_struct.h.
.
files_struct include/linux/file.h.
.
fd fdtable (
include/linux/file.h).
namespace ,
(
). include/linux/namespace.h.
,
, list.
, CLONE_FILES
CLONE_FS
(, ), files_struct
fs_struct.
. CLONE_NEWNS,
61
.
. [10]
2.4.2.
, .
, .
/linfs/.
, ,
VFS .
LinFS. :
1.
inode.
2.
, .
3.
.
4. .
5. .
inode
inode
. linfs_make_inode().
static struct inode *linfs_make_inode(struct super_block *sb, int mode)
62
inode inode.
inode new_inode().
struct inode *ret = new_inode(sb);
(if (ret))
inode:
ret->i_mode = mode;
ret->i_uid = ret->i_gid = 0;
ret->i_blksize = PAGE_CACHE_SIZE;
ret->i_blocks = 0;
ret->i_atime = ret->i_mtime = ret->i_ctime = CURRENT_TIME;
i_mode inode.
. i_uid i_gid User ID
Group ID inode .
. i_blksize ()
.
PAGE_CACHE_SIZE,
include/linux/pagemap.h PAGE_SIZE,
include/asm/page.h 4096 (). i_blocks
. ,
. i_atime, i_mtime, i_ctime
,
.
, .
63
.
register_filesystem().
file_system_type.
static struct file_system_type linfs_type = {
.owner
= THIS_MODULE,
.name
= "linfs",
.get_sb
= linfs_get_super,
.kill_sb
= kill_litter_super,
};
ISO
C99.
. :
static struct super_operations linfs_sops = {
owner:
THIS_MODULE,
name:
"linfs",
get_sb:
linfs_get_super,
kill_sb:
kill_litter_super,
};
ISO C99.
name : ext2, vfat, ntfs ,
name . get_sb ,
linfs_get_super() get_sb_single().
static struct super_block *linfs_get_super
64
(struct file_system_type *fst, int flags, char *devname, void *data, struct
vfsmount *mnt)
{
return get_sb_single(fst, flags, data, linfs_fill_super, mnt);
}
get_sb_single() fs/super.c.
int get_sb_single(struct file_system_type *fs_type, int flags, void *data,
int (*fill_super)(struct super_block *, void *, int), struct vfsmount *mnt)
fs_type. ,
fill_super().
linfs_fill_super().
static int linfs_fill_super(struct super_block *sb, void *data, int silent)
.
sb->s_blocksize = PAGE_CACHE_SIZE;
sb->s_blocksize_bits = PAGE_CACHE_SHIFT;
sb->s_magic = LFS_MAGIC;
sb->s_op = &linfs_sops;
s_blocksize s_blocksize_bits ()
. s_op
( ). s_magic " "
. 0x19980122.
#define LFS_MAGIC 0x19980122
.
struct inode *root;
65
linfs_create_files().
dentry.
linfs_create_files() counter.
atomic_set(&counter, 0);
linfs_create_file(sb, root, "counter", &counter);
atomic_set()
counter
66
atomic_t
()
0.
linfs_create_file() ,
dentry (), ,
dentry .
static struct dentry *linfs_create_file
(struct super_block *sb, struct dentry *dir, const char *name, atomic_t
*counter)
linfs_create_file() dentry.
struct qstr qname;
qname.name = name;
qname.len = strlen(name);
qname.hash = full_name_hash(name, qname.len);
qstr dentry,
include/linux/fs.h.
: len ( ) -.
full_name_hash() include/linux/dcache.h.
inode dentry .
dentry = d_alloc(dir, &qname);
inode = linfs_make_inode(sb, S_IFREG | 0644);
inode->i_fop = &linfs_fops;
inode->u.generic_ip = counter;
d_add(dentry, inode);
d_alloc() dentry.
d_alloc() fs/dcache.c.
dentry.
inode. u.generic_ip
67
. .
d_add() .
dentry inode. dentry
-, inode "" (attach)
dentry. include/linux/dentry.h.
counter linfs_create_files()
subdir subcounter.
atomic_set(&subcounter, 0);
subdir = linfs_create_dir(sb, root, "subdir");
linfs_create_dir() .
,
dentry, .
linfs_create_file(), Unix
.
inode.
inode->i_op = &simple_dir_inode_operations;
inode->i_fop = &simple_dir_operations;
i_op i_fop simple_dir_inode_operations
simple_dir_operations. (if (subdir)),
subcounter.
linfs_create_file(sb, subdir, "subcounter", &subcounter);
.
.
68
super_operations "" .
static struct super_operations linfs_sops = {
.statfs
= simple_statfs,
.drop_inode
= generic_delete_inode,
};
statfs , VFS
simple_statfs(),
fs/libfs.c. drop_inode ,
VFS,
inode. generic_delete_inode(),
fs/inode.c.
file_operations. file_operations (
open), ( read) ( write).
static struct file_operations linfs_fops = {
.open= linfs_open,
.read = linfs_read_file,
.write = linfs_write_file,
};
. linfs_open() .
static int linfs_open(struct inode *inode, struct file *filp)
69
{
filp->private_data = inode->u.generic_ip;
return 0;
}
inode,
file filp. private_data file
.
u.generic_ip,
linfs_create_file().
, .
linfs_read_file() .
static ssize_t linfs_read_file
(struct file *filp, char *buf, size_t count, loff_t *offset)
file,
, buf,
count ( )
offset.
counter
v atomic_read().
Int v;
v = atomic_read(counter);
, (
offset ). counter
atomic_inc(). v
.
if (*offset == 0)
70
atomic_inc(counter);
else
v -= 1;
tmp TMPSIZE
. len.
#define TMPSIZE 20
char tmp[TMPSIZE];
int len;
int len = snprintf(tmp, TMPSIZE, "%d\n", v);
0.
if (*offset > len)
return 0;
, (count >
len *offset), count ,
(len *offset). (*offset > len).
if (count > len *offset)
count = len *offset;
tmp, .
,
.
copy_to_user(buf, tmp + *offset, count)
, count.
*offset += count;
71
linfs_write_file() .
static ssize_t linfs_write_file
(struct file *filp, const char *buf, size_t count, loff_t *offset)
filp file,
buf, count offset.
. (),
.
if (*offset != 0)
return -EINVAL;
TMPSIZE, . ,
memset().
if (count >= TMPSIZE)
return -EINVAL;
memset(tmp, 0, TMPSIZE);
.
.
if (copy_from_user(tmp, buf, count))
return -EFAULT;
,
counter.
atomic_set(counter, simple_strtol(tmp, NULL, 10));
simple_stroll() lib/sprintf.c.
tmp unsigned long long
72
10.
NULL.
unregister_filesystem().
unregister_filesystem(&linfs_type);
linfs.c .
.
? -
, mount
none.
# mount -t linfs none /linfs/
.
.
2.5. procfs
2.5.1. /proc/
procfs Unix-
,
. procfs
/proc/. - /proc/,
.
.
73
/proc/,
.
procfs
. /proc/
.
( 0).
, procfs
( ). , ,
, pid .
/proc/self/ . [4, 14]
/proc/sys/
/proc/sys/ 1.3.57
, .
:
debug/. C .
dev/. C , (
dev/cdrom/info). .
fs/. .
kernel/. . ,
, , , .
net/.
.
sunrpc/. Sun
(NFS). .
vm/. ,
.
74
/proc/
man proc. [5]
2.5.2. procfs
, /proc/
mykernel_test/ :
jiffies
.
jiffies2 jiffies.
seconds ,
.
foo .
procfs. include/linux/proc_fs.h.
procfs
fs/proc/.
, procfs, :
static struct proc_dir_entry
*example_dir,
*jiffies_file,
*symlink,
*success_file;
75
*seconds_file,
*foo_file,
proc_mkdir().
, /proc/mykernel_test:
#define MYKERNEL_ENTRY "mykernel_test"
example_dir = proc_mkdir(MYKERNEL_ENTRY, NULL);
, ,
create_proc_read_entry(). , jiffies
/proc/mykernel_test/ 0444:
jiffies_file =
create_proc_read_entry("jiffies",
0444,
example_dir,
proc_read_jiffies, NULL);
proc_read_jiffies():
static int proc_read_jiffies
(char *page, char **start, off_t off, int count, int *eof, void *data)
{
int len;
len = sprintf(page, "Your processor timer ticked %lu times\n", jiffies);
return len;
}
,
page.
( jiffies).
proc_read_seconds() ,
jiffies/HZ. HZ
. jiffies / HZ ,
.
76
proc_symlink().
,
/proc/mykernel_test/jiffies2 /proc/test/jiffies:
symlink = proc_symlink("jiffies2", example_dir, "jiffies");
,
, .
, ,
create_proc_entry(). , /proc/mykernel_test/foo
0644:
foo_file = create_proc_entry("foo", 0644, example_dir);
,
.
,
foo.
#define FOO_LEN 16
struct fb_data_t {
char value[FOO_LEN + 1];
};
strcpy(foo_data.value, "foo\n");
foo_file->data = &foo_data;
proc_read_foo(),
proc_write_foo():
foo_file->read_proc = proc_read_foo;
foo_file->write_proc = proc_write_foo;
77
proc_read_foo() proc_read_jiffies(),
, char *page, value
foo_data_t.
static int proc_read_foo
(char *page, char **start, off_t off, int count, int *eof, void *data)
{
int len;
struct fb_data_t *fb_data = (struct fb_data_t *)data;
len = sprintf(page, "Last message: %s", fb_data->value);
return len;
}
proc_write_foo()
copy_from_user().
static int proc_write_foo
(struct file *file, const char *buffer, unsigned long count, void *data)
{
int len;
struct fb_data_t *fb_data = (struct fb_data_t *)data;
if(count > FOO_LEN)
len = FOO_LEN;
else
len = count;
if(copy_from_user(fb_data->value, buffer, len))
return -EFAULT;
78
fb_data->value[len] = '\0';
return len;
}
owner:
example_dir->owner = THIS_MODULE;
jiffies_file->owner = THIS_MODULE;
symlink->owner = THIS_MODULE;
foo_file->owner = THIS_MODULE;
/proc/test/jiffies
/proc/mykernel_test/jiffies2
:
# cat /proc/mykernel_test/jiffies
Your processor timer ticked 35938 times
/proc/test/foo
"foo", :
# cat /proc/mykernel_test/foo
Last message: foo
# echo "hello" > /proc/mykernel_test/foo
# cat /proc/mykernel_test/foo
Last message: hello
remove_proc_entry().
remove_proc_entry("success", example_dir);
remove_proc_entry("foo", example_dir);
79
remove_proc_entry("seconds", example_dir);
remove_proc_entry("jiffies2", example_dir);
remove_proc_entry("jiffies", example_dir);
remove_proc_entry(MYKERNEL_ENTRY, NULL);
procfiles.c .
2.6.
2 Linux.
2.1 Linux,
API. ,
,
.
2.2
.
,
.
2.3 Linux
,
. ,
: ,
.
Linux 50 . 2.4
,
80
. VFS
.
, ,
.
2.5 /proc/
procfs.
/proc/sys/.
, procfs.
81
,
, , ,
Linux
,
.
:
. ,
Linux
.
.
.
taskinfo
Linux.
:
/.
(SMP).
. .
. kobject
sysfs.
Linux API.
.
82
, .
: " ,
.
".
83
1. Corbet, J. Creating Linux virtual filesystems [ ] / J.
Corbet. Linux Weekly News. http://lwn.net/Articles/13325/ (22 . 2002).
2. Salzman, P. J. The Linux Kernel Module Programming Guide [
] / P. J. Salzman, Burian M., Pomerantz O. The Linux Documentation
Project. http://tldp.org/LDP/lkmpg/2.6/html/index.html. (31 . 2005).
3. , . [ ] /
. . CITKIT. http://citkit.ru/articles/18/. (17 . 2005).
4. , . [] / . // . 2005
. 9. . 104-106.
5. , . Linux [] / . // . 2005 .
10. . 102-104.
6. , . Linux [ ] / .
. . http://linuxcenter.ru/lib/books/zlp/ (4 . 2006).
7. , . [] / . //
. 2003 . 10. . 30-37.
8. , . . Linux [
]
http://www.linuxcenter.ru/lib/history/lh-00.phtml. ( 2005).
9. , . . Linux [ ] / .
. . .
http://www.intuit.ru/department/os/baseLinuxwork/.
10., . Linux [] / . . .: ".. ",
2006. 448 .
11., . LPI 201: Linux [ ] / . .
IBM
developerWorks.
http://www.ibm.com/developerworks/ru/edu/l-
84
12., . Linux [] / . //
. 2004 . 6. . 42-51.
13.,
Linux
http://www.linuxcenter.ru/lib/articles/programming/new_scall.phtml (31
2005).
14., . Linux.
[] / . , . , . . .:
"", 2004. 288 .
15., . Linux.
[ ] / . . .
http://linuxcenter.ru/lib/books/linuxdev/_index (6 . 2006).
16., . Linux. [] / . .
.: -, 2005. 656 .
17., . . [] /
. , . . .: , 2006. 576 .
18., . Linux? ? [] / . // Chip Linux. 2005 .
1. . 56-60.
85