ͬ�ô�ѧ

Linux����ϵͳʵ��ԭ��

�ں˳���

 

�Ծ�

2017/9/18

 

 

Linux 0.12���ں���ע�ͳ���

 

 


 

Ŀ¼

 

 


��5�� �ں˱�������������... 1

5.1 ����5‑1 linux/Makefile�ļ�... 1

��6�� ������������... 6

6.1 ����6 ‑1 linux/boot/bootsect.S. 6

6.2 ���� 6‑2 linux/boot/setup.S. 21

6.3 ����6-3 linux/boot/head.s. 38

��7�� �ں˳�ʼ������... 48

7.1 ����7-1 linux/init/main.c. 48

��8�� �ں˺��ij���... 56

8.1 ����8-1 linux/kernel/asm.s. 56

8.2 ����8-2 linux/kernel/traps.c. 61

8.3 ����8-3 linux/kernel/sys_call.s. 66

8.4 ����8-4 linux/kernel/mktime.c����... 74

8.5 ����8-5 linux/kernel/sched.c. 76

8.6 ����8-6 linux/kernel/signal.c. 89

8.7 ����8-7 linux/kernel/exit.c. 96

8.8 ����8-8 linux/kernel/fork.c. 109

8.9 ����8-9 linux/kernel/sys.c����... 114

8.10 ����8-10 linux/kernel/vsprintf.c. 129

8.11 ����8-11 linux/kernel/printk.c. 135

8.12 ����8-12 linux/kernel/panic.c. 136

��9�� �ں˿��豸����... 137

9.1 ����9-1 linux/kernel/blk_drv/blk.h.. 137

9.2 ����9-2 linux/kernel/blk_drv/hd.c. 142

9.3 ����9-3 linux/kernel/blk_drv/ll_rw_blk.c. 155

9.4 ����9-4 linux/kernel/blk_drv/ramdisk.c. 162

9.5 ����9-5 linux/kernel/blk_drv/floppy.c. 166

��10�� �ַ��豸����... 181

10.1 ����10-1 linux/kernel/chr_drv/keyboard.S. 181

10.2 ����10-2 linux/kernel/chr_drv/console.c. 196

10.3 ����10-3 linux/kernel/chr_drv/serial.c. 224

10.4 ����10-4 linux/kernel/chr_drv/rs_io.s. 226

10.5 ����10-5 linux/kernel/chr_drv/tty_io.c. 230

10.6 ����10-6 linux/kernel/chr_drv/tty_ioctl.c. 245

��11�� �������������... 253

11.1 ����11-1 linux/kernel/math/math_emulate.c  253

11.2 ����11-2 linux/kernel/math/error.c. 265

11.3 ����11-3 linux/kernel/math/ea.c. 266

11.4 ����11-4 linux/kernel/math/convert.c. 269

11.5 ����11-5 linux/kernel/math/add.c. 274

11.6 ����11-6 linux/kernel/math/compare.c. 277

11.7 ����11-7 linux/kernel/math/get_put.c. 279

11.8 ����11-8 linux/kernel/math/mul.c. 286

11.9 ����11-9 linux/kernel/math/div.c. 288

��12�� �ļ�ϵͳ����... 291

12.1 ����12-1 linux/fs/buffer.c. 291

12.2 ���� 12-2  linux/fs/bitmap.c. 303

12.3 ����12-3 linux/fs/truncate.c. 308

12.4 ����12-4 linux/fs/inode.c. 311

12.5 ����12-5 linux/fs/super.c. 321

12.6 ����12-6 linux/fs/namei.c. 330

12.7 ����12-7 linux/fs/file_table.c. 357

12.8 ����12-8 linux/fs/block_dev.c. 358

12.9 ����12-9 linux/fs/file_dev.c. 361

12.10 ����12-10 linux/fs/pipe.c. 364

12.11 ����12-11 linux/fs/char_dev.c. 368

12.12 ����12-12 linux/fs/read_write.c. 371

12.13 ����12-13 linux/fs/open.c. 374

12.14 ����12-14 linux/fs/exec.c. 382

12.15 ����12-15 linux/fs/stat.c. 395

12.16 ����12-16 linux/fs/fcntl.c. 398

12.17 ����12-17 linux/fs/ioctl.c. 401

12.18 ����12-18 linux/fs/select.c. 403

��13�� �ڴ��������... 411

13.1 ����13-1 linux/mm/memory.c. 411

13.2 ����13-2 linux/mm/page.s. 429

13.3 ����13-3 linux/mm/swap.c. 430

��14�� �ں˰�������... 438

14.1 ����14-1 linux/include/a.out.h.. 438

14.2 ����14-2 linux/include/const.h.. 444

14.3 ����14-3 linux/include/ctype.h.. 445

14.4 ����14-4  linux/include/errno.h.. 446

14.5 ����14-5  linux/include/fcntl.h.. 448

14.6 ����14-6  linux/include/signal.h.. 450

14.7 ����14-7 linux/include/stdarg.h.. 453

14.8 ����14-8 linux/include/stddef.h.. 454

14.9 ����14-9 linux/include/string.h.. 455

14.10 ����14-10 linux/include/termios.h.. 465

14.11 ����14-11 linux/include/time.h.. 471

14.12 ����14-12 linux/include/unistd.h.. 473

14.13 ����14-13 linux/include/utime.h.. 480

14.14 ����14-14 linux/include/asm/io.h.. 481

14.15 ����14-15 linux/include/asm/memory.h.. 482

14.16 ����14-16 linux/include/asm/segment.h.. 483

14.17 ����14-17 linux/include/asm/system.h.. 485

14.18 ����14-18 linux/include/linux/config.h.. 487

14.19 ����14-19 linux/include/linux/fdreg.h.. 489

14.20 ����14-20 linux/include/linux/fs.h.. 492

14.21 ����14-21 linux/include/linux/hdreg.h.. 498

14.22 ����14-22 linux/include/linux/head.h.. 500

14.23 ����14-23 linux/include/linux/kernel.h.. 501

14.24 ����14-24 linux/include/linux/math_emu.h   503

14.25 ����14-25 linux/include/linux/mm.h.. 509

14.26 ����14-26 linux/include/linux/sched.h.. 511

14.27 ����14-27 linux/include/linux/sys.h.. 519

14.28 ����14-28 linux/include/linux/tty.h.. 522

14.29 ����14-29 linux/include/sys/param.h.. 525

14.30 ����14-30 linux/include/sys/resource.h.. 526

14.31 ����14-31 linux/include/sys/stat.h.. 528

14.32 ����14-32 linux/include/sys/time.h.. 530

14.33 ����14-33 linux/include/sys/times.h.. 532

14.34 ����14-34 linux/include/sys/types.h.. 533

14.35 ����14-35 linux/include/sys/utsname.h.. 535

14.36 ����14-36 linux/include/sys/wait.h.. 536

��15�� �ں˿⺯������... 537

15.1 ����15-1 linux/lib/_exit.c. 537

15.2 ����15-2 linux/lib/close.c. 538

15.3 ����15-3 linux/lib/ctype.c. 539

15.4 ����15-4 linux/lib/dup.c. 540

15.5 ����15-5 linux/lib/errno.c. 541

15.6 ����15-6 linux/lib/execve.c. 542

15.7 ����15-7 linux/lib/malloc.c. 543

15.8 ����15-8 linux/lib/open.c. 550

15.9 ����15-9 linux/lib/setsid.c. 551

15.10 ����15-10 linux/lib/string.c. 552

15.11 ����15-11 linux/lib/wait.c. 553

15.12 ����15-12 linux/lib/write.c. 554

��16�� �ں˴�����ϳ���... 555

16.1 ����16-1 linux/tools/build.c. 555


 

 

 


 

��5�� �ں˱�������������

 

5.1 ����5‑1 linux/Makefile�ļ�


  1 #

  2 # if you want the ram-disk device, define this to be the

  3 # size in blocks.

  4 #

    # �����Ҫʹ��RAM��(RAMDISK)�豸�Ļ��Ͷ����Ĵ�С������Ĭ��RAMDISKû�ж��壨ע�͵��ˣ���

    # ����gcc����ʱ�����ѡ��'-DRAMDISK=512'���μ���13�С�

  5 RAMDISK = #-DRAMDISK=512

  6

  7 AS86    =as86 -0 -a       # 8086���������������������б���Ľ��ܡ�����IJ�������ֱ�

  8 LD86    =ld86 -0          # �ǣ�-0 ����8086Ŀ�����-a ������gas��gld���ּ��ݵĴ��롣

  9

 10 AS      =gas              # GNU���������������������б���Ľ��ܡ�

 11 LD      =gld

    # ������GNU������gld����ʱ�õ���ѡ������ǣ�-s ����ļ���ʡ�����еķ�����Ϣ��-x ɾ��

    # ���оֲ����ţ�-M ��ʾ��Ҫ�ڱ�׼����豸(��ʾ��)�ϴ�ӡ����ӳ��(link map)����ָ�����ӳ���

    # ������һ���ڴ��ַӳ�������г��˳����װ�뵽�ڴ��е�λ����Ϣ������������������Ϣ��

    # • Ŀ���ļ���������Ϣӳ�䵽�ڴ��е�λ�ã�

    # • ����������η��ã�

    # • �����а����������ļ���Ա�������õķ��š�

 12 LDFLAGS =-s -x -M

 

    # gcc��GNU C���������������UNIX��Ľű�(script)������ԣ������ö���ı�ʶ��ʱ������ǰ

    # �����$���Ų���������ס��ʶ����

 13 CC      =gcc $(RAMDISK)

 

    # ����ָ��gccʹ�õ�ѡ�ǰһ������'\'���ű�ʾ��һ�������С�ѡ���Ϊ��-Wall ��ӡ����

    # ������Ϣ��-O �Դ�������Ż���'-f��־'ָ��������޹صı����־������-fstrength-reduce��

    # ���Ż�ѭ����䣻-fcombine-regs����ָ������������ϱ���׶ΰѸ���һ���Ĵ�������һ���Ĵ�

    # ����ָ�������һ��-fomit-frame-pointer ָ����������ָ֡�루Frame pointer���ĺ�����Ҫ

    # ��ָ֡�뱣���ڼĴ����С������ں����п��Ա����ָ֡��IJ�����ά����-mstring-insns ��

    # Linus��ѧϰgcc������ʱΪgcc���ӵ�ѡ�����gcc-1.40�ڸ��ƽṹ�Ȳ���ʱʹ��386 CPU��

    # �ַ���ָ�����ȥ����

 14 CFLAGS  =-Wall -O -fstrength-reduce -fomit-frame-pointer \ 

 15 -fcombine-regs -mstring-insns

 

    # ����cpp��gcc��ǰ(Ԥ)����������ǰ���������ڽ��г����еĺ��滻�������������봦���Լ�

    # ������ָ���ļ������ݣ�����ʹ��'#include'ָ�����ļ�����������Դ�����ļ��������Է���'#'

    # ��ʼ���о���Ҫ��ǰ���������д���������������'#define'����ĺ궼��ʹ���䶨�岿���滻����

    # ����������'#if'��'#ifdef'��'#ifndef'��'#endif'�������б�������ȷ���Ƿ������ָ����Χ��

    # ����䡣

    # '-nostdinc -Iinclude'�����Dz�Ҫ������׼ͷ�ļ�Ŀ¼�е��ļ���������ϵͳ/usr/include/Ŀ¼

    # �µ�ͷ�ļ�������ʹ��'-I'ѡ��ָ����Ŀ¼�������ڵ�ǰĿ¼������ͷ�ļ���

 16 CPP     =cpp -nostdinc -Iinclude

 17

 18 #

 19 # ROOT_DEV specifies the default root-device when making the image.

 20 # This can be either FLOPPY, /dev/xxxx or empty, in which case the

 21 # default of /dev/hd6 is used by 'build'.

 22 #

    # ROOT_DEVָ���ڴ����ں�ӳ��(image)�ļ�ʱ��ʹ�õ�Ĭ�ϸ��ļ�ϵͳ��

    # �ڵ��豸�������������(FLOPPY)��/dev/xxxx���߸ɴ���ţ�����ʱ

    # build������tools/Ŀ¼�У���ʹ��Ĭ��ֵ/dev/hd6��

    #

    # ����/dev/hd6��Ӧ��2��Ӳ�̵ĵ�1������������Linus����Linux�ں�ʱ�Լ��Ļ����ϸ�

    # �ļ�ϵͳ���ڵķ���λ�á�/dev/hd2��ʾ�ѵ�1��Ӳ�̵ĵ�2��������������������

 23 ROOT_DEV=/dev/hd6

 24 SWAP_DEV=/dev/hd2

 25

    # ������kernelĿ¼��mmĿ¼��fsĿ¼��������Ŀ������ļ���Ϊ�˷������������ォ������

    # ARCHIVES���鵵�ļ�����ʶ����ʾ��

 26 ARCHIVES=kernel/kernel.o mm/mm.o fs/fs.o

 

    # ����ַ��豸���ļ���'.a'��ʾ���ļ��Ǹ��鵵�ļ���Ҳ�������������ִ�ж����ƴ����ӳ���

    # ���ϵĿ��ļ���ͨ������GNU��ar�������ɡ�ar��GNU�Ķ������ļ������������ڴ������޸�

    # �Լ��ӹ鵵�ļ��г�ȡ�ļ���

 27 DRIVERS =kernel/blk_drv/blk_drv.a kernel/chr_drv/chr_drv.a

 28 MATH    =kernel/math/math.a        # ��ѧ������ļ���

 29 LIBS    =lib/lib.a                 # ��lib/Ŀ¼�е��ļ����������ɵ�ͨ�ÿ��ļ���

 30

    # ������make��ʽ����ʽ��׺���򡣸���ָʾmake���������������е�'.c'�ļ���������'.s'

    # ������':'��ʾ�����Ǹù������������ʾ��gcc����ǰ��CFLAGS��ָ����ѡ���Լ���ʹ

    # ��include/Ŀ¼�е�ͷ�ļ������ʵ��ر���󲻽��л���ֹͣ��-S�����Ӷ�����������ĸ���C

    # �ļ���Ӧ�Ļ��������ʽ�Ĵ����ļ���Ĭ��������������Ļ������ļ���ԭC�ļ���ȥ��'.c'��

    # �ټ���'.s'��׺��'-o'��ʾ���������ļ�����ʽ������'$*.s'����'$@'�����Զ�Ŀ�������'$<'

    # ������һ���Ⱦ����������T�Ƿ�������'*.c'���ļ���

    # ������3����ͬ����ֱ����ڲ�ͬ�IJ���Ҫ����Ŀ����.s�ļ�����Դ�ļ���.c�ļ����ʹ

    # �õ�һ��������Ŀ¼��.o����ԭ�ļ���.s����ʹ�õ�2��������Ŀ����.o�ļ���ԭ�ļ�

    # ��c�ļ������ֱ��ʹ�õ�3������

 31 .c.s:

 32         $(CC) $(CFLAGS) \

 33         -nostdinc -Iinclude -S -o $*.s $<

 

    # ��ʾ������.s�������ļ������.oĿ���ļ��� �����ʾʹ��gas������������������.o

    # Ŀ���ļ���-c ��ʾֻ������࣬�����������Ӳ�����

 34 .s.o:

 35         $(AS) -c -o $*.o $<

    # �������棬*.c�ļ�-��*.oĿ���ļ��������ʾʹ��gcc��C�����ļ������Ŀ���ļ��������ӡ�

 36 .c.o:

 37         $(CC) $(CFLAGS) \

 38         -nostdinc -Iinclude -c -o $*.o $<

 39

 

    # ����'all'��ʾ����Makefile��֪������Ŀ�ꡣ���T��Image�ļ����������ɵ�Image�ļ�

    # ��������������ӳ���ļ�bootimage��������д�����̾Ϳ���ʹ�ø���������Linuxϵͳ�ˡ���

    # Linux�½�Imageд�����̵�����μ�46�С�DOSϵͳ�¿���ʹ������rawrite.exe��

 40 all:    Image

 41

    # ˵��Ŀ�꣨Image�ļ�������ð�ź����4��Ԫ�ز������ֱ���boot/Ŀ¼�е�bootsect��setup

    # �ļ���tools/Ŀ¼�е�system��build�ļ���42--43������ִ�е����42�б�ʾʹ��toolsĿ

    # ¼�µ�build���߳��������˵��������ɣ���bootsect��setup��system�ļ���$(ROOT_DEV)

    # Ϊ���ļ�ϵͳ�豸��װ���ں�ӳ���ļ�Image����43�е�syncͬ����������ʹ�������������д��

    # �����³����顣

 42 Image: boot/bootsect boot/setup tools/system tools/build

 43         tools/build boot/bootsect boot/setup tools/system $(ROOT_DEV) \

 44                 $(SWAP_DEV) > Image

 45         sync

 46

    # ��ʾdisk���Ŀ��Ҫ��Image������ddΪUNIX��׼�������һ���ļ�������ѡ�����ת���͸�

    # ʽ����bs=��ʾһ�ζ�/д���ֽ�����if=��ʾ������ļ���of=��ʾ��������ļ�������/dev/PS0��

    # ָ��һ������������(�豸�ļ�)����Linuxϵͳ��ʹ��/dev/fd0��

 47 disk: Image

 48         dd bs=8192 if=Image of=/dev/PS0

 49

 50 tools/build: tools/build.c            # ��toolsĿ¼�µ�build.c��������ִ�г���build��

 51         $(CC) $(CFLAGS) \

 52         -o tools/build tools/build.c  # ��������ִ�г���build�����

 53

 54 boot/head.o: boot/head.s              # �������������.s.o��������head.oĿ���ļ���

 55

    # ��ʾtoolsĿ¼�е�system�ļ�Ҫ��ð���ұ����е�Ԫ�����ɡ�56--61��������system�����

    # ���� > System.map ��ʾgld��Ҫ������ӳ���ض�������System.map�ļ��С�

    # ����System.map�ļ�����;�μ�ע�ͺ��˵����

 56 tools/system:   boot/head.o init/main.o \

 57                 $(ARCHIVES) $(DRIVERS) $(MATH) $(LIBS)

 58         $(LD) $(LDFLAGS) boot/head.o init/main.o \

 59         $(ARCHIVES) \

 60         $(DRIVERS) \

 61         $(MATH) \

 62         $(LIBS) \

 63         -o tools/system > System.map

 64

    # ��ѧЭ���������ļ�math.a��64���ϵ�����ʵ�֣�����kernel/math/Ŀ¼������make���߳���

 65 kernel/math/math.a:

 66         (cd kernel/math; make)

 67

 68 kernel/blk_drv/blk_drv.a:           # ���ɿ��豸���ļ�blk_drv.a�����к��п��ض�λĿ���ļ���

 69         (cd kernel/blk_drv; make)

 70

 71 kernel/chr_drv/chr_drv.a:           # �����ַ��豸�����ļ�chr_drv.a��

 72         (cd kernel/chr_drv; make)

 73

 74 kernel/kernel.o:                    # �ں�Ŀ��ģ��kernel.o

 75         (cd kernel; make)

 76

 77 mm/mm.o:                            # �ڴ����ģ��mm.o

 78         (cd mm; make)

 79

 80 fs/fs.o:                            # �ļ�ϵͳĿ��ģ��fs.o

 81         (cd fs; make)

 82

 83 lib/lib.a:                          # �⺯��lib.a

 84         (cd lib; make)

 85

 86 boot/setup: boot/setup.s                        # ���↑ʼ��������ʹ��8086����������

 87         $(AS86) -o boot/setup.o boot/setup.s    # ��setup.s�ļ����б�������setup�ļ���

 88         $(LD86) -s -o boot/setup boot/setup.o   # -s ѡ���ʾҪȥ��Ŀ���ļ��еķ�����Ϣ��

 89

 90 boot/setup.s:   boot/setup.S include/linux/config.h       # ִ��C����Ԥ�������滻*.S��

 91         $(CPP) -traditional boot/setup.S -o boot/setup.s  # ���еĺ����ɶ�Ӧ��*.s�ļ���

 92

 93 boot/bootsect.s:        boot/bootsect.S include/linux/config.h

 94         $(CPP) -traditional boot/bootsect.S -o boot/bootsect.s

 95

 96 boot/bootsect:  boot/bootsect.s                 # ͬ�ϡ�����bootsect.o���������顣

 97         $(AS86) -o boot/bootsect.o boot/bootsect.s

 98         $(LD86) -s -o boot/bootsect boot/bootsect.o

 99

    # ��ִ��'make clean'ʱ���ͻ�ִ��98--103���ϵ����ȥ�����б����������ɵ��ļ���

    # 'rm'���ļ�ɾ�����ѡ��-f�����Ǻ��Բ����ڵ��ļ������Ҳ���ʾɾ����Ϣ��

100 clean:

101         rm -f Image System.map tmp_make core boot/bootsect boot/setup \

102                 boot/bootsect.s boot/setup.s

103         rm -f init/*.o tools/system tools/build boot/*.o

104         (cd mm;make clean)       # ����mm/Ŀ¼��ִ�и�Ŀ¼Makefile�ļ��е�clean����

105         (cd fs;make clean)

106         (cd kernel;make clean)

107         (cd lib;make clean)

108

    # �ù�������ִ�������clean����Ȼ���linux/Ŀ¼����ѹ��������'backup.Z'ѹ���ļ���

    # 'cd .. '��ʾ�˵�linux/����һ��������Ŀ¼��'tar cf - linux'��ʾ��linux/Ŀ¼ִ��tar�鵵

    # ����'-cf'��ʾ��Ҫ�����µĹ鵵�ļ� '| compress -'��ʾ��tar�����ִ��ͨ���ܵ�����('|')

    # ���ݸ�ѹ������compress������ѹ�������������backup.Z�ļ���

109 backup: clean

110         (cd .. ; tar cf - linux | compress - > backup.Z)

111         sync                                    # ��ʹ�������������д�̲����´��̳����顣

112

113 dep: 

# ��Ŀ���������ڲ������ļ�֮���������ϵ��������Щ������ϵ��Ϊ����make������������ȷ��

# �Ƿ���Ҫ�ؽ�һ��Ŀ����󡣱��統ij��ͷ�ļ����Ķ�����make����ͨ�����ɵ�������ϵ������

# �������ͷ�ļ��йص�����*.c�ļ������巽�����£�

    # ʹ���ַ����༭����sed��Makefile�ļ������T�DZ��ļ������д��������Ϊɾ����Makefile

    # �ļ���'### Dependencies'�к���������У���ɾ���������122��ʼ���ļ�ĩ�������У�������

    # һ����ʱ�ļ�tmp_make��Ҳ��114�е����ã���Ȼ���ָ��Ŀ¼�£�init/����ÿһ��C�ļ�����ʵ

    # ֻ��һ���ļ�main.c��ִ��gccԤ������������־'-M'����Ԥ��������cpp�������ÿ��Ŀ���ļ�

    # ����ԵĹ��򣬲�����Щ�������make�﷨������ÿһ��Դ�ļ���Ԥ������������һ��������

    # �����ʽ������ӦԴ�����ļ���Ŀ���ļ���������������ϵ������Դ�ļ��а���������ͷ�ļ��б���

    # Ȼ���Ԥ������������ӵ���ʱ�ļ�tmp_make�У���󽫸���ʱ�ļ����Ƴ��µ�Makefile�ļ���

    # 115���ϵ�'$$i'ʵ������'$($i) '������'$i'�����ǰ���shell����'i'��ֵ��

114         sed '/\#\#\# Dependencies/q' < Makefile > tmp_make

115         (for i in init/*.c;do echo -n "init/";$(CPP) -M $$i;done) >> tmp_make

116         cp tmp_make Makefile

117         (cd fs; make dep)                  # ��fs/Ŀ¼�µ�Makefile�ļ�Ҳ��ͬ���Ĵ�����

118         (cd kernel; make dep)

119         (cd mm; make dep)

120

121 ### Dependencies:

122 init/main.o : init/main.c include/unistd.h include/sys/stat.h \

123   include/sys/types.h include/sys/time.h include/time.h include/sys/times.h \

124   include/sys/utsname.h include/sys/param.h include/sys/resource.h \

125   include/utime.h include/linux/tty.h include/termios.h include/linux/sched.h \

126   include/linux/head.h include/linux/fs.h include/linux/mm.h \

127   include/linux/kernel.h include/signal.h include/asm/system.h \

128   include/asm/io.h include/stddef.h include/stdarg.h include/fcntl.h \

129   include/string.h


 


 

 

��6�� ������������

6.1 ����6 ‑1 linux/boot/bootsect.S


  1 !

  2 ! SYS_SIZE is the number of clicks (16 bytes) to be loaded.

  3 ! 0x3000 is 0x30000 bytes = 196kB, more than enough for current

  4 ! versions of linux

    ! SYS_SIZE��Ҫ���ص�ϵͳģ�鳤�ȣ���λ�ǽڣ�ÿ��16�ֽڡ�0x3000��Ϊ0x30000�ֽ�=196KB��

    ! ����1024�ֽ�Ϊ1KB�ƣ���Ӧ����192KB�����ڵ�ǰ�ں˰汾����ռ䳤�����㹻�ˡ�����ֵΪ

    ! 0x8000ʱ����ʾ�ں����Ϊ512KB����Ϊ�ڴ�0x90000����ʼ����ƶ����bootsect��setup

    ! �Ĵ��룬��˸�ֵ��󲻵ó���0x9000����ʾ584KB����

    ! �����̾��'!'��ֺ�';'��ʾ����ע����俪ʼ��

  5 !

    ! ͷ�ļ�linux/config.h�ж������ں��õ���һЩ�������ź�Linus�Լ�ʹ�õ�Ĭ��Ӳ�̲����顣

    ! �������ж���������һЩ������

    ! DEF_SYSSIZE  = 0x3000 - Ĭ��ϵͳģ�鳤�ȡ���λ�ǽڣ�ÿ��Ϊ16�ֽڣ�

    ! DEF_INITSEG  = 0x9000 - Ĭ�ϱ���������ƶ�Ŀ�Ķ�λ�ã�

    ! DEF_SETUPSEG = 0x9020 - Ĭ��setup��������λ�ã�

    ! DEF_SYSSEG   = 0x1000 - Ĭ�ϴӴ��̼���ϵͳģ�鵽�ڴ�Ķ�λ�á�

  6 #include <linux/config.h>

  7 SYSSIZE = DEF_SYSSIZE           ! ����һ����Ż���š�ָ���������Ӻ�systemģ��Ĵ�С��

  8 !

  9 !       bootsect.s              (C) 1991 Linus Torvalds

 10 !       modified by Drew Eckhardt

 11 !

 12 ! bootsect.s is loaded at 0x7c00 by the bios-startup routines, and moves

 13 ! iself out of the way to address 0x90000, and jumps there.

 14 !

 15 ! It then loads 'setup' directly after itself (0x90200), and the system

 16 ! at 0x10000, using BIOS interrupts.

 17 !

 18 ! NOTE! currently system is at most 8*65536 bytes long. This should be no

 19 ! problem, even in the future. I want to keep it simple. This 512 kB

 20 ! kernel size should be enough, especially as this doesn't contain the

 21 ! buffer cache as in minix

 22 !

 23 ! The loader has been made as simple as possible, and continuos

 24 ! read errors will result in a unbreakable loop. Reboot by hand. It

 25 ! loads pretty fast by getting whole sectors at a time whenever possible.

    !

    ! ������ǰ�����ֵ����ģ�

    !     bootsect.s              (C) 1991 Linus Torvalds

    !     Drew Eckhardt�޸�

    !

    ! bootsect.s ��ROM BIOS�����ӳ��������0x7c00 (31KB)���������Լ��Ƶ��˵�ַ0x90000

    ! (576KB)��������ת�����

    !

    ! ��Ȼ��ʹ��BIOS�жϽ�'setup'ֱ�Ӽ��ص��Լ��ĺ���(0x90200)(576.5KB)������system��

    ! �ص���ַ0x10000����

    !

    ! ע��! Ŀǰ���ں�ϵͳ��󳤶�����Ϊ(8*65536)(512KB)�ֽڣ���ʹ���ڽ�����ҲӦ��û����

    ! ��ġ������������ּ����ˡ�����512KB������ں˳���Ӧ���㹻�ˣ�����������û����

    ! MINIX��һ���������������ٻ��塣

    !

    ! ���س����Ѿ����ù����ˣ����Գ����ض�����������������ѭ����ֻ���ֹ�������ֻҪ���ܣ�

    ! ͨ��һ�ζ�ȡ���е����������ع��̿������úܿ졣

 26

    ! αָ�α��������.globl��.global���ڶ������ı�ʶ�����ⲿ�Ļ�ȫ�ֵģ����Ҽ�ʹ��

    ! ʹ��Ҳǿ�����롣 .text��.data��.bss���ڷֱ��嵱ǰ����Ρ����ݶκ�δ��ʼ�����ݶΡ�

    ! �����Ӷ��Ŀ��ģ��ʱ�����ӳ���ld86����������ǵ����Ѹ���Ŀ��ģ���е���Ӧ�ηֱ�

    ! ��ϣ��ϲ�����һ������������ζ�������ͬһ�ص���ַ��Χ�У���˱�����ʵ���ϲ��ֶΡ�

    ! ���⣬�����ð�ŵ��ַ����DZ�ţ����������'begtext:'��

    ! һ��������ͨ���ɱ�ţ���ѡ����ָ�����Ƿ���ָ�������Ͳ����������ֶ���ɡ����λ��

    ! һ��ָ��ĵ�һ���ֶΡ�������������λ�õĵ�ַ��ͨ��ָ��һ����תָ���Ŀ��λ�á�

 27 .globl begtext, begdata, begbss, endtext, enddata, endbss

 28 .text                              ! �ı��Σ�����Σ���

 29 begtext:

 30 .data                              ! ���ݶΡ�

 31 begdata:

 32 .bss                               ! δ��ʼ�����ݶΡ�

 33 begbss:

 34 .text                              ! �ı��Σ�����Σ���

 35

    ! ����Ⱥ�'='�����'EQU'���ڶ����ʶ��������������ֵ��

 36 SETUPLEN = 4                       ! nr of setup-sectors

                                       ! setup�������ռ�ô���������(setup-sectors)ֵ��

 37 BOOTSEG  = 0x07c0                  ! original address of boot-sector

                                       ! bootsect���������ڴ�ԭʼ�ε�ַ��

 38 INITSEG  = DEF_INITSEG             ! we move boot here - out of the way

                                       ! ��bootsect�Ƶ�λ��0x90000 - �ܿ�ϵͳģ��ռ�ô���

 39 SETUPSEG = DEF_SETUPSEG            ! setup starts here

                                       ! setup������ڴ�0x90200����ʼ��

 40 SYSSEG   = DEF_SYSSEG              ! system loaded at 0x10000 (65536).

                                       ! systemģ����ص�0x10000��64 KB������

 41 ENDSEG   = SYSSEG + SYSSIZE        ! where to stop loading

                                       ! ֹͣ���صĶε�ַ��

 42

 43 ! ROOT_DEV & SWAP_DEV are now written by "build".

    ! ���ļ�ϵͳ�豸��ROOT_DEV�ͽ����豸��SWAP_DEV ������toolsĿ¼�µ�build����д�롣

    ! �豸��0x306ָ�����ļ�ϵͳ�豸�ǵ�2��Ӳ�̵ĵ�1������������Linus���ڵ�2��Ӳ����

    ! ��װ��Linux 0.11ϵͳ����������ROOT_DEV������Ϊ0x306���ڱ�������ں�ʱ����Ը���

    ! �Լ����ļ�ϵͳ�����豸λ���޸�����豸�š�����豸����Linuxϵͳ��ʽ��Ӳ���豸����

    ! ����ʽ��Ӳ���豸�ž���ֵ�ĺ������£�

    ! �豸��=���豸��*256 + ���豸�ţ�Ҳ��dev_no = (major<<8) + minor ��

    ! �����豸�ţ�1-�ڴ�,2-����,3-Ӳ��,4-ttyx,5-tty,6-���п�,7-�������ܵ���

    ! 0x300 - /dev/hd0 - ����������1��Ӳ�̣�

    ! 0x301 - /dev/hd1 - ��1���̵ĵ�1��������

    !  ��

    ! 0x304 - /dev/hd4 - ��1���̵ĵ�4��������

    ! 0x305 - /dev/hd5 - ����������2��Ӳ�̣�

    ! 0x306 - /dev/hd6 - ��2���̵ĵ�1��������

    !  ��

    ! 0x309 - /dev/hd9 - ��2���̵ĵ�4��������

    ! ��Linux�ں�0.95�����Ѿ�ʹ���������ں���ͬ�����������ˡ�

 44 ROOT_DEV = 0                       ! ���ļ�ϵͳ�豸ʹ����ϵͳ����ʱͬ�����豸��

 45 SWAP_DEV = 0                       ! �����豸ʹ����ϵͳ����ʱͬ�����豸��

 46

    ! αָ��entry��ʹ���ӳ��������ɵ�ִ�г���a.out���а���ָ���ı�ʶ�����š�������

    ! ����ִ�п�ʼ�㡣49 -- 58�������ǽ�����(bootsect)��Ŀǰ��λ�� 0x07c0(31KB) �ƶ���

    ! 0x9000(576KB) ������256�֣�512�ֽڣ���Ȼ����ת���ƶ�������go��Ŵ���Ҳ������

    ! �����һ��䴦��

 47 entry start                        ! ��֪���ӳ��򣬳����start��ſ�ʼִ�С�

 48 start:

 49         mov     ax,#BOOTSEG        ! ��ds�μĴ�����Ϊ0x7C0��

 50         mov     ds,ax

 51         mov     ax,#INITSEG        ! ��es�μĴ�����Ϊ0x9000��

 52         mov     es,ax

 53         mov     cx,#256            ! �����ƶ�����ֵ=256�֣�512�ֽڣ���

 54         sub     si,si              ! Դ��ַ   ds:si = 0x07C0:0x0000

 55         sub     di,di              ! Ŀ�ĵ�ַ es:di = 0x9000:0x0000

 56         rep                        ! �ظ�ִ�в��ݼ�cx��ֵ��ֱ��cx = 0Ϊֹ��

 57         movw                       ! ��movsָ����ڴ�[si]���ƶ�cx���ֵ�[di]����

 58         jmpi    go,INITSEG         ! �μ���ת��Jump Intersegment��������INITSEG

                                       ! ָ����ת���Ķε�ַ�����go�Ƕ���ƫ�Ƶ�ַ��

 59

    ! �����濪ʼ��CPU�����ƶ���0x90000λ�ô��Ĵ�����ִ�С�

    ! ��δ������ü����μĴ���������ջ�Ĵ���ss��sp��ջָ��spֻҪָ��Զ����512�ֽ�ƫ��

    ! ������ַ0x90200���������ԡ���Ϊ��0x90200��ַ��ʼ����Ҫ����setup���򣬶���ʱsetup

    ! �����ԼΪ4�����������spҪָ����ڣ�0x200 + 0x200 * 4 +��ջ��С��λ�ô�������sp

    ! ����Ϊ 0x9ff00 - 12�����������ȣ�����sp = 0xfef4���ڴ�֮��λ�û���һ���Խ�������

    ! ����������������˵����ʵ����BIOS�������������ص�0x7c00 ������ִ��Ȩ������������ʱ��

    ! ss = 0x00��sp = 0xfffe��

    ! ���⣬��65����pushָ�����������������ʱ�Ѷ�ֵ������ջ�У�Ȼ�������ִ�����жϴŵ�

    ! ���������ٵ���ջ�������μĴ��� fs��gs��ֵ����109�У����������ڵ�67��68������޸�

    ! ��ջ�ε�λ�ã���˳�����ִ��ջ��������֮ǰ��ջ�λָ���ԭλ�ã�����������ƾ��Ǵ���ġ�

    ! ����������һ��bug�������ķ���֮һ��ȥ����65�У����ѵ�109���޸ijɡ�mov ax,cs����

 60 go:     mov     ax,cs              ! ��ds��es��ss���ó��ƶ���������ڵĶδ�(0x9000)��

 61         mov     dx,#0xfef4         ! arbitrary value >>512 - disk parm size

 62

 63         mov     ds,ax

 64         mov     es,ax

 65         push    ax                 ! ��ʱ�����ֵ��0x9000������109��ʹ�á�����ͷ!��

 66

 67         mov     ss,ax              ! put stack at 0x9ff00 - 12.

 68         mov     sp,dx

 69 /*

 70  *      Many BIOS's default disk parameter tables will not

 71  *      recognize multi-sector reads beyond the maximum sector number

 72  *      specified in the default diskette parameter tables - this may

 73  *      mean 7 sectors in some cases.

 74  *

 75  *      Since single sector reads are slow and out of the question,

 76  *      we must take care of this by creating new parameter tables

 77  *      (for the first disk) in RAM.  We will set the maximum sector

 78  *      count to 18 - the most we will encounter on an HD 1.44. 

 79  *

 80  *      High doesn't hurt.  Low does.

 81  *

 82  *      Segments are as follows: ds=es=ss=cs - INITSEG,

 83  *              fs = 0, gs = parameter table segment

 84  */

    /*

     *      ���ڶ���������������������������Ĭ�ϴ��̲�������ָ�������������ʱ��

     *      �ܶ�BIOS�����ܽ�����ȷʶ����ijЩ�������7��������

     *

     *      ���ڵ�����������̫���������Կ��ǣ�������DZ���ͨ�����ڴ����ش����µ�

     *      ��������Ϊ��1���������������������⡣���ǽ��������������������Ϊ

     *      18 -- ����1.44MB�����ϻ������������ֵ��

     *     

     *      �����ֵ���˲�������⣬����̫С�Ͳ����ˡ�

     *

     *      �μĴ����������óɣ�ds=es=ss=cs - ��ΪINITSEG��0x9000����

     *      fs = 0��gs = ���������ڶ�ֵ��

     */

 85 ! BIOS���õ��ж�0x1E���ж�����ֵ��������������ַ��������ֵλ���ڴ�0x1E * 4 = 0x78

    ! ������δ������ȴ��ڴ�0x0000:0x0078������ԭ������������0x9000:0xfef4����Ȼ���޸�

    ! ���е�ÿ�ŵ����������Ϊ18��

 86

 87         push    #0                 ! �öμĴ���fs = 0��

 88         pop     fs                 ! fs:bxָ�����������������ַ����ָ���ָ�룩��

 89         mov     bx,#0x78           ! fs:bx is parameter table address

    ! ����ָ���ʾ��һ�����IJ�������fs�μĴ�����ָ�Ķ��С���ֻӰ������һ����䡣����

    ! �� fs:bx ��ָ�ڴ�λ�ô��ı���ַ�ŵ��Ĵ����� gs:si ����Ϊԭ��ַ���Ĵ����� es:di =

    ! 0x9000:0xfef4 ΪĿ�ĵ�ַ��

 90         seg fs

 91         lgs     si,(bx)            ! gs:si is source

 92

 93         mov     di,dx              ! es:di is destination ! dx=0xfef4����61�б����á�

 94         mov     cx,#6              ! copy 12 bytes

 95         cld                        ! �巽���־������ʱָ�������

 96

 97         rep                        ! ����12�ֽڵ�������������0x9000:0xfef4����

 98         seg gs

 99         movw

100

101         mov     di,dx              ! es:diָ���±����޸ı���ƫ��4�������������Ϊ18��

102         movb    4(di),*18          ! patch sector count

103

104         seg fs                     ! ���ж�����0x1E��ֵָ���±���

105         mov     (bx),di

106         seg fs

107         mov     2(bx),es

108

109         pop     ax                 ! ��ʱax���������65�б��������Ķ�ֵ��0x9000����

110         mov     fs,ax              ! ����fs = gs = 0x9000��

111         mov     gs,ax

112        

113         xor     ah,ah              ! reset FDC ! ��λ���̿���������������²�����

114         xor     dl,dl              ! dl = 0����1��������

115         int     0x13   

116

117 ! load the setup-sectors directly after the bootblock.

118 ! Note that 'es' is already set up.

    ! ��bootsect����������ż���setupģ��Ĵ������ݡ�

    ! ע��es�Ѿ����ú��ˡ������ƶ�����ʱes�Ѿ�ָ��Ŀ�Ķε�ַ��0x9000����

119

    ! 121--137�е���;������ROM BIOS�ж�INT 0x13 ��setup ģ��Ӵ��̵�2��������ʼ����

    ! 0x90200 ��ʼ�������� 4���������ڶ��������������������������ʾ�����ϳ�������λ�ã�

    ! Ȼ��λ�����������ԣ�û����·��

    ! INT 0x13������ʹ�õ��ò����������£�

    ! ah = 0x02 - �������������ڴ棻al = ��Ҫ����������������

    ! ch = �ŵ�(����)�ŵĵ�8λ��   cl = ��ʼ����(λ0-5)���ŵ��Ÿ�2λ(λ6-7)��

    ! dh = ��ͷ�ţ�                 dl = �������ţ������Ӳ����λ7Ҫ��λ����

    ! es:bx ��ָ�����ݻ�������  ���������CF��־��λ��ah���dz����롣

120 load_setup:

121         xor     dx, dx                  ! drive 0, head 0

122         mov     cx,#0x0002              ! sector 2, track 0

123         mov     bx,#0x0200              ! address = 512, in INITSEG

124         mov     ax,#0x0200+SETUPLEN     ! service 2, nr of sectors

125         int     0x13                    ! read it

126         jnc     ok_load_setup           ! ok - continue

127

128         push    ax                      ! dump error code ! ��ʾ������Ϣ����������ջ��

129         call    print_nl                ! ��Ļ���س���

130         mov     bp, sp                  ! ss:bpָ������ʾ���֣�word����

131         call    print_hex               ! ��ʾʮ������ֵ��

132         pop     ax     

133        

134         xor     dl, dl                  ! reset FDC ! ��λ���̿����������ԡ�

135         xor     ah, ah

136         int     0x13

137         j       load_setup              ! j ��jmpָ�

138

139 ok_load_setup:

140

141 ! Get disk drive parameters, specifically nr of sectors/track

    ! ��δ���ȡ�����������IJ�����ʵ������ȡÿ�ŵ�����������������λ��sectors����

    ! ȡ��������������INT 0x13���ø�ʽ�ͷ�����Ϣ���£�

    ! ah = 0x08     dl = �������ţ������Ӳ����Ҫ��λ7Ϊ1����

    ! ������Ϣ��

    ! ���������CF��λ������ah = ״̬�롣

    ! ah = 0�� al = 0��          bl = ���������ͣ�AT/PS2��

    ! ch = ���ŵ��ŵĵ�8λ��  cl = ÿ�ŵ����������(λ0-5)�����ŵ��Ÿ�2λ(λ6-7)

    ! dh = ����ͷ����          dl = ������������

    ! es:di -�� �������̲�������

142

143         xor     dl,dl

144         mov     ah,#0x08           ! AH=8 is get drive parameters

145         int     0x13

146         xor     ch,ch

    ! ����ָ���ʾ��һ�����IJ������� cs�μĴ�����ָ�Ķ��С���ֻӰ������һ����䡣ʵ��

    ! �ϣ����ڱ������������ݶ������ô���ͬһ�����У����μĴ���cs��ds��es��ֵ��ͬ����

    ! �˱������д˴����Բ�ʹ�ø�ָ�

147         seg cs

    ! �¾䱣��ÿ�ŵ�������������������˵��dl=0���������ŵ��Ų��ᳬ��256��ch�Ѿ��㹻��

    ! ʾ�������cl��λ6-7�϶�Ϊ0����146������ch=0����˴�ʱcx����ÿ�ŵ���������

148         mov     sectors,cx

149         mov     ax,#INITSEG

150         mov     es,ax              ! ��Ϊ����ȡ���̲����жϸ���esֵ���������¸Ļء�

151

152 ! Print some inane message

    ! ��ʾ��Ϣ����'Loading'+�س�+���С�������ʾ�����س��ͻ��п����ַ����ڵ�9���ַ���

    ! BIOS�ж�0x10���ܺ� ah = 0x03�������λ�á�

    ! ���룺bh = ҳ��

    ! ���أ�ch = ɨ�迪ʼ�ߣ�cl = ɨ������ߣ�dh = �к�(0x00����)��dl = �к�(0x00�����)��

    !

    ! BIOS�ж�0x10���ܺ� ah = 0x13����ʾ�ַ�����

    ! ���룺al = ���ù��ķ�ʽ���涨���ԡ�0x01-��ʾʹ��bl�е�����ֵ�����ͣ���ַ�����β����

    ! es:bp �˼Ĵ�����ָ��Ҫ��ʾ���ַ�����ʼλ�ô���cx = ��ʾ���ַ����ַ�����bh = ��ʾҳ��ţ�

    ! bl = �ַ����ԡ�dh = �кţ�dl = �кš�

153

154         mov     ah,#0x03           ! read cursor pos

155         xor     bh,bh              ! ���ȶ����λ�á����ع��λ��ֵ��dx�С�

156         int     0x10               ! dh - �У�0--24����dl - ��(0--79)��

157        

158         mov     cx,#9              ! ����ʾ9���ַ���

159         mov     bx,#0x0007         ! page 0, attribute 7 (normal)

160         mov     bp,#msg1           ! es:bpָ��Ҫ��ʾ���ַ�����

161         mov     ax,#0x1301         ! write string, move cursor

162         int     0x10               ! д�ַ������ƶ���굽����β����

163

164 ! ok, we've written the message, now

165 ! we want to load the system (at 0x10000)

    ! ���ڿ�ʼ��systemģ����ص�0x10000��64KB����ʼ����

166

167         mov     ax,#SYSSEG

168         mov     es,ax              ! segment of 0x010000 ! es = ���system�Ķε�ַ��

169         call    read_it            ! ��������systemģ�飬esΪ���������

170         call    kill_motor         ! �ر���������������Ϳ���֪����������״̬�ˡ�

171         call    print_nl           ! ���س����С�

172

173 ! After that we check which root-device to use. If the device is

174 ! defined (!= 0), nothing is done and the given device is used.

175 ! Otherwise, either /dev/PS0 (2,28) or /dev/at0 (2,8), depending

176 ! on the number of sectors that the BIOS reports currently.

    ! �˺����Ǽ��Ҫʹ���ĸ����ļ�ϵͳ�豸����Ƹ��豸��������Ѿ�ָ�����豸(!=0)��

    ! ��ֱ��ʹ�ø������豸���������Ҫ����BIOS�����ÿ�ŵ���������ȷ������ʹ��/dev/PS0

    ! (2,28)������ /dev/at0 (2,8)��

    !! ����һ���������豸�ļ��ĺ��壺

    !! ��Linux�����������豸����2(�μ���43�е�ע��)�����豸�� = type*4 + nr������

    !! nrΪ0-3�ֱ��Ӧ����A��B��C��D��type�����������ͣ�2��1.2MB��7��1.44MB�ȣ���

    !! ��Ϊ7*4 + 0 = 28������ /dev/PS0 (2,28)ָ����1.44MB A������,���豸����0x021c

    !! ͬ�� /dev/at0 (2,8)ָ����1.2MB A�����������豸����0x0208��

 

    ! ����root_dev��������������508��509�ֽڴ���ָ���ļ�ϵͳ�����豸�š�0x0306ָ��2

    ! ��Ӳ�̵�1������������Ĭ��Ϊ0x0306����Ϊ��ʱ Linus ����Linuxϵͳʱ���ڵ�2��Ӳ

    ! �̵�1�������д�Ÿ��ļ�ϵͳ�����ֵ��Ҫ�������Լ����ļ�ϵͳ����Ӳ�̺ͷ���������

    ! �ġ����磬�����ĸ��ļ�ϵͳ�ڵ�1��Ӳ�̵ĵ�1�������ϣ���ô��ֵӦ��Ϊ0x0301����

    ! ��0x01, 0x03����������ļ�ϵͳ���ڵ�2��Bochs�����ϣ���ô��ֵӦ��Ϊ0x021D����

    ! ��0x1D,0x02�����������ں�ʱ���������Makefile�ļ�������ָ�����Լ���ֵ���ں�ӳ��

    ! �ļ�Image�Ĵ�������tools/build��ʹ����ָ����ֵ��������ĸ��ļ�ϵͳ�����豸�š�

177

178         seg cs

179         mov     ax,root_dev        ! ȡ508,509�ֽڴ��ĸ��豸�Ų��ж��Ƿ��ѱ����塣

180         or      ax,ax

181         jne     root_defined

    ! ȡ�����148�б����ÿ�ŵ������������sectors=15��˵����1.2MB�������������

    ! sectors=18����˵����1.44MB��������Ϊ�ǿ������������������Կ϶���A����

182         seg cs

183         mov     bx,sectors

184         mov     ax,#0x0208         ! /dev/ps0 - 1.2Mb

185         cmp     bx,#15             ! �ж�ÿ�ŵ��������Ƿ�=15

186         je      root_defined       ! ������ڣ���ax�о����������������豸�š�

187         mov     ax,#0x021c         ! /dev/PS0 - 1.44Mb

188         cmp     bx,#18

189         je      root_defined

190 undef_root:                        ! �������һ��������ѭ������������

191         jmp undef_root

192 root_defined:

193         seg cs

194         mov     root_dev,ax        ! ���������豸�ű��浽root_dev�С�

195

196 ! after that (everyting loaded), we jump to

197 ! the setup-routine loaded directly after

198 ! the bootblock:

    ! ���ˣ����г��򶼼�����ϣ����Ǿ���ת����������bootsect�����setup����ȥ��

    ! ����μ���תָ�Jump Intersegment������ת��0x9020:0000(setup.s����ʼ��)ȥִ�С�

199

200         jmpi    0,SETUPSEG         !!!! ���˱�����ͽ����ˡ�!!!!

 

    ! �����Ǽ����ӳ���read_it���ڶ�ȡ�����ϵ�systemģ�顣kill_moter���ڹر��������

    ! ����һЩ��Ļ��ʾ�ӳ���

201

202 ! This routine loads the system at address 0x10000, making sure

203 ! no 64kB boundaries are crossed. We try to load it as fast as

204 ! possible, loading whole tracks whenever we can.

205 !

206 ! in:   es - starting address segment (normally 0x1000)

207 !

    ! ���ӳ���ϵͳģ����ص��ڴ��ַ0x10000������ȷ��û�п�Խ64KB���ڴ�߽硣

    ! ������ͼ����ؽ��м��أ�ֻҪ���ܣ���ÿ�μ��������ŵ������ݡ�

    ! ���룺es �C ��ʼ�ڴ��ַ��ֵ��ͨ����0x1000��

    !

    ! ����α������.word����һ��2�ֽ�Ŀ�ꡣ�൱��C���Գ����ж���ı�������ռ�ڴ�ռ��С��

    ! '1+SETUPLEN'��ʾ��ʼʱ�Ѿ�����1������������setup������ռ��������SETUPLEN��

208 sread:  .word 1+SETUPLEN        ! sectors read of current track !��ǰ�ŵ����Ѷ���������

209 head:   .word 0                 ! current head    !��ǰ��ͷ�š�

210 track:  .word 0                 ! current track   !��ǰ�ŵ��š�

211

212 read_it:

    ! ���Ȳ�������Ķ�ֵ�������϶�������ݱ�������λ���ڴ��ַ 64KB �ı߽翪ʼ��������

    ! ������ѭ������bx�Ĵ��������ڱ�ʾ��ǰ���ڴ�����ݵĿ�ʼλ�á�

    ! 153���ϵ�ָ��test�Ա���λ�߼�����������������������������Ӧ�ı���λ��Ϊ1������

    ! ֵ�Ķ�Ӧ����λΪ1������Ϊ0���ò������ֻӰ���־�����־ZF�ȣ���������AX=0x1000��

    ! ��ôtestָ���ִ�н����(0x1000 & 0x0fff) = 0x0000������ZF��־��λ����ʱ����һ��

    ! ָ��jne ������������

213         mov ax,es

214         test ax,#0x0fff

215 die:    jne die                 ! es must be at 64kB boundary ! esֵ����λ��64KB�߽�!

216         xor bx,bx               ! bx is starting address within segment! bxΪ����ƫ�ơ�

217 rp_read:

    ! �����ж��Ƿ��Ѿ�����ȫ�����ݡ��Ƚϵ�ǰ�������Ƿ����ϵͳ����ĩ�������Ķ�(#ENDSEG)��

    ! ������Ǿ���ת������ok1_read��Ŵ����������ݡ������˳��ӳ��򷵻ء�

218         mov ax,es

219         cmp ax,#ENDSEG          ! have we loaded all yet?    ! �Ƿ��Ѿ�������ȫ�����ݣ�

220         jb ok1_read

221         ret

222 ok1_read:

    ! Ȼ��������֤��ǰ�ŵ���Ҫ��ȡ��������������ax�Ĵ����С�

    ! ���ݵ�ǰ�ŵ���δ��ȡ���������Լ����������ֽڿ�ʼƫ��λ�ã��������ȫ����ȡ��Щδ��

    ! �������������ֽ����Ƿ�ᳬ��64KB�γ��ȵ����ơ����ᳬ��������ݴ˴�����ܶ�����ֽ�

    ! �� (64KB �C����ƫ��λ��)��������˴���Ҫ��ȡ����������

223         seg cs

224         mov ax,sectors             ! ȡÿ�ŵ���������

225         sub ax,sread               ! ��ȥ��ǰ�ŵ��Ѷ���������

226         mov cx,ax                  ! cx = ax = ��ǰ�ŵ�δ����������

227         shl cx,#9                  ! cx = cx * 512 �ֽ� + ���ڵ�ǰƫ��ֵ(bx)��

228         add cx,bx                  !   = �˴ζ������󣬶��ڹ�������ֽ�����

229         jnc ok2_read               ! ��û�г���64KB�ֽڣ�����ת��ok2_read��ִ�С�

230         je ok2_read

    ! �����ϴ˴ν����ŵ�������δ������ʱ�ᳬ��64KB��������ʱ����ܶ�����ֽ�����

    ! (64KB�C���ڶ�ƫ��λ��)����ת�������ȡ��������������0��ij������ȡ����64KB�IJ�ֵ��

231         xor ax,ax

232         sub ax,bx

233         shr ax,#9

234 ok2_read:

    ! ����ǰ�ŵ���ָ����ʼ������cl���������������al�������ݵ� es:bx��ʼ����Ȼ��ͳ�Ƶ�ǰ

    ! �ŵ����Ѿ���ȡ������������ŵ���������� sectors���Ƚϡ����С��sectors˵����ǰ��

    ! ���ϵĻ�������δ����������ת��ok3_read������������

235         call read_track            ! ����ǰ�ŵ���ָ����ʼ��������������������ݡ�

236         mov cx,ax                  ! cx = �ôβ����Ѷ�ȡ����������

237         add ax,sread               ! ���ϵ�ǰ�ŵ����Ѿ���ȡ����������

238         seg cs

239         cmp ax,sectors             ! ����ǰ�ŵ��ϵĻ�������δ��������ת��ok3_read����

240         jne ok3_read

    ! ���ôŵ��ĵ�ǰ��ͷ�����������Ѿ���ȡ������ôŵ�����һ��ͷ�棨1�Ŵ�ͷ���ϵ����ݡ�

    ! ����Ѿ���ɣ���ȥ����һ�ŵ���

241         mov ax,#1

242         sub ax,head                ! �жϵ�ǰ��ͷ�š�

243         jne ok4_read               ! �����0��ͷ������ȥ��1��ͷ���ϵ��������ݡ�

244         inc track                  ! ����ȥ����һ�ŵ���

245 ok4_read:

246         mov head,ax                ! ���浱ǰ��ͷ�š�

247         xor ax,ax                  ! �嵱ǰ�ŵ��Ѷ���������

248 ok3_read:

    ! �����ǰ�ŵ��ϵĻ���δ�������������ȱ��浱ǰ�ŵ��Ѷ���������Ȼ�����������ݴ��Ŀ�

    ! ʼλ�á���С��64KB�߽�ֵ������ת��rp_read(217��)�������������ݡ�

249         mov sread,ax               ! ���浱ǰ�ŵ��Ѷ���������

250         shl cx,#9                  ! �ϴ��Ѷ�������*512�ֽڡ�

251         add bx,cx                  ! ������ǰ�������ݿ�ʼλ�á�

252         jnc rp_read

    ! ����˵���Ѿ���ȡ64KB���ݡ���ʱ������ǰ�Σ�Ϊ����һ��������׼����

253         mov ax,es

254         add ah,#0x10               ! ���λ�ַ����Ϊָ����һ��64KB�ڴ濪ʼ����

255         mov es,ax

256         xor bx,bx                  ! ��������ݿ�ʼƫ��ֵ��

257         jmp rp_read                ! ��ת��rp_read(217��)�������������ݡ�

258

    ! read_track �ӳ��򡣶���ǰ�ŵ���ָ����ʼ��������������������ݵ� es:bx ��ʼ�����μ�

    ! ��67���¶�BIOS���̶��ж�int 0x13��ah=2��˵����

    ! al �C �����������es:bx �C ��������ʼλ�á�

259 read_track:

    ! ���ȵ���BIOS�ж�0x10������0x0e���Ե紫��ʽд�ַ��������ǰ��һλ�á���ʾһ��'.'��

260         pusha                      ! ѹ�����мĴ�����push all����

261         pusha                      ! Ϊ������ʾ�ж�ѹ�����мĴ���ֵ��

262         mov ax, #0xe2e             ! loading... message 2e = .

263         mov bx, #7                 ! �ַ�ǰ��ɫ���ԡ�

264         int 0x10

265         popa           

266

    ! Ȼ����ʽ���дŵ�������������

267         mov dx,track               ! ȡ��ǰ�ŵ��š�

268         mov cx,sread               ! ȡ��ǰ�ŵ����Ѷ���������

269         inc cx                     ! cl = ��ʼ��������

270         mov ch,dl                  ! ch = ��ǰ�ŵ��š�

271         mov dx,head                ! ȡ��ǰ��ͷ�š�

272         mov dh,dl                  ! dh = ��ͷ�ţ�dl = ��������(Ϊ0��ʾ��ǰA������)��

273         and dx,#0x0100             ! ��ͷ�Ų�����1��

274         mov ah,#2                  ! ah = 2���������������ܺš�

275        

276         push dx                    ! save for error dump

277         push cx                    ! Ϊ�����������һЩ��Ϣ��

278         push bx

279         push ax

280

281         int 0x13

282         jc bad_rt                  ! ������������ת��bad_rt��

283         add sp,#8                  ! û�г�������˶���Ϊ��������������Ϣ��

284         popa

285         ret

286

    ! �����̲���������������ʾ������Ϣ��Ȼ��ִ����������λ�����������жϹ��ܺ�0��������ת

    ! ��read_track�����ԡ�

287 bad_rt: push ax                    ! save error code

288         call print_all             ! ah = error, al = read

289        

290        

291         xor ah,ah

292         xor dl,dl

293         int 0x13

294        

295

296         add sp, #10                ! ����Ϊ��������������Ϣ��

297         popa   

298         jmp read_track

299

300 /*

301  *      print_all is for debugging purposes. 

302  *      It will print out all of the registers.  The assumption is that this is

303  *      called from a routine, with a stack frame like

304  *      dx

305  *      cx

306  *      bx

307  *      ax

308  *      error

309  *      ret <- sp

310  *

311 */

    /*

     *      �ӳ���print_all���ڵ���Ŀ�ġ�������ʾ���мĴ��������ݡ�ǰ����������Ҫ��

     *      һ���ӳ����е��ã�����ջ֡�ṹΪ������ʾ���������棩

     */

    ! ����־�Ĵ�����CF=0������ʾ�Ĵ������ơ�

312 

313 print_all:

314         mov cx, #5                 ! error code + 4 registers  ! ��ʾֵ������

315         mov bp, sp                 ! ���浱ǰջָ��sp��

316

317 print_loop:

318         push cx                    ! save count left   ! ������Ҫ��ʾ��ʣ�������

319         call print_nl              ! nl for readability  ! Ϊ�ɶ������ù��س����С�

320         jae no_reg                 ! see if register name is needed

321                                    ! ��FLAGS�ı�־CF=0����ʾ�Ĵ�������������ת��

    ! ��Ӧ��ջ�Ĵ���˳��ֱ���ʾ���ǵ����ơ�AX�����ȡ�

322         mov ax, #0xe05 + 0x41 - 1  ! ah =���ܺţ�0x0e����al =�ַ���0x05 + 0x41 -1����

323         sub al, cl

324         int 0x10

325

326         mov al, #0x58              ! X     ! ��ʾ�ַ�'X'��

327         int 0x10

328

329         mov al, #0x3a              ! :     ! ��ʾ�ַ�':'��

330         int 0x10

331

    ! ��ʾ�Ĵ���bp��ָջ�����ݡ���ʼʱbpָ�򷵻ص�ַ��

332 no_reg:

333         add bp, #2                 ! next register   ! ջ����һ��λ�á�

334         call print_hex             ! print it        ! ��ʮ��������ʾ��

335         pop cx

336         loop print_loop

337         ret

338

    ! ����BIOS�ж�0x10���Ե紫��ʽ��ʾ�س����С�

339 print_nl:

340         mov ax, #0xe0d             ! CR

341         int 0x10

342         mov al, #0xa               ! LF

343         int 0x10

344         ret

345

346 /*

347  *      print_hex is for debugging purposes, and prints the word

348  *      pointed to by ss:bp in hexadecmial.

349 */

    /*

     *      �ӳ���print_hex���ڵ���Ŀ�ġ���ʹ��ʮ����������Ļ����ʾ��

     *      ss:bpָ����֡�

     */

350

    ! ����BIOS�ж�0x10���Ե紫��ʽ��4��ʮ����������ʾss:bpָ����֡�

351 print_hex:

352         mov     cx, #4             ! 4 hex digits         ! Ҫ��ʾ4��ʮ���������֡�

353         mov     dx, (bp)           ! load word into dx    ! ��ʾֵ����dx�С�

354 print_digit:

    ! ����ʾ���ֽڣ������Ҫ��dx��ֵ����4���أ���ʱ��4������dx�ĵ�4λ�С�

355         rol     dx, #4             ! rotate so that lowest 4 bits are used

356         mov     ah, #0xe           ! �жϹ��ܺš�

357         mov     al, dl             ! mask off so we have only next nibble

358         and     al, #0xf           ! ����al�в�ֻȡ��4���أ�1��ֵ����

    ! ����'0' ��ASCII��ֵ0x30������ʾֵת���ɻ�������'0' ���ַ�������ʱal ֵ���� 0x39��

    ! ��ʾ����ʾֵ��������9�������Ҫʹ��'A'--'F'����ʾ��

359         add     al, #0x30          ! convert to 0 based digit, '0'

360         cmp     al, #0x39          ! check for overflow

361         jbe     good_digit

362         add     al, #0x41 - 0x30 - 0xa       ! 'A' - '0' - 0xa

363

364 good_digit:

365         int     0x10

366         loop    print_digit        ! cx--����cx>0��ȥ��ʾ��һ��ֵ��

367         ret

368

369

370 /*

371  * This procedure turns off the floppy drive motor, so

372  * that we enter the kernel in a known state, and

373  * don't have to worry about it later.

374  */

    /* ����ӳ������ڹر�����������������ǽ����ں˺����

     * ֪����������״̬���Ժ�Ҳ�����뵣�����ˡ�

     */

    ! �����377���ϵ�ֵ0x3f2�����̿�������һ���˿ڣ�����Ϊ��������Ĵ�����DOR���˿ڡ�����

    ! һ��8λ�ļĴ�������λ7--λ4�ֱ����ڿ���4��������D--A���������͹رա�λ3--λ2����

    ! ����/��ֹDMA���ж������Լ�����/��λ���̿�����FDC�� λ1--λ0����ѡ��ѡ�������������

    ! ��378������al�����ò������0ֵ����������ѡ��A���������ر�FDC����ֹDMA���ж�����

    ! �ر�����й��������ƿ���̵���ϸ��Ϣ��μ�kernel/blk_drv/floppy.c��������˵����

375 kill_motor:

376         push dx

377         mov dx,#0x3f2              ! �������ƿ�����������Ĵ����˿ڣ�ֻд��

378         xor al, al                 ! A���������ر�FDC����ֹDMA���ж����󣬹ر����

379         outb                       ! ��al�е����������dxָ���Ķ˿�ȥ��

380         pop dx

381         ret

382

383 sectors:

384         .word 0                    ! ��ŵ�ǰ��������ÿ�ŵ�����������

385

386 msg1:                              ! ��������BIOS�ж���ʾ����Ϣ����9���ַ���

387         .byte 13,10                ! �س������е�ASCII�롣

388         .ascii "Loading"

389

    ! ��ʾ�������ӵ�ַ508(0x1FC)��ʼ������root_dev�����������ĵ�508��ʼ��2���ֽ��С�

390 .org 506

391 swap_dev:

392         .word SWAP_DEV             ! �����Ž���ϵͳ�����豸��(init/main.c�л���)��

393 root_dev:

394         .word ROOT_DEV             ! �����Ÿ��ļ�ϵͳ�����豸��(init/main.c�л���)��

 

    ! �����������̾�����Ч���������ı�־������BIOS�еij��������������ʱʶ��ʹ�á�������

    ! λ��������������������ֽ��С�

395 boot_flag:

396         .word 0xAA55

397

398 .text

399 endtext:

400 .data

401 enddata:

402 .bss

403 endbss:

404


 

 


 

6.2 ���� 6‑2 linux/boot/setup.S


  1 !

  2 !       setup.s         (C) 1991 Linus Torvalds

  3 !

  4 ! setup.s is responsible for getting the system data from the BIOS,

  5 ! and putting them into the appropriate places in system memory.

  6 ! both setup.s and system has been loaded by the bootblock.

  7 !

  8 ! This code asks the bios for memory/disk/other parameters, and

  9 ! puts them in a "safe" place: 0x90000-0x901FF, ie where the

 10 ! boot-block used to be. It is then up to the protected mode

 11 ! system to read them from there before the area is overwritten

 12 ! for buffer-blocks.

 13 !

    ! setup.s�����BIOS�л�ȡϵͳ���ݣ�������Щ���ݷŵ�ϵͳ�ڴ���ʵ�

    ! �ط�����ʱsetup.s��system�Ѿ���bootsect��������ص��ڴ��С�

    !

    ! ��δ���ѯ��bios�й��ڴ�/����/����������������Щ�����ŵ�һ��

    ! ����ȫ�ġ��ط���0x90000-0x901FF��Ҳ��ԭ��bootsect�����������

    ! �ĵط���Ȼ���ڱ�����鸲�ǵ�֮ǰ�ɱ���ģʽ��system��ȡ��

 14

 15 ! NOTE! These had better be the same as in bootsect.s!

    ! ������Щ������ú�bootsect.s�е���ͬ��

 16 #include <linux/config.h>

    ! config.h�ж�����DEF_INITSEG = 0x9000��DEF_SYSSEG = 0x1000��DEF_SETUPSEG = 0x9020��

 17

 18 INITSEG  = DEF_INITSEG  ! we move boot here - out of the way ! ԭ��bootsect�����ĶΡ�

 19 SYSSEG   = DEF_SYSSEG   ! system loaded at 0x10000 (65536).  ! system��0x10000����

 20 SETUPSEG = DEF_SETUPSEG ! this is the current segment        ! ���������ڵĶε�ַ��

 21

 22 .globl begtext, begdata, begbss, endtext, enddata, endbss

 23 .text

 24 begtext:

 25 .data

 26 begdata:

 27 .bss

 28 begbss:

 29 .text

 30

 31 entry start

 32 start:

 33

 34 ! ok, the read went well so we get current cursor position and save it for

 35 ! posterity.

    ! ok�����������̹��̶����������ڽ����λ�ñ����Ա����ʹ�ã���ش�����59--62�У���

 36

    ! �¾佫ds�ó�INITSEG(0x9000)�����Ѿ���bootsect���������ù�������������setup����

    ! Linus������Ҫ����������һ�¡�

 37         mov     ax,#INITSEG

 38         mov     ds,ax

 39

 40 ! Get memory size (extended mem, kB)

    ! ȡ��չ�ڴ�Ĵ�Сֵ��KB����

    ! ����BIOS�ж�0x15 ���ܺ�ah = 0x88 ȡϵͳ������չ�ڴ��С���������ڴ�0x90002����

    ! ���أ�ax = ��0x100000��1M������ʼ����չ�ڴ��С(KB)����������CF��λ��ax = �����롣

 41

 42         mov     ah,#0x88

 43         int     0x15

 44         mov     [2],ax             ! ����չ�ڴ���ֵ����0x90002����1���֣���

 45

 46 ! check for EGA/VGA and some config parameters

    ! �����ʾ��ʽ��EGA/VGA����ȡ������

    ! ����BIOS�ж�0x10�����ӹ���ѡ��ʽ��Ϣ�����ܺţ�ah = 0x12��bl = 0x10

    ! ���أ�bh =��ʾ״̬��0x00 -��ɫģʽ��I/O�˿�=0x3dX��0x01 -��ɫģʽ��I/O�˿�=0x3bX��

    ! bl = ��װ����ʾ�ڴ档0x00 - 64k��0x01 - 128k��0x02 - 192k��0x03 = 256k��

    ! cx = ��ʾ�����Բ���(�μ�������BIOS��Ƶ�ж�0x10��˵��)��

 47

 48         mov     ah,#0x12

 49         mov     bl,#0x10

 50         int     0x10

 51         mov     [8],ax           ! 0x90008 = ??

 52         mov     [10],bx          ! 0x9000A =��װ����ʾ�ڴ棻0x9000B=��ʾ״̬(��/��ɫ)

 53         mov     [12],cx          ! 0x9000C =��ʾ�����Բ�����

    ! �����Ļ��ǰ����ֵ������ʾ����VGA��ʱ�������û�ѡ����ʾ����ֵ�������浽0x9000E����

 54         mov     ax,#0x5019       ! ��ax��Ԥ����ĻĬ������ֵ��ah = 80�У�al=25�У���

 55         cmp     bl,#0x10         ! ���жϷ���blֵΪ0x10�����ʾ����VGA��ʾ������ת��

 56         je      novga

 57         call    chsvga           ! �����ʾ�����Һ����ͣ��޸���ʾ����ֵ����215�У���

 58 novga:  mov     [14],ax          ! ������Ļ��ǰ����ֵ��0x9000E��0x9000F����

 

    ! ��δ���ʹ��BIOS�ж�ȡ��Ļ��ǰ���λ�ã��С��У������������ڴ�0x90000����2�ֽڣ���

    ! ����̨��ʼ������ᵽ�˴���ȡ��ֵ��

    ! BIOS�ж�0x10���ܺ� ah = 0x03�������λ�á�

    ! ���룺bh = ҳ��

    ! ���أ�ch = ɨ�迪ʼ�ߣ�cl = ɨ������ߣ�dh = �к�(0x00����)��dl = �к�(0x00�����)��

 59         mov     ah,#0x03         ! read cursor pos

 60         xor     bh,bh

 61         int     0x10             ! save it in known place, con_init fetches

 62         mov     [0],dx           ! it from 0x90000.

 63        

 64 ! Get video-card data:

    ! �����������ȡ��ʾ����ǰ��ʾģʽ��

    ! ����BIOS�ж�0x10�����ܺ� ah = 0x0f

    ! ���أ�ah = �ַ�������al = ��ʾģʽ��bh = ��ǰ��ʾҳ��

    ! 0x90004(1��)��ŵ�ǰҳ��0x90006�����ʾģʽ��0x90007����ַ�������

 65        

 66         mov     ah,#0x0f

 67         int     0x10

 68         mov     [4],bx          ! bh = display page

 69         mov     [6],ax          ! al = video mode, ah = window width

 70

 71 ! Get hd0 data

    ! ȡ��һ��Ӳ�̵���Ϣ������Ӳ�̲���������

    ! ��1��Ӳ�̲��������׵�ַ��Ȼ���ж�����0x41������ֵ������2��Ӳ�̲����������ڵ�1��

    ! ���ĺ��棬�ж�����0x46������ֵҲָ���2��Ӳ�̵IJ�������ַ�����ij�����16���ֽڡ�

    ! �������γ���ֱ���ROM BIOS���й�����Ӳ�̵IJ�������0x90080����ŵ�1��Ӳ�̵ı���

    ! 0x90090����ŵ�2��Ӳ�̵ı���

 72

    ! ��75�������ڴ�ָ��λ�ô���ȡһ����ָ��ֵ������ds��si�Ĵ����С�ds�зŶε�ַ��

    ! si�Ƕ���ƫ�Ƶ�ַ�������ǰ��ڴ��ַ4 * 0x41��= 0x104���������4���ֽڶ�������4��

    ! �ڼ���Ӳ�̲���������λ�õĶκ�ƫ��ֵ��

 73         mov     ax,#0x0000

 74         mov     ds,ax

 75         lds     si,[4*0x41]        ! ȡ�ж�����0x41��ֵ����hd0�������ĵ�ַ��ds:si

 76         mov     ax,#INITSEG

 77         mov     es,ax

 78         mov     di,#0x0080         ! �����Ŀ�ĵ�ַ: 0x9000:0x0080 �� es:di

 79         mov     cx,#0x10           ! ������16�ֽڡ�

 80         rep

 81         movsb

 82

 83 ! Get hd1 data

 84

 85         mov     ax,#0x0000

 86         mov     ds,ax

 87         lds     si,[4*0x46]        ! ȡ�ж�����0x46��ֵ����hd1�������ĵ�ַ��ds:si

 88         mov     ax,#INITSEG

 89         mov     es,ax

 90         mov     di,#0x0090         ! �����Ŀ�ĵ�ַ: 0x9000:0x0090 �� es:di

 91         mov     cx,#0x10

 92         rep

 93         movsb

 94

 95 ! Check that there IS a hd1 :-)

    ! ���ϵͳ�Ƿ��е�2��Ӳ�̡����û����ѵ�2�������㡣

    ! ����BIOS�жϵ���0x13��ȡ�����͹��ܣ����ܺ� ah = 0x15��

    ! ���룺dl = �������ţ�0x8X��Ӳ�̣�0x80ָ��1��Ӳ�̣�0x81��2��Ӳ�̣�

    ! �����ah = �����룻00 - û������̣�CF��λ��01 - ��������û��change-line֧�֣�

    !                    02 - ������(���������ƶ��豸)����change-line֧�֣� 03 - ��Ӳ�̡�

 96

 97         mov     ax,#0x01500

 98         mov     dl,#0x81

 99         int     0x13

100         jc      no_disk1

101         cmp     ah,#3              ! ��Ӳ����(���� = 3 ��)��

102         je      is_disk1

103 no_disk1:

104         mov     ax,#INITSEG        ! ��2��Ӳ�̲����ڣ���Ե�2��Ӳ�̱����㡣

105         mov     es,ax

106         mov     di,#0x0090

107         mov     cx,#0x10

108         mov     ax,#0x00

109         rep

110         stosb

111 is_disk1:

112

113 ! now we want to move to protected mode ...

    ! ��������Ҫ���뱣��ģʽ����...

114

115         cli                     ! no interrupts allowed !     ! �Ӵ˿�ʼ�������жϡ�

116

117 ! first we move the system to it's rightful place

    ! �������ǽ�systemģ���Ƶ���ȷ��λ�á�

    ! bootsect���������� system ģ����뵽�ڴ� 0x10000��64KB����ʼ��λ�á����ڵ�ʱ����

    ! systemģ����󳤶Ȳ��ᳬ��0x80000��512KB��������ĩ�˲��ᳬ���ڴ��ַ0x90000������

    ! bootsect����Լ��ƶ���0x90000��ʼ�ĵط�������setup���ص����ĺ��档������γ����

    ! ��;���ٰ�����systemģ���ƶ��� 0x00000λ�ã����Ѵ� 0x10000��0x8ffff ���ڴ����ݿ�

    ! ��512KB����������ڴ�Ͷ��ƶ���0x10000��64KB����λ�á�

118

119         mov     ax,#0x0000

120         cld                     ! 'direction'=0, movs moves forward

121 do_move:

122         mov     es,ax           ! destination segment ! es:di��Ŀ�ĵ�ַ(��ʼΪ0x0:0x0)

123         add     ax,#0x1000

124         cmp     ax,#0x9000      ! �Ѿ������һ�Σ���0x8000�ο�ʼ��64KB�������ƶ��ꣿ

125         jz      end_move        ! �ǣ�����ת��

126         mov     ds,ax           ! source segment  ! ds:si��Դ��ַ(��ʼΪ0x1000:0x0)

127         sub     di,di

128         sub     si,si

129         mov     cx,#0x8000      ! �ƶ�0x8000�֣�64KB�ֽڣ���

130         rep

131         movsw

132         jmp     do_move

133

134 ! then we load the segment descriptors

    ! �˺����Ǽ��ض���������

    ! �����↑ʼ������32λ����ģʽ�IJ����������ҪIntel 32λ����ģʽ��̷����֪ʶ�ˣ�

    ! �й��ⷽ�����Ϣ������б���ļ򵥽��ܻ�¼�е���ϸ˵�������������Ҫ˵�����ڽ���

    ! ����ģʽ������֮ǰ��������Ҫ�������ú���Ҫʹ�õĶ�����������������Ҫ����ȫ��������

    ! �����ж�����������

    !

    ! ����ָ��lidt���ڼ����ж�����������IDT���Ĵ��������IJ�������idt_48����6�ֽڡ�ǰ2

    ! �ֽڣ��ֽ�0-1���������������ֽڳ���ֵ����4�ֽڣ��ֽ�2-5��������������32λ���Ի�

    ! ��ַ������ʽ�μ�����218--220�к�222--224��˵�����ж����������е�ÿһ��8�ֽڱ���

    ! ָ�������ж�ʱ��Ҫ���õĴ�����Ϣ�����ж�������Щ���ƣ���Ҫ�����������Ϣ��

    !

    ! lgdtָ�����ڼ���ȫ������������GDT���Ĵ��������������ʽ��lidtָ�����ͬ��ȫ������

    ! �����е�ÿ���������8�ֽڣ������˱���ģʽ�����ݶκʹ���Σ��飩����Ϣ�� ���а���

    ! �ε���󳤶����ƣ�16λ�����ε����Ե�ַ��ַ��32λ�����ε���Ȩ�������Ƿ����ڴ桢��д

    ! ����Ȩ�Լ�����һЩ����ģʽ���еı�־���μ�����205--216�С�

135

136 end_move:

137         mov     ax,#SETUPSEG    ! right, forgot this at first. didn't work :-)

138         mov     ds,ax           ! dsָ�򱾳���(setup)�Ρ�

139         lidt    idt_48          ! load idt with 0,0                  ! ����IDT�Ĵ�����

140         lgdt    gdt_48          ! load gdt with whatever appropriate ! ����GDT�Ĵ�����

141

142 ! that was painless, now we enable A20

    ! ���ϵIJ����ܼ򵥣��������ǿ���A20��ַ�ߡ�

    ! Ϊ���ܹ����ʺ�ʹ��1MB���ϵ������ڴ棬������Ҫ���ȿ���A20��ַ�ߡ��μ��������б���

    ! �й�A20�ź��ߵ�˵�����������漰��һЩ�˿ں�����ɲο�kernel/chr_drv/keyboard.S

    ! �����Լ��̽ӿڵ�˵�������ڻ����Ƿ�����������A20��ַ�ߣ����ǻ���Ҫ�ڽ��뱣��ģʽ

    ! ֮���ܷ���1MB�����ڴ�֮���ڲ���һ�¡��������������head.S�����У�32--36�У���

143

144         call    empty_8042              ! ����8042״̬�Ĵ������ȴ����뻺�����ա�

                                            ! ֻ�е����뻺����Ϊ��ʱ�ſ��Զ���ִ��д���

145         mov     al,#0xD1                ! command write ! 0xD1������-��ʾҪд���ݵ�

146         out     #0x64,al                ! 8042��P2�˿ڡ�P2�˿�λ1����A20�ߵ�ѡͨ��

147         call    empty_8042              ! �ȴ����뻺�����գ��������Ƿ񱻽��ܡ�

148         mov     al,#0xDF                ! A20 on        ! ѡͨA20��ַ�ߵIJ�����

149         out     #0x60,al                ! ����Ҫд��0x60�ڡ�

150         call    empty_8042              ! ����ʱ���뻺����Ϊ�գ����ʾA20���Ѿ�ѡͨ��

151

152 ! well, that went ok, I hope. Now we have to reprogram the interrupts :-(

153 ! we put them right after the intel-reserved hardware interrupts, at

154 ! int 0x20-0x2F. There they won't mess up anything. Sadly IBM really

155 ! messed this up with the original PC, and they haven't been able to

156 ! rectify it afterwards. Thus the bios puts interrupts at 0x08-0x0f,

157 ! which is used for the internal hardware interrupts as well. We just

158 ! have to reprogram the 8259's, and it isn't fun.

    !

    ! ϣ������һ���������������DZ������¶��жϽ��б�� :-( ���ǽ����Ƿ�������

    ! ����Intel������Ӳ���жϺ��棬��int 0x20--0x2F�����������Dz��������ͻ��

    ! ���ҵ���IBM��ԭPC���и����ˣ��Ժ�Ҳû�о�������������PC��BIOS���ж�

    ! ������0x08--0x0f����Щ�ж�Ҳ�������ڲ�Ӳ���жϡ��������Ǿͱ������¶�8259

    ! �жϿ��������б�̣���һ�㶼û��˼��

    !

    ! PC��ʹ��2��8259AоƬ�����ڶԿɱ�̿�����8259AоƬ�ı�̷�����μ��������Ľ��ܡ�

    ! ��162���϶���������֣�0x00eb����ֱ��ʹ�û������ʾ�����������תָ�����ʱ���á�

    ! 0xeb��ֱ�ӽ���תָ��IJ����룬��1���ֽڵ����λ��ֵ�������ת��Χ��-127��127��CPU

    ! ͨ����������λ��ֵ�ӵ�EIP�Ĵ����о��γ�һ���µ���Ч��ַ����ʱEIPָ����һ����ִ��

    ! ��ָ�ִ��ʱ�����ѵ�CPUʱ����������7��10����0x00eb ��ʾ��תֵ��0��һ��ָ���

    ! �˻���ֱ��ִ����һ��ָ�������ָ����ṩ14--20��CPUʱ�����ڵ��ӳ�ʱ�䡣��as86

    ! ��û�б�ʾ��Ӧָ������Ƿ������Linus��setup.s��һЩ�������о�ֱ��ʹ�û���������

    ! ʾ����ָ����⣬ÿ���ղ���ָ��NOP��ʱ����������3���������Ҫ�ﵽ��ͬ���ӳ�Ч����

    ! ��Ҫ6��7��NOPָ�

159

    ! 8259оƬ��Ƭ�˿���0x20-0x21����Ƭ�˿���0xA0-0xA1�����ֵ0x11��ʾ��ʼ�����ʼ��

    ! ����ICW1�����֣���ʾ���ش�������Ƭ8259���������Ҫ����ICW4�����֡�

160         mov     al,#0x11                ! initialization sequence

161         out     #0x20,al                ! send it to 8259A-1  ! ���͵�8259A��оƬ��

162         .word   0x00eb,0x00eb           ! jmp $+2, jmp $+2    ! '$'��ʾ��ǰָ��ĵ�ַ��

163         out     #0xA0,al                ! and to 8259A-2      ! �ٷ��͵�8259A��оƬ��

164         .word   0x00eb,0x00eb

    ! LinuxϵͳӲ���жϺű����óɴ�0x20��ʼ���μ���3-2��Ӳ���ж������ź����жϺŶ�Ӧ����

165         mov     al,#0x20                ! start of hardware int's (0x20)

166         out     #0x21,al                ! ����оƬICW2�����֣�������ʼ�жϺţ�Ҫ����˿ڡ�

167         .word   0x00eb,0x00eb

168         mov     al,#0x28                ! start of hardware int's 2 (0x28)

169         out     #0xA1,al                ! �ʹ�оƬICW2�����֣���оƬ����ʼ�жϺš�

170         .word   0x00eb,0x00eb

171         mov     al,#0x04                ! 8259-1 is master

172         out     #0x21,al                ! ����оƬICW3�����֣���оƬ��IR2����оƬINT��

                                            ���μ������б����˵����

173         .word   0x00eb,0x00eb

174         mov     al,#0x02                ! 8259-2 is slave

175         out     #0xA1,al                ! �ʹ�оƬICW3�����֣���ʾ��оƬ��INT������о

                                            ! Ƭ��IR2�����ϡ�

176         .word   0x00eb,0x00eb

177         mov     al,#0x01                ! 8086 mode for both

178         out     #0x21,al                ! ����оƬICW4�����֡�8086ģʽ����ͨEOI���ǻ���

                                            ! ��ʽ���跢��ָ������λ����ʼ��������оƬ������

179         .word   0x00eb,0x00eb

180         out     #0xA1,al                ���ʹ�оƬICW4�����֣�����ͬ�ϡ�

181         .word   0x00eb,0x00eb

182         mov     al,#0xFF                ! mask off all interrupts for now

183         out     #0x21,al                ! ������оƬ�����ж�����

184         .word   0x00eb,0x00eb

185         out     #0xA1,al                �����δ�оƬ�����ж�����

186

187 ! well, that certainly wasn't fun :-(. Hopefully it works, and we don't

188 ! need no steenking BIOS anyway (except for the initial loading :-).

189 ! The BIOS-routine wants lots of unnecessary data, and it's less

190 ! "interesting" anyway. This is how REAL programmers do it.

191 !

192 ! Well, now's the time to actually move into protected mode. To make

193 ! things as simple as possible, we do no register set-up or anything,

194 ! we let the gnu-compiled 32-bit programs do that. We just jump to

195 ! absolute address 0x00000, in 32-bit protected mode.

    !

    ! �ߣ�������α�̵�Ȼû��:-(����ϣ�������ܹ�������������Ҳ������Ҫ��ζ��BIOS

    ! �ˣ����˳�ʼ����:-)��BIOS�ӳ���Ҫ��ܶ಻��Ҫ�����ݣ�������һ�㶼ûȤ������

    ! ���������ij���Ա�������¡�

    !

    ! ���ˣ�������������ʼ���뱣��ģʽ��ʱ���ˡ�Ϊ�˰��������þ����򵥣����Dz�����

    ! �Ĵ������ݽ����κ����á�������gnu�����32λ����ȥ������Щ�¡��ڽ���32λ��

    ! ��ģʽʱ���ǽ��Ǽ򵥵���ת�����Ե�ַ0x00000����

196

    ! �������ò�����32λ����ģʽ���С����ȼ��ػ���״̬��(lmsw-Load Machine Status Word)��

    ! Ҳ�ƿ��ƼĴ���CR0�������λ0��1������CPU�л�������ģʽ��������������Ȩ��0�У���

    ! ��ǰ��Ȩ��CPL=0����ʱ�μĴ�����Ȼָ����ʵ��ַģʽ����ͬ�����Ե�ַ������ʵ��ַģʽ��

    ! ���Ե�ַ�������ڴ��ַ��ͬ���������øñ���λ�����һ��ָ�������һ���μ���תָ����

    ! ����ˢ��CPU��ǰָ����С���ΪCPU����ִ��һ��ָ��֮ǰ���Ѵ��ڴ��ȡ��ָ��������

    ! ���롣Ȼ���ڽ��뱣��ģʽ�Ժ���Щ����ʵģʽ��Ԥ��ȡ�õ�ָ����Ϣ�ͱ�ò�����Ч����һ��

    ! �μ���תָ��ͻ�ˢ��CPU�ĵ�ǰָ����У���������Щ��Ч��Ϣ�����⣬��Intel��˾���ֲ�

    ! �Ͻ���80386������CPUӦ��ʹ��ָ����mov cr0,ax���л�������ģʽ��lmswָ������ڼ�����

    ! ǰ��286 CPU��

 

197         mov     ax,#0x0001      ! protected mode (PE) bit        ! ����ģʽ����λ(PE)��

198         lmsw    ax              ! This is it!                    ! ���������ػ���״̬��!

199         jmpi    0,8             ! jmp offset 0 of segment 8 (cs) ! ��ת��cs��ƫ��0����

    ! �����Ѿ���systemģ���ƶ���0x00000��ʼ�ĵط��������Ͼ��е�ƫ�Ƶ�ַ��0������ֵ8�Ѿ�

    ! �DZ���ģʽ�µĶ�ѡ����ˣ�����ѡ�����������������������Լ���Ҫ�����Ȩ������ѡ�����

    ! ��Ϊ16λ��2�ֽڣ���λ0-1��ʾ�������Ȩ��0--3����Linux����ϵͳֻ�õ�������0������

    ! �˼�����3�����û�������λ2����ѡ��ȫ������������0�����Ǿֲ���������(1)��λ3-15����

    ! ���������������ָ��ѡ��ڼ��������������Զ�ѡ���8��0b0000,0000,0000,1000����ʾ����

    ! ��Ȩ��0��ʹ��ȫ����������GDT�е�2���������������ָ������Ļ���ַ��0���μ�571�У���

    ! ����������תָ��ͻ�ȥִ��system�еĴ��롣���⣬

200

201 ! This routine checks that the keyboard command queue is empty

202 ! No timeout is used - if this hangs there is something wrong with

203 ! the machine, and we probably couldn't proceed anyway.

    ! ��������ӳ����������������Ƿ�Ϊ�ա����ﲻʹ�ó�ʱ���� -

    ! ���������������˵��PC�������⣬���Ǿ�û�а취�ٴ�����ȥ�ˡ�

    !

    ! ֻ�е����뻺����Ϊ��ʱ�����̿�����״̬�Ĵ���λ1 = 0���ſ��Զ���ִ��д���

204 empty_8042:

205         .word   0x00eb,0x00eb

206         in      al,#0x64        ! 8042 status port         ! ��AT���̿�����״̬�Ĵ�����

207         test    al,#2           ! is input buffer full?    ! ����λ1�����뻺��������

208         jnz     empty_8042      ! yes - loop

209         ret

210

211 ! Routine trying to recognize type of SVGA-board present (if any)

212 ! and if it recognize one gives the choices of resolution it offers.

213 ! If one is found the resolution chosen is given by al,ah (rows,cols).

    ! ����������ʶ��SVGA��ʾ�������еĻ������ӳ�����ʶ���һ������û�

    ! �ṩѡ��ֱ��ʵĻ��ᣬ���ѷֱ��ʷ���Ĵ���al��ah���С��У��з��ء�

    !

    ! ע������215--566�д���ǣ�浽�ڶ���ʾ���˿���Ϣ����˱Ƚϸ��ӡ���������δ������ں�

    ! ���й�ϵ������˿�������������

    ! ����������ʾ588���ϵ�msg1�ַ�����"��<�س���>�鿴���ڵ�SVGAģʽ�������������"����

    ! Ȼ��ѭ����ȡ���̿�����������������ȴ��û�����������û����»س�����ȥ���ϵͳ����

    ! ��SVGAģʽ������AL��AH�з����������ֵ����������Ĭ��ֵAL=25�С�AH=80�в����ء�

214

215 chsvga: cld

216         push    ds               ! ����dsֵ������231�У���490��492�У�������

217         push    cs               ! ��Ĭ�����ݶ����óɺʹ����ͬһ���Ρ�

218         pop     ds

219         mov     ax,#0xc000

220         mov     es,ax            ! es ָ��0xc000�Ρ��˴���VGA���ϵ�ROM BIOS����

221         lea     si,msg1          ! ds:siָ��msg1�ַ�����

222         call    prtstr           ! ��ʾ��NULL��β��msg1�ַ�����

223 nokey:  in      al,#0x60         ! ��ȡ���̿�������������������Լ��̵�ɨ����������

224         cmp     al,#0x82         ! ����յ���0x82С��ɨ�������ǽ�ͨɨ���룬��Ϊ0x82��

225         jb      nokey            ! ��С�Ͽ�ɨ����ֵ��С��0x82��ʾ��û�а����ɿ���

226         cmp     al,#0xe0         ! ���ɨ�������0xe0����ʾ�յ�������չɨ����ǰ׺��

227         ja      nokey

228         cmp     al,#0x9c         ! ����Ͽ�ɨ������0x9c����ʾ�û�����/�ɿ��˻س�����

229         je      svga             ! ���dz�����תȥ���ϵͳ�Ƿ����SVGAģʽ��

230         mov     ax,#0x5019       ! �����AX�з�������ֵĬ������ΪAL=25�С�AH=80�С�

231         pop     ds

232         ret

    ! �������VGA��ʾ���ϵ�ROM BIOSָ��λ�ô����������ݴ�����֧�ֵ��ر������жϻ�����

    ! ��װ����ʲô���ӵ���ʾ����������֧��10����ʾ������չ���ܡ�ע�⣬��ʱ�����Ѿ��ڵ�

    ! 220�а�esָ��VGA����ROM BIOS���ڵĶ�0xc000���μ���2�£���

    ! �����ж��Dz���ATI��ʾ�������ǰ� ds:siָ��595����ATI��ʾ���������ݴ�������es:siָ

    ! ��VGA BIOS��ָ��λ�ã�ƫ��0x31��������Ϊ������������9���ַ���"761295520"���������

    ! ��ѭ���Ƚ�����������������ͬ���ʾ�����е�VGA����ATI���ӵģ�������ds:siָ�����

    ! ʾ���������õ�����ģʽֵdscati����615�У�����diָ��ATI�������õ����и�����ģʽ��

    ! ����ת�����selmod��438�У�����һ���������á�

233 svga:   lea     si,idati         ! Check ATI 'clues'  ! ����ж� ATI��ʾ�������ݡ�

234         mov     di,#0x31         ! ��������0xc000:0x0031��ʼ��

235         mov     cx,#0x09         ! ��������9���ֽڡ�

236         repe

237         cmpsb

238         jne     noati            ! ����������ͬ���ʾ����ATI��ʾ������ת������⿨��

239         lea     si,dscati        ! ���9���ֽڶ���ͬ����ʾϵͳ����һ��ATI����ʾ����

240         lea     di,moati         ! ����siָ��ATI�����еĿ�ѡ����ֵ��diָ���ѡ����

241         lea     cx,selmod        ! ��ģʽ�б���Ȼ����ת��selmod��438�У�������������

242         jmp     cx

 

    ! �������ж��Dz���Ahead���ӵ���ʾ����������EGA/VGA ͼ�������Ĵ���0x3ceд������ʵ�

    ! �������Ĵ���������0x0f��ͬʱ��0x3cf�˿ڣ���ʱ��Ӧ�������Ĵ�����д�뿪����չ�Ĵ���

    ! ��־ֵ0x20��Ȼ��ͨ��0x3cf�˿ڶ�ȡ�������Ĵ���ֵ���Լ���Ƿ�������ÿ�����չ�Ĵ���

    ! ��־�����������˵����Ahead���ӵ���ʾ����ע��word���ʱal���˿�n��ah���˿�n+1��

243 noati:  mov     ax,#0x200f       ! Check Ahead 'clues'

244         mov     dx,#0x3ce        ! ���ݶ˿�ָ���������Ĵ�����0x0f��0x3ce�˿ڣ���

245         out     dx,ax            ! �����ÿ�����չ�Ĵ�����־��0x20��0x3cf�˿ڣ���

246         inc     dx               ! Ȼ���ٶ�ȡ�üĴ��������ñ�־�Ƿ������ϡ�

247         in      al,dx

248         cmp     al,#0x20         ! �����ȡֵ��0x20�����ʾ��Ahead A��ʾ����

249         je      isahed           ! �����ȡֵ��0x21�����ʾ��Ahead B��ʾ����

250         cmp     al,#0x21         ! ����˵������Ahead��ʾ����������ת����������࿨��

251         jne     noahed

252 isahed: lea     si,dscahead      ! si ָ��Ahead��ʾ����ѡ����ֵ����diָ����չģʽ��

253         lea     di,moahead       ! ������չģʽ���б���Ȼ����ת��selmod��438�У�����

254         lea     cx,selmod        ! ��������

255         jmp     cx

 

    ! ����������Dz���Chips & Tech��������ʾ����ͨ���˿�0x3c3��0x94��0x46e8������VGA����

    ! �Ĵ����Ľ�������ģʽ��־��λ4����Ȼ��Ӷ˿�0x104��ȡ��ʾ��оƬ����ʶֵ������ñ�ʶֵ

    ! ��0xA5����˵����Chips & Tech��������ʾ����

256 noahed: mov     dx,#0x3c3        ! Check Chips & Tech. 'clues'

257         in      al,dx            ! ��0x3c3�˿ڶ�ȡVGA�����Ĵ���ֵ�������Ͻ�������ģʽ

258         or      al,#0x10         ! ��־��λ4������д�ء�

259         out     dx,al

260         mov     dx,#0x104        ! ������ģʽʱ��ȫ�ֱ�ʶ�˿�0x104��ȡ��ʾ��оƬ��ʶֵ��

261         in      al,dx            ! ����ʱ�����bl�Ĵ����С�

262         mov     bl,al

263         mov     dx,#0x3c3        ! Ȼ���0x3c3�˿��еĽ�������ģʽ��־��λ��

264         in      al,dx

265         and     al,#0xef

266         out     dx,al

267         cmp     bl,[idcandt]     ! �ٰ�bl�б�ʶֵ��λ��idcandt������596�У���Chips &

268         jne     nocant           ! Tech�ı�ʶֵ0xA5���Ƚϡ������ͬ����ת�Ƚ���һ���Կ���

269         lea     si,dsccandt      ! ��siָ��������ʾ���Ŀ�ѡ����ֵ����diָ����չģʽ����

270         lea     di,mocandt       ! ����չģʽ���б���Ȼ����ת��selmod��438�У���������

271         lea     cx,selmod        ! ��ʾģʽ�IJ�����

272         jmp     cx

 

    ! ���ڼ���Dz���Cirrus��ʾ����������ʹ��CRT������������0x1f�Ĵ��������������Խ�ֹ��չ

    ! ���ܡ��üĴ�������Ϊӥ�꣨Eagle ID���Ĵ���������ֵ�ߵͰ��ֽڽ���һ�º�д��˿�0x3c4��

    ! ����6�ţ�����/��չ���Ĵ���Ӧ�û��ֹCirrus��ʾ������չ���ܡ����������˵������Cirrus

    ! ��ʾ������Ϊ�Ӷ˿�0x3d4������0x1fӥ��Ĵ����ж�ȡ��������ӥ��ֵ��0x0c�����Ŷ�Ӧ����

    ! ����ʼ��ַ���ֽڼĴ�������������֮���ֵ������ڶ�0x1f������֮ǰ������Ҫ�Ȱ��Դ���ʼ

    ! ���ֽڼĴ������ݱ�������㣬���ڼ���ָ�֮�����⣬��û�н�������Eagle IDֵд��0x3c4

    ! �˿�������6�Ŷ���/��չ�Ĵ��������¿�����չ���ܡ�

273 nocant: mov     dx,#0x3d4        ! Check Cirrus 'clues'

274         mov     al,#0x0c         ! ������CRT���ƼĴ����������Ĵ����˿�0x3d4д��Ҫ����

275         out     dx,al            ! �ļĴ���������0x0c����Ӧ�Դ���ʼ��ַ���ֽڼĴ�������

276         inc     dx               ! Ȼ���0x3d5�˿ڶ����Դ���ʼ��ַ���ֽڲ��ݴ���bl�У�

277         in      al,dx            ! �ٰ��Դ���ʼ��ַ���ֽڼĴ������㡣

278         mov     bl,al

279         xor     al,al

280         out     dx,al

281         dec     dx               ! ������0x3d4�˿��������0x1f��ָ������Ҫ��0x3d5�˿�

282         mov     al,#0x1f         ! ���ʶ�ȡ��Eagle ID���Ĵ������ݡ�

283         out     dx,al

284         inc     dx

285         in      al,dx            ! ��0x3d5�˿ڶ�ȡ��Eagle ID���Ĵ���ֵ�����ݴ���bh�С�

286         mov     bh,al            ! Ȼ��Ѹ�ֵ�ߵ�4���ػ���λ�ô�ŵ�cl�С�������8λ

287         xor     ah,ah            ! �����ch�У���cl�з�����ֵ6��

288         shl     al,#4

289         mov     cx,ax

290         mov     al,bh

291         shr     al,#4

292         add     cx,ax

293         shl     cx,#8

294         add     cx,#6            ! ����cxֵ�����ax�С���ʱah���ǻ�λ��ġ�Eagle

295         mov     ax,cx            ! ID��ֵ��al����������6����Ӧ����/��չ�Ĵ�������ah

296         mov     dx,#0x3c4        ! д��0x3c4�˿������Ķ���/��չ�Ĵ���Ӧ�ûᵼ��Cirrus

297         out     dx,ax            ! ��ʾ����ֹ��չ���ܡ�

298         inc     dx

299         in      al,dx            ! �����չ������ı���ֹ����ô��ʱ�����ֵӦ��Ϊ0��

300         and     al,al            ! �����Ϊ0���ʾ����Cirrus��ʾ������ת���������������

301         jnz     nocirr

302         mov     al,bh            ! ��Cirrus��ʾ���������õ�286�б�����bh�еġ�Eagle

303         out     dx,al            ! ID��ԭֵ�����¿���Cirrus����չ���ܡ���ʱ��ȡ�ķ���

304         in      al,dx            ! ֵӦ��Ϊ1�������ǣ�����Ȼ˵������Cirrus��ʾ����

305         cmp     al,#0x01

306         jne     nocirr

307         call    rst3d4           ! �ָ�CRT����������ʾ��ʼ��ַ���ֽڼĴ������ݡ�

308         lea     si,dsccirrus     ! siָ��Cirrus��ʾ���Ŀ�ѡ����ֵ��diָ����չģʽ����

309         lea     di,mocirrus      ! �Ͷ�Ӧģʽ�š�Ȼ����ת��selmod��ȥѡ����ʾģʽ��

310         lea     cx,selmod

311         jmp     cx

    ! ���ӳ������ñ�����bl�е�ֵ����278�У��ָ�CRT����������ʾ��ʼ��ַ���ֽڼĴ������ݡ�

312 rst3d4: mov     dx,#0x3d4

313         mov     al,bl

314         xor     ah,ah

315         shl     ax,#8

316         add     ax,#0x0c

317         out     dx,ax            ! ע�⣬����word������� al ��0x3d4��ah ��0x3d5��

318         ret    

 

    ! ���ڼ��ϵͳ���Dz���Everex��ʾ���������������ж�int 0x10����0x70��ax =0x7000��

    ! bx=0x0000������Everex����չ��ƵBIOS���ܡ�����Everes������ʾ�������жϵ���Ӧ��

    ! �᷵��ģ��״̬���������·�����Ϣ��

    ! al = 0x70�����ǻ���Trident��Everex��ʾ����

    ! cl = ��ʾ�����ͣ�00-��ɫ��01-CGA��02-EGA��03-���ֶ�Ƶ��04-PS/2��05-IBM 8514��06-SVGA��

    ! ch = ���ԣ�λ7-6��00-256K��01-512K��10-1MB��11-2MB��λ4-����VGA������λ0-6845ģ�⡣

    ! dx = �忨�ͺţ�λ15-4�������ͱ�ʶ�ţ�λ3-0����������ʶ�š�

    !      0x2360-Ultragraphics II��0x6200-Vision VGA��0x6730-EVGA��0x6780-Viewpoint��

    ! di = ��BCD���ʾ����ƵBIOS�汾�š�

319 nocirr: call    rst3d4           ! Check Everex 'clues'

320         mov     ax,#0x7000       ! ����ax = 0x7000, bx=0x0000������int 0x10��

321         xor     bx,bx

322         int     0x10

323         cmp     al,#0x70         ! ����Everes��ʾ����al��Ӧ�÷���ֵ0x70��

324         jne     noevrx

325         shr     dx,#4            ! ���ɰ������ţ�λ3-0����

326         cmp     dx,#0x678        ! �����ͺ���0x678��ʾ��һ��Trident��ʾ��������ת��

327         je      istrid

328         cmp     dx,#0x236        ! �����ͺ���0x236��ʾ��һ��Trident��ʾ��������ת��

329         je      istrid

330         lea     si,dsceverex     ! ��siָ��Everex��ʾ���Ŀ�ѡ����ֵ������diָ����չ

331         lea     di,moeverex      ! ģʽ������ģʽ���б���Ȼ����ת��selmodȥִ��ѡ��

332         lea     cx,selmod        ! ��ʾģʽ�IJ�����

333         jmp     cx

334 istrid: lea     cx,ev2tri        ! ��Trident���͵�Everex��ʾ��������ת��ev2tri������

335         jmp     cx

 

    ! ���ڼ���Dz���Genoa��ʾ������ʽ�Ǽ������ƵBIOS�е��������ִ���0x77��0x00��0x66��

    ! 0x99����ע�⣬��ʱes�Ѿ��ڵ�220�б����ó�ָ��VGA����ROM BIOS���ڵĶ�0xc000��

336 noevrx: lea     si,idgenoa       ! Check Genoa 'clues'

337         xor     ax,ax            ! ��ds:siָ���597���ϵ��������ִ���

338         seg es

339         mov     al,[0x37]        ! ȡVGA����BIOS��0x37����ָ�루��ָ������������

340         mov     di,ax            ! ��˴�ʱes:diָ���������ִ���ʼ����

341         mov     cx,#0x04

342         dec     si

343         dec     di

344 l1:     inc     si               ! Ȼ��ѭ���Ƚ���4���ֽڵ��������ִ���

345         inc     di

346         mov     al,(si)

347         seg es

348         and     al,(di)

349         cmp     al,(si)

350         loope   l1

351         cmp     cx,#0x00         ! ����������ִ���ȫ��ͬ�����ʾ��Genoa��ʾ����

352         jne     nogen            ! ������תȥ����������͵���ʾ����

353         lea     si,dscgenoa      ! ��siָ��Genoa��ʾ���Ŀ�ѡ����ֵ������diָ����չ

354         lea     di,mogenoa       ! ģʽ������ģʽ���б���Ȼ����ת��selmodȥִ��ѡ��

355         lea     cx,selmod        ! ��ʾģʽ�IJ�����

356         jmp     cx

 

    ! ���ڼ���Dz���Paradise��ʾ����ͬ���Dz��ñȽ���ʾ����BIOS������������VGA=�����ķ�ʽ��

357 nogen:  lea     si,idparadise    ! Check Paradise 'clues'

358         mov     di,#0x7d         ! es:diָ��VGA ROM BIOS��0xc000:0x007d�����ô�Ӧ����

359         mov     cx,#0x04         ! 4���ַ���VGA=����

360         repe

361         cmpsb

362         jne     nopara           ! ���в�ͬ���ַ�����ʾ����Paradise��ʾ����������ת��

363         lea     si,dscparadise   ! ������siָ��Paradise��ʾ���Ŀ�ѡ����ֵ������diָ

364         lea     di,moparadise    ! ����չģʽ������ģʽ���б���Ȼ����ת��selmod��ȥѡ

365         lea     cx,selmod        ! ����Ҫʹ�õ���ʾģʽ��

366         jmp     cx

 

    ! ���ڼ���Dz���Trident��TVGA����ʾ����TVGA��ʾ�������ģʽ���ƼĴ���1��0x3c4�˿�����

    ! ��0x0e����λ3--0��64K�ڴ�ҳ�����ֵ������ֶ�ֵ��һ�����ԣ���д��ʱ��������Ҫ���Ȱ�

    ! ֵ��0x02��������������д�룻����ȡ��ֵʱ����Ҫִ���������������ǰ��ֵӦ����д

    ! ����ٶ�ȡ��ֵ��ͬ���������������������������Dz���Trident��ʾ����

367 nopara: mov     dx,#0x3c4        ! Check Trident 'clues'

368         mov     al,#0x0e         ! �����ڶ˿�0x3c4���������0x0e������ģʽ���ƼĴ���1��

369         out     dx,al            ! Ȼ���0x3c5���ݶ˿ڶ���üĴ���ԭֵ�����ݴ���ah�С�

370         inc     dx

371         in      al,dx

372         xchg    ah,al

373         mov     al,#0x00         ! Ȼ��������üĴ���д��0x00���ٶ�ȡ��ֵ��al��

374         out     dx,al            ! д��0x00���൱�ڡ�ԭֵ��0x02���0x02���д��ֵ��

375         in      al,dx            ! �������Trident��ʾ������˺�����ֵӦ����0x02��

376         xchg    al,ah            ! ������al=ԭģʽ���ƼĴ���1��ֵ��ah=����ȡ��ֵ��

    ! �����������Ӣ��ע���ǡ������...���в�û��Ҫ��������������������ҵ�Trident��ʾ��

    ! �����á����������������Ļ�ͻ��ģ��...�����⼸�и�����Ӣ��ע�͵����ִ�����²�����

    ! ���bl��ԭģʽ���ƼĴ���1��λ1����λ״̬�Ļ��ͽ��临λ������ͽ�λ1��λ��

    ! ʵ�����⼸�������Ƕ�ԭģʽ���ƼĴ���1��ִֵ����� 0x02�IJ�����Ȼ���ý��ֵȥ����

    ! ���ָ���ԭ�Ĵ���ֵ��

377         mov     bl,al            ! Strange thing ... in the book this wasn't

378         and     bl,#0x02         ! necessary but it worked on my card which

379         jz      setb2            ! is a trident. Without it the screen goes

380         and     al,#0xfd         ! blurred ...

381         jmp     clrb2            !

382 setb2:  or      al,#0x02         !

383 clrb2:  out     dx,al

384         and     ah,#0x0f         ! ȡ375��������ֵ��ҳ������ֶΣ�λ3--0�������

385         cmp     ah,#0x02         ! ���ֶ�ֵ����0x02�����ʾ��Trident��ʾ����

386         jne     notrid

387 ev2tri: lea     si,dsctrident    ! ��Trident��ʾ����������siָ�����ʾ���Ŀ�ѡ����

388         lea     di,motrident     ! ֵ�б�����diָ���Ӧ��չģʽ������ģʽ���б���Ȼ

389         lea     cx,selmod        ! ����ת��selmodȥִ��ģʽѡ�������

390         jmp     cx

 

    ! ���ڼ���Dz���Tseng��ʾ����ET4000AX��ET4000/W32�ࣩ�������Ƕ�0x3cd�˿ڶ�Ӧ�Ķ�

    ! ѡ��Segment Select���Ĵ���ִ�ж�д�������üĴ�����4λ��λ7--4����Ҫ���ж�������

    ! 64KB�κţ�Bank number������4λ��λ3--0����ָ��Ҫд�Ķκš����ָ����ѡ��Ĵ�����

    ! ��ֵ�� 0x55����ʾ����д��6��64KB�Σ�����ô����Tseng��ʾ����˵���Ѹ�ֵд��Ĵ���

    ! ���ٶ���Ӧ�û���0x55��

391 notrid: mov     dx,#0x3cd        ! Check Tseng 'clues'

392         in      al,dx            ! Could things be this simple ! :-)

393         mov     bl,al            ! �ȴ�0x3cd�˿ڶ�ȡ��ѡ��Ĵ���ԭֵ����������bl�С�

394         mov     al,#0x55         ! Ȼ��������üĴ�����д��0x55���ٶ��벢����ah�С�

395         out     dx,al

396         in      al,dx

397         mov     ah,al

398         mov     al,bl            ! ���Żָ��üĴ�����ԭֵ��

399         out     dx,al

400         cmp     ah,#0x55         ! �����ȡ�ľ�������д���ֵ���������Tseng��ʾ����

401         jne     notsen

402         lea     si,dsctseng      ! ������siָ��Tseng��ʾ���Ŀ�ѡ����ֵ���б�����di

403         lea     di,motseng       ! ָ���Ӧ��չģʽ������ģʽ���б���Ȼ����ת��selmod

404         lea     cx,selmod        ! ȥִ��ģʽѡ�������

405         jmp     cx

 

    ! �������Dz���Video7��ʾ�����˿�0x3c2�ǻ������Ĵ���д�˿ڣ���0x3cc�ǻ������Ĵ�

    ! �����˿ڡ��üĴ�����λ0�ǵ�ɫ/��ɫ��־�����Ϊ0���ʾ�ǵ�ɫ�������Dz�ɫ���ж��Dz���

    ! Video7��ʾ���ķ�ʽ������������ʾ����CRT������չ��ʶ�Ĵ�������������0x1f�����üĴ���

    ! ��ֵʵ���Ͼ����Դ���ʼ��ַ���ֽڼĴ�����������0x0c�������ݺ�0xea�������������ֵ��

    ! �������ֻҪ���Դ���ʼ��ַ���ֽڼĴ�����д��һ���ض�ֵ��Ȼ��ӱ�ʶ�Ĵ����ж�ȡ��ʶֵ

    ! �����жϼ��ɡ�

    ! ͨ����������ʾ��������Video7��ʾ���ļ����������ǿ�֪������ͨ����Ϊ�����������衣

    ! ���ȶ�ȡ�����������Ҫ�õ��ļĴ���ԭֵ��Ȼ��ʹ���ض�����ֵ����д��Ͷ�������������

    ! ��ԭ�Ĵ���ֵ���Լ���������жϡ�

406 notsen: mov     dx,#0x3cc        ! Check Video7 'clues'

407         in      al,dx

408         mov     dx,#0x3b4        ! ������dxΪ��ɫ��ʾCRT���������Ĵ����˿ں�0x3b4��

409         and     al,#0x01         ! ����������Ĵ�����λ0����0����ɫ����ֱ����ת��

410         jz      even7            ! ����dx����Ϊ��ɫ��ʾCRT���������Ĵ����˿ں�0x3d4��

411         mov     dx,#0x3d4

412 even7:  mov     al,#0x0c         ! ���üĴ���������Ϊ0x0c����Ӧ�Դ���ʼ��ַ���ֽڼĴ�����

413         out     dx,al

414         inc     dx

415         in      al,dx            ! ��ȡ��ʾ�ڴ���ʼ��ַ���ֽڼĴ������ݣ���������bl�С�

416         mov     bl,al

417         mov     al,#0x55         ! Ȼ�����Դ���ʼ��ַ���ֽڼĴ�����д��ֵ0x55���ٶ�ȡ������

418         out     dx,al

419         in      al,dx

420         dec     dx               ! Ȼ��ͨ��CRTC�����Ĵ����˿�0x3b4��0x3d4ѡ����������

421         mov     al,#0x1f         ! 0x1f��Video7��ʾ����ʶ�Ĵ������üĴ�������ʵ���Ͼ���

422         out     dx,al            ! �Դ���ʼ��ַ���ֽں�0xea������������Ľ��ֵ��

423         inc     dx

424         in      al,dx            ! ��ȡVideo7��ʾ����ʶ�Ĵ���ֵ����������bh�С�

425         mov     bh,al

426         dec     dx               ! Ȼ����ѡ���Դ���ʼ��ַ���ֽڼĴ������ָ���ԭֵ��

427         mov     al,#0x0c

428         out     dx,al

429         inc     dx

430         mov     al,bl

431         out     dx,al

432         mov     al,#0x55         ! �����������֤��Video7��ʾ����ʶ�Ĵ���ֵ�����Դ���ʼ

433         xor     al,#0xea         ! ��ַ���ֽں�0xea������������Ľ��ֵ�������0x55

434         cmp     al,bh            ! ��0xea�����������Ľ����Ӧ�õ��ڱ�ʶ�Ĵ����IJ���ֵ��

435         jne     novid7           ! ������Video7��ʾ����������Ĭ����ʾ����ֵ��492�У���

436         lea     si,dscvideo7     ! ��Video7��ʾ����������siָ�����ʾ������ֵ������di

437         lea     di,movideo7      ! ָ����չģʽ������ģʽ���б���

 

    ! ����������������жϳ�����ʾ�������Լ�ȡ�õ������չģʽ��Ϣ��siָ�������ֵ�б���di

    ! ָ����չģʽ������ģʽ���б�������ʾ�û�ѡ����õ���ʾģʽ�������ó���Ӧ��ʾģʽ�����

    ! �ӳ��򷵻�ϵͳ��ǰ���õ���Ļ����ֵ��ah = ������al=�����������磬���ϵͳ����ATI��ʾ����

    ! ��ô��Ļ�ϻ���ʾ������Ϣ��

    ! Mode:  COLSxROWS:

    ! 0.     132 x 25

    ! 1.     132 x 44

    ! Choose mode by pressing the corresponding number.

    !

    ! ��γ�����������Ļ����ʾNULL��β���ַ�����Ϣ��Mode:  COLSxROWS:����

438 selmod: push    si

439         lea     si,msg2

440         call    prtstr

441         xor     cx,cx

442         mov     cl,(di)          ! ��ʱcl���Ǽ�������ʾ������չģʽ������

443         pop     si

444         push    si

445         push    cx

    ! Ȼ����ÿһ������ʾ����ǰ��ʾ����ѡ�����չģʽ����ֵ�����û�ѡ�á�

446 tbl:    pop     bx               ! bx = ��ʾ������չģʽ�ܸ�����

447         push    bx

448         mov     al,bl

449         sub     al,cl

450         call    dprnt            ! ��ʮ���Ƹ�ʽ��ʾal�е�ֵ��

451         call    spcing           ! ��ʾһ�����ٿ�4���ո�

452         lodsw                    ! ��ax�м���siָ�������ֵ�����siָ����һ��wordֵ��

453         xchg    al,ah            ! ����λ�ú�al = ������

454         call    dprnt            ! ��ʾ������

455         xchg    ah,al            ! ��ʱal��������ֵ��

456         push    ax

457         mov     al,#0x78         ! ��ʾһ��С��x�������˺š�

458         call    prnt1

459         pop     ax               ! ��ʱal��������ֵ��

460         call    dprnt            ! ��ʾ������

461         call    docr             ! �س����С�

462         loop    tbl              ! ����ʾ��һ������ֵ��cx����չģʽ����ֵ�ݼ�1��

    ! ����չģʽ����ֵ����ʾ֮����ʾ��Choose mode by pressing the corresponding number.����

    ! Ȼ��Ӽ��̿ڶ�ȡ�û�������ɨ���룬���ݸ�ɨ����ȷ���û�ѡ�������ֵģʽ�ţ�������ROM

    ! BIOS����ʾ�ж�int 0x10����0x00��������Ӧ����ʾģʽ��

    ! ��468�е���ģʽ����ֵ+0x80�����������ּ�-1���ɿ�ɨ���롣����0--9���ּ������ǵ��ɿ�

    ! ɨ����ֱ��ǣ�0 - 0x8B��1 - 0x82��2 - 0x83��3 - 0x84��4 - 0x85��

    !               5 - 0x86��6 - 0x87��7 - 0x88��8 - 0x89��9 - 0x8A��

    ! ��ˣ������ȡ�ļ����ɿ�ɨ����С��0x82�ͱ�ʾ�������ּ������ɨ�������0x8B���ʾ�û�

    ! ��������0����

463         pop     cx               ! cl������ʾ����չģʽ�ܸ���ֵ��

464         call    docr

465         lea     si,msg3          ! ��ʾ���밴��Ӧ���ּ���ѡ��ģʽ����

466         call    prtstr

467         pop     si               ! ����ԭ����ֵָ�루ָ����ʾ������ֵ����ʼ������

468         add     cl,#0x80         ! cl + 0x80 = ��Ӧ�����ּ�-1�����ɿ�ɨ���롣

469 nonum:  in      al,#0x60         ! Quick and dirty...

470         cmp     al,#0x82         ! �������ɿ�ɨ����С��0x82���ʾ�������ּ������ɸü���

471         jb      nonum

472         cmp     al,#0x8b         ! �������ɿ�ɨ�������0x8b����ʾ���������ּ�0��

473         je      zero

474         cmp     al,cl            ! ��ɨ���������չģʽ����ֵ��Ӧ�����ɨ����ֵ����ʾ

475         ja      nonum            ! �����ֵ������Χ�������ּ����ɿ�ɨ���롣�����ʾ

476         jmp     nozero           ! �û����²��ɿ���һ����0���ְ�����

    ! ������ɿ�ɨ����ת���ɶ�Ӧ�����ְ���ֵ��Ȼ�����ø�ֵ��ģʽ������ģʽ���б���ѡ���Ӧ��

    ! ��ģʽ�š����ŵ��û���ROM BIOS�ж�int 0x10����0����Ļ���ó�ģʽ��ָ����ģʽ�������

    ! ����ģʽ�Ŵ���ʾ������ֵ����ѡ����ax�з��ض�Ӧ������ֵ��

477 zero:   sub     al,#0x0a         ! al = 0x8b - 0x0a = 0x81��

478 nozero: sub     al,#0x80         ! �ټ�ȥ0x80�Ϳ��Եõ��û�ѡ���˵ڼ���ģʽ��

479         dec     al               ! ��0�������

480         xor     ah,ah            ! int 0x10��ʾ���ܺ�=0��������ʾģʽ����

481         add     di,ax

482         inc     di               ! diָ���Ӧ��ģʽ�ţ�������1��ģʽ�����ֽ�ֵ����

483         push    ax

484         mov     al,(di)          ! ȡģʽ����al�У�������ϵͳBIOS��ʾ�жϹ���0��

485         int     0x10

486         pop     ax

487         shl     ax,#1            ! ģʽ�ų�2��ת����Ϊ����ֵ���ж�Ӧֵ��ָ�롣

488         add     si,ax

489         lodsw                    ! ȡ��Ӧ����ֵ��ax�У�ah = ������al = ��������

490         pop     ds               ! �ָ���216�б����dsԭֵ����ax�з��ص�ǰ��ʾ����ֵ��

491         ret

 

    ! �����������������ʾ������ô����ֻ�ò���Ĭ�ϵ�80 x 25 �ı�׼����ֵ��

492 novid7: pop     ds               ! Here could be code to support standard 80x50,80x30

493         mov     ax,#0x5019     

494         ret

495

496 ! Routine that 'tabs' to next col.

    ! ����ƶ�����һ�Ʊ�λ���ӳ���

497

    ! ��ʾһ�����ַ�'.'��4���ո�

498 spcing: mov     al,#0x2e         ! ��ʾһ�����ַ�'.'��

499         call    prnt1

500         mov     al,#0x20

501         call    prnt1  

502         mov     al,#0x20

503         call    prnt1  

504         mov     al,#0x20

505         call    prnt1  

506         mov     al,#0x20

507         call    prnt1

508         ret    

509

510 ! Routine to print asciiz-string at DS:SI

    ! ��ʾλ��DS:SI����NULL��0x00����β���ַ�����

511

512 prtstr: lodsb

513         and     al,al

514         jz      fin

515         call    prnt1            ! ��ʾal�е�һ���ַ���

516         jmp     prtstr

517 fin:    ret

518

519 ! Routine to print a decimal value on screen, the value to be

520 ! printed is put in al (i.e 0-255).

    ! ��ʾʮ�������ֵ��ӳ�����ʾֵ���ڼĴ���al�У�0--255����

521

522 dprnt:  push    ax

523         push    cx

524         mov     ah,#0x00               

525         mov     cl,#0x0a

526         idiv    cl

527         cmp     al,#0x09

528         jbe     lt100

529         call    dprnt

530         jmp     skip10

531 lt100:  add     al,#0x30

532         call    prnt1

533 skip10: mov     al,ah

534         add     al,#0x30

535         call    prnt1  

536         pop     cx

537         pop     ax

538         ret

539

540 ! Part of above routine, this one just prints ascii al

    ! �����ӳ����һ���֡���ʾal�е�һ���ַ���

    ! ���ӳ���ʹ���ж�0x10��0x0E���ܣ��Ե紫��ʽ����Ļ��дһ���ַ��������Զ��Ƶ���һ��

    ! λ�ô������д��һ�й��ͻ��ƶ�����һ�п�ʼ��������Ѿ�д��һ�����һ�У���������Ļ

    ! �����Ϲ���һ�С��ַ�0x07��BEL����0x08��BS����0x0A(LF)��0x0D��CR������Ϊ�������ʾ��

    ! ���룺AL -- ��д�ַ���BH -- ��ʾҳ�ţ�BL -- ǰ����ʾɫ��ͼ�η�ʽʱ����

541

542 prnt1:  push    ax

543         push    cx

544         mov     bh,#0x00         ! ��ʾҳ�档

545         mov     cx,#0x01

546         mov     ah,#0x0e

547         int     0x10

548         pop     cx

549         pop     ax

550         ret

551

552 ! Prints <CR> + <LF>    ! ��ʾ�س�+���С�

553

554 docr:   push    ax

555         push    cx

556         mov     bh,#0x00

557         mov     ah,#0x0e

558         mov     al,#0x0a

559         mov     cx,#0x01

560         int     0x10

561         mov     al,#0x0d

562         int     0x10

563         pop     cx

564         pop     ax

565         ret    

566        

    ! ȫ������������ʼ�������������ɶ��8�ֽڳ�������������ɡ����������3���������

    ! ��1�����ã�568�У���������ڡ���2����ϵͳ�������������570-573�У�����3����ϵ

    ! ͳ���ݶ�������(575-578��)��

567 gdt:

568         .word   0,0,0,0         ! dummy   ! ��1�������������á�

569

    ! ��GDT���������ƫ������0x08�������ں˴����ѡ�����ֵ��

570         .word   0x07FF          ! 8Mb - limit=2047  (0--2047�������2048*4096=8Mb)

571         .word   0x0000          ! base address=0

572         .word   0x9A00          ! code read/exec         ! �����Ϊֻ������ִ�С�

573         .word   0x00C0          ! granularity=4096, 386  ! ������Ϊ4096��32λģʽ��

574

    ! ��GDT���������ƫ������0x10�������ں����ݶ�ѡ�����ֵ��

575         .word   0x07FF          ! 8Mb - limit=2047 (2048*4096=8Mb)

576         .word   0x0000          ! base address=0

577         .word   0x9200          ! data read/write        ! ���ݶ�Ϊ�ɶ���д��

578         .word   0x00C0          ! granularity=4096, 386  ! ������Ϊ4096��32λģʽ��

579

    ! �����Ǽ����ж����������Ĵ���idtr��ָ��lidtҪ���6�ֽڲ�������ǰ2�ֽ���IDT����

    ! �޳�����4�ֽ���idt�������Ե�ַ�ռ��е�32λ����ַ��CPUҪ���ڽ��뱣��ģʽ֮ǰ����

    ! ��IDT�����������������һ������Ϊ0�Ŀձ���

580 idt_48:

581         .word   0               ! idt limit=0

582         .word   0,0             ! idt base=0L

583

    ! ���Ǽ���ȫ�����������Ĵ���gdtr��ָ��lgdtҪ���6�ֽڲ�������ǰ2�ֽ���gdt������

    ! ������4�ֽ��� gdt�������Ի���ַ������ȫ�ֱ���������Ϊ 2KB��0x7ff���ɣ�����Ϊÿ8

    ! �ֽ����һ��������������Ա��й����� 256�4�ֽڵ����Ի���ַΪ 0x0009<<16 +

    ! 0x0200 + gdt����0x90200 + gdt��(����gdt��ȫ�ֱ��ڱ�������е�ƫ�Ƶ�ַ����205��)

584 gdt_48:

585         .word   0x800           ! gdt limit=2048, 256 GDT entries

586         .word   512+gdt,0x9     ! gdt base = 0X9xxxx

587

588 msg1:   .ascii  "Press <RETURN> to see SVGA-modes available or any other key to continue."

589                 db      0x0d, 0x0a, 0x0a, 0x00

590 msg2:           .ascii  "Mode:  COLSxROWS:"

591                 db      0x0d, 0x0a, 0x0a, 0x00

592 msg3:           .ascii  "Choose mode by pressing the corresponding number."

593                 db      0x0d, 0x0a, 0x00

594                

    ! ������4����ʾ�����������ݴ���

595 idati:          .ascii  "761295520"

596 idcandt:        .byte   0xa5                   ! ���idcandt��˼��ID of Chip AND Tech.

597 idgenoa:        .byte   0x77, 0x00, 0x66, 0x99

598 idparadise:     .ascii  "VGA="

599

    ! �����Ǹ�����ʾ����ʹ�õ���չģʽ�����Ͷ�Ӧ��ģʽ���б�������ÿһ�е�1���ֽ���ģʽ��

    ! ��ֵ������һЩֵ���ж�0x10����0��AH=0����ʹ�õ�ģʽ�š������602�п�֪������ATI

    ! ���ӵ���ʾ�������˱�׼ģʽ���⻹��ʹ��������չģʽ��0x23��0x33��

600 ! Manufacturer:   Numofmodes:   Mode:

    ! ���ң�          ģʽ������    ģʽ�б���

601

602 moati:          .byte   0x02,   0x23, 0x33

603 moahead:        .byte   0x05,   0x22, 0x23, 0x24, 0x2f, 0x34

604 mocandt:        .byte   0x02,   0x60, 0x61

605 mocirrus:       .byte   0x04,   0x1f, 0x20, 0x22, 0x31

606 moeverex:       .byte   0x0a,   0x03, 0x04, 0x07, 0x08, 0x0a, 0x0b, 0x16, 0x18, 0x21, 0x40

607 mogenoa:        .byte   0x0a,   0x58, 0x5a, 0x60, 0x61, 0x62, 0x63, 0x64, 0x72, 0x74, 0x78

608 moparadise:     .byte   0x02,   0x55, 0x54

609 motrident:      .byte   0x07,   0x50, 0x51, 0x52, 0x57, 0x58, 0x59, 0x5a

610 motseng:        .byte   0x05,   0x26, 0x2a, 0x23, 0x24, 0x22

611 movideo7:       .byte   0x06,   0x40, 0x43, 0x44, 0x41, 0x42, 0x45

612

    ! �����Ǹ�������VGA��ʾ����ʹ�õ�ģʽ��Ӧ���С���ֵ�б��������615�б�ʾATI��ʾ����

    ! ����չģʽ���С���ֵ�ֱ��� 132 x 25�� 132 x 44��

613 !                       msb = Cols   lsb = Rows:

    !                       ���ֽ�=����  ���ֽ�=������

614

615 dscati:         .word   0x8419, 0x842c                           ! ATI���������С���ֵ��

616 dscahead:       .word   0x842c, 0x8419, 0x841c, 0xa032, 0x5042   ! Ahead��������ֵ��

617 dsccandt:       .word   0x8419, 0x8432

618 dsccirrus:      .word   0x8419, 0x842c, 0x841e, 0x6425

619 dsceverex:      .word   0x5022, 0x503c, 0x642b, 0x644b, 0x8419, 0x842c, 0x501e, 0x641b, 0xa040, 0x841e

620 dscgenoa:       .word   0x5020, 0x642a, 0x8419, 0x841d, 0x8420, 0x842c, 0x843c, 0x503c, 0x5042, 0x644b

621 dscparadise:    .word   0x8419, 0x842b

622 dsctrident:     .word   0x501e, 0x502b, 0x503c, 0x8419, 0x841e, 0x842b, 0x843c

623 dsctseng:       .word   0x503c, 0x6428, 0x8419, 0x841c, 0x842c

624 dscvideo7:      .word   0x502b, 0x503c, 0x643c, 0x8419, 0x842c, 0x841c

625        

626 .text

627 endtext:

628 .data

629 enddata:

630 .bss

631 endbss:


 

 


 

6.3 ����6-3 linux/boot/head.s


  1 /*

  2  *  linux/boot/head.s

  3  *

  4  *  (C) 1991  Linus Torvalds

  5  */

  6

  7 /*

  8  *  head.s contains the 32-bit startup code.

  9  *

 10  * NOTE!!! Startup happens at absolute address 0x00000000, which is also where

 11  * the page directory will exist. The startup code will be overwritten by

 12  * the page directory.

 13  */

    /*

     *  head.s����32λ�������롣

     * ע��!!! 32λ���������ǴӾ��Ե�ַ0x00000000��ʼ�ģ�����Ҳͬ����ҳĿ¼�����ڵĵط���

     * ���������������뽫��ҳĿ¼���ǵ���

     */

 14 .text

 15 .globl _idt,_gdt,_pg_dir,_tmp_floppy_area

 16 _pg_dir:                   # ҳĿ¼�����������

 

    # �ٴ�ע��!!! �����Ѿ�����32λ����ģʽ����������$0x10�����ǰѵ�ַ0x10װ�����

    # �μĴ�������������ʵ��ȫ�ֶ����������е�ƫ��ֵ�����߸�׼ȷ��˵��һ������������

    # ��ѡ������й�ѡ�����˵����μ�setup.s��193���µ�˵��������$0x10�ĺ���������

    # ��Ȩ��0(λ0-1=0)��ѡ��ȫ����������(λ2=0)��ѡ����е�2��(λ3-15=2)��������ָ

    # ����е����ݶ�����������������ľ�����ֵ�μ�ǰ��setup.s��212��213�У�

    # �������ĺ����ǣ�����ds,es,fs,gsΪsetup.s �й�������ݶΣ�ȫ�ֶ�����������2�

    # ��ѡ���=0x10��������ջ������stack_startָ���user_stack��������Ȼ��ʹ�ñ�����

    # ���涨������ж�����������ȫ�ֶ�����������ȫ�ֶ��������г�ʼ������setup.s�еĻ���

    # һ���������޳���8MB�޸ij���16MB��stack_start������kernel/sched.c��69�С�����ָ��

    # user_stack����ĩ�˵�һ����ָ�롣��23����������ʹ�õ�ջ�����ҳ�Ϊϵͳջ�������ƶ���

    # ����0ִ�У�init/main.c��137�У��Ժ��ջ�ͱ���������0������1��ͬʹ�õ��û�ջ�ˡ�

 

 17 startup_32:                  # 18-22�����ø������ݶμĴ�����

 18         movl $0x10,%eax      # ����GNU��࣬ÿ��ֱ�Ӳ�����Ҫ��'$'��ʼ�������ʾ��ַ��

                                 # ÿ���Ĵ�������Ҫ��'%'��ͷ��eax��ʾ��32λ��ax�Ĵ�����

 19         mov %ax,%ds

 20         mov %ax,%es

 21         mov %ax,%fs

 22         mov %ax,%gs

 23         lss _stack_start,%esp      # ��ʾ_stack_start��ss:esp������ϵͳ��ջ��

                                       # stack_start������kernel/sched.c��69�С�

 24         call setup_idt             # ���������ж����������ӳ���

 25         call setup_gdt             # ��������ȫ�����������ӳ���

 26         movl $0x10,%eax            # reload all the segment registers

 27         mov %ax,%ds                # after changing gdt. CS was already

 28         mov %ax,%es                # reloaded in 'setup_gdt'

 29         mov %ax,%fs                # ��Ϊ�޸���gdt��������Ҫ����װ�����еĶμĴ�����

 30         mov %ax,%gs                # CS����μĴ����Ѿ���setup_gdt�����¼��ع��ˡ�

 

    # ���ڶ��������еĶ��޳���setup.s�е�8MB�ij��˱��������õ�16MB����setup.s��208-216

    # �ͱ���������235-236�У�����������ٴζ����жμĴ���ִ�м��ز����DZ���ġ����⣬ͨ��

    # ʹ��bochs���ٹ۲죬�������CS�ٴ�ִ�м��أ���ô��ִ�е�26��ʱCS����β��ɼ�������

    # ���޳�����8MB����������Ӧ�����¼���CS����������setup.s�е��ں˴�����������뱾������

    # �������õĴ�������������˶��޳��������ಿ����ȫһ����8MB���޳����ں˳�ʼ���׶β�����

    # ���⣬�������Ժ��ں�ִ�й����жμ���תʱ�����¼���CS���������û�м�������û���ó���

    # ������

    # ��Ը����⣬Ŀǰ�ں��о��ڵ�25��֮��������һ������תָ�'ljmp $(__KERNEL_CS),$1f'��

    # ��ת����26����ȷ��CSȷʵ�ֱ����¼��ء�

 

 31         lss _stack_start,%esp

 

    # 32-36�����ڲ���A20��ַ���Ƿ��Ѿ����������õķ��������ڴ��ַ0x000000��д������

    # һ����ֵ��Ȼ���ڴ��ַ0x100000(1M)���Ƿ�Ҳ�������ֵ�����һֱ��ͬ�Ļ�����һֱ

    # �Ƚ���ȥ��Ҳ����ѭ������������ʾ��ַA20��û��ѡͨ������ں˾Ͳ���ʹ��1MB�����ڴ档

    #

    # 33���ϵ�'1:'��һ���ֲ����Ź��ɵı�š�����ɷ��ź��һ��ð����ɡ���ʱ�÷��ű�ʾ�

    # λ�ü�����Active location counter���ĵ�ǰֵ����������Ϊָ��IJ��������ֲ��������ڰ���

    # �������ͱ����Ա��ʱʹ��һЩ���ơ�����10���ֲ������������������������ظ�ʹ�á���Щ����

    # ��ʹ������'0'��'1'��...��'9'�����á�Ϊ�˶���һ���ֲ����ţ���ѱ��д��'N:'��ʽ������N

    # ��ʾһ�����֣���Ϊ��������ǰ��������������ţ���Ҫд��'Nb'������N�Ƕ�����ʱʹ�õ�

    # ���֡�Ϊ������һ���ֲ���ŵ���һ�����壬��Ҫд��'Nf'������N��10��ǰ������֮һ������

    # 'b'��ʾ�����backwards������'f'��ʾ����ǰ��forwards�������ڻ������ijһ�����������

    # �������/��ǰ����10����ţ���Զ��10������

 

 32         xorl %eax,%eax

 33 1:      incl %eax                  # check that A20 really IS enabled

 34         movl %eax,0x000000         # loop forever if it isn't

 35         cmpl %eax,0x100000

 36         je 1b                      # '1b'��ʾ���(backward)��ת�����1ȥ��33�У���

                                       # ����'5f'���ʾ��ǰ(forward)��ת�����5ȥ��

 37 /*

 38  * NOTE! 486 should set bit 16, to check for write-protect in supervisor

 39  * mode. Then it would be unnecessary with the "verify_area()"-calls.

 40  * 486 users probably want to set the NE (#5) bit also, so as to use

 41  * int 16 for math errors.

 42  */

    /*

     * ע��! ��������γ����У�486Ӧ�ý�λ16��λ���Լ���ڳ����û�ģʽ�µ�д����,

     * �˺� "verify_area()" ���þͲ���Ҫ�ˡ�486���û�ͨ��Ҳ���뽫NE(#5)��λ���Ա�

     * ����ѧЭ�������ij���ʹ��int 16��

     */

    # ����ԭע�����ᵽ��486 CPU��CR0���ƼĴ�����λ16��д������־WP��Write-Protect����

    # ���ڽ�ֹ�����û����ij�����һ���û�ֻ��ҳ���н���д�������ñ�־��Ҫ���ڲ���ϵͳ�ڴ���

    # �½���ʱʵ��дʱ���ƣ�copy-on-write��������

    # ������γ���43-65�����ڼ����ѧЭ������оƬ�Ƿ���ڡ��������޸Ŀ��ƼĴ���CR0����

    # �������Э�������������ִ��һ��Э������ָ���������Ļ���˵��Э������оƬ�����ڣ�

    # ��Ҫ����CR0�е�Э����������λEM��λ2��������λЭ���������ڱ�־MP��λ1����

 

 43         movl %cr0,%eax             # check math chip

 44         andl $0x80000011,%eax      # Save PG,PE,ET

 45 /* "orl $0x10020,%eax" here for 486 might be good */

 46         orl $2,%eax                # set MP

 47         movl %eax,%cr0

 48         call check_x87

 49         jmp after_page_tables      # ��ת��135�С�

 50

 51 /*

 52  * We depend on ET to be correct. This checks for 287/387.

 53  */

    /*

     * ����������ET��־����ȷ�������287/387�������

     */

    # ����fninit��fstsw����ѧЭ��������80287/80387����ָ�

    # finit ��Э������������ʼ����������Э����������һ��δ����ǰ����Ӱ�����֪״̬������

    # �������ΪĬ��ֵ�����״̬�ֺ����и���ջʽ�Ĵ������ǵȴ���ʽ������ָ�fninit��������

    # Э��������ִֹ�е�ǰ����ִ�е��κ���ǰ������������fstsw ָ��ȡЭ��������״̬�֡����ϵ

    # ͳ�д���Э�������Ļ�����ô��ִ����fninitָ�����״̬�ֵ��ֽڿ϶�Ϊ0��

 

 54 check_x87:

 55         fninit                     # ��Э������������ʼ�����

 56         fstsw %ax                  # ȡЭ������״̬�ֵ�ax�Ĵ����С�

 57         cmpb $0,%al                # ��ʼ����״̬��Ӧ��Ϊ0������˵��Э�����������ڡ�

 58         je 1f                      /* no coprocessor: have to set bits */

 59         movl %cr0,%eax             # �����������ǰ��ת�����1���������дcr0��

 60         xorl $6,%eax               /* reset MP, set EM */

 61         movl %eax,%cr0

 62         ret

 

    # ������һ�������ָʾ�����京����ָ�洢�߽���������"2"��ʾ�����Ĵ�������ݵ�ƫ��λ��

    # ��������ֵַ���2����λΪ���λ�ã�2^2��������4�ֽڷ�ʽ�����ڴ��ַ����������GNU as

    # ֱ��ʱд�������ֵ����2�Ĵη�ֵ�ˡ�ʹ�ø�ָʾ����Ŀ����Ϊ�����32λCPU�����ڴ��д���

    # �����ݵ��ٶȺ�Ч�ʡ��μ���������ϸ˵����

    # ����������ֽ�ֵ��80287Э������ָ��fsetpm�Ļ����롣�������ǰ�80287����Ϊ����ģʽ��

    # 80387�����ָ����ҽ���Ѹ�ָ����ǿղ�����

 

 63 .align 2

 64 1:      .byte 0xDB,0xE4            /* fsetpm for 287, ignored by 387 */  # 287Э�������롣

 65         ret

 66

 67 /*

 68  *  setup_idt

 69  *

 70  *  sets up a idt with 256 entries pointing to

 71  *  ignore_int, interrupt gates. It then loads

 72  *  idt. Everything that wants to install itself

 73  *  in the idt-table may do so themselves. Interrupts

 74  *  are enabled elsewhere, when we can be relatively

 75  *  sure everything is ok. This routine will be over-

 76  *  written by the page tables.

 77  */

    /*

     * ��������������ж����������ӳ��� setup_idt

     *

     * ���ж���������idt���óɾ���256�������ָ��ignore_int�ж��š�Ȼ������ж�

     * ���������Ĵ���(��lidtָ��)������ʵ�õ��ж����Ժ��ٰ�װ���������������ط���Ϊһ��

     * ������ʱ�ٿ����жϡ����ӳ��򽫻ᱻҳ�����ǵ���

     */

    # �ж����������е�����ȻҲ��8�ֽ���ɣ������ʽ��ȫ�ֱ��еIJ�ͬ������Ϊ��������

    # (Gate Descriptor)������0-1,6-7�ֽ���ƫ������2-3�ֽ���ѡ�����4-5�ֽ���һЩ��־��

    # ��δ���������edx��eax��������ó�8�ֽ�Ĭ�ϵ��ж�������ֵ��Ȼ����idt��ÿһ����

    # �����ø�����������256�eax������������4�ֽڣ�edx���и�4�ֽڡ��ں������ij�ʼ

    # �������л��滻��װ��Щ����ʵ�õ��ж��������

 

 78 setup_idt:

 79         lea ignore_int,%edx        # ��ignore_int����Ч��ַ��ƫ��ֵ��ֵ��edx�Ĵ���

 80         movl $0x00080000,%eax      # ��ѡ���0x0008����eax�ĸ�16λ�С�

 81         movw %dx,%ax               /* selector = 0x0008 = cs */

                                       # ƫ��ֵ�ĵ�16λ����eax�ĵ�16λ�С���ʱeax����

                                       # ����������4�ֽڵ�ֵ��

 82         movw $0x8E00,%dx           /* interrupt gate - dpl=0, present */

 83                                    # ��ʱedx��������������4�ֽڵ�ֵ��

 84         lea _idt,%edi              # _idt���ж����������ĵ�ַ��

 85         mov $256,%ecx

 86 rp_sidt:

 87         movl %eax,(%edi)           # �����ж���������������С�

 88         movl %edx,4(%edi)          # eax���ݷŵ� edi+4 ��ָ�ڴ�λ�ô���

 89         addl $8,%edi               # ediָ�������һ�

 90         dec %ecx

 91         jne rp_sidt

 92         lidt idt_descr             # �����ж����������Ĵ���ֵ��

 93         ret

 94

 95 /*

 96  *  setup_gdt

 97  *

 98  *  This routines sets up a new gdt and loads it.

 99  *  Only two entries are currently built, the same

100  *  ones that were built in init.s. The routine

101  *  is VERY complicated at two whole lines, so this

102  *  rather long comment is certainly needed :-).

103  *  This routine will beoverwritten by the page tables.

104  */

    /*

     * ����ȫ������������ setup_gdt

     * ����ӳ�������һ���µ�ȫ����������gdt�������ء���ʱ�����������������ǰ

     * ���һ�������ӳ���ֻ�����У����dz��ġ����ӣ����Ե�Ȼ��Ҫ��ô����ע����J��

     * ���ӳ��򽫱�ҳ�����ǵ���

     */

105 setup_gdt:

106         lgdt gdt_descr             # ����ȫ�����������Ĵ���(���������úã���234-238��)��

107         ret

108

109 /*

110  * I put the kernel page tables right after the page directory,

111  * using 4 of them to span 16 Mb of physical memory. People with

112  * more than 16MB will have to expand this.

113  */

    /* Linus���ں˵��ڴ�ҳ��ֱ�ӷ���ҳĿ¼֮��ʹ����4������Ѱַ16 MB�������ڴ档

     * ������ж���16 Mb���ڴ棬����Ҫ��������������޸ġ�

     */

     # ÿ��ҳ����Ϊ4 Kb�ֽڣ�1ҳ�ڴ�ҳ�棩����ÿ��ҳ������Ҫ4���ֽڣ����һ��ҳ�������Դ��

     # 1024��������һ��ҳ����Ѱַ4 KB�ĵ�ַ�ռ䣬��һ��ҳ���Ϳ���Ѱַ4 MB�������ڴ档

     # ҳ����ĸ�ʽΪ�����ǰ0-11λ���һЩ��־�������Ƿ����ڴ���(Pλ0)����д����(R/Wλ1)��

     # ��ͨ�û����dz����û�ʹ��(U/Sλ2)���Ƿ��޸Ĺ�(�Ƿ�����)(Dλ6)�ȣ������λ12-31��

     # ҳ���ַ������ָ��һҳ�ڴ��������ʼ��ַ��

 

114 .org 0x1000      # ��ƫ��0x1000����ʼ�ǵ�1��ҳ����ƫ��0��ʼ�������ҳ��Ŀ¼����

115 pg0:

116

117 .org 0x2000

118 pg1:

119

120 .org 0x3000

121 pg2:

122

123 .org 0x4000

124 pg3:

125

126 .org 0x5000        # ����������ڴ����ݿ��ƫ��0x5000����ʼ��

127 /*

128  * tmp_floppy_area is used by the floppy-driver when DMA cannot

129  * reach to a buffer-block. It needs to be aligned, so that it isn't

130  * on a 64kB border.

131  */

    /* ��DMA��ֱ�Ӵ洢�����ʣ����ܷ��ʻ����ʱ�������tmp_floppy_area�ڴ��

     * �Ϳɹ�������������ʹ�á����ַ��Ҫ��������������Ͳ����Խ64KB�߽硣

     */

132 _tmp_floppy_area:

133         .fill 1024,1,0             # ������1024�ÿ��1�ֽڣ������ֵ0��

134

    # �����⼸����ջ��������Ϊ��ת��init/main.c�е�main()������׼����������139����

    # ��ָ����ջ��ѹ���˷��ص�ַ������140����ѹ����main()��������ĵ�ַ����head.s

    # ����ڵ�218��ִ��retָ��ʱ�ͻᵯ��main()�ĵ�ַ�����ѿ���Ȩת�Ƶ�init/main.c

    # �����С��μ���3�����й�C�������û��Ƶ�˵����

    # ǰ��3����ջ0ֵӦ�÷ֱ��ʾenvp��argvָ���argc��ֵ����main()û���õ���

    # 139�е���ջ������ģ�����main.c����ʱ���Ƚ����ص�ַ��ջ�IJ������������

    # main.c��������˳�ʱ���ͻ᷵�ص�����ı��L6������ִ����ȥ��Ҳ����ѭ����

    # 140�н�main.c�ĵ�ַѹ���ջ�������������÷�ҳ������setup_paging��������

    # ִ��'ret'����ָ��ʱ�ͻὫmain.c����ĵ�ַ������ջ����ȥִ��main.c�����ˡ�

    # �й�C�������û�����μ�������˵����

135 after_page_tables:

136         pushl $0                   # These are the parameters to main :-)

137         pushl $0                   # ��Щ�ǵ���main����IJ�����ָinit/main.c����

138         pushl $0                   # ���е�'$'���ű�ʾ����һ��������������

139         pushl $L6                  # return address for main, if it decides to.

140         pushl $_main               # '_main'�DZ�������main���ڲ���ʾ������

141         jmp setup_paging           # ��ת����198�С�

142 L6:

143         jmp L6                     # main should never return here, but

144                                    # just in case, we know what happens.

                                       # main������Բ�Ӧ�÷��ص��������Ϊ���Է���һ��

                                       # ���������˸���䡣�������Ǿ�֪������ʲô�����ˡ�

145

146 /* This is the default interrupt "handler" :-) */

    /* ������Ĭ�ϵ��жϡ����������J */

147 int_msg:

148         .asciz "Unknown interrupt\n\r"     # �����ַ�����δ֪�ж�(�س�����)����

149 .align 2                   # ��4�ֽڷ�ʽ�����ڴ��ַ��

150 ignore_int:

151         pushl %eax

152         pushl %ecx

153         pushl %edx

154         push %ds           # ������ע�⣡��ds,es,fs,gs����Ȼ��16λ�ļĴ���������ջ��

155         push %es           # ��Ȼ����32λ����ʽ��ջ��Ҳ����Ҫռ��4���ֽڵĶ�ջ�ռ䡣

156         push %fs

157         movl $0x10,%eax    # �ö�ѡ�����ʹds,es,fsָ��gdt���е����ݶΣ���

158         mov %ax,%ds

159         mov %ax,%es

160         mov %ax,%fs

161         pushl $int_msg     # �ѵ���printk�����IJ���ָ�루��ַ����ջ��ע�⣡��int_msg

162         call _printk       # ǰ����'$'�����ʾ��int_msg���Ŵ��ij��֣�'Unkn'����ջJ��

163         popl %eax          # �ú�����/kernel/printk.c�С�'_printk'��printk�����ģ����

164         pop %fs            # ���ڲ���ʾ����

165         pop %es

166         pop %ds

167         popl %edx

168         popl %ecx

169         popl %eax

170         iret           # �жϷ��أ����жϵ���ʱѹ��ջ��CPU��־�Ĵ�����32λ��ֵҲ��������

171

172

173 /*

174  * Setup_paging

175  *

176  * This routine sets up paging by setting the page bit

177  * in cr0. The page tables are set up, identity-mapping

178  * the first 16MB. The pager assumes that no illegal

179  * addresses are produced (ie >4Mb on a 4Mb machine).

180  *

181  * NOTE! Although all physical memory should be identity

182  * mapped by this routine, only the kernel page functions

183  * use the >1Mb addresses directly. All "normal" functions

184  * use just the lower 1Mb, or the local data space, which

185  * will be mapped to some other place - mm keeps track of

186  * that.

187  *

188  * For those with more memory than 16 Mb - tough luck. I've

189  * not got it, why should you :-) The source is here. Change

190  * it. (Seriously - it shouldn't be too difficult. Mostly

191  * change some constants etc. I left it at 16Mb, as my machine

192  * even cannot be extended past that (ok, but it was cheap :-)

193  * I've tried to show which constants to change by having

194  * some kind of marker at them (search for "16Mb"), but I

195  * won't guarantee that's all :-( )

196  */

    /*

     * ����ӳ���ͨ�����ÿ��ƼĴ���cr0�ı�־��PG λ31�����������ڴ�ķ�ҳ�������ܣ�

     * �����ø���ҳ��������ݣ��Ժ��ӳ��ǰ16 MB�������ڴ档��ҳ���ٶ���������Ƿ���

     * ��ַӳ�䣨Ҳ����ֻ��4Mb�Ļ��������ó�����4Mb���ڴ��ַ����

     *

     * ע�⣡�������е�������ַ��Ӧ��������ӳ�����к��ӳ�䣬��ֻ���ں�ҳ�����������

     * ֱ��ʹ��>1Mb�ĵ�ַ�����С���ͨ��������ʹ�õ���1Mb�ĵ�ַ�ռ䣬������ʹ�þֲ�����

     * �ռ䣬�õ�ַ�ռ佫��ӳ�䵽����һЩ�ط�ȥ -- mm���ڴ�������򣩻������Щ�µġ�

     *

     * ������Щ�ж���16Mb�ڴ�ļһ� �C ����̫�����ˣ��һ�û�У�Ϊʲô�����J���������

     * ������������޸İɡ���ʵ���ϣ��Ⲣ��̫���ѵġ�ͨ��ֻ���޸�һЩ�����ȡ��Ұ�������

     * Ϊ16Mb����Ϊ�ҵĻ�������ô�����������ܳ���������ޣ���Ȼ���ҵĻ����Ǻܱ��˵�J����

     * ���Ѿ�ͨ������ij���־��������Ҫ�Ķ��ĵط���������16Mb���������Ҳ��ܱ�֤����Щ

     * �Ķ�������L����

     */

    # ����Ӣ��ע�͵�2�εĺ�����ָ�ڻ��������ڴ��д���1MB���ڴ�ռ���Ҫ���������ڴ�����

    # ���ڴ����ռ���mmģ����������漰��ҳ��ӳ��������ں�����������������������ָ��һ��

    #����ͨ����������Ҫʹ�����ڴ�����ҳ�棬����Ҫʹ��get_free_page()�Ⱥ�����ȡ����Ϊ����

    # �������ڴ�ҳ���ǹ�����Դ�������г������ͳһ�����Ա�����Դ���ú;�����

    #

    # ���ڴ�������ַ0x0����ʼ���1ҳҳĿ¼����4ҳҳ����ҳĿ¼����ϵͳ���н��̹��õģ���

    # �����4ҳҳ���������ں�ר�ã�����һһӳ�����Ե�ַ��ʼ16MB�ռ䷶Χ�������ڴ��ϡ�����

    # �µĽ��̣�ϵͳ�������ڴ���Ϊ������ҳ����ҳ�������⣬1ҳ�ڴ泤����4096�ֽڡ�

 

197 .align 2                           # ��4�ֽڷ�ʽ�����ڴ��ַ�߽硣

198 setup_paging:                      # ���ȶ�5ҳ�ڴ棨1ҳĿ¼ + 4ҳҳ�������㡣

199         movl $1024*5,%ecx          /* 5 pages - pg_dir+4 page tables */

200         xorl %eax,%eax

201         xorl %edi,%edi             /* pg_dir is at 0x000 */

                                       # ҳĿ¼��0x000��ַ��ʼ��

202         cld;rep;stosl              # eax���ݴ浽es:edi��ָ�ڴ�λ�ô�����edi��4��

 

    # ����4������ҳĿ¼���е����Ϊ���ǣ��ںˣ�����4��ҳ������ֻ������4�

    # ҳĿ¼��Ľṹ��ҳ������Ľṹһ����4���ֽ�Ϊ1��μ�����113���µ�˵����

    # ����"$pg0+7"��ʾ��0x00001007����ҳĿ¼���еĵ�1�

    # ���1��ҳ�����ڵĵ�ַ = 0x00001007 & 0xfffff000 = 0x1000��

    # ��1��ҳ�������Ա�־ = 0x00001007 & 0x00000fff = 0x07����ʾ��ҳ���ڡ��û��ɶ�д��

203         movl $pg0+7,_pg_dir        /* set present bit/user r/w */

204         movl $pg1+7,_pg_dir+4      /*  --------- " " --------- */

205         movl $pg2+7,_pg_dir+8      /*  --------- " " --------- */

206         movl $pg3+7,_pg_dir+12     /*  --------- " " --------- */

 

    # ����6����д4��ҳ��������������ݣ����У�4(ҳ��)*1024(��/ҳ��)=4096��(0 - 0xfff)��

    # Ҳ����ӳ�������ڴ� 4096*4Kb = 16Mb��

    # ÿ��������ǣ���ǰ����ӳ��������ڴ��ַ + ��ҳ�ı�־�������Ϊ7����

    # ʹ�õķ����Ǵ����һ��ҳ�������һ�ʼ������˳����д��һ��ҳ�������һ����ҳ���е�

    # λ����1023*4 = 4092��������һҳ�����һ���λ�þ���$pg3+4092��

 

207         movl $pg3+4092,%edi        # edi�����һҳ�����һ�

208         movl $0xfff007,%eax        /*  16Mb - 4096 + 7 (r/w user,p) */

                                       # ���1���Ӧ�����ڴ�ҳ��ĵ�ַ��0xfff000��

                                       # �������Ա�־7����Ϊ0xfff007��

209         std                        # ����λ��λ��ediֵ�ݼ�(4�ֽ�)��

210 1:      stosl                      /* fill pages backwards - more efficient :-) */

211         subl $0x1000,%eax          # ÿ��д��һ�������ֵַ��0x1000��

212         jge 1b                     # ���С��0��˵��ȫ��д���ˡ�

    # ����ҳĿ¼����ַ�Ĵ���cr3��ֵ��ָ��ҳĿ¼����cr3�б������ҳĿ¼����������ַ��

213         xorl %eax,%eax             /* pg_dir is at 0x0000 */   # ҳĿ¼����0x0000����

214         movl %eax,%cr3             /* cr3 - page directory start */

    # ��������ʹ�÷�ҳ������cr0��PG��־��λ31��

215         movl %cr0,%eax

216         orl $0x80000000,%eax       # ����PG��־��

217         movl %eax,%cr0             /* set paging (PG) bit */

218         ret                        /* this also flushes prefetch-queue */

 

    # �ڸı��ҳ������־��Ҫ��ʹ��ת��ָ��ˢ��Ԥȡָ����У������õ��Ƿ���ָ��ret��

    # �÷���ָ�����һ�������ǽ�140��ѹ���ջ�е�main����ĵ�ַ����������ת��/init/main.c

    # ����ȥ���С������򵽴˾����������ˡ�

 

219

220 .align 2                           # ��4�ֽڷ�ʽ�����ڴ��ַ�߽硣

221 .word 0                            # �����ȿճ�2�ֽڣ�����224���ϵij�����4�ֽڶ���ġ�

 

    ! �����Ǽ����ж����������Ĵ���idtr��ָ��lidtҪ���6�ֽڲ�������ǰ2�ֽ���idt�����޳���

    ! ��4�ֽ���idt�������Ե�ַ�ռ��е�32λ����ַ��

222 idt_descr:

223         .word 256*8-1              # idt contains 256 entries  # ��256��޳�=���� - 1��

224         .long _idt

225 .align 2

226 .word 0

 

    ! �������ȫ�����������Ĵ���gdtr��ָ��lgdtҪ���6�ֽڲ�������ǰ2�ֽ���gdt�����޳���

    ! ��4�ֽ���gdt�������Ի���ַ������ȫ�ֱ���������Ϊ2KB�ֽڣ�0x7ff���ɣ�����Ϊÿ8�ֽ�

    ! ���һ������������Ա��й�����256�����_gdt��ȫ�ֱ��ڱ������е�ƫ��λ�ã���234�С�

227 gdt_descr:

228         .word 256*8-1              # so does gdt (not that that's any   # ע��not �� note

229         .long _gdt                 # magic number, but it works for me :^)

230

231         .align 3                   # ��8��2^3���ֽڷ�ʽ�����ڴ��ַ�߽硣

232 _idt:   .fill 256,8,0              # idt is uninitialized   # 256�ÿ��8�ֽڣ���0��

233

    # ȫ�ֱ���ǰ4��ֱ��ǿ�����ã�������������������ݶ���������ϵͳ���ö�������������

    # ϵͳ���ö���������û�����ô���Linus��ʱ���������ϵͳ���ô���ר�ŷ�����������Ķ��С�

    # ���滹Ԥ����252��Ŀռ䣬���ڷ�������������ľֲ�������(LDT)�Ͷ�Ӧ������״̬��TSS

    # ����������

    # (0-nul, 1-cs, 2-ds, 3-syscall, 4-TSS0, 5-LDT0, 6-TSS1, 7-LDT1, 8-TSS2 etc...)

 

234 _gdt:   .quad 0x0000000000000000        /* NULL descriptor */

235         .quad 0x00c09a0000000fff        /* 16Mb */      # 0x08���ں˴������󳤶�16MB��

236         .quad 0x00c0920000000fff        /* 16Mb */      # 0x10���ں����ݶ���󳤶�16MB��

237         .quad 0x0000000000000000        /* TEMPORARY - don't use */

238         .fill 252,8,0                   /* space for LDT's and TSS's etc */  # Ԥ���ռ䡣



 

 

��7�� �ں˳�ʼ������

7.1 ����7-1 linux/init/main.c


  1 /*

  2  *  linux/init/main.c

  3  *

  4  *  (C) 1991  Linus Torvalds

  5  */

  6

    // ����ꡰ__LIBRARY__����Ϊ�˰���������unistd.h�е���Ƕ���������Ϣ��

  7 #define __LIBRARY__

    // *.hͷ�ļ����ڵ�Ĭ��Ŀ¼��include/�����ڴ����оͲ�����ȷָ����λ�á��������UNIX��

    // ��׼ͷ�ļ�������Ҫָ�����ڵ�Ŀ¼������˫������ס��unistd.h�DZ�׼���ų����������ļ���

    // ���ж����˸��ַ��ų��������ͣ��������˸��ֺ���������������˷���__LIBRARY__���򻹻�

    // ����ϵͳ���úź���Ƕ������syscall0()�ȡ�

  8 #include <unistd.h>

  9 #include <time.h>    // ʱ������ͷ�ļ�����������Ҫ������tm�ṹ��һЩ�й�ʱ��ĺ���ԭ�Ρ�

 10

 11 /*

 12  * we need this inline - forking from kernel space will result

 13  * in NO COPY ON WRITE (!!!), until an execve is executed. This

 14  * is no problem, but for the stack. This is handled by not letting

 15  * main() use the stack at all after fork(). Thus, no function

 16  * calls - which means inline code for fork too, as otherwise we

 17  * would use the stack upon exit from 'fork()'.

 18  *

 19  * Actually only pause and fork are needed inline, so that there

 20  * won't be any messing with the stack from main(), but we define

 21  * some others too.

 22  */

    /*

     * ������Ҫ������Щ��Ƕ��� - ���ں˿ռ䴴�����̽�����û��дʱ����(COPY ON WRITE)!!!

     * ֱ��ִ��һ��execve���á���Զ�ջ���ܴ������⡣������������fork()���ú���main()

     * ʹ���κζ�ջ����˾Ͳ����к������� - ����ζ��forkҲҪʹ����Ƕ�Ĵ��룬���������ڴ�

     * fork()�˳�ʱ��Ҫʹ�ö�ջ�ˡ�

     *

     * ʵ����ֻ��pause��fork��Ҫʹ����Ƕ��ʽ���Ա�֤��main()�в���Ū�Ҷ�ջ����������ͬ

     * ʱ������������һЩ������

     */

    // Linux���ں˿ռ䴴������ʱ��ʹ��дʱ���Ƽ�����Copy on write����main()���ƶ����û�

    // ģʽ��������0����ִ����Ƕ��ʽ��fork()��pause()����˿ɱ�֤��ʹ������0���û�ջ��

    // ��ִ��moveto_user_mode()֮�󣬱�����main()��������0�������������ˡ�������0����

    // �н������ӽ��̵ĸ����̡���������һ���ӽ���ʱ��init���̣�����������1���������ں�

    // �ռ䣬���û��ʹ��дʱ���ƹ��ܡ���ʱ����0���û�ջ��������1���û�ջ�������ǹ�ͬ

    // ʹ��һ��ջ�ռ䡣���ϣ����main.c����������0�Ļ�����ʱ��Ҫ�жԶ�ջ���κβ�������

    // ��Ū�Ҷ�ջ�������ٴ�ִ��fork()��ִ�й�execve()�����󣬱����س����Ѳ������ں˿ռ䣬

    // ��˿���ʹ��дʱ���Ƽ����ˡ���μ�5.3�ڡ�Linux�ں�ʹ���ڴ�ķ��������ݡ�

 

    // ����_syscall0()��unistd.h�е���Ƕ����롣��Ƕ�������ʽ����Linux��ϵͳ�����ж�

    // 0x80�����ж�������ϵͳ���õ���ڡ��������ʵ������int fork()��������ϵͳ���á���չ

    // ����֮�ͻ��������ס�syscall0����������0��ʾ�޲�����1��ʾ1��������

    // �μ�include/unistd.h��133�С�

 23 static inline _syscall0(int,fork)

    // int pause()ϵͳ���ã���ͣ���̵�ִ�У�ֱ���յ�һ���źš�

 24 static inline _syscall0(int,pause)

    // int setup(void * BIOS)ϵͳ���ã�������linux��ʼ����������������б����ã���

 25 static inline _syscall1(int,setup,void *,BIOS)

    // int sync()ϵͳ���ã������ļ�ϵͳ��

 26 static inline _syscall0(int,sync)

 27

 28 #include <linux/tty.h>    // ttyͷ�ļ����������й�tty_io������ͨ�ŷ���IJ�����������

 29 #include <linux/sched.h>  // ���ȳ���ͷ�ļ�������������ṹtask_struct����1����ʼ����

                              // �����ݡ�����һЩ�Ժ����ʽ������й��������������úͻ�ȡ��

                              // Ƕ��ʽ��ຯ������

 30 #include <linux/head.h>   // headͷ�ļ��������˶��������ļ򵥽ṹ���ͼ���ѡ���������

 31 #include <asm/system.h>   // ϵͳͷ�ļ����Ժ���ʽ�����������й����û��޸�������/�ж���

                              // �ȵ�Ƕ��ʽ����ӳ���

 32 #include <asm/io.h>       // ioͷ�ļ����Ժ��Ƕ���������ʽ�����io�˿ڲ����ĺ�����

 33

 34 #include <stddef.h>       // ��׼����ͷ�ļ���������NULL, offsetof(TYPE, MEMBER)��

 35 #include <stdarg.h>       // ��׼����ͷ�ļ����Ժ����ʽ������������б�����Ҫ˵����-��

                              // ����(va_list)��������(va_start, va_arg��va_end)��vsprintf��

                              // vprintf��vfprintf��

 36 #include <unistd.h>

 37 #include <fcntl.h>        // �ļ�����ͷ�ļ��������ļ������������IJ������Ƴ������ŵĶ��塣

 38 #include <sys/types.h>    // ����ͷ�ļ��������˻�����ϵͳ�������͡�

 39

 40 #include <linux/fs.h>     // �ļ�ϵͳͷ�ļ��������ļ����ṹ��file,buffer_head,m_inode�ȣ���

 41                           // �����ж��壺extern int ROOT_DEV��

 42 #include <string.h>       // �ַ���ͷ�ļ�����Ҫ������һЩ�й��ڴ���ַ���������Ƕ�뺯����

 43

 44 static char printbuf[1024];           // ��̬�ַ������飬�����ں���ʾ��Ϣ�Ļ��档

 45

 46 extern char *strcpy();

 47 extern int vsprintf();                // �͸�ʽ�������һ�ַ����У�vsprintf.c��92�У���

 48 extern void init(void);               // ����ԭ�Σ���ʼ����������168�У���

 49 extern void blk_dev_init(void);       // ���豸��ʼ���ӳ���blk_drv/ll_rw_blk.c,157�У�

 50 extern void chr_dev_init(void);       // �ַ��豸��ʼ����chr_drv/tty_io.c, 347�У�

 51 extern void hd_init(void);            // Ӳ�̳�ʼ������blk_drv/hd.c, 343�У�

 52 extern void floppy_init(void);        // ������ʼ������blk_drv/floppy.c, 457�У�

 53 extern void mem_init(long start, long end);      // �ڴ������ʼ����mm/memory.c, 399�У�

 54 extern long rd_init(long mem_start, int length); // �����̳�ʼ��(blk_drv/ramdisk.c,52)

 55 extern long kernel_mktime(struct tm * tm);       // ����ϵͳ��������ʱ�䣨�룩��

 56

    // �ں�ר��sprintf()�������ú������ڲ�����ʽ����Ϣ�������ָ��������str�С�����'*fmt'

    // ָ����������õĸ�ʽ���μ���׼C�����鼮�����ӳ���������vsprintf���ʹ�õ�һ����

    // ���ӡ�����ʹ��vsprintf()����ʽ���ַ�������str���������μ���179���ϵ�printf()������

 57 static int sprintf(char * str, const char *fmt, ...)

 58 {

 59         va_list args;

 60         int i;

 61

 62         va_start(args, fmt);

 63         i = vsprintf(str, fmt, args);

 64         va_end(args);

 65         return i;

 66 }

 67

 68 /*

 69  * This is set up by the setup-routine at boot-time

 70  */

    /*

     * ������Щ���������ں������ڼ���setup.s�������õġ�

     */

    // �������зֱ�ָ�������Ե�ַǿ��ת��Ϊ�����������͵�ָ�룬����ȡָ����ָ���ݡ�����

    // �ں˴���α�ӳ�䵽��������ַ�㿪ʼ�ĵط��������Щ���Ե�ַ����Ҳ�Ƕ�Ӧ��������ַ��

    // ��Щָ����ַ���ڴ�ֵ�ĺ�����μ���6�µı�6-2��setup�����ȡ������IJ�������

    // drive_info�ṹ��μ������125�С�

 71 #define EXT_MEM_K (*(unsigned short *)0x90002)      // 1MB�Ժ����չ�ڴ��С��KB����

 72 #define CON_ROWS ((*(unsigned short *)0x9000e) & 0xff)  // ѡ���Ŀ���̨��Ļ�С�������

 73 #define CON_COLS (((*(unsigned short *)0x9000e) & 0xff00) >> 8)

 74 #define DRIVE_INFO (*(struct drive_info *)0x90080)  // Ӳ�̲�����32�ֽ����ݡ�

 75 #define ORIG_ROOT_DEV (*(unsigned short *)0x901FC)  // ���ļ�ϵͳ�����豸�š�

 76 #define ORIG_SWAP_DEV (*(unsigned short *)0x901FA)  // �����ļ������豸�š�

 77

 78 /*

 79  * Yeah, yeah, it's ugly, but I cannot find how to do this correctly

 80  * and this seems to work. I anybody has more info on the real-time

 81  * clock I'd be interested. Most of this was trial and error, and some

 82  * bios-listing reading. Urghh.

 83  */

    /*

     * �ǰ����ǰ���������γ���ܲ�����Ҳ�֪�������ȷ��ʵ�֣����Һ���

     * ���������С�����й���ʵʱʱ�Ӹ�������ϣ����Һܸ���Ȥ����Щ������

     * ̽�����ģ����⻹����һЩbios���򣬺ǣ�

     */

 84

    // ��κ��ȡCMOSʵʱʱ����Ϣ��outb_p��inb_p��include/asm/io.h�ж���Ķ˿���������ꡣ

 85 #define CMOS_READ(addr) ({ \

 86 outb_p(0x80|addr,0x70); \       // 0x70��д��ַ�˿ںţ�0x80|addr��Ҫ��ȡ��CMOS�ڴ��ַ��

 87 inb_p(0x71); \                  // 0x71�Ƕ����ݶ˿ںš�

 88 })

 89

    // ����ꡣ��BCD��ת���ɶ�������ֵ��BCD�����ð���ֽڣ�4���أ���ʾһ��10�����������

    // һ���ֽڱ�ʾ2��10��������(val)&15ȡBCD��ʾ��10���Ƹ�λ������ (val)>>4ȡBCD��ʾ

    // ��10����ʮλ�����ٳ���10��������������Ӿ���һ���ֽ�BCD���ʵ�ʶ�������ֵ��

 90 #define BCD_TO_BIN(val) ((val)=((val)&15) + ((val)>>4)*10)

 91

    // �ú���ȡCMOSʵʱ����Ϣ��Ϊ����ʱ�䣬�����浽ȫ�ֱ���startup_time(��)�С��μ�����

    // CMOS�ڴ��б�˵�������е��õĺ���kernel_mktime()���ڼ����1970��1��1��0ʱ��

    // �������վ�������������Ϊ����ʱ�䣨kernel/mktime.c 41�У���

 92 static void time_init(void)

 93 {

 94         struct tm time;                        // ʱ��ṹtm������include/time.h�С�

 95

    // CMOS�ķ����ٶȺ�����Ϊ�˼�Сʱ�����ڶ�ȡ������ѭ����������ֵ������ʱCMOS��

    // ��ֵ�����˱仯����ô�����¶�ȡ����ֵ�������ں˾��ܰ���CMOSʱ����������1��֮�ڡ�

 96         do {

 97                 time.tm_sec = CMOS_READ(0);       // ��ǰʱ����ֵ������BCD��ֵ����

 98                 time.tm_min = CMOS_READ(2);       // ��ǰ����ֵ��

 99                 time.tm_hour = CMOS_READ(4);      // ��ǰСʱֵ��

100                 time.tm_mday = CMOS_READ(7);      // һ���еĵ������ڡ�

101                 time.tm_mon = CMOS_READ(8);       // ��ǰ�·ݣ�1��12����

102                 time.tm_year = CMOS_READ(9);      // ��ǰ��ݡ�

103         } while (time.tm_sec != CMOS_READ(0));

104         BCD_TO_BIN(time.tm_sec);                  // ת���ɶ�������ֵ��

105         BCD_TO_BIN(time.tm_min);

106         BCD_TO_BIN(time.tm_hour);

107         BCD_TO_BIN(time.tm_mday);

108         BCD_TO_BIN(time.tm_mon);

109         BCD_TO_BIN(time.tm_year);

110         time.tm_mon--;                            // tm_mon���·ݷ�Χ��0��11��

111         startup_time = kernel_mktime(&time);      // ���㿪��ʱ�䡣kernel/mktime.c 41�С�

112 }

113

    // ���涨��һЩ�ֲ�������

114 static long memory_end = 0;                       // �������е������ڴ��������ֽ�������

115 static long buffer_memory_end = 0;                // ���ٻ�����ĩ�˵�ַ��

116 static long main_memory_start = 0;                // ���ڴ棨�����ڷ�ҳ����ʼ��λ�á�

117 static char term[32];                             // �ն������ַ�����������������

118

    // ��ȡ��ִ��/etc/rc�ļ�ʱ��ʹ�õ������в����ͻ���������

119 static char * argv_rc[] = { "/bin/sh", NULL };       // ����ִ�г���ʱ�������ַ������顣

120 static char * envp_rc[] = { "HOME=/", NULL ,NULL };  // ����ִ�г���ʱ�Ļ����ַ������顣

121

    // ���е�¼shellʱ��ʹ�õ������в����ͻ���������

    // ��122����argv[0]�е��ַ���-���Ǵ��ݸ�shell����sh��һ����־��ͨ��ʶ��ñ�־��

    // sh�������Ϊ��¼shellִ�С���ִ�й�������shell��ʾ����ִ��sh��һ����

122 static char * argv[] = { "-/bin/sh",NULL };          // ͬ�ϡ�

123 static char * envp[] = { "HOME=/usr/root", NULL, NULL };

124

125 struct drive_info { char dummy[32]; } drive_info;    // ���ڴ��Ӳ�̲�������Ϣ��

126

    // �ں˳�ʼ�������򡣳�ʼ��������������0��idle���񼴿������񣩵��������С�

    // Ӣ��ע�ͺ����ǡ�����ȷʵ��void��û������startup����(head.s)�о�����������ġ����μ�

    // head.s�����136�п�ʼ�ļ��д��롣

127 void main(void)         /* This really IS void, no error here. */

128 {                       /* The startup routine assumes (well, ...) this */

129 /*

130  * Interrupts are still disabled. Do necessary setups, then

131  * enable them

132  */

    /*

     * ��ʱ�ж��Ա���ֹ�ţ������Ҫ�����ú�ͽ��俪����

     */

    // ���ȱ�����ļ�ϵͳ�豸�źͽ����ļ��豸�ţ�������setup.s�����л�ȡ����Ϣ���ÿ���̨

    // �ն���Ļ�С�������������TERM�����������ó�ʼinit������ִ��etc/rc�ļ���shell����

    // ʹ�õĻ����������Լ������ڴ�0x90080����Ӳ�̲�������

    // ����ROOT_DEV ����ǰ���������include/linux/fs.h�ļ���206���ϱ�����Ϊextern int��

    // ��SWAP_DEV��include/linux/mm.h�ļ���Ҳ������ͬ����������mm.h�ļ���û����ʽ������

    // ������ǰ������Ϊǰ���������include/linux/sched.h�ļ����Ѿ���������

133         ROOT_DEV = ORIG_ROOT_DEV;               // ROOT_DEV������fs/super.c��29�С�

134         SWAP_DEV = ORIG_SWAP_DEV;               // SWAP_DEV������mm/swap.c��36�С�

135         sprintf(term, "TERM=con%dx%d", CON_COLS, CON_ROWS);

136         envp[1] = term;

137         envp_rc[1] = term;

138         drive_info = DRIVE_INFO;                // �����ڴ�0x90080����Ӳ�̲�������

 

    // ���Ÿ��ݻ��������ڴ��������ø��ٻ����������ڴ�����λ�úͷ�Χ��

    // ���ٻ���ĩ�˵�ַ��buffer_memory_end�������ڴ�������memory_end��

    // ���ڴ濪ʼ��ַ  ��main_memory_start��

139         memory_end = (1<<20) + (EXT_MEM_K<<10); // �ڴ��С=1Mb + ��չ�ڴ�(k)*1024�ֽڡ�

140         memory_end &= 0xfffff000;               // ���Բ���4Kb��1ҳ�����ڴ�����

141         if (memory_end > 16*1024*1024)          // ����ڴ�������16Mb����16Mb�ơ�

142                 memory_end = 16*1024*1024;

143         if (memory_end > 12*1024*1024)          // ����ڴ�>12Mb�������û�����ĩ��=4Mb

144                 buffer_memory_end = 4*1024*1024;

145         else if (memory_end > 6*1024*1024)      // �������ڴ�>6Mb�������û�����ĩ��=2Mb

146                 buffer_memory_end = 2*1024*1024;

147         else

148                 buffer_memory_end = 1*1024*1024; // ���������û�����ĩ��=1Mb

149         main_memory_start = buffer_memory_end;  // ���ڴ���ʼλ�� = ������ĩ�ˡ�

 

    // �����Makefile�ļ��ж������ڴ������̷���RAMDISK�����ʼ�������̡���ʱ���ڴ潫���١�

    //�μ�kernel/blk_drv/ramdisk.c��

150 #ifdef RAMDISK

151         main_memory_start += rd_init(main_memory_start, RAMDISK*1024);

152 #endif

    // �������ں˽������з���ij�ʼ���������Ķ�ʱ��ø��ŵ��õij��������ȥ������ʵ�ڿ�

    // ����ȥ�ˣ����ȷ�һ�ţ���������һ����ʼ������ -- ���Ǿ���̸֮J��

153         mem_init(main_memory_start,memory_end);  // ���ڴ�����ʼ������mm/memory.c��399��

154         trap_init();          // �����ţ�Ӳ���ж���������ʼ������kernel/traps.c��181��

155         blk_dev_init();       // ���豸��ʼ����    ��blk_drv/ll_rw_blk.c��157��

156         chr_dev_init();       // �ַ��豸��ʼ����  ��chr_drv/tty_io.c��347��

157         tty_init();           // tty��ʼ����      ��chr_drv/tty_io.c��406��

158         time_init();          // ���ÿ�������ʱ�䡣������92�У�

159         sched_init();         // ���ȳ����ʼ������������0��tr,ldtr����kernel/sched.c��385��

160         buffer_init(buffer_memory_end); // ���������ʼ�������ڴ������ȡ���fs/buffer.c��348��

161         hd_init();            // Ӳ�̳�ʼ����      ��blk_drv/hd.c��343��

162         floppy_init();        // ������ʼ����      ��blk_drv/floppy.c��457��

163         sti();                // ���г�ʼ�������������ˣ����ǿ����жϡ�

 

    // �������ͨ���ڶ�ջ�����õIJ����������жϷ���ָ����������0ִ�С�

164         move_to_user_mode();    // �Ƶ��û�ģʽ��ִ�С���include/asm/system.h����1�У�

165         if (!fork()) {          /* we count on this going ok */

166                 init();         // ���½����ӽ��̣�����1��init���̣���ִ�С�

167         }

 

    // ������뿪ʼ������0���������С�

168 /*

169  *   NOTE!!   For any other task 'pause()' would mean we have to get a

170  * signal to awaken, but task0 is the sole exception (see 'schedule()')

171  * as task 0 gets activated at every idle moment (when no other tasks

172  * can run). For task0 'pause()' just means we go check if some other

173  * task can run, and if not we return here.

174  */

    /* ע��!! �����κ�����������'pause()'����ζ�����DZ���ȴ��յ�һ���ź�

     * �Ż᷵�ؾ���̬��������0��task0����Ψһ����������μ�'schedule()'����

     * ��Ϊ����0���κο���ʱ���ﶼ�ᱻ�����û����������������ʱ�������

     * ��������0'pause()'����ζ�����Ƿ������鿴�Ƿ�����������������У����

     * û�еĻ����Ǿͻص����һֱѭ��ִ��'pause()'��

     */

    // pause()ϵͳ���ã�kernel/sched.c,144���������0ת���ɿ��жϵȴ�״̬����ִ�е��Ⱥ�����

    // ���ǵ��Ⱥ���ֻҪ����ϵͳ��û�����������������ʱ�ͻ��л�������0����������������0��

    // ״̬��

175         for(;;)

176                 __asm__("int $0x80"::"a" (__NR_pause):"ax");  // ��ִ��ϵͳ����pause()��

177 }

178

    // ���溯��������ʽ����Ϣ���������׼����豸stdout(1)��������ָ��Ļ����ʾ������'*fmt'

    // ָ����������õĸ�ʽ���μ���׼C�����鼮�����ӳ���������vsprintf���ʹ�õ�һ����

    // ���ӡ��ó���ʹ��vsprintf()����ʽ�����ַ�������printbuf��������Ȼ����write()������

    // ���������������׼�豸��1--stdout����vsprintf()������ʵ�ּ�kernel/vsprintf.c��

179 static int printf(const char *fmt, ...)

180 {

181         va_list args;

182         int i;

183

184         va_start(args, fmt);

185         write(1,printbuf,i=vsprintf(printbuf, fmt, args));

186         va_end(args);

187         return i;

188 }

189

 

    // ��main()���Ѿ�������ϵͳ��ʼ���������ڴ����������Ӳ���豸����������init()����

    // ����������0��1�δ������ӽ��̣�����1���С������ȶԵ�һ����Ҫִ�еij���shell��

    // �Ļ������г�ʼ����Ȼ���Ե�¼shell��ʽ���ظó���ִ��֮��

190 void init(void)

191 {

192         int pid,i;

193

    // setup() ��һ��ϵͳ���á����ڶ�ȡӲ�̲���������������Ϣ�����������̣������ڵĻ�����

    // ��װ���ļ�ϵͳ�豸���ú�����25���ϵĺ궨�壬��Ӧ������sys_setup()���ڿ��豸��Ŀ¼

    // kernel/blk_drv/hd.c��74�С�

194         setup((void *) &drive_info);

 

    // �����Զ�д���ʷ�ʽ���豸��/dev/tty0��������Ӧ�ն˿���̨���������ǵ�һ�δ��ļ�

    // ��������˲������ļ�����ţ��ļ����������϶���0���þ����UNIX�����ϵͳĬ�ϵĿ�

    // ��̨��׼������stdin�������ٰ����Զ���д�ķ�ʽ�ֱ����Ϊ�˸��Ʋ�����׼�����д��

    // ���stdout�ͱ�׼����������stderr������ǰ��ġ�(void)��ǰ׺���ڱ�ʾǿ�ƺ�������

    // ����ֵ��

195         (void) open("/dev/tty1",O_RDWR,0);

196         (void) dup(0);             // ���ƾ�����������1��--stdout��׼����豸��

197         (void) dup(0);             // ���ƾ�����������2��--stderr��׼��������豸��

 

    // �����ӡ���������������ֽ�����ÿ��1024�ֽڣ��Լ����ڴ��������ڴ��ֽ�����

198         printf("%d buffers = %d bytes buffer space\n\r",NR_BUFFERS,

199                 NR_BUFFERS*BLOCK_SIZE);

200         printf("Free mem: %d bytes\n\r",memory_end-main_memory_start);

 

    // ����fork()���ڴ���һ���ӽ��̣�����2�������ڱ��������ӽ��̣�fork()������0ֵ������

    // ԭ���̣������̣��򷵻��ӽ��̵Ľ��̺�pid�����Ե�202--206�����ӽ���ִ�е����ݡ�����

    // ���̹ر��˾��0��stdin������ֻ����ʽ��/etc/rc�ļ�����ʹ��execve()��������������

    // �滻�� /bin/sh���򣨼�shell���򣩣�Ȼ��ִ�� /bin/sh������Я���IJ����ͻ���������

    // ����argv_rc��envp_rc����������رվ��0�����̴� /etc/rc�ļ��������ǰѱ�׼����

    // stdin�ض��� /etc/rc�ļ�������shell����/bin/sh�Ϳ�������rc�ļ������õ������

    // ������sh�����з�ʽ�Ƿǽ���ʽ�ģ������ִ����rc�ļ��е������ͻ������˳�������2

    // Ҳ��֮����������execve()����˵����μ�fs/exec.c����207�С�

    // ����_exit()�˳�ʱ�ij�����1 �C ����δ���ɣ�2 -- �ļ���Ŀ¼�����ڡ�

201         if (!(pid=fork())) {

202                 close(0);

203                 if (open("/etc/rc",O_RDONLY,0))

204                         _exit(1);                // �����ļ�ʧ�ܣ����˳�(lib/_exit.c,10)��

205                 execve("/bin/sh",argv_rc,envp_rc);         // �滻��/bin/sh����ִ�С�

206                 _exit(2);                                  // ��execve()ִ��ʧ�����˳���

207         }

 

    // ���滹�Ǹ����̣�1��ִ�е���䡣wait()�ȴ��ӽ���ֹͣ����ֹ������ֵӦ���ӽ��̵Ľ��̺�

    // (pid)��������������Ǹ����̵ȴ��ӽ��̵Ľ�����&i�Ǵ�ŷ���״̬��Ϣ��λ�á����wait()

    // ����ֵ�������ӽ��̺ţ�������ȴ���

208         if (pid>0)

209                 while (pid != wait(&i))

210                         /* nothing */;       /* ��ѭ�� */

 

    // ���ִ�е����˵���մ������ӽ��̵�ִ����ֹͣ����ֹ�ˡ�����ѭ���������ٴ���һ����

    // ���̣��������������ʾ����ʼ�����򴴽��ӽ���ʧ�ܡ���Ϣ������ִ�С��������������ӽ�

    // �̽��ر�������ǰ�������ľ��(stdin, stdout, stderr)���´���һ���Ự�����ý�����ţ�

    // Ȼ�����´� /dev/tty0 ��Ϊ stdin�������Ƴ� stdout�� stderr���ٴ�ִ��ϵͳ���ͳ���

    // /bin/sh�������ִ����ѡ�õIJ����ͻ���������ѡ��һ�ף�������122--123�У���Ȼ�󸸽�

    // ���ٴ����� wait()�ȴ�������ӽ�����ֹͣ��ִ�У����ڱ�׼�������ʾ������Ϣ���ӽ���

    // pidֹͣ�����У���������i����Ȼ�����������ȥ�����γɡ�����ѭ����

211         while (1) {

212                 if ((pid=fork())<0) {

213                         printf("Fork failed in init\r\n");

214                         continue;

215                 }

216                 if (!pid) {                           // �µ��ӽ��̡�

217                         close(0);close(1);close(2);

218                         setsid();                     // ����һ�µĻỰ�ڣ�������˵����

219                         (void) open("/dev/tty1",O_RDWR,0);

220                         (void) dup(0);

221                         (void) dup(0);

222                         _exit(execve("/bin/sh",argv,envp));

223                 }

224                 while (1)

225                         if (pid == wait(&i))

226                                 break;

227                 printf("\n\rchild %d died with code %04x\n\r",pid,i);

228                 sync();                               // ͬ��������ˢ�»�������

229         }

230         _exit(0);       /* NOTE! _exit, not exit() */  /*ע�⣡��_exit()����exit()*/

    // _exit()��exit()������������ֹһ����������_exit()ֱ����һ��sys_exitϵͳ���ã���

    // exit()��ͨ������ͨ�������е�һ��������������ִ��һЩ����������������ִ�и���ֹ

    // �������򡢹ر����б�׼IO�ȣ�Ȼ�����sys_exit��

231 }

232


 


 

��8�� �ں˺��ij���

8.1 ����8-1 linux/kernel/asm.s


  1 /*

  2  *  linux/kernel/asm.s

  3  *

  4  *  (C) 1991  Linus Torvalds

  5  */

  6

  7 /*

  8  * asm.s contains the low-level code for most hardware faults.

  9  * page_exception is handled by the mm, so that isn't here. This

 10  * file also handles (hopefully) fpu-exceptions due to TS-bit, as

 11  * the fpu must be properly saved/resored. This hasn't been tested.

 12  */

    /*

     * asm.s�����а����󲿷ֵ�Ӳ�����ϣ�������������ĵײ�δ��롣ҳ�쳣���ڴ��������

     * mm���������Բ�������˳��򻹴�����ϣ��������������TS-λ����ɵ�fpu�쳣����Ϊ

     * fpu������ȷ�ؽ��б���/�ָ���������Щ��û�в��Թ���

     */

 13

    # �������ļ���Ҫ�漰��Intel�����ж�int0--int16�Ĵ�����int17-int31�������ʹ�ã���

    # ������һЩȫ�ֺ���������������ԭ����traps.c��˵����

 14 .globl _divide_error,_debug,_nmi,_int3,_overflow,_bounds,_invalid_op

 15 .globl _double_fault,_coprocessor_segment_overrun

 16 .globl _invalid_TSS,_segment_not_present,_stack_segment

 17 .globl _general_protection,_coprocessor_error,_irq13,_reserved

 18 .globl _alignment_check

 19

    # ������γ������޳����ŵ������

    # int0 -- ��������������������  ���ͣ����󣻳����ţ��ޡ�

    # ��ִ��DIV��IDIVָ��ʱ����������0��CPU�ͻ��������쳣����EAX����AX��AL������

    # ����һ���Ϸ��������Ľ��ʱ��Ҳ���������쳣��21�б��'_do_divide_error'ʵ������

    # C���Ժ���do_divide_error()�����������ģ���ж�Ӧ�����ơ�����'do_divide_error'��

    # traps.c��ʵ�֣���101�п�ʼ����

 20 _divide_error:

 21         pushl $_do_divide_error    # ���Ȱѽ�Ҫ���õĺ�����ַ��ջ��

 22 no_error_code:                     # �������޳����Ŵ�������ڴ����������56�еȡ�

 23         xchgl %eax,(%esp)          # _do_divide_error�ĵ�ַ �� eax��eax��������ջ��

 24         pushl %ebx

 25         pushl %ecx

 26         pushl %edx

 27         pushl %edi

 28         pushl %esi

 29         pushl %ebp

 30         push %ds                   # ����16λ�ĶμĴ�����ջ��ҲҪռ��4���ֽڡ�

 31         push %es

 32         push %fs

 33         pushl $0                   # "error code"   # ����ֵ0��Ϊ��������ջ��

 34         lea 44(%esp),%edx          # ȡ��Ч��ַ����ջ��ԭ���÷��ص�ַ����ջָ��λ�ã�

 35         pushl %edx                 # ��ѹ���ջ��

 36         movl $0x10,%edx            # ��ʼ���μĴ���ds��es��fs�������ں����ݶ�ѡ�����

 37         mov %dx,%ds

 38         mov %dx,%es

 39         mov %dx,%fs

    # �����ϵ�'*'�ű�ʾ���ò�����ָ����ַ���ĺ�������Ϊ��ӵ��á����ĺ����ǵ������𱾴�

    # �쳣��C��������������do_divide_error()�ȡ���41���ǽ���ջָ���8�൱��ִ������pop

    # ������������������������ջ������C����������33�к�35����ջ��ֵ�����ö�ջָ������

    # ָ��Ĵ���fs��ջ����

 40         call *%eax

 41         addl $8,%esp

 42         pop %fs

 43         pop %es

 44         pop %ds

 45         popl %ebp

 46         popl %esi

 47         popl %edi

 48         popl %edx

 49         popl %ecx

 50         popl %ebx

 51         popl %eax                  # ����ԭ��eax�е����ݡ�

 52         iret

 53

    # int1 -- debug�����ж���ڵ㡣��������ͬ�ϡ����ͣ�����/���壨Fault/Trap�����޴���š�

    # ��eflags��TF��־��λʱ���������жϡ�������Ӳ���ϵ㣨���ݣ����壬���룺���󣩣�����

    # ������ָ�������������񽻻����壬���ߵ��ԼĴ���������Ч�����󣩣�CPU�ͻ�������쳣��

 54 _debug:

 55         pushl $_do_int3         # _do_debug  # C����ָ����ջ������ͬ��

 56         jmp no_error_code

 57

    # int2 -- �������жϵ�����ڵ㡣  ���ͣ����壻�޴���š�

    # ���ǽ��еı�����̶��ж�������Ӳ���жϡ�ÿ�����յ�һ��NMI�źţ�CPU�ڲ��ͻ�����ж�

    # ����2����ִ�б�׼�ж�Ӧ�����ڣ���˺ܽ�ʡʱ�䡣NMIͨ������Ϊ��Ϊ��Ҫ��Ӳ���¼�ʹ�á�

    # ��CPU�յ�һ�� NMI �źŲ��ҿ�ʼִ�����жϴ�������ʱ��������е�Ӳ���ж϶��������ԡ�

 58 _nmi:

 59         pushl $_do_nmi

 60         jmp no_error_code

 61

    # int3 -- �ϵ�ָ�������жϵ���ڵ㡣  ���ͣ����壻�޴���š�

    # ��int 3 ָ���������жϣ���Ӳ���ж��޹ء���ָ��ͨ���ɵ�ʽ�����뱻��ʽ����Ĵ����С�

    # ��������ͬ_debug��

 62 _int3:

 63         pushl $_do_int3

 64         jmp no_error_code

 65

    # int4 -- ������������ж���ڵ㡣  ���ͣ����壻�޴���š�

    # EFLAGS��OF��־��λʱCPUִ��INTOָ��ͻ��������жϡ�ͨ�����ڱ����������������������

 66 _overflow:

 67         pushl $_do_overflow

 68         jmp no_error_code

 69

    # int5 -- �߽�������ж���ڵ㡣  ���ͣ������޴���š�

    # ������������Ч��Χ����ʱ�������жϡ���BOUNDָ�����ʧ�ܾͻ�������жϡ�BOUNDָ����

    # 3���������������1��������������֮�䣬�Ͳ����쳣5��

 70 _bounds:

 71         pushl $_do_bounds

 72         jmp no_error_code

 73

    # int6 -- ��Ч����ָ������ж���ڵ㡣  ���ͣ������޴���š�

    # CPU ִ�л�����⵽һ����Ч�IJ������������жϡ�

 74 _invalid_op:

 75         pushl $_do_invalid_op

 76         jmp no_error_code

 77

    # int9 -- Э�������γ��������ж���ڵ㡣  ���ͣ��������޴���š�

    # ���쳣�����ϵ�ͬ��Э������������������Ϊ�ڸ���ָ�������̫��ʱ�����Ǿ������������

    # ���ػ򱣴泬�����ݶεĸ���ֵ��

 78 _coprocessor_segment_overrun:

 79         pushl $_do_coprocessor_segment_overrun

 80         jmp no_error_code

 81

    # int15 �C ����Intel�����жϵ���ڵ㡣

 82 _reserved:

 83         pushl $_do_reserved

 84         jmp no_error_code

 85

    # int45 -- (0x20 + 13) Linux���õ���ѧЭ������Ӳ���жϡ�

    # ��Э������ִ����һ������ʱ�ͻᷢ��IRQ13�ж��źţ���֪ͨCPU������ɡ�80387��ִ��

    # ����ʱ��CPU��ȴ��������ɡ�����89����0xF0��Э�����˿ڣ�������æ��������ͨ��д

    # �ö˿ڣ����жϽ�����CPU��BUSY�����źţ������¼���80387�Ĵ�������չ��������PEREQ��

    # �ò�����Ҫ��Ϊ��ȷ���ڼ���ִ��80387���κ�ָ��֮ǰ��CPU��Ӧ���жϡ�

 86 _irq13:

 87         pushl %eax

 88         xorb %al,%al

 89         outb %al,$0xF0

 90         movb $0x20,%al

 91         outb %al,$0x20             # ��8259���жϿ���оƬ����EOI���жϽ������źš�

 92         jmp 1f                     # ��������תָ������ʱ���á�

 93 1:      jmp 1f

 94 1:      outb %al,$0xA0             # ����8259���жϿ���оƬ����EOI���жϽ������źš�

 95         popl %eax

 96         jmp _coprocessor_error     # �ú���ԭ�ڱ������У����ѷŵ�system_call.s�С�

 97

    # �����ж��ڵ���ʱCPU�����жϷ��ص�ַ֮�󽫳�����ѹ���ջ����˷���ʱҲ��Ҫ��������

    # �������μ�ͼ5.3(b)����

 

    # int8 -- ˫�������ϡ�  ���ͣ��������д����롣

    # ͨ����CPU�ڵ���ǰһ���쳣�Ĵ���������ּ�⵽һ���µ��쳣ʱ���������쳣�ᱻ���еؽ���

    # ��������Ҳ���������ٵ������CPU���ܽ��������Ĵ��д�����������ʱ�ͻ��������жϡ�

 98 _double_fault:

 99         pushl $_do_double_fault    # C������ַ��ջ��

100 error_code:

101         xchgl %eax,4(%esp)         # error code <-> %eax��eaxԭ����ֵ�������ڶ�ջ�ϡ�

102         xchgl %ebx,(%esp)          # &function <-> %ebx��ebxԭ����ֵ�������ڶ�ջ�ϡ�

103         pushl %ecx

104         pushl %edx

105         pushl %edi

106         pushl %esi

107         pushl %ebp

108         push %ds

109         push %es

110         push %fs

111         pushl %eax                 # error code   # ��������ջ��

112         lea 44(%esp),%eax          # offset       # ���򷵻ص�ַ����ջָ��λ��ֵ��ջ��

113         pushl %eax

114         movl $0x10,%eax            # ���ں����ݶ�ѡ�����

115         mov %ax,%ds

116         mov %ax,%es

117         mov %ax,%fs

118         call *%ebx                 # ��ӵ��ã�������Ӧ��C���������������ջ��

119         addl $8,%esp               # ������ջ��2������C�����IJ�����

120         pop %fs

121         pop %es

122         pop %ds

123         popl %ebp

124         popl %esi

125         popl %edi

126         popl %edx

127         popl %ecx

128         popl %ebx

129         popl %eax

130         iret

131

    # int10 -- ��Ч������״̬��(TSS)��  ���ͣ������г����롣

    # CPU��ͼ�л���һ�����̣����ý��̵�TSS��Ч������TSS����һ�����������쳣��������TSS

    # ���ȳ���104�ֽ�ʱ������쳣�ڵ�ǰ�����в���������л�����ֹ������������ᵼ�����л�

    # ����������в������쳣��

132 _invalid_TSS:

133         pushl $_do_invalid_TSS

134         jmp error_code

135

    # int11 -- �β����ڡ�  ���ͣ������г����롣

    # �����õĶβ����ڴ��С����������б�־ָ���β����ڴ��С�

136 _segment_not_present:

137         pushl $_do_segment_not_present

138         jmp error_code

139

    # int12 -- ��ջ�δ���  ���ͣ������г����롣

    # ָ�������ͼ������ջ�η�Χ�����߶�ջ�β����ڴ��С������쳣11��13����������Щ����

    # ϵͳ������������쳣��ȷ��ʲôʱ��Ӧ��Ϊ�����������ջ�ռ䡣

140 _stack_segment:

141         pushl $_do_stack_segment

142         jmp error_code

143

    # int13 -- һ�㱣���Գ�����  ���ͣ������г����롣

    # �����Dz������κ�������Ĵ�����һ���쳣����ʱû�ж�Ӧ�Ĵ���������0--16����ͨ����

    # ��鵽���ࡣ

144 _general_protection:

145         pushl $_do_general_protection

146         jmp error_code

147

    # int17 -- �߽�����������

    # ���������ڴ�߽���ʱ������Ȩ��3���û��������ݷDZ߽����ʱ��������쳣��

148 _alignment_check:

149         pushl $_do_alignment_check

150         jmp error_code

151

    # int7 -- �豸�����ڣ�_device_not_available����kernel/sys_call.s��158�С�

    # int14 -- ҳ����_page_fault����mm/page.s��14�С�

    # int16 -- Э����������_coprocessor_error����kernel/sys_call.s��140�С�

    # ʱ���ж�int 0x20��_timer_interrupt����kernel/sys_call.s��189�С�

    # ϵͳ����int 0x80��_system_call����kernel/sys_call.s��84�С�


 


 

8.2 ����8-2 linux/kernel/traps.c


  1 /*

  2  *  linux/kernel/traps.c

  3  *

  4  *  (C) 1991  Linus Torvalds

  5  */

  6

  7 /*

  8  * 'Traps.c' handles hardware traps and faults after we have saved some

  9  * state in 'asm.s'. Currently mostly a debugging-aid, will be extended

 10  * to mainly kill the offending process (probably by giving it a signal,

 11  * but possibly by killing it outright if necessary).

 12  */

    /*

     * �ڳ���asm.s�б�����һЩ״̬�󣬱�������������Ӳ������͹��ϡ�Ŀǰ��Ҫ���ڵ���Ŀ�ģ�

     * �Ժ���չ����ɱ�����𻵵Ľ��̣���Ҫ��ͨ������һ���źţ��������ҪҲ��ֱ��ɱ������

     */

 13 #include <string.h>       // �ַ���ͷ�ļ�����Ҫ������һЩ�й��ڴ���ַ���������Ƕ�뺯����

 14

 15 #include <linux/head.h>   // headͷ�ļ��������˶��������ļ򵥽ṹ���ͼ���ѡ���������

 16 #include <linux/sched.h>  // ���ȳ���ͷ�ļ�������������ṹtask_struct����ʼ����0�����ݣ�

                              // ����һЩ�й��������������úͻ�ȡ��Ƕ��ʽ��ຯ������䡣

 17 #include <linux/kernel.h> // �ں�ͷ�ļ�������һЩ�ں˳��ú�����ԭ�ζ��塣

 18 #include <asm/system.h>   // ϵͳͷ�ļ������������û��޸�������/�ж��ŵȵ�Ƕ��ʽ���ꡣ

 19 #include <asm/segment.h>  // �β���ͷ�ļ����������йضμĴ���������Ƕ��ʽ��ຯ����

 20 #include <asm/io.h>       // ����/���ͷ�ļ�������Ӳ���˿�����/���������䡣

 21

    // ������䶨��������Ƕ��ʽ������亯�����й�Ƕ��ʽ���Ļ����﷨���������б����˵����

    // ��Բ������ס�������䣨�������е���䣩������Ϊ����ʽʹ�ã���������__res�������ֵ��

    // ��23�ж�����һ���Ĵ�������__res���ñ�������������һ���Ĵ����У��Ա��ڿ��ٷ��ʺͲ�����

    // �����ָ���Ĵ���������eax������ô���ǿ��԰Ѹþ�д�ɡ�register char __res asm("ax");����

    // ȡ��seg�е�ַaddr����һ���ֽڡ�

    // ������seg - ��ѡ�����addr - ����ָ����ַ��

    // �����%0 - eax (__res)�����룺%1 - eax (seg)��%2 - �ڴ��ַ (*(addr))��

 22 #define get_seg_byte(seg,addr) ({ \

 23 register char __res; \

 24 __asm__("push %%fs;mov %%ax,%%fs;movb %%fs:%2,%%al;pop %%fs" \

 25         :"=a" (__res):"0" (seg),"m" (*(addr))); \

 26 __res;})

 27

    // ȡ��seg�е�ַaddr����һ�����֣�4�ֽڣ���

    // ������seg - ��ѡ�����addr - ����ָ����ַ��

    // �����%0 - eax (__res)�����룺%1 - eax (seg)��%2 - �ڴ��ַ (*(addr))��

 28 #define get_seg_long(seg,addr) ({ \

 29 register unsigned long __res; \

 30 __asm__("push %%fs;mov %%ax,%%fs;movl %%fs:%2,%%eax;pop %%fs" \

 31         :"=a" (__res):"0" (seg),"m" (*(addr))); \

 32 __res;})

 33

    // ȡfs�μĴ�����ֵ��ѡ�������

    // �����%0 - eax (__res)��

 34 #define _fs() ({ \

 35 register unsigned short __res; \

 36 __asm__("mov %%fs,%%ax":"=a" (__res):); \

 37 __res;})

 38

    // ���¶�����һЩ����ԭ�͡�

 39 void page_exception(void);                   // ҳ�쳣��ʵ����page_fault��mm/page.s��14����

 40

 41 void divide_error(void);                     // int0��kernel/asm.s��20����

 42 void debug(void);                            // int1��kernel/asm.s��54����

 43 void nmi(void);                              // int2��kernel/asm.s��58����

 44 void int3(void);                             // int3��kernel/asm.s��62����

 45 void overflow(void);                         // int4��kernel/asm.s��66����

 46 void bounds(void);                           // int5��kernel/asm.s��70����

 47 void invalid_op(void);                       // int6��kernel/asm.s��74����

 48 void device_not_available(void);             // int7��kernel/sys_call.s��158����

 49 void double_fault(void);                     // int8��kernel/asm.s��98����

 50 void coprocessor_segment_overrun(void);      // int9��kernel/asm.s��78����

 51 void invalid_TSS(void);                      // int10��kernel/asm.s��132����

 52 void segment_not_present(void);              // int11��kernel/asm.s��136����

 53 void stack_segment(void);                    // int12��kernel/asm.s��140����

 54 void general_protection(void);               // int13��kernel/asm.s��144����

 55 void page_fault(void);                       // int14��mm/page.s��14����

 56 void coprocessor_error(void);                // int16��kernel/sys_call.s��140����

 57 void reserved(void);                         // int15��kernel/asm.s��82����

 58 void parallel_interrupt(void);               // int39��kernel/sys_call.s��295����

 59 void irq13(void);                            // int45 Э�������жϴ�����kernel/asm.s��86����

 60 void alignment_check(void);                  // int46��kernel/asm.s��148����

 61

    // ���ӳ���������ӡ�����жϵ����ơ������š����ó����EIP��EFLAGS��ESP��fs�μĴ���ֵ��

    // �εĻ�ַ���εij��ȡ����̺�pid������š�10�ֽ�ָ���롣�����ջ���û����ݶΣ���

    // ��ӡ16�ֽڵĶ�ջ���ݡ���Щ��Ϣ�����ڳ�����ԡ�

 62 static void die(char * str,long esp_ptr,long nr)

 63 {

 64         long * esp = (long *) esp_ptr;

 65         int i;

 66

 67         printk("%s: %04x\n\r",str,nr&0xffff);

    // ���д�ӡ�����ʾ��ǰ���ý��̵�CS:EIP��EFLAGS��SS:ESP��ֵ����������!δ�ҵ�����Դ����֪������esp[0]

    // ��Ϊͼ�е�esp0λ�á�������ǰ�����ֿ�����Ϊ��

    // (1) EIP:\t%04x:%p\n  -- esp[1]�Ƕ�ѡ�����cs����esp[0]��eip

    // (2) EFLAGS:\t%p      -- esp[2]��eflags

    // (3) ESP:\t%04x:%p\n  -- esp[4]��ԭss��esp[3]��ԭesp

 68         printk("EIP:\t%04x:%p\nEFLAGS:\t%p\nESP:\t%04x:%p\n",

 69                 esp[1],esp[0],esp[2],esp[4],esp[3]);

 70         printk("fs: %04x\n",_fs());

 71         printk("base: %p, limit: %p\n",get_base(current->ldt[1]),get_limit(0x17));

 72         if (esp[4] == 0x17) {             // ��ԭssֵΪ0x17���û�ջ�����򻹴�ӡ��

 73                 printk("Stack: ");        // �û�ջ�е�4������ֵ��16�ֽڣ���

 74                 for (i=0;i<4;i++)

 75                         printk("%p ",get_seg_long(0x17,i+(long *)esp[3]));

 76                 printk("\n");

 77         }

 78         str(i);                 // ȡ��ǰ�������������ţ�include/linux/sched.h��210�У���

 79         printk("Pid: %d, process nr: %d\n\r",current->pid,0xffff & i); // ���̺ţ�����š�

 80         for(i=0;i<10;i++)

 81                 printk("%02x ",0xff & get_seg_byte(esp[1],(i+(char *)esp[0])));

 82         printk("\n\r");

 83         do_exit(11);            /* play segment exception */

 84 }

 85

    // ������Щ��do_��ͷ�ĺ�����asm.s�ж�Ӧ�жϴ���������õ�C������

 86 void do_double_fault(long esp, long error_code)

 87 {

 88         die("double fault",esp,error_code);

 89 }

 90

 91 void do_general_protection(long esp, long error_code)

 92 {

 93         die("general protection",esp,error_code);

 94 }

 95

 96 void do_alignment_check(long esp, long error_code)

 97 {

 98     die("alignment check",esp,error_code);

 99 }

100

101 void do_divide_error(long esp, long error_code)

102 {

103         die("divide error",esp,error_code);

104 }

105

    // �����ǽ����жϺ�˳��ѹ���ջ�ļĴ���ֵ���μ�asm.s�����24--35�С�

106 void do_int3(long * esp, long error_code,

107                 long fs,long es,long ds,

108                 long ebp,long esi,long edi,

109                 long edx,long ecx,long ebx,long eax)

110 {

111         int tr;

112

113         __asm__("str %%ax":"=a" (tr):"" (0));               // ȡ����Ĵ���ֵ��tr��

114         printk("eax\t\tebx\t\tecx\t\tedx\n\r%8x\t%8x\t%8x\t%8x\n\r",

115                 eax,ebx,ecx,edx);

116         printk("esi\t\tedi\t\tebp\t\tesp\n\r%8x\t%8x\t%8x\t%8x\n\r",

117                 esi,edi,ebp,(long) esp);

118         printk("\n\rds\tes\tfs\ttr\n\r%4x\t%4x\t%4x\t%4x\n\r",

119                 ds,es,fs,tr);

120         printk("EIP: %8x   CS: %4x  EFLAGS: %8x\n\r",esp[0],esp[1],esp[2]);

121 }

122

123 void do_nmi(long esp, long error_code)

124 {

125         die("nmi",esp,error_code);

126 }

127

128 void do_debug(long esp, long error_code)

129 {

130         die("debug",esp,error_code);

131 }

132

133 void do_overflow(long esp, long error_code)

134 {

135         die("overflow",esp,error_code);

136 }

137

138 void do_bounds(long esp, long error_code)

139 {

140         die("bounds",esp,error_code);

141 }

142

143 void do_invalid_op(long esp, long error_code)

144 {

145         die("invalid operand",esp,error_code);

146 }

147

148 void do_device_not_available(long esp, long error_code)

149 {

150         die("device not available",esp,error_code);

151 }

152

153 void do_coprocessor_segment_overrun(long esp, long error_code)

154 {

155         die("coprocessor segment overrun",esp,error_code);

156 }

157

158 void do_invalid_TSS(long esp,long error_code)

159 {

160         die("invalid TSS",esp,error_code);

161 }

162

163 void do_segment_not_present(long esp,long error_code)

164 {

165         die("segment not present",esp,error_code);

166 }

167

168 void do_stack_segment(long esp,long error_code)

169 {

170         die("stack segment",esp,error_code);

171 }

172

173 void do_coprocessor_error(long esp, long error_code)

174 {

175         if (last_task_used_math != current)

176                 return;

177         die("coprocessor error",esp,error_code);

178 }

179

180 void do_reserved(long esp, long error_code)

181 {

182         die("reserved (15,17-47) error",esp,error_code);

183 }

184

    // �������쳣�����壩�жϳ����ʼ���ӳ����������ǵ��жϵ����ţ��ж���������

    // set_trap_gate()��set_system_gate()��ʹ�����ж���������IDT�е������ţ�Trap Gate����

    // ����֮�����Ҫ��������ǰ�����õ���Ȩ��Ϊ0��������3����˶ϵ������ж�int3������ж�

    // overflow �ͱ߽�����ж� bounds �������κγ�����á� ��������������Ƕ��ʽ�������

    // �μ�include/asm/system.h����36�С�39�С�

185 void trap_init(void)

186 {

187         int i;

188

189         set_trap_gate(0,&divide_error);     // ���ó������������ж�����ֵ��������ͬ��

190         set_trap_gate(1,&debug);

191         set_trap_gate(2,&nmi);

192         set_system_gate(3,&int3);           /* int3-5 can be called from all */

193         set_system_gate(4,&overflow);       /* int3-5 ���Ա����г���ִ�� */

194         set_system_gate(5,&bounds);

195         set_trap_gate(6,&invalid_op);

196         set_trap_gate(7,&device_not_available);

197         set_trap_gate(8,&double_fault);

198         set_trap_gate(9,&coprocessor_segment_overrun);

199         set_trap_gate(10,&invalid_TSS);

200         set_trap_gate(11,&segment_not_present);

201         set_trap_gate(12,&stack_segment);

202         set_trap_gate(13,&general_protection);

203         set_trap_gate(14,&page_fault);

204         set_trap_gate(15,&reserved);

205         set_trap_gate(16,&coprocessor_error);

206         set_trap_gate(17,&alignment_check);

 

    // �����int17-47���������Ⱦ�����Ϊreserved���Ժ��Ӳ����ʼ��ʱ�����������Լ��������š�

207         for (i=18;i<48;i++)

208                 set_trap_gate(i,&reserved);

 

    // ����Э�������ж�0x2d��45����������������������������ж��������ò��п��ж���������

209         set_trap_gate(45,&irq13);

210         outb_p(inb_p(0x21)&0xfb,0x21);          // ����8259A��оƬ��IRQ2�ж�����

211         outb(inb_p(0xA1)&0xdf,0xA1);            // ����8259A��оƬ��IRQ13�ж�����

212         set_trap_gate(39,&parallel_interrupt);  // ���ò��п�1���ж�0x27��������������

213 }

214


 


 

8.3 ����8-3 linux/kernel/sys_call.s


  1 /*

  2  *  linux/kernel/system_call.s

  3  *

  4  *  (C) 1991  Linus Torvalds

  5  */

  6

  7 /*

  8  *  system_call.s  contains the system-call low-level handling routines.

  9  * This also contains the timer-interrupt handler, as some of the code is

 10  * the same. The hd- and flopppy-interrupts are also here.

 11  *

 12  * NOTE: This code handles signal-recognition, which happens every time

 13  * after a timer-interrupt and after each system call. Ordinary interrupts

 14  * don't handle signal-recognition, as that would clutter them up totally

 15  * unnecessarily.

 16  *

 17  * Stack layout in 'ret_from_system_call':

 18  *

 19  *       0(%esp) - %eax

 20  *       4(%esp) - %ebx

 21  *       8(%esp) - %ecx

 22  *       C(%esp) - %edx

 23  *      10(%esp) - original %eax        (-1 if not system call)

 24  *      14(%esp) - %fs

 25  *      18(%esp) - %es

 26  *      1C(%esp) - %ds

 27  *      20(%esp) - %eip

 28  *      24(%esp) - %cs

 29  *      28(%esp) - %eflags

 30  *      2C(%esp) - %oldesp

 31  *      30(%esp) - %oldss

 32  */

    /*

     * system_call.s�ļ�����ϵͳ���ã�system-call���ײ㴦���ӳ���������Щ����Ƚ����ƣ�

     * ����ͬʱҲ����ʱ���жϴ�����timer-interrupt�������Ӳ�̺����̵��жϴ�������Ҳ�����

     *

     * ע�⣺��δ��봦���źţ�signal��ʶ����ÿ��ʱ���жϺ�ϵͳ����֮�󶼻����ʶ��һ��

     * �жϹ��̲��������ź�ʶ����Ϊ���ϵͳ��ɻ��ҡ�

     *

     * ��ϵͳ���÷��أ�'ret_from_system_call'��ʱ��ջ�����ݼ�����19-30�С�

     */

    # ����Linusԭע����һ���жϹ�����ָ����ϵͳ�����жϣ�int 0x80����ʱ���жϣ�int 0x20��

    # ����������жϡ���Щ�жϻ����ں�̬���û�̬���������������Щ�жϹ�����Ҳ�����ź�ʶ��

    # �Ļ������п�����ϵͳ�����жϺ�ʱ���жϹ����ж��źŵ�ʶ�����������ͻ����Υ�����ں�

    # �������ռԭ�����ϵͳ���ޱ�Ҫ����Щ���������ж��д����źţ�Ҳ��������������

 33

 34 SIG_CHLD        = 17               # ����SIG_CHLD�źţ��ӽ���ֹͣ���������

 35

 36 EAX             = 0x00             # ��ջ�и����Ĵ�����ƫ��λ�á�

 37 EBX             = 0x04

 38 ECX             = 0x08

 39 EDX             = 0x0C

 40 ORIG_EAX        = 0x10             # �������ϵͳ���ã��������жϣ�ʱ����ֵΪ-1��

 41 FS              = 0x14

 42 ES              = 0x18

 43 DS              = 0x1C

 44 EIP             = 0x20             # 44 -- 48�� ��CPU�Զ���ջ��

 45 CS              = 0x24

 46 EFLAGS          = 0x28

 47 OLDESP          = 0x2C             # ����Ȩ���仯ʱ��ԭ��ջָ��Ҳ����ջ��

 48 OLDSS           = 0x30

 49

    # ������Щ������ṹ��task_struct���б�����ƫ��ֵ���μ�include/linux/sched.h��105�п�ʼ��

 50 state   = 0             # these are offsets into the task-struct.  # ����״̬�롣

 51 counter = 4             # ��������ʱ�����(�ݼ�)���δ�����������ʱ��Ƭ��

 52 priority = 8            # ����������������ʼ����ʱcounter=priority��Խ��������ʱ��Խ����

 53 signal  = 12            # ���ź�λͼ��ÿ������λ����һ���źţ��ź�ֵ=λƫ��ֵ+1��

 54 sigaction = 16          # MUST be 16 (=len of sigaction) # sigaction�ṹ���ȱ�����16�ֽڡ�

 55 blocked = (33*16)       # �������ź�λͼ��ƫ������

 56

    # ���¶�����sigaction�ṹ�е�ƫ�������μ�include/signal.h����55�п�ʼ��

 57 # offsets within sigaction

 58 sa_handler = 0                     # �źŴ������̵ľ��������������

 59 sa_mask = 4                        # �ź������롣

 60 sa_flags = 8                       # �źż���

 61 sa_restorer = 12                   # �ָ�����ָ�룬�μ�kernel/signal.c����˵����

 62

 63 nr_system_calls = 82               # Linux 0.12���ں��е�ϵͳ����������

 64

 65 ENOSYS = 38                        # ϵͳ���úų����롣

 66

 67 /*

 68  * Ok, I get parallel printer interrupts while using the floppy for some

 69  * strange reason. Urgel. Now I just ignore them.

 70  */

    /* ���ˣ���ʹ������ʱ���յ��˲��д�ӡ���жϣ�����֡��ǣ����ڲ�������

     */

 71 .globl _system_call,_sys_fork,_timer_interrupt,_sys_execve

 72 .globl _hd_interrupt,_floppy_interrupt,_parallel_interrupt

 73 .globl _device_not_available, _coprocessor_error

 74

    # ϵͳ���úŴ���ʱ�����س�����-ENOSYS��

 75 .align 2                           # �ڴ�4�ֽڶ��롣

 76 bad_sys_call:

 77         pushl $-ENOSYS             # eax����-ENOSYS��

 78         jmp ret_from_sys_call

 

    # ����ִ�е��ȳ�����ڡ����ȳ���schedule()�ڣ�kernel/sched.c��119�д���ʼ��

    # �����ȳ���schedule()����ʱ�ʹ�ret_from_sys_call����107�У�����ִ�С�

 79 .align 2

 80 reschedule:

 81         pushl $ret_from_sys_call   # ��ret_from_sys_call�ĵ�ַ��ջ��107�У���

 82         jmp _schedule

 

    #### int 0x80 --linuxϵͳ������ڵ㣨�����ж�int 0x80��eax���ǵ��úţ���

 83 .align 2

 84 _system_call:

 85         push %ds                   # ����ԭ�μĴ���ֵ��

 86         push %es

 87         push %fs

 88         pushl %eax                 # save the orig_eax   # ����eaxԭֵ��

 

    # һ��ϵͳ�������ɴ���3��������Ҳ���Բ���������������ջ��ebx��ecx��edx�з���ϵͳ

    # ������ӦC���Ժ���������99�У��ĵ��ò������⼸���Ĵ�����ջ��˳������GNU gcc�涨�ģ�

    # ebx�пɴ�ŵ�1��������ecx�д�ŵ�2��������edx�д�ŵ�3��������

    # ϵͳ�������ɲμ�ͷ�ļ�include/unistd.h�е�150��200�е�ϵͳ���úꡣ

 89         pushl %edx             

 90         pushl %ecx                 # push %ebx,%ecx,%edx as parameters

 91         pushl %ebx                 # to the system call

 

    # �ڱ�����μĴ���֮����ds,esָ���ں����ݶΣ���fsָ��ǰ�ֲ����ݶΣ���ָ��ִ�б�

    # ��ϵͳ���õ��û���������ݶΡ�ע�⣬��Linux 0.12���ں˸��������Ĵ���������ڴ��

    # ���ص��ģ����ǵĶλ�ַ�Ͷ��޳���ͬ���μ�fork.c������copy_mem()������

 92         movl $0x10,%edx            # set up ds,es to kernel space

 93         mov %dx,%ds

 94         mov %dx,%es

 95         movl $0x17,%edx            # fs points to local data space

 96         mov %dx,%fs

 

 97         cmpl _NR_syscalls,%eax     # ���ú����������Χ�Ļ�����ת��

 98         jae bad_sys_call

 

    # �������������ĺ����ǣ����õ�ַ=[_sys_call_table + %eax * 4]���μ�������˵����

    # sys_call_table[]��һ��ָ�����飬������include/linux/sys.h�У����������������ں�

    # ����82��ϵͳ����C���������ĵ�ַ��

 99         call _sys_call_table(,%eax,4)   # ��ӵ���ָ������C������

100         pushl %eax                      # ��ϵͳ���÷���ֵ��ջ��

 

    # ����101-106�в鿴��ǰ���������״̬��������ھ���״̬��state������0����ȥִ�е���

    # ��������������ھ���״̬��������ʱ��Ƭ�Ѿ����꣨counter=0������Ҳȥִ�е��ȳ���

    # ���統��̨�������еĽ���ִ�п����ն˶�д����ʱ����ôĬ�������¸ú�̨���������н���

    # ���յ�SIGTTIN��SIGTTOU�źţ����½����������н��̴���ֹͣ״̬������ǰ�����������

    # ���ء�

101 2:

102         movl _current,%eax         # ȡ��ǰ���񣨽��̣����ݽṹָ����eax��

103         cmpl $0,state(%eax)        # state

104         jne reschedule

105         cmpl $0,counter(%eax)      # counter

106         je reschedule

 

    # ������δ���ִ�д�ϵͳ����C�������غ󣬶��źŽ���ʶ�����������жϷ�������˳�ʱҲ

    # ����ת��������д�������˳��жϹ��̣��������131���ϵĴ����������ж�int 16��

    # �����б�ǰ�����Ƿ��dz�ʼ����task0��������򲻱ض�������ź�������Ĵ�����ֱ�ӷ��ء�

    # 109���ϵ�_task��ӦC�����е�task[]���飬ֱ������task�൱������task[0]��

107 ret_from_sys_call:

108         movl _current,%eax

109         cmpl _task,%eax            # task[0] cannot have signals

110         je 3f                      # ��ǰ(forward)��ת�����3���˳��жϴ�����

 

    # ͨ����ԭ���ó������ѡ����ļ�����жϵ��ó����Ƿ����û��������������ֱ���˳��жϡ�

    # ������Ϊ�������ں�ִ̬��ʱ������ռ���������������ź�����ʶ����������Ƚ�ѡ�����

    # ��Ϊ�û�����ε�ѡ��� 0x000f��RPL=3���ֲ���������Σ����ж��Ƿ�Ϊ�û������������

    # ��˵����ij���жϷ�����������ж�16����ת����107��ִ�е��ˣ�������ת�˳��жϳ���

    # ���⣬���ԭ��ջ��ѡ�����Ϊ0x17����ԭ��ջ�����û����У���Ҳ˵������ϵͳ���õĵ�����

    # �����û�������Ҳ�˳���

111         cmpw $0x0f,CS(%esp)        # was old code segment supervisor ?

112         jne 3f

113         cmpw $0x17,OLDSS(%esp)     # was stack segment = 0x17 ?

114         jne 3f

 

    # ������δ��루115-128�����ڴ�����ǰ�����е��źš�����ȡ��ǰ����ṹ�е��ź�λͼ��32λ��

    # ÿλ����1���źţ���Ȼ��������ṹ�е��ź����������Σ��룬�������������ź�λ��ȡ����ֵ

    # ��С���ź�ֵ���ٰ�ԭ�ź�λͼ�и��źŶ�Ӧ��λ��λ����0������󽫸��ź�ֵ��Ϊ����֮һ��

    # ��do_signal()��do_signal()�ڣ�kernel/signal.c,128���У����������13����ջ����Ϣ��

    # ��do_signal()���źŴ�����������֮��������ֵ��Ϊ0���ٿ����Ƿ���Ҫ�л����̻��������

    # �����źš�

115         movl signal(%eax),%ebx     # ȡ�ź�λͼ��ebx��ÿ1λ����1���źţ���32���źš�

116         movl blocked(%eax),%ecx    # ȡ���������Σ��ź�λͼ��ecx��

117         notl %ecx                  # ÿλȡ����

118         andl %ebx,%ecx             # ������ɵ��ź�λͼ��

119         bsfl %ecx,%ecx             # �ӵ�λ��λ0����ʼɨ��λͼ�����Ƿ���1��λ��

                                       # ���У���ecx������λ��ƫ��ֵ�����ڼ�λ0--31����

120         je 3f                      # ���û���ź�����ǰ��ת�˳���

121         btrl %ecx,%ebx             # ��λ���źţ�ebx����ԭsignalλͼ����

122         movl %ebx,signal(%eax)     # ���±���signalλͼ��Ϣ��current->signal��

123         incl %ecx                  # ���źŵ���Ϊ��1��ʼ������1--32����

124         pushl %ecx                 # �ź�ֵ��ջ��Ϊ����do_signal�IJ���֮һ��

125         call _do_signal            # ����C�����źŴ�������kernel/signal.c��128����

126         popl %ecx                  # ������ջ���ź�ֵ��

127         testl %eax, %eax           # ���Է���ֵ������Ϊ0����ת��ǰ����2��101�У�����

128         jne 2b                     # see if we need to switch tasks, or do more signals

 

129 3:      popl %eax                  # eax�к��е�100����ջ��ϵͳ���÷���ֵ��

130         popl %ebx

131         popl %ecx

132         popl %edx

133         addl $4, %esp              # skip orig_eax    # ������������ԭeaxֵ��

134         pop %fs

135         pop %es

136         pop %ds

137         iret

138

    #### int16 -- �����������жϡ�  ���ͣ������޴����롣

    # ����һ���ⲿ�Ļ���Ӳ�����쳣����Э��������⵽�Լ���������ʱ���ͻ�ͨ��ERROR����

    # ֪ͨCPU������������ڴ���Э�����������ij����źš�����תȥִ��C����math_error()

    # ��kernel/math/error.c 11�������غ���ת�����ret_from_sys_call������ִ�С�

139 .align 2

140 _coprocessor_error:

141         push %ds

142         push %es

143         push %fs

144         pushl $-1                   # fill in -1 for orig_eax  # ��-1����������ϵͳ���á�

145         pushl %edx

146         pushl %ecx

147         pushl %ebx

148         pushl %eax

149         movl $0x10,%eax            # ds,es��Ϊָ���ں����ݶΡ�

150         mov %ax,%ds

151         mov %ax,%es

152         movl $0x17,%eax            # fs��Ϊָ��ֲ����ݶΣ�������������ݶΣ���

153         mov %ax,%fs

154         pushl $ret_from_sys_call   # ��������÷��صĵ�ַ��ջ��

155         jmp _math_error            # ִ��math_error()��kernel/math/error.c��11����

156

    #### int7 -- �豸�����ڻ�Э�����������ڡ�  ���ͣ������޴����롣

    # ������ƼĴ��� CR0 ��EM��ģ�⣩��־��λ����CPU ִ��һ��Э������ָ��ʱ�ͻ�������

    # �жϣ�����CPU�Ϳ����л���������жϴ�������ģ��Э������ָ�181�У���

    # CR0�Ľ�����־TS���� CPUִ������ת��ʱ���õġ�TS ��������ȷ��ʲôʱ��Э�������е�

    # ������CPU ����ִ�е�����ƥ���ˡ���CPU ������һ��Э������ת��ָ��ʱ����TS��λʱ��

    # �ͻ��������жϡ���ʱ�Ϳ��Ա���ǰһ�������Э���������ݣ����ָ��������Э������ִ��

    # ״̬��176�У����μ�kernel/sched.c��92�С����ж����ת�Ƶ����ret_from_sys_call

    # ��ִ����ȥ����Ⲣ�����źţ���

157 .align 2

158 _device_not_available:

159         push %ds

160         push %es

161         push %fs

162         pushl $-1                  # fill in -1 for orig_eax  # ��-1����������ϵͳ���á�

163         pushl %edx

164         pushl %ecx

165         pushl %ebx

166         pushl %eax

167         movl $0x10,%eax            # ds,es��Ϊָ���ں����ݶΡ�

168         mov %ax,%ds

169         mov %ax,%es

170         movl $0x17,%eax            # fs��Ϊָ��ֲ����ݶΣ�������������ݶΣ���

171         mov %ax,%fs

    # ��CR0�������ѽ�����־TS����ȡCR0ֵ��������Э�����������־EMû����λ��˵������

    # EM������жϣ���ָ�����Э������״̬��ִ��C���� math_state_restore()�����ڷ���ʱ

    # ȥִ��ret_from_sys_call���Ĵ��롣

172         pushl $ret_from_sys_call   # ��������ת����õķ��ص�ַ��ջ��

173         clts                       # clear TS so that we can use math

174         movl %cr0,%eax

175         testl $0x4,%eax            # EM (math emulation bit)

176         je _math_state_restore     # ִ��math_state_restore()��kernel/sched.c��92�У���

 

    # ��EM��־��λ����ȥִ����ѧ�������math_emulate()��

177         pushl %ebp

178         pushl %esi

179         pushl %edi

180         pushl $0                   # temporary storage for ORIG_EIP

181         call _math_emulate         # ����C������math/math_emulate.c��476�У���

182         addl $4,%esp               # ������ʱ�洢��

183         popl %edi

184         popl %esi

185         popl %ebp

186         ret                        # �����ret����ת��ret_from_sys_call(107��)��

187

    #### int32 -- (int 0x20) ʱ���жϴ��������ж�Ƶ������Ϊ100Hz(include/linux/sched.h,4)��

    # ��ʱоƬ8253/8254����(kernel/sched.c,438)����ʼ���ġ��������jiffiesÿ10�����1��

    # ��δ��뽫jiffies��1�����ͽ����ж�ָ���8259��������Ȼ���õ�ǰ��Ȩ����Ϊ��������

    # C����do_timer(long CPL)�������÷���ʱתȥ��Ⲣ�����źš�

188 .align 2

189 _timer_interrupt:

190         push %ds                   # save ds,es and put kernel data space

191         push %es                   # into them. %fs is used by _system_call

192         push %fs                   # ����ds��es������ָ���ں����ݶΡ�fs������system_call��

193         pushl $-1                  # fill in -1 for orig_eax  # ��-1����������ϵͳ���á�

 

    # �������DZ���Ĵ���eax��ecx��edx��������Ϊgcc�������ڵ��ú���ʱ���ᱣ�����ǡ�����Ҳ

    # ������ebx�Ĵ�������Ϊ�ں���ret_from_sys_call�л��õ�����

194         pushl %edx                 # we save %eax,%ecx,%edx as gcc doesn't

195         pushl %ecx                 # save those across function calls. %ebx

196         pushl %ebx                 # is saved as we use that in ret_sys_call

197         pushl %eax

198         movl $0x10,%eax            # ds,es��Ϊָ���ں����ݶΡ�

199         mov %ax,%ds

200         mov %ax,%es

201         movl $0x17,%eax            # fs��Ϊָ��ֲ����ݶΣ���������ݶΣ���

202         mov %ax,%fs

203         incl _jiffies

    # ���ڳ�ʼ���жϿ���оƬʱû�в����Զ�EOI������������Ҫ��ָ�������Ӳ���жϡ�

204         movb $0x20,%al             # EOI to interrupt controller #1

205         outb %al,$0x20

 

    # ����Ӷ�ջ��ȡ��ִ��ϵͳ���ô����ѡ�����CS�μĴ���ֵ���еĵ�ǰ��Ȩ����(0��3)��ѹ��

    # ��ջ����Ϊdo_timer�IJ�����do_timer()����ִ�������л�����ʱ�ȹ�������kernel/sched.c��

    # 324��ʵ�֡�

206         movl CS(%esp),%eax

207         andl $3,%eax               # %eax is CPL (0 or 3, 0=supervisor)

208         pushl %eax

209         call _do_timer             # 'do_timer(long CPL)' does everything from

210         addl $4,%esp               # task switching to accounting ...

211         jmp ret_from_sys_call

212

    #### ����sys_execve()ϵͳ���á�ȡ�жϵ��ó���Ĵ���ָ����Ϊ��������C����do_execve()��

    # do_execve()��fs/exec.c��207�С�

213 .align 2

214 _sys_execve:

215         lea EIP(%esp),%eax         # eaxָ���ջ�б����û�����eipָ�봦��

216         pushl %eax

217         call _do_execve

218         addl $4,%esp               # ��������ʱѹ��ջ��EIPֵ��

219         ret

220

    #### sys_fork()���ã����ڴ����ӽ��̣���system_call����2��ԭ����include/linux/sys.h�С�

    # ���ȵ���C����find_empty_process()��ȡ��һ�����̺�last_pid�������ظ�����˵��Ŀǰ����

    # ����������Ȼ�����copy_process()���ƽ��̡�

221 .align 2

222 _sys_fork:

223         call _find_empty_process   # Ϊ�½���ȡ�ý��̺�last_pid����kernel/fork.c��143����

224         testl %eax,%eax            # ��eax�з��ؽ��̺š������ظ������˳���

225         js 1f

226         push %gs

227         pushl %esi

228         pushl %edi

229         pushl %ebp

230         pushl %eax

231         call _copy_process         # ����C����copy_process()��kernel/fork.c��68����

232         addl $20,%esp              # ������������ѹջ���ݡ�

233 1:      ret

234

    #### int 46 -- (int 0x2E) Ӳ���жϴ���������ӦӲ���ж�����IRQ14��

    # �������Ӳ�̲�����ɻ�����ͻᷢ�����ж��źš�(�μ�kernel/blk_drv/hd.c)��

    # ������8259A�жϿ��ƴ�оƬ���ͽ���Ӳ���ж�ָ��(EOI)��Ȼ��ȡ����do_hd�еĺ���ָ�����edx

    # �Ĵ����У�����do_hdΪNULL�������ж�edx����ָ���Ƿ�Ϊ�ա����Ϊ�գ����edx��ֵָ��

    # unexpected_hd_interrupt()��������ʾ������Ϣ�������8259A��оƬ��EOIָ�������edx��

    # ָ��ָ��ĺ���: read_intr()��write_intr()��unexpected_hd_interrupt()��

235 _hd_interrupt:

236         pushl %eax

237         pushl %ecx

238         pushl %edx

239         push %ds

240         push %es

241         push %fs

242         movl $0x10,%eax            # ds,es��Ϊ�ں����ݶΡ�

243         mov %ax,%ds

244         mov %ax,%es

245         movl $0x17,%eax            # fs��Ϊ���ó���ľֲ����ݶΡ�

246         mov %ax,%fs

    # ���ڳ�ʼ���жϿ���оƬʱû�в����Զ�EOI������������Ҫ��ָ�������Ӳ���жϡ�

247         movb $0x20,%al

248         outb %al,$0xA0             # EOI to interrupt controller #1 # �ʹ�8259A��

249         jmp 1f                     # give port chance to breathe    # ����jmp����ʱ���á�

250 1:      jmp 1f

    # do_hd����Ϊһ������ָ�룬������ֵread_intr()��write_intr()������ַ���ŵ�edx�Ĵ�����

    # �ͽ�do_hdָ�������ΪNULL��Ȼ����Եõ��ĺ���ָ�룬����ָ��Ϊ�գ������ָ��ָ��C

    # ����unexpected_hd_interrupt()���Դ���δ֪Ӳ���жϡ�

251 1:      xorl %edx,%edx

252         movl %edx,_hd_timeout      # hd_timeout��Ϊ0����ʾ���������ڹ涨ʱ���ڲ������жϡ�

253         xchgl _do_hd,%edx

254         testl %edx,%edx

255         jne 1f                     # ���գ�����ָ��ָ��C����unexpected_hd_interrupt()��

256         movl $_unexpected_hd_interrupt,%edx

257 1:      outb %al,$0x20             # ��8259A��оƬEOIָ�����Ӳ���жϣ���

258         call *%edx                 # "interesting" way of handling intr.

259         pop %fs                    # �Ͼ����do_hdָ���C������

260         pop %es

261         pop %ds

262         popl %edx

263         popl %ecx

264         popl %eax

265         iret

266

    #### int38 -- (int 0x26) �����������жϴ���������ӦӲ���ж�����IRQ6��

    # �䴦�������������Ӳ�̵Ĵ�������һ������kernel/blk_drv/floppy.c����

    # ������8259A�жϿ�������оƬ����EOIָ�Ȼ��ȡ����do_floppy�еĺ���ָ�����eax

    # �Ĵ����У�����do_floppyΪNULL�������ж�eax����ָ���Ƿ�Ϊ�ա���Ϊ�գ����eax��ֵָ��

    # unexpected_floppy_interrupt ()��������ʾ������Ϣ��������eaxָ��ĺ���: rw_interrupt,

    # seek_interrupt,recal_interrupt,reset_interrupt��unexpected_floppy_interrupt��

267 _floppy_interrupt:

268         pushl %eax

269         pushl %ecx

270         pushl %edx

271         push %ds

272         push %es

273         push %fs

274         movl $0x10,%eax            # ds,es��Ϊ�ں����ݶΡ�

275         mov %ax,%ds

276         mov %ax,%es

277         movl $0x17,%eax            # fs��Ϊ���ó���ľֲ����ݶΡ�

278         mov %ax,%fs

279         movb $0x20,%al             # ����8259A�жϿ�����EOIָ�����Ӳ���жϣ���

280         outb %al,$0x20             # EOI to interrupt controller #1

    # do_floppyΪһ����ָ�룬������ֵʵ�ʴ���C����ָ�롣��ָ���ڱ������ŵ�eax�Ĵ�����ͽ�

    # do_floppy�����ÿա�Ȼ�����eax��ԭָ���Ƿ�Ϊ�գ�������ʹָ��ָ��C����

    # unexpected_floppy_interrupt()��

281         xorl %eax,%eax

282         xchgl _do_floppy,%eax

283         testl %eax,%eax            # ���Ժ���ָ���Ƿ�=NULL?

284         jne 1f                 # ���գ���ʹָ��ָ��C����unexpected_floppy_interrupt()��

285         movl $_unexpected_floppy_interrupt,%eax

286 1:      call *%eax                 # "interesting" way of handling intr.   # ��ӵ��á�

287         pop %fs                    # �Ͼ����do_floppyָ��ĺ�����

288         pop %es

289         pop %ds

290         popl %edx

291         popl %ecx

292         popl %eax

293         iret

294

    #### int 39 -- (int 0x27) ���п��жϴ������򣬶�ӦӲ���ж������ź�IRQ7��

    # ���汾�ں˻�δʵ�֡�����ֻ�Ƿ���EOIָ�

295 _parallel_interrupt:

296         pushl %eax

297         movb $0x20,%al

298         outb %al,$0x20

299         popl %eax

300         iret



 

8.4 ����8-4 linux/kernel/mktime.c����


  1 /*

  2  *  linux/kernel/mktime.c

  3  *

  4  *  (C) 1991  Linus Torvalds

  5  */

  6

  7 #include <time.h>            // ʱ��ͷ�ļ��������˱�׼ʱ�����ݽṹtm��һЩ����ʱ�亯��ԭ�͡�

  8

  9 /*

 10  * This isn't the library routine, it is only used in the kernel.

 11  * as such, we don't care about years<1970 etc, but assume everything

 12  * is ok. Similarly, TZ etc is happily ignored. We just do everything

 13  * as easily as possible. Let's find something public for the library

 14  * routines (although I think minix times is public).

 15  */

 16 /*

 17  * PS. I hate whoever though up the year 1970 - couldn't they have gotten

 18  * a leap-year instead? I also hate Gregorius, pope or no. I'm grumpy.

 19  */

    /*

     * �ⲻ�ǿ⺯�����������ں�ʹ�á�������Dz�����С��1970�����ݵȣ����ٶ�һ�о���������

     * ͬ����ʱ������TZ����Ҳ�Ⱥ��ԡ�����ֻ�Ǿ����ܼ򵥵ش������⡣������ҵ�һЩ�����Ŀ⺯��

     * ����������Ϊminix��ʱ�亯���ǹ����ģ���

     * ���⣬�Һ��Ǹ�����1970�꿪ʼ���� - �ѵ����ǾͲ���ѡ���һ�����꿪ʼ���Һ޸����������

     * �����̻ʡ����̣���ʲô�����ں������Ǹ�Ƣ��������ˡ�

     */

 20 #define MINUTE 60                    // 1���ӵ�������

 21 #define HOUR (60*MINUTE)             // 1Сʱ��������

 22 #define DAY (24*HOUR)                // 1���������

 23 #define YEAR (365*DAY)               // 1���������

 24

 25 /* interestingly, we assume leap-years */

    /* ��Ȥ�������ǿ��ǽ������� */

    // ��������Ϊ���ޣ�������ÿ���¿�ʼʱ������ʱ�䡣

 26 static int month[12] = {

 27         0,

 28         DAY*(31),

 29         DAY*(31+29),

 30         DAY*(31+29+31),

 31         DAY*(31+29+31+30),

 32         DAY*(31+29+31+30+31),

 33         DAY*(31+29+31+30+31+30),

 34         DAY*(31+29+31+30+31+30+31),

 35         DAY*(31+29+31+30+31+30+31+31),

 36         DAY*(31+29+31+30+31+30+31+31+30),

 37         DAY*(31+29+31+30+31+30+31+31+30+31),

 38         DAY*(31+29+31+30+31+30+31+31+30+31+30)

 39 };

 40

    // �ú��������1970��1��1��0ʱ�𵽿������վ�������������Ϊ����ʱ�䡣

    // ����tm�и��ֶ��Ѿ���init/main.c�б���ֵ����Ϣȡ��CMOS��

 41 long kernel_mktime(struct tm * tm)

 42 {

 43         long res;

 44         int year;

 45

    // ���ȼ���70�굽���ھ�������������Ϊ��2λ��ʾ��ʽ�����Ի���2000�����⡣���ǿ���

    // �򵥵�����ǰ������һ����������������⣺if (tm->tm_year<70) tm->tm_year += 100;

    // ����UNIX�����y�Ǵ�1970�����𡣵�1972�����һ�����꣬��˹�3�꣨71��72��73��

    // ���ǵ�1�����꣬������1970�꿪ʼ�����������㷽����Ӧ����Ϊ1 + (y - 3)/4����Ϊ

    // (y + 1)/4��res = ��Щ�꾭��������ʱ�� + ÿ������ʱ��1�������ʱ�� + ���굽����ʱ

    // �����������⣬month[]�������Ѿ���2�·ݵ������а�����������ʱ����������2�·�����

    // ������ 1�졣��ˣ������겻�����겢�ҵ�ǰ�·ݴ��� 2�·ݵĻ������Ǿ�Ҫ��ȥ���졣��

    // Ϊ��70�꿪ʼ�������Ե�����������жϷ����� (y + 2) �ܱ�4�����������ܳ���������

    // �����Ͳ������ꡣ

 46         year = tm->tm_year - 70;

 47 /* magic offsets (y+1) needed to get leapyears right.*/

    /* Ϊ�˻����ȷ����������������Ҫ����һ��ħ��ֵ(y+1) */

 48         res = YEAR*year + DAY*((year+1)/4);

 49         res += month[tm->tm_mon];

 50 /* and (y+2) here. If it wasn't a leap-year, we have to adjust */

    /* �Լ�(y+2)�����(y+2)�������꣬��ô���Ǿͱ�����е���(��ȥһ�������ʱ��)��*/

 51         if (tm->tm_mon>1 && ((year+2)%4))

 52                 res -= DAY;

 53         res += DAY*(tm->tm_mday-1);         // �ټ��ϱ��¹�ȥ������������ʱ�䡣

 54         res += HOUR*tm->tm_hour;            // �ټ��ϵ����ȥ��Сʱ��������ʱ�䡣

 55         res += MINUTE*tm->tm_min;           // �ټ���1Сʱ�ڹ�ȥ�ķ�����������ʱ�䡣

 56         res += tm->tm_sec;                  // �ټ���1�������ѹ���������

 57         return res;                         // �����ڴ�1970����������������ʱ�䡣

 58 }

 59


 


 

8.5 ����8-5 linux/kernel/sched.c


  1 /*

  2  *  linux/kernel/sched.c

  3  *

  4  *  (C) 1991  Linus Torvalds

  5  */

  6

  7 /*

  8  * 'sched.c' is the main kernel file. It contains scheduling primitives

  9  * (sleep_on, wakeup, schedule etc) as well as a number of simple system

 10  * call functions (type getpid(), which just extracts a field from

 11  * current-task

 12  */

    /*

     * 'sched.c'����Ҫ���ں��ļ������а����йص��ȵĻ�������(sleep_on��wakeup��schedule��)

     * �Լ�һЩ�򵥵�ϵͳ���ú���������getpid()�����ӵ�ǰ�����л�ȡһ���ֶΣ���

     */

 

    // �����ǵ��ȳ���ͷ�ļ�������������ṹtask_struct����1����ʼ��������ݡ�����һЩ�Ժ�

    // ����ʽ������й��������������úͻ�ȡ��Ƕ��ʽ��ຯ������

 13 #include <linux/sched.h>

 14 #include <linux/kernel.h> // �ں�ͷ�ļ�������һЩ�ں˳��ú�����ԭ�ζ��塣

 15 #include <linux/sys.h>    // ϵͳ����ͷ�ļ�������82��ϵͳ����C��������,��'sys_'��ͷ��

 16 #include <linux/fdreg.h>  // ����ͷ�ļ����������̿�����������һЩ���塣

 17 #include <asm/system.h>   // ϵͳͷ�ļ������������û��޸�������/�ж��ŵȵ�Ƕ��ʽ���ꡣ

 18 #include <asm/io.h>       // ioͷ�ļ�������Ӳ���˿�����/���������䡣

 19 #include <asm/segment.h>  // �β���ͷ�ļ����������йضμĴ���������Ƕ��ʽ��ຯ����

 20

 21 #include <signal.h>       // �ź�ͷ�ļ��������źŷ��ų�����sigaction�ṹ����������ԭ�͡�

 22

    // �ú�ȡ�ź�nr���ź�λͼ�ж�Ӧλ�Ķ�������ֵ���źű��1-32�������ź�5��λͼ��ֵ����

    // 1<<(5-1) = 16 = 00010000b��

 23 #define _S(nr) (1<<((nr)-1))

    // ����SIGKILL��SIGSTOP�ź����������źŶ��ǿ�������(��1011,1111,1110,1111,1111b)��

 24 #define _BLOCKABLE (~(_S(SIGKILL) | _S(SIGSTOP)))

 25

    // �ں˵��Ժ�������ʾ�����nr�Ľ��̺š�����״̬���ں˶�ջ�����ֽ�������Լ����

 26 void show_task(int nr,struct task_struct * p)

 27 {

 28         int i,j = 4096-sizeof(struct task_struct);

 29

 30         printk("%d: pid=%d, state=%d, father=%d, child=%d, ",nr,p->pid,

 31                 p->state, p->p_pptr->pid, p->p_cptr ? p->p_cptr->pid : -1);

 32         i=0;

 33         while (i<j && !((char *)(p+1))[i])  // ���ָ���������ݽṹ�Ժ����0���ֽ�����

 34                 i++;

 35         printk("%d/%d chars free in kstack\n\r",i,j);

 36         printk("   PC=%08X.", *(1019 + (unsigned long *) p));

 37         if (p->p_ysptr || p->p_osptr)

 38                 printk("   Younger sib=%d, older sib=%d\n\r",

 39                         p->p_ysptr ? p->p_ysptr->pid : -1,

 40                         p->p_osptr ? p->p_osptr->pid : -1);

 41         else

 42                 printk("\n\r");

 43 }

 44

    // ��ʾ�������������š����̺š�����״̬���ں˶�ջ�����ֽ�������Լ����

    // NR_TASKS��ϵͳ�����ɵ�������(����)����(64��)��������include/kernel/sched.h ��6�С�

 45 void show_state(void)

 46 {

 47         int i;

 48

 49         printk("\rTask-info:\n\r");

 50         for (i=0;i<NR_TASKS;i++)

 51                 if (task[i])

 52                         show_task(i,task[i]);

 53 }

 54

    // PC��8253��ʱоƬ������ʱ��Ƶ��ԼΪ1.193180MHz��Linux�ں�ϣ����ʱ�������жϵ�Ƶ����

    // 100Hz��Ҳ��ÿ10ms����һ��ʱ���жϡ��������LATCH������8253оƬ�ij�ֵ���μ�438�С�

 55 #define LATCH (1193180/HZ)

 56

 57 extern void mem_use(void);         // [??]û���κεط���������øú�����

 58

 59 extern int timer_interrupt(void);  // ʱ���жϴ�������kernel/system_call.s��176����

 60 extern int system_call(void);      // ϵͳ�����жϴ�������kernel/system_call.s��80����

 61

    // ÿ�����񣨽��̣����ں�̬����ʱ�����Լ����ں�̬��ջ�����ﶨ����������ں�̬��ջ�ṹ��

    // ���ﶨ���������ϣ�����ṹ��Ա��stack�ַ������Ա������Ϊһ����������ݽṹ�����ں�

    // ̬��ջ����ͬһ�ڴ�ҳ�У����ԴӶ�ջ�μĴ���ss���Ի�������ݶ�ѡ�����

 62 union task_union {

 63         struct task_struct task;

 64         char stack[PAGE_SIZE];

 65 };

 66

    // ���ó�ʼ��������ݡ���ʼ������include/kernel/sched.h�У���156�п�ʼ��

 67 static union task_union init_task = {INIT_TASK,};

 68

    // �ӿ�����ʼ����ĵδ���ʱ��ֵȫ�ֱ�����10ms/�δ𣩡�ϵͳʱ���ж�ÿ����һ�μ�һ���δ�

    // ǰ����޶��� volatile��Ӣ�Ľ������׸ı�ġ����ȶ�����˼������޶��ʵĺ������������

    // ָ�����������ݿ��ܻ����ڱ����������޸Ķ��仯��ͨ���ڳ���������һ������ʱ�� ��������

    // �������������ͨ�üĴ����У����� ebx������߷���Ч�ʡ���CPU����ֵ�ŵ� ebx�к�һ��

    // �Ͳ����ٹ��ĸñ�����Ӧ�ڴ�λ���е����ݡ�����ʱ�������������ں˳����һ���жϹ��̣�

    // �޸����ڴ��иñ�����ֵ��ebx�е�ֵ��������֮���¡�Ϊ�˽����������ʹ�����volatile

    // �޶������ô��������øñ���ʱһ��Ҫ��ָ���ڴ�λ����ȡ����ֵ�����T��Ҫ�� gcc��Ҫ��

    // jiffies �����Ż�������Ҳ��ҪŲ��λ�ã�������Ҫ���ڴ���ȡ��ֵ����Ϊʱ���жϴ�������

    // �ȳ�����޸�����ֵ��

 69 unsigned long volatile jiffies=0;

 70 unsigned long startup_time=0;                 // ����ʱ�䡣��1970:0:0:0��ʼ��ʱ��������

    // ������������ۼ���Ҫ������ʱ���������

 71 int jiffies_offset = 0;         /* # clock ticks to add to get "true

 72                                    time".  Should always be less than

 73                                    1 second's worth.  For time fanatics

 74                                    who like to syncronize their machines

 75                                    to WWV :-) */

    /* Ϊ����ʱ�Ӷ���Ҫ���ӵ�ʱ����������Ի�á���ȷʱ�䡱����Щ�����������

     * ���ܺͲ�Ӧ�ó���1�롣��������Ϊ����Щ��ʱ�侫ȷ��Ҫ����̵��ˣ�����ϲ

     * ���Լ��Ļ���ʱ����WWVͬ�� :-)

     */

 76

 77 struct task_struct *current = &(init_task.task);  // ��ǰ����ָ�루��ʼ��ָ������0����

 78 struct task_struct *last_task_used_math = NULL;   // ʹ�ù�Э�����������ָ�롣

 79

    // ��������ָ�����顣��1���ʼ��ָ���ʼ��������0�����������ݽṹ��

 80 struct task_struct * task[NR_TASKS] = {&(init_task.task), };

 81

    // �����û���ջ����1K�����4K�ֽڡ����ں˳�ʼ�����������б������ں�ջ����ʼ�����

    // �Ժ󽫱���������0���û�̬��ջ������������0֮ǰ�����ں�ջ���Ժ���������0��1����

    // ��̬ջ������ṹ�������ö�ջss:esp�����ݶ�ѡ�����ָ�룩����head.s����23�С�

    // ss������Ϊ�ں����ݶ�ѡ�����0x10����ָ��espָ�� user_stack�������һ����档����

    // ��ΪIntel CPUִ�ж�ջ����ʱ���ȵݼ���ջָ��spֵ��Ȼ����spָ�봦������ջ���ݡ�

 82 long user_stack [ PAGE_SIZE>>2 ] ;

 83

 84 struct {

 85         long * a;

 86         short b;

 87         } stack_start = { & user_stack [PAGE_SIZE>>2] , 0x10 };

 88 /*

 89  *  'math_state_restore()' saves the current math information in the

 90  * old math state array, and gets the new ones from the current task

 91  */

    /*

     * ����ǰЭ���������ݱ��浽��Э������״̬�����У�������ǰ�����Э������

     * ���ݼ��ؽ�Э��������

     */

    // �����񱻵��Ƚ������Ժ󣬸ú������Ա���ԭ�����Э������״̬�������ģ����ָ��µ��Ƚ�

    // ���ĵ�ǰ�����Э������ִ��״̬��

 92 void math_state_restore()

 93 {

    // �������û���򷵻�(��һ��������ǵ�ǰ����)������"��һ������"��ָ�ձ�������ȥ������

 94         if (last_task_used_math == current)

 95                 return;

    // �ڷ���Э����������֮ǰҪ�ȷ�WAITָ�����ϸ�����ʹ����Э���������򱣴���״̬��

 96         __asm__("fwait");

 97         if (last_task_used_math) {

 98                 __asm__("fnsave %0"::"m" (last_task_used_math->tss.i387));

 99         }

    // ���ڣ�last_task_used_mathָ��ǰ�����Ա���ǰ���񱻽�����ȥʱʹ�á���ʱ�����ǰ

    // �����ù�Э����������ָ���״̬������Ļ�˵���ǵ�һ��ʹ�ã����Ǿ���Э����������ʼ��

    // ���������ʹ����Э��������־��

100         last_task_used_math=current;

101         if (current->used_math) {

102                 __asm__("frstor %0"::"m" (current->tss.i387));

103         } else {

104                 __asm__("fninit"::);           // ��Э����������ʼ�����

105                 current->used_math=1;          // ����ʹ����Э��������־��

106         }

107 }

108

109 /*

110  *  'schedule()' is the scheduler function. This is GOOD CODE! There

111  * probably won't be any reason to change this, as it should work well

112  * in all circumstances (ie gives IO-bound processes good response etc).

113  * The one thing you might take a look at is the signal-handler code here.

114  *

115  *   NOTE!!  Task 0 is the 'idle' task, which gets called when no other

116  * tasks can run. It can not be killed, and it cannot sleep. The 'state'

117  * information in task[0] is never used.

118  */

    /*

     * 'schedule()'�ǵ��Ⱥ��������Ǹ��ܺõĴ��룡û���κ����ɶ��������޸ģ���Ϊ

     * �����������еĻ����¹����������ܹ���IO-�߽紦���ܺõ���Ӧ�ȣ���ֻ��һ��

     * ��ֵ�����⣬�Ǿ���������źŴ������롣

     *

     *   ע�⣡������0�Ǹ�����('idle')����ֻ�е�û�����������������ʱ�ŵ���

     * ���������ܱ�ɱ����Ҳ����˯�ߡ�����0�е�״̬��Ϣ'state'�Ǵ������õġ�

     */

119 void schedule(void)

120 {

121         int i,next,c;

122         struct task_struct ** p;              // ����ṹָ���ָ�롣

123

124 /* check alarm, wake up any interruptible tasks that have got a signal */

    /* ���alarm�����̵ı�����ʱֵ���������κ��ѵõ��źŵĿ��ж����� */

125

    // ���������������һ������ʼѭ�����alarm����ѭ��ʱ������ָ���

126         for(p = &LAST_TASK ; p > &FIRST_TASK ; --p)

127                 if (*p) {

    // ������ù�����ʱ��ʱtimeout�������Ѿ���ʱ����λ��ʱ��ʱֵ��������������ڿ�

    // �ж�˯��״̬TASK_INTERRUPTIBLE�£�������Ϊ����״̬��TASK_RUNNING����

128                         if ((*p)->timeout && (*p)->timeout < jiffies) {

129                                 (*p)->timeout = 0;

130                                 if ((*p)->state == TASK_INTERRUPTIBLE)

131                                         (*p)->state = TASK_RUNNING;

132                         }

    // ������ù�����Ķ�ʱֵalarm�������Ѿ�����(alarm<jiffies),�����ź�λͼ����SIGALRM

    // �źţ�����������SIGALARM�źš�Ȼ����alarm�����źŵ�Ĭ�ϲ�������ֹ���̡�jiffies

    // ��ϵͳ�ӿ�����ʼ����ĵδ�����10ms/�δ𣩡�������sched.h��139�С�

133                         if ((*p)->alarm && (*p)->alarm < jiffies) {

134                                 (*p)->signal |= (1<<(SIGALRM-1));

135                                 (*p)->alarm = 0;

136                         }

    // ����ź�λͼ�г����������ź��⻹�������źţ����������ڿ��ж�״̬����������Ϊ����

    // ״̬������'~(_BLOCKABLE & (*p)->blocked)'���ں��Ա��������źţ���SIGKILL��SIGSTOP

    // ���ܱ�������

137                         if (((*p)->signal & ~(_BLOCKABLE & (*p)->blocked)) &&

138                         (*p)->state==TASK_INTERRUPTIBLE)

139                                 (*p)->state=TASK_RUNNING;   //��Ϊ��������ִ�У�״̬��

140                 }

141

142 /* this is the scheduler proper: */

    /* �����ǵ��ȳ������Ҫ���� */

143

144         while (1) {

145                 c = -1;

146                 next = 0;

147                 i = NR_TASKS;

148                 p = &task[NR_TASKS];

    // ��δ���Ҳ�Ǵ�������������һ������ʼѭ���������������������������ۡ��Ƚ�ÿ��

    // ����״̬�����counter����������ʱ��ĵݼ��δ������ֵ����һ��ֵ������ʱ�仹������

    // next��ָ���ĸ�������š�

149                 while (--i) {

150                         if (!*--p)

151                                 continue;

152                         if ((*p)->state == TASK_RUNNING && (*p)->counter > c)

153                                 c = (*p)->counter, next = i;

154                 }

    // ����Ƚϵó���counterֵ������0�Ľ��������ϵͳ��û��һ�������е�������ڣ���ʱc

    // ��ȻΪ-1��next=0�������˳�144�п�ʼ��ѭ����ִ��161���ϵ������л�����������͸���

    // ÿ�����������Ȩֵ������ÿһ�������counterֵ��Ȼ��ص�125�����±Ƚϡ�counter ֵ

    // �ļ��㷽ʽΪ counter = counter /2 + priority��ע�⣬���������̲����ǽ��̵�״̬��

155                 if (c) break;

156                 for(p = &LAST_TASK ; p > &FIRST_TASK ; --p)

157                         if (*p)

158                                 (*p)->counter = ((*p)->counter >> 1) +

159                                                 (*p)->priority;

160         }

    // ������꣨������sched.h�У��ѵ�ǰ����ָ��currentָ�������Ϊnext�����񣬲��л�

    // �������������С���146����next����ʼ��Ϊ0�������ϵͳ��û���κ��������������ʱ��

    // �� next ʼ��Ϊ0����˵��Ⱥ�������ϵͳ����ʱȥִ������0�� ��ʱ����0��ִ��pause()

    // ϵͳ���ã����ֻ���ñ�������

161         switch_to(next);                     // �л��������Ϊnext�����񣬲�����֮��

162 }

163

    //// pause()ϵͳ���á�ת����ǰ�����״̬Ϊ���жϵĵȴ�״̬�������µ��ȡ�

    // ��ϵͳ���ý����½��̽���˯��״̬��ֱ���յ�һ���źš����ź�������ֹ���̻���ʹ����

    // ����һ���źŲ�������ֻ�е�������һ���źţ������źŲ������������أ�pause()��

    // �᷵�ء���ʱ pause()����ֵӦ���� -1������ errno����Ϊ EINTR�����ﻹû����ȫʵ��

    // ��ֱ��0.95�棩��

164 int sys_pause(void)

165 {

166         current->state = TASK_INTERRUPTIBLE;

167         schedule();

168         return 0;

169 }

170

    // �ѵ�ǰ������Ϊָ����˯��״̬�����жϵĻ򲻿��жϵģ�������˯�߶���ͷָ��ָ��ǰ����

    // ��������p�ǵȴ��������ͷָ�롣ָ���Ǻ���һ��������ַ�ı������������pʹ����ָ���

    // ָ����ʽ '**p'��������ΪC��������ֻ�ܴ�ֵ��û��ֱ�ӵķ�ʽ�ñ����ú����ı���øú���

    // �����б�����ֵ������ָ��'*p'ָ���Ŀ�꣨����������ṹ����ı䣬���Ϊ�����޸ĵ��ø�

    // ����������ԭ������ָ�������ֵ������Ҫ����ָ��'*p'��ָ�룬��'**p'���μ�����ǰʾ��ͼ��

    // pָ���ʹ�������

    // ����state������˯��ʹ�õ�״̬��TASK_UNINTERRUPTIBLE��TASK_INTERRUPTIBLE�����ڲ���

    // �ж�˯��״̬��TASK_UNINTERRUPTIBLE����������Ҫ�ں˳�������wake_up()������ȷ����֮��

    // ���ڿ��ж�˯��״̬��TASK_INTERRUPTIBLE������ͨ���źš�����ʱ���ֶλ��� ����Ϊ����

    // ״̬TASK_RUNNING����

    // *** ע�⣬���ڱ��ں˴��벻�Ǻܳ��죬���������˯����صĴ������һЩ���⣬�������

171 static inline void __sleep_on(struct task_struct **p, int state)

172 {

173         struct task_struct *tmp;

174

    // ��ָ����Ч�����˳�����ָ����ָ�Ķ��������NULL����ָ�뱾������Ϊ0)��

    // �����ǰ����������0��������(impossible!)��

175         if (!p)

176                 return;

177         if (current == &(init_task.task))

178                 panic("task[0] trying to sleep");

    // ��tmpָ���Ѿ��ڵȴ������ϵ�����(����еĻ�)������inode->i_wait�����ҽ�˯�߶���ͷ

    // �ĵȴ�ָ��ָ��ǰ���������Ͱѵ�ǰ������뵽�� *p�ĵȴ������С�Ȼ�󽫵�ǰ������

    // Ϊָ���ĵȴ�״̬����ִ�����µ��ȡ�

179         tmp = *p;

180         *p = current;

181         current->state = state;

182 repeat: schedule();

    // ֻ�е�����ȴ����񱻻���ʱ��������ֻ᷵�ص������ʾ�����ѱ���ȷ�ػ��Ѳ�ִ�С�

    // ����ȴ������л��еȴ����񣬲��Ҷ���ͷָ�� *p ��ָ��������ǵ�ǰ����ʱ��˵��

    // �ڱ��������ȴ����к����������ȴ����С���������Ӧ��ҲҪ����������񣬶���

    // ���Լ�Ӧ��˳������Щ���������е������ѣ�������ォ�ȴ�����ͷ��ָ��������Ϊ

    // ����״̬�����Լ�����Ϊ�����жϵȴ�״̬�����Լ�Ҫ�ȴ���Щ���������е����񱻻���

    // ��ִ��ʱ�����ѱ�����Ȼ������ִ�е��ȳ���

183         if (*p && *p != current) {

184                 (**p).state = 0;

185                 current->state = TASK_UNINTERRUPTIBLE;

186                 goto repeat;

187         }

    // ִ�е����˵������������������ִ�С���ʱ�ȴ�����ͷָ��Ӧ��ָ����������Ϊ

    // �գ���������������⣬������ʾ������Ϣ�����������ͷָ��ָ��������ǰ��������

    // ������*p = tmp���� ��ȷʵ��������һ�����񣬼������л�������tmp��Ϊ�գ�����

    // ����֮�����Ƚ�����е������ڻ��Ѻ�����ʱ���ջ�ѵȴ�����ͷָ���ó�NULL��

188         if (!*p)

189                 printk("Warning: *P = NULL\n\r");

190         if (*p = tmp)

191                 tmp->state=0;

192 }

193

    // ����ǰ������Ϊ���жϵĵȴ�״̬��TASK_INTERRUPTIBLE����������ͷָ��*pָ���ĵȴ�

    // �����С�

194 void interruptible_sleep_on(struct task_struct **p)

195 {

196         __sleep_on(p,TASK_INTERRUPTIBLE);

197 }

198

    // �ѵ�ǰ������Ϊ�����жϵĵȴ�״̬��TASK_UNINTERRUPTIBLE��������˯�߶���ͷָ��ָ��

    // ��ǰ����ֻ����ȷ�ػ���ʱ�Ż᷵�ء��ú����ṩ�˽������жϴ�������֮���ͬ�����ơ�

199 void sleep_on(struct task_struct **p)

200 {

201         __sleep_on(p,TASK_UNINTERRUPTIBLE);

202 }

203

    // ���� *pָ�������*p������ȴ�����ͷָ�롣�����µȴ������Dz����ڵȴ�����ͷָ��

    // ���ģ���˻��ѵ���������ȴ����е��������������Ѿ�����ֹͣ����״̬������ʾ

    // ������Ϣ��

204 void wake_up(struct task_struct **p)

205 {

206         if (p && *p) {

207                 if ((**p).state == TASK_STOPPED)         // ����ֹͣ״̬��

208                         printk("wake_up: TASK_STOPPED");

209                 if ((**p).state == TASK_ZOMBIE)          // ���ڽ���״̬��

210                         printk("wake_up: TASK_ZOMBIE");

211                 (**p).state=0;                           // ��Ϊ����״̬TASK_RUNNING��

212         }

213 }

214

215 /*

216  * OK, here are some floppy things that shouldn't be in the kernel

217  * proper. They are here because the floppy needs a timer, and this

218  * was the easiest way of doing it.

219  */

    /*

     * ���ˣ������↑ʼ��һЩ�й����̵��ӳ��򣬱���Ӧ�÷����ں˵���Ҫ����

     * �еġ������Ƿ�����������Ϊ������Ҫ��ʱ���������������������ġ�

     */

    // ����220 -- 281�д������ڴ���������ʱ�����Ķ���δ���֮ǰ���ȿ�һ�¿��豸һ����

    // �й�������������floppy.c�������˵���� ���ߵ��Ķ����̿��豸��������ʱ��������

    // �δ��롣����ʱ�䵥λ��1���δ� = 1/100�롣

    // ��������wait_motor[]���ڴ�ŵȴ�������������������ת�ٵĽ���ָ�롣��������0-3

    // �ֱ��Ӧ����A--D������ mon_timer[]��Ÿ�����������������Ҫ�ĵδ�����������Ĭ��

    // ����ʱ��Ϊ50���δ�0.5�룩������ moff_timer[] ��Ÿ�����������ͣת֮ǰ��ά��

    // ��ʱ�䡣�������趨Ϊ10000���δ�100�룩��

220 static struct task_struct * wait_motor[4] = {NULL,NULL,NULL,NULL};

221 static int  mon_timer[4]={0,0,0,0};

222 static int moff_timer[4]={0,0,0,0};

 

    // ���������Ӧ�����������е�ǰ��������Ĵ������üĴ���ÿλ�Ķ������£�

    // λ7-4���ֱ����������D-A�����������1 - ������0 - �رա�

    // λ��1 - ����DMA���ж�����0 - ��ֹDMA���ж�����

    // λ��1 - �������̿�������    0 - ��λ���̿�������

    // λ1-0��00 - 11������ѡ����Ƶ�����A-D��

    // �������ó�ֵΪ������DMA���ж���������FDC��

223 unsigned char current_DOR = 0x0C;

224

    // ָ������������������ת״̬����ȴ�ʱ�䡣

    // ����nr -- ������(0--3)������ֵΪ�δ�����

    // �ֲ�����selected��ѡ��������־��blk_drv/floppy.c��123�У���mask����ѡ������Ӧ��

    // ��������Ĵ����������������λ��mask��4λ�Ǹ��������������־��

225 int ticks_to_floppy_on(unsigned int nr)

226 {

227         extern unsigned char selected;

228         unsigned char mask = 0x10 << nr;

229

    // ϵͳ�����4������������Ԥ�����ú�ָ������nrͣת֮ǰ��Ҫ������ʱ�䣨100�룩��Ȼ��

    // ȡ��ǰDOR�Ĵ���ֵ����ʱ����mask�У�����ָ������������������־��λ��

230         if (nr>3)

231                 panic("floppy_on: nr>3");

232         moff_timer[nr]=10000;           /* 100 s = very big :-) */   // ͣתά��ʱ�䡣

233         cli();                          /* use floppy_off to turn it off */ // ���жϡ�

234         mask |= current_DOR;

    // �����ǰû��ѡ�������������ȸ�λ����������ѡ��λ��Ȼ����ָ������ѡ��λ��

235         if (!selected) {

236                 mask &= 0xFC;

237                 mask |= nr;

238         }

    // �����������Ĵ����ĵ�ǰֵ��Ҫ���ֵ��ͬ������FDC��������˿������ֵ(mask)������

    // ���Ҫ�����������ﻹû��������������Ӧ����������������ʱ��ֵ��HZ/2 = 0.5��� 50��

    // �δ𣩡����Ѿ���������������������ʱΪ2���δ����������� do_floppy_timer()���ȵ�

    // �����жϵ�Ҫ��ִ�б��ζ�ʱ�����Ҫ�󼴿ɡ��˺���µ�ǰ��������Ĵ���current_DOR��

239         if (mask != current_DOR) {

240                 outb(mask,FD_DOR);

241                 if ((mask ^ current_DOR) & 0xf0)

242                         mon_timer[nr] = HZ/2;

243                 else if (mon_timer[nr] < 2)

244                         mon_timer[nr] = 2;

245                 current_DOR = mask;

246         }

247         sti();                          // ���жϡ�

248         return mon_timer[nr];           // ��󷵻��������������ʱ��ֵ��

249 }

250

    // �ȴ�ָ�������������������һ��ʱ�䣬Ȼ�󷵻ء�

    // ����ָ����������������������ת���������ʱ��Ȼ��˯�ߵȴ����ڶ�ʱ�жϹ����л�һֱ

    // �ݼ��ж������趨����ʱֵ������ʱ���ڣ��ͻỽ������ĵȴ����̡�

251 void floppy_on(unsigned int nr)

252 {

    // ���жϡ��������������ʱ��û������һֱ�ѵ�ǰ������Ϊ�����ж�˯��״̬������ȴ�����

    // ���еĶ����С�Ȼ���жϡ�

253         cli();

254         while (ticks_to_floppy_on(nr))

255                 sleep_on(nr+wait_motor);

256         sti();

257 }

258

    // �ùر���Ӧ��������ͣת��ʱ����3�룩��

    // ����ʹ�øú�����ȷ�ر�ָ������������������↑��100��֮��Ҳ�ᱻ�رա�

259 void floppy_off(unsigned int nr)

260 {

261         moff_timer[nr]=3*HZ;

262 }

263

    // ���̶�ʱ�����ӳ��򡣸�������������ʱֵ������ر�ͣת��ʱֵ�����ӳ������ʱ�Ӷ�ʱ

    // �жϹ����б����ã����ϵͳÿ����һ���δ�(10ms)�ͻᱻ����һ�Σ���ʱ�������↑����

    // ͣת��ʱ����ֵ�����ijһ������ͣת��ʱ��������������Ĵ�����������λ��λ��

264 void do_floppy_timer(void)

265 {

266         int i;

267         unsigned char mask = 0x10;

268

269         for (i=0 ; i<4 ; i++,mask <<= 1) {

270                 if (!(mask & current_DOR))             // �������DORָ����������������

271                         continue;

272                 if (mon_timer[i]) {                    // �������������ʱ�����ѽ��̡�

273                         if (!--mon_timer[i])

274                                 wake_up(i+wait_motor);

275                 } else if (!moff_timer[i]) {           // �������ͣת��ʱ����

276                         current_DOR &= ~mask;          // ��λ��Ӧ��������λ������

277                         outb(current_DOR,FD_DOR);      // ������������Ĵ�����

278                 } else

279                         moff_timer[i]--;               // ��������ͣת��ʱ�ݼ���

280         }

281 }

282

    // �����ǹ��ڶ�ʱ���Ĵ��롣������64����ʱ����

283 #define TIME_REQUESTS 64

284

    // ��ʱ�������ṹ�Ͷ�ʱ�����顣�ö�ʱ������ר���ڹ������ر�������������ﶨʱ������

    // �������Ͷ�ʱ�������ִ�Linuxϵͳ�еĶ�̬��ʱ����Dynamic Timer���������ں�ʹ�á�

285 static struct timer_list {

286         long jiffies;                  // ��ʱ�δ�����

287         void (*fn)();                  // ��ʱ��������

288         struct timer_list * next;      // ����ָ����һ����ʱ����

289 } timer_list[TIME_REQUESTS], * next_timer = NULL;  // next_timer�Ƕ�ʱ������ͷָ�롣

290

    // ���Ӷ�ʱ�����������Ϊָ���Ķ�ʱֵ(�δ���)����Ӧ�Ĵ�������ָ�롣

    // ������������floppy.c�����øú���ִ��������ر��������ʱ������

    // ����jiffies �C ��10����Ƶĵδ�����*fn()- ��ʱʱ�䵽ʱִ�еĺ�����

291 void add_timer(long jiffies, void (*fn)(void))

292 {

293         struct timer_list * p;

294

    // �����ʱ��������ָ��Ϊ�գ����˳���������жϡ�

295         if (!fn)

296                 return;

297         cli();

    // �����ʱֵ<=0�������̵����䴦�����򡣲��Ҹö�ʱ�������������С�

298         if (jiffies <= 0)

299                 (fn)();

300         else {

    // ����Ӷ�ʱ�������У���һ�������

301                 for (p = timer_list ; p < timer_list + TIME_REQUESTS ; p++)

302                         if (!p->fn)

303                                 break;

    // ����Ѿ������˶�ʱ�����飬��ϵͳ����J��������ʱ�����ݽṹ������Ӧ��Ϣ��������

    // ����ͷ��

304                 if (p >= timer_list + TIME_REQUESTS)

305                         panic("No more time requests free");

306                 p->fn = fn;

307                 p->jiffies = jiffies;

308                 p->next = next_timer;

309                 next_timer = p;

    // �������ʱֵ��С��������������ʱ��ȥ����ǰ����Ҫ�ĵδ����������ڴ�����ʱ��ʱ

    // ֻҪ�鿴����ͷ�ĵ�һ��Ķ�ʱ�Ƿ��ڼ��ɡ�[[?? ��γ������û�п�����ȫ�������

    // ����Ķ�ʱ��ֵС��ԭ��ͷһ����ʱ��ֵʱ������������ѭ���У�����ʱ����Ӧ�ý�����

    // ������һ����ʱ��ֵ��ȥ�µĵ�1���Ķ�ʱֵ���������1����ʱֵ<=��2�������2��

    // ��ʱֵ�۳���1����ֵ���ɣ������������ѭ���н��д�����]]

310                 while (p->next && p->next->jiffies < p->jiffies) {

311                         p->jiffies -= p->next->jiffies;

312                         fn = p->fn;

313                         p->fn = p->next->fn;

314                         p->next->fn = fn;

315                         jiffies = p->jiffies;

316                         p->jiffies = p->next->jiffies;

317                         p->next->jiffies = jiffies;

318                         p = p->next;

319                 }

320         }

321         sti();

322 }

323

    //// ʱ���ж�C��������������sys_call.s�е�_timer_interrupt��189�У������á�

    // ����cpl�ǵ�ǰ��Ȩ��0��3����ʱ���жϷ���ʱ����ִ�еĴ���ѡ����е���Ȩ����

    // cpl=0ʱ��ʾ�жϷ���ʱ����ִ���ں˴��룻cpl=3ʱ��ʾ�жϷ���ʱ����ִ���û����롣

    // ����һ����������ִ��ʱ��Ƭ����ʱ������������л�����ִ��һ����ʱ���¹�����

324 void do_timer(long cpl)

325 {

326         static int blanked = 0;

327

    // �����ж��Ƿ񾭹���һ��ʱ�������Ļ������blankout�������blankcount������Ϊ�㣬

    // ���ߺ�����ʱ���ʱ��blankintervalΪ0�Ļ�����ô���Ѿ����ں���״̬��������־

    // blanked = 1����������Ļ�ָ���ʾ����blankcount������Ϊ�㣬��ݼ�֮�����Ҹ�λ

    // ������־��

328         if (blankcount || !blankinterval) {

329                 if (blanked)

330                         unblank_screen();

331                 if (blankcount)

332                         blankcount--;

333                 blanked = 0;

    // ����Ļ���������־δ��λ��������Ļ�������������ú�����־��

334         } else if (!blanked) {

335                 blank_screen();

336                 blanked = 1;

337         }

    // ���Ŵ���Ӳ�̲�����ʱ���⡣���Ӳ�̳�ʱ�����ݼ�֮��Ϊ0�������Ӳ�̷��ʳ�ʱ������

338         if (hd_timeout)

339                 if (!--hd_timeout)

340                         hd_times_out();  // Ӳ�̷��ʳ�ʱ������blk_drv/hdc��318�У���

341

    // ���������������������رշ�����(��0x61�ڷ��������λλ0��1��λ0����8253

    // ������2�Ĺ�����λ1����������)��

342         if (beepcount)          // ����������ʱ��δ�����chr_drv/console.c,950�У���

343                 if (!--beepcount)

344                         sysbeepstop();

345

    // �����ǰ��Ȩ��(cpl)Ϊ0����ߣ���ʾ���ں˳����ڹ����������ں˴�������ʱ��stime

    // ������[ Linus���ں˳���ͳ��Ϊ�����û�(supervisor)�ij��򣬼�sys_call.s��207��

    // �ϵ�Ӣ��ע�͡����ֳƺ�������Intel CPU �ֲᡣ] ���cpl > 0�����ʾ��һ���û�����

    // �ڹ���������utime��

346         if (cpl)

347                 current->utime++;

348         else

349                 current->stime++;

350

    // ����ж�ʱ�����ڣ���������1����ʱ����ֵ��1������ѵ���0���������Ӧ�Ĵ�������

    // �����ô�������ָ����Ϊ�ա�Ȼ��ȥ�����ʱ����next_timer�Ƕ�ʱ��������ͷָ�롣

351         if (next_timer) {

352                 next_timer->jiffies--;

353                 while (next_timer && next_timer->jiffies <= 0) {

354                         void (*fn)(void);        // ���������һ������ָ�붨�壡��L

355                        

356                         fn = next_timer->fn;

357                         next_timer->fn = NULL;

358                         next_timer = next_timer->next;

359                         (fn)();                 // ���ö�ʱ����������

360                 }

361         }

    // �����ǰ���̿�����FDC����������Ĵ�������������λ����λ�ģ���ִ�����̶�ʱ����

362         if (current_DOR & 0xf0)

363                 do_floppy_timer();

  // �����������ʱ�仹û�꣬���˳��������õ�ǰ�������м���ֵΪ0������������ʱ���ж�ʱ

  // �����ں˴����������򷵻أ��������ִ�е��Ⱥ�����

364         if ((--current->counter)>0) return;

365         current->counter=0;

366         if (!cpl) return;              // �����ں�̬���򣬲�����counterֵ���е��ȡ�

367         schedule();

368 }

369

    // ϵͳ���ù��� - ���ñ�����ʱʱ��ֵ(��)��

    // ������seconds����0���������¶�ʱֵ��������ԭ��ʱʱ�̻�ʣ��ļ��ʱ�䡣���򷵻�0��

    // �������ݽṹ�б�����ʱֵalarm�ĵ�λ��ϵͳ�δ�1�δ�Ϊ10���룩������ϵͳ������

    // ���ö�ʱ����ʱϵͳ�δ�ֵjiffies��ת���ɵδ�λ�Ķ�ʱֵ֮�ͣ���'jiffies + HZ*��ʱ

    // ��ֵ'��������������������Ϊ��λ�Ķ�ʱֵ����˱���������Ҫ�����ǽ������ֵ�λ��ת����

    // ���г���HZ = 100�����ں�ϵͳ����Ƶ�ʡ�������include/sched.h��4���ϡ�

    // ����seconds���µĶ�ʱʱ��ֵ����λ���롣

370 int sys_alarm(long seconds)

371 {

372         int old = current->alarm;

373

374         if (old)

375                 old = (old - jiffies) / HZ;

376         current->alarm = (seconds>0)?(jiffies+HZ*seconds):0;

377         return (old);

378 }

379

    // ȡ��ǰ���̺�pid��

380 int sys_getpid(void)

381 {

382         return current->pid;

383 }

384

    // ȡ�����̺�ppid��

385 int sys_getppid(void)

386 {

387         return current->p_pptr->pid;

388 }

389

    // ȡ�û���uid��

390 int sys_getuid(void)

391 {

392         return current->uid;

393 }

394

    // ȡ��Ч���û���euid��

395 int sys_geteuid(void)

396 {

397         return current->euid;

398 }

399

    // ȡ���gid��

400 int sys_getgid(void)

401 {

402         return current->gid;

403 }

404

    // ȡ��Ч�����egid��

405 int sys_getegid(void)

406 {

407         return current->egid;

408 }

409

    // ϵͳ���ù��� -- ���Ͷ�CPU��ʹ������Ȩ�����˻�����J����

    // Ӧ������incrementΪ����0��ֵ�������ʹ����Ȩ���󣡣�

410 int sys_nice(long increment)

411 {

412         if (current->priority-increment>0)

413                 current->priority -= increment;

414         return 0;

415 }

416

    // �ں˵��ȳ���ij�ʼ���ӳ���

417 void sched_init(void)

418 {

419         int i;

420         struct desc_struct * p;        // ���������ṹָ�롣

421

    // Linuxϵͳ����֮�����ں˲����졣�ں˴���ᱻ�����޸ġ�Linus���Լ��������޸�����Щ

    // �ؼ��Ե����ݽṹ�������POSIX��׼�IJ����ݡ����������������ж���䲢�ޱ�Ҫ������

    // ��Ϊ�������Լ��Լ������޸��ں˴�����ˡ�

422         if (sizeof(struct sigaction) != 16)    // sigaction�Ǵ���й��ź�״̬�Ľṹ��

423                 panic("Struct sigaction MUST be 16 bytes");

    // ��ȫ���������������ó�ʼ��������0��������״̬���������;ֲ����ݱ���������

    // FIRST_TSS_ENTRY��FIRST_LDT_ENTRY��ֵ�ֱ���4��5��������include/linux/sched.h

    // �У�gdt ��һ�������������飨include/linux/head.h ����ʵ���϶�Ӧ���� head.s ��

    // ��234���ϵ�ȫ������������ַ��_gdt������� gdt + FIRST_TSS_ENTRY ��Ϊ

    // gdt[FIRST_TSS_ENTRY]������gdt[4]����Ҳ�� gdt �����4��ĵ�ַ�� �μ�

    // include/asm/system.h,��65�п�ʼ��

424         set_tss_desc(gdt+FIRST_TSS_ENTRY,&(init_task.task.tss));

425         set_ldt_desc(gdt+FIRST_LDT_ENTRY,&(init_task.task.ldt));

    // ��������������������ע��i=1��ʼ�����Գ�ʼ��������������ڣ�����������ṹ

    // �������ļ�include/linux/head.h�С�

426         p = gdt+2+FIRST_TSS_ENTRY;

427         for(i=1;i<NR_TASKS;i++) {

428                 task[i] = NULL;

429                 p->a=p->b=0;

430                 p++;

431                 p->a=p->b=0;

432                 p++;

433         }

434 /* Clear NT, so that we won't have troubles with that later on */

    /* �����־�Ĵ����е�λNT�������Ժ�Ͳ������鷳 */

    // EFLAGS�е�NT��־λ���ڿ��������Ƕ�׵��á���NTλ��λʱ����ô��ǰ�ж�����ִ��

    // IRETָ��ʱ�ͻ����������л���NTָ��TSS�е�back_link�ֶ��Ƿ���Ч��NT=0ʱ��Ч��

435         __asm__("pushfl ; andl $0xffffbfff,(%esp) ; popfl");    // ��λNT��־��

    // ������0 �� TSS��ѡ������ص�����Ĵ���tr�����ֲ�����������ѡ������ص��ֲ�����

    // �����Ĵ���ldtr�С�ע�⣡���ǽ�GDT����ӦLDT��������ѡ������ص�ldtr��ֻ��ȷ��

    // ��һ�Σ��Ժ�������LDT�ļ��أ���CPU����TSS�е�LDT���Զ����ء�

436         ltr(0);                    // ������include/linux/sched.h ��157-158�С�

437         lldt(0);                   // ���в�����0��������š�

    // ����������ڳ�ʼ�� 8253��ʱ����ͨ��0��ѡ������ʽ3�������Ƽ�����ʽ��ͨ��0��

    // ������Ž����жϿ�����оƬ��IRQ0�ϣ���ÿ10���뷢��һ��IRQ0����LATCH�dz�ʼ

    // ��ʱ����ֵ��

438         outb_p(0x36,0x43);                /* binary, mode 3, LSB/MSB, ch 0 */

439         outb_p(LATCH & 0xff , 0x40);      /* LSB */    // ��ʱֵ���ֽڡ�

440         outb(LATCH >> 8 , 0x40);          /* MSB */    // ��ʱֵ���ֽڡ�

    // ����ʱ���жϴ���������������ʱ���ж��ţ����޸��жϿ����������룬����ʱ���жϡ�

    // Ȼ������ϵͳ�����ж��š������������ж���������IDT���������ĺ궨�����ļ�

    // include/asm/system.h�е�33��39�д������ߵ�����μ�system.h�ļ���ʼ����˵����

441         set_intr_gate(0x20,&timer_interrupt);

442         outb(inb_p(0x21)&~0x01,0x21);

443         set_system_gate(0x80,&system_call);

444 }

445


 


 

8.6 ����8-6 linux/kernel/signal.c


  1 /*

  2  *  linux/kernel/signal.c

  3  *

  4  *  (C) 1991  Linus Torvalds

  5  */

  6

  7 #include <linux/sched.h>  // ���ȳ���ͷ�ļ�����������ṹtask_struct����ʼ����0�����ݣ�

                              // ����һЩ�й��������������úͻ�ȡ��Ƕ��ʽ��ຯ������䡣

  8 #include <linux/kernel.h> // �ں�ͷ�ļ�������һЩ�ں˳��ú�����ԭ�ζ��塣

  9 #include <asm/segment.h>  // �β���ͷ�ļ����������йضμĴ���������Ƕ��ʽ��ຯ����

 10

 11 #include <signal.h>       // �ź�ͷ�ļ��������źŷ��ų������źŽṹ���źŲ�������ԭ�͡�

 12 #include <errno.h>        // ������ͷ�ļ�����������ŷ��ų�����

 13  

    // ��ȡ��ǰ�����ź�����λͼ��������������룩��sgetmask�ɷֽ�Ϊsignal-get-mask���������ơ�

 14 int sys_sgetmask()

 15 {

 16         return current->blocked;

 17 }

 18

    // �����µ��ź�����λͼ���ź�SIGKILL��SIGSTOP���ܱ����Ρ�����ֵ��ԭ�ź�����λͼ��

 19 int sys_ssetmask(int newmask)

 20 {

 21         int old=current->blocked;

 22

 23         current->blocked = newmask & ~(1<<(SIGKILL-1)) & ~(1<<(SIGSTOP-1));

 24         return old;

 25 }

 26

    // ��Ⲣȡ�ý����յ��ĵ������Σ����������źš���δ�����źŵ�λͼ��������set�С�

 27 int sys_sigpending(sigset_t *set)

 28 {

 29     /* fill in "set" with signals pending but blocked. */

        /* �û�δ�������ұ������źŵ�λͼ����setָ����ָλ�ô� */

    // ������֤�����ṩ���û��洢�ռ�Ӧ��4���ֽڡ�Ȼ��ѻ�δ�������ұ������źŵ�λͼ����

    // setָ����ָλ�ô���

 30     verify_area(set,4);

 31     put_fs_long(current->blocked & current->signal, (unsigned long *)set);

 32     return 0;

 33 }

 34

 35 /* atomically swap in the new signal mask, and wait for a signal.

 36  *

 37  * we need to play some games with syscall restarting.  We get help

 38  * from the syscall library interface.  Note that we need to coordinate

 39  * the calling convention with the libc routine.

 40  *

 41  * "set" is just the sigmask as described in 1003.1-1988, 3.3.7.

 42  *      It is assumed that sigset_t can be passed as a 32 bit quantity.

 43  *

 44  * "restart" holds a restart indication.  If it's non-zero, then we

 45  *      install the old mask, and return normally.  If it's zero, we store

 46  *      the current mask in old_mask and block until a signal comes in.

 47  */

    /* �Զ��ظ������µ��ź������룬���ȴ��źŵĵ�����

     *

     * ������Ҫ��ϵͳ���ã�syscall����һЩ���������ǻ��ϵͳ���ÿ�ӿ�ȡ��ijЩ��Ϣ��

     * ע�⣬������Ҫ�ѵ��ù�����libc���е��ӳ���ͳһ���ǡ�

     *

     * "set" ����POSIX��׼1003.1-1988��3.3.7�������������ź�������sigmask��

     *       ������Ϊ����sigset_t�ܹ���Ϊһ��32λ�����ݡ�

     *

     * "restart"�б���������ָʾ��־�����Ϊ��0ֵ����ô���Ǿ�����ԭ���������룬

     *       �����������ء������Ϊ0����ô���ǾͰѵ�ǰ�������뱣����oldmask��

     *       �����������̣�ֱ���յ��κ�һ���ź�Ϊֹ��

     */

    // ��ϵͳ������ʱ�ѽ����ź��������滻�ɲ����и�����set��Ȼ�������̣�ֱ���յ�һ��

    // �ź�Ϊֹ��

    // restart��һ�����жϵ�ϵͳ��������������־������1�ε��ø�ϵͳ����ʱ������0������

    // �ڸú����л�ѽ���ԭ���������� blocked����������old_mask���������� restartΪ��0

    // ֵ����˵����̵�2�ε��ø�ϵͳ����ʱ�����ͻ�ָ�����ԭ��������old_mask�е������롣

 48 int sys_sigsuspend(int restart, unsigned long old_mask, unsigned long set)

 49 {

    // pause()ϵͳ���ý����µ������Ľ��̽���˯��״̬��ֱ���յ�һ���źš����źŻ��߻���ֹ

    // ���̵�ִ�У����ߵ��½���ȥִ����Ӧ���źŲ�������

 50     extern int sys_pause(void);

 51

    // ���restart��־��Ϊ0����ʾ�������ó����������������ǻָ�ǰ�汣����old_mask�е�

    // ԭ���������롣��������-EINTR��ϵͳ���ñ��ź��жϣ���

 52     if (restart) {

 53         /* we're restarting */       /* ����������������ϵͳ���� */

 54         current->blocked = old_mask;

 55         return -EINTR;

 56     }

    // �����ʾrestart��־��ֵ��0����ʾ��1�ε��á�������������restart��־����Ϊ1����

    // ������̵�ǰ������ blocked �� old_mask�У����ѽ��̵��������滻�� set��Ȼ�����

    // pause()�ý���˯�ߣ��ȴ��źŵĵ������������յ�һ���ź�ʱ��pause() �ͻ᷵�أ�����

    // ���̻�ȥִ���źŴ���������Ȼ�󱾵��÷��� -ERESTARTNOINTR ���˳������������˵��

    // �ڴ������źź�Ҫ�󷵻ص���ϵͳ�����м������У�����ϵͳ���ò��ᱻ�жϡ�

 57     /* we're not restarting.  do the work */

        /* ���Dz��������������У���ô�͸ɻ�� */

 58     *(&restart) = 1;

 59     *(&old_mask) = current->blocked;

 60     current->blocked = set;

 61     (void) sys_pause();                 /* return after a signal arrives */

 62     return -ERESTARTNOINTR;             /* handle the signal, and come back */

 63 }

 64

    // ����sigaction���ݵ�fs���ݶ�to���������ں˿ռ临�Ƶ��û����������ݶ��С�

 65 static inline void save_old(char * from,char * to)

 66 {

 67         int i;

 68

    // ������֤to�����ڴ�ռ��Ƿ��㹻��Ȼ���һ��sigaction�ṹ��Ϣ���Ƶ�fs�Σ��û���

    // �ռ��С��꺯��put_fs_byte()��include/asm/segment.h��ʵ�֡�

 69         verify_area(to, sizeof(struct sigaction));

 70         for (i=0 ; i< sizeof(struct sigaction) ; i++) {

 71                 put_fs_byte(*from,to);

 72                 from++;

 73                 to++;

 74         }

 75 }

 76

    // ��sigaction���ݴ�fs���ݶ�fromλ�ø��Ƶ�to���������û����ݿռ�ȡ���ں����ݶ��С�

 77 static inline void get_new(char * from,char * to)

 78 {

 79         int i;

 80

 81         for (i=0 ; i< sizeof(struct sigaction) ; i++)

 82                 *(to++) = get_fs_byte(from++);

 83 }

 84

    // signal()ϵͳ���á�������sigaction()��Ϊָ�����źŰ�װ�µ��źž��(�źŴ�������)��

    // �źž���������û�ָ���ĺ�����Ҳ������SIG_DFL��Ĭ�Ͼ������SIG_IGN�����ԣ���

    // ����signum --ָ�����źţ�handler -- ָ���ľ����restorer �C�ָ�����ָ�룬�ú�����

    // Libc ���ṩ���������źŴ������������ָ�ϵͳ���÷���ʱ�����Ĵ�����ԭ��ֵ�Լ�ϵͳ

    // ���õķ���ֵ���ͺ���ϵͳ����û��ִ�й��źŴ��������ֱ�ӷ��ص��û�����һ���� ����

    // ����ԭ�źž����

 85 int sys_signal(int signum, long handler, long restorer)

 86 {

 87         struct sigaction tmp;

 88

    // ������֤�ź�ֵ����Ч��Χ��1--32���ڣ����Ҳ������ź�SIGKILL����SIGSTOP������Ϊ��

    // �����źŲ��ܱ����̲���

 89         if (signum<1 || signum>32 || signum==SIGKILL || signum==SIGSTOP)

 90                 return -EINVAL;

    // Ȼ������ṩ�IJ����齨sigaction�ṹ���ݡ�sa_handler��ָ�����źŴ����������������

    // sa_mask��ִ���źŴ������ʱ���ź������롣sa_flags��ִ��ʱ��һЩ��־��ϡ������趨

    // ���źŴ������ֻʹ��1�κ�ͻָ���Ĭ��ֵ���������ź����Լ��Ĵ���������յ���

 91         tmp.sa_handler = (void (*)(int)) handler;

 92         tmp.sa_mask = 0;

 93         tmp.sa_flags = SA_ONESHOT | SA_NOMASK;

 94         tmp.sa_restorer = (void (*)(void)) restorer;      // ����ָ���������ָ�롣

    // ����ȡ���ź�ԭ���Ĵ�������������ø��źŵ�sigaction�ṹ����󷵻�ԭ�źž����

 95         handler = (long) current->sigaction[signum-1].sa_handler;

 96         current->sigaction[signum-1] = tmp;

 97         return handler;

 98 }

 99

    // sigaction()ϵͳ���á��ı�������յ�һ���ź�ʱ�IJ�����signum�dz���SIGKILL�����

    // �κ��źš�[����²�����action����Ϊ�� ]���²�������װ����� oldactionָ�벻Ϊ�գ�

    // ��ԭ������������oldaction���ɹ��򷵻�0������Ϊ-EINVAL��

100 int sys_sigaction(int signum, const struct sigaction * action,

101         struct sigaction * oldaction)

102 {

103         struct sigaction tmp;

104

    // ������֤�ź�ֵ����Ч��Χ��1--32���ڣ����Ҳ������ź�SIGKILL����SIGSTOP������Ϊ��

    // �����źŲ��ܱ����̲���

105         if (signum<1 || signum>32 || signum==SIGKILL || signum==SIGSTOP)

106                 return -EINVAL;

    // ���źŵ�sigaction�ṹ�������µIJ����������������oldactionָ�벻Ϊ�յĻ�����

    // ԭ����ָ�뱣�浽oldaction��ָ��λ�á�

107         tmp = current->sigaction[signum-1];

108         get_new((char *) action,

109                 (char *) (signum-1+current->sigaction));

110         if (oldaction)

111                 save_old((char *) &tmp,(char *) oldaction);

    // ��������ź����Լ����źž�����յ�������������Ϊ0�������������α��źš�

112         if (current->sigaction[signum-1].sa_flags & SA_NOMASK)

113                 current->sigaction[signum-1].sa_mask = 0;

114         else

115                 current->sigaction[signum-1].sa_mask |= (1<<(signum-1));

116         return 0;

117 }

118

119 /*

120  * Routine writes a core dump image in the current directory.

121  * Currently not implemented.

122  */

    /*

     * �ڵ�ǰĿ¼�в���core dumpӳ���ļ����ӳ���Ŀǰ��û��ʵ�֡�

     */

123 int core_dump(long signr)

124 {

125         return(0);      /* We didn't do a dump */

126 }

127

    // ϵͳ���õ��жϴ����������������ź�Ԥ����������kernel/sys_call.s,119�У������

    // �������Ҫ�����ǽ��źŴ���������뵽�û������ջ�У����ڱ�ϵͳ���ý������غ�����

    // ִ���źž������Ȼ�����ִ���û��ij���

    // �����IJ����ǽ���ϵͳ���ô�������sys_call.s��ʼ��ֱ�����ñ�������sys_call.s

    // ��125�У�ǰ��ѹ���ջ��ֵ����Щֵ��������sys_call.s�еĴ����У���

    // �� CPUִ���ж�ָ��ѹ����û�ջ��ַss��esp����־�Ĵ���eflags�ͷ��ص�ַcs��eip��

    // �� ��85--91���ڸս���system_callʱѹ��ջ�ĶμĴ���ds��es��fs�Լ��Ĵ���eax

    // ��orig_eax����edx��ecx��ebx��ֵ��

    // �� ��100�е���sys_call_table��ѹ��ջ�е���Ӧϵͳ���ô��������ķ���ֵ��eax����

    // �� ��124��ѹ��ջ�еĵ�ǰ�������ź�ֵ��signr����

128 int do_signal(long signr,long eax,long ebx, long ecx, long edx, long orig_eax,

129         long fs, long es, long ds,

130         long eip, long cs, long eflags,

131         unsigned long * esp, long ss)

132 {

133         unsigned long sa_handler;

134         long old_eip=eip;

135         struct sigaction * sa = current->sigaction + signr - 1;

136         int longs;                                // �� current->sigaction[signr-1]��

137

138         unsigned long * tmp_esp;

139

    // �����ǵ�����䡣��������notdefʱ���ӡ�����Ϣ��

140 #ifdef notdef

141         printk("pid: %d, signr: %x, eax=%d, oeax = %d, int=%d\n",

142                 current->pid, signr, eax, orig_eax,

143                 sa->sa_flags & SA_INTERRUPT);

144 #endif

    // �������ϵͳ���ö��������ж�ִ�й����е��õ�������ʱ��  roig_eax ֵΪ -1�� �μ�

    // sys_call.s ��144�� ����䡣��˵� orig_eax������ -1 ʱ��˵������ij��ϵͳ���õ�

    // �������˱��������� kernel/exit.c �� waitpid() �����У�����յ���SIGCHLD �źţ�

    // �����ڶ��ܵ�����fs/pipe.c�йܵ���ǰ�����ݵ�û�ж����κ����ݵ�����£������յ�

    // ���κ�һ�����������źţ��򶼻��� -ERESTARTSYS ����ֵ���ء�����ʾ���̿��Ա��жϣ�

    // �����ڼ���ִ�к����������ϵͳ���á�������-ERESTARTNOINTR˵���ڴ������źź�Ҫ��

    // ���ص�ԭϵͳ�����м������У���ϵͳ���ò��ᱻ�жϡ��μ�ǰ���62�С�

    // ����������˵���������ϵͳ�����е��õı�������������Ӧϵͳ���õķ����� eax����

    // -ERESTARTSYS�� -ERESTARTNOINTRʱ��������Ĵ�����ʵ���ϻ�û�������ص��û������У���

145         if ((orig_eax != -1) &&

146             ((eax == -ERESTARTSYS) || (eax == -ERESTARTNOINTR))) {

    // ���ϵͳ���÷������� -ERESTARTSYS����������ϵͳ���ã������� sigaction �к��б�־

    // SA_INTERRUPT��ϵͳ���ñ��ź��жϺ���������ϵͳ���ã������ź�ֵС�� SIGCONT����

    // �ź�ֵ����SIGTTOU�����źŲ���SIGCONT��SIGSTOP��SIGTSTP��SIGTTIN ��SIGTTOU������

    // �޸�ϵͳ���õķ���ֵΪeax = -EINTR�������ź��жϵ�ϵͳ���á�

147                 if ((eax == -ERESTARTSYS) && ((sa->sa_flags & SA_INTERRUPT) ||

148                     signr < SIGCONT || signr > SIGTTOU))

149                         *(&eax) = -EINTR;

150                 else {

    // ����ͻָ����̼Ĵ���eax�ڵ���ϵͳ����֮ǰ��ֵ�����Ұ�ԭ����ָ��ָ��ص�2�ֽڡ���

    // �������û�����ʱ���ó�����������ִ�б��ź��жϵ�ϵͳ���á�

151                         *(&eax) = orig_eax;

152                         *(&eip) = old_eip -= 2;

153                 }

154         }

    // ����źž��ΪSIG_IGN��1��Ĭ�Ϻ��Ծ�����򲻶��źŽ��д�����ֱ�ӷ��ء�

155         sa_handler = (unsigned long) sa->sa_handler;

156         if (sa_handler==1)

157                 return(1);   /* Ignore, see if there are more signals... */

    // ������ΪSIG_DFL��0��Ĭ�ϴ�����������ݾ�����źŽ��зֱ�����

158         if (!sa_handler) {

159                 switch (signr) {

    // ����ź�������������Ҳ����֮�������ء�

160                 case SIGCONT:

161                 case SIGCHLD:

162                         return(1);  /* Ignore, ... */

163

    // ����ź�������4���ź�֮һ����ѵ�ǰ����״̬��Ϊֹͣ״̬TASK_STOPPED������ǰ����

    // �����̶�SIGCHLD�źŵ� sigaction������־ SA_NOCLDSTOP �������ӽ���ִֹͣ�л��ּ�

    // ��ִ��ʱ��Ҫ����SIGCHLD�źţ�û����λ����ô�͸������̷���SIGCHLD�źš�

164                 case SIGSTOP:

165                 case SIGTSTP:

166                 case SIGTTIN:

167                 case SIGTTOU:

168                         current->state = TASK_STOPPED;

169                         current->exit_code = signr;

170                         if (!(current->p_pptr->sigaction[SIGCHLD-1].sa_flags &

171                                         SA_NOCLDSTOP))

172                                 current->p_pptr->signal |= (1<<(SIGCHLD-1));

173                         return(1);  /* Reschedule another event */

174

    // ����ź�������6���ź�֮һ����ô���źŲ�����core dump�������˳���Ϊsignr|0x80

    // ����do_exit()�˳��������˳�������ź�ֵ��do_exit()�IJ����Ƿ�����ͳ����ṩ���˳�

    // ״̬��Ϣ������Ϊwait()��waitpid()������״̬��Ϣ���μ�sys/wait.h�ļ���13-18�С�

    // wait()��waitpid()������Щ��Ϳ���ȡ���ӽ��̵��˳�״̬����ӽ�����ֹ��ԭ���źţ���

175                 case SIGQUIT:

176                 case SIGILL:

177                 case SIGTRAP:

178                 case SIGIOT:

179                 case SIGFPE:

180                 case SIGSEGV:

181                         if (core_dump(signr))

182                                 do_exit(signr|0x80);

183                         /* fall through */

184                 default:

185                         do_exit(signr);

186                 }

187         }

188         /*

189          * OK, we're invoking a handler

190          */

            /*

             * OK����������׼�����źž�����õ�����

             */

    // ������źž��ֻ�豻����һ�Σ��򽫸þ���ÿա�ע�⣬���źž����ǰ���Ѿ�������

    // sa_handlerָ���С�

    // ��ϵͳ���ý����ں�ʱ���û����򷵻ص�ַ��eip��cs�����������ں�̬ջ�С�������δ�

    // ���޸��ں�̬��ջ���û�����ϵͳ����ʱ�Ĵ���ָ�� eip Ϊָ���źŴ��������ͬʱҲ��

    // sa_restorer��signr������������(���SA_NOMASKû��λ)��eax��ecx��edx��Ϊ�����Լ�

    // ԭ����ϵͳ���õij��򷵻�ָ�뼰��־�Ĵ���ֵѹ���û���ջ�� ����ڱ���ϵͳ�����ж�

    // �����û�����ʱ������ִ���û����źž������Ȼ���ټ���ִ���û�����

191         if (sa->sa_flags & SA_ONESHOT)

192                 sa->sa_handler = NULL;

    // ���ں�̬ջ���û�����ϵͳ������һ������ָ��ָ��eipָ����źŴ������������C����

    // �Ǵ�ֵ��������˸�eip��ֵʱ��Ҫʹ�� "*(&eip)" ����ʽ�����⣬��������ź��Լ���

    // ��������յ��ź��Լ�����Ҳ��Ҫ�����̵�������ѹ���ջ��

    // ������ע�⣬ʹ�����·�ʽ����193�У�����ͨC�������������޸��Dz������õġ���Ϊ��

    // ��������ʱ��ջ�ϵIJ������ᱻ�����߶���������֮���Կ���ʹ�����ַ�ʽ������Ϊ�ú���

    // �Ǵӻ������б����õģ������ں������غ������û�аѵ���do_signal()ʱ������

    // ������������eip����Ȼ�ڶ�ջ�С�

    // sigaction�ṹ��sa_mask�ֶθ������ڵ�ǰ�źž�����ź�������������ִ���ڼ�Ӧ�ñ�

    // ���ε��źż���ͬʱ�������źž��ִ�е��ź�Ҳ�ᱻ���Ρ� ������sa_flags��ʹ����

    // SA_NOMASK��־����ô�����źž��ִ�е��źŽ����ᱻ���ε�����������ź��Լ��Ĵ�

    // ����������յ��ź��Լ�����Ҳ��Ҫ�����̵��ź�������ѹ���ջ��

193         *(&eip) = sa_handler;

194         longs = (sa->sa_flags & SA_NOMASK)?7:8;

    // ��ԭ���ó�����û���ջָ��������չ7����8�������֣�������ŵ����źž���IJ����ȣ���

    // ������ڴ�ʹ���������������ڴ泬���������ҳ�ȣ���

195         *(&esp) -= longs;

196         verify_area(esp,longs*4);

    // ���û���ջ�д��µ��ϴ��sa_restorer���ź�signr��������blocked�����SA_NOMASK

    // ��λ����eax��ecx��edx��eflags���û�����ԭ����ָ�롣

197         tmp_esp=esp;

198         put_fs_long((long) sa->sa_restorer,tmp_esp++);

199         put_fs_long(signr,tmp_esp++);

200         if (!(sa->sa_flags & SA_NOMASK))

201                 put_fs_long(current->blocked,tmp_esp++);

202         put_fs_long(eax,tmp_esp++);

203         put_fs_long(ecx,tmp_esp++);

204         put_fs_long(edx,tmp_esp++);

205         put_fs_long(eflags,tmp_esp++);

206         put_fs_long(old_eip,tmp_esp++);

207         current->blocked |= sa->sa_mask;   // ����������(������)����sa_mask�е���λ��

208         return(0);              /* Continue, execute handler */

209 }

210


 


 

8.7 ����8-7 linux/kernel/exit.c


  1 /*

  2  *  linux/kernel/exit.c

  3  *

  4  *  (C) 1991  Linus Torvalds

  5  */

  6

  7 #define DEBUG_PROC_TREE   // ������š����Խ���������

  8

  9 #include <errno.h>        // �����ͷ�ļ�������ϵͳ�и��ֳ����š�(Linus��minix��������)

 10 #include <signal.h>       // �ź�ͷ�ļ��������źŷ��ų������źŽṹ�Լ��źŲ�������ԭ�͡�

 11 #include <sys/wait.h>     // �ȴ�����ͷ�ļ�������ϵͳ����wait()��waitpid()����س������š�

 12

 13 #include <linux/sched.h>  // ���ȳ���ͷ�ļ�������������ṹtask_struct������0���ݵȡ�

 14 #include <linux/kernel.h> // �ں�ͷ�ļ�������һЩ�ں˳��ú�����ԭ�ζ��塣

 15 #include <linux/tty.h>    // ttyͷ�ļ����������й�tty_io������ͨ�ŷ���IJ�����������

 16 #include <asm/segment.h>  // �β���ͷ�ļ����������йضμĴ���������Ƕ��ʽ��ຯ����

 17

 18 int sys_pause(void);      // �ѽ�����Ϊ˯��״̬��ֱ���յ��źţ�kernel/sched.c��164�У���

 19 int sys_close(int fd);    // �ر�ָ���ļ���ϵͳ���ã�fs/open.c��219�У���

 20

    //// �ͷ�ָ������ռ�õ�����ۼ����������ݽṹռ�õ��ڴ�ҳ�档

    // ����p ���������ݽṹָ�롣�ú����ں���� sys_kill() �� sys_waitpid() �����б����á�

    // ɨ������ָ������� task[] ��Ѱ��ָ������������ҵ�����������ո�����ۣ�Ȼ���ͷ�

    // ���������ݽṹ��ռ�õ��ڴ�ҳ�棬���ִ�е��Ⱥ������ڷ���ʱ�����˳����������������

    // ����û���ҵ�ָ�������Ӧ������ں�panicJ��

 21 void release(struct task_struct * p)

 22 {

 23         int i;

 24

    // �������������ṹָ��ΪNULL���˳��������ָ��ָ��ǰ��������ʾ������Ϣ�˳���

 25         if (!p)

 26                 return;

 27         if (p == current) {

 28                 printk("task releasing itself\n\r");

 29                 return;

 30         }

    // ɨ������ṹָ�����飬Ѱ��ָ��������p������ҵ������ÿ�����ָ�������ж�Ӧ�����

    // ��������ṹ֮��Ĺ���ָ�룬�ͷ�����p���ݽṹռ�õ��ڴ�ҳ�档�����ִ�е��ȳ���

    // ���غ��˳������û���ҵ�ָ��������p����˵���ں˴�������ˣ�����ʾ������Ϣ��������

    // �������Ӳ��ֵĴ�����ָ������p��˫��������ɾ����

 31         for (i=1 ; i<NR_TASKS ; i++)

 32                 if (task[i]==p) {

 33                         task[i]=NULL;

 34                         /* Update links */    /* �������� */

    // ���p����������ϣ����ӽ��̣����ñ����ϵı��ڽ���ָ������µı��ڽ��̡����p

    // �������µ��ӽ��̣����ñ����µı����ӽ���ָ����ڵ��Ͻ��̡� �������p �������µ�

    // �ӽ��̣�����Ҫ�����丸���̵������ӽ���ָ��cptrΪָ��p�ı����ӽ��̡�

    // ָ��osptr��old sibling pointer��ָ���p�ȴ������ֵܽ��̡�

    // ָ��ysptr��younger sibling pointer��ָ���p�󴴽����ֵܽ��̡�

    // ָ��pptr��parent pointer��ָ��p�ĸ����̡�

    // ָ��cptr��child pointer���Ǹ�����ָ�����£���󣩴������ӽ��̡�

 35                         if (p->p_osptr)

 36                                 p->p_osptr->p_ysptr = p->p_ysptr;

 37                         if (p->p_ysptr)

 38                                 p->p_ysptr->p_osptr = p->p_osptr;

 39                         else

 40                                 p->p_pptr->p_cptr = p->p_osptr;

 41                         free_page((long)p);

 42                         schedule();

 43                         return;

 44                 }

 45         panic("trying to release non-existent task");

 46 }

 47

 48 #ifdef DEBUG_PROC_TREE

    // ��������˷���DEBUG_PROC_TREE�������ʱ�������´��롣

 49 /*

 50  * Check to see if a task_struct pointer is present in the task[] array

 51  * Return 0 if found, and 1 if not found.

 52  */

    /*

     * ���task[]�������Ƿ����һ��ָ����task_struct�ṹָ��p��

     * ��������򷵻�0�����򷵻�1��

     */

    // �������ṹָ��p��

 53 int bad_task_ptr(struct task_struct *p)

 54 {

 55         int     i;

 56

 57         if (!p)

 58                 return 0;

 59         for (i=0 ; i<NR_TASKS ; i++)

 60                 if (task[i] == p)

 61                         return 0;

 62         return 1;

 63 }

 64        

 65 /*

 66  * This routine scans the pid tree and make sure the rep invarient still

 67  * holds.  Used for debugging only, since it's very slow....

 68  *

 69  * It looks a lot scarier than it really is.... we're doing nothing more

 70  * than verifying the doubly-linked list found in p_ysptr and p_osptr,

 71  * and checking it corresponds with the process tree defined by p_cptr and

 72  * p_pptr;

 73  */

    /*

     * ����ĺ�������ɨ�����������ȷ�����Ĺ���������Ȼ��ȷ�������ڵ�ʽ��

     * ��Ϊ�ú����Ƚ���....

     *

     * �ú�������ȥҪ��ʵ�ʵĿֲ�.... ��ʵ���ǽ�����֤��ָ��p_ysptr��

     * p_osptr���ɵ�˫���������������������ָ��p_cptr��p_pptr���ɵ�

     * ������֮��Ĺ�ϵ��

     */

    // ����������

 74 void audit_ptree()

 75 {

 76         int     i;

 77

    // ɨ��ϵͳ�еij�����0������������񣬼��������4��ָ�루pptr��cptr��ysptr��osptr��

    // ����ȷ�ԡ�����������ۣ��Ϊ����������

 78         for (i=1 ; i<NR_TASKS ; i++) {

 79                 if (!task[i])

 80                         continue;

    // �������ĸ�����ָ��p_pptrû��ָ���κν��̣��������������в����ڣ�������ʾ������Ϣ

    // �����棬pid��N�ĸ��������������⡱����������cptr��ysptr��osptr�������Ʋ�����

 81                 if (bad_task_ptr(task[i]->p_pptr))

 82                         printk("Warning, pid %d's parent link is bad\n",

 83                                 task[i]->pid);

 84                 if (bad_task_ptr(task[i]->p_cptr))

 85                         printk("Warning, pid %d's child link is bad\n",

 86                                 task[i]->pid);

 87                 if (bad_task_ptr(task[i]->p_ysptr))

 88                         printk("Warning, pid %d's ys link is bad\n",

 89                                 task[i]->pid);

 90                 if (bad_task_ptr(task[i]->p_osptr))

 91                         printk("Warning, pid %d's os link is bad\n",

 92                                 task[i]->pid);

    // �������ĸ�����ָ��p_pptrָ�����Լ�������ʾ������Ϣ�����棬pid��N�ĸ���������

    // ָ��ָ�����Լ�������������cptr��ysptr��osptr�������Ʋ�����

 93                 if (task[i]->p_pptr == task[i])

 94                         printk("Warning, pid %d parent link points to self\n");

 95                 if (task[i]->p_cptr == task[i])

 96                         printk("Warning, pid %d child link points to self\n");

 97                 if (task[i]->p_ysptr == task[i])

 98                         printk("Warning, pid %d ys link points to self\n");

 99                 if (task[i]->p_osptr == task[i])

100                         printk("Warning, pid %d os link points to self\n");

    // ��������б��Լ��ȴ����ı����ֵܽ��̣���ô�ͼ�������Ƿ��й�ͬ�ĸ����̣���������

    // ���ֽ��̵�ysptrָ���Ƿ���ȷ��ָ�򱾽��̡�������ʾ������Ϣ��

101                 if (task[i]->p_osptr) {

102                         if (task[i]->p_pptr != task[i]->p_osptr->p_pptr)

103                                 printk(

104                         "Warning, pid %d older sibling %d parent is %d\n",

105                                 task[i]->pid, task[i]->p_osptr->pid,

106                                 task[i]->p_osptr->p_pptr->pid);

107                         if (task[i]->p_osptr->p_ysptr != task[i])

108                                 printk(

109                 "Warning, pid %d older sibling %d has mismatched ys link\n",

110                                 task[i]->pid, task[i]->p_osptr->pid);

111                 }

    // ��������б��Լ��󴴽��ı����ֵܽ��̣���ô�ͼ�������Ƿ��й�ͬ�ĸ����̣���������

    // С�ܽ��̵�osptrָ���Ƿ���ȷ��ָ�򱾽��̡�������ʾ������Ϣ��

112                 if (task[i]->p_ysptr) {

113                         if (task[i]->p_pptr != task[i]->p_ysptr->p_pptr)

114                                 printk(

115                         "Warning, pid %d younger sibling %d parent is %d\n",

116                                 task[i]->pid, task[i]->p_osptr->pid,

117                                 task[i]->p_osptr->p_pptr->pid);

118                         if (task[i]->p_ysptr->p_osptr != task[i])

119                                 printk(

120                 "Warning, pid %d younger sibling %d has mismatched os link\n",

121                                 task[i]->pid, task[i]->p_ysptr->pid);

122                 }

    // �������������ӽ���ָ��cptr���գ���ô�����ӽ��̵ĸ������Ƿ��DZ����̣�������

    // �ӽ��̵�С�ܽ���ָ��yspter�Ƿ�Ϊ�ա�����������ʾ������Ϣ��

123                 if (task[i]->p_cptr) {

124                         if (task[i]->p_cptr->p_pptr != task[i])

125                                 printk(

126                         "Warning, pid %d youngest child %d has mismatched parent link\n",

127                                 task[i]->pid, task[i]->p_cptr->pid);

128                         if (task[i]->p_cptr->p_ysptr)

129                                 printk(

130                         "Warning, pid %d youngest child %d has non-NULL ys link\n",

131                                 task[i]->pid, task[i]->p_cptr->pid);

132                 }

133         }

134 }

135 #endif /* DEBUG_PROC_TREE */

136

    //// ��ָ������p�����ź�sig��Ȩ��Ϊpriv��

    // ������sig - �ź�ֵ��p - ָ�������ָ�룻priv - ǿ�Ʒ����źŵı�־��������Ҫ���ǽ���

    // �û����Ի򼶱���ܷ����źŵ�Ȩ�����ú��������жϲ�������ȷ�ԣ�Ȼ���ж������Ƿ����㡣

    // ����������ָ�����̷����ź�sig���˳������򷵻�δ���ɴ���š�

137 static inline int send_sig(long sig,struct task_struct * p,int priv)

138 {

    // ���û��Ȩ�ޣ����ҵ�ǰ���̵���Ч�û�ID�����p�IJ�ͬ������Ҳ���dz����û�����˵��

    // û����p�����źŵ�Ȩ����suser()����Ϊ(current->euid==0)�������ж��Ƿ��dz����û���

139         if (!p)

140                 return -EINVAL;

141         if (!priv && (current->euid!=p->euid) && !suser())

142                 return -EPERM;

    // ����Ҫ���͵��ź���SIGKILL�� SIGCONT����ô�����ʱ�����źŵĽ��� p������ֹͣ״̬

    // ������Ϊ���������У�״̬��Ȼ���޸Ľ���p���ź�λͼsignal��ȥ������λ���ᵼ�½���

    // ֹͣ���ź�SIGSTOP��SIGTSTP��SIGTTIN��SIGTTOU��

143         if ((sig == SIGKILL) || (sig == SIGCONT)) {

144                 if (p->state == TASK_STOPPED)

145                         p->state = TASK_RUNNING;

146                 p->exit_code = 0;

147                 p->signal &= ~( (1<<(SIGSTOP-1)) | (1<<(SIGTSTP-1)) |

148                                 (1<<(SIGTTIN-1)) | (1<<(SIGTTOU-1)) );

149         }

150         /* If the signal will be ignored, don't even post it */

            /* ���Ҫ���͵��ź�sig��������p���Ե�����ô�͸������÷��� */

151         if ((int) p->sigaction[sig-1].sa_handler == 1)

152                 return 0;

153         /* Depends on order SIGSTOP, SIGTSTP, SIGTTIN, SIGTTOU */

            /* �����ж�������SIGSTOP��SIGTSTP��SIGTTIN��SIGTTOU�Ĵ��� */

    // ����ź���SIGSTOP��SIGTSTP��SIGTTIN��SIGTTOU֮һ����ô˵��Ҫ�ý����źŵĽ���p

    // ֹͣ���С���ˣ���p ���ź�λͼ���� SIGCONT ��λ������Ҫ��λλͼ�м������е��ź�

    // SIGCONT����λ��

154         if ((sig >= SIGSTOP) && (sig <= SIGTTOU))

155                 p->signal &= ~(1<<(SIGCONT-1));

156         /* Actually deliver the signal */

            /* ������������p�����ź�p */

157         p->signal |= (1<<(sig-1));

158         return 0;

159 }

160

    // ���ݽ������pgrpȡ�ý����������ĻỰ�š�

    // ɨ���������飬Ѱ�ҽ������Ϊpgrp�Ľ��̣���������Ự�š����û���ҵ�ָ���������

    // Ϊpgrp���κν��̣��򷵻�-1��

161 int session_of_pgrp(int pgrp)

162 {

163         struct task_struct **p;

164

165         for (p = &LAST_TASK ; p > &FIRST_TASK ; --p)

166                 if ((*p)->pgrp == pgrp)

167                         return((*p)->session);

168         return -1;

169 }

170

    // ��ֹ�����飨������鷢���źţ���

    // ������pgrp - ָ���Ľ�����ţ�sig - ָ�����źţ�priv - Ȩ�ޡ�

    // ����ָ��������pgrp�е�ÿ�����̷���ָ���ź�sig��ֻҪ��һ�����̷��ͳɹ����ͻ�

    // ����0���������û���ҵ�ָ���������pgrp���κ�һ�����̣��򷵻س�����-ESRCH����

    // �ҵ����������pgrp�Ľ��̣����Ƿ����ź�ʧ�ܣ��򷵻ط���ʧ�ܵĴ����롣

171 int kill_pg(int pgrp, int sig, int priv)

172 {

173         struct task_struct **p;

174         int err,retval = -ESRCH;         // -ESRCH��ʾָ���Ľ��̲����ڡ�

175         int found = 0;

176

    // �����жϸ������źźͽ�������Ƿ���Ч��Ȼ��ɨ��ϵͳ������������ɨ�赽�������Ϊ

    // pgrp�Ľ��̣������䷢���ź�sig��ֻҪ��һ���źŷ��ͳɹ����������ͻ᷵��0��

177         if (sig<1 || sig>32 || pgrp<=0)

178                 return -EINVAL;

179         for (p = &LAST_TASK ; p > &FIRST_TASK ; --p)

180                 if ((*p)->pgrp == pgrp) {

181                         if (sig && (err = send_sig(sig,*p,priv)))

182                                 retval = err;

183                         else

184                                 found++;

185                 }

186         return(found ? 0 : retval);

187 }

188

    // ��ֹ���̣�����̷����źţ���

    // ������pid - ���̺ţ�sig - ָ���źţ�priv - Ȩ�ޡ�

    // ������̺�Ϊpid�Ľ��̷���ָ���ź�sig�����ҵ�ָ��pid�Ľ��̣���ô���źŷ��ͳɹ���

    // �򷵻�0�����򷵻��źŷ��ͳ����š����û���ҵ�ָ�����̺�pid�Ľ��̣��򷵻س�����

    // -ESRCH��ָ�����̲����ڣ���

189 int kill_proc(int pid, int sig, int priv)

190 {

191         struct task_struct **p;

192

193         if (sig<1 || sig>32)

194                 return -EINVAL;

195         for (p = &LAST_TASK ; p > &FIRST_TASK ; --p)

196                 if ((*p)->pid == pid)

197                         return(sig ? send_sig(sig,*p,priv) : 0);

198         return(-ESRCH);

199 }

200

201 /*

202  * POSIX specifies that kill(-1,sig) is unspecified, but what we have

203  * is probably wrong.  Should make it like BSD or SYSV.

204  */

    /*

     * POSIX��׼ָ��kill(-1,sig)δ���塣��������֪���Ŀ��ܴ��ˡ�Ӧ������

     * ��BSD��SYSVϵͳһ����

     */

    //// ϵͳ����kill()���������κν��̻�����鷢���κ��źţ�������ֻ��ɱ������J��

    // ����pid�ǽ��̺ţ�sig����Ҫ���͵��źš�

    // ���pidֵ>0�����źű����͸����̺���pid�Ľ��̡�

    // ���pid=0����ô�źžͻᱻ���͸���ǰ���̵Ľ����������еĽ��̡�

    // ���pid=-1�����ź�sig�ͻᷢ�͸�����һ�����̣���ʼ���̣�������н��̡�

    // ���pid < -1�����ź�sig�����͸�������-pid�����н��̡�

    // ����ź�sigΪ0���򲻷����źţ����Ի���д����顣����ɹ��򷵻�0��

    // �ú���ɨ�������������������pid�����������Ľ��̷���ָ���ź�sig����pid����0��

    // ������ǰ�����ǽ������鳤�������Ҫ���������ڵĽ���ǿ�Ʒ����ź�sig��

205 int sys_kill(int pid,int sig)

206 {

207         struct task_struct **p = NR_TASKS + task;    // pָ�������������һ�

208         int err, retval = 0;

209

210         if (!pid)

211                 return(kill_pg(current->pid,sig,0));

212         if (pid == -1) {

213                 while (--p > &FIRST_TASK)

214                         if (err = send_sig(sig,*p,0))

215                                 retval = err;

216                 return(retval);

217         }

218         if (pid < 0)

219                 return(kill_pg(-pid,sig,0));

220         /* Normal kill */

221         return(kill_proc(pid,sig,0));

222 }

223

224 /*

225  * Determine if a process group is "orphaned", according to the POSIX

226  * definition in 2.2.2.52.  Orphaned process groups are not to be affected

227  * by terminal-generated stop signals.  Newly orphaned process groups are

228  * to receive a SIGHUP and a SIGCONT.

229  *

230  * "I ask you, have you ever known what it is to be an orphan?"

231  */

    /*

     * ����POSIX��׼2.2.2.52���еĶ��壬ȷ��һ���������Ƿ��ǡ��¶������¶�����

     * �鲻���ܵ��ն˲�����ֹͣ�źŵ�Ӱ�졣�½������Ŷ������齫���յ�һ��SIGHUP

     * �źź�һ��SIGCONT�źš�

     *

     * �������㣬���Ƿ�����֪����Ϊһ���¶���ζ��ʲô����

     */

    // �����ᵽ��POSIX P1003.1 2.2.2.52���ǹ��ڹ¶������������������������µ�һ������

    // ��ֹʱ���ܵ��½������ɡ��¶�����  һ�������鵽������ĸ�����֮�����ϵ�����ڸø�

    // ���̺����ӽ������ߡ���ˣ����������һ�����Ӹ����̵Ľ��̻����һ�������̵�ֱ�Ӻ���

    // ��ֹ�Ļ�����ô���������ͻ��Ϊһ���¶������顣���κ�һ������£�������̵���ֹ��

    // �½������ɹ¶������飬��ô�������е����н��̾ͻ������ǵ���ҵ����shell�Ͽ���ϵ��

    // ��ҵ����shell�����پ��иý�������ڵ��κ���Ϣ�����ý������д���ֹͣ״̬�Ľ��̽���

    // ��Զ��ʧ��Ϊ�˽��������⣬����ֹͣ״̬���̵��½������Ŷ����������Ҫ���յ�һ��

    // SIGHUP�źź�һ��SIGCONT�źţ�����ָʾ�����Ѿ������ǵĻỰ�� session���жϿ���ϵ��

    // SIGHUP�źŽ����½������г�Ա����ֹ���������Dz���������SIGHUP�źš��� SIGCONT��

    // �Ž�ʹ��Щû�б�SIGHUP�ź���ֹ�Ľ��̼������С� ���ڴ��������£����������һ����

    // �̴���ֹͣ״̬����ô�������еĽ��̿��ܶ�����ֹͣ״̬��

    //

    // �ж�һ���������Ƿ��ǹ¶����̡���������򷵻�0��������򷵻�1��

    // ɨ���������顣���������գ����߽��̵������ָ���IJ�ͬ�����߽����Ѿ����ڽ���״̬��

    // ���߽��̵ĸ�������init���̣���˵��ɨ��Ľ��̲���ָ��������ij�Ա�����߲�����Ҫ��

    // ���������� ����˵���ý�����ָ����ij�Ա�����丸���̲��� init���̡���ʱ����ý���

    // �����̵���Ų�����ָ�������pgrp���������̵ĻỰ�ŵ��ڽ��̵ĻỰ�ţ���˵������ͬ

    // ����һ���Ự�����ָ����pgrp������϶����ǹ¶������顣����...��

232 int is_orphaned_pgrp(int pgrp)

233 {

234         struct task_struct **p;

235

236         for (p = &LAST_TASK ; p > &FIRST_TASK ; --p) {

237                 if (!(*p) ||

238                     ((*p)->pgrp != pgrp) ||

239                     ((*p)->state == TASK_ZOMBIE) ||

240                     ((*p)->p_pptr->pid == 1))

241                         continue;

242                 if (((*p)->p_pptr->pgrp != pgrp) &&

243                     ((*p)->p_pptr->session == (*p)->session))

244                         return 0;

245         }

246         return(1);      /* (sighing) "Often!" */    /* �������ǹ¶������飡*/

247 }

248

    // �жϽ��������Ƿ��д���ֹͣ״̬����ҵ�������飩�����򷵻�1�����򷵻�0��

    // ���ҷ�����ɨ�������������顣�������ָ����pgrp���κν����Ƿ���ֹͣ״̬��

249 static int has_stopped_jobs(int pgrp)

250 {

251         struct task_struct ** p;

252

253         for (p = &LAST_TASK ; p > &FIRST_TASK ; --p) {

254                 if ((*p)->pgrp != pgrp)

255                         continue;

256                 if ((*p)->state == TASK_STOPPED)

257                         return(1);

258         }

259         return(0);

260 }

261

    // �����˳�����������������365�д���ϵͳ���ô�������sys_exit()���á�

    // �ú��������ݵ�ǰ�������������Զ�����д��������ѵ�ǰ����״̬���óɽ���״̬

    // TASK_ZOMBIE�������õ��Ⱥ���schedule()ȥִ���������̣����ٷ��ء�

262 volatile void do_exit(long code)

263 {

264         struct task_struct *p;

265         int i;

266

    // �����ͷŵ�ǰ���̴���κ����ݶ���ռ���ڴ�ҳ�� ����free_page_tables() �ĵ�1������

    // ��get_base()����ֵ��ָ����CPU���Ե�ַ�ռ�����ʼ����ַ����2����get_limit()����ֵ��

    // ˵�����ͷŵ��ֽڳ���ֵ��get_base()���е�current->ldt[1]�������̴������������λ��

    // ��current->ldt[2]�������̴������������λ�ã���get_limit()�е�0x0f�ǽ��̴���ε�

    // ѡ�����0x17�ǽ������ݶε�ѡ�����������ȡ�λ���ַʱʹ�øöε�������������ַ��Ϊ

    // ������ȡ�γ���ʱʹ�øöε�ѡ�����Ϊ������ free_page_tables()����λ��mm/memory.c

    // �ļ��ĵ�69�п�ʼ����get_base()��get_limit()��λ��include/linux/sched.hͷ�ļ��ĵ�

    // 264�п�ʼ����

267         free_page_tables(get_base(current->ldt[1]),get_limit(0x0f));

268         free_page_tables(get_base(current->ldt[2]),get_limit(0x17));

    // Ȼ��رյ�ǰ���̴��ŵ������ļ����ٶԵ�ǰ���̵Ĺ���Ŀ¼pwd����Ŀ¼root��ִ�г���

    // �ļ��� i�ڵ��Լ����ļ�����ͬ���������Żظ��� i�ڵ㲢�ֱ��ÿգ��ͷţ��� ���Űѵ�ǰ

    // ���̵�״̬����Ϊ����״̬��TASK_ZOMBIE���������ý����˳��롣

269         for (i=0 ; i<NR_OPEN ; i++)

270                 if (current->filp[i])

271                         sys_close(i);

272         iput(current->pwd);

273         current->pwd = NULL;

274         iput(current->root);

275         current->root = NULL;

276         iput(current->executable);

277         current->executable = NULL;

278         iput(current->library);

279         current->library = NULL;

280         current->state = TASK_ZOMBIE;

281         current->exit_code = code;

282         /*

283          * Check to see if any process groups have become orphaned

284          * as a result of our exiting, and if they have any stopped

285          * jobs, send them a SIGUP and then a SIGCONT.  (POSIX 3.2.2.2)

286          *

287          * Case i: Our father is in a different pgrp than we are

288          * and we were the only connection outside, so our pgrp

289          * is about to become orphaned.

290          */

             /*

              * ��鵱ǰ���̵��˳��Ƿ������κν������ɹ¶������顣���

              * �У������д���ֹͣ״̬��TASK_STOPPED������Ա���������Ƿ���

              * һ��SIGHUP�źź�һ��SIGCONT�źš���POSIX 3.2.2.2��Ҫ��

              *

              * ���1�����ǵĸ�����������һ�������Dz�ͬ�Ľ������У���������

              * ������������Ψһ��ϵ���������ǵĽ����齫���һ���¶������顣

              */

    // POSIX 3.2.2.2��1991�棩�ǹ���exit()������˵����������������ڵĽ������뵱ǰ���̵�

    // ��ͬ����������ͬһ���Ự��session���У����ҵ�ǰ�������ڽ����齫Ҫ��ɹ¶������˲���

    // ��ǰ���̵Ľ������к��д���ֹͣ״̬����ҵ�����̣�����ô��Ҫ�������ǰ���̵Ľ����鷢

    // �������źţ�SIGHUP��SIGCONT�������������źŵ�ԭ���232��ǰ��˵����

291         if ((current->p_pptr->pgrp != current->pgrp) &&

292             (current->p_pptr->session == current->session) &&

293             is_orphaned_pgrp(current->pgrp) &&

294             has_stopped_jobs(current->pgrp)) {

295                 kill_pg(current->pgrp,SIGHUP,1);

296                 kill_pg(current->pgrp,SIGCONT,1);

297         }

298         /* Let father know we died */         /* ֪ͨ�����̵�ǰ���̽���ֹ */

299         current->p_pptr->signal |= (1<<(SIGCHLD-1));

300        

301         /*

302          * This loop does two things:

303          *

304          * A.  Make init inherit all the child processes

305          * B.  Check to see if any process groups have become orphaned

306          *      as a result of our exiting, and if they have any stopped

307          *      jons, send them a SIGUP and then a SIGCONT.  (POSIX 3.2.2.2)

308          */

            /*

             * �����ѭ�������������飺

             *

             * A.  ��init���̼̳е�ǰ���������ӽ��̡�

             * B.  ��鵱ǰ���̵��˳��Ƿ������κν������ɹ¶������顣���

             *     �У������д���ֹͣ״̬��TASK_STOPPED������Ա���������Ƿ���

             *     һ��SIGHUP�źź�һ��SIGCONT�źš���POSIX 3.2.2.2��Ҫ��

             */

    // �����ǰ�������ӽ��̣���p_cptrָ��ָ������������ӽ��̣������ý���1��init���̣�

    // ��Ϊ�������ӽ��̵ĸ����̡�����ӽ����Ѿ����ڽ���״̬������init���̣������̣�����

    // �ӽ�������ֹ�ź�SIGCHLD��

309         if (p = current->p_cptr) {

310                 while (1) {

311                         p->p_pptr = task[1];

312                         if (p->state == TASK_ZOMBIE)

313                                 task[1]->signal |= (1<<(SIGCHLD-1));

314                         /*

315                          * process group orphan check

316                          * Case ii: Our child is in a different pgrp

317                          * than we are, and it was the only connection

318                          * outside, so the child pgrp is now orphaned.

319                          */

                             /* �¶��������⡣

                              * ���2�����ǵ��ӽ����ڲ�ͬ�Ľ������У���������

                              * ������Ψһ���������ӡ���������ӽ������ڽ���

                              * �齫��ɹ¶��������ˡ�

                              */

    // ����ӽ����뵱ǰ���̲���ͬһ���������е�����ͬһ��session�У����ҵ�ǰ�������ڽ���

    // �齫Ҫ��ɹ¶������ˣ����ҵ�ǰ���̵Ľ������к��д���ֹͣ״̬����ҵ�����̣�����ô��

    // Ҫ�������ǰ���̵Ľ����鷢�������źţ�SIGHUP��SIGCONT��  ������ӽ������ֵܽ��̣�

    // �����ѭ��������Щ�ֵܽ��̡�

320                         if ((p->pgrp != current->pgrp) &&

321                             (p->session == current->session) &&

322                             is_orphaned_pgrp(p->pgrp) &&

323                             has_stopped_jobs(p->pgrp)) {

324                                 kill_pg(p->pgrp,SIGHUP,1);

325                                 kill_pg(p->pgrp,SIGCONT,1);

326                         }

327                         if (p->p_osptr) {

328                                 p = p->p_osptr;

329                                 continue;

330                         }

331                         /*

332                          * This is it; link everything into init's children

333                          * and leave

334                          */

                            /*

                             * ���������������ӽ������ӳ�Ϊinit���ӽ��̲��˳�ѭ����

                             */

    // ͨ�����洦������ǰ�����ӽ��̵������ֵ��ӽ��̶��Ѿ�����������ʱpָ�����ϵ��ֵ���

    // ���̡����ǰ���Щ�ֵ��ӽ���ȫ������init���̵��ӽ���˫������ͷ���С������init

    // ���̵�p_cptr ָ��ǰ����ԭ�ӽ�����������ģ�the youngest���ӽ��̣���ԭ�ӽ�����

    // ���ϵģ�the oldest���ֵ��ӽ��� p_osptr ָ��ԭ init���̵���������̣���ԭinit��

    // ������������̵� p_ysptrָ��ԭ�ӽ��������ϵ��ֵ��ӽ��̡����ѵ�ǰ���̵�p_cptr

    // ָ���ÿգ����˳�ѭ����

335                         p->p_osptr = task[1]->p_cptr;

336                         task[1]->p_cptr->p_ysptr = p;

337                         task[1]->p_cptr = current->p_cptr;

338                         current->p_cptr = 0;

339                         break;

340                 }

341         }

    // �����ǰ�����ǻỰͷ��(leader)���̣���ô�����п����նˣ���������ʹ�øÿ����ն˵�

    // �����鷢�͹Ҷ��ź�SIGHUP��Ȼ���ͷŸ��նˡ�����ɨ���������飬�����ڵ�ǰ���̻Ự��

    // ���̵��ն��ÿգ�ȡ������

342         if (current->leader) {

343                 struct task_struct **p;

344                 struct tty_struct *tty;

345

346                 if (current->tty >= 0) {

347                         tty = TTY_TABLE(current->tty);

348                         if (tty->pgrp>0)

349                                 kill_pg(tty->pgrp, SIGHUP, 1);

350                         tty->pgrp = 0;

351                         tty->session = 0;

352                 }

353                 for (p = &LAST_TASK ; p > &FIRST_TASK ; --p)

354                         if ((*p)->session == current->session)

355                                 (*p)->tty = -1;

356         }

    // �����ǰ�����ϴ�ʹ�ù�Э����������Ѽ�¼����Ϣ��ָ���ÿա��������˵��Խ��������ţ�

    // ����ý����������ʾ�����������õ��Ⱥ��������µ��Ƚ������У����ø������ܹ�����

    // �������̵������ƺ����ˡ�

357         if (last_task_used_math == current)

358                 last_task_used_math = NULL;

359 #ifdef DEBUG_PROC_TREE

360         audit_ptree();

361 #endif

362         schedule();

363 }

364

    // ϵͳ����exit()����ֹ���̡�

    // ����error_code���û������ṩ���˳�״̬��Ϣ��ֻ�е��ֽ���Ч����error_code����8

    // ������ wait() �� waitpid()������Ҫ�󡣵��ֽ��н���������wait()��״̬��Ϣ�����磬

    // ������̴�����ͣ״̬��TASK_STOPPED������ô����ֽھ͵��� 0x7f���μ� sys/wait.h

    // �ļ���13--19�С� wait() ��waitpid() ������Щ��Ϳ���ȡ���ӽ��̵��˳�״̬�����

    // ������ֹ��ԭ���źţ���

365 int sys_exit(int error_code)

366 {

367         do_exit((error_code&0xff)<<8);

368 }

369

    // ϵͳ����waitpid()������ǰ���̣�ֱ��pid ָ�����ӽ����˳�����ֹ�������յ�Ҫ����ֹ

    // �ý��̵��źţ���������Ҫ����һ���źž�����źŴ������򣩡����pid��ָ���ӽ�������

    // �˳����ѳ���ν�Ľ������̣����򱾵��ý����̷��ء��ӽ���ʹ�õ�������Դ���ͷš�

    // ���pid > 0����ʾ�ȴ����̺ŵ���pid���ӽ��̡�

    // ���pid = 0����ʾ�ȴ�������ŵ��ڵ�ǰ������ŵ��κ��ӽ��̡�

    // ���pid < -1����ʾ�ȴ�������ŵ���pid����ֵ���κ��ӽ��̡�

    // ���pid = -1����ʾ�ȴ��κ��ӽ��̡�

    // ��options = WUNTRACED����ʾ����ӽ�����ֹͣ�ģ�Ҳ���Ϸ��أ�������٣���

    // ��options = WNOHANG����ʾ���û���ӽ����˳�����ֹ�����Ϸ��ء�

    // �������״ָ̬��stat_addr��Ϊ�գ���ͽ�״̬��Ϣ���浽���

    // ����pid�ǽ��̺ţ�*stat_addr�DZ���״̬��Ϣλ�õ�ָ�룻options��waitpidѡ�

370 int sys_waitpid(pid_t pid,unsigned long * stat_addr, int options)

371 {

372         int flag;               // �ñ�־���ں����ʾ��ѡ�����ӽ��̴��ھ�����˯��̬��

373         struct task_struct *p;

374         unsigned long oldblocked;

375

    // ������֤��Ҫ���״̬��Ϣ��λ�ô��ڴ�ռ��㹻��Ȼ��λ��־flag�����Ŵӵ�ǰ���̵���

    // �����ӽ��̿�ʼɨ���ӽ����ֵ�������

376         verify_area(stat_addr,4);

377 repeat:

378         flag=0;

379         for (p = current->p_cptr ; p ; p = p->p_osptr) {

    // ����ȴ����ӽ��̺�pid>0�����뱻ɨ���ӽ���p��pid����ȣ�˵�����ǵ�ǰ�����������

    // ���̣����������ý��̣�����ɨ����һ�����̡�

380                 if (pid>0) {

381                         if (p->pid != pid)

382                                 continue;

    // �������ָ���ȴ����̵�pid=0����ʾ���ڵȴ�������ŵ��ڵ�ǰ������ŵ��κ��ӽ��̡�

    // �����ʱ��ɨ�����p�Ľ�������뵱ǰ���̵���Ų��ȣ���������

383                 } else if (!pid) {

384                         if (p->pgrp != current->pgrp)

385                                 continue;

    // �������ָ����pid < -1����ʾ���ڵȴ�������ŵ���pid����ֵ���κ��ӽ��̡������ʱ

    // ��ɨ�����p�������pid�ľ���ֵ���ȣ���������

386                 } else if (pid != -1) {

387                         if (p->pgrp != -pid)

388                                 continue;

389                 }

    // ���ǰ3����pid���ж϶������ϣ����ʾ��ǰ�������ڵȴ����κ��ӽ��̣�Ҳ��pid = -1

    // ���������ʱ��ѡ�񵽵Ľ��� p ����������̺ŵ���ָ�� pid�������ǵ�ǰ�������е��κ�

    // �ӽ��̣������ǽ��̺ŵ���ָ�� pid ����ֵ���ӽ��̣��������κ��ӽ��̣���ʱָ���� pid

    // ���� -1������������������ӽ���p������״̬��������

    // ���ӽ���p ����ֹͣ״̬ʱ�������ʱ����ѡ��options��WUNTRACED ��־û����λ����ʾ

    // �����������̷��أ������ӽ��̴�ʱ���˳������ 0�����Ǽ���ɨ�账�������ӽ��̡� ���

    // WUNTRACED��λ���ӽ����˳��벻Ϊ0������˳���������ֽڣ�����״̬��Ϣ 0x7f �����

    // *stat_addr���ڸ�λ�ӽ����˳��������̷����ӽ��̺�pid������0x7f ��ʾ�ķ���״̬ʹ

    // WIFSTOPPED()��Ϊ�档�μ�include/sys/wait.h��14�С�

390                 switch (p->state) {

391                         case TASK_STOPPED:

392                                 if (!(options & WUNTRACED) ||

393                                     !p->exit_code)

394                                         continue;

395                                 put_fs_long((p->exit_code << 8) | 0x7f,

396                                         stat_addr);

397                                 p->exit_code = 0;

398                                 return p->pid;

    // ����ӽ���p���ڽ���״̬�������Ȱ������û�̬���ں�̬���е�ʱ��ֱ��ۼƵ���ǰ����

    // �������̣��У�Ȼ��ȡ���ӽ��̵�pid���˳��룬���˳�����뷵��״̬λ��stat_addr��

    // ���ͷŸ��ӽ��̡���󷵻��ӽ��̵��˳����pid�� �������˵��Խ��������ţ�����ý���

    // �������ʾ������

399                         case TASK_ZOMBIE:

400                                 current->cutime += p->utime;

401                                 current->cstime += p->stime;

402                                 flag = p->pid;

403                                 put_fs_long(p->exit_code, stat_addr);

404                                 release(p);

405 #ifdef DEBUG_PROC_TREE

406                                 audit_ptree();

407 #endif

408                                 return flag;

    // �������ӽ���p��״̬�Ȳ���ֹͣҲ���ǽ�������ô����flag = 1����ʾ�ҵ���һ������

    // Ҫ����ӽ��̣���������������̬��˯��̬��

409                         default:

410                                 flag=1;

411                                 continue;

412                 }

413         }

    // ���������������ɨ���������� flag����λ��˵���з��ϵȴ�Ҫ����ӽ��̲�û�д�

    // ���˳�����״̬����ʱ���������WNOHANGѡ���ʾ��û���ӽ��̴����˳�����ֹ̬��

    // ���̷��أ��������̷���0���˳�������ѵ�ǰ������Ϊ���жϵȴ�״̬�����������޸�

    // ��ǰ�����ź�����λͼ����������յ�SIGCHLD�źš�Ȼ��ִ�е��ȳ��򡣵�ϵͳ�ֿ�ʼ

    // ִ�б�����ʱ������������յ���SIGCHLD���������δ�����źţ������˳��롰������

    // ��ϵͳ���á����ء�������ת��������ʼ��repeat��Ŵ��ظ�������

414         if (flag) {

415                 if (options & WNOHANG)

416                         return 0;

417                 current->state=TASK_INTERRUPTIBLE;

418                 oldblocked = current->blocked;

419                 current->blocked &= ~(1<<(SIGCHLD-1));

420                 schedule();

421                 current->blocked = oldblocked;

422                 if (current->signal & ~(current->blocked | (1<<(SIGCHLD-1))))

423                         return -ERESTARTSYS;

424                 else

425                         goto repeat;

426         }

    // ��flag = 0����ʾû���ҵ�����Ҫ����ӽ��̣��򷵻س����루�ӽ��̲����ڣ���

427         return -ECHILD;

428 }

429


 


 

8.8 ����8-8 linux/kernel/fork.c


  1 /*

  2  *  linux/kernel/fork.c

  3  *

  4  *  (C) 1991  Linus Torvalds

  5  */

  6

  7 /*

  8  *  'fork.c' contains the help-routines for the 'fork' system call

  9  * (see also system_call.s), and some misc functions ('verify_area').

 10  * Fork is rather simple, once you get the hang of it, but the memory

 11  * management can be a bitch. See 'mm/mm.c': 'copy_page_tables()'

 12  */

    /*

     * 'fork.c'�к���ϵͳ����'fork'�ĸ����ӳ��򣨲μ�system_call.s�����Լ�һЩ

     * ����������'verify_area'����һ�����˽���fork���ͻᷢ�����Ƿdz��򵥵ģ���

     * �ڴ����ȴ��Щ�Ѷȡ��μ�'mm/memory.c'�е�'copy_page_tables()'������

     */

 13 #include <errno.h>        // �����ͷ�ļ�������ϵͳ�и��ֳ����š�

 14

 15 #include <linux/sched.h>  // ���ȳ���ͷ�ļ�������������ṹtask_struct������0�����ݡ�

 16 #include <linux/kernel.h> // �ں�ͷ�ļ�������һЩ�ں˳��ú�����ԭ�ζ��塣

 17 #include <asm/segment.h>  // �β���ͷ�ļ����������йضμĴ���������Ƕ��ʽ��ຯ����

 18 #include <asm/system.h>   // ϵͳͷ�ļ������������û��޸�������/�ж��ŵȵ�Ƕ��ʽ���ꡣ

 19

    // дҳ����֤����ҳ�治��д������ҳ�档������mm/memory.c ��261�п�ʼ��

 20 extern void write_verify(unsigned long address);

 21

 22 long last_pid=0;          // ���½��̺ţ���ֵ����get_empty_process()���ɡ�

 23

    //// ���̿ռ�����дǰ��֤������

    // ����80386 CPU����ִ����Ȩ��0����ʱ���������û��ռ��е�ҳ���Ƿ���ҳ�����ģ����

    // ��ִ���ں˴���ʱ�û��ռ�������ҳ�汣����־�������ã�дʱ���ƻ���Ҳ��ʧȥ�����á�

    // verify_area()���������ڴ�Ŀ�ġ�������80486�������CPU������ƼĴ���CR0����һ��

    // д������־WP��λ16�����ں˿���ͨ�����øñ�־����ֹ��Ȩ��0�Ĵ������û��ռ�ֻ��

    // ҳ��ִ��д���ݣ����򽫵��·���д�����쳣���Ӷ�486����CPU����ͨ�����øñ�־����

    // ��ʹ�ñ�����ͬ����Ŀ�ġ�

    // �ú����Ե�ǰ�����߼���ַ�� addr �� addr + size ��һ�η�Χ��ҳΪ��λִ��д����ǰ

    // �ļ����������ڼ���ж�����ҳ��Ϊ��λ���в�������˳���������Ҫ�ҳ�addr����ҳ

    // �濪ʼ��ַstart��Ȼ�� start���Ͻ������ݶλ�ַ��ʹ���start�任��CPU 4G���Կ�

    // ���еĵ�ַ�����ѭ������write_verify() ��ָ����С���ڴ�ռ����дǰ��֤����ҳ��

    // ��ֻ���ģ���ִ�й�������͸���ҳ�������дʱ���ƣ���

 24 void verify_area(void * addr,int size)

 25 {

 26         unsigned long start;

 27

    // ���Ƚ���ʼ��ַstart����Ϊ������ҳ����߽翪ʼλ�ã�ͬʱ��Ӧ�ص�����֤�����С��

    // �¾��е� start & 0xfff �������ָ����ʼλ��addr��Ҳ��start��������ҳ���е�ƫ��

    // ֵ��ԭ��֤��Χ size �������ƫ��ֵ����չ���� addr ����ҳ����ʼλ�ÿ�ʼ�ķ�Χֵ��

    // ����� 30���� Ҳ��Ҫ����֤��ʼλ�� start ������ҳ��߽�ֵ���μ�ǰ���ͼ���ڴ���

    // ֤��Χ�ĵ�������

 28         start = (unsigned long) addr;

 29         size += start & 0xfff;

 30         start &= 0xfffff000;               // ��ʱstart�ǵ�ǰ���̿ռ��е��߼���ַ��

    // ����� start ���Ͻ������ݶ������Ե�ַ�ռ��е���ʼ��ַ�����ϵͳ�������Կռ��еĵ�

    // ַλ�á�����Linux 0.1x�ںˣ������ݶκʹ���������Ե�ַ�ռ��еĻ�ַ���޳�����ͬ��

    // Ȼ��ѭ������дҳ����֤����ҳ�治��д������ҳ�档��mm/memory.c��274�У�

 31         start += get_base(current->ldt[2]);     // include/linux/sched.h��277�С�

 32         while (size>0) {

 33                 size -= 4096;

 34                 write_verify(start);

 35                 start += 4096;

 36         }

 37 }

 38

    // �����ڴ�ҳ����

    // ����nr��������ţ�p�����������ݽṹָ�롣�ú���Ϊ�����������Ե�ַ�ռ������ô���

    // �κ����ݶλ�ַ���޳���������ҳ����  ����Linuxϵͳ������дʱ���ƣ�copy on write��

    // ������ ��������Ϊ�½��������Լ���ҳĿ¼�����ҳ�����û��ʵ��Ϊ�½��̷�������

    // �ڴ�ҳ�档��ʱ�½������丸���̹��������ڴ�ҳ�档�����ɹ�����0�����򷵻س����š�

 39 int copy_mem(int nr,struct task_struct * p)

 40 {

 41         unsigned long old_data_base,new_data_base,data_limit;

 42         unsigned long old_code_base,new_code_base,code_limit;

 43

    // ����ȡ��ǰ���ֲ̾����������д���������������ݶ����������еĶ��޳����ֽ�������

    // 0x0f�Ǵ����ѡ�����0x17�����ݶ�ѡ�����Ȼ��ȡ��ǰ���̴���κ����ݶ������Ե�ַ

    // �ռ��еĻ���ַ������Linux 0.12�ں˻���֧�ִ�������ݶη�������������������Ҫ

    // ������κ����ݶλ�ַ�Ƿ���ͬ������Ҫ�����ݶεij������ٲ�С�ڴ���εij���

    // ���μ�ͼ5-12���������ں���ʾ������Ϣ����ֹͣ���С�

    // get_limit()��get_base()������include/linux/sched.h��277�к�279�д���

 44         code_limit=get_limit(0x0f);

 45         data_limit=get_limit(0x17);

 46         old_code_base = get_base(current->ldt[1]);

 47         old_data_base = get_base(current->ldt[2]);

 48         if (old_data_base != old_code_base)

 49                 panic("We don't support separate I&D");

 50         if (data_limit < code_limit)

 51                 panic("Bad data_limit");

    // Ȼ�����ô����е��½��������Ե�ַ�ռ��еĻ���ַ���ڣ�64MB * ������ţ������ø�ֵ

    // �����½��ֲ̾����������ж��������еĻ���ַ�����������½��̵�ҳĿ¼�����ҳ���

    // �����Ƶ�ǰ���̣������̣���ҳĿ¼�����ҳ��� ��ʱ�ӽ��̹��������̵��ڴ�ҳ�档

    // ���������copy_page_tables()����0�������ʾ���������ͷŸ������ҳ���

 52         new_data_base = new_code_base = nr * TASK_SIZE;

 53         p->start_code = new_code_base;

 54         set_base(p->ldt[1],new_code_base);

 55         set_base(p->ldt[2],new_data_base);

 56         if (copy_page_tables(old_data_base,new_data_base,data_limit)) {

 57                 free_page_tables(new_data_base,data_limit);

 58                 return -ENOMEM;

 59         }

 60         return 0;

 61 }

 62

 63 /*

 64  *  Ok, this is the main fork-routine. It copies the system process

 65  * information (task[nr]) and sets up the necessary registers. It

 66  * also copies the data segment in it's entirety.

 67  */

    /*

     * OK����������Ҫ��fork�ӳ���������ϵͳ������Ϣ(task[n])

     * �������ñ�Ҫ�ļĴ��������������ظ������ݶΣ�Ҳ�Ǵ���Σ���

     */

    // ���ƽ��̡�

    // �ú����IJ����ǽ���ϵͳ�����жϴ������̣�sys_call.s����ʼ��ֱ�����ñ�ϵͳ���ô���

    // ���̣�sys_call.s��208�У��͵��ñ�����ǰ��sys_call.s��217�У���ѹ������ں�

    // ̬ջ�ĸ��Ĵ�����ֵ����Щ��sys_call.s��������ѹ���ں�̬ջ��ֵ������������:

    // �� CPUִ���ж�ָ��ѹ����û�ջ��ַss��esp����־eflags�ͷ��ص�ַcs��eip��

    // �� ��83--88���ڸս���system_callʱ��ջ�ĶμĴ���ds��es��fs��edx��ecx��edx��

    // �� ��94�е���sys_call_table��sys_fork����ʱ��ջ�ķ��ص�ַ������none��ʾ����

    // �� ��212--216���ڵ���copy_process()֮ǰ��ջ��gs��esi��edi��ebp��eax��nr����

    // ���в���nr�ǵ���find_empty_process()���������������š�

 68 int copy_process(int nr,long ebp,long edi,long esi,long gs,long none,

 69                 long ebx,long ecx,long edx, long orig_eax,

 70                 long fs,long es,long ds,

 71                 long eip,long cs,long eflags,long esp,long ss)

 72 {

 73         struct task_struct *p;

 74         int i;

 75         struct file *f;

 76

    // ����Ϊ���������ݽṹ�����ڴ档����ڴ����������򷵻س����벢�˳���Ȼ��������

    // �ṹָ��������������nr���С�����nrΪ����ţ���ǰ��find_empty_process()���ء�

    // ���Űѵ�ǰ��������ṹ���ݸ��Ƶ������뵽���ڴ�ҳ��p��ʼ����

 77         p = (struct task_struct *) get_free_page();

 78         if (!p)

 79                 return -EAGAIN;

 80         task[nr] = p;

 81         *p = *current/* NOTE! this doesn't copy the supervisor stack */

                            /* ע�⣡���������Ḵ�Ƴ����û���ջ��ֻ���ƽ��̽ṹ��*/

    // ���Ը������Ľ��̽ṹ���ݽ���һЩ�޸ģ���Ϊ�½��̵�����ṹ���Ƚ��½��̵�״̬

    // ��Ϊ�����жϵȴ�״̬���Է�ֹ�ں˵�����ִ�С�Ȼ�������½��̵Ľ��̺�pid������ʼ

    // ����������ʱ��Ƭֵ������ priorityֵ�� һ��Ϊ15����ણ������Ÿ�λ�½��̵��ź�

    // λͼ��������ʱֵ���Ự��session���쵼��־ leader�� ���̼����ӽ������ں˺��û�

    // ̬����ʱ��ͳ��ֵ�������ý��̿�ʼ���е�ϵͳʱ��start_time��

 82         p->state = TASK_UNINTERRUPTIBLE;

 83         p->pid = last_pid;           // �½��̺š�Ҳ��find_empty_process()�õ���

 84         p->counter = p->priority;    // ����ʱ��Ƭֵ�����������

 85         p->signal = 0;               // �ź�λͼ��

 86         p->alarm = 0;                // ������ʱֵ�����������

 87         p->leader = 0;               /* process leadership doesn't inherit */

                                         /* ���̵��쵼Ȩ�Dz��ܼ̳е� */

 88         p->utime = p->stime = 0;     // �û�̬ʱ��ͺ���̬����ʱ�䡣

 89         p->cutime = p->cstime = 0;   // �ӽ����û�̬�ͺ���̬����ʱ�䡣

 90         p->start_time = jiffies;     // ���̿�ʼ����ʱ�䣨��ǰʱ��δ�������

    // ���޸�����״̬��TSS ���ݣ��μ��б���˵����������ϵͳ������ṹ p������1ҳ��

    // �ڴ棬���� (PAGE_SIZE + (long) p) ��esp0����ָ���ҳ���ˡ� ss0:esp0 ��������

    // ���ں�ִ̬��ʱ��ջ�����⣬�ڵ�3���������Ѿ�֪����ÿ�������� GDT���ж�������

    // ����������һ���������TSS������������һ���������LDT����������������111��

    // �����ǰ�GDT�б�����LDT����������ѡ��������ڱ������TSS���С���CPUִ��

    // �л�����ʱ�����Զ���TSS�а�LDT����������ѡ������ص�ldtr�Ĵ����С�

 91         p->tss.back_link = 0;

 92         p->tss.esp0 = PAGE_SIZE + (long) p;  // �����ں�̬ջָ�롣

 93         p->tss.ss0 = 0x10;           // �ں�̬ջ�Ķ�ѡ��������ں����ݶ���ͬ����

 94         p->tss.eip = eip;            // ָ�����ָ�롣

 95         p->tss.eflags = eflags;      // ��־�Ĵ�����

 96         p->tss.eax = 0;              // ���ǵ�fork()����ʱ�½��̻᷵��0��ԭ�����ڡ�

 97         p->tss.ecx = ecx;

 98         p->tss.edx = edx;

 99         p->tss.ebx = ebx;

100         p->tss.esp = esp;

101         p->tss.ebp = ebp;

102         p->tss.esi = esi;

103         p->tss.edi = edi;

104         p->tss.es = es & 0xffff;     // �μĴ�����16λ��Ч��

105         p->tss.cs = cs & 0xffff;

106         p->tss.ss = ss & 0xffff;

107         p->tss.ds = ds & 0xffff;

108         p->tss.fs = fs & 0xffff;

109         p->tss.gs = gs & 0xffff;

110         p->tss.ldt = _LDT(nr);       // ����ֲ�����������ѡ�����LDT��������GDT�У���

111         p->tss.trace_bitmap = 0x80000000;       //����16λ��Ч����

    // �����ǰ����ʹ����Э���������ͱ����������ġ����ָ��clts����������ƼĴ���CR0

    // �е������ѽ�����TS����־��ÿ�����������л���CPU�������øñ�־���ñ�־���ڹ���

    // ��ѧЭ������������ñ�־��λ����ôÿ��ESCָ��ᱻ�����쳣7�������Э����

    // �����ڱ�־MPҲͬʱ��λ�Ļ�����ôWAITָ��Ҳ�Ჶ����ˣ���������л�������һ

    // ��ESCָ�ʼִ��֮����Э�������е����ݾͿ�����Ҫ��ִ���µ�ESCָ��֮ǰ����

    // ����������������ᱣ��Э�����������ݲ���λTS��־��ָ��fnsave���ڰ�Э������

    // ������״̬���浽Ŀ�IJ�����ָ�����ڴ������У�tss.i387����

112         if (last_task_used_math == current)

113                 __asm__("clts ; fnsave %0 ; frstor %0"::"m" (p->tss.i387));

 

    // ���������ƽ���ҳ�����������Ե�ַ�ռ����������������κ����ݶ��������еĻ�ַ

    // ���޳���������ҳ�����������������ֵ����0������λ������������Ӧ��ͷ�Ϊ

    // ��������������������ṹ���ڴ�ҳ��

114         if (copy_mem(nr,p)) {              // ���ز�Ϊ0��ʾ������

115                 task[nr] = NULL;

116                 free_page((long) p);

117                 return -EAGAIN;

118         }

    // ��������������ļ��Ǵ򿪵ģ��򽫶�Ӧ�ļ��Ĵ򿪴�����1����Ϊ���ﴴ�����ӽ���

    // ���븸���̹�����Щ�򿪵��ļ�������ǰ���̣������̣���pwd, root��executable

    // ���ô�������1��������ͬ���ĵ������ӽ���Ҳ��������Щi�ڵ㡣

119         for (i=0; i<NR_OPEN;i++)

120                 if (f=p->filp[i])

121                         f->f_count++;

122         if (current->pwd)

123                 current->pwd->i_count++;

124         if (current->root)

125                 current->root->i_count++;

126         if (current->executable)

127                 current->executable->i_count++;

128         if (current->library)

129                 current->library->i_count++;

    // �����GDT��������������TSS�κ�LDT����������������ε��޳��������ó�104

    // �ֽڡ��μ� include/asm/system.h��52��66 �д��롣 Ȼ�����ý���֮��Ĺ�ϵ����

    // ָ�룬�����½��̲��뵽��ǰ���̵��ӽ��������С����½��̵ĸ���������Ϊ��ǰ���̣�

    // ���½��̵������ӽ���ָ��p_cptr �������ֵܽ���ָ��p_ysptr�ÿա��������½���

    // �����ֽ���ָ��p_osptr���õ��ڸ����̵������ӽ���ָ�롣����ǰ����ȴ�ǻ�������

    // �ӽ��̣����ñ������ֽ��̵����������ָ��p_yspter ָ���½��̡����ѵ�ǰ����

    // �������ӽ���ָ��ָ������½��̡�Ȼ����½������óɾ���̬����󷵻��½��̺š�

    // ���⣬ set_tss_desc() �� set_ldt_desc() ������ include/asm/system.h �ļ��С�

    // ��gdt+(nr<<1)+FIRST_TSS_ENTRY��������nr��TSS����������ȫ�ֱ��еĵ�ַ����Ϊ

    // ÿ������ռ��GDT����2������ʽ��Ҫ����'(nr<<1)'��

    // ��ע�⣬�������л�ʱ������Ĵ���tr����CPU�Զ����ء�

130         set_tss_desc(gdt+(nr<<1)+FIRST_TSS_ENTRY,&(p->tss));

131         set_ldt_desc(gdt+(nr<<1)+FIRST_LDT_ENTRY,&(p->ldt));

132         p->p_pptr = current;               // �����½��̵ĸ�����ָ�롣

133         p->p_cptr = 0;                     // ��λ�½��̵������ӽ���ָ�롣

134         p->p_ysptr = 0;                    // ��λ�½��̵ı��������ֵܽ���ָ�롣

135         p->p_osptr = current->p_cptr;      // �����½��̵ı��������ֵܽ���ָ�롣

136         if (p->p_osptr)                    // ���½����������ֵܽ��̣�������

137                 p->p_osptr->p_ysptr = p;   // ��������ֵ�ָ��ָ���½��̡�

138         current->p_cptr = p;               // �õ�ǰ���������ӽ���ָ��ָ���½��̡�

139         p->state = TASK_RUNNING;        /* do this last, just in case */

140         return last_pid;

141 }

142

    // Ϊ�½���ȡ�ò��ظ��Ľ��̺�last_pid���������������������е������(������)��

143 int find_empty_process(void)

144 {

145         int i;

146

    // ���Ȼ�ȡ�µĽ��̺š����last_pid��1�󳬳����̺ŵ�������ʾ��Χ�������´�1��ʼ

    // ʹ��pid�š� Ȼ�����������������������õ�pid���Ƿ��Ѿ����κ�����ʹ�á��������

    // ��ת��������ʼ�����»��һ��pid�š� ����������������Ϊ������Ѱ��һ���������

    // ������š� last_pid��һ��ȫ�ֱ��������÷��ء������ʱ����������64�����Ѿ���ȫ

    // ��ռ�ã��򷵻س����롣

147         repeat:

148                 if ((++last_pid)<0) last_pid=1;

149                 for(i=0 ; i<NR_TASKS ; i++)

150                         if (task[i] && ((task[i]->pid == last_pid) ||

151                                         (task[i]->pgrp == last_pid)))

152                                 goto repeat;

153         for(i=1 ; i<NR_TASKS ; i++)             // ����0��ų����⡣

154                 if (!task[i])

155                         return i;

156         return -EAGAIN;

157 }

158


 


 

8.9 ����8-9 linux/kernel/sys.c����


  1 /*

  2  *  linux/kernel/sys.c

  3  *

  4  *  (C) 1991  Linus Torvalds

  5  */

  6

  7 #include <errno.h>        // �����ͷ�ļ�������ϵͳ�и��ֳ����š�

  8

  9 #include <linux/sched.h>  // ���ȳ���ͷ�ļ�������������ṹtask_struct������0�����ݣ�

                              // ����һЩ�й��������������úͻ�ȡ��Ƕ��ʽ��ຯ������䡣

 10 #include <linux/tty.h>    // ttyͷ�ļ����������й�tty_io������ͨ�ŷ���IJ�����������

 11 #include <linux/kernel.h> // �ں�ͷ�ļ�������һЩ�ں˳��ú�����ԭ�ζ��塣

 12 #include <linux/config.h> // �ں˳��������ļ���������Ҫʹ�����е�ϵͳ���Ƴ���������Ϣ��

 13 #include <asm/segment.h>  // �β���ͷ�ļ����������йضμĴ���������Ƕ��ʽ��ຯ����

 14 #include <sys/times.h>    // �����˽���������ʱ��Ľṹtms�Լ�times()����ԭ�͡�

 15 #include <sys/utsname.h>  // ϵͳ���ƽṹͷ�ļ���

 16 #include <sys/param.h>    // ϵͳ����ͷ�ļ�������ϵͳһЩȫ�ֳ������š�����HZ�ȡ�

 17 #include <sys/resource.h> // ϵͳ��Դͷ�ļ��������йؽ�����Դʹ������Ľṹ����Ϣ��

 18 #include <string.h>       // �ַ���ͷ�ļ����ַ������ڴ��ֽ����в���������

 19

 20 /*

 21  * The timezone where the local system is located.  Used as a default by some

 22  * programs who obtain this value by using gettimeofday.

 23  */

    /*

     * ��ϵͳ���ڵ�ʱ����timezone������ΪijЩ����ʹ��gettimeofdayϵͳ���û�ȡ

     * ʱ����Ĭ��ֵ��

     */

    // ʱ���ṹtimezone��1���ֶΣ�tz_minuteswest����ʾ��������α�׼ʱ��GMT�����ķ���

    // ������2���ֶΣ�tz_dsttime��������ʱDST��Daylight Savings Time���������͡� �ýṹ

    // ������include/sys/time.h�С�

 24 struct timezone sys_tz = { 0, 0};

 25

    // ���ݽ������pgrpȡ�ý����������Ự��session���š��ú�����kernel/exit.c��ʵ�֡�

 26 extern int session_of_pgrp(int pgrp);

 27

    // �������ں�ʱ�䣨ftime �C Fetch time����

    // ���·���ֵ��-ENOSYS��ϵͳ���ú�������ʾ�ڱ��汾�ں��л�δʵ�֡�

 28 int sys_ftime()

 29 {

 30         return -ENOSYS;

 31 }

 32

 33 int sys_break()

 34 {

 35         return -ENOSYS;

 36 }

 37

    // ���ڵ�ǰ���̶��ӽ��̽��е���(debugging)��

 38 int sys_ptrace()

 39 {

 40         return -ENOSYS;

 41 }

 42

    // �ı䲢��ӡ�ն������á�

 43 int sys_stty()

 44 {

 45         return -ENOSYS;

 46 }

 47

    // ȡ�ն���������Ϣ��

 48 int sys_gtty()

 49 {

 50         return -ENOSYS;

 51 }

 52

    // �޸��ļ�����

 53 int sys_rename()

 54 {

 55         return -ENOSYS;

 56 }

 57

 58 int sys_prof()

 59 {

 60         return -ENOSYS;

 61 }

 62

 63 /*

 64  * This is done BSD-style, with no consideration of the saved gid, except

 65  * that if you set the effective gid, it sets the saved gid too.  This

 66  * makes it possible for a setgid program to completely drop its privileges,

 67  * which is often a useful assertion to make when you are doing a security

 68  * audit over a program.

 69  *

 70  * The general idea is that a program which uses just setregid() will be

 71  * 100% compatible with BSD.  A program which uses just setgid() will be

 72  * 100% compatible with POSIX w/ Saved ID's.

 73  */

    /*

     * ������BSD��ʽ��ʵ�֣�û�п��DZ����gid��saved gid��sgid�������˵���

     * ��������Ч��gid��effective gid��egid��ʱ�������gidҲ�ᱻ���á���ʹ

     * ��һ��ʹ��setgid�ij��������ȫ��������Ȩ�������ڶ�һ��������а�ȫ��

     * ��ʱ����ͨ����һ�ֺܺõĴ���������

     *

     * ������Ŀ�����һ��ʹ��setregid()�ij��򽫻���BSDϵͳ100%�ļ��ݡ���һ

     * ��ʹ��setgid()�ͱ����gid�ij��򽫻���POSIX 100%�ļ��ݡ�

     */

    // ���õ�ǰ�����ʵ���Լ�/������Ч��ID��gid�����������û�г����û���Ȩ����ôֻ�ܻ�

    // ����ʵ����ID ����Ч�� ID�����������г����û���Ȩ����������������Ч�ĺ�ʵ�ʵ���

    // ID��������gid��saved gid�������ó�����Чgid��ʵ����ID��ָ���̵�ǰ��gid��

 74 int sys_setregid(int rgid, int egid)

 75 {

 76         if (rgid>0) {

 77                 if ((current->gid == rgid) ||

 78                     suser())

 79                         current->gid = rgid;

 80                 else

 81                         return(-EPERM);

 82         }

 83         if (egid>0) {

 84                 if ((current->gid == egid) ||

 85                     (current->egid == egid) ||

 86                     suser()) {

 87                         current->egid = egid;

 88                         current->sgid = egid;

 89                 } else

 90                         return(-EPERM);

 91         }

 92         return 0;

 93 }

 94

 95 /*

 96  * setgid() is implemeneted like SysV w/ SAVED_IDS

 97  */

    /*

     * setgid()��ʵ�������SAVED_IDS��SYSV��ʵ�ַ������ơ�

     */

    // ���ý������(gid)���������û�г����û���Ȩ��������ʹ�� setgid() ������Чgid

    // ��effective gid������Ϊ���䱣��gid(saved gid)����ʵ��gid(real gid)���������

    // �г����û���Ȩ����ʵ��gid����Чgid�ͱ���gid�������óɲ���ָ����gid��

 98 int sys_setgid(int gid)

 99 {

100         if (suser())

101                 current->gid = current->egid = current->sgid = gid;

102         else if ((gid == current->gid) || (gid == current->sgid))

103                 current->egid = gid;

104         else

105                 return -EPERM;

106         return 0;

107 }

108

    // �򿪻�رս��̼��ʹ��ܡ�

109 int sys_acct()

110 {

111         return -ENOSYS;

112 }

113

    // ӳ�����������ڴ浽���̵������ַ�ռ䡣

114 int sys_phys()

115 {

116         return -ENOSYS;

117 }

118

119 int sys_lock()

120 {

121         return -ENOSYS;

122 }

123

124 int sys_mpx()

125 {

126         return -ENOSYS;

127 }

128

129 int sys_ulimit()

130 {

131         return -ENOSYS;

132 }

133

    // ���ش� 1970��1��1��00:00:00 GMT ��ʼ��ʱ��ʱ��ֵ���룩�����tloc��Ϊnull��

    // ��ʱ��ֵҲ�洢�����

    // ���ڲ�����һ��ָ�룬������ָλ�����û��ռ䣬�����Ҫʹ�ú��� put_fs_long() ��

    // ���ʸ�ֵ���ڽ����ں�������ʱ���μĴ���fs��Ĭ�ϵ�ָ��ǰ�û����ݿռ䡣��˸�

    // �����Ϳ�����fs�������û��ռ��е�ֵ��

134 int sys_time(long * tloc)

135 {

136         int i;

137

138         i = CURRENT_TIME;

139         if (tloc) {

140                 verify_area(tloc,4);       // ��֤�ڴ������Ƿ񹻣�������4�ֽڣ���

141                 put_fs_long(i,(unsigned long *)tloc);   // �����û����ݶ�tloc����

142         }

143         return i;

144 }

145

146 /*

147  * Unprivileged users may change the real user id to the effective uid

148  * or vice versa.  (BSD-style)

149  *

150  * When you set the effective uid, it sets the saved uid too.  This

151  * makes it possible for a setuid program to completely drop its privileges,

152  * which is often a useful assertion to make when you are doing a security

153  * audit over a program.

154  *

155  * The general idea is that a program which uses just setreuid() will be

156  * 100% compatible with BSD.  A program which uses just setuid() will be

157  * 100% compatible with POSIX w/ Saved ID's.

158  */

    /*

     * ����Ȩ���û����Լ�ʵ�ʵ�uid��real uid���ij���Ч��uid��effective uid����

     * ��֮ҲȻ����BSD��ʽ��ʵ�֣�

     *

     * ����������Ч��uid ʱ����ͬʱҲ�����˱���� uid����ʹ��һ��ʹ�� setuid

     * �ij��������ȫ��������Ȩ�������ڶ�һ��������а�ȫ���ʱ����ͨ����һ��

     * �ܺõĴ���������

     * ������Ŀ�����һ��ʹ�� setreuid()�ij��򽫻��� BSDϵͳ100%�ļ��ݡ���һ

     * ��ʹ��setuid()�ͱ����gid�ij��򽫻���POSIX 100%�ļ��ݡ�

     */

    // ���������ʵ���Լ�/������Ч���û�ID��uid�����������û�г����û���Ȩ����ôֻ��

    // ������ʵ�ʵ�uid ����Ч��uid�����������г����û���Ȩ����������������Ч�ĺ�ʵ

    // �ʵ��û�ID�������uid��saved uid�������ó�����Чuidֵͬ��

159 int sys_setreuid(int ruid, int euid)

160 {

161         int old_ruid = current->uid;

162        

163         if (ruid>0) {

164                 if ((current->euid==ruid) ||

165                     (old_ruid == ruid) ||

166                     suser())

167                         current->uid = ruid;

168                 else

169                         return(-EPERM);

170         }

171         if (euid>0) {

172                 if ((old_ruid == euid) ||

173                     (current->euid == euid) ||

174                     suser()) {

175                         current->euid = euid;

176                         current->suid = euid;

177                 } else {

178                         current->uid = old_ruid;

179                         return(-EPERM);

180                 }

181         }

182         return 0;

183 }

184

185 /*

186  * setuid() is implemeneted like SysV w/ SAVED_IDS

187  *

188  * Note that SAVED_ID's is deficient in that a setuid root program

189  * like sendmail, for example, cannot set its uid to be a normal

190  * user and then switch back, because if you're root, setuid() sets

191  * the saved uid too.  If you don't like this, blame the bright people

192  * in the POSIX commmittee and/or USG.  Note that the BSD-style setreuid()

193  * will allow a root program to temporarily drop privileges and be able to

194  * regain them by swapping the real and effective uid. 

195  */

    /*

     * setuid()��ʵ�������SAVED_IDS��SYSV��ʵ�ַ������ơ�

     *

     * ��ע��ʹ��SAVED_ID��setuid()��ijЩ�����Dz����Ƶġ����磬һ��ʹ��

     * setuid�ij����û�����sendmail������������uid���ó�һ����ͨ�û���

     * uid��Ȼ���ٽ��������� ��Ϊ�������һ�������û���setuid() Ҳͬʱ��

     * ���ñ����uid������㲻ϲ�������������Ļ��������POSIX��ί���Լ�

     * /����USG�еĴ����˰ɡ�������ע��BSD��ʽ��setreuid()ʵ���ܹ�����

     * һ�������û�������ʱ������Ȩ��������ͨ������ʵ�ʵĺ���Ч�� uid ��

     * �ٴλ����Ȩ��

     */

    // ���������û�ID��uid�����������û�г����û���Ȩ��������ʹ��setuid()������Ч��

    // uid��effective uid�����ó��䱣���uid��saved uid������ʵ�ʵ�uid��real uid����

    // ��������г����û���Ȩ����ʵ�ʵ�uid����Ч��uid�ͱ����uid���ᱻ���óɲ���ָ

    // ����uid��

196 int sys_setuid(int uid)

197 {

198         if (suser())

199                 current->uid = current->euid = current->suid = uid;

200         else if ((uid == current->uid) || (uid == current->suid))

201                 current->euid = uid;

202         else

203                 return -EPERM;

204         return(0);

205 }

206

    // ����ϵͳ����ʱ�䡣����tptr�Ǵ�1970��1��1��00:00:00 GMT��ʼ��ʱ��ʱ��ֵ���룩��

    // ���ý��̱�����г����û�Ȩ�ޡ�����HZ=100�����ں�ϵͳ����Ƶ�ʡ�

    // ���ڲ�����һ��ָ�룬������ָλ�����û��ռ䣬�����Ҫʹ�ú���get_fs_long()�����ʸ�

    // ֵ���ڽ����ں�������ʱ���μĴ��� fs ��Ĭ�ϵ�ָ��ǰ�û����ݿռ䡣��˸ú����Ϳ���

    // ��fs�������û��ռ��е�ֵ��

    // ���������ṩ�ĵ�ǰʱ��ֵ��ȥϵͳ�Ѿ����е�ʱ����ֵ��jiffies/HZ�����ǿ���ʱ����ֵ��

207 int sys_stime(long * tptr)

208 {

209         if (!suser())                // ������dz����û���������أ����ɣ���

210                 return -EPERM;

211         startup_time = get_fs_long((unsigned long *)tptr) - jiffies/HZ;

212         jiffies_offset = 0;

213         return 0;

214 }

215

    // ��ȡ��ǰ��������ʱ��ͳ��ֵ��

    // ��tbuf��ָ�û����ݿռ䴦����tms�ṹ����������ʱ��ͳ��ֵ��tms�ṹ�а��������û�

    // ����ʱ�䡢�ںˣ�ϵͳ��ʱ�䡢�ӽ����û�����ʱ�䡢�ӽ���ϵͳ����ʱ�䡣��������ֵ��

    // ϵͳ���е���ǰ���������

216 int sys_times(struct tms * tbuf)

217 {

218         if (tbuf) {

219                 verify_area(tbuf,sizeof *tbuf);

220                 put_fs_long(current->utime,(unsigned long *)&tbuf->tms_utime);

221                 put_fs_long(current->stime,(unsigned long *)&tbuf->tms_stime);

222                 put_fs_long(current->cutime,(unsigned long *)&tbuf->tms_cutime);

223                 put_fs_long(current->cstime,(unsigned long *)&tbuf->tms_cstime);

224         }

225         return jiffies;

226 }

227

    // ������end_data_seg��ֵ����������ϵͳȷʵ���㹻���ڴ棬���ҽ���û�г�Խ���������

    // �δ�Сʱ���ú����������ݶ�ĩβΪend_data_segָ����ֵ����ֵ������ڴ����β����Ҫ

    // С�ڶ�ջ��β16KB������ֵ�����ݶε��½�βֵ���������ֵ��Ҫ��ֵ��ͬ��������д���

    // ���������ú����������û�ֱ�ӵ��ã�����libc�⺯�����а�װ�����ҷ���ֵҲ��һ����

228 int sys_brk(unsigned long end_data_seg)

229 {

    // �������ֵ���ڴ����β������С�ڣ���ջ - 16KB���������������ݶν�βֵ��

230         if (end_data_seg >= current->end_code &&

231             end_data_seg < current->start_stack - 16384)

232                 current->brk = end_data_seg;

233         return current->brk;              // ���ؽ��̵�ǰ�����ݶν�βֵ��

234 }

235

236 /*

237  * This needs some heave checking ...

238  * I just haven't get the stomach for it. I also don't fully

239  * understand sessions/pgrp etc. Let somebody who does explain it.

240  *

241  * OK, I think I have the protection semantics right.... this is really

242  * only important on a multi-user system anyway, to make sure one user

243  * can't send a signal to a process owned by another.  -TYT, 12/12/91

244  */

    /*

     * ���������ҪijЩ�ϸ�ļ����

     * ��ֻ��û��θ��������Щ����Ҳ����ȫ����sessions/pgrp�ȵĺ��塣������

     * �˽����ǵ��������ɡ�

     *

     * OK���������Ѿ���ȷ��ʵ���˱�������...����֮������ʵֻ�Զ��û�ϵͳ��

     * ��Ҫ�ģ���ȷ��һ���û������������û��Ľ��̷����źš� -TYT 12/12/91

     */

    // ����ָ������pid�Ľ������Ϊpgid��

    // ����pid ��ָ�����̵Ľ��̺š������Ϊ0������pid���ڵ�ǰ���̵Ľ��̺š�����pgid

    // ��ָ���Ľ�����š������Ϊ0�����������ڽ���pid�Ľ�����š�����ú������ڽ�����

    // ��һ���������Ƶ���һ�������飬���������������������ͬһ���Ự(session)��������

    // ����£�����pgid ָ����Ҫ��������н�����ID����ʱ����ĻỰID�����뽫Ҫ�����

    // �̵���ͬ(263��)��

245 int sys_setpgid(int pid, int pgid)

246 {

247         int i;

248

    // �������pidΪ0����pidȡֵΪ��ǰ���̵Ľ��̺�pid���������pgidΪ0����pgidҲ

    // ȡֵΪ��ǰ���̵�pid��[?? ������POSIX��׼�������г��� ]���� pgidС��0���򷵻�

    // ��Ч�����롣

249         if (!pid)

250                 pid = current->pid;

251         if (!pgid)

252                 pgid = current->pid;

253         if (pgid < 0)

254                 return -EINVAL;

    // ɨ���������飬����ָ�����̺� pid ����������ҵ��˽��̺���pid �Ľ��̣����Ҹý���

    // �ĸ����̾��ǵ�ǰ���̻��߸ý��̾��ǵ�ǰ���̣���ô���������Ѿ��ǻỰ���죬��������ء�

    // ��������ĻỰ�ţ�session���뵱ǰ���̵IJ�ͬ������ָ���Ľ������pgid��pid��ͬ����

    // pgid �����������Ự���뵱ǰ���������Ự�Ų�ͬ����Ҳ�������ء� ����Ѳ��ҵ��Ľ��̵�

    // pgrp����Ϊpgid��������0����û���ҵ�ָ��pid�Ľ��̣��򷵻ؽ��̲����ڳ����롣

255         for (i=0 ; i<NR_TASKS ; i++)

256                 if (task[i] && (task[i]->pid == pid) &&

257                     ((task[i]->p_pptr == current) ||

258                      (task[i] == current))) {

259                         if (task[i]->leader)

260                                 return -EPERM;

261                         if ((task[i]->session != current->session) ||

262                             ((pgid != pid) &&

263                              (session_of_pgrp(pgid) != current->session)))

264                                 return -EPERM;

265                         task[i]->pgrp = pgid;

266                         return 0;

267                 }

268         return -ESRCH;

269 }

270

    // ���ص�ǰ���̵Ľ�����š���getpgid(0)��ͬ��

271 int sys_getpgrp(void)

272 {

273         return current->pgrp;

274 }

275

    // ����һ���Ự(session)����������leader=1��������������Ự��=�����=����̺š�

    // �����ǰ�������ǻỰ���첢�Ҳ��dz����û�����������ء��������õ�ǰ����Ϊ�»Ự

    // ���죨leader = 1�����������õ�ǰ���̻Ự�� session�����pgrp�����ڽ��̺�pid��

    // �������õ�ǰ����û�п����նˡ����ϵͳ���÷��ػỰ�š�

276 int sys_setsid(void)

277 {

278         if (current->leader && !suser())

279                 return -EPERM;

280         current->leader = 1;

281         current->session = current->pgrp = current->pid;

282         current->tty = -1;                   // ��ʾ��ǰ����û�п����նˡ�

283         return current->pgrp;

284 }

285

286 /*

287  * Supplementary group ID's

288  */

    /*

     * ���̵������û���š�

     */

    // ȡ��ǰ�������������û���š�

    // �������ݽṹ��groups[]���鱣���Ž���ͬʱ�����Ķ���û���š������鹲NGROUPS���

    // ��ij���ֵ��NOGROUP����Ϊ -1�������ʾ�Ӹ��ʼ�Ժ���������С������������б�

    // ������û���š�

    // ����gidsetsize�ǻ�ȡ���û���Ÿ�����grouplist�Ǵ洢��Щ�û���ŵ��û��ռ仺�档

289 int sys_getgroups(int gidsetsize, gid_t *grouplist)

290 {

291         int     i;

292

    // ������֤grouplistָ����ָ���û�����ռ��Ƿ��㹻��Ȼ��ӵ�ǰ���̽ṹ��groups[]

    // ���������ȡ���û���Ų����Ƶ��û������С��ڸ��ƹ����У���� groups[] �е�����

    // ���ڸ����IJ��� gidsetsize ��ָ���ĸ��������ʾ�û������Ļ���̫С���������µ�ǰ

    // ����������ţ���˴˴�ȡ��Ų�����������ء������ƹ����������������᷵�ظ�

    // �Ƶ��û���Ÿ�������gidsetsize �C gid set size���û���ż���С����

293         if (gidsetsize)

294                 verify_area(grouplist, sizeof(gid_t) * gidsetsize);

295

296         for (i = 0; (i < NGROUPS) && (current->groups[i] != NOGROUP);

297              i++, grouplist++) {

298                 if (gidsetsize) {

299                         if (i >= gidsetsize)

300                                 return -EINVAL;

301                         put_fs_word(current->groups[i], (short *) grouplist);

302                 }

303         }

304         return(i);             // ����ʵ�ʺ��е��û���Ÿ�����

305 }

306

    // ���õ�ǰ����ͬʱ���������������û���š�

    // ����gidsetsize�ǽ����õ��û���Ÿ�����grouplist�Ǻ����û���ŵ��û��ռ仺�档

307 int sys_setgroups(int gidsetsize, gid_t *grouplist)

308 {

309         int     i;

310

    // ���Ȳ�Ȩ�޺Ͳ�������Ч�ԡ�ֻ�г����û������޸Ļ����õ�ǰ���̵ĸ����û���ţ�����

    // ���õ��������ܳ������̵�groups[NGROUPS]�����������Ȼ����û���������������û�

    // ��ţ���gidsetsize����������Ƶĸ���û������groups[]���������һ��������ֵΪ-1

    // ���NOGROUP�������������0��

311         if (!suser())

312                 return -EPERM;

313         if (gidsetsize > NGROUPS)

314                 return -EINVAL;

315         for (i = 0; i < gidsetsize; i++, grouplist++) {

316                 current->groups[i] = get_fs_word((unsigned short *) grouplist);

317         }

318         if (i < NGROUPS)

319                 current->groups[i] = NOGROUP;

320         return 0;

321 }

322

    // ��鵱ǰ�����Ƿ���ָ�����û���grp�С����򷵻�1�����򷵻�0��

323 int in_group_p(gid_t grp)

324 {

325         int     i;

326

    // �����ǰ���̵���Ч��ž���grp�����ʾ��������grp�����顣��������1���������

    // ���̵ĸ����û���������ɨ���Ƿ��� grp ������š���������Ҳ����1����ɨ�赽ֵ

    // Ϊ NOGROUP �����ʾ��ɨ����ȫ����Ч���û�з���ƥ�����ţ���˺�������0��

327         if (grp == current->egid)

328                 return 1;

329

330         for (i = 0; i < NGROUPS; i++) {

331                 if (current->groups[i] == NOGROUP)

332                         break;

333                 if (current->groups[i] == grp)

334                         return 1;

335         }

336         return 0;

337 }

338

    // utsname�ṹ����һЩ�ַ����ֶΡ����ڱ���ϵͳ�����ơ����а���5���ֶΣ��ֱ��ǣ�

    // ��ǰ����ϵͳ�����ơ�����ڵ����ƣ�������������ǰ����ϵͳ���м��𡢲���ϵͳ�汾

    // ���Լ�ϵͳ���е�Ӳ���������ơ��ýṹ������ include/sys/utsname.h �ļ��С� ����

    // �ں�ʹ�� include/linux/config.h �ļ��еij����������������ǵ�Ĭ��ֵ�����Ƿֱ�Ϊ

    // ��Linux������(none)������0������0.12������i386����

339 static struct utsname thisname = {

340         UTS_SYSNAME, UTS_NODENAME, UTS_RELEASE, UTS_VERSION, UTS_MACHINE

341 };

342

    // ��ȡϵͳ���Ƶ���Ϣ��

343 int sys_uname(struct utsname * name)

344 {

345         int i;

346

347         if (!name) return -ERROR;

348         verify_area(name,sizeof *name);

349         for(i=0;i<sizeof *name;i++)

350                 put_fs_byte(((char *) &thisname)[i],i+(char *) name);

351         return 0;

352 }

353

354 /*

355  * Only sethostname; gethostname can be implemented by calling uname()

356  */

    /*

     * ͨ������uname()ֻ��ʵ��sethostname��gethostname��

     */

    // ����ϵͳ��������ϵͳ������ڵ�������

    // ����nameָ��ָ���û��������к����������ַ����Ļ�������len���������ַ������ȡ�

357 int sys_sethostname(char *name, int len)

358 {

359         int     i;

360        

    // ϵͳ������ֻ���ɳ����û����û��޸ģ��������������Ȳ��ܳ�����󳤶�MAXHOSTNAMELEN��

361         if (!suser())

362                 return -EPERM;

363         if (len > MAXHOSTNAMELEN)

364                 return -EINVAL;

365         for (i=0; i < len; i++) {

366                 if ((thisname.nodename[i] = get_fs_byte(name+i)) == 0)

367                         break;

368         }

    // �ڸ�����Ϻ�����û��ṩ���ַ�����û�а���NULL�ַ�����ô�����Ƶ����������Ȼ�û��

    // ���� MAXHOSTNAMELEN�������������ַ���������һ��NULL�����Ѿ����� MAXHOSTNAMELEN����

    // ����������һ���ַ��ij�NULL�ַ�����thisname.nodename[min(i,MAXHOSTNAMELEN)] = 0��

369         if (thisname.nodename[i]) {

370                 thisname.nodename[i>MAXHOSTNAMELEN ? MAXHOSTNAMELEN : i] = 0;

371         }

372         return 0;

373 }

374

    // ȡ��ǰ����ָ����Դ�Ľ���ֵ��

    // ���̵�����ṹ�ж�����һ������rlim[RLIM_NLIMITS]�����ڿ��ƽ���ʹ��ϵͳ��Դ�Ľ��ޡ�

    // ����ÿ������һ��rlimit �ṹ�����а��������ֶΡ� һ��˵�����̶�ָ����Դ�ĵ�ǰ����

    // ���ޣ�soft limit���������ƣ�����һ��˵��ϵͳ��ָ����Դ��������ƽ��ޣ�hard limit��

    // ��Ӳ���ƣ��� rlim[] �����ÿһ���Ӧϵͳ�Ե�ǰ����һ����Դ�Ľ�����Ϣ��Linux 0.12

    // ϵͳ����6����Դ�涨�˽��ޣ���RLIM_NLIMITS=6����ο�ͷ�ļ�include/sys/resource.h

    // �е�41 �� 46�е�˵����

    // ���� resource ָ��������ѯ����Դ���ƣ�ʵ������������ṹ��rlim[]�����������ֵ��

    // ����rlim��ָ��rlimit�ṹ���û�������ָ�룬���ڴ��ȡ�õ���Դ������Ϣ��

375 int sys_getrlimit(int resource, struct rlimit *rlim)

376 {

    // ����ѯ����Դresourceʵ�����ǽ�������ṹ��rlim[]�����������ֵ��������ֵ��Ȼ����

    // ���������������� RLIM_NLIMITS������֤�� rlim ָ����ָ�û������㹻�Ժ�����Ͱ�

    // ����ָ������Դresource�ṹ��Ϣ���Ƶ��û������У�������0��

377         if (resource >= RLIM_NLIMITS)

378                 return -EINVAL;

379         verify_area(rlim,sizeof *rlim);

380         put_fs_long(current->rlim[resource].rlim_cur,       // ��ǰ����������ֵ��

381                     (unsigned long *) rlim);

382         put_fs_long(current->rlim[resource].rlim_max,       // ϵͳ��Ӳ������ֵ��

383                     ((unsigned long *) rlim)+1);

384         return 0;      

385 }

386

    // ���õ�ǰ����ָ����Դ�Ľ���ֵ��

    // ���� resource ָ���������ý��޵���Դ���ƣ�ʵ������������ṹ��rlim[]���������

    // ��ֵ������rlim��ָ��rlimit�ṹ���û�������ָ�룬�����ں˶�ȡ�µ���Դ������Ϣ��

387 int sys_setrlimit(int resource, struct rlimit *rlim)

388 {

389         struct rlimit new, *old;

390

    // �����жϲ���resource������ṹrlim[]������ֵ����Ч�ԡ�Ȼ������rlimit�ṹָ��

    // oldָ��ָ��������ṹ��ָ����Դ�ĵ�ǰrlimit�ṹ��Ϣ�����Ű��û��ṩ����Դ����

    // ��Ϣ���Ƶ���ʱrlimit�ṹnew�С���ʱ����жϳ�new�ṹ�е�������ֵ��Ӳ����ֵ

    // ���ڽ��̸���ԴԭӲ����ֵ�����ҵ�ǰ���dz����û��Ļ����ͷ������ɴ��������ʾnew

    // ����Ϣ�������߽����dz����û����̣����޸�ԭ����ָ����Դ��Ϣ����new�ṹ�е���Ϣ��

    // ���ɹ�����0��

391         if (resource >= RLIM_NLIMITS)

392                 return -EINVAL;

393         old = current->rlim + resource;        // ��old = current->rlim[resource]��

394         new.rlim_cur = get_fs_long((unsigned long *) rlim);

395         new.rlim_max = get_fs_long(((unsigned long *) rlim)+1);

396         if (((new.rlim_cur > old->rlim_max) ||

397              (new.rlim_max > old->rlim_max)) &&

398             !suser())

399                 return -EPERM;

400         *old = new;

401         return 0;

402 }

403

404 /*

405  * It would make sense to put struct rusuage in the task_struct,

406  * except that would make the task_struct be *really big*.  After

407  * task_struct gets moved into malloc'ed memory, it would

408  * make sense to do this.  It will make moving the rest of the information

409  * a lot simpler!  (Which we're not doing right now because we're not

410  * measuring them yet).

411  */

    /*

     * ��rusuage�ṹ�Ž�����ṹtask struct����ǡ���ģ���������ʹ����

     * �ṹ���ȱ�÷dz����ڰ�����ṹ�����ں�malloc������ڴ���֮��

     * ��������ʹ����ṹ�ܴ�Ҳû�����ˡ��⽫ʹ��������Ϣ���ƶ���÷dz�

     * ���㣡�����ǻ�û������������Ϊ���ǻ�û�в��Թ����ǵĴ�С����

     */

    // ��ȡָ�����̵���Դ������Ϣ��

    // ��ϵͳ�����ṩ��ǰ���̻�������ֹ�ĺ͵ȴ��ŵ��ӽ�����Դʹ��������������who����

    // RUSAGE_SELF���򷵻ص�ǰ���̵���Դ������Ϣ�����ָ������who �� RUSAGE_CHILDREN��

    // �򷵻ص�ǰ���̵�����ֹ�͵ȴ��ŵ��ӽ�����Դ������Ϣ�� ���ų���RUSAGE_SELF ��

    // RUSAGE_CHILDREN �Լ� rusage�ṹ�������� include/sys/resource.hͷ�ļ��С�

412 int sys_getrusage(int who, struct rusage *ru)

413 {

414         struct rusage r;

415         unsigned long   *lp, *lpend, *dest;

416

    // �����жϲ���ָ�����̵���Ч�ԡ����who�Ȳ���RUSAGE_SELF��ָ����ǰ���̣���Ҳ����

    // RUSAGE_CHILDREN ��ָ���ӽ��̣���������Ч�����뷵�ء���������֤��ָ��ru ָ������

    // ����������󣬰���ʱ rusage�ṹ����r���㡣

417         if (who != RUSAGE_SELF && who != RUSAGE_CHILDREN)

418                 return -EINVAL;

419         verify_area(ru, sizeof *ru);

420         memset((char *) &r, 0, sizeof(r));      // ��include/strings.h�ļ����

    // ������who ��RUSAGE_SELF�����Ƶ�ǰ������Դ������Ϣ��r�ṹ�С���ָ������who

    // ��RUSAGE_CHILDREN�� ���Ƶ�ǰ���̵�����ֹ�͵ȴ��ŵ��ӽ�����Դ������Ϣ����ʱ

    // rusuage�ṹr�С���CT_TO_SECS ��CT_TO_USECS���ڰ�ϵͳ��ǰ�����ת��������ֵ

    // ��΢��ֵ��ʾ�����Ƕ����� include/linux/sched.h �ļ��С� jiffies_offset��ϵͳ

    // ���������������

421         if (who == RUSAGE_SELF) {

422                 r.ru_utime.tv_sec = CT_TO_SECS(current->utime);

423                 r.ru_utime.tv_usec = CT_TO_USECS(current->utime);

424                 r.ru_stime.tv_sec = CT_TO_SECS(current->stime);

425                 r.ru_stime.tv_usec = CT_TO_USECS(current->stime);

426         } else {

427                 r.ru_utime.tv_sec = CT_TO_SECS(current->cutime);

428                 r.ru_utime.tv_usec = CT_TO_USECS(current->cutime);

429                 r.ru_stime.tv_sec = CT_TO_SECS(current->cstime);

430                 r.ru_stime.tv_usec = CT_TO_USECS(current->cstime);

431         }

    // Ȼ����lpָ��ָ��r�ṹ��lpendָ��r�ṹĩβ������destָ��ָ���û��ռ��е�ru

    // �ṹ������r����Ϣ���Ƶ��û��ռ�ru�ṹ�У�������0��

432         lp = (unsigned long *) &r;

433         lpend = (unsigned long *) (&r+1);

434         dest = (unsigned long *) ru;

435         for (; lp < lpend; lp++, dest++)

436                 put_fs_long(*lp, dest);

437         return(0);

438 }

439

    // ȡ��ϵͳ��ǰʱ�䣬����ָ����ʽ���ء�

    // timeval�ṹ��timezone�ṹ��������include/sys/time.h�ļ��С�timeval�ṹ������

    // ��΢�루tv_sec��tv_usec�������ֶΡ�timezone�ṹ���б��ؾ�������α�׼ʱ������

    // �ķ�������tz_minuteswest��������ʱ��������ͣ�tz_dsttime�������ֶΡ�

    // ��dst -- Daylight Savings Time��

440 int sys_gettimeofday(struct timeval *tv, struct timezone *tz)

441 {

    // �������������timeval�ṹָ�벻�գ����ڸýṹ�з��ص�ǰʱ�䣨��ֵ��΢��ֵ����

    // ��������������û����ݿռ��� timezone�ṹ��ָ�벻�գ���Ҳ���ظýṹ����Ϣ��

    // ������startup_time��ϵͳ����ʱ�䣨��ֵ���� ��CT_TO_SECS��CT_TO_USECS����

    // ��ϵͳ��ǰ�����ת��������ֵ��΢��ֵ��ʾ�����Ƕ�����include/linux/sched.h

    // �ļ��С�jiffies_offset��ϵͳ���������������

442         if (tv) {

443                 verify_area(tv, sizeof *tv);

444                 put_fs_long(startup_time + CT_TO_SECS(jiffies+jiffies_offset),

445                             (unsigned long *) tv);

446                 put_fs_long(CT_TO_USECS(jiffies+jiffies_offset),

447                             ((unsigned long *) tv)+1);

448         }

449         if (tz) {

450                 verify_area(tz, sizeof *tz);

451                 put_fs_long(sys_tz.tz_minuteswest, (unsigned long *) tz);

452                 put_fs_long(sys_tz.tz_dsttime, ((unsigned long *) tz)+1);

453         }

454         return 0;

455 }

456

457 /*

458  * The first time we set the timezone, we will warp the clock so that

459  * it is ticking GMT time instead of local time.  Presumably,

460  * if someone is setting the timezone then we are running in an

461  * environment where the programs understand about timezones.

462  * This should be done at boot time in the /etc/rc script, as

463  * soon as possible, so that the clock can be set right.  Otherwise,

464  * various programs will get confused when the clock gets warped.

465  */

    /*

     * �ڵ�1������ʱ����timezone��ʱ�����ǻ�ı�ʱ��ֵ����ϵͳʹ�ø���

     * ���α�׼ʱ�䣨GMT�����У�����ʹ�ñ���ʱ�䡣 �Ʋ�����˵�����ij��

     * ������ʱ��ʱ�䣬��ô���Ǿ������ڳ���֪��ʱ��ʱ��Ļ����С�����ʱ

     * ������Ӧ����ϵͳ�����׶Σ��������/etc/rc�ű������н��С�����ʱ

     * �ӾͿ���������ȷ�� ����Ļ����������Ժ������ʱ��������ʱ��ʱ��

     * �ı䣬���ܻ���һЩ��������г������⡣

     */

    // ����ϵͳ��ǰʱ�䡣

    // ����tv��ָ���û���������timeval�ṹ��Ϣ��ָ�롣����tz���û���������timezone

    // �ṹ��ָ�롣�ò�����Ҫ�����û�Ȩ�ޡ�������߽�Ϊ�գ���ʲôҲ��������������0��

466 int sys_settimeofday(struct timeval *tv, struct timezone *tz)

467 {

468         static int      firsttime = 1;

469         void            adjust_clock();

470

    // ����ϵͳ��ǰʱ����Ҫ�����û�Ȩ�ޡ����tzָ�벻�գ�������ϵͳʱ����Ϣ���������û�

    // timezone�ṹ��Ϣ��ϵͳ�е� sys_tz�ṹ�У�����24�У�������ǵ�1�ε��ñ�ϵͳ����

    // ���Ҳ���tvָ�벻�գ������ϵͳʱ��ֵ��

471         if (!suser())

472                 return -EPERM;

473         if (tz) {

474                 sys_tz.tz_minuteswest = get_fs_long((unsigned long *) tz);

475                 sys_tz.tz_dsttime = get_fs_long(((unsigned long *) tz)+1);

476                 if (firsttime) {

477                         firsttime = 0;

478                         if (!tv)

479                                 adjust_clock();

480                 }

481         }

    // ���������timeval�ṹָ��tv���գ����øýṹ��Ϣ����ϵͳʱ�ӡ����ȴ�tv��ָ��

    // ��ȡ����ֵ��sec����΢��ֵ��usec����ʾ��ϵͳʱ�䣬Ȼ������ֵ�޸�ϵͳ����ʱ��ȫ��

    // ����startup_timeֵ������΢��ֵ����ϵͳ������ֵjiffies_offset��

482         if (tv) {

483                 int sec, usec;

484

485                 sec = get_fs_long((unsigned long *)tv);

486                 usec = get_fs_long(((unsigned long *)tv)+1);

487        

488                 startup_time = sec - jiffies/HZ;

489                 jiffies_offset = usec * HZ / 1000000 - jiffies%HZ;

490         }

491         return 0;

492 }

493

494 /*

495  * Adjust the time obtained from the CMOS to be GMT time instead of

496  * local time.

497  *

498  * This is ugly, but preferable to the alternatives.  Otherwise we

499  * would either need to write a program to do it in /etc/rc (and risk

500  * confusion if the program gets run more than once; it would also be

501  * hard to make the program warp the clock precisely n hours)  or

502  * compile in the timezone information into the kernel.  Bad, bad....

503  *

504  * XXX Currently does not adjust for daylight savings time.  May not

505  * need to do anything, depending on how smart (dumb?) the BIOS

506  * is.  Blast it all.... the best thing to do not depend on the CMOS

507  * clock at all, but get the time via NTP or timed if you're on a

508  * network....                          - TYT, 1/1/92

509  */

    /*

     * �Ѵ�CMOS�ж�ȡ��ʱ��ֵ����ΪGMTʱ��ֵ���棬���DZ���ʱ��ֵ��

     *

     * ��������������ţ���Ҫ�����������á��������Ǿ���Ҫдһ����������

     * ��/etc/rc��������������£�����ð�Ÿó�����ܻᱻ���ִ�ж�������

     * ���⡣ ����������Ҳ�����ó����ʱ�Ӿ�ȷ�ص���nСʱ�� ���߰�ʱ����

     * Ϣ������ں��С���Ȼ�������ͷdz����dz����...

     *

     * Ŀǰ���溯����XXX���ĵ���������û�п��ǵ�����ʱ���⡣����BIOS�ж�

     * ô���ܣ��޴�����Ҳ�������Ͳ��ÿ����ⷽ�档��Ȼ����õ���������ȫ��

     * ������CMOSʱ�ӣ�������ϵͳͨ��NTP������ʱ��Э�飩����timed��ʱ��

     * �����������ʱ�䣬��������������Ļ�...��        - TYT��1/1/92

     */

    // ��ϵͳ����ʱ�����Ϊ��GMTΪ��׼��ʱ�䡣

    // startup_time����ֵ�����������Ҫ��ʱ������ֵ����60��

510 void adjust_clock()

511 {

512         startup_time += sys_tz.tz_minuteswest*60;

513 }

514

    // ���õ�ǰ���̴����ļ�����������Ϊmask & 0777��������ԭ�����롣

515 int sys_umask(int mask)

516 {

517         int old = current->umask;

518

519         current->umask = mask & 0777;

520         return (old);

521 }

522


 


 

8.10 ����8-10 linux/kernel/vsprintf.c


  1 /*

  2  *  linux/kernel/vsprintf.c

  3  *

  4  *  (C) 1991  Linus Torvalds

  5  */

  6

  7 /* vsprintf.c -- Lars Wirzenius & Linus Torvalds. */

  8 /*

  9  * Wirzenius wrote this portably, Torvalds fucked it up :-)

 10  */

    // Lars Wirzenius��Linus�ĺ��ѣ���Helsinki��ѧʱ��ͬ��һ��칫�ҡ���1991���ļ�����Linux

    // ʱ��Linus��ʱ��C���Ի����Ǻ���Ϥ��������ʹ�ÿɱ�����б��������ܡ����Lars Wirzenius

    // ��Ϊ����д����������ں���ʾ��Ϣ�Ĵ��롣������(1998��)��������δ�������һ��bug��ֱ��

    // 1994������˷��֣������Ծ��������bug����ʹ��*��Ϊ��������ʱ�����ǵ���ָ�����������

    // ���ˡ��ڱ����������bug����Ȼ���ڣ�130�У��� ���ĸ�����ҳ��http://liw.iki.fi/liw/

 11

 12 #include <stdarg.h>       // ��׼����ͷ�ļ����Ժ����ʽ������������б�����Ҫ˵����-��

                              // ����(va_list)��������(va_start, va_arg��va_end)������

                              // vsprintf��vprintf��vfprintf������

 13 #include <string.h>       // �ַ���ͷ�ļ�����Ҫ������һЩ�й��ַ���������Ƕ�뺯����

 14

 15 /* we use this so that we can do without the ctype library */

    /* ����ʹ������Ķ��壬�������ǾͿ��Բ�ʹ��ctype���� */

 16 #define is_digit(c)     ((c) >= '0' && (c) <= '9')   // �ж��ַ�c�Ƿ�Ϊ�����ַ���

 17

    // �ú������ַ����ִ�ת�������������������ִ�ָ���ָ�룬�����ǽ����ֵ������ָ�뽫ǰ�ơ�

 18 static int skip_atoi(const char **s)

 19 {

 20         int i=0;

 21

 22         while (is_digit(**s))

 23                 i = i*10 + *((*s)++) - '0';

 24         return i;

 25 }

 26

    // ���ﶨ��ת�����͵ĸ��ַ��ų�����

 27 #define ZEROPAD 1               /* pad with zero */        /* ����� */

 28 #define SIGN    2               /* unsigned/signed long */ /* �޷���/���ų����� */

 29 #define PLUS    4               /* show plus */            /* ��ʾ�� */

 30 #define SPACE   8               /* space if plus */        /* ���Ǽӣ����ÿո� */

 31 #define LEFT    16              /* left justified */      /* ����� */

 32 #define SPECIAL 32              /* 0x */                  /* 0x */

 33 #define SMALL   64              /* use 'abcdef' instead of 'ABCDEF' */ /* ʹ��Сд��ĸ */

 34

    // �����������룺nΪ��������baseΪ�����������nΪ�̣���������ֵΪ������

    // �μ�4.5.3���й�Ƕ�������Ϣ��

 35 #define do_div(n,base) ({ \

 36 int __res; \

 37 __asm__("divl %4":"=a" (n),"=d" (__res):"0" (n),"1" (0),"r" (base)); \

 38 __res; })

 39

    // ������ת��Ϊָ�����Ƶ��ַ�����

    // ���룺num-������base-���ƣ�size-�ַ������ȣ�precision-���ֳ���(����)��type-����ѡ�

    // ���������ת�����ַ�����ָ����ַ���ĩ�˺����ָ�롣

 40 static char * number(char * str, int num, int base, int size, int precision

 41         ,int type)

 42 {

 43         char c,sign,tmp[36];

 44         const char *digits="0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";

 45         int i;

 46

    // �������typeָ����Сд��ĸ������Сд��ĸ����

    // �������ָ��Ҫ�����������߽磩�������������е������־��

    // ������ƻ���С��2�����36�����˳�������Ҳ��������ֻ�ܴ���������2-32֮�������

 47         if (type&SMALL) digits="0123456789abcdefghijklmnopqrstuvwxyz";

 48         if (type&LEFT) type &= ~ZEROPAD;

 49         if (base<2 || base>36)

 50                 return 0;

    // �������ָ��Ҫ���㣬�����ַ�����c='0'������c���ڿո��ַ���

    // �������ָ���Ǵ�������������ֵnumС��0�����÷��ű���sign=���ţ���ʹnumȡ����ֵ��

    // �����������ָ���ǼӺţ�����sign=�Ӻţ����������ʹ��ո��־��sign=�ո񣬷�����0��

 51         c = (type & ZEROPAD) ? '0' : ' ' ;

 52         if (type&SIGN && num<0) {

 53                 sign='-';

 54                 num = -num;

 55         } else

 56                 sign=(type&PLUS) ? '+' : ((type&SPACE) ? ' ' : 0);

    // �������ţ������ֵ��1��������ָ��������ת���������ʮ�����ƿ����ټ���2λ(����0x)��

    // ���ڰ˽��ƿ��ȼ�1�����ڰ˽���ת�����ǰ��һ���㣩��

 57         if (sign) size--;

 58         if (type&SPECIAL)

 59                 if (base==16) size -= 2;

 60                 else if (base==8) size--;

    // �����ֵnumΪ0������ʱ�ַ���='0'��������ݸ����Ļ�������ֵnumת�����ַ���ʽ��

 61         i=0;

 62         if (num==0)

 63                 tmp[i++]='0';

 64         else while (num!=0)

 65                 tmp[i++]=digits[do_div(num,base)];

    // ����ֵ�ַ��������ھ���ֵ���򾫶�ֵ��չΪ���ָ���ֵ��

    // ����ֵsize��ȥ���ڴ����ֵ�ַ��ĸ�����

 66         if (i>precision) precision=i;

 67         size -= precision;

 

    // ������������ʼ�γ�����Ҫ��ת�����������ʱ�����ַ���str�С�

    // ��������û������(ZEROPAD)�����루���������־������str������

    // ���ʣ�����ֵָ���Ŀո��������������λ���������š�

 68         if (!(type&(ZEROPAD+LEFT)))

 69                 while(size-->0)

 70                         *str++ = ' ';

 71         if (sign)

 72                 *str++ = sign;

    // ������ָ��������ת��������ڰ˽���ת�����ͷһλ����һ��'0'��������ʮ����������'0x'��

 73         if (type&SPECIAL)

 74                 if (base==8)

 75                         *str++ = '0';

 76                 else if (base==16) {

 77                         *str++ = '0';

 78                         *str++ = digits[33];   // 'X'��'x'

 79                 }

    // ��������û������������룩��־������ʣ������д��c�ַ���'0'��ո񣩣���51�С�

 80         if (!(type&LEFT))

 81                 while(size-->0)

 82                         *str++ = c;

    // ��ʱi������ֵnum�����ָ����������ָ���С�ھ���ֵ����str�з��루����ֵ-i����'0'��

 83         while(i<precision--)

 84                 *str++ = '0';

    // ����ֵת���õ������ַ�����str�С���i����

 85         while(i-->0)

 86                 *str++ = tmp[i];

    // ������ֵ�Դ����㣬���ʾ���ͱ�־���������־������ʣ������з���ո�

 87         while(size-->0)

 88                 *str++ = ' ';

 89         return str;    // ����ת���õ�ָ���ַ���ĩ�˺��ָ�롣

 90 }

 91

    // ���溯�����͸�ʽ��������ַ����С�

    // Ϊ�������ں���ʹ�ø�ʽ���������Linus���ں�ʵ���˸�C��׼������

    // ���в���fmt�Ǹ�ʽ�ַ�����args�Ǹ����仯��ֵ��buf������ַ�����������

    // ��μ��������б�����йظ�ʽת���ַ��Ľ��ܡ�

 92 int vsprintf(char *buf, const char *fmt, va_list args)

 93 {

 94         int len;

 95         int i;

 96         char * str;            // ���ڴ��ת�������е��ַ�����

 97         char *s;

 98         int *ip;

 99

100         int flags;              /* flags to number() */

101                                 /* number()����ʹ�õı�־ */

102         int field_width;        /* width of output field */

                                    /* ����ֶο���*/

103         int precision;          /* min. # of digits for integers; max

104                                    number of chars for from string */

                                    /* min. �������ָ�����max. �ַ������ַ����� */

105         int qualifier;          /* 'h', 'l', or 'L' for integer fields */

106                                 /* 'h', 'l',��'L'���������ֶ� */

    // ���Ƚ��ַ�ָ��ָ��buf��Ȼ��ɨ���ʽ�ַ������Ը�����ʽת��ָʾ������Ӧ�Ĵ�����

107         for (str=buf ; *fmt ; ++fmt) {

    // ��ʽת��ָʾ�ַ�������'%'��ʼ�������fmt��ʽ�ַ�����ɨ��'%'��Ѱ�Ҹ�ʽת���ַ����Ŀ�ʼ��

    // ���Ǹ�ʽָʾ��һ���ַ��������δ���str��

108                 if (*fmt != '%') {

109                         *str++ = *fmt;

110                         continue;

111                 }

112                        

    // ����ȡ�ø�ʽָʾ�ַ����еı�־�򣬲�����־��������flags�����С�

113                 /* process flags */

114                 flags = 0;

115                 repeat:

116                         ++fmt;          /* this also skips first '%' */

117                         switch (*fmt) {

118                                 case '-': flags |= LEFT; goto repeat;    // ���������

119                                 case '+': flags |= PLUS; goto repeat;    // �żӺš�

120                                 case ' ': flags |= SPACE; goto repeat;   // �ſո�

121                                 case '#': flags |= SPECIAL; goto repeat; // ������ת����

122                                 case '': flags |= ZEROPAD; goto repeat;  // Ҫ����(��'0')��

123                                 }

124                

    // ȡ��ǰ�����ֶο�����ֵ������field_width�����С����������������ֵ��ֱ��ȡ��Ϊ����ֵ��

    // ��������������ַ�'*'����ʾ��һ������ָ�����ȡ���˵���va_argȡ����ֵ������ʱ����ֵ

    // С��0����ø�����ʾ����б�־��'-'��־�����룩����˻����ڱ�־����������ñ�־����

    // ���ֶο���ֵȡΪ�����ֵ��

125                 /* get field width */

126                 field_width = -1;

127                 if (is_digit(*fmt))

128                         field_width = skip_atoi(&fmt);

129                 else if (*fmt == '*') {

130                         /* it's the next argument */     // �����и�bug��Ӧ����++fmt;

131                         field_width = va_arg(args, int);

132                         if (field_width < 0) {

133                                 field_width = -field_width;

134                                 flags |= LEFT;

135                         }

136                 }

137

    // ������δ��룬ȡ��ʽת�����ľ����򣬲�����precision�����С�������ʼ�ı�־��'.'��

    // �䴦���������������������ơ����������������ֵ��ֱ��ȡ��Ϊ����ֵ���������������

    // �ַ�'*'����ʾ��һ������ָ�����ȡ���˵���va_argȡ����ֵ������ʱ����ֵС��0����

    // �ֶξ���ֵȡΪ0��

138                 /* get the precision */

139                 precision = -1;

140                 if (*fmt == '.') {

141                         ++fmt; 

142                         if (is_digit(*fmt))

143                                 precision = skip_atoi(&fmt);

144                         else if (*fmt == '*') {

145                                 /* it's the next argument */   // ͬ������ҲӦ����++fmt;

146                                 precision = va_arg(args, int);

147                         }

148                         if (precision < 0)

149                                 precision = 0;

150                 }

151

    // ������δ�������������η������������qualifer��������h,l,L�ĺ���μ��б����˵������

152                 /* get the conversion qualifier */

153                 qualifier = -1;

154                 if (*fmt == 'h' || *fmt == 'l' || *fmt == 'L') {

155                         qualifier = *fmt;

156                         ++fmt;

157                 }

158

    // �������ת��ָʾ����

159                 switch (*fmt) {

    // ���ת��ָʾ����'c'�����ʾ��Ӧ����Ӧ���ַ�����ʱ�����־������������룬����ֶ�ǰ��

    // ����'������ֵ-1'���ո��ַ���Ȼ���ٷ�������ַ�����������򻹴���0�����ʾΪ���룬����

    // �����ַ���������'����ֵ-1'���ո��ַ���

160                 case 'c':

161                         if (!(flags & LEFT))

162                                 while (--field_width > 0)

163                                         *str++ = ' ';

164                         *str++ = (unsigned char) va_arg(args, int);

165                         while (--field_width > 0)

166                                 *str++ = ' ';

167                         break;

168

    // ���ת��ָʾ����'s'�����ʾ��Ӧ�������ַ���������ȡ�����ַ����ij��ȣ����䳬���˾�����ֵ��

    // ����չ������=�ַ������ȡ���ʱ�����־������������룬����ֶ�ǰ����'����ֵ-�ַ�������'

    // ���ո��ַ���Ȼ���ٷ�������ַ�������������򻹴���0�����ʾΪ���룬���ڲ����ַ�������

    // ����'����ֵ-�ַ�������'���ո��ַ���

169                 case 's':

170                         s = va_arg(args, char *);

171                         len = strlen(s);

172                         if (precision < 0)

173                                 precision = len;

174                         else if (len > precision)

175                                 len = precision;

176

177                         if (!(flags & LEFT))

178                                 while (len < field_width--)

179                                         *str++ = ' ';

180                         for (i = 0; i < len; ++i)

181                                 *str++ = *s++;

182                         while (len < field_width--)

183                                 *str++ = ' ';

184                         break;

185

    // �����ʽת������'o'����ʾ�轫��Ӧ�IJ���ת���ɰ˽��������ַ���������number()����������

186                 case 'o':

187                         str = number(str, va_arg(args, unsigned long), 8,

188                                 field_width, precision, flags);

189                         break;

190

    // �����ʽת������'p'����ʾ��Ӧ������һ��ָ�����͡���ʱ���ò���û�����ÿ�������Ĭ�Ͽ���

    // Ϊ8��������Ҫ���㡣Ȼ�����number()�������д�����

191                 case 'p':

192                         if (field_width == -1) {

193                                 field_width = 8;

194                                 flags |= ZEROPAD;

195                         }

196                         str = number(str,

197                                 (unsigned long) va_arg(args, void *), 16,

198                                 field_width, precision, flags);

199                         break;

200

    // ����ʽת��ָʾ��'x'��'X'�����ʾ��Ӧ������Ҫ��ӡ��ʮ�������������'x'��ʾ��Сд��ĸ��ʾ��

201                 case 'x':

202                         flags |= SMALL;

203                 case 'X':

204                         str = number(str, va_arg(args, unsigned long), 16,

205                                 field_width, precision, flags);

206                         break;

207

    // �����ʽת���ַ���'d','i'��'u'�����ʾ��Ӧ������������'d', 'i'�������������������Ҫ����

    // �����ű�־��'u'�����޷���������

208                 case 'd':

209                 case 'i':

210                         flags |= SIGN;

211                 case 'u':

212                         str = number(str, va_arg(args, unsigned long), 10,

213                                 field_width, precision, flags);

214                         break;

215

    // ����ʽת��ָʾ����'n'�����ʾҪ�ѵ�ĿǰΪֹת������ַ������浽��Ӧ����ָ��ָ����λ���С�

    // ��������va_arg()ȡ�øò���ָ�룬Ȼ���Ѿ�ת���õ��ַ��������ָ����ָ��λ�á�

216                 case 'n':

217                         ip = va_arg(args, int *);

218                         *ip = (str - buf);

219                         break;

220

    // ����ʽת��������'%'�����ʾ��ʽ�ַ����д���ֱ�ӽ�һ��'%'д��������С�

    // �����ʽת������λ�ô������ַ�����Ҳֱ�ӽ����ַ�д��������У������ص�107�м�������

    // ��ʽ�ַ����������ʾ�Ѿ���������ʽ�ַ����Ľ�β�������˳�ѭ����

221                 default:

222                         if (*fmt != '%')

223                                 *str++ = '%';

224                         if (*fmt)

225                                 *str++ = *fmt;

226                         else

227                                 --fmt;

228                         break;

229                 }

230         }

231         *str = '\0';         // �����ת���õ��ַ�����β������null��

232         return str-buf;      // ����ת���õ��ַ�������ֵ��

233 }

234


 


 

8.11 ����8-11 linux/kernel/printk.c


  1 /*

  2  *  linux/kernel/printk.c

  3  *

  4  *  (C) 1991  Linus Torvalds

  5  */

  6

  7 /*

  8  * When in kernel-mode, we cannot use printf, as fs is liable to

  9  * point to 'interesting' things. Make a printf with fs-saving, and

 10  * all is well.

 11  */

    /*

     * �������ں�ģʽʱ�����Dz���ʹ��printf����Ϊ�Ĵ���fsָ������������Ȥ

     * �ĵط����Լ�����һ��printf����ʹ��ǰ����fs��һ�оͽ���ˡ�

     */

    // ��׼����ͷ�ļ����Ժ����ʽ������������б�����Ҫ˵����-������(va_list)��������

    // va_start��va_arg��va_end������vsprintf��vprintf��vfprintf������

 12 #include <stdarg.h>

 13 #include <stddef.h>       // ��׼����ͷ�ļ���������NULL, offsetof(TYPE, MEMBER)��

 14

 15 #include <linux/kernel.h> // �ں�ͷ�ļ�������һЩ�ں˳��ú�����ԭ�ζ��塣

 16

 17 static char buf[1024];    // ��ʾ����ʱ��������

 18

    // ����vsprintf()������linux/kernel/vsprintf.c��92�п�ʼ����

 19 extern int vsprintf(char * buf, const char * fmt, va_list args);

 20

    // �ں�ʹ�õ���ʾ������

 21 int printk(const char *fmt, ...)

 22 {

 23         va_list args;                  // va_listʵ������һ���ַ�ָ�����͡�

 24         int i;

 25

    // ���в���������ʼ������Ȼ��ʹ�ø�ʽ��fmt�������б�args�����buf�С�����ֵi

    // ��������ַ����ij��ȡ������в����������������������ÿ���̨��ʾ������������ʾ

    // �ַ�����

 26         va_start(args, fmt);

 27         i=vsprintf(buf,fmt,args);

 28         va_end(args);

 29         console_print(buf);            // chr_drv/console.c����995�п�ʼ��

 30         return i;

 31 }

 32


 


 

8.12 ����8-12 linux/kernel/panic.c


  1 /*

  2  *  linux/kernel/panic.c

  3  *

  4  *  (C) 1991  Linus Torvalds

  5  */

  6

  7 /*

  8  * This function is used through-out the kernel (includeinh mm and fs)

  9  * to indicate a major problem.

 10  */

    /*

     * �ú����������ں���ʹ�ã������� ͷ�ļ�*.h, �ڴ��������mm���ļ�ϵͳfs�У���

     * ����ָ����Ҫ�ij������⡣

     */

 11 #include <linux/kernel.h> // �ں�ͷ�ļ�������һЩ�ں˳��ú�����ԭ�ζ��塣

 12 #include <linux/sched.h>  // ���ȳ���ͷ�ļ�������������ṹtask_struct����ʼ����0�����ݣ�

                              // ����һЩ�й��������������úͻ�ȡ��Ƕ��ʽ��ຯ������䡣

 13

 14 void sys_sync(void);    /* it's really int */ /* ʵ����������int (fs/buffer.c,44) */

 15

    // �ú���������ʾ�ں��г��ֵ��ش������Ϣ���������ļ�ϵͳͬ��������Ȼ�������ѭ��--������

    // �����ǰ����������0�Ļ�����˵���ǽ���������������һ�û�������ļ�ϵͳͬ��������

    // ������ǰ�Ĺؼ���volatile���ڸ��߱�����gcc�ú������᷵�ء���������gcc��������һЩ��

    // ���룬����Ҫ����ʹ������ؼ��ֿ��Ա������ijЩ��δ��ʼ�������ģ��پ�����Ϣ��

    // ��ͬ������gcc�ĺ�������˵����void panic(const char *s) __attribute__ ((noreturn));

 16 volatile void panic(const char * s)

 17 {

 18         printk("Kernel panic: %s\n\r",s);

 19         if (current == task[0])

 20                 printk("In swapper task - not syncing\n\r");

 21         else

 22                 sys_sync();

 23         for(;;);

 24 }

 25


 


 

��9�� �ں˿��豸����

9.1 ����9-1 linux/kernel/blk_drv/blk.h


  1 #ifndef _BLK_H

  2 #define _BLK_H

  3

  4 #define NR_BLK_DEV      7          // ���豸����������

  5 /*

  6  * NR_REQUEST is the number of entries in the request-queue.

  7  * NOTE that writes may use only the low 2/3 of these: reads

  8  * take precedence.

  9  *

 10  * 32 seems to be a reasonable number: enough to get some benefit

 11  * from the elevator-mechanism, but not so much as to lock a lot of

 12  * buffers when they are in the queue. 64 seems to be too many (easily

 13  * long pauses in reading when heavy writing/syncing is going on)

 14  */

    /*

     * ���涨���NR_REQUEST�������������������������

     * ע�⣬д������ʹ����Щ���еͶ˵�2/3����������ȴ�����

     *

     * 32�������һ�����������֣������Ѿ��㹻�ӵ����㷨�л�úô���

     * �����������ڶ����ж���סʱ�ֲ��Ե��Ǻܴ������64�Ϳ���ȥ̫

     * ���ˣ���������д/ͬ����������ʱ����������ʱ�����ͣ����

     */

 15 #define NR_REQUEST      32

 16

 17 /*

 18  * Ok, this is an expanded form so that we can use the same

 19  * request for paging requests when that is implemented. In

 20  * paging, 'bh' is NULL, and 'waiting' is used to wait for

 21  * read/write completion.

 22  */

    /*

     * OK��������request�ṹ��һ����չ��ʽ�������ʵ���Ժ�����

     * �Ϳ����ڷ�ҳ������ʹ��ͬ���� request �ṹ�� �ڷ�ҳ�����У�

     * 'bh'��NULL����'waiting'�����ڵȴ���/д����ɡ�

     */

    // �����������������Ľṹ����������ֶ�dev = -1�����ʾ�����и���û�б�ʹ�á�

    // �ֶ�cmd��ȡ���� READ��0���� WRITE��1����������include/linux/fs.h�У���

    // ���У��ں˲�û���õ�waitingָ�룬�����֮���ں�ʹ���˻����ĵȴ����С���Ϊ

    // �ȴ�һ���������ȴ�����������ǶԵȵġ�

 23 struct request {

 24         int dev;                       /* -1 if no request */  // ��������豸�š�

 25         int cmd;                       /* READ or WRITE */  // READ��WRITE���

 26         int errors;                     //����ʱ�����Ĵ��������

 27         unsigned long sector;           // ��ʼ������(1��=2����)

 28         unsigned long nr_sectors;       // ��/д��������

 29         char * buffer;                  // ���ݻ�������

 30         struct task_struct * waiting;   // ����ȴ�������ɲ����ĵط������У���

 31         struct buffer_head * bh;        // ������ͷָ��(include/linux/fs.h,68)��

 32         struct request * next;          // ָ����һ�����

 33 };

 34

 35 /*

 36  * This is used in the elevator algorithm: Note that

 37  * reads always go before writes. This is natural: reads

 38  * are much more time-critical than writes.

 39  */

    /*

     * ����Ķ������ڵ����㷨��ע�������������д����֮ǰ���С�

     * ���Ǻ���Ȼ�ģ���������ʱ���Ҫ��Ҫ��д�����ϸ�öࡣ

     */

    // ������в���s1��s2��ȡֵ�����涨�������ṹrequest��ָ�롣�ú궨�����ڸ�����������

    // ָ����������ṹ�е���Ϣ������cmd��READ��WRITE�����豸��dev�Լ���������������sector��

    // ���жϳ�����������ṹ��ǰ������˳�����˳���������ʿ��豸ʱ��������ִ��˳��

    // �������ڳ���blk_drv/ll_rw_blk.c�к���add_request()�б����ã���96�У����ú겿��

    // ��ʵ����I/O���ȹ��ܣ���ʵ���˶�������������ܣ���һ����������ϲ����ܣ���

 40 #define IN_ORDER(s1,s2) \

 41 ((s1)->cmd<(s2)->cmd || (s1)->cmd==(s2)->cmd && \

 42 ((s1)->dev < (s2)->dev || ((s1)->dev == (s2)->dev && \

 43 (s1)->sector < (s2)->sector)))

 44

    // ���豸�����ṹ��

 45 struct blk_dev_struct {

 46         void (*request_fn)(void);                      // ����������ָ�롣

 47         struct request * current_request;              // ��ǰ����������ṹ��

 48 };

 49

    // ���豸�������飩��ÿ�ֿ��豸ռ��һ���7�

 50 extern struct blk_dev_struct blk_dev[NR_BLK_DEV];

    // ����������飬��32�

 51 extern struct request request[NR_REQUEST];

    // �ȴ�����������Ľ��̶���ͷָ�롣

 52 extern struct task_struct * wait_for_request;

 53

    // �豸���ݿ�����ָ�����顣ÿ��ָ����ָ��ָ�����豸�ŵ��ܿ�������hd_sizes[]������

    // ��������ÿһ���Ӧ���豸��ȷ����һ�����豸����ӵ�е����ݿ�������1���С = 1KB����

 54 extern int * blk_size[NR_BLK_DEV];

 55

    // �ڿ��豸����������hd.c��������ͷ�ļ�ʱ�������ȶ��������������豸�����豸�š�

    // ������������63����90�о���Ϊ�������ļ����������������ȷ�ĺ궨�塣

 56 #ifdef MAJOR_NR                    // ���豸�š�

 57

 58 /*

 59  * Add entries as needed. Currently the only block devices

 60  * supported are hard-disks and floppies.

 61  */

    /*

     * ��Ҫʱ������Ŀ��Ŀǰ���豸��֧��Ӳ�̺����̣����������̣���

     */

 62

    // ���������MAJOR_NR = 1��RAM�����豸�ţ������������·��ų����ͺꡣ

 63 #if (MAJOR_NR == 1)

 64 /* ram disk */

 65 #define DEVICE_NAME "ramdisk"                // �豸���ƣ����ڴ������̡�����

 66 #define DEVICE_REQUEST do_rd_request         // �豸�������������

 67 #define DEVICE_NR(device) ((device) & 7)     // �豸�ţ�0 �C 7����

 68 #define DEVICE_ON(device)                    // �����豸�����������뿪���͹رգ���

 69 #define DEVICE_OFF(device)                   // �ر��豸��

 70

    // �������������MAJOR_NR = 2���������豸�ţ������������·��ų����ͺꡣ

 71 #elif (MAJOR_NR == 2)

 72 /* floppy */

 73 #define DEVICE_NAME "floppy"                 // �豸���ƣ�������������������

 74 #define DEVICE_INTR do_floppy                // �豸�жϴ���������

 75 #define DEVICE_REQUEST do_fd_request         // �豸�������������

 76 #define DEVICE_NR(device) ((device) & 3)     // �豸�ţ�0 �C 3����

 77 #define DEVICE_ON(device) floppy_on(DEVICE_NR(device))    // �����豸�ꡣ

 78 #define DEVICE_OFF(device) floppy_off(DEVICE_NR(device))  // �ر��豸�ꡣ

 79

    // �������������MAJOR_NR = 3��Ӳ�����豸�ţ������������·��ų����ͺꡣ

 80 #elif (MAJOR_NR == 3)

 81 /* harddisk */

 82 #define DEVICE_NAME "harddisk"               // �豸���ƣ���Ӳ�̡�����

 83 #define DEVICE_INTR do_hd                    // �豸�жϴ���������

 84 #define DEVICE_TIMEOUT hd_timeout            // �豸��ʱֵ��

 85 #define DEVICE_REQUEST do_hd_request         // �豸�������������

 86 #define DEVICE_NR(device) (MINOR(device)/5)  // �豸�š�

 87 #define DEVICE_ON(device)                    // �����豸��

 88 #define DEVICE_OFF(device)                   // �ر��豸��

 89

    // �����ڱ���Ԥ�����׶���ʾ������Ϣ����δ֪���豸����

 90 #elif

 91 /* unknown blk device */

 92 #error "unknown blk device"

 93

 94 #endif

 95

    // Ϊ�˱��ڱ�̱�ʾ�����ﶨ���������꣺CURRENT��ָ��ס�豸�ŵĵ�ǰ����ṹ��ָ�룬

    // CURRENT_DEV �ǵ�ǰ������CURRENT���豸�š�

 96 #define CURRENT (blk_dev[MAJOR_NR].current_request)

 97 #define CURRENT_DEV DEVICE_NR(CURRENT->dev)

 98

    // ����������豸�жϴ������ų��������������Ϊһ������ָ�룬��Ĭ��ΪNULL��

 99 #ifdef DEVICE_INTR

100 void (*DEVICE_INTR)(void) = NULL;

101 #endif

    // ����������豸��ʱ���ų�����������ֵ����0��������SET_INTR()�ꡣ����ֻ����ꡣ

102 #ifdef DEVICE_TIMEOUT

103 int DEVICE_TIMEOUT = 0;

104 #define SET_INTR(x) (DEVICE_INTR = (x),DEVICE_TIMEOUT = 200)

105 #else

106 #define SET_INTR(x) (DEVICE_INTR = (x))

107 #endif

    // �����豸������ų���DEVICE_REGUEST��һ�������������޷��صľ�̬����ָ�롣

108 static void (DEVICE_REQUEST)(void);

109

    // ����ָ���Ļ���顣

    // ���ָ�������bh��û�б�����������ʾ������Ϣ�����򽫸û��������������ѵȴ�

    // �û����Ľ��̡���Ϊ��Ƕ�����������ǻ����ͷָ�롣

110 extern inline void unlock_buffer(struct buffer_head * bh)

111 {

112         if (!bh->b_lock)

113                 printk(DEVICE_NAME ": free buffer being unlocked\n");

114         bh->b_lock=0;

115         wake_up(&bh->b_wait);

116 }

117

    // ������������

    // ����uptodate�Ǹ��±�־��

    // ���ȹر�ָ�����豸��Ȼ����˴ζ�д�������Ƿ���Ч�������Ч����ݲ���ֵ���û���

    // �����ݸ��±�־���������û������� ������±�־����ֵ��0����ʾ�˴�������IJ�����ʧ

    // �ܣ������ʾ��ؿ��豸IO������Ϣ�� ��󣬻��ѵȴ���������Ľ����Լ��ȴ���������

    // ����ֵĽ��̣��ͷŲ�������������ɾ������������ѵ�ǰ������ָ��ָ����һ�����

118 extern inline void end_request(int uptodate)

119 {

120         DEVICE_OFF(CURRENT->dev);                   // �ر��豸��

121         if (CURRENT->bh) {                          // CURRENTΪ��ǰ����ṹ��ָ�롣

122                 CURRENT->bh->b_uptodate = uptodate; // �ø��±�־��

123                 unlock_buffer(CURRENT->bh);         // ������������

124         }

125         if (!uptodate) {                            // �����±�־Ϊ0����ʾ������Ϣ��

126                 printk(DEVICE_NAME " I/O error\n\r");

127                 printk("dev %04x, block %d\n\r",CURRENT->dev,

128                         CURRENT->bh->b_blocknr);

129         }

130         wake_up(&CURRENT->waiting);                 // ���ѵȴ���������Ľ��̡�

131         wake_up(&wait_for_request);                 // ���ѵȴ�����������Ľ��̡�

132         CURRENT->dev = -1;                          // �ͷŸ������

133         CURRENT = CURRENT->next;                    // ָ����һ�����

134 }

135

    // ����������豸��ʱ���ų���DEVICE_TIMEOUT������CLEAR_DEVICE_TIMEOUT���ų���

    // Ϊ��DEVICE_TIMEOUT = 0����������CLEAR_DEVICE_TIMEOUTΪ�ա�

136 #ifdef DEVICE_TIMEOUT

137 #define CLEAR_DEVICE_TIMEOUT DEVICE_TIMEOUT = 0;

138 #else

139 #define CLEAR_DEVICE_TIMEOUT

140 #endif

141

    // ����������豸�жϷ��ų���DEVICE_INTR������CLEAR_DEVICE_INTR���ų���Ϊ

    // ��DEVICE_INTR = 0������������Ϊ�ա�

142 #ifdef DEVICE_INTR

143 #define CLEAR_DEVICE_INTR DEVICE_INTR = 0;

144 #else

145 #define CLEAR_DEVICE_INTR

146 #endif

147

    // �����ʼ��������ꡣ

    // ���ڼ������豸��������ʼ����������ij�ʼ���������ƣ��������Ϊ���Ƕ�����һ��

    // ͳһ�ij�ʼ���ꡣ�ú����ڶԵ�ǰ���������һЩ��Ч���жϡ������������£�

    // ����豸��ǰ������Ϊ�գ�NULL������ʾ���豸Ŀǰ������Ҫ�������������������ɨβ

    // �������˳���Ӧ���������������ǰ���������豸�����豸�Ų��������������������

    // ���ţ�˵������������ҵ��ˣ������ں���ʾ������Ϣ��ͣ�������������������õĻ����

    // û�б�������Ҳ˵���ں˳���������⣬������ʾ������Ϣ��ͣ����

148 #define INIT_REQUEST \

149 repeat: \

150         if (!CURRENT) {\                         // �����ǰ������ָ��ΪNULL�򷵻ء�

151                 CLEAR_DEVICE_INTR \

152                 CLEAR_DEVICE_TIMEOUT \

153                 return; \

154         } \

155         if (MAJOR(CURRENT->dev) != MAJOR_NR) \   // �����ǰ�豸���豸�Ų�����ͣ����

156                 panic(DEVICE_NAME ": request list destroyed"); \

157         if (CURRENT->bh) { \

158                 if (!CURRENT->bh->b_lock) \      // ���������Ļ�����û������ͣ����

159                         panic(DEVICE_NAME ": block not locked"); \

160         }

161

162 #endif

163

164 #endif

165


 


 

9.2 ����9-2 linux/kernel/blk_drv/hd.c


  1 /*

  2  *  linux/kernel/hd.c

  3  *

  4  *  (C) 1991  Linus Torvalds

  5  */

  6

  7 /*

  8  * This is the low-level hd interrupt support. It traverses the

  9  * request-list, using interrupts to jump between functions. As

 10  * all the functions are called within interrupts, we may not

 11  * sleep. Special care is recommended.

 12  *

 13  *  modified by Drew Eckhardt to check nr of hd's from the CMOS.

 14  */

    /*

     * �������ǵײ�Ӳ���жϸ���������Ҫ����ɨ����������У�ʹ���ж�

     * �ں���֮����ת���������еĺ����������ж�����õģ�������Щ����

     * ������˯�ߡ����ر�ע�⡣

     *

     * ��Drew Eckhardt�޸ģ�����CMOS��Ϣ���Ӳ������

     */

 15

 16 #include <linux/config.h> // �ں�����ͷ�ļ�������������Ժ�Ӳ�����ͣ�HD_TYPE��ѡ�

 17 #include <linux/sched.h>  // ���ȳ���ͷ�ļ�����������ṹtask_struct������0���ݵȡ�

 18 #include <linux/fs.h>     // �ļ�ϵͳͷ�ļ��������ļ����ṹ��file��m_inode���ȡ�

 19 #include <linux/kernel.h> // �ں�ͷ�ļ�������һЩ�ں˳��ú�����ԭ�ζ��塣

 20 #include <linux/hdreg.h>  // Ӳ�̲���ͷ�ļ�������Ӳ�̼Ĵ����˿ڡ�״̬�롢����������Ϣ��

 21 #include <asm/system.h>   // ϵͳͷ�ļ����������û��޸�������/�ж��ŵȵĻ��ꡣ

 22 #include <asm/io.h>       // ioͷ�ļ�������Ӳ���˿�����/���������䡣

 23 #include <asm/segment.h>  // �β���ͷ�ļ����������йضμĴ���������Ƕ��ʽ��ຯ����

 24

    // ����Ӳ�����豸�ŷ��ų����������������У����豸�ű����ڰ���blk.h�ļ�֮ǰ�����塣

    // ��Ϊblk.h�ļ���Ҫ�õ�������ų���ֵ��ȷ��һЩ��������ط��ų����ͺꡣ

 25 #define MAJOR_NR 3        // Ӳ�����豸����3��

 26 #include "blk.h"          // ���豸ͷ�ļ��������������ݽṹ�����豸���ݽṹ�ͺ����Ϣ��

 27

    // ��CMOS�����꺯����

    // ��κ��ȡCMOS��Ӳ����Ϣ��outb_p��inb_p��include/asm/io.h�ж���Ķ˿���������ꡣ

    // ��init/main.c�ж�ȡCMOSʱ����Ϣ�ĺ���ȫһ����

 28 #define CMOS_READ(addr) ({ \

 29 outb_p(0x80|addr,0x70); \          // 0x70��д�˿ںţ�0x80|addr��Ҫ����CMOS�ڴ��ַ��

 30 inb_p(0x71); \                     // 0x71�Ƕ��˿ںš�

 31 })

 32

 33 /* Max read/write errors/sector */

    /* ÿ������/д�������������������� */

 34 #define MAX_ERRORS      7          // ��/дһ������ʱ������������������

 35 #define MAX_HD          2          // ϵͳ֧�ֵ����Ӳ������

 36

    // ����У������������

    // ��λ����ʱ��Ӳ���жϴ��������е��õ�����У������(311��)��

 37 static void recal_intr(void);

    // ��дӲ��ʧ�ܴ������ú�����

    // ����������������������ø�λ��־Ҫ��ִ�и�λӲ�̿����������������ԣ�242�У���

 38 static void bad_rw_intr(void);

 39

    // ����У����־���������˸ñ�־�������л����recal_intr()�Խ���ͷ�ƶ���0���档

 40 static int recalibrate = 0;

   // ��λ��־����������д����ʱ�����øñ�־��������ظ�λ�������Ը�λӲ�̺Ϳ�������

 41 static int reset = 0;

 42

 43 /*

 44  *  This struct defines the HD's and their types.

 45  */

    /* ����ṹ������Ӳ�̲��������� */

    // Ӳ����Ϣ�ṹ��Harddisk information struct����

    // ���ֶηֱ��Ǵ�ͷ����ÿ�ŵ�����������������дǰԤ��������š���ͷ��½������š�

    // �����ֽڡ����ǵĺ�����μ������б����˵����

 46 struct hd_i_struct {

 47         int head,sect,cyl,wpcom,lzone,ctl;

 48         };

 

    // ����Ѿ���include/linux/config.h�����ļ��ж����˷��ų���HD_TYPE����ȡ���ж���

    // �õIJ�����ΪӲ����Ϣ����hd_info[]�е����ݡ�������Ĭ�϶���Ϊ0ֵ����setup()����

    // �л����½������á�

 49 #ifdef HD_TYPE

 50 struct hd_i_struct hd_info[] = { HD_TYPE };                       // Ӳ����Ϣ���顣

 51 #define NR_HD ((sizeof (hd_info))/(sizeof (struct hd_i_struct)))  // ����Ӳ�̸�����

 52 #else

 53 struct hd_i_struct hd_info[] = { {0,0,0,0,0,0},{0,0,0,0,0,0} };

 54 static int NR_HD = 0;

 55 #endif

 56

    // ����Ӳ�̷����ṹ������ÿ��������Ӳ��0����ʼ�����������ʼ�����źͷ�������������

    // ����5�ı������������hd[0]��hd[5]�ȣ���������Ӳ�̵IJ�����

 57 static struct hd_struct {

 58         long start_sect;                 // ������Ӳ���е���ʼ���������ԣ�������

 59         long nr_sects;                   // ����������������

 60 } hd[5*MAX_HD]={{0,0},};

 61

    // Ӳ��ÿ���������ݿ��������顣

 62 static int hd_sizes[5*MAX_HD] = {0, };

 63

    // ���˿�Ƕ����ꡣ���˿�port������nr�֣�������buf�С�

 64 #define port_read(port,buf,nr) \

 65 __asm__("cld;rep;insw"::"d" (port),"D" (buf),"c" (nr):"cx","di")

 66

    // д�˿�Ƕ����ꡣд�˿�port����дnr�֣���buf��ȡ���ݡ�

 67 #define port_write(port,buf,nr) \

 68 __asm__("cld;rep;outsw"::"d" (port),"S" (buf),"c" (nr):"cx","si")

 69

 

 70 extern void hd_interrupt(void);         // Ӳ���жϹ��̣�sys_call.s��235�У���

 71 extern void rd_load(void);              // �����̴������غ�����ramdisk.c��71�У���

 72

 73 /* This may be used only once, enforced by 'static int callable' */

    /* ����ú���ֻ�ڳ�ʼ��ʱ������һ�Ρ��þ�̬����callable��Ϊ�ɵ��ñ�־��*/

    // ϵͳ���ú�����

    // ��������BIOS���ɳ�ʼ������init/main.c��init�ӳ�������Ϊָ��Ӳ�̲������ṹ��ָ�롣

    // ��Ӳ�̲������ṹ����2��Ӳ�̲����������ݣ���32�ֽڣ����Ǵ��ڴ�0x90080�����ƶ�����

    // 0x90080����Ӳ�̲���������setup.s��������ROM BIOS����ȡ�á�Ӳ�̲�������Ϣ�μ�����

    // �б����˵���� ��������Ҫ�����Ƕ�ȡ CMOS��Ӳ�̲�������Ϣ����������Ӳ�̷����ṹhd��

    // �����Լ���RAM�����̺͸��ļ�ϵͳ��

 74 int sys_setup(void * BIOS)

 75 {

 76         static int callable = 1;                // ���Ʊ�����ֻ�ܱ�����1�εı�־��

 77         int i,drive;

 78         unsigned char cmos_disks;

 79         struct partition *p;

 80         struct buffer_head * bh;

 81

    // ��������callable��־��ʹ�ñ�����ֻ�ܱ�����1�Ρ�Ȼ������Ӳ����Ϣ����hd_info[]��

    // ����� include/linux/config.h �ļ����Ѷ����˷��ų���HD_TYPE����ô hd_info[]����

    // �Ѿ���ǰ���49�������ú��ˡ��������Ҫ��ȡboot/setup.s���������ڴ�0x90080��

    // ��ʼ��Ӳ�̲�������setup.s�������ڴ�˴����������һ������Ӳ�̲�������

 82         if (!callable)

 83                 return -1;

 84         callable = 0;

 85 #ifndef HD_TYPE                                  // ���û�ж���HD_TYPE�����ȡ��

 86         for (drive=0 ; drive<2 ; drive++) {

 87                 hd_info[drive].cyl = *(unsigned short *) BIOS;      // ��������

 88                 hd_info[drive].head = *(unsigned char *) (2+BIOS);  // ��ͷ����

 89                 hd_info[drive].wpcom = *(unsigned short *) (5+BIOS); // дǰԤ��������š�

 90                 hd_info[drive].ctl = *(unsigned char *) (8+BIOS);    // �����ֽڡ�

 91                 hd_info[drive].lzone = *(unsigned short *) (12+BIOS);// ��ͷ��½������š�

 92                 hd_info[drive].sect = *(unsigned char *) (14+BIOS);  // ÿ�ŵ���������

 93                 BIOS += 16;             // ÿ��Ӳ�̲�������16�ֽڣ�����BIOSָ����һ����

 94         }

    // setup.s������ȡBIOSӲ�̲�������Ϣʱ�����ϵͳ��ֻ��1��Ӳ�̣��ͻὫ��Ӧ��2��

    // Ӳ�̵�16�ֽ�ȫ�����㡣�������ֻҪ�жϵ�2��Ӳ���������Ƿ�Ϊ0�Ϳ���֪���Ƿ���

    // ��2��Ӳ���ˡ�

 95         if (hd_info[1].cyl)

 96                 NR_HD=2;               // Ӳ������Ϊ2��

 97         else

 98                 NR_HD=1;

 99 #endif

    // �����Ӳ����Ϣ����hd_info[]�Ѿ����úã�����ȷ����ϵͳ���е�Ӳ����NR_HD������

    // ��ʼ����Ӳ�̷����ṹ����hd[]�����������0����5 �ֱ��ʾ����Ӳ�̵������������

    // ��1��4��6��9�ֱ��ʾ����Ӳ�̵�4�������IJ����� �����������ñ�ʾӲ��������Ϣ

    // �������0��5����

100         for (i=0 ; i<NR_HD ; i++) {

101                 hd[i*5].start_sect = 0;                        // Ӳ����ʼ�����š�

102                 hd[i*5].nr_sects = hd_info[i].head*

103                                 hd_info[i].sect*hd_info[i].cyl;  // Ӳ������������

104         }

105

106         /*

107                 We querry CMOS about hard disks : it could be that

108                 we have a SCSI/ESDI/etc controller that is BIOS

109                 compatable with ST-506, and thus showing up in our

110                 BIOS table, but not register compatable, and therefore

111                 not present in CMOS.

112

113                 Furthurmore, we will assume that our ST-506 drives

114                 <if any> are the primary drives in the system, and

115                 the ones reflected as drive 1 or 2.

116

117                 The first drive is stored in the high nibble of CMOS

118                 byte 0x12, the second in the low nibble.  This will be

119                 either a 4 bit drive type or 0xf indicating use byte 0x19

120                 for an 8 bit type, drive 1, 0x1a for drive 2 in CMOS.

121

122                 Needless to say, a non-zero value means we have

123                 an AT controller hard disk for that drive.

124

125                 

126         */

            /*

                    ���Ƕ�CMOS�й�Ӳ�̵���Ϣ��Щ���ɣ����ܻ���������������

                    ������һ��SCSI/ESDI/�ȵĿ�������������ST-506��ʽ��BIOS

                    ����ݵģ��������������ǵ�BIOS�������У���ȴ�ֲ��ǼĴ�

                    �����ݵģ������Щ������CMOS���ֲ����ڡ�

 

                    ���⣬���Ǽ���ST-506������������еĻ�����ϵͳ�еĻ�����

                    ������Ҳ����������1��2���ֵ���������

 

                    ��1�����������������CMOS�ֽ�0x12�ĸ߰��ֽ��У���2��

                    ����ڵͰ��ֽ��С���4λ�ֽ���Ϣ���������������ͣ�Ҳ����

                    ����0xf��0xf��ʾʹ��CMOS��0x19�ֽ���Ϊ������1��8λ

                    �����ֽڣ�ʹ��CMOS��0x1A�ֽ���Ϊ������2�������ֽڡ�

 

                    ��֮��һ������ֵ��ζ��Ӳ����һ��AT����������Ӳ�̡�

             */

127

    // �����������ԭ������������������Ӳ�̵����Dz���AT���������ݵġ��й�CMOS��Ϣ

    // ��μ���4����4.2.3.1�ڡ������CMOSƫ�Ƶ�ַ0x12������Ӳ�������ֽڡ�����Ͱ�

    // �ֽ�ֵ������ŵ�2��Ӳ������ֵ����Ϊ0�����ʾϵͳ����Ӳ�̣������ʾϵͳֻ��1

    // ��Ӳ�̡����0x12��������ֵΪ0�����ʾϵͳ��û��AT����Ӳ�̡�

128         if ((cmos_disks = CMOS_READ(0x12)) & 0xf0)

129                 if (cmos_disks & 0x0f)

130                         NR_HD = 2;

131                 else

132                         NR_HD = 1;

133         else

134                 NR_HD = 0;

    // ��NR_HD = 0��������Ӳ�̶�����AT���������ݵģ�����Ӳ�����ݽṹȫ���㡣

    // ��NR_HD = 1���򽫵�2��Ӳ�̵IJ������㡣

135         for (i = NR_HD ; i < 2 ; i++) {

136                 hd[i*5].start_sect = 0;

137                 hd[i*5].nr_sects = 0;

138         }

    // �ã�����Ϊֹ�����Ѿ�����ȷ����ϵͳ��������Ӳ�̸���NR_HD��������������ȡÿ��Ӳ��

    // �ϵ�1�������еķ�������Ϣ���������÷����ṹ����hd[] ��Ӳ�̸���������Ϣ��������

    // �ö��麯��bread()��Ӳ�̵�1�����ݿ飨fs/buffer.c����267�У�����1��������0x300��

    // 0x305 ���ֱ�������Ӳ�̵��豸�ţ���2��������0���������ȡ�Ŀ�š����������ɹ���

    // �����ݻᱻ����ڻ����bh���������С��������ͷָ��bhΪ0����˵��������ʧ�ܣ���

    // ��ʾ������Ϣ��ͣ�����������Ǹ���Ӳ�̵�1��������������ֽ�Ӧ����0xAA55���ж���

    // �������ݵ���Ч�ԣ��Ӷ�����֪��������λ��ƫ��0x1BE��ʼ���ķ������Ƿ���Ч������Ч

    // ��Ӳ�̷�������Ϣ����Ӳ�̷����ṹ����hd[]�С�����ͷ�bh��������

139         for (drive=0 ; drive<NR_HD ; drive++) {

140                 if (!(bh = bread(0x300 + drive*5,0))) {  // 0x300��0x305���豸�š�

141                         printk("Unable to read partition table of drive %d\n\r",

142                                 drive);

143                         panic("");

144                 }

145                 if (bh->b_data[510] != 0x55 || (unsigned char)

146                     bh->b_data[511] != 0xAA) {            // �ж�Ӳ�̱�־0xAA55��

147                         printk("Bad partition table on drive %d\n\r",drive);

148                         panic("");

149                 }

150                 p = 0x1BE + (void *)bh->b_data;    // ������λ�ڵ�1����0x1BE����

151                 for (i=1;i<5;i++,p++) {

152                         hd[i+5*drive].start_sect = p->start_sect;

153                         hd[i+5*drive].nr_sects = p->nr_sects;

154                 }

155                 brelse(bh);                 // �ͷ�Ϊ���Ӳ�����ݿ������Ļ�������

156         }

    // �����ٶ�ÿ�������е����ݿ���������ͳ�ƣ���������Ӳ�̷��������ݿ�����hd_sizes[]�С�

    // Ȼ�����豸���ݿ�����ָ������ı��豸��ָ������顣

157         for (i=0 ; i<5*MAX_HD ; i++)

158                 hd_sizes[i] = hd[i].nr_sects>>1 ;

159         blk_size[MAJOR_NR] = hd_sizes;

    // ���������������Ӳ�̷����ṹ����hd[]���������ȷʵ��Ӳ�̴��ڲ����Ѷ��������

    // ��������ʾ����������������Ϣ��Ȼ������ϵͳ�ڴ��������м����������а����ĸ���

    // ��ϵͳӳ��blk_drv/ramdisk.c����71�У�������ϵͳ�����������̵�������ж�������

    // ���Ƿ񻹺��и��ļ�ϵͳ��ӳ�����ݡ�����У���ʱ�������̳�Ϊ�����̣����԰Ѹ�ӳ��

    // ���ز���ŵ��������У�Ȼ��Ѵ�ʱ�ĸ��ļ�ϵͳ�豸��ROOT_DEV�޸ij������̵��豸�š�

    // �����ٶԽ����豸���г�ʼ�������װ���ļ�ϵͳ��

160         if (NR_HD)

161                 printk("Partition table%s ok.\n\r",(NR_HD>1)?"s":"");

162         rd_load();                          // blk_drv/ramdisk.c����71�С�

163         init_swapping();                    // mm/swap.c����199�С�

164         mount_root();                       // fs/super.c����241�С�

165         return (0);

166 }

167

    //// �жϲ�ѭ���ȴ�Ӳ�̿�����������

    // ��Ӳ�̿�����״̬�Ĵ����˿�HD_STATUS(0x1f7)��ѭ��������е���������������λ��λ6��

    // �Ƿ���λ���ҿ�����æλ��λ7���Ƿ񱻸�λ�� �������ֵretriesΪ0�����ʾ�ȴ�����

    // �����е�ʱ���Ѿ���ʱ����������������ֵ��Ϊ0��˵���ڵȴ���ѭ����ʱ�������ڿ�����

    // �ص�����״̬��OK��

    // ʵ���ϣ����ǽ�����״̬�Ĵ���æλ��λ7���Ƿ�Ϊ1���жϿ������Ƿ���æ״̬������

    // ���Ƿ��������λ6�Ƿ�Ϊ1�����������״̬�޹ء�������ǿ��԰ѵ�172������д�ɣ�

    // ��while (--retries && (inb_p(HD_STATUS)&0x80));�����⣬�������ڵ�PC���ٶȶ��ܿ죬

    // ������ǿ��԰ѵȴ���ѭ�������ټӴ�һЩ������������10����

168 static int controller_ready(void)

169 {

170         int retries = 100000;

171

172         while (--retries && (inb_p(HD_STATUS)&0xc0)!=0x40);

173         return (retries);                        // ���صȴ�ѭ��������

174 }

175

    //// ���Ӳ��ִ��������״̬����win ��ʾ����˹��Ӳ�̵���д��

    // ��ȡ״̬�Ĵ����е�����ִ�н��״̬�� ����0��ʾ������1��ʾ���������ִ���������

    // ����Ҫ�ٶ�����Ĵ���HD_ERROR��0x1f1����

176 static int win_result(void)

177 {

178         int i=inb_p(HD_STATUS);             // ȡ״̬��Ϣ��

179

180         if ((i & (BUSY_STAT | READY_STAT | WRERR_STAT | SEEK_STAT | ERR_STAT))

181                 == (READY_STAT | SEEK_STAT))

182                 return(0); /* ok */

183         if (i&1) i=inb(HD_ERROR);          // ��ERR_STAT��λ�����ȡ����Ĵ�����

184         return (1);

185 }

186

    //// ��Ӳ�̿�������������顣

    // ������drive - Ӳ�̺�(0-1)��nsect - ��д��������sect  - ��ʼ������

    //       head  - ��ͷ�ţ�     cyl   - ����ţ�    cmd   - �����루�������������б�����

    //       intr_addr() - Ӳ���жϴ��������н����õ�C��������ָ�롣

    // �ú�����Ӳ�̿���������֮��������ȫ��ָ�����do_hdΪӲ���жϴ��������н����õ�

    // C��������ָ�롣Ȼ���ٷ���Ӳ�̿����ֽں�7�ֽڵIJ�������顣

    // �ú�����Ӳ�̿���������֮��������ȫ�ֺ���ָ�����do_hdָ��Ӳ���жϴ��������н���

    // ���õ�C����������Ȼ���ٷ���Ӳ�̿����ֽں�7�ֽڵIJ�������顣Ӳ���жϴ�������Ĵ�

    // ��λ��kernel/sys_call.s�����235�д���

    // ��191�ж���1���Ĵ�������__res���ñ�������������1���Ĵ����У��Ա��ڿ��ٷ��ʡ�

    // �����ָ���Ĵ�������eax���������ǿ��԰Ѹþ�д�ɡ�register char __res asm("ax");����

187 static void hd_out(unsigned int drive,unsigned int nsect,unsigned int sect,

188                 unsigned int head,unsigned int cyl,unsigned int cmd,

189                 void (*intr_addr)(void))

190 {

191         register int port asm("dx");    // ����ֲ��Ĵ�������������ָ���Ĵ���dx�С�

192

    // ���ȶԲ���������Ч�Լ�顣����������Ŵ���1��ֻ����0��1�����ߴ�ͷ�Ŵ���15�����

    // ��֧�֣�ͣ����������жϲ�ѭ���ȴ�����������������ȴ�һ��ʱ�����δ�������ʾ

    // Ӳ�̿�����������Ҳͣ����

193         if (drive>1 || head>15)

194                 panic("Trying to write bad sector");

195         if (!controller_ready())

196                 panic("HD controller not ready");

    // ������������Ӳ���жϷ���ʱ�����õ�C����ָ��do_hd���ú���ָ�붨����blk.h�ļ���

    // ��56--109��֮�䣬���ر��������еĵ�83�к�100�У���Ȼ������Ӳ�̿��������Ͳ���

    // ������֮ǰ���涨Ҫ�������������˿ڣ�0x3f6������һָ��Ӳ�̵Ŀ����ֽڣ��Խ�����

    // Ӧ��Ӳ�̿��Ʒ�ʽ���ÿ����ֽڼ���Ӳ����Ϣ�ṹ�����е� ctl �ֶΡ�Ȼ����������˿�

    // 0x1f1�C0x1f7����7�ֽڵIJ�������顣

197         SET_INTR(intr_addr);                    // do_hd = intr_addr���ж��б����á�

198         outb_p(hd_info[drive].ctl,HD_CMD);      // ����ƼĴ�����������ֽڡ�

199         port=HD_DATA;                           // ��dxΪ���ݼĴ����˿�(0x1f0)��

200         outb_p(hd_info[drive].wpcom>>2,++port); // ������дԤ���������(���4)��

201         outb_p(nsect,++port);                   // ��������/д����������

202         outb_p(sect,++port);                    // ��������ʼ������

203         outb_p(cyl,++port);                     // ����������ŵ�8λ��

204         outb_p(cyl>>8,++port);                  // ����������Ÿ�8λ��

205         outb_p(0xA0|(drive<<4)|head,++port);    // ��������������+��ͷ�š�

206         outb(cmd,++port);                       // ���Ӳ�̿������

207 }

208

    //// �ȴ�Ӳ�̾�����

    // �ú���ѭ���ȴ���״̬������æ��־λ��λ�������о�����Ѱ��������־��λ�����ʾӲ��

    // �������ɹ�����0��������һ��ʱ����Ϊæ���򷵻�1��

209 static int drive_busy(void)

210 {

211         unsigned int i;

212         unsigned char c;

213

    // ѭ����ȡ����������״̬�Ĵ���HD_STATUS���ȴ�������־λ��λ����æλ��λ��Ȼ����

    // ����æλ������λ��Ѱ������λ�������о�����Ѱ��������־��λ�����ʾӲ�̾���������

    // 0�������ʾ�ȴ���ʱ�����Ǿ�����ʾ��Ϣ��������1��

214         for (i = 0; i < 50000; i++) {

215                 c = inb_p(HD_STATUS);                     // ȡ��������״̬�ֽڡ�

216                 c &= (BUSY_STAT | READY_STAT | SEEK_STAT);

217                 if (c == (READY_STAT | SEEK_STAT))

218                         return 0;

219         }

220         printk("HD controller times out\n\r");   // �ȴ���ʱ����ʾ��Ϣ��������1��

221         return(1);

222 }

223

    //// ��ϸ�λ������У����Ӳ�̿�������

    // ��������ƼĴ����˿ڣ�0x3f6������������λ��4�������ֽڡ�Ȼ��ѭ���ղ����ȴ�һ��ʱ

    // ���ÿ�����ִ�и�λ��������������ö˿ڷ��������Ŀ����ֽ�(����ֹ���ԡ��ض�)������

    // ��Ӳ�̾��������ȴ�Ӳ�̾�����ʱ������ʾ������Ϣ��Ȼ���ȡ����Ĵ������ݣ����䲻��

    // ��1����ʾ�޴�������ʾӲ�̿�������λʧ����Ϣ��

224 static void reset_controller(void)

225 {

226         int     i;

227

228         outb(4,HD_CMD);                       // ����ƼĴ����˿ڷ��͸�λ�����ֽڡ�

229         for(i = 0; i < 1000; i++) nop();      // �ȴ�һ��ʱ�䡣

230         outb(hd_info[0].ctl & 0x0f ,HD_CMD);  // �������������ֽ�(����ֹ���ԡ��ض�)��

231         if (drive_busy())

232                 printk("HD-controller still busy\n\r");

233         if ((i = inb(HD_ERROR)) != 1)

234                 printk("HD-controller reset failed: %02x\n\r",i);

235 }

236

    //// Ӳ�̸�λ������

    // ���ȸ�λ������У����Ӳ�̿�������Ȼ����Ӳ�̿���������������������������ڱ�

    // ���������Ӳ���жϴ����������ֻ���ñ���������ʱ�ú��������ִ�и�����Ľ����

    // ���Ƿ�Ҫ���г����������Ǽ���ִ���������������

237 static void reset_hd(void)

238 {

239         static int i;

240

    // �����λ��־reset����λ�ģ����ڰѸ�λ��־�����ִ�и�λӲ�̿�����������Ȼ��

    // ��Ե�i��Ӳ������������͡����������������������������ִ���˸�������ֻ�

    // ����Ӳ���ж��źš���ʱ�������ᱻ�жϹ��̵��ö��ٴ�ִ�С�����reset�Ѿ���־��λ��

    // ��˻�����ȥִ��246�п�ʼ����䣬�ж�����ִ���Ƿ������������Ƿ�������ͻ����

    // bad_rw_intr() ������ͳ�Ƴ������������ݴ�ȷ���Ƿ�������reset��־�������������

    // reset��־����ת��repeat����ִ�б�����������λ�����������������һ��Ӳ�̷���

    // �����������������������������ͬ�����������ϵͳ��NR_HD��Ӳ�̶��Ѿ�����ִ��

    // �˷��͵�������ٴ�do_hd_request()������ʼ����������д�����

241 repeat:

242         if (reset) {

243                 reset = 0;

244                 i = -1;                       // ��ʼ����ǰӲ�̺ţ���̬��������

245                 reset_controller();

246         } else if (win_result()) {

247                 bad_rw_intr();

248                 if (reset)

249                         goto repeat;

250         }

251         i++;                                  // ������һ��Ӳ�̣���1����0����

252         if (i < NR_HD) {

253                 hd_out(i,hd_info[i].sect,hd_info[i].sect,hd_info[i].head-1,

254                         hd_info[i].cyl,WIN_SPECIFY,&reset_hd);

255         } else

256                 do_hd_request();              // ִ�����������

257 }

258

    //// ����Ӳ���жϵ��ú�����

    // ��������Ӳ���ж�ʱ��Ӳ���жϴ��������е��õ�Ĭ��C�����������ڱ����ú���ָ��Ϊ

    // NULLʱ���øú������μ���kernel/sys_call.s����256�У����ú�������ʾ������Ϣ��

    // ���ø�λ��־reset��Ȼ����������������go_hd_request()��������ִ�и�λ����

    // ������

259 void unexpected_hd_interrupt(void)

260 {

261         printk("Unexpected HD interrupt\n\r");

262         reset = 1;

263         do_hd_request();

264 }

265

    //// ��дӲ��ʧ�ܴ������ú�����

    // ���������ʱ�ij����������ڻ����7��ʱ���������ǰ��������ѵȴ�������Ľ��̣�

    // ���Ҷ�Ӧ���������±�־��λ����ʾ����û�и��¡������дһ����ʱ�ij��������Ѿ�����

    // 3�Σ���Ҫ��ִ�и�λӲ�̿��������������ø�λ��־����

266 static void bad_rw_intr(void)

267 {

268         if (++CURRENT->errors >= MAX_ERRORS)

269                 end_request(0);

270         if (CURRENT->errors > MAX_ERRORS/2)

271                 reset = 1;

272 }

273

    //// �������жϵ��ú�����

    // �ú�������Ӳ�̶��������ʱ������Ӳ���жϹ����б����á�

    // �ڶ�����ִ�к�����Ӳ���ж��źţ���ִ��Ӳ���жϴ������򣬴�ʱ��Ӳ���жϴ�������

    // �е��õ�C����ָ��do_hd�Ѿ�ָ��read_intr()����˻���һ�ζ�����������ɣ��������

    // ��ͻ�ִ�иú�����

274 static void read_intr(void)

275 {

    // �ú��������жϴ˴ζ���������Ƿ����������������������������æ״̬����������

    // ִ�д�������Ӳ�̲���ʧ�����⣬�����ٴ�����Ӳ������λ������ִ�����������

    // Ȼ�󷵻ء�ÿ�ζ�������������Ե�ǰ�����������������ۼƣ����������������������

    // ����������һ�룬�����ִ��Ӳ�̸�λ������Ȼ����ִ�б������������������������

    // �����ڵ������������������MAX_ERRORS��7�Σ������������������Ĵ�����ȥ������

    // ������һ�������

276         if (win_result()) {                   // ��������æ����д��������ִ�д���

277                 bad_rw_intr();                // ����ж�дӲ��ʧ�ܴ�����

278                 do_hd_request();              // �ٴ�����Ӳ������Ӧ(��λ)������

279                 return;

280         }

    // ���������û�г�����������ݼĴ����˿ڰ�1�����������ݶ���������Ļ������У�����

    // �ݼ������������ȡ��������ֵ�����ݼ��󲻵��� 0����ʾ��������������ûȡ�꣬����

    // �ٴ����жϵ���C����ָ��do_hdΪread_intr()��ֱ�ӷ��أ��ȴ�Ӳ���ڶ�����1������

    // ���ݺ󷢳��жϲ��ٴε��ñ�������ע�⣺281������е�256��ָ�ڴ��֣���512�ֽڡ�

    // ע��1��262���ٴ���do_hdָ��ָ��read_intr()����ΪӲ���жϴ�������ÿ�ε���do_hd

    // ʱ���Ὣ�ú���ָ���ÿա��μ�sys_call.s�����251��253�С�

281         port_read(HD_DATA,CURRENT->buffer,256);    // �����ݵ�����ṹ��������

282         CURRENT->errors = 0;                 // �����������

283         CURRENT->buffer += 512;              // ����������ָ�룬ָ���µĿ�����

284         CURRENT->sector++;                   // ��ʼ�����ż�1��

285         if (--CURRENT->nr_sectors) {         // ��������������������û���꣬����

286                 SET_INTR(&read_intr);        // ��Ӳ�̵���C����ָ��Ϊread_intr()��

287                 return;

288         }

    // ִ�е��ˣ�˵�������������ȫ�����������Ѿ����꣬�����end_request()����ȥ������

    // ����������ˡ� ����ٴε��� do_hd_request()��ȥ��������Ӳ�������ִ������Ӳ��

    // ���������

289         end_request(1);                         // �����Ѹ��±�־��λ��1����

290         do_hd_request();

291 }

292

    //// д�����жϵ��ú�����

    // �ú�������Ӳ��д�������ʱ������Ӳ���жϹ����б����á�����������read_intr()���ơ�

    // ��д����ִ�к�����Ӳ���ж��źţ���ִ��Ӳ���жϴ������򣬴�ʱ��Ӳ���жϴ�������

    // �е��õ�C����ָ��do_hd�Ѿ�ָ��write_intr()����˻���һ��д����������ɣ��������

    // ��ͻ�ִ�иú�����

293 static void write_intr(void)

294 {

    // �ú��������жϴ˴�д��������Ƿ����������������������������æ״̬����������

    // ִ�д�������Ӳ�̲���ʧ�����⣬�����ٴ�����Ӳ������λ������ִ�����������

    // Ȼ�󷵻ء��� bad_rw_intr() �����У�ÿ�β�����������Ե�ǰ�����������������ۼƣ�

    // �������������������������������һ�룬�����ִ��Ӳ�̸�λ������Ȼ����ִ�б�����

    // ������������������Ѿ����ڵ������������������MAX_ERRORS��7�Σ������������

    // ������Ĵ�����ȥ������������һ�������do_hd_request()�л���ݵ�ʱ����ı�־

    // ״̬���б��Ƿ���Ҫ��ִ�и�λ������У���Ȳ�����Ȼ���ټ���������һ�������

295         if (win_result()) {                 // ���Ӳ�̿��������ش�����Ϣ��

296                 bad_rw_intr();              // �����Ƚ���Ӳ�̶�дʧ�ܴ�����

297                 do_hd_request();            // �ٴ�����Ӳ������Ӧ(��λ)������

298                 return;

299         }

    // ��ʱ˵������дһ���������ɹ�����˽���д��������1�����䲻Ϊ0����˵����������

    // Ҫд�����ǰѵ�ǰ������ʼ������ +1�����������������ݻ�����ָ��ָ����һ����д��

    // ���ݡ�Ȼ��������Ӳ���жϴ��������е��õ�C����ָ��do_hd��ָ�򱾺�������������

    // ���������ݶ˿�д��512�ֽ����ݣ�Ȼ��������ȥ�ȴ�����������Щ����д��Ӳ�̺��

    // �����жϡ�

300         if (--CURRENT->nr_sectors) {          // ����������Ҫд����

301                 CURRENT->sector++;            // ��ǰ������ʼ������+1��

302                 CURRENT->buffer += 512;       // �������󻺳���ָ�룬

303                 SET_INTR(&write_intr);        // do_hd�ú���ָ��Ϊwrite_intr()��

304                 port_write(HD_DATA,CURRENT->buffer,256);  // �����ݶ˿�д256�֡�

305                 return;

306         }

    // �������������ȫ�����������Ѿ�д�꣬�����end_request()����ȥ����������������ˡ�

    // ����ٴε��� do_hd_request()��ȥ��������Ӳ�������ִ������Ӳ�����������

307         end_request(1);                       // ��������������ˣ������ø��±�־����

308         do_hd_request();                      // ִ������Ӳ�����������

309 }

310

    //// Ӳ������У������λ���жϵ��ú�����

    // �ú�������Ӳ��ִ������У��������������Ӳ���ж��б����á�

    // ���Ӳ�̿��������ش�����Ϣ���������Ƚ���Ӳ�̶�дʧ�ܴ�����Ȼ������Ӳ������Ӧ

    // ����λ�������� �� bad_rw_intr() �����У�ÿ�β�����������Ե�ǰ����������������

    // �ۼƣ��������������������������������һ�룬�����ִ��Ӳ�̸�λ������Ȼ����ִ��

    // ������������������������Ѿ����ڵ������������������MAX_ERRORS��7�Σ������

    // ������������Ĵ�����ȥ������������һ�������do_hd_request() �л���ݵ�ʱ����

    // �ı�־״̬���б��Ƿ���Ҫ��ִ�и�λ������У���Ȳ�����Ȼ���ټ���������һ�����

311 static void recal_intr(void)

312 {

313         if (win_result())                // �����س����������bad_rw_intr()��

314                 bad_rw_intr();

315         do_hd_request();

316 }

317

    // Ӳ�̲�����ʱ������

    // ����������do_timer()�У�kernel/sched.c����340�У������á�����Ӳ�̿�����������

    // һ����������ھ�����hd_timeout��ϵͳ�δ���������û�з���һ��Ӳ���ж��źţ�

    // ��˵������������Ӳ�̣�������ʱ����ʱdo_timer()�ͻ���ñ��������ø�λ��־reset

    // ������do_hd_request()ִ�и�λ����������Ԥ��ʱ���ڣ�200�δ�Ӳ�̿�����������Ӳ

    // ���жϲ���ʼִ��Ӳ���жϴ���������ôht_timeoutֵ�ͻ����жϴ��������б���0��

    // ��ʱdo_timer()�ͻ�������������

318 void hd_times_out(void)

319 {

    // �����ǰ��û��������Ҫ�������豸������ָ��ΪNULL�������޳�ʱ���ԣ�ֱ�ӷ��ء���

    // ������ʾ������Ϣ��Ȼ���жϵ�ǰ������ִ�й����з����ij��������Ƿ��Ѿ������趨ֵ

    // MAX_ERRORS��7�������������ʧ����ʽ��������������Ĵ��������������ݸ��±�־����

    // Ȼ����жϹ����е��õ�C����ָ��do_hd�ÿգ������ø�λ��־reset���̶���������

    // ��������do_hd_request()��ȥִ�и�λ������

320         if (!CURRENT)

321                 return;

322         printk("HD timeout");

323         if (++CURRENT->errors >= MAX_ERRORS)

324                 end_request(0);

325         SET_INTR(NULL);                        // ��do_hd = NULL,time_out=200��

326         reset = 1;                             // ���ø�λ��־��

327         do_hd_request();

328 }

329

    //// ִ��Ӳ�̶�д���������

    // �ú��������豸��ǰ�������е��豸�ź���ʼ��������Ϣ���ȼ���õ���ӦӲ���ϵ�����š�

    // ��ǰ�ŵ��������š���ͷ�����ݣ�Ȼ���ٸ����������е����READ/WRITE����Ӳ�̷�����Ӧ

    // ��/д��� ����������λ��־��Ӳ������У����־�ѱ���λ����ô���Ȼ�ȥִ�и�λ������

    // У��������

    // ���������ʱ�ǿ��豸�ĵ�1����ԭ���豸���У�������豸��ǰ������ָ���ֱ��ָ�����

    // ����μ�ll_rw_blk.c��28�У����������̵��ñ�����ִ�ж�д������������һ����д����

    // ��ɶ�������Ӳ���жϹ����У���������������Ҫ��������Ҳ����Ӳ���жϹ����е��ñ�������

    // �μ�kernel/sys_call.s��235�С�

330 void do_hd_request(void)

331 {

332         int i,r;

333         unsigned int block,dev;

334         unsigned int sec,head,cyl;

335         unsigned int nsect;

336

    // �������ȼ��������ĺϷ��ԡ��������������û�����������˳����μ�blk.h��127�У���

    // Ȼ��ȡ�豸���е����豸�ţ����б����Ӳ���豸�ŵ�˵�����Լ��豸��ǰ�������е���ʼ

    // �����š����豸�ż���ӦӲ���ϸ�������������豸�Ų����ڻ�����ʼ�������ڸ� ������

    // ����-2������������������ת�����repeat����������INIT_REQUEST��ʼ��������Ϊ

    // һ��Ҫ���дһ�����ݣ�2����������1024�ֽڣ�����������������Ų��ܴ��ڷ��������

    // �����ڶ��������š�Ȼ��ͨ���������豸�Ŷ�Ӧ��������ʼ�����ţ��Ͱ���Ҫ��д�Ŀ��Ӧ

    // ������Ӳ�̵ľ���������block�ϡ������豸�ű�5�������ɵõ���Ӧ��Ӳ�̺š�

337         INIT_REQUEST;

338         dev = MINOR(CURRENT->dev);

339         block = CURRENT->sector;                         // �������ʼ������

340         if (dev >= 5*NR_HD || block+2 > hd[dev].nr_sects) {

341                 end_request(0);

342                 goto repeat;                             // �ñ����blk.h����档

343         }

344         block += hd[dev].start_sect;

345         dev /= 5;                      // ��ʱdev����Ӳ�̺ţ�Ӳ��0����Ӳ��1����

    // Ȼ�������õľ���������block��Ӳ�̺�dev�����ǾͿ��Լ������ӦӲ���еĴŵ�����

    // ���ţ�sec������������ţ�cyl�� �ʹ�ͷ�ţ�head���� ����Ƕ��Ļ����뼴��������Ӳ

    // ����Ϣ�ṹ�е�ÿ�ŵ���������Ӳ�̴�ͷ����������Щ���ݡ����㷽��Ϊ��

    // 310--311�д����ʼʱeax��������block��edx����0��divlָ���edx:eax��ɵ�����

    // �ų���ÿ�ŵ���������hd_info[dev].sect��������������ֵ��eax�У�������edx�С���

    // ��eax���ǵ�ָ��λ�õĶ�Ӧ�ܴŵ��������д�ͷ�棩��edx���ǵ�ǰ�ŵ��ϵ������š�

    // 312--313�д����ʼʱeax�Ǽ�����Ķ�Ӧ�ܴŵ�����edx����0��divlָ���edx:eax

    // �Ķ�Ӧ�ܴŵ�������Ӳ���ܴ�ͷ����hd_info[dev].head������eax�еõ�������ֵ������

    // �ţ�cyl����edx�еõ����������Ƕ�Ӧ�õ�ǰ��ͷ�ţ�head����

346         __asm__("divl %4":"=a" (block),"=d" (sec):"0" (block),"1" (0),

347                 "r" (hd_info[dev].sect));

348         __asm__("divl %4":"=a" (cyl),"=d" (head):"0" (block),"1" (0),

349                 "r" (hd_info[dev].head));

350         sec++;                               // �Լ������õ�ǰ�ŵ������Ž��е�����

351         nsect = CURRENT->nr_sectors;         // ����/д����������

    // ��ʱ���ǵõ�������д��Ӳ����ʼ����block����Ӧ��Ӳ��������ţ�cyl�����ڵ�ǰ�ŵ�

    // �ϵ������ţ�sec������ͷ�ţ�head���Լ�����д������������nsect���� �������ǿ��Ը�

    // ����Щ��Ϣ��Ӳ�̿���������I/O������Ϣ�ˡ� ���ڷ���֮ǰ���ǻ���Ҫ�ȿ����Ƿ��и�

    // λ������״̬������У��Ӳ�̵ı�־��ͨ���ڸ�λ����֮����Ҫ����У��Ӳ�̴�ͷλ�á�

    // ����Щ��־�ѱ���λ����˵��ǰ���Ӳ�̲������ܳ�����һЩ���⣬����������ϵͳ��һ

    // ��Ӳ�̶�д����������� �������Ǿ���Ҫ���¸�λӲ�̻������������У��Ӳ�̡�

 

    // �����ʱ��λ��־reset����λ�ģ�����Ҫִ�и�λ��������λӲ�̺Ϳ�����������Ӳ��

    // ��Ҫ����У����־�����ء�reset_hd()��������Ӳ�̿��������͸�λ������У�������

    // Ȼ����Ӳ�̿��������������������������

352         if (reset) {

353                 recalibrate = 1;             // ��������У����־��

354                 reset_hd();

355                 return;

356         }

    // �����ʱ����У����־��recalibrate������λ�ģ������ȸ�λ�ñ�־��Ȼ����Ӳ�̿���

    // ����������У������������ִ��Ѱ���������ô����κεط��Ĵ�ͷ�ƶ���0���档

357         if (recalibrate) {

358                 recalibrate = 0;

359                 hd_out(dev,hd_info[CURRENT_DEV].sect,0,0,0,

360                         WIN_RESTORE,&recal_intr);

361                 return;

362         }      

    // �������������־��û����λ����ô���ǾͿ��Կ�ʼ��Ӳ�̿������������������ݶ�/д

    // ���������ˡ������ǰ������д��������������д���ѭ����ȡ״̬�Ĵ�����Ϣ����

    // ����������־DRQ_STAT�Ƿ���λ��DRQ_STAT��Ӳ��״̬�Ĵ������������λ����ʾ��

    // �����Ѿ�׼���������������ݶ˿�֮�䴫��һ���ֻ�һ���ֽڵ����ݡ��ⷽ�����Ϣ�ɲ�

    // ������ǰ���Ӳ�̲�����/дʱ��ͼ������������DRQ��λ���˳�ѭ���� ���ȵ�ѭ����

    // ��Ҳû����λ�����ʾ���͵�Ҫ��дӲ������ʧ�ܣ�������תȥ�������ֵ���������ִ

    // ����һ��Ӳ�����󡣷������ǾͿ�����Ӳ�̿��������ݼĴ����˿�HD_DATAд��1������

    // �����ݡ�

363         if (CURRENT->cmd == WRITE) {

364                 hd_out(dev,nsect,sec,head,cyl,WIN_WRITE,&write_intr);

365                 for(i=0 ; i<10000 && !(r=inb_p(HD_STATUS)&DRQ_STAT) ; i++)

366                         /* nothing */ ;

367                 if (!r) {

368                         bad_rw_intr();

369                         goto repeat;                // �ñ����blk.h�ļ�����档

370                 }

371                 port_write(HD_DATA,CURRENT->buffer,256);

    // �����ǰ�����Ƕ�Ӳ�����ݣ�����Ӳ�̿��������Ͷ����������������Ч��ͣ����

372         } else if (CURRENT->cmd == READ) {

373                 hd_out(dev,nsect,sec,head,cyl,WIN_READ,&read_intr);

374         } else

375                 panic("unknown hd-command");

376 }

377

    // Ӳ��ϵͳ��ʼ����

    // ����Ӳ���ж���������������Ӳ�̿����������ж������źš�

    // �ú�������Ӳ���豸�������������ָ��Ϊdo_hd_request()��Ȼ������Ӳ���ж�������

    // ����hd_interrupt��kernel/sys_call.s����235�У������жϴ������̵�ַ�� Ӳ���жϺ�

    // Ϊint 0x2E��46������Ӧ8259AоƬ���ж������ź�IRQ13�����Ÿ�λ��������8259A int2

    // ������λ��������Ƭ�����ж������źš��ٸ�λӲ�̵��ж���������λ���ڴ�Ƭ�ϣ�������

    // Ӳ�̿����������ж������źš��ж���������IDT���ж������������ú�set_intr_gate()

    // ��include/asm/system.h��ʵ�֡�

378 void hd_init(void)

379 {

380         blk_dev[MAJOR_NR].request_fn = DEVICE_REQUEST;     // do_hd_request()��

381         set_intr_gate(0x2E,&hd_interrupt);  // �����ж����д�������ָ�롣

382         outb_p(inb_p(0x21)&0xfb,0x21);      // ��λ��������8259A int2������λ��

383         outb(inb_p(0xA1)&0xbf,0xA1);        // ��λӲ���ж���������λ���ڴ�Ƭ�ϣ���

384 }

385


 


 

9.3 ����9-3 linux/kernel/blk_drv/ll_rw_blk.c


  1 /*

  2  *  linux/kernel/blk_dev/ll_rw.c

  3  *

  4  * (C) 1991 Linus Torvalds

  5  */

  6

  7 /*

  8  * This handles all read/write requests to block devices

  9  */

 10 #include <errno.h>        // �����ͷ�ļ�������ϵͳ�и��ֳ����š�

 11 #include <linux/sched.h>  // ���ȳ���ͷ�ļ�������������ṹtask_struct������0���ݵȡ�

 12 #include <linux/kernel.h> // �ں�ͷ�ļ�������һЩ�ں˳��ú�����ԭ�ζ��塣

 13 #include <asm/system.h>   // ϵͳͷ�ļ������������û��޸�������/�ж��ŵȵ�Ƕ��ʽ���ꡣ

 14

 15 #include "blk.h"          // ���豸ͷ�ļ��������������ݽṹ�����豸���ݽṹ�ͺ����Ϣ��

 16

 17 /*

 18  * The request-struct contains all necessary data

 19  * to load a nr of sectors into memory

 20  */

    /*

     * ����ṹ�к��м���nr���������ݵ��ڴ���ȥ�����б������Ϣ��

     */

    // ������������С�����NR_REQUEST = 32�������

 21 struct request request[NR_REQUEST];

 22

 23 /*

 24  * used to wait on when there are no free requests

 25  */

    /*

     * ����������������û�п�����ʱ���̵���ʱ�ȴ�����

     */

 26 struct task_struct * wait_for_request = NULL;

 27

 28 /* blk_dev_struct is:

 29  *      do_request-address

 30  *      next-request

 31  */

    /* blk_dev_struct���豸�ṹ�ǣ����μ��ļ�kernel/blk_drv/blk.h����45�У�

     *      do_request-address      // ��Ӧ���豸�ŵ�����������ָ�롣

     *      current-request         // ���豸����һ������

     */

    // ���豸���顣������ʹ�����豸����Ϊ������ʵ�����ݽ��ڸ����豸���������ʼ��ʱ���롣

    // ���磬Ӳ�����������ʼ��ʱ��hd.c��343�У�����һ����伴��������blk_dev[3]�����ݡ�

 32 struct blk_dev_struct blk_dev[NR_BLK_DEV] = {

 33         { NULL, NULL },         /* no_dev */     // 0 - ���豸��

 34         { NULL, NULL },         /* dev mem */    // 1 - �ڴ档

 35         { NULL, NULL },         /* dev fd */     // 2 - �����豸��

 36         { NULL, NULL },         /* dev hd */     // 3 - Ӳ���豸��

 37         { NULL, NULL },         /* dev ttyx */   // 4 - ttyx�豸��

 38         { NULL, NULL },         /* dev tty */    // 5 - tty�豸��

 39         { NULL, NULL }          /* dev lp */     // 6 - lp��ӡ���豸��

 40 };

 41

 42 /*

 43  * blk_size contains the size of all block-devices:

 44  *

 45  * blk_size[MAJOR][MINOR]

 46  *

 47  * if (!blk_size[MAJOR]) then no minor size checking is done.

 48  */

    /*

     * blk_size���麬�����п��豸�Ĵ�С������������

     * blk_size[MAJOR][MINOR]

     * ��� (!blk_size[MAJOR])���򲻱ؼ�����豸�Ŀ�������

     */

    // �豸���ݿ�����ָ�����顣ÿ��ָ����ָ��ָ�����豸�ŵ��ܿ������顣���ܿ�������ÿһ

    // ���Ӧ���豸��ȷ����һ�����豸����ӵ�е����ݿ�������1���С = 1KB����

 49 int * blk_size[NR_BLK_DEV] = { NULL, NULL, };

 50

    // ����ָ������顣

    // ���ָ���Ļ�����Ѿ�������������������ʹ�Լ�˯�ߣ������жϵصȴ�����ֱ����ִ�н�

    // ��������������ȷ�ػ��ѡ�

 51 static inline void lock_buffer(struct buffer_head * bh)

 52 {

 53         cli();                          // ���ж����ɡ�

 54         while (bh->b_lock)              // ����������ѱ�������˯�ߣ�ֱ��������������

 55                 sleep_on(&bh->b_wait);

 56         bh->b_lock=1;                   // ���������û�������

 57         sti();                          // ���жϡ�

 58 }

 59

    // �ͷţ������������Ļ�������

    // �ú�����blk.h�ļ��е�ͬ��������ȫһ����

 60 static inline void unlock_buffer(struct buffer_head * bh)

 61 {

 62         if (!bh->b_lock)                // ����û�����û�б����������ӡ������Ϣ��

 63                 printk("ll_rw_block.c: buffer not locked\n\r");

 64         bh->b_lock = 0;                 // ��������־��

 65         wake_up(&bh->b_wait);           // ���ѵȴ��û�����������

 66 }

 67

 68 /*

 69  * add-request adds a request to the linked list.

 70  * It disables interrupts so that it can muck with the

 71  * request-lists in peace.

 72  *

 73  * Note that swapping requests always go before other requests,

 74  * and are done in the order they appear.

 75  */

    /*

     * add-request()�������м���һ�����������ر��жϣ�

     * �������ܰ�ȫ�ش������������ˡ�

     *

     * ע�⣬����������������������֮ǰ���������������dz�

     * �ֵ�˳����ɡ�

     */

    //// �������м��������

    // ����dev��ָ�����豸�ṹָ�룬�ýṹ���д����������ָ��͵�ǰ����������ָ�룻

    // req�������ú����ݵ�������ṹָ�롣

    // ���������Ѿ����úõ�������req���ӵ�ָ���豸�������������С�������豸�ĵ�ǰ����

    // ������ָ��Ϊ�գ����������reqΪ��ǰ��������̵����豸�����������������Ͱ�

    // req��������뵽�������������С�

 76 static void add_request(struct blk_dev_struct * dev, struct request * req)

 77 {

 78         struct request * tmp;

 79

    // �����ٽ�һ���Բ����ṩ���������ָ��ͱ�־����ʼ���á��ÿ��������е���һ������ָ

    // �룬���жϲ������������ػ��������־��

 80         req->next = NULL;

 81         cli();                                // ���жϡ�

 82         if (req->bh)

 83                 req->bh->b_dirt = 0;          // �建�������ࡱ��־��

    // Ȼ��鿴ָ���豸�Ƿ��е�ǰ��������鿴�豸�Ƿ���æ�����ָ���豸dev��ǰ������

    // ��current_request���Ӷ�Ϊ�գ����ʾĿǰ���豸û������������ǵ�1�������Ҳ��

    // Ψһ��һ������˿ɽ����豸��ǰ����ָ��ֱ��ָ��������������ִ����Ӧ�豸������

    // ������

 84         if (!(tmp = dev->current_request)) {

 85                 dev->current_request = req;

 86                 sti();                     // ���жϡ�

 87                 (dev->request_fn)();       // ִ��������������Ӳ����do_hd_request()��

 88                 return;

 89         }

    // ���Ŀǰ���豸�Ѿ��е�ǰ�������ڴ��������������õ����㷨������Ѳ���λ�ã�Ȼ��

    // ��ǰ��������뵽���������С������������У�����жϳ�������������Ļ����ͷָ��գ�

    // ��û�л���飬��ô����Ҫ��һ������Ѿ��п��õĻ���顣�������ǰ����λ�ã�tmp

    // ֮�󣩴��Ŀ�������ͷָ�벻�գ���ѡ�����λ�á������˳�ѭ���������������˴���

    // ����жϲ��˳������������㷨���������ô��̴�ͷ���ƶ�������С���Ӷ����ƣ����٣�

    // Ӳ�̷���ʱ�䡣

    // ����forѭ����if������ڰ�req��ָ��������������У������������е����������Ƚϣ�

    // �ҳ�req����ö��е���ȷλ��˳��Ȼ���ж�ѭ��������req���뵽�ö�����ȷλ�ô���

 90         for ( ; tmp->next ; tmp=tmp->next) {

 91                 if (!req->bh)

 92                         if (tmp->next->bh)

 93                                 break;

 94                         else

 95                                 continue;

 96                 if ((IN_ORDER(tmp,req) ||

 97                     !IN_ORDER(tmp,tmp->next)) &&

 98                     IN_ORDER(req,tmp->next))

 99                         break;

100         }

101         req->next=tmp->next;

102         tmp->next=req;

103         sti();

104 }

105

    //// ���������������������С�

    // ����major�����豸�ţ�rw��ָ�����bh�Ǵ�����ݵĻ�����ͷָ�롣

106 static void make_request(int major,int rw, struct buffer_head * bh)

107 {

108         struct request * req;

109         int rw_ahead;

110

111 /* WRITEA/READA is special case - it is not really needed, so if the */

112 /* buffer is locked, we just forget about it, else it's a normal read */

    /* WRITEA/READA��һ��������� - ���Dz��DZ�Ҫ����������������Ѿ�������*/

    /* ���ǾͲ��ù���������Ļ���ֻ��һ��һ��Ķ������� */

    // ����'READ'��'WRITE'�����'A'�ַ�����Ӣ�ĵ���Ahead����ʾ��ǰԤ��/д���ݿ����˼��

    // �ú������ȶ�����READA/WRITEA���������һЩ���������������������ָ���Ļ�����

    // ����ʹ�ö��ѱ�����ʱ���ͷ���Ԥ��/д���󡣷������Ϊ��ͨ��READ/WRITE������в�����

    // ���⣬�����������������Ȳ��� READҲ���� WRITE�����ʾ�ں˳����д�����ʾ������

    // Ϣ��ͣ����ע�⣬���޸�����֮ǰ������Ϊ�����Ƿ���Ԥ��/д���������˱�־rw_ahead��

113         if (rw_ahead = (rw == READA || rw == WRITEA)) {

114                 if (bh->b_lock)

115                         return;

116                 if (rw == READA)

117                         rw = READ;

118                 else

119                         rw = WRITE;

120         }

121         if (rw!=READ && rw!=WRITE)

122                 panic("Bad block dev command, must be R/W/RA/WA");

123         lock_buffer(bh);

124         if ((rw == WRITE && !bh->b_dirt) || (rw == READ && bh->b_uptodate)) {

125                 unlock_buffer(bh);

126                 return;

127         }

128 repeat:

129 /* we don't allow the write-requests to fill up the queue completely:

130  * we want some room for reads: they take precedence. The last third

131  * of the requests are only for reads.

132  */

    /* ���Dz����ö�����ȫ����д�����������ҪΪ��������һЩ�ռ䣺������

     * �����ȵġ�������еĺ�����֮һ�ռ�����ڶ������

     */

    // �ã��������DZ���Ϊ���������ɲ����Ӷ�/д�������ˡ�����������Ҫ������������Ѱ�ҵ�

    // һ��������ۣ��������������������̴���������ĩ�˿�ʼ����������Ҫ�󣬶��ڶ�

    // ������������ֱ�ӴӶ���ĩβ��ʼ������������д�����ֻ�ܴӶ���2/3�������ͷ����

    // ���������롣�������ǿ�ʼ�Ӻ���ǰ������������ṹrequest���豸�ֶ�devֵ = -1ʱ��

    // ��ʾ����δ��ռ�ã����У������û��һ���ǿ��еģ���ʱ����������ָ���Ѿ�����Խ��ͷ

    // ��������鿴�˴������Ƿ�����ǰ��/д��READA��WRITEA���������������˴����������

    // �����ñ������������˯�ߣ��Եȴ���������ڳ��������һ����������������С�

133         if (rw == READ)

134                 req = request+NR_REQUEST;          // ���ڶ����󣬽�ָ��ָ�����β����

135         else

136                 req = request+((NR_REQUEST*2)/3);  // ����д����ָ��ָ�����2/3����

137 /* find an empty request */                        /* ����һ���������� */

138         while (--req >= request)

139                 if (req->dev<0)

140                         break;

141 /* if none found, sleep on new requests: check for rw_ahead */

    /* ���û���ҵ���������øô����������˯�ߣ������Ƿ���ǰ��/д */

142         if (req < request) {                      // �����������ͷ�������޿����

143                 if (rw_ahead) {                   // ��������ǰ��/д�������˳���

144                         unlock_buffer(bh);

145                         return;

146                 }

147                 sleep_on(&wait_for_request);      // �����˯�ߣ������ٲ鿴������С�

148                 goto repeat;                      // ��ת110�С�

149         }

150 /* fill up the request-info, and add it to the queue */

    /* ���������������д������Ϣ���������������� */

    // OK������ִ�е������ʾ���ҵ�һ����������� �������������úõ����������͵���

    // add_request()�������ӵ���������У������˳�������ṹ��μ�blk_drv/blk.h��23�С�

    // req->sector�Ƕ�д��������ʼ�����ţ�req->buffer�������������ݵĻ�������

151         req->dev = bh->b_dev;             // �豸�š�

152         req->cmd = rw;                    // ����(READ/WRITE)��

153         req->errors=0;                    // ����ʱ�����Ĵ��������

154         req->sector = bh->b_blocknr<<1;   // ��ʼ���������ת����������(1��=2����)��

155         req->nr_sectors = 2;              // ����������Ҫ��д����������

156         req->buffer = bh->b_data;         // ���������ָ��ָ�����д�����ݻ�������

157         req->waiting = NULL;              // ����ȴ�����ִ����ɵĵط���

158         req->bh = bh;                     // �����ͷָ�롣

159         req->next = NULL;                 // ָ����һ�����

160         add_request(major+blk_dev,req);   // ����������������(blk_dev[major],req)��

161 }

162

    //// �ͼ�ҳ���д������Low Level Read Write Page����

    // ��ҳ�棨4K��Ϊ��λ���ʿ��豸���ݣ���ÿ�ζ�/д8���������μ�����ll_rw_blk()������

163 void ll_rw_page(int rw, int dev, int page, char * buffer)

164 {

165         struct request * req;

166         unsigned int major = MAJOR(dev);

167

    // ���ȶԺ��������ĺϷ��Խ��м�⡣����豸���豸�Ų����ڻ��߸��豸���������������

    // ���ڣ�����ʾ������Ϣ�������ء������������������Ȳ��� READҲ���� WRITE�����ʾ

    // �ں˳����д�����ʾ������Ϣ��ͣ����

168         if (major >= NR_BLK_DEV || !(blk_dev[major].request_fn)) {

169                 printk("Trying to read nonexistent block-device\n\r");

170                 return;

171         }

172         if (rw!=READ && rw!=WRITE)

173                 panic("Bad block dev command, must be R/W");

    // �ڲ�����������ɺ�����������ҪΪ���β����������������������Ҫ������������

    // Ѱ�ҵ�һ��������ۣ��������������������̴���������ĩ�˿�ʼ���������ǿ�ʼ��

    // ����ǰ������������ṹrequest���豸�ֶ�devֵ <0 ʱ����ʾ����δ��ռ�ã����У���

    // ���û��һ���ǿ��еģ���ʱ����������ָ���Ѿ�����Խ��ͷ���������ñ������������˯

    // �ߣ��Եȴ���������ڳ��������һ����������������С�

174 repeat:

175         req = request+NR_REQUEST;                 // ��ָ��ָ�����β����

176         while (--req >= request)

177                 if (req->dev<0)

178                         break;

179         if (req < request) {

180                 sleep_on(&wait_for_request);      // ˯�ߣ������ٲ鿴������С�

181                 goto repeat;                      // ��ת��174��ȥ����������

182         }

183 /* fill up the request-info, and add it to the queue */

    /* ���������������д������Ϣ���������������� */

    // OK������ִ�е������ʾ���ҵ�һ����������� �����������ú���������ѵ�ǰ����

    // ��Ϊ�����ж�˯���жϺ󣬾�ȥ����add_request()�������ӵ���������У�Ȼ��ֱ�ӵ���

    // ���Ⱥ����õ�ǰ����˯�ߵȴ�ҳ��ӽ����豸�ж��롣���ﲻ��make_request()��������

    // ֱ���˳�������������schedule()������Ϊmake_request()��������2���������ݡ�����

    // ����Ҫ�Խ����豸��/д8����������Ҫ���ϳ���ʱ�䡣��˵�ǰ���̿϶���Ҫ�ȴ���˯�ߡ�

    // �������ֱ�Ӿ��ý���ȥ˯���ˣ�ʡ���ڳ��������ط���Ҫ������Щ�жϲ�����

184         req->dev = dev;                           // �豸�š�

185         req->cmd = rw;                            // ����(READ/WRITE)��

186         req->errors = 0;                          // ��д�������������

187         req->sector = page<<3;                    // ��ʼ��д������

188         req->nr_sectors = 8;                      // ��д��������

189         req->buffer = buffer;                     // ���ݻ�������

190         req->waiting = current;                   // ��ǰ���̽��������ȴ����С�

191         req->bh = NULL;                           // �޻����ͷָ�루���ø��ٻ��壩��

192         req->next = NULL;                         // ��һ��������ָ�롣

193         current->state = TASK_UNINTERRUPTIBLE;    // ��Ϊ�����ж�״̬��

194         add_request(major+blk_dev,req);           // ���������������С�

195         schedule();

196 }      

197

    //// �ͼ����ݿ��д������Low Level Read Write Block����

    // �ú����ǿ��豸����������ϵͳ�������ֵĽӿں�����ͨ����fs/buffer.c�����б����á�

    // ��Ҫ�����Ǵ������豸��д��������뵽ָ�����豸��������С�ʵ�ʵĶ�д��������

    // ���豸��request_fn()������ɡ�����Ӳ�̲������ú�����do_hd_request()����������

    // �����ú�����do_fd_request()����������������do_rd_request()�� ���⣬�ڵ��øú�

    // ��֮ǰ����������Ҫ���ȰѶ�/д���豸����Ϣ�����ڻ����ͷ�ṹ�У����豸�š���š�

    // ������rw �C READ��READA��WRITE��WRITEA�����bh �C ���ݻ����ͷָ�롣

198 void ll_rw_block(int rw, struct buffer_head * bh)

199 {

200         unsigned int major;               // ���豸�ţ�����Ӳ����3����

201

    // ����豸���豸�Ų����ڻ��߸��豸������������������ڣ�����ʾ������Ϣ�������ء�

    // ���򴴽����������������С�

202         if ((major=MAJOR(bh->b_dev)) >= NR_BLK_DEV ||

203         !(blk_dev[major].request_fn)) {

204                 printk("Trying to read nonexistent block-device\n\r");

205                 return;

206         }

207         make_request(major,rw,bh);

208 }

209

    //// ���豸��ʼ���������ɳ�ʼ������main.c���á�

    // ��ʼ���������飬��������������Ϊ������(dev = -1)����32��(NR_REQUEST = 32)��

210 void blk_dev_init(void)

211 {

212         int i;

213

214         for (i=0 ; i<NR_REQUEST ; i++) {

215                 request[i].dev = -1;

216                 request[i].next = NULL;

217         }

218 }

219


 


 

9.4 ����9-4 linux/kernel/blk_drv/ramdisk.c


  1 /*

  2  *  linux/kernel/blk_drv/ramdisk.c

  3  *

  4  *  Written by Theodore Ts'o, 12/2/91

  5  */

    /* ��Theodore Ts'o���ƣ�12/2/91

     */

    // Theodore Ts'o (Ted Ts'o)��Linux�����е��������Linux�����緶Χ�ڵ�����Ҳ������

    // ��Ĺ��͡�����Linux����ϵͳ������ʱ�����ͻ��ż��������ΪLinux�ķ�չ�ṩ�˵�����

    // ���б�����maillist�����ڱ�����������������Linux��ftp������վ�㣨tsx-11.mit.edu����

    // ����������Ϊ���Linux�û��ṩ��������Linux�����������֮һ�������ʵ����ext2

    // �ļ�ϵͳ�����ļ�ϵͳ�ѳ�ΪLinux��������ʵ�ϵ��ļ�ϵͳ��׼����������Ƴ���ext3�ļ�

    // ϵͳ�����������ļ�ϵͳ���ȶ��ԡ��ɻָ��Ժͷ���Ч�ʡ���Ϊ�������Ƴ磬��97�ڣ�2002

    // ��5�£���LinuxJournal�ڿ�������Ϊ�˷�����������������˲ɷá�Ŀǰ��ΪIBM Linux

    // �������Ĺ��������������й�LSB (Linux Standard Base)�ȷ���Ĺ����������ĸ�����ҳ�ǣ�

    // http://thunk.org/tytso/)

  6

  7 #include <string.h>       // �ַ���ͷ�ļ�����Ҫ������һЩ�й��ַ���������Ƕ�뺯����

  8

  9 #include <linux/config.h> // �ں�����ͷ�ļ�������������Ժ�Ӳ�����ͣ�HD_TYPE����ѡ�

 10 #include <linux/sched.h>  // ���ȳ���ͷ�ļ�������������ṹtask_struct������0�����ݣ�

                              // ����һЩ�й��������������úͻ�ȡ��Ƕ��ʽ��ຯ������䡣

 11 #include <linux/fs.h>     // �ļ�ϵͳͷ�ļ��������ļ����ṹ��file��m_inode���ȡ�

 12 #include <linux/kernel.h> // �ں�ͷ�ļ�������һЩ�ں˳��ú�����ԭ�Ͷ��塣

 13 #include <asm/system.h>   // ϵͳͷ�ļ������������û��޸�������/�ж��ŵ�Ƕ��ʽ���ꡣ

 14 #include <asm/segment.h>  // �β���ͷ�ļ����������йضμĴ���������Ƕ��ʽ��ຯ����

 15 #include <asm/memory.h>   // �ڴ濽��ͷ�ļ�������memcpy()Ƕ��ʽ���꺯����

 16

    // ����RAM�����豸�ŷ��ų��������������������豸�ű����ڰ���blk.h�ļ�֮ǰ�����塣

    // ��Ϊblk.h�ļ���Ҫ�õ�������ų���ֵ��ȷ��һЩ�е������������źͺꡣ

 17 #define MAJOR_NR 1

 18 #include "blk.h"

 19

    // ���������ڴ��е���ʼλ�á���λ�û��ڵ�52���ϳ�ʼ������rd_init()��ȷ�����μ��ں�

    // ��ʼ������init/main.c����124�С�'rd'��'ramdisk'����д��

 20 char    *rd_start;                       // ���������ڴ��еĿ�ʼ��ַ��

 21 int     rd_length = 0;                   // ��������ռ�ڴ��С���ֽڣ���

 22

    // �����̵�ǰ���������������

    // �ú����ij���ṹ��Ӳ�̵�do_hd_request()�������ƣ��μ�hd.c��294�С��ڵͼ����豸

    // �ӿں���ll_rw_block()�����������̣�rd������������ӵ� rd��������֮�󣬾ͻ��

    // �øú����� rd��ǰ��������д������ú������ȼ��㵱ǰ��������ָ������ʼ������Ӧ��

    // ���������ڴ����ʼλ��addr ��Ҫ�����������Ӧ���ֽڳ���ֵ len��Ȼ�������������

    // ��������в���������д����WRITE���Ͱ���������ָ�������е�����ֱ�Ӹ��Ƶ��ڴ�λ��

    // addr�������Ƕ�������֮�����ݸ�����ɺ󼴿�ֱ�ӵ��� end_request() �Ա���������

    // ������������Ȼ����ת��������ʼ����ȥ������һ�����������û�����������˳���

 23 void do_rd_request(void)

 24 {

 25         int     len;

 26         char    *addr;

 27

    // ���ȼ��������ĺϷ��ԣ�����û�����������˳����μ�blk.h����127�У���Ȼ�������

    // �����������������ʼ�����������ڴ��ж�Ӧ�ĵ�ַaddr��ռ�õ��ڴ��ֽڳ���ֵlen��

    // �¾�����ȡ���������е���ʼ������Ӧ���ڴ���ʼλ�ú��ڴ泤�ȡ�����sector << 9��ʾ

    // sector * 512��������ֽ�ֵ��CURRENT������Ϊ (blk_dev[MAJOR_NR].current_request)��

 28         INIT_REQUEST;

 29         addr = rd_start + (CURRENT->sector << 9);

 30         len = CURRENT->nr_sectors << 9;

    // �����ǰ�����������豸�Ų�Ϊ1���߶�Ӧ�ڴ���ʼλ�ô���������ĩβ��������������

    // ����ת�� repeat ��ȥ������һ���������������� repeat �����ں� INIT_REQUEST �ڣ�

    // λ�ں�Ŀ�ʼ�����μ�blk.h�ļ���127�С�

 31         if ((MINOR(CURRENT->dev) != 1) || (addr+len > rd_start+rd_length)) {

 32                 end_request(0);

 33                 goto repeat;

 34         }

    // Ȼ�����ʵ�ʵĶ�д�����������д���WRITE�������������л����������ݸ��Ƶ���ַ

    // addr��������Ϊlen�ֽڡ�����Ƕ����READ������addr��ʼ���ڴ����ݸ��Ƶ�������

    // �������У�����Ϊlen�ֽڡ�������ʾ������ڣ�������

 35         if (CURRENT-> cmd == WRITE) {

 36                 (void ) memcpy(addr,

 37                               CURRENT->buffer,

 38                               len);

 39         } else if (CURRENT->cmd == READ) {

 40                 (void) memcpy(CURRENT->buffer,

 41                               addr,

 42                               len);

 43         } else

 44                 panic("unknown ramdisk-command");

    // Ȼ����������ɹ��������ø��±�־���������������豸����һ�����

 45         end_request(1);

 46         goto repeat;

 47 }

 48

 49 /*

 50  * Returns amount of memory which needs to be reserved.

 51  */

    /* �����ڴ�������ramdisk������ڴ��� */

    // �����̳�ʼ��������

    // �ú������������������豸�������������ָ��ָ��do_rd_request()��Ȼ��ȷ��������

    // �������ڴ��е���ʼ��ַ��ռ���ֽڳ���ֵ���������������������㡣��󷵻��������ȡ�

    // ��linux/Makefile�ļ������ù�RAMDISKֵ��Ϊ��ʱ����ʾϵͳ�лᴴ��RAM�������豸��

    // ����������µ��ں˳�ʼ�������У��������ͻᱻ���ã�init/main.c��L151�У����ú���

    // �ĵ�2������length�ᱻ��ֵ��RAMDISK * 1024����λΪ�ֽڡ�

 52 long rd_init(long mem_start, int length)

 53 {

 54         int     i;

 55         char    *cp;

 56

 57         blk_dev[MAJOR_NR].request_fn = DEVICE_REQUEST;  // do_rd_request()��

 58         rd_start = (char *) mem_start;                  // ����16MBϵͳ��ֵΪ4MB��

 59         rd_length = length;                             // ���������򳤶�ֵ��

 60         cp = rd_start;

 61         for (i=0; i < length; i++)                      // �������㡣

 62                 *cp++ = '\0';

 63         return(length);

 64 }

 65

 66 /*

 67  * If the root device is the ram disk, try to load it.

 68  * In order to do this, the root device is originally set to the

 69  * floppy, and we later change it to be ram disk.

 70  */

    /*

     * ������ļ�ϵͳ�豸(root device)��ramdisk�Ļ������Լ�������

     * root deviceԭ����ָ�����̵ģ����ǽ����ij�ָ��ramdisk��

     */

    //// ���԰Ѹ��ļ�ϵͳ���ص��������С�

    // �ú��������ں����ú���setup()��hd.c��156�У��б����á����⣬1���̿� = 1024�ֽڡ�

    // ��75���ϵı���block=256��ʾ���ļ�ϵͳӳ���ļ����洢��boot�̵�256���̿鿪ʼ����

 71 void rd_load(void)

 72 {

 73         struct buffer_head *bh;         // ���ٻ����ͷָ�롣

 74         struct super_block      s;      // �ļ�������ṹ��

 75         int             block = 256;    /* Start at block 256 */ /* ��ʼ��256�̿� */

 76         int             i = 1;

 77         int             nblocks;        // �ļ�ϵͳ�̿�������

 78         char            *cp;            /* Move pointer */

 79         

    // ���ȼ�������̵���Ч�Ժ������ԡ����ramdisk�ij���Ϊ�㣬���˳���������ʾramdisk

    // �Ĵ�С�Լ��ڴ���ʼλ�á������ʱ���ļ��豸���������豸����Ҳ�˳���

 80         if (!rd_length)

 81                 return;

 82         printk("Ram disk: %d bytes, starting at 0x%x\n", rd_length,

 83                 (int) rd_start);

 84         if (MAJOR(ROOT_DEV) != 2)

 85                 return;

    // Ȼ������ļ�ϵͳ�Ļ����������������̿�256+1��256��256+2������block+1��ָ������

    // �ij����顣breada() ���ڶ�ȡָ�������ݿ飬���������Ҫ���Ŀ飬Ȼ�󷵻غ������ݿ��

    // ������ָ�롣�������NULL�����ʾ���ݿ鲻�ɶ���fs/buffer.c��322����Ȼ��ѻ�������

    // �Ĵ��̳����飨d_super_block�Ǵ��̳�����ṹ�����Ƶ�s�����У����ͷŻ������� ����

    // ���ǿ�ʼ�Գ��������Ч�Խ����жϡ� ������������ļ�ϵͳħ�����ԣ���˵�����ص�����

    // �鲻��MINIX�ļ�ϵͳ�������˳����й�MINIX������Ľṹ��μ��ļ�ϵͳһ�����ݡ�

 86         bh = breada(ROOT_DEV,block+1,block,block+2,-1);

 87         if (!bh) {

 88                 printk("Disk error while looking for ramdisk!\n");

 89                 return;

 90         }

 91         *((struct d_super_block *) &s) = *((struct d_super_block *) bh->b_data);

 92         brelse(bh);

 93         if (s.s_magic != SUPER_MAGIC)

 94                 /* No ram disk image present, assume normal floppy boot */

                    /* ������û��ramdiskӳ���ļ����˳�ȥִ��ͨ������������ */

 95                 return;

    // Ȼ��������ͼ���������ļ�ϵͳ���뵽�ڴ����������С�����һ���ļ�ϵͳ��˵���䳬����

    // �ṹ�� s_nzones �ֶ��б��������߼����������Ϊ����������һ���߼����к��е����ݿ�

    // �������ֶ�s_log_zone_sizeָ��������ļ�ϵͳ�е����ݿ�����nblocks �͵��� (�߼���

    // �� * 2^(ÿ���ο����Ĵη�))����nblocks = (s_nzones * 2^s_log_zone_size)���������

    // �ļ�ϵͳ�����ݿ����������ڴ��������������ɵĿ��������������ִ�м��ز�������ֻ

    // ����ʾ������Ϣ�����ء�

 96         nblocks = s.s_nzones << s.s_log_zone_size;

 97         if (nblocks > (rd_length >> BLOCK_SIZE_BITS)) {

 98                 printk("Ram disk image too big!  (%d blocks, %d avail)\n",

 99                         nblocks, rd_length >> BLOCK_SIZE_BITS);

100                 return;

101         }

    // �����������������ɵ����ļ�ϵͳ�����ݿ�������������ʾ�������ݿ���Ϣ������cpָ��

    // �ڴ���������ʼ����Ȼ��ʼִ��ѭ�������������ϸ��ļ�ϵͳӳ���ļ����ص��������ϡ�

    // �ڲ��������У����һ����Ҫ���ص��̿�������2�飬���Ǿ����ó�ǰԤ������breada()��

    // �����ʹ��bread()�������е����ȡ�����ڶ��̹����г���I/O�������󣬾�ֻ�ܷ�����

    // �ع��̷��ء�����ȡ�Ĵ��̿��ʹ��memcpy()�����Ӹ��ٻ������и��Ƶ��ڴ���������Ӧ

    // λ�ô���ͬʱ��ʾ�Ѽ��صĿ�������ʾ�ַ����еİ˽�����'\010'��ʾ��ʾһ���Ʊ�����

102         printk("Loading %d bytes into ram disk... 0000k",

103                 nblocks << BLOCK_SIZE_BITS);

104         cp = rd_start;

105         while (nblocks) {

106                 if (nblocks > 2)                // ����ȡ��������2������ó�ǰԤ����

107                         bh = breada(ROOT_DEV, block, block+1, block+2, -1);

108                 else                            // ����͵����ȡ��

109                         bh = bread(ROOT_DEV, block);

110                 if (!bh) {

111                         printk("I/O error on block %d, aborting load\n",

112                                 block);

113                         return;

114                 }

115                 (void) memcpy(cp, bh->b_data, BLOCK_SIZE);       // ���Ƶ�cp����

116                 brelse(bh);

117                 printk("\010\010\010\010\010%4dk",i);        // ��ӡ���ؿ����ֵ��

118                 cp += BLOCK_SIZE;                            // ������ָ��ǰ�ơ�

119                 block++;

120                 nblocks--;

121                 i++;

122         }

    // ��boot���д�256�̿鿪ʼ���������ļ�ϵͳ������Ϻ�������ʾ��done��������Ŀǰ

    // ���ļ��豸���޸ij������̵��豸��0x0101����󷵻ء�

123         printk("\010\010\010\010\010done \n");

124         ROOT_DEV=0x0101;

125 }

126


 


 

9.5 ����9-5 linux/kernel/blk_drv/floppy.c


  1 /*

  2  *  linux/kernel/floppy.c

  3  *

  4  *  (C) 1991  Linus Torvalds

  5  */

  6

  7 /*

  8  * 02.12.91 - Changed to static variables to indicate need for reset

  9  * and recalibrate. This makes some things easier (output_byte reset

 10  * checking etc), and means less interrupt jumping in case of errors,

 11  * so the code is hopefully easier to understand.

 12  */

    /*

     * 02.12.91 - �޸ijɾ�̬����������Ӧ��λ������У����������ʹ��ijЩ����

     * ��������Ϊ���㣨output_byte ��λ���ȣ���������ζ���ڳ���ʱ�ж���ת

     * Ҫ��һЩ������Ҳϣ�������ܸ����ױ����⡣

     */

 13

 14 /*

 15  * This file is certainly a mess. I've tried my best to get it working,

 16  * but I don't like programming floppies, and I have only one anyway.

 17  * Urgel. I should check for more errors, and do more graceful error

 18  * recovery. Seems there are problems with several drives. I've tried to

 19  * correct them. No promises.

 20  */

    /*

     * ����ļ���Ȼ�Ƚϻ��ҡ����Ѿ���������ʹ���ܹ����������Ҳ�ϲ��������̣�

     * ������Ҳֻ��һ�����������⣬��Ӧ��������IJ���������Լ���������Ĵ���

     * ����ijЩ��������������������󻹴���һЩ���⡣���Ѿ������Ž��о����ˣ�

     * �����ܱ�֤��������ʧ��

     */

 21

 22 /*

 23  * As with hd.c, all routines within this file can (and will) be called

 24  * by interrupts, so extreme caution is needed. A hardware interrupt

 25  * handler may not sleep, or a kernel panic will happen. Thus I cannot

 26  * call "floppy-on" directly, but have to set a special timer interrupt

 27  * etc.

 28  *

 29  * Also, I'm not certain this works on more than 1 floppy. Bugs may

 30  * abund.

 31  */

    /*

     * ��ͬhd.c�ļ�һ�������ļ��е������ӳ����ܹ����жϵ��ã�������Ҫ�ر�

     * ��С�ġ�Ӳ���жϴ��������Dz���˯�ߵģ������ں˾ͻ�ɵ��(����)J����˲���

     * ֱ�ӵ���"floppy-on"����ֻ������һ������Ķ�ʱ�жϵȡ�

     *

     * ���⣬�Ҳ��ܱ�֤�ó������ڶ���1��������ϵͳ�Ϲ������п��ܴ��ڴ���

     */

 32

 33 #include <linux/sched.h>  // ���ȳ���ͷ�ļ�������������ṹtask_struct������0���ݵȡ�

 34 #include <linux/fs.h>     // �ļ�ϵͳͷ�ļ������ļ����ṹ��file��m_inode���ȡ�

 35 #include <linux/kernel.h> // �ں�ͷ�ļ�������һЩ�ں˳��ú�����ԭ�ζ��塣

 36 #include <linux/fdreg.h>  // ����ͷ�ļ����������̿�����������һЩ���塣

 37 #include <asm/system.h>   // ϵͳͷ�ļ������������û��޸�������/�ж��ŵȵ�Ƕ����ꡣ

 38 #include <asm/io.h>       // ioͷ�ļ�������Ӳ���˿�����/���������䡣

 39 #include <asm/segment.h>  // �β���ͷ�ļ����������йضμĴ���������Ƕ��ʽ��ຯ����

 40

    // �����������豸�ŷ��ų����������������У����豸�ű����ڰ���blk.h�ļ�֮ǰ�����塣

    // ��Ϊblk.h�ļ���Ҫ�õ�������ų���ֵ��ȷ��һЩ��������ط��ų����ͺꡣ

 41 #define MAJOR_NR 2        // ���������豸����2��

 42 #include "blk.h"          // ���豸ͷ�ļ�����������ṹ�����豸�ṹ�ͺ꺯������Ϣ��

 43

 44 static int recalibrate = 0;        // ��־��1��ʾ��Ҫ����У����ͷλ�ã���ͷ���������

 45 static int reset = 0;              // ��־��1��ʾ��Ҫ���и�λ������

 46 static int seek = 0;               // ��־��1��ʾ��Ҫִ��Ѱ��������

 47

    // ��ǰ��������Ĵ���DOR��Digital Output Register����������kernel/sched.c��223�С�

    // �ñ����������������е���Ҫ��־������ѡ�����������Ƶ��������������λ���̿�������

    // ������/��ֹDMA���ж�������μ������б����DOR�Ĵ�����˵����

 48 extern unsigned char current_DOR;

 49

    // �ֽ�ֱ���������Ƕ����꣩����ֵval�����port�˿ڡ�

 50 #define immoutb_p(val,port) \

 51 __asm__("outb %0,%1\n\tjmp 1f\n1:\tjmp 1f\n1:"::"a" ((char) (val)),"i" (port))

 52

    // �������궨�����ڼ����������豸�š�

    // ����x�Ǵ��豸�š����豸�� = TYPE*4 + DRIVE�����㷽���μ��б���

 53 #define TYPE(x) ((x)>>2)           // �������ͣ�2--1.2Mb��7--1.44Mb����

 54 #define DRIVE(x) ((x)&0x03)        // ������ţ�0--3��ӦA--D����

 55 /*

 56  * Note that MAX_ERRORS=8 doesn't imply that we retry every bad read

 57  * max 8 times - some types of errors increase the errorcount by 2,

 58  * so we might actually retry only 5-6 times before giving up.

 59  */

    /*

     * ע�⣬���涨��MAX_ERRORS=8������ʾ��ÿ�ζ����������8�� - ��Щ����

     * �Ĵ����ѳ�������ֵ��2����������ʵ�����ڷ�������֮ǰֻ�賢��5-6�鼴�ɡ�

     */

 60 #define MAX_ERRORS 8

 61

 62 /*

 63  * globals used by 'result()'

 64  */

    /* �����Ǻ���'result()'ʹ�õ�ȫ�ֱ��� */

    // ��Щ״̬�ֽ��и�����λ�ĺ�����μ�include/linux/fdreg.hͷ�ļ������μ��б���˵����

 65 #define MAX_REPLIES 7                            // FDC��෵��7�ֽڵĽ����Ϣ��

 66 static unsigned char reply_buffer[MAX_REPLIES];  // ���FDC���ص�Ӧ������Ϣ��

 67 #define ST0 (reply_buffer[0])                    // ���״̬�ֽ�0��

 68 #define ST1 (reply_buffer[1])                    // ���״̬�ֽ�1��

 69 #define ST2 (reply_buffer[2])                    // ���״̬�ֽ�2��

 70 #define ST3 (reply_buffer[3])                    // ���״̬�ֽ�3��

 71

 72 /*

 73  * This struct defines the different floppy types. Unlike minix

 74  * linux doesn't have a "search for right type"-type, as the code

 75  * for that is convoluted and weird. I've got enough problems with

 76  * this driver as it is.

 77  *

 78  * The 'stretch' tells if the tracks need to be boubled for some

 79  * types (ie 360kB diskette in 1.2MB drive etc). Others should

 80  * be self-explanatory.

 81  */

    /*

     * ��������̽ṹ�����˲�ͬ���������͡���minix��ͬ���ǣ�Linuxû��

     * "������ȷ������"-���ͣ���Ϊ���䴦���Ĵ������˷ѽ��ҹֵֹġ�������

     * �Ѿ���������̫��������ˡ�

     *

     * ��ijЩ���͵����̣�������1.2MB�������е�360kB���̵ȣ���'stretch'

     * ���ڼ��ŵ��Ƿ���Ҫ���⴦������������Ӧ���������ġ�

     */

    // �������̽ṹ�����̲����У�

    // size          ��С(������)��

    // sect          ÿ�ŵ���������

    // head          ��ͷ����

    // track         �ŵ�����

    // stretch       �Դŵ��Ƿ�Ҫ���⴦������־����

    // gap           ������϶����(�ֽ���)��

    // rate          ���ݴ������ʣ�

    // spec1         ��������4λ�������ʣ�����λ��ͷж��ʱ�䣩��

 82 static struct floppy_struct {

 83         unsigned int size, sect, head, track, stretch;

 84         unsigned char gap,rate,spec1;

 85 } floppy_type[] = {

 86         {    0, 0,0, 0,0,0x00,0x00,0x00 },      /* no testing */

 87         {  720, 9,2,40,0,0x2A,0x02,0xDF },      /* 360kB PC diskettes */

 88         { 2400,15,2,80,0,0x1B,0x00,0xDF },      /* 1.2 MB AT-diskettes */

 89         {  720, 9,2,40,1,0x2A,0x02,0xDF },      /* 360kB in 720kB drive */

 90         { 1440, 9,2,80,0,0x2A,0x02,0xDF },      /* 3.5" 720kB diskette */

 91         {  720, 9,2,40,1,0x23,0x01,0xDF },      /* 360kB in 1.2MB drive */

 92         { 1440, 9,2,80,0,0x23,0x01,0xDF },      /* 720kB in 1.2MB drive */

 93         { 2880,18,2,80,0,0x1B,0x00,0xCF },      /* 1.44MB diskette */

 94 };

 95

 96 /*

 97  * Rate is 0 for 500kb/s, 2 for 300kbps, 1 for 250kbps

 98  * Spec1 is 0xSH, where S is stepping rate (F=1ms, E=2ms, D=3ms etc),

 99  * H is head unload time (1=16ms, 2=32ms, etc)

100  *

101  * Spec2 is (HLD<<1 | ND), where HLD is head load time (1=2ms, 2=4 ms etc)

102  * and ND is set means no DMA. Hardcoded to 6 (HLD=6ms, use DMA).

103  */

    /*

     * ��������rate��0��ʾ500kbps��1��ʾ300kbps��2��ʾ250kbps��

     * ����spec1��0xSH������S�Dz������ʣ�F-1ms��E-2ms��D=3ms�ȣ���

     * H�Ǵ�ͷж��ʱ�䣨1=16ms��2=32ms�ȣ�

     *

     * spec2�ǣ�HLD<<1 | ND��������HLD�Ǵ�ͷ����ʱ�䣨1=2ms��2=4ms�ȣ�

     * ND��λ��ʾ��ʹ��DMA��No DMA�����ڳ�����Ӳ�����6��HLD=6ms��ʹ��DMA����

     */

    // ע�⣬������ͷ����ʱ�����дHLD���д�ɱ�׼��HLT��Head Load Time����

104

    // floppy_interrupt()��sys_call.s�����������жϴ������̱�š����ォ�����̳�ʼ��

    // ����floppy_init()����469�У�ʹ������ʼ���ж���������������

105 extern void floppy_interrupt(void);

    // ����boot/head.s��132�д��������ʱ���̻����������������Ļ����������ڴ�1MB

    // ����ij���ط�������Ҫ��DMA������������ʱ�������򴦡���Ϊ8237AоƬֻ����1MB��

    // ַ��Χ��Ѱַ��

106 extern char tmp_floppy_area[1024];

107

108 /*

109  * These are global variables, as that's the easiest way to give

110  * information to interrupts. They are the data used for the current

111  * request.

112  */

    /*

     * ������һЩȫ�ֱ�������Ϊ���ǽ���Ϣ�����жϳ�����򵥵ķ�ʽ������

     * ���ڵ�ǰ����������ݡ�

     */

    // ��Щ��ν�ġ�ȫ�ֱ�������ָ�������жϴ��������е��õ�C����ʹ�õı�������Ȼ��Щ

    // C�������ڱ������ڡ�

113 static int cur_spec1 = -1;                           // ��ǰ���̲���spec1��

114 static int cur_rate = -1;                            // ��ǰ����ת��rate��

115 static struct floppy_struct * floppy = floppy_type;  // �������ͽṹ����ָ�롣

116 static unsigned char current_drive = 0;              // ��ǰ�������š�

117 static unsigned char sector = 0;                     // ��ǰ�����š�

118 static unsigned char head = 0;                       // ��ǰ��ͷ�š�

119 static unsigned char track = 0;                      // ��ǰ�ŵ��š�

120 static unsigned char seek_track = 0;                 // Ѱ���ŵ��š�

121 static unsigned char current_track = 255;            // ��ǰ��ͷ���ڴŵ��š�

122 static unsigned char command = 0;                    // ��/д���

123 unsigned char selected = 0;    // ������ѡ����־���ڴ���������֮ǰҪ����ѡ��������

124 struct task_struct * wait_on_floppy_select = NULL;   // �ȴ�ѡ��������������С�

125

    //// ȡ��ѡ��������

    // �����������ָ��������nr��ǰ��û�б�ѡ��������ʾ������Ϣ��Ȼ��λ������ѡ����־

    // selected�������ѵȴ�ѡ���������������������Ĵ���(DOR)�ĵ�2λ����ָ��ѡ�����

    // ����0-3��ӦA-D����

126 void floppy_deselect(unsigned int nr)

127 {

128         if (nr != (current_DOR & 3))

129                 printk("floppy_deselect: drive not selected\n\r");

130         selected = 0;                                // ��λ������ѡ����־��

131         wake_up(&wait_on_floppy_select);             // ���ѵȴ�������

132 }

133

134 /*

135  * floppy-change is never called from an interrupt, so we can relax a bit

136  * here, sleep etc. Note that floppy-on tries to set current_DOR to point

137  * to the desired drive, but it will probably not survive the sleep if

138  * several floppies are used at the same time: thus the loop.

139  */

    /*

     * floppy-change()���Ǵ��жϳ����е��õģ������������ǿ�������һ�£�˯�ߵȡ�

     * ע��floppy-on()�᳢������current_DORָ�������������������ͬʱʹ�ü���

     * ����ʱ����˯�ߣ���˴�ʱֻ��ʹ��ѭ����ʽ��

     */

    //// ���ָ�����������̸��������

    // ����nr�������š�������̸������򷵻�1�����򷵻�0��

    // �ú�������ѡ������ָ��������nr��Ȼ��������̿���������������Ĵ���DIR��ֵ������

    // ���������е������Ƿ񱻸��������ú����ɳ���fs/buffer.c�е� check_disk_change()��

    // �����ã���119�У���

140 int floppy_change(unsigned int nr)

141 {

    // ����Ҫ��������������ת�������ﵽ��������ת�١�����Ҫ����һ��ʱ�䡣���õķ�������

    // ��kernel/sched.c�����̶�ʱ����do_floppy_timer()����һ������ʱ������floppy_on()

    // �����������ж���ʱ�Ƿ񵽣�mon_timer[nr]==0?������û�е����õ�ǰ���̼���˯�ߵȴ���

    // ����ʱ����do_floppy_timer()�ỽ�ѵ�ǰ���̡�

142 repeat:

143         floppy_on(nr);        // �������ȴ�ָ������nr��kernel/sched.c����251�У���

    // ��������������ת��֮���������鿴һ�µ�ǰѡ��������Dz��Ǻ�������ָ��������nr��

    // �����ǰѡ�����������ָ��������nr�������Ѿ�ѡ�����������������õ�ǰ��������

    // �жϵȴ�״̬���Եȴ�����������ȡ��ѡ�����μ�����floppy_deselect()�� �����ǰû

    // ��ѡ������������������������ȡ��ѡ����ʹ��ǰ���񱻻���ʱ�� ��ǰ������Ȼ����ָ��

    // ������nr������ת��������ʼ������ѭ���ȴ���

144         while ((current_DOR & 3) != nr && selected)

145                 sleep_on(&wait_on_floppy_select);

146         if ((current_DOR & 3) != nr)

147                 goto repeat;

    // �������̿�������ѡ������ָ��������nr������ȡ��������Ĵ���DIR��ֵ����������

    // λ��λ7����λ�����ʾ�����Ѹ�������ʱ���ɹر����ﲢ����1�˳��� ����ر����ﷵ

    // ��0�˳�����ʾ����û�б�������

148         if (inb(FD_DIR) & 0x80) {

149                 floppy_off(nr);

150                 return 1;

151         }

152         floppy_off(nr);

153         return 0;

154 }

155

    //// �����ڴ滺��飬��1024�ֽڡ�

    // ���ڴ��ַfrom������1024�ֽ����ݵ���ַto����

156 #define copy_buffer(from,to) \

157 __asm__("cld ; rep ; movsl" \

158         ::"c" (BLOCK_SIZE/4),"S" ((long)(from)),"D" ((long)(to)) \

159         :"cx","di","si")

160

    //// ���ã���ʼ��������DMAͨ����

    // ���������ݶ�д������ʹ��DMA���еġ������ÿ�ν������ݴ���֮ǰ��Ҫ����DMAоƬ

    // ��ר������������ͨ��2���й�DMA��̷�����μ������б������Ϣ��

161 static void setup_DMA(void)

162 {

163         long addr = (long) CURRENT->buffer;      // ��ǰ��������������ڴ��ַ��

164

    // ���ȼ��������Ļ���������λ�á���������������ڴ�1MB���ϵ�ij���ط�������Ҫ��

    // DMA������������ʱ��������tmp_floppy_area��������Ϊ8237AоƬֻ����1MB��ַ��

    // Χ��Ѱַ�������д���������Ҫ�����ݴ�������������Ƶ�����ʱ����

165         cli();

166         if (addr >= 0x100000) {

167                 addr = (long) tmp_floppy_area;

168                 if (command == FD_WRITE)

169                         copy_buffer(CURRENT->buffer,tmp_floppy_area);

170         }

    // ���������ǿ�ʼ����DMAͨ��2���ڿ�ʼ����֮ǰ��Ҫ�����θ�ͨ������ͨ�����μĴ���

    // �˿�Ϊ0x0A��λ0-1ָ��DMAͨ��(0--3)��λ2��1��ʾ���Σ�0��ʾ�������� Ȼ����

    // DMA�������˿�12��11д�뷽ʽ�֣�������0x46��д������0x4A���� ��д�봫��ʹ��

    // ��������ַaddr����Ҫ������ֽ���0x3ff��0--1023�������λ��DMAͨ��2�����Σ�

    // ����DMA2����DREQ�źš�

171 /* mask DMA 2 */    /* ����DMAͨ��2 */

172         immoutb_p(4|2,10);

173 /* output command byte. I don't know why, but everyone (minix, */

174 /* sanches & canton) output this twice, first to 12 then to 11 */

    /* ��������ֽڡ����Dz�֪��Ϊʲô������ÿ���ˣ�minix��*/

    /* sanches��canton����������Σ�������12�ڣ�Ȼ����11�� */

    // ����Ƕ���������DMA�������ġ�����Ⱥ󴥷������˿�12�ͷ�ʽ�Ĵ����˿�11д��

    // ��ʽ�֣�����ʱ��0x46��д����0x4A����

    // ���ڸ�ͨ���ĵ�ַ�ͼ����Ĵ�������16λ�ģ��������������ʱ����Ҫ��2�ν��в�����

    // һ�η��ʵ��ֽڣ���һ�η��ʸ��ֽڡ���ʵ����д�ĸ��ֽ������Ⱥ󴥷�����״̬������

    // ��������Ϊ0ʱ������ʵ��ֽڣ����ֽڴ�����Ϊ1ʱ������ʸ��ֽڡ�ÿ����һ�Σ�

    // �ô�������״̬�ͱ仯һ�Ρ���д�˿�12�Ϳ��Խ��������ó�0״̬���Ӷ���16λ�Ĵ�

    // �������ôӵ��ֽڿ�ʼ��

175         __asm__("outb %%al,$12\n\tjmp 1f\n1:\tjmp 1f\n1:\t"

176         "outb %%al,$11\n\tjmp 1f\n1:\tjmp 1f\n1:"::

177         "a" ((char) ((command == FD_READ)?DMA_READ:DMA_WRITE)));

178 /* 8 low bits of addr */     /* ��ַ��0-7λ */

    // ��DMAͨ��2д���/��ǰ��ַ�Ĵ������˿�4����

179         immoutb_p(addr,4);

180         addr >>= 8;

181 /* bits 8-15 of addr */    /* ��ַ��8-15λ */

182         immoutb_p(addr,4);

183         addr >>= 8;

184 /* bits 16-19 of addr */    /* ��ַ16-19λ */

    // DMAֻ������1MB�ڴ�ռ���Ѱַ�����16-19λ��ַ�����ҳ��Ĵ���(�˿�0x81)��

185         immoutb_p(addr,0x81);

186 /* low 8 bits of count-1 (1024-1=0x3ff) */  /* ��������8λ(1024-1 = 0x3ff) */

    // ��DMAͨ��2д���/��ǰ�ֽڼ�����ֵ���˿�5����

187         immoutb_p(0xff,5);

188 /* high 8 bits of count-1 */    /* ��������8λ */

    // һ�ι�����1024�ֽڣ�������������

189         immoutb_p(3,5);

190 /* activate DMA 2 */    /* ����DMAͨ��2������ */

191         immoutb_p(0|2,10);

192         sti();

193 }

194

    //// ���������������һ���ֽ�����������

    // �������������һ���ֽ�֮ǰ����������Ҫ����׼����״̬���������ݴ��䷽���������

    // �ɴ�CPU �� FDC����˺�����Ҫ���ȶ�ȡ������״̬��Ϣ������ʹ����ѭ����ѯ��ʽ����

    // ���ʵ���ʱ����������������ø�λ��־reset��

195 static void output_byte(char byte)

196 {

197         int counter;

198         unsigned char status;

199

    // ѭ����ȡ��״̬������FD_STATUS��0x3f4����״̬���������״̬�� STATUS_READY ����

    // ����λSTATUS_DIR = 0��CPU��FDC�����������ݶ˿����ָ���ֽڡ�

200         if (reset)

201                 return;

202         for(counter = 0 ; counter < 10000 ; counter++) {

203                 status = inb_p(FD_STATUS) & (STATUS_READY | STATUS_DIR);

204                 if (status == STATUS_READY) {

205                         outb(byte,FD_DATA);

206                         return;

207                 }

208         }

    // �����ѭ��1��ν��������ܷ��ͣ����ø�λ��־������ӡ������Ϣ��

209         reset = 1;

210         printk("Unable to send byte to FDC\n\r");

211 }

212

    //// ��ȡFDCִ�еĽ����Ϣ��

    // �����Ϣ���7���ֽڣ����������reply_buffer[]�С����ض���Ľ���ֽ�����������

    // ֵ = -1�����ʾ��������������ʽ�����溯�����ơ�

213 static int result(void)

214 {

215         int i = 0, counter, status;

216

    // ����λ��־����λ���������˳���ȥִ�к��������еĸ�λ����������ѭ����ȡ��״̬��

    // ����FD_STATUS��0x3f4����״̬�������ȡ�Ŀ�����״̬��READY����ʾ�Ѿ�û�����ݿ�

    // ȡ���򷵻��Ѷ�ȡ���ֽ���i�����������״̬�Ƿ����־��λ��CPUßFDC������׼���á�

    // æ����ʾ�����ݿɶ�ȡ�� ���ǰѿ������еĽ�����ݶ��뵽Ӧ���������С� ����ȡ

    // MAX_REPLIES��7�����ֽڡ�

217         if (reset)

218                 return -1;

219         for (counter = 0 ; counter < 10000 ; counter++) {

220                 status = inb_p(FD_STATUS)&(STATUS_DIR|STATUS_READY|STATUS_BUSY);

221                 if (status == STATUS_READY)

222                         return i;

223                 if (status == (STATUS_DIR|STATUS_READY|STATUS_BUSY)) {

224                         if (i >= MAX_REPLIES)

225                                 break;

226                         reply_buffer[i++] = inb_p(FD_DATA);

227                 }

228         }

    // �����ѭ��1��ν��������ܷ��ͣ����ø�λ��־������ӡ������Ϣ��

229         reset = 1;

230         printk("Getstatus times out\n\r");

231         return -1;

232 }

233

    //// ���̶�д��������������

    // �ú����������̶�д����������ȷ����Ҫ��ȡ�Ľ�һ���ж��������ǰ���������������

    // �������ڹ涨������������MAX_ERRORS��8�Σ������ٶԵ�ǰ����������һ���IJ���

    // ���ԡ������/д���������Ѿ�����MAX_ERRORS/2������Ҫ����������λ��������������

    // ��λ��־reset�������������������������ֵ��һ�룬��ֻ������У��һ�´�ͷλ�ã�

    // ������������У����־recalibrate�������ĸ�λ������У���������ں����ij����н��С�

234 static void bad_flp_intr(void)

235 {

    // ���Ȱѵ�ǰ���������������1�������ǰ������������������������������������ȡ

    // ��ѡ����ǰ�����������������������������û�б����£���

236         CURRENT->errors++;

237         if (CURRENT->errors > MAX_ERRORS) {

238                 floppy_deselect(current_drive);

239                 end_request(0);

240         }

    // �����ǰ����������������������������������һ�룬���ø�λ��־������������и�

    // λ������Ȼ�����ԡ���������������У��һ�����ԡ�

241         if (CURRENT->errors > MAX_ERRORS/2)

242                 reset = 1;

243         else

244                 recalibrate = 1;

245 }      

246

247 /*

248  * Ok, this interrupt is called after a DMA read/write has succeeded,

249  * so we check the results, and copy any buffers.

250  */

    /*

     * OK��������жϴ�����������DMA��/д�ɹ�����õģ��������ǾͿ��Լ��

     * ִ�н���������ƻ������е����ݡ�

     */

    //// ���̶�д�����жϵ��ú�����

    // �ú��������������������������������жϴ��������б����á��������ȶ�ȡ�������״

    // ̬��Ϣ���ݴ��жϲ����Ƿ�������Ⲣ����Ӧ������ �����/д�����ɹ�����ô��������

    // �Ƕ����������仺�������ڴ�1MB����λ�ã�����Ҫ�����ݴ�������ʱ���������Ƶ�����

    // ��Ļ�������

251 static void rw_interrupt(void)

252 {

    // ��ȡFDCִ�еĽ����Ϣ��������ؽ���ֽ���������7������״̬�ֽ�0��1��2�д���

    // ������־����ô����д��������ʾ������Ϣ���ͷŵ�ǰ����������������ǰ���������

    // ��ִ�г�������������Ȼ�����ִ���������������������״̬�ĺ���μ�fdreg.h�ļ���

    // ( 0xf8 = ST0_INTR | ST0_SE | ST0_ECE | ST0_NR )

    // ( 0xbf = ST1_EOC | ST1_CRC | ST1_OR | ST1_ND | ST1_WP | ST1_MAM��Ӧ����0xb7)

    // ( 0x73 = ST2_CM | ST2_CRC | ST2_WC | ST2_BC | ST2_MAM )

253         if (result() != 7 || (ST0 & 0xf8) || (ST1 & 0xbf) || (ST2 & 0x73)) {

254                 if (ST1 & 0x02) {         // 0x02 = ST1_WP - Write Protected��

255                         printk("Drive %d is write protected\n\r",current_drive);

256                         floppy_deselect(current_drive);

257                         end_request(0);

258                 } else

259                         bad_flp_intr();

260                 do_fd_request();

261                 return;

262         }

    // �����ǰ������Ļ�����λ��1MB��ַ���ϣ���˵���˴����̶����������ݻ�������ʱ��

    // �����ڣ���Ҫ���Ƶ���ǰ������Ļ������У���ΪDMAֻ����1MB��ַ��ΧѰַ�������

    // �ͷŵ�ǰ������ȡ��ѡ������ִ�е�ǰ������������������ѵȴ���������Ľ��У�����

    // �ȴ�����������Ľ��̣����еĻ������������豸������������ɾ����������ټ���ִ

    // ���������������������

263         if (command == FD_READ && (unsigned long)(CURRENT->buffer) >= 0x100000)

264                 copy_buffer(tmp_floppy_area,CURRENT->buffer);

265         floppy_deselect(current_drive);

266         end_request(1);

267         do_fd_request();

268 }

269

    //// ����DMAͨ��2�������̿������������Ͳ��������1�ֽ����� + 0~7�ֽڲ�������

    // ��reset��־û����λ����ô�ڸú����˳��������̿�����ִ������Ӧ��/д������ͻ�

    // ����һ�������ж����󣬲���ʼִ�������жϴ�������

270 inline void setup_rw_floppy(void)

271 {

272         setup_DMA();               // ��ʼ������DMAͨ����

273         do_floppy = rw_interrupt;  // �������жϵ��ú���ָ�롣

274         output_byte(command);      // ���������ֽڡ�

275         output_byte(head<<2 | current_drive);  // ��������ͷ��+�������š�

276         output_byte(track);        // �������ŵ��š�

277         output_byte(head);         // ��������ͷ�š�

278         output_byte(sector);       // ��������ʼ�����š�

279         output_byte(2);         /* sector size = 512 */ // ������(N=2)512�ֽڡ�

280         output_byte(floppy->sect); // ������ÿ�ŵ���������

281         output_byte(floppy->gap);  // ����������������ȡ�

282         output_byte(0xFF);      /* sector size (0xff when n!=0 ?) */

                                    // ��������N=0ʱ������������ֽڳ��ȣ��������á�

    // �������κ�һ��output_byte()����������������ø�λ��־reset����ʱ��������ȥִ��

    // do_fd_request()�еĸ�λ�������롣

283         if (reset)

284                 do_fd_request();

285 }

286

287 /*

288  * This is the routine called after every seek (or recalibrate) interrupt

289  * from the floppy controller. Note that the "unexpected interrupt" routine

290  * also does a recalibrate, but doesn't come here.

291  */

    /*

     * ���ӳ�������ÿ�����̿�����Ѱ����������У�����ж��б����õġ�ע��

     * "unexpected interrupt"(�����ж�)�ӳ���Ҳ��ִ������У�������������ڴ˵ء�

     */

    //// Ѱ�������������жϹ����е��õ�C������

    // ���ȷ��ͼ���ж�״̬������״̬��ϢST0�ʹ�ͷ���ڴŵ���Ϣ����������ִ�д���

    // ������⴦����ȡ���������̲���������������״̬��Ϣ���õ�ǰ�ŵ�������Ȼ���

    // �ú���setup_rw_floppy()����DMA��������̶�д����Ͳ�����

292 static void seek_interrupt(void)

293 {

    // ���ȷ��ͼ���ж�״̬����Ի�ȡѰ������ִ�еĽ��������������������ؽ����

    // Ϣ�������ֽڣ�ST0�ʹ�ͷ��ǰ�ŵ��š�Ȼ���ȡFDCִ�еĽ����Ϣ�� ������ؽ����

    // ����������2������ST0��ΪѰ�����������ߴ�ͷ���ڴŵ���ST1���������趨�ŵ�����˵

    // �������˴�������ִ�м��������������Ȼ�����ִ�������������ִ�и�λ������

294 /* sense drive status */    /* ���������״̬ */

295         output_byte(FD_SENSEI);

296         if (result() != 2 || (ST0 & 0xF8) != 0x20 || ST1 != seek_track) {

297                 bad_flp_intr();

298                 do_fd_request();

299                 return;

300         }

    // ��Ѱ�������ɹ��������ִ�е�ǰ����������̲������������̿�������������Ͳ�����

301         current_track = ST1;       // ���õ�ǰ�ŵ���

302         setup_rw_floppy();         // ����DMA��������̲�������Ͳ�����

303 }

304

305 /*

306  * This routine is called when everything should be correctly set up

307  * for the transfer (ie floppy motor is on and the correct floppy is

308  * selected).

309  */

    /*

     * �ú������ڴ��������������Ϣ����ȷ���úú󱻵��õģ������������ѿ���

     * ������ѡ������ȷ�����̣���������

     */

    //// ��д���ݴ��亯����

310 static void transfer(void)

311 {

    // ���ȼ�鵱ǰ�����������Ƿ����ָ���������IJ����������Ǿͷ���������������������

    // ����Ӧ����������1����4λ�������ʣ�����λ��ͷж��ʱ�䣻����2����ͷ����ʱ�䣩��

    // Ȼ���жϵ�ǰ���ݴ��������Ƿ���ָ����������һ�£������Ǿͷ���ָ������������ֵ��

    // ���ݴ������ʿ��ƼĴ���(FD_DCR)��

312         if (cur_spec1 != floppy->spec1) {          // ��⵱ǰ������

313                 cur_spec1 = floppy->spec1;

314                 output_byte(FD_SPECIFY);           // �������ô��̲������

315                 output_byte(cur_spec1);            /* hut etc */  // ���Ͳ�����

316                 output_byte(6);                    /* Head load time =6ms, DMA */

317         }

318         if (cur_rate != floppy->rate)              // ��⵱ǰ���ʡ�

319                 outb_p(cur_rate = floppy->rate,FD_DCR);

    // �������κ�һ��output_byte()����ִ�г�������λ��־reset�ͻᱻ��λ���������

    // ������Ҫ���һ��reset��־����reset��ı���λ�ˣ�������ȥִ��do_fd_request()

    // �еĸ�λ�������롣

320         if (reset) {

321                 do_fd_request();

322                 return;

323         }

    // �����ʱѰ����־Ϊ�㣨������ҪѰ������������DMA�������̿�����������Ӧ��������

    // �Ͳ����󷵻ء������ִ��Ѱ�����������������������жϴ������ú���ΪѰ���жϺ�����

    // �����ʼ�ŵ��Ų����������ʹ�ͷѰ������Ͳ�������ʹ�õIJ������ǵ�112--121��

    // �����õ�ȫ�ֱ���ֵ�������ʼ�ŵ���seek_trackΪ0����ִ������У�������ô�ͷ����

    // λ��

324         if (!seek) {

325                 setup_rw_floppy();                   // ������������顣

326                 return;

327         }

328         do_floppy = seek_interrupt;                  // Ѱ���жϵ��õ�C������

329         if (seek_track) {                            // ��ʼ�ŵ��š�

330                 output_byte(FD_SEEK);                // ���ʹ�ͷѰ�����

331                 output_byte(head<<2 | current_drive);// ���Ͳ�������ͷ��+��ǰ�����š�

332                 output_byte(seek_track);             // ���Ͳ������ŵ��š�

333         } else {

334                 output_byte(FD_RECALIBRATE);         // ��������У�������ͷ���㣩��

335                 output_byte(head<<2 | current_drive);// ���Ͳ�������ͷ��+��ǰ�����š�

336         }

    // ͬ���أ��������κ�һ��output_byte()����ִ�г�������λ��־reset�ͻᱻ��λ��

    // ��reset��ı���λ�ˣ�������ȥִ��do_fd_request()�еĸ�λ�������롣

337         if (reset)

338                 do_fd_request();

339 }

340

341 /*

342  * Special case - used after a unexpected interrupt (or reset)

343  */

    /*

     * ������� - ���������жϣ���λ��������

     */

    //// ��������У���жϵ��ú�����

    // ���ȷ��ͼ���ж�״̬����޲�������������ؽ���������������ø�λ��־����������

    // У����־���㡣Ȼ���ٴ�ִ���������������������Ӧ������

344 static void recal_interrupt(void)

345 {

346         output_byte(FD_SENSEI);                  // ���ͼ���ж�״̬���

347         if (result()!=2 || (ST0 & 0xE0) == 0x60) // ������ؽ���ֽ���������2������

348                 reset = 1;                       // �쳣���������ø�λ��־��

349         else

350                 recalibrate = 0;                 // ����λ����У����־��

351         do_fd_request();                         // ����Ӧ������

352 }

353

    //// ���������ж����������������жϴ��������е��õĺ�����

    // ���ȷ��ͼ���ж�״̬����޲�������������ؽ���������������ø�λ��־������������

    // У����־��

354 void unexpected_floppy_interrupt(void)

355 {

356         output_byte(FD_SENSEI);                  // ���ͼ���ж�״̬���

357         if (result()!=2 || (ST0 & 0xE0) == 0x60) // ������ؽ���ֽ���������2������

358                 reset = 1;                       // �쳣���������ø�λ��־��

359         else

360                 recalibrate = 1;                 // ����������У����־��

361 }

362

    //// ��������У������������

    // �����̿�����FDC��������У������Ͳ���������λ����У����־�������̿�����ִ����

    // ����У������ͻ����������������ж��е���recal_interrupt()������

363 static void recalibrate_floppy(void)

364 {

365         recalibrate = 0;                         // ��λ����У����־��

366         current_track = 0;                       // ��ǰ�ŵ��Ź��㡣

367         do_floppy = recal_interrupt;             // ָ������У���жϵ��õ�C������

368         output_byte(FD_RECALIBRATE);             // �������У����

369         output_byte(head<<2 | current_drive);    // ��������ͷ�� + ��ǰ�������š�

    // �������κ�һ��output_byte()����ִ�г�������λ��־reset�ͻᱻ��λ���������

    // ������Ҫ���һ��reset��־����reset��ı���λ�ˣ�������ȥִ��do_fd_request()

    // �еĸ�λ�������롣

370         if (reset)

371                 do_fd_request();

372 }

373

    //// ���̿�����FDC��λ�жϵ��ú�����

    // �ú�������������������˸�λ��������������������жϴ��������б����á�

    // ���ȷ��ͼ���ж�״̬����޲�������Ȼ��������صĽ���ֽڡ����ŷ����趨����

    // �����������ز���������ٴε��������������do_fd_request() ȥִ������У��

    // ������������ִ��output_byte() ��������ʱ��λ��־�ֻᱻ��λ�����Ҳ�����ٴ�ȥ

    // ִ�и�λ������

374 static void reset_interrupt(void)

375 {

376         output_byte(FD_SENSEI);                  // ���ͼ���ж�״̬���

377         (void) result();                         // ��ȡ����ִ�н���ֽڡ�

378         output_byte(FD_SPECIFY);                 // �����趨�����������

379         output_byte(cur_spec1);                  /* hut etc */  // ���Ͳ�����

380         output_byte(6);                          /* Head load time =6ms, DMA */

381         do_fd_request();                         // ����ִ����������

382 }

383

384 /*

385  * reset is done by pulling bit 2 of DOR low for a while.

386  */

    /* FDC��λ��ͨ������������Ĵ���(DOR)λ2��0һ���ʵ�ֵ� */

    //// ��λ���̿�������

    // �ú����������ò����ͱ�־���Ѹ�λ��־��0��Ȼ�����������cur_spec1��cur_rate

    // ��Ϊ��Ч����Ϊ��λ��������������������Ҫ�������á�����������Ҫ����У����־��

    // ������FDCִ�и�λ�����������������ж��е��õ�C����reset_interrupt()�����

    // ��DOR�Ĵ���λ2��0һ����Զ�����ִ�и�λ��������ǰ��������Ĵ���DOR��λ2

    // ������/��λ����λ��

387 static void reset_floppy(void)

388 {

389         int i;

390

391         reset = 0;                            // ��λ��־��0��

392         cur_spec1 = -1;                       // ʹ��Ч��

393         cur_rate = -1;

394         recalibrate = 1;                      // ����У����־��λ��

395         printk("Reset-floppy called\n\r");    // ��ʾִ�����̸�λ������Ϣ��

396         cli();                                // ���жϡ�

397         do_floppy = reset_interrupt;          // �������жϴ��������е��õĺ�����

398         outb_p(current_DOR & ~0x04,FD_DOR);   // �����̿�����FDCִ�и�λ������

399         for (i=0 ; i<100 ; i++)               // �ղ������ӳ١�

400                 __asm__("nop");

401         outb(current_DOR,FD_DOR);             // ���������̿�������

402         sti();                                // ���жϡ�

403 }

404

    //// ����������ʱ�жϵ��ú�����

    // ��ִ��һ��������Ҫ��IJ���֮ǰ��Ϊ�˵ȴ�ָ������������ת�������������Ĺ���ת�٣�

    // do_fd_request()����Ϊ׼���õĵ�ǰ������������һ����ʱ��ʱ�������������Ǹö�ʱ��

    // ����ʱ���õĺ����������ȼ����������Ĵ���(DOR)��ʹ��ѡ��ǰָ������������Ȼ��

    // ����ִ�����̶�д���亯��transfer()��

405 static void floppy_on_interrupt(void)           // floppy_on() interrupt��

406 {

407 /* We cannot do a floppy-select, as that might sleep. We just force it */

    /* ���Dz�����������ѡ�����������Ϊ����ܻ��������˯�ߡ�����ֻ����ʹ���Լ�ѡ�� */

    // �����ǰ������������������Ĵ���DOR�еIJ�ͬ������Ҫ��������DORΪ��ǰ��������

    // ������������Ĵ��������ǰDOR�Ժ�ʹ�ö�ʱ���ӳ�2���δ�ʱ�䣬��������õ�ִ

    // �С�Ȼ��������̶�д���亯��transfer()������ǰ��������DOR�е��������ô�Ϳ���

    // ֱ�ӵ������̶�д���亯����

408         selected = 1;                          // ����ѡ����ǰ��������־��

409         if (current_drive != (current_DOR & 3)) {

410                 current_DOR &= 0xFC;

411                 current_DOR |= current_drive;

412                 outb(current_DOR,FD_DOR);      // ����������Ĵ��������ǰDOR��

413                 add_timer(2,&transfer);        // ���Ӷ�ʱ����ִ�д��亯����

414         } else

415                 transfer();                    // ִ�����̶�д���亯����

416 }

417

    //// ���̶�д�������������

    // �ú�����������������������Ҫ�ĺ�������Ҫ�����ǣ��ٴ����и�λ��־������У����־��

    // λ������������������е��豸�ż���ȡ��������ָ�������IJ����飻�������ںӶ�ʱ����

    // �����̶�/д������

418 void do_fd_request(void)

419 {

420         unsigned int block;

421

    // ���ȼ���Ƿ��и�λ��־������У����־��λ�������򱾺�����ִ����ر�־�Ĵ�������

    // ��ͷ��ء������λ��־����λ����ִ�����̸�λ���������ء��������У����־����λ��

    // ��ִ����������У�����������ء�

422         seek = 0;                              // ��Ѱ����־��

423         if (reset) {                           // ��λ��־����λ��

424                 reset_floppy();

425                 return;

426         }

427         if (recalibrate) {                     // ����У����־����λ��

428                 recalibrate_floppy();

429                 return;

430         }

    // ���������������ܴ����↑ʼ����������blk.h�ļ��е�INIT_REQUEST��������������

    // �Ϸ��ԣ������û�����������˳����μ�blk.h,127����Ȼ�������������е��豸��ȡ����

    // ����ָ�������IJ����顣��������齫�����������������̲���ʹ�õ�ȫ�ֱ��������飨��

    // ��112 - 122�У����������豸���е��������� (MINOR(CURRENT->dev)>>2) ������������

    // ������floppy_type[]������ֵ��ȡ��ָ�������IJ����顣

431         INIT_REQUEST;

432         floppy = (MINOR(CURRENT->dev)>>2) + floppy_type;

 

    // ���濪ʼ����112--122���ϵ�ȫ�ֱ���ֵ�������ǰ��������current_drive����������

    // ��ָ�����������ţ����ñ�־seek����ʾ��ִ�ж�/д����֮ǰ��Ҫ����������ִ��Ѱ����

    // ����Ȼ��ѵ�ǰ������������Ϊ��������ָ�����������š�

433         if (current_drive != CURRENT_DEV)   // CURRENT_DEV����������ָ���������š�

434                 seek = 1;

435         current_drive = CURRENT_DEV;

 

    // ���ö�д��ʼ����block����Ϊÿ�ζ�д���Կ�Ϊ��λ��1��Ϊ2����������������ʼ����

    // ��Ҫ����ȴ�����������С2������������˵����������������Ч�������ô�����������

    // ȥִ����һ�������

436         block = CURRENT->sector;            // ȡ��ǰ��������������ʼ�����š�

437         if (block+2 > floppy->size) {       // ���block + 2���ڴ�������������

438                 end_request(0);             // ������������������

439                 goto repeat;

440         }

    // �����Ӧ�ڴŵ��ϵ������š���ͷ�š��ŵ��š���Ѱ�ŵ��ţ�������������ͬ��ʽ���̣���

441         sector = block % floppy->sect;   // ��ʼ������ÿ�ŵ�������ȡģ���ôŵ��������š�

442         block /= floppy->sect;           // ��ʼ������ÿ�ŵ�������ȡ��������ʼ�ŵ�����

443         head = block % floppy->head;     // ��ʼ�ŵ����Դ�ͷ��ȡģ���ò����Ĵ�ͷ�š�

444         track = block / floppy->head;    // ��ʼ�ŵ����Դ�ͷ��ȡ�����ò����Ĵŵ��š�

445         seek_track = track << floppy->stretch; // ��Ӧ�������������ͽ��е�������Ѱ���š�

 

    // �ٿ����Ƿ���Ҫ����ִ��Ѱ�����������Ѱ�����뵱ǰ��ͷ���ڴŵ��Ų�ͬ������Ҫ����

    // Ѱ����������������ҪѰ����־seek�������������ִ�е���������command��

446         if (seek_track != current_track)

447                 seek = 1;

448         sector++;                        // ������ʵ�����������Ǵ�1����

449         if (CURRENT->cmd == READ)        // ����������Ƕ����������ö������롣

450                 command = FD_READ;

451         else if (CURRENT->cmd == WRITE)  // �����������д����������д�����롣

452                 command = FD_WRITE;

453         else

454                 panic("do_fd_request: unknown command");

    // ���������ú� 112--122��������ȫ�ֱ���ֵ֮�����ǿ��Կ�ʼִ������������ˡ��ò�

    // �����ö�ʱ������������ΪΪ���ܶ��������ж�д��������Ҫ�����������������ﲢ�ﵽ��

    // ����ת�ٶȡ�������Ҫһ����ʱ�䡣����������� ticks_to_floppy_on() ������������ʱ

    // ʱ�䣬Ȼ��ʹ�ø���ʱ�趨һ����ʱ������ʱ�䵽ʱ�͵��ú���floppy_on_interrupt()��

455         add_timer(ticks_to_floppy_on(current_drive),&floppy_on_interrupt);

456 }

457

    // ���������������̺��е����ݿ�������

458 static int floppy_sizes[] ={

459            0,   0,   0,   0,

460          360, 360 ,360, 360,

461         1200,1200,1200,1200,

462          360, 360, 360, 360,

463          720, 720, 720, 720,

464          360, 360, 360, 360,

465          720, 720, 720, 720,

466         1440,1440,1440,1440

467 };

468

    //// ����ϵͳ��ʼ����

    // �������̿��豸������Ĵ�������do_fd_request()�������������ж��ţ�int 0x26����Ӧ

    // Ӳ���ж������ź�IRQ6���� Ȼ��ȡ���Ը��ж��źŵ����Σ����������̿�����FDC������

    // �������źš��ж���������IDT�����������������ú�set_trap_gate()������ͷ�ļ�

    // include/asm/system.h�С�

469 void floppy_init(void)

470 {

    // ���������ж�����������floppy_interrupt��kernel/sys_call.s��267�У������жϴ���

    // ���̡��жϺ�Ϊint 0x26��38������Ӧ8259AоƬ�ж������ź�IRQ6��

471         blk_size[MAJOR_NR] = floppy_sizes;

472         blk_dev[MAJOR_NR].request_fn = DEVICE_REQUEST;  // = do_fd_request()��

473         set_trap_gate(0x26,&floppy_interrupt);          // ������������������

474         outb(inb_p(0x21)&~0x40,0x21);                   // ��λ�����ж���������λ��

475 }

476


 


 

��10�� �ַ��豸����

10.1 ����10-1 linux/kernel/chr_drv/keyboard.S


  1 /*

  2  *  linux/kernel/keyboard.S

  3  *

  4  *  (C) 1991  Linus Torvalds

  5  */

  6

  7 /*

  8  *      Thanks to Alfred Leung for US keyboard patches

  9  *              Wolfgang Thiel for German keyboard patches

 10  *              Marc Corsini for the French keyboard

 11  */

    /*

     *      ��лAlfred Leung������US���̲�������

     *              Wolfgang Thiel�����˵�����̲�������

     *              Marc Corsini�����˷��ļ��̲�������

     */

 12

 13 /* KBD_FINNISH for Finnish keyboards

 14  * KBD_US for US-type

 15  * KBD_GR for German keyboards

 16  * KBD_FR for Frech keyboard

 17  */

    /*

     * KBD_FINNISH �Ƿ������̡�

     * KBD_US ����ʽ���̡�

     * KBD_GR �ǵ�ʽ���̡�

     * KBD_FR �Ƿ�ʽ���̡�

     */

 18 #define KBD_FINNISH         // ����ʹ�õļ������͡����ں���ѡ����õ��ַ�ӳ�������

 19

 20 .text

 21 .globl _keyboard_interrupt  // ����Ϊȫ�ֱ����������ڳ�ʼ��ʱ���ü����ж���������

 22

 23 /*

 24  * these are for the keyboard read functions

 25  */

    /*

     * ������Щ���ڶ����̲�����

     */

    // size�Ǽ��̻�������������У����ȣ��ֽ�������

    /* ֵ������2�Ĵη���������tty_io.c�е�ֵƥ��!!!! */

 26 size    = 1024          /* must be a power of two ! And MUST be the same

 27                            as in tty_io.c !!!! */

 

    // �����Ǽ��̻���������ݽṹtty_queue�е�ƫ������include/linux/tty.h����16�У���

 28 head = 4                // ������ͷָ���ֶ���tty_queue�ṹ�е�ƫ�ơ�

 29 tail = 8                // ������βָ���ֶ�ƫ�ơ�

 30 proc_list = 12          // �ȴ��û�����еĽ����ֶ�ƫ�ơ�

 31 buf = 16                // �������ֶ�ƫ�ơ�

 32

    // �ڱ�������ʹ����3����־�ֽڡ�mode�Ǽ����������ctrl��alt��caps���İ���״̬��־��

    // leds �����ڱ�ʾ����ָʾ�Ƶ�״̬��־�� e0�ǵ��յ�ɨ���� 0xe0 �� 0xe1 ʱ���õı�־��

    // ÿ���ֽڱ�־�и�λ�ĺ��������˵����

    // (1) mode�Ǽ���������İ���״̬��־��

    // ��ʾ��Сдת����(caps)��������(alt)�����Ƽ�(ctrl)�ͻ�����(shift)��״̬��

    //     λ7 caps�����£�

    //     λ6 caps����״̬��Ӧ����leds�ж�Ӧcaps�ı�־λһ������

    //     λ5 ��alt�����£�

    //     λ4 ��alt�����£�

    //     λ3 ��ctrl�����£�

    //     λ2 ��ctrl�����£�

    //     λ1 ��shift�����£�

    //     λ0 ��shift�����¡�

    // (2) leds�����ڱ�ʾ����ָʾ�Ƶ�״̬��־������ʾ������������num-lock������Сдת��

    // ����caps-lock���͹�����������scroll-lock����LED�����״̬��

    //     λ7-3 ȫ0���ã�

    //     λ2 caps-lock��

    //     λ1 num-lock����ʼ��1��Ҳ����������������(num-lock)�����Ϊ������

    //     λ0 scroll-lock��

    // (3) ��ɨ������0xe0��0xe1ʱ���øñ�־����ʾ��󻹸�����1����2���ַ�ɨ���롣ͨ

    // �����յ�ɨ����0xe0����ζ�Ż���һ���ַ�����������յ�ɨ����0xe1���ʾ���滹��

    // ����2���ַ����μ������б���˵����

    //     λ1 =1 �յ�0xe1��־��

    //     λ0 =1 �յ�0xe0��־��

 33 mode:   .byte 0         /* caps, alt, ctrl and shift mode */

 34 leds:   .byte 2         /* num-lock, caps, scroll-lock mode (nom-lock on) */

 35 e0:     .byte 0

 36

 37 /*

 38  *  con_int is the real interrupt routine that reads the

 39  *  keyboard scan-code and converts it into the appropriate

 40  *  ascii character(s).

 41  */

    /*

     * con_int��ʵ�ʵ��жϴ����ӳ������ڶ�����ɨ���벢����ת��

     * ����Ӧ��ascii�ַ���[ ע�����Ӣ��ע���ѹ�ʱ��]

     */

    //// �����жϴ���������ڵ㡣

    // �����̿��������յ��û���һ����������ʱ���ͻ����жϿ���������һ�������ж������ź�

    // IRQ1����CPU��Ӧ������ʱ�ͻ�ִ�м����жϴ������򡣸��жϴ��������Ӽ��̿�������

    // Ӧ�˿ڣ�0x60�����밴��ɨ���룬�����ö�Ӧ��ɨ�����ӳ�����д�����

    // ���ȴӶ˿�0x60��ȡ��ǰ������ɨ���롣Ȼ���жϸ�ɨ�����Ƿ���0xe0 �� 0xe1�������

    // �Ļ������̶Լ��̿���������Ӧ�𣬲����жϿ����������жϽ�����EOI���źţ���������

    // �̿������ܼ��������ж��źţ��Ӷ������������պ������ַ��� ������յ���ɨ���벻��

    // ����������ɨ���룬���Ǿ͸���ɨ����ֵ���ð�����ת�� key_table ����Ӧ���������ӳ�

    // �򣬰�ɨ�����Ӧ���ַ�������ַ��������read_q�С�Ȼ���ڶԼ��̿���������Ӧ��

    // ������EOI�ź�֮�󣬵��ú���do_tty_interrupt()��ʵ�����ǵ��� copy_to_cooked()��

    // ��read_q�е��ַ�����������ŵ�secondary���������С�

 42 _keyboard_interrupt:

 43         pushl %eax

 44         pushl %ebx

 45         pushl %ecx

 46         pushl %edx

 47         push %ds

 48         push %es

 49         movl $0x10,%eax         // ��ds��es�μĴ�����Ϊ�ں����ݶΡ�

 50         mov %ax,%ds

 51         mov %ax,%es

 52         movl _blankinterval,%eax

 53         movl %eax,_blankcount   // Ԥ�ú���ʱ�����ֵΪblankinterval���δ�������

 54         xorl %eax,%eax          /* %eax is scan code */   /* eax����ɨ���� */

 55         inb $0x60,%al           // ��ȡɨ������al��

 56         cmpb $0xe0,%al          // ɨ������0xe0����������ת������e0��־���봦��

 57         je set_e0

 58         cmpb $0xe1,%al          // ɨ������0xe1����������ת������e1��־���봦��

 59         je set_e1

 60         call key_table(,%eax,4) // ���ü��������� key_table + eax*4���μ�502�У���

 61         movb $0,e0              // ����֮��λe0��־��

 

    // ������δ��루55-65�У����ʹ��8255A��PC��׼���̵�·����Ӳ����λ�������˿�0x61

    // ��8255A �����B �ĵ�ַ��������˿ڵĵ�7λ��PB7�����ڽ�ֹ�������Լ������ݵĴ�����

    // ��γ������ڶ��յ���ɨ��������Ӧ�𡣷��������Ƚ�ֹ���̣�Ȼ�����������������̹�����

 62 e0_e1:  inb $0x61,%al           // ȡPPI�˿�B״̬����λ7��������/��ֹ��0/1�����̡�

 63         jmp 1f                  // �ӳ�һ�ᡣ

 64 1:      jmp 1f

 65 1:      orb $0x80,%al           // alλ7��λ����ֹ���̹�������

 66         jmp 1f

 67 1:      jmp 1f

 68 1:      outb %al,$0x61          // ʹPPI PB7λ��λ��

 69         jmp 1f

 70 1:      jmp 1f

 71 1:      andb $0x7F,%al          // alλ7��λ��

 72         outb %al,$0x61          // ʹPPI PB7λ��λ���������̹�������

 73         movb $0x20,%al          // ��8259�ж�оƬ����EOI(�жϽ���)�źš�

 74         outb %al,$0x20

 75         pushl $0                // ����̨tty��=0����Ϊ������ջ��

 76         call _do_tty_interrupt  // ���յ�����ת���ɹ淶ģʽ������ڹ淶�ַ���������С�

 77         addl $4,%esp            // ������ջ�IJ��������������ļĴ��������жϷ��ء�

 78         pop %es

 79         pop %ds

 80         popl %edx

 81         popl %ecx

 82         popl %ebx

 83         popl %eax

 84         iret

 85 set_e0: movb $1,e0              // �յ�ɨ��ǰ����0xe0ʱ������e0��־��λ0����

 86         jmp e0_e1

 87 set_e1: movb $2,e0              // �յ�ɨ��ǰ����0xe1ʱ������e1��־��λ1����

 88         jmp e0_e1

 89

 90 /*

 91  * This routine fills the buffer with max 8 bytes, taken from

 92  * %ebx:%eax. (%edx is high). The bytes are written in the

 93  * order %al,%ah,%eal,%eah,%bl,%bh ... until %eax is zero.

 94  */

    /*

     * ������ӳ����ebx:eax�е����8���ַ����뻺������С���ebx��

     * ���֣���д���ַ���˳����al,ah,eal,eah,bl,bh...ֱ��eax����0��

     */

    // ���ȴӻ�����е�ַ��table_list��tty_io.c��99�У�ȡ����̨�Ķ��������read_q��ַ��

    // Ȼ���al�Ĵ����е��ַ����Ƶ�������ͷָ�봦����ͷָ��ǰ��1�ֽ�λ�á���ͷָ���Ƴ�

    // ����������ĩ�ˣ���������Ƶ���������ʼ���� Ȼ���ٿ�����ʱ��������Ƿ����������Ƚ�

    // һ�¶���ͷָ���Ƿ���βָ����ȣ���ȱ�ʾ������ ����������Ͱ�ebx:eax�п��ܻ��е�

    // �����ַ�ȫ���������������������δ�����Ͱ�ebx:eax��������������8�����أ�����ah

    // ֵ�Ƶ�al��bl��ah��bh��bl����Ȼ���ظ������al�Ĵ������̡�ֱ�������ַ����������

    // �ͱ��浱ǰͷָ��ֵ���ټ��һ���Ƿ��н��̵ȴ��Ŷ����У�����оȻ���֮��

 95 put_queue:

 96         pushl %ecx

 97         pushl %edx                   // �¾�ȡ����̨tty�ṹ�ж��������ָ�롣

 98         movl _table_list,%edx         # read-queue for console

 99         movl head(%edx),%ecx         // ȡ����ͷָ����ecx��

100 1:      movb %al,buf(%edx,%ecx)      // ��al�е��ַ�����ͷָ��λ�ô���

101         incl %ecx                    // ͷָ��ǰ��1�ֽڡ�

102         andl $size-1,%ecx            // ����ͷָ�롣������������ĩ�����ƻؿ�ʼ����

103         cmpl tail(%edx),%ecx          # buffer full - discard everything

                                         // ͷָ��==βָ���𣿣���������������𣿣�

104         je 3f                        // ��������������δ������ַ�ȫ������

105         shrdl $8,%ebx,%eax           // ��ebx��8����������8λ��eax�У�ebx���䡣

106         je 2f                        // �����ַ�����û�У�����0������ת��

107         shrl $8,%ebx                 // ��ebxֵ����8λ������ת�����1����������

108         jmp 1b

109 2:      movl %ecx,head(%edx)         // ���ѽ������ַ���������У��򱣴�ͷָ�롣

110         movl proc_list(%edx),%ecx    // �ö��еĵȴ�����ָ�룿

111         testl %ecx,%ecx              // ����Ƿ��еȴ��ö��еĽ��̡�

112         je 3f                        // �ޣ�����ת��

113         movl $0,(%ecx)               // �У����ѽ��̣��øý���Ϊ����״̬����

114 3:      popl %edx

115         popl %ecx

116         ret

117

    // �����↑ʼ�Ǽ���ת��key_table��ָ���Ӧ�ĸ������������ɼ��������ӳ��򡣹������

    // 53�������á�����ת��key_table�ڵ�513�п�ʼ��

    //

    // ������δ������ctrl��alt��ɨ���룬�ֱ�����ģʽ��־mode����Ӧλ������ڸ�ɨ��

    // ��֮ǰ�յ���0xe0ɨ���루e0��־��λ������˵�����µ��Ǽ����ұߵ�ctrl��alt������

    // ��Ӧ����ctrl��alt��ģʽ��־mode�еı���λ��

118 ctrl:   movb $0x04,%al               // 0x4��mode����ctrl����Ӧ�ı���λ��λ2����

119         jmp 1f

120 alt:    movb $0x10,%al               // 0x10��mode����alt����Ӧ�ı���λ��λ4����

121 1:      cmpb $0,e0                   // e0��λ���𣨰��µ����ұߵ�ctrl/alt���𣩣�

122         je 2f                        // ������ת��

123         addb %al,%al                 // �ǣ���ij�����Ӧ�Ҽ���־λ��λ3��λ5����

124 2:      orb %al,mode                 // ����mode��־�ж�Ӧ�ı���λ��

125         ret

    // ��δ��봦��ctrl��alt���ɿ�ʱ��ɨ���룬��λģʽ��־mode�еĶ�Ӧ����λ���ڴ���

    // ʱҪ����e0��־�Ƿ���λ���ж��Ƿ��Ǽ����ұߵ�ctrl��alt����

126 unctrl: movb $0x04,%al               // mode����ctrl����Ӧ�ı���λ��λ2����

127         jmp 1f

128 unalt:  movb $0x10,%al               // 0x10��mode����alt����Ӧ�ı���λ��λ4����

129 1:      cmpb $0,e0                   // e0��λ�����ͷŵ����ұߵ�ctrl/alt���𣩣�

130         je 2f                        // ���ǣ���ת��

131         addb %al,%al                 // �ǣ���ijɸ�λ��Ӧ�Ҽ��ı�־λ��λ3��λ5����

132 2:      notb %al                     // ��λmode��־�ж�Ӧ�ı���λ��

133         andb %al,mode

134         ret

135

    // ��δ��봦������shift�����º��ɿ�ʱ��ɨ���룬�ֱ����ú͸�λmode�е���Ӧλ��

136 lshift:

137         orb $0x01,mode               // ����shift�����£�����mode��λ0��

138         ret

139 unlshift:

140         andb $0xfe,mode              // ����shift���ɿ�����λmode��λ0��

141         ret

142 rshift:

143         orb $0x02,mode               // ����shift�����£�����mode��λ1��

144         ret

145 unrshift:

146         andb $0xfd,mode              // ����shift���ɿ�����λmode��λ1��

147         ret

148

    // ��δ�����յ�caps��ɨ������д�����ͨ��mode��λ7����֪��caps����ǰ�Ƿ�������

    // �ڰ���״̬�������򷵻أ�����ͷ�תmode��־��caps�����µı���λ��λ6����leds��

    // ־��caps-lock����λ��λ2��������mode��־��caps���Ѱ��±�־λ��λ7����

149 caps:   testb $0x80,mode             // ����mode��λ7�Ƿ�����λ�����ڰ���״̬����

150         jne 1f                       // ����Ѵ��ڰ���״̬���򷵻أ�186�У���

151         xorb $4,leds                 // ��תleds��־��caps-lock����λ��λ2����

152         xorb $0x40,mode              // ��תmode��־��caps�����µı���λ��λ6����

153         orb $0x80,mode               // ����mode��־��caps���Ѱ��±�־λ��λ7����

    // ��δ������leds��־��������ر�LEDָʾ����

154 set_leds:

155         call kb_wait                 // �ȴ����̿��������뻺��ա�

156         movb $0xed,%al               /* set leds command */

157         outb %al,$0x60               // ���ͼ�������0xed��0x60�˿ڡ�

158         call kb_wait

159         movb leds,%al                // ȡleds��־����Ϊ������

160         outb %al,$0x60               // ���͸ò�����

161         ret

162 uncaps: andb $0x7f,mode              // caps���ɿ�����λmode�еĶ�Ӧλ��λ7����

163         ret

164 scroll:

165         testb $0x03,mode             // ����ʱctrl��Ҳͬʱ���£���

166         je 1f

167         call _show_mem               // ��ʾ�ڴ�״̬��Ϣ��mm/memory.c��457�У���

168         jmp 2f

169 1:      call _show_state             // ������ʾ����״̬��Ϣ��kernel/sched.c��45�У���

170 2:      xorb $1,leds                 // scroll�����£���תleds�ж�Ӧλ��λ0����

171         jmp set_leds                 // ����leds��־���¿�����ر�LEDָʾ����

172 num:    xorb $2,leds                 // num�����£���תleds�еĶ�Ӧλ��λ1����

173         jmp set_leds                 // ����leds��־���¿�����ر�LEDָʾ����

174

175 /*

176  *  curosr-key/numeric keypad cursor keys are handled here.

177  *  checking for numeric keypad etc.

178  */

    /*

     * ���ﴦ�������/����С���̷�������������С���̵ȡ�

     */

179 cursor:

180         subb $0x47,%al          // ɨ���������ּ����ϵļ�����ɨ����>=0x47�������ģ�

181         jb 1f                   // ���С���򲻴��������أ�198�У���

182         cmpb $12,%al            // ���ɨ���� > 0x53��0x53 - 0x47 = 12������

183         ja 1f                   // ��ʾɨ����ֵ����83��0x53���������������ء�

184         jne cur2                /* check for ctrl-alt-del */ /* ���ctrl-alt-del��*/

    // ������12��˵��del���ѱ����£�������ж�ctrl��alt�Ƿ�Ҳ��ͬʱ���¡�

185         testb $0x0c,mode        // ��ctrl�����������ޣ�����ת��

186         je cur2

187         testb $0x30,mode        // ��alt��������

188         jne reboot              // �У�����ת��������������594�У���

189 cur2:   cmpb $0x01,e0           /* e0 forces cursor movement */ /* e0��λָ����ƶ�*/

                                    // e0��־��λ����

190         je cur                  // ��λ�ˣ�����ת����ƶ�������cur��

191         testb $0x02,leds        /* not num-lock forces cursor */ /* num-lock������*/

                                    // ����leds�б�־num-lock����־�Ƿ���λ��

192         je cur                  // ��û����λ��num��LED����������Ҳ��������ƶ���

193         testb $0x03,mode        /* shift forces cursor */ /* shift��Ҳʹ����ƶ� */

                                    // ����ģʽ��־mode��shift���±�־��

194         jne cur                 // �����shift�����£���Ҳ���й���ƶ�������

195         xorl %ebx,%ebx          // �����ѯС���ֱ���199�У���ȡ��������ASCII�롣

196         movb num_table(%eax),%al      // ��eax��Ϊ����ֵ��ȡ��Ӧ�����ַ���al��

197         jmp put_queue           // �ַ����뻺������С�����Ҫ������е��ַ���<=4�����

198 1:      ret                     // ��ִ��put_queueǰ���ebx���㣬��87���ϵ�ע�͡�

199

    // ��δ��봦������ƶ������ɾ��������

200 cur:    movb cur_table(%eax),%al      // ȡ����ַ�������Ӧ���Ĵ����ַ���al��

201         cmpb $'9,%al            // ���ַ�<='9'��5��6��2��3����˵������һҳ����һҳ��

202         ja ok_cur               // �����ɾ�����������ַ�������Ҫ�����ַ�'~'������

203         movb $'~,%ah            // ���ں˲�û�ж����ǽ���ʶ��ʹ�����

204 ok_cur: shll $16,%eax           // ��ax�������Ƶ�eax�����С�

205         movw $0x5b1b,%ax        // ��'esc ['����ax����eax�������ַ�����ƶ����С�

206         xorl %ebx,%ebx          // ����ֻ���eax���ַ�������У������Ҫ��ebx���㡣

207         jmp put_queue           // �����ַ����뻺������С�

208

209 #if defined(KBD_FR)

210 num_table:

211         .ascii "789 456 1230."  // ����С�����ϼ���Ӧ������ASCII�����

212 #else

213 num_table:

214         .ascii "789 456 1230,"

215 #endif

216 cur_table:

217         .ascii "HA5 DGC YB623"  // С�����Ϸ���������ɾ������Ӧ���ƶ���ʾ�ַ�����

218

219 /*

220  * this routine handles function keys

221  */

    /*

     * �����ӳ��������ܼ���

     */

    // �ѹ��ܼ�ɨ����任��ת���ַ����в���ŵ��������С�

222 func:

223         subb $0x3B,%al             // ��'F1'��ɨ������0x3B�����al���ǹ��ܼ������š�

224         jb end_func                // ���ɨ����С��0x3b���򲻴��������ء�

225         cmpb $9,%al                // ���ܼ���F1--F10��

226         jbe ok_func                // �ǣ�����ת��

227         subb $18,%al               // �ǹ��ܼ�F11��F12��F11��F12ɨ������0x57��0x58��

228         cmpb $10,%al               // �ǹ��ܼ�F11��

229         jb end_func                // ���ǣ��򲻴��������ء�

230         cmpb $11,%al               // �ǹ��ܼ�F12��

231         ja end_func                // ���ǣ��򲻴��������ء�

232 ok_func:

233         testb $0x10,mode           // ��alt��Ҳͬʱ��������

234         jne alt_func               // ������ת����������������նˡ�

235         cmpl $4,%ecx               /* check that there is enough room */ /*���ռ�*/

236         jl end_func                // [??]��Ҫ����4���ַ�������Ų��£��򷵻ء�

237         movl func_table(,%eax,4),%eax      // ȡ���ܼ���Ӧ�ַ����С�

238         xorl %ebx,%ebx             // ��Ҫ��������ַ���=4�����ִ��put_queue֮ǰ

239         jmp put_queue              // ���ebx���㡣

    // ���� alt + Fn ��ϼ����ı���������նˡ���ʱeax���ǹ��ܼ������ţ�F1 -- 0������Ӧ

    // ��������ն˺š�

240 alt_func:

241         pushl %eax                 // ��������ն˺���ջ����Ϊ������

242         call _change_console       // ���ĵ�ǰ��������նˣ�chr_dev/tty_io.c��87�У���

243         popl %eax                  // ����������

244 end_func:

245         ret

246

247 /*

248  * function keys send F1:'esc [ [ A' F2:'esc [ [ B' etc.

249  */

    /*

     * ���ܼ����͵�ɨ���룬F1��Ϊ��'esc [ [ A'�� F2��Ϊ��'esc [ [ B'�ȡ�

     */

250 func_table:

251         .long 0x415b5b1b,0x425b5b1b,0x435b5b1b,0x445b5b1b

252         .long 0x455b5b1b,0x465b5b1b,0x475b5b1b,0x485b5b1b

253         .long 0x495b5b1b,0x4a5b5b1b,0x4b5b5b1b,0x4c5b5b1b

254

    // ɨ����-ASCII�ַ�ӳ�����

    // ����ǰ�涨��ļ�������(FINNISH��US��GERMEN��FRANCH)������Ӧ����ɨ����ӳ�䵽

    // ASCII�ַ���

255 #if     defined(KBD_FINNISH)    // �����Ƿ�������̵�ɨ����ӳ�����

256 key_map:

257         .byte 0,27              // ɨ����0x00,0x01��Ӧ��ASCII�룻

258         .ascii "1234567890+'"   // ɨ����0x02,...0x0c,0x0d��Ӧ��ASCII�룬�������ơ�

259         .byte 127,9

260         .ascii "qwertyuiop}"

261         .byte 0,13,0

262         .ascii "asdfghjkl|{"

263         .byte 0,0

264         .ascii "'zxcvbnm,.-"

265         .byte 0,'*,0,32         /* 36-39 */   /* ɨ����0x36-0x39��Ӧ��ASCII�� */

266         .fill 16,1,0            /* 3A-49 */   /* ɨ����0x3A-0x49��Ӧ��ASCII�� */

267         .byte '-,0,0,0,'+       /* 4A-4E */   /* ɨ����0x4A-0x4E��Ӧ��ASCII�� */

268         .byte 0,0,0,0,0,0,0     /* 4F-55 */   /* ɨ����0x4F-0x55��Ӧ��ASCII�� */

269         .byte '<

270         .fill 10,1,0

271

272 shift_map:                      // shift��ͬʱ����ʱ��ӳ�����

273         .byte 0,27

274         .ascii "!\"#$%&/()=?`"

275         .byte 127,9

276         .ascii "QWERTYUIOP]^"

277         .byte 13,0

278         .ascii "ASDFGHJKL\\["

279         .byte 0,0

280         .ascii "*ZXCVBNM;:_"

281         .byte 0,'*,0,32         /* 36-39 */

282         .fill 16,1,0            /* 3A-49 */

283         .byte '-,0,0,0,'+       /* 4A-4E */

284         .byte 0,0,0,0,0,0,0     /* 4F-55 */

285         .byte '>

286         .fill 10,1,0

287

288 alt_map:                         // alt��ͬʱ����ʱ��ӳ�����

289         .byte 0,0

290         .ascii "\0@\0$\0\0{[]}\\\0"

291         .byte 0,0

292         .byte 0,0,0,0,0,0,0,0,0,0,0

293         .byte '~,13,0

294         .byte 0,0,0,0,0,0,0,0,0,0,0

295         .byte 0,0

296         .byte 0,0,0,0,0,0,0,0,0,0,0

297         .byte 0,0,0,0           /* 36-39 */

298         .fill 16,1,0            /* 3A-49 */

299         .byte 0,0,0,0,0         /* 4A-4E */

300         .byte 0,0,0,0,0,0,0     /* 4F-55 */

301         .byte '|

302         .fill 10,1,0

303

304 #elif defined(KBD_US)           // ��������ʽ���̵�ɨ����ӳ�����

305

306 key_map:

307         .byte 0,27

308         .ascii "1234567890-="

309         .byte 127,9

310         .ascii "qwertyuiop[]"

311         .byte 13,0

312         .ascii "asdfghjkl;'"

313         .byte '`,0

314         .ascii "\\zxcvbnm,./"

315         .byte 0,'*,0,32         /* 36-39 */

316         .fill 16,1,0            /* 3A-49 */

317         .byte '-,0,0,0,'+       /* 4A-4E */

318         .byte 0,0,0,0,0,0,0     /* 4F-55 */

319         .byte '<

320         .fill 10,1,0

321

322

323 shift_map:

324         .byte 0,27

325         .ascii "!@#$%^&*()_+"

326         .byte 127,9

327         .ascii "QWERTYUIOP{}"

328         .byte 13,0

329         .ascii "ASDFGHJKL:\""

330         .byte '~,0

331         .ascii "|ZXCVBNM<>?"

332         .byte 0,'*,0,32         /* 36-39 */

333         .fill 16,1,0            /* 3A-49 */

334         .byte '-,0,0,0,'+       /* 4A-4E */

335         .byte 0,0,0,0,0,0,0     /* 4F-55 */

336         .byte '>

337         .fill 10,1,0

338

339 alt_map:

340         .byte 0,0

341         .ascii "\0@\0$\0\0{[]}\\\0"

342         .byte 0,0

343         .byte 0,0,0,0,0,0,0,0,0,0,0

344         .byte '~,13,0

345         .byte 0,0,0,0,0,0,0,0,0,0,0

346         .byte 0,0

347         .byte 0,0,0,0,0,0,0,0,0,0,0

348         .byte 0,0,0,0           /* 36-39 */

349         .fill 16,1,0            /* 3A-49 */

350         .byte 0,0,0,0,0         /* 4A-4E */

351         .byte 0,0,0,0,0,0,0     /* 4F-55 */

352         .byte '|

353         .fill 10,1,0

354

355 #elif defined(KBD_GR)           // �����ǵ�����̵�ɨ����ӳ�����

356

357 key_map:

358         .byte 0,27

359         .ascii "1234567890\\'"

360         .byte 127,9

361         .ascii "qwertzuiop@+"

362         .byte 13,0

363         .ascii "asdfghjkl[]^"

364         .byte 0,'#

365         .ascii "yxcvbnm,.-"

366         .byte 0,'*,0,32         /* 36-39 */

367         .fill 16,1,0            /* 3A-49 */

368         .byte '-,0,0,0,'+       /* 4A-4E */

369         .byte 0,0,0,0,0,0,0     /* 4F-55 */

370         .byte '<

371         .fill 10,1,0

372

373

374 shift_map:

375         .byte 0,27

376         .ascii "!\"#$%&/()=?`"

377         .byte 127,9

378         .ascii "QWERTZUIOP\\*"

379         .byte 13,0

380         .ascii "ASDFGHJKL{}~"

381         .byte 0,''

382         .ascii "YXCVBNM;:_"

383         .byte 0,'*,0,32         /* 36-39 */

384         .fill 16,1,0            /* 3A-49 */

385         .byte '-,0,0,0,'+       /* 4A-4E */

386         .byte 0,0,0,0,0,0,0     /* 4F-55 */

387         .byte '>

388         .fill 10,1,0

389

390 alt_map:

391         .byte 0,0

392         .ascii "\0@\0$\0\0{[]}\\\0"

393         .byte 0,0

394         .byte '@,0,0,0,0,0,0,0,0,0,0

395         .byte '~,13,0

396         .byte 0,0,0,0,0,0,0,0,0,0,0

397         .byte 0,0

398         .byte 0,0,0,0,0,0,0,0,0,0,0

399         .byte 0,0,0,0           /* 36-39 */

400         .fill 16,1,0            /* 3A-49 */

401         .byte 0,0,0,0,0         /* 4A-4E */

402         .byte 0,0,0,0,0,0,0     /* 4F-55 */

403         .byte '|

404         .fill 10,1,0

405

406

407 #elif defined(KBD_FR)           // �����Ƿ�����̵�ɨ����ӳ�����

408

409 key_map:

410         .byte 0,27

411         .ascii "&{\"'(-}_/@)="

412         .byte 127,9

413         .ascii "azertyuiop^$"

414         .byte 13,0

415         .ascii "qsdfghjklm|"

416         .byte '`,0,42           /* coin sup gauche, don't know, [*|mu] */

417         .ascii "wxcvbn,;:!"

418         .byte 0,'*,0,32         /* 36-39 */

419         .fill 16,1,0            /* 3A-49 */

420         .byte '-,0,0,0,'+       /* 4A-4E */

421         .byte 0,0,0,0,0,0,0     /* 4F-55 */

422         .byte '<

423         .fill 10,1,0

424

425 shift_map:

426         .byte 0,27

427         .ascii "1234567890]+"

428         .byte 127,9

429         .ascii "AZERTYUIOP<>"

430         .byte 13,0

431         .ascii "QSDFGHJKLM%"

432         .byte '~,0,'#

433         .ascii "WXCVBN?./\\"

434         .byte 0,'*,0,32         /* 36-39 */

435         .fill 16,1,0            /* 3A-49 */

436         .byte '-,0,0,0,'+       /* 4A-4E */

437         .byte 0,0,0,0,0,0,0     /* 4F-55 */

438         .byte '>

439         .fill 10,1,0

440

441 alt_map:

442         .byte 0,0

443         .ascii "\0~#{[|`\\^@]}"

444         .byte 0,0

445         .byte '@,0,0,0,0,0,0,0,0,0,0

446         .byte '~,13,0

447         .byte 0,0,0,0,0,0,0,0,0,0,0

448         .byte 0,0

449         .byte 0,0,0,0,0,0,0,0,0,0,0

450         .byte 0,0,0,0           /* 36-39 */

451         .fill 16,1,0            /* 3A-49 */

452         .byte 0,0,0,0,0         /* 4A-4E */

453         .byte 0,0,0,0,0,0,0     /* 4F-55 */

454         .byte '|

455         .fill 10,1,0

456

457 #else

458 #error "KBD-type not defined"

459 #endif

460 /*

461  * do_self handles "normal" keys, ie keys that don't change meaning

462  * and which have just one character returns.

463  */

    /*

     * do_self���ڴ�������ͨ������Ҳ������û�б仯����ֻ��һ���ַ����صļ���

     */

    // ���ȸ���mode��־ѡ��alt_map��shift_map��key_mapӳ���֮һ��

464 do_self:

465         lea alt_map,%ebx             // ȡalt��ͬʱ����ʱ��ӳ�����ַalt_map��

466         testb $0x20,mode             /* alt-gr */  /* ��alt��ͬʱ������? */

467         jne 1f                       // �ǣ�����ǰ��ת�����1����

468         lea shift_map,%ebx           // ȡshift��ͬʱ����ʱ��ӳ�����ַshift_map��

469         testb $0x03,mode             // ��shift��ͬʱ��������

470         jne 1f                       // �У�����ǰ��ת�����1��ȥӳ���ַ���

471         lea key_map,%ebx             // ����ʹ����ͨӳ���key_map��

    // Ȼ�����ɨ����ȡӳ����ж�Ӧ��ASCII�ַ�����û�ж�Ӧ�ַ����򷵻أ�תnone����

472 1:      movb (%ebx,%eax),%al         // ��ɨ������Ϊ����ֵ��ȡ��Ӧ��ASCII����al��

473         orb %al,%al                  // ��⿴�Ƿ��ж�Ӧ��ASCII�롣

474         je none                      // ��û��(��Ӧ��ASCII��=0)���򷵻ء�

    // ��ctrl���Ѱ��»�caps�������������ַ��� 'a'--'}'��0x61--0x7D����Χ�ڣ�����ת��

    // ��д�ַ���0x41--0x5D����

475         testb $0x4c,mode             /* ctrl or caps */  /* ���Ƽ��Ѱ��»�caps����*/

476         je 2f                        // û�У�����ǰ��ת���2����

477         cmpb $'a,%al                 // ��al�е��ַ���'a'�Ƚϡ�

478         jb 2f                        // ��alֵ<'a'����ת���2����

479         cmpb $'},%al                 // ��al�е��ַ���'}'�Ƚϡ�

480         ja 2f                        // ��alֵ>'}'����ת���2����

481         subb $32,%al                 // ��alת��Ϊ��д�ַ�����0x20����

    // ��ctrl���Ѱ��£������ַ��� '`'--'_'��0x40--0x5F��֮�䣬���Ǵ�д�ַ�������ת��Ϊ

    // �����ַ���0x00--0x1F����

482 2:      testb $0x0c,mode             /* ctrl */  /* ctrl��ͬʱ��������*/

483         je 3f                        // ��û����ת���3��

484         cmpb $64,%al                 // ��al��'@'��64���ַ��Ƚϣ����ж��ַ�������Χ��

485         jb 3f                        // ��ֵ<'@'����ת���3��

486         cmpb $64+32,%al              // ��al��'`'��96���ַ��Ƚϣ����ж��ַ�������Χ��

487         jae 3f                       // ��ֵ>='`'����ת���3��

488         subb $64,%al                 // ����al��0x40��ת��Ϊ0x00--0x1f�Ŀ����ַ���

    // ����alt��ͬʱ���£����ַ���λ7��λ������ʱ����ֵ����0x7f����չ�ַ����е��ַ���

489 3:      testb $0x10,mode             /* left alt */  /* ��alt��ͬʱ���£�*/

490         je 4f                        // û�У���ת���4��

491         orb $0x80,%al                // �ַ���λ7��λ��

    // ��al�е��ַ��������������С�

492 4:      andl $0xff,%eax              // ��eax�ĸ��ֺ�ah��

493         xorl %ebx,%ebx               // ���ڷ�������ַ���<=4��������ebx���㡣

494         call put_queue               // ���ַ����뻺������С�

495 none:   ret

496

497 /*

498  * minus has a routine of it's own, as a 'E0h' before

499  * the scan code for minus means that the numeric keypad

500  * slash was pushed.

501  */

    /*

     * ���������Լ��Ĵ����ӳ�����Ϊ�ڼ���ɨ����֮ǰ��0xe0

     * ��ζ�Ű���������С�����ϵ�б�ܼ���

     */

    // ע�⣬���ڷ�����͵�����̣�ɨ����0x35��Ӧ����'-'�����μ���264��365�С�

502 minus:  cmpb $1,e0                   // e0��־��λ����

503         jne do_self                  // û�У������do_self�Լ��ŷ�������ͨ������

504         movl $'/,%eax                // ������'/'�滻����'-'��al��

505         xorl %ebx,%ebx               // ���ڷ�������ַ���<=4��������ebx���㡣

506         jmp put_queue                // �����ַ����뻺������С�

507

508 /*

509  * This table decides which routine to call when a scan-code has been

510  * gotten. Most routines just call do_self, or none, depending if

511  * they are make or break.

512  */

    /*

     * ������һ���ӳ����ַ��ת������ȡ��ɨ�����͸��ݴ˱�������Ӧ��ɨ����

     * �����ӳ��򡣴�������õ��ӳ�����do_self��������none����������ǰ���

     * ��make�������ͷż�(break)��

     */

513 key_table:

514         .long none,do_self,do_self,do_self      /* 00-03 s0 esc 1 2 */

515         .long do_self,do_self,do_self,do_self   /* 04-07 3 4 5 6 */

516         .long do_self,do_self,do_self,do_self   /* 08-0B 7 8 9 0 */

517         .long do_self,do_self,do_self,do_self   /* 0C-0F + ' bs tab */

518         .long do_self,do_self,do_self,do_self   /* 10-13 q w e r */

519         .long do_self,do_self,do_self,do_self   /* 14-17 t y u i */

520         .long do_self,do_self,do_self,do_self   /* 18-1B o p } ^ */

521         .long do_self,ctrl,do_self,do_self      /* 1C-1F enter ctrl a s */

522         .long do_self,do_self,do_self,do_self   /* 20-23 d f g h */

523         .long do_self,do_self,do_self,do_self   /* 24-27 j k l | */

524         .long do_self,do_self,lshift,do_self    /* 28-2B { para lshift , */

525         .long do_self,do_self,do_self,do_self   /* 2C-2F z x c v */

526         .long do_self,do_self,do_self,do_self   /* 30-33 b n m , */

527         .long do_self,minus,rshift,do_self      /* 34-37 . - rshift * */

528         .long alt,do_self,caps,func             /* 38-3B alt sp caps f1 */

529         .long func,func,func,func               /* 3C-3F f2 f3 f4 f5 */

530         .long func,func,func,func               /* 40-43 f6 f7 f8 f9 */

531         .long func,num,scroll,cursor            /* 44-47 f10 num scr home */

532         .long cursor,cursor,do_self,cursor      /* 48-4B up pgup - left */

533         .long cursor,cursor,do_self,cursor      /* 4C-4F n5 right + end */

534         .long cursor,cursor,cursor,cursor       /* 50-53 dn pgdn ins del */

535         .long none,none,do_self,func            /* 54-57 sysreq ? < f11 */

536         .long func,none,none,none               /* 58-5B f12 ? ? ? */

537         .long none,none,none,none               /* 5C-5F ? ? ? ? */

538         .long none,none,none,none               /* 60-63 ? ? ? ? */

539         .long none,none,none,none               /* 64-67 ? ? ? ? */

540         .long none,none,none,none               /* 68-6B ? ? ? ? */

541         .long none,none,none,none               /* 6C-6F ? ? ? ? */

542         .long none,none,none,none               /* 70-73 ? ? ? ? */

543         .long none,none,none,none               /* 74-77 ? ? ? ? */

544         .long none,none,none,none               /* 78-7B ? ? ? ? */

545         .long none,none,none,none               /* 7C-7F ? ? ? ? */

546         .long none,none,none,none               /* 80-83 ? br br br */

547         .long none,none,none,none               /* 84-87 br br br br */

548         .long none,none,none,none               /* 88-8B br br br br */

549         .long none,none,none,none               /* 8C-8F br br br br */

550         .long none,none,none,none               /* 90-93 br br br br */

551         .long none,none,none,none               /* 94-97 br br br br */

552         .long none,none,none,none               /* 98-9B br br br br */

553         .long none,unctrl,none,none             /* 9C-9F br unctrl br br */

554         .long none,none,none,none               /* A0-A3 br br br br */

555         .long none,none,none,none               /* A4-A7 br br br br */

556         .long none,none,unlshift,none           /* A8-AB br br unlshift br */

557         .long none,none,none,none               /* AC-AF br br br br */

558         .long none,none,none,none               /* B0-B3 br br br br */

559         .long none,none,unrshift,none           /* B4-B7 br br unrshift br */

560         .long unalt,none,uncaps,none            /* B8-BB unalt br uncaps br */

561         .long none,none,none,none               /* BC-BF br br br br */

562         .long none,none,none,none               /* C0-C3 br br br br */

563         .long none,none,none,none               /* C4-C7 br br br br */

564         .long none,none,none,none               /* C8-CB br br br br */

565         .long none,none,none,none               /* CC-CF br br br br */

566         .long none,none,none,none               /* D0-D3 br br br br */

567         .long none,none,none,none               /* D4-D7 br br br br */

568         .long none,none,none,none               /* D8-DB br ? ? ? */

569         .long none,none,none,none               /* DC-DF ? ? ? ? */

570         .long none,none,none,none               /* E0-E3 e0 e1 ? ? */

571         .long none,none,none,none               /* E4-E7 ? ? ? ? */

572         .long none,none,none,none               /* E8-EB ? ? ? ? */

573         .long none,none,none,none               /* EC-EF ? ? ? ? */

574         .long none,none,none,none               /* F0-F3 ? ? ? ? */

575         .long none,none,none,none               /* F4-F7 ? ? ? ? */

576         .long none,none,none,none               /* F8-FB ? ? ? ? */

577         .long none,none,none,none               /* FC-FF ? ? ? ? */

578

579 /*

580  * kb_wait waits for the keyboard controller buffer to empty.

581  * there is no timeout - if the buffer doesn't empty, we hang.

582  */

    /*

     * �ӳ���kb_wait���ڵȴ����̿���������ա������ڳ�ʱ���� - ���

     * ������Զ���յĻ�������ͻ���Զ�ȴ�(����)��

     */

583 kb_wait:

584         pushl %eax

585 1:      inb $0x64,%al                 // �����̿�����״̬��

586         testb $0x02,%al               // �������뻺�����Ƿ�Ϊ�գ�����0����

587         jne 1b                        // �����գ�����תѭ���ȴ���

588         popl %eax

589         ret

590 /*

591  * This routine reboots the machine by asking the keyboard

592  * controller to pulse the reset-line low.

593  */

    /*

     * ���ӳ���ͨ�����ü��̿���������λ����������壬ʹϵͳ��

     * λ������reboot����

     */

    // ���ӳ����������ڴ��ַ0x472��дֵ0x1234����λ��������ģʽ��reboot_mode����־�֡�

    // ������������ROM BIOS���ȡ������ģʽ��־ֵ��������ֵ��ָ����һ����ִ�С� �����

    // ֵ��0x1234����BIOS �ͻ������ڴ�����̶�ִ����������Warm-boot�����̡� �������

    // ֵΪ0����ִ����������Cold-boot�����̡�

594 reboot:

595         call kb_wait                  // ���ȵȴ����̿��������뻺�����ա�

596         movw $0x1234,0x472            /* don't do memory check */ /* ������ڴ� */

597         movb $0xfc,%al                /* pulse reset and A20 low */

598         outb %al,$0x64                // ��ϵͳ��λ���ź�A20����������塣

599 die:    jmp die                       // ͣ����


 


 

10.2 ����10-2 linux/kernel/chr_drv/console.c


  1 /*

  2  *  linux/kernel/console.c

  3  *

  4  *  (C) 1991  Linus Torvalds

  5  */

  6

  7 /*

  8  *      console.c

  9  *

 10  * This module implements the console io functions

 11  *      'void con_init(void)'

 12  *      'void con_write(struct tty_queue * queue)'

 13  * Hopefully this will be a rather complete VT102 implementation.

 14  *

 15  * Beeping thanks to John T Kohl.

 16  *

 17  * Virtual Consoles, Screen Blanking, Screen Dumping, Color, Graphics

 18  *   Chars, and VT100 enhancements by Peter MacDonald.

 19  */

    /*

     *      console.c

     *

     * ��ģ��ʵ�ֿ���̨�����������

     *     'void con_init(void)'

     *     'void con_write(struct tty_queue * queue)'

     * ϣ������һ���dz�������VT102ʵ�֡�

     *

     * ��лJohn T Kohl ʵ���˷���ָʾ�ӳ���

     *

     * �������̨����Ļ������������Ļ��������ɫ������ͼ���ַ���ʾ�Լ�

     * VT100�ն���ǿ������Peter MacDonald���ơ�

     */

 20

 21 /*

 22  *  NOTE!!! We sometimes disable and enable interrupts for a short while

 23  * (to put a word in video IO), but this will work even for keyboard

 24  * interrupts. We know interrupts aren't enabled when getting a keyboard

 25  * interrupt, as we use trap-gates. Hopefully all is well.

 26  */

    /*

     * ע��!!! ������ʱ���ݵؽ�ֹ�������жϣ������һ����(word) ����ƵIO������

     * ��ʹ���ڼ����ж���Ҳ�ǿ��Թ����ġ���Ϊ����ʹ�������ţ���������֪���ڴ���

     * һ�������жϹ����ڼ��ж��DZ���ֹ�ġ�ϣ��һ�о�������

     */

 27

 28 /*

 29  * Code to check for different video-cards mostly by Galen Hunt,

 30  * <g-hunt@ee.utah.edu>

 31  */

    /*

     * ��ⲻͬ��ʾ���Ĵ����������Galen Hunt��д�ģ�

     * <g-hunt@ee.utah.edu>

     */

 32

 33 #include <linux/sched.h>  // ���ȳ���ͷ�ļ�����������ṹtask_struct������0���ݵȡ�

 34 #include <linux/tty.h>    // ttyͷ�ļ��������й�tty_io������ͨ�ŷ���IJ�����������

 35 #include <linux/config.h> // �ں�����ͷ�ļ�������Ӳ�����ͣ�HD_TYPE����ѡ�

 36 #include <linux/kernel.h> // �ں�ͷ�ļ�������һЩ�ں˳��ú�����ԭ�ζ��塣

 37

 38 #include <asm/io.h>       // ioͷ�ļ�������Ӳ���˿�����/���������䡣

 39 #include <asm/system.h>   // ϵͳͷ�ļ����������û��޸�������/�ж��ŵȵĻ��ꡣ

 40 #include <asm/segment.h>  // �β���ͷ�ļ����������йضμĴ���������Ƕ��ʽ��ຯ����

 41

 42 #include <string.h>       // �ַ���ͷ�ļ�����Ҫ������һЩ�й��ַ���������Ƕ�뺯����

 43 #include <errno.h>        // �����ͷ�ļ�������ϵͳ�и��ֳ����š�

 44

    // �÷��ų��������ն�IO�ṹ��Ĭ�����ݡ����з��ų��������include/termios.h�ļ���

 45 #define DEF_TERMIOS \

 46 (struct termios) { \

 47         ICRNL, \

 48         OPOST | ONLCR, \

 49         0, \

 50         IXON | ISIG | ICANON | ECHO | ECHOCTL | ECHOKE, \

 51         0, \

 52         INIT_C_CC \

 53 }

 54

 55

 56 /*

 57  * These are set up by the setup-routine at boot-time:

 58  */

    /*

     * ��Щ��setup��������������ϵͳʱ���õIJ�����

     */

    // �μ���boot/setup.s��ע�ͺ�setup�����ȡ��������ϵͳ��������

 59

 60 #define ORIG_X            (*(unsigned char *)0x90000)      // ��ʼ����кš�

 61 #define ORIG_Y            (*(unsigned char *)0x90001)      // ��ʼ����кš�

 62 #define ORIG_VIDEO_PAGE   (*(unsigned short *)0x90004)     // ��ʼ��ʾҳ�档

 63 #define ORIG_VIDEO_MODE   ((*(unsigned short *)0x90006) & 0xff)          // ��ʾģʽ��

 64 #define ORIG_VIDEO_COLS   (((*(unsigned short *)0x90006) & 0xff00) >> 8) // ��Ļ������

 65 #define ORIG_VIDEO_LINES  ((*(unsigned short *)0x9000e) & 0xff)          // ��Ļ������

 66 #define ORIG_VIDEO_EGA_AX (*(unsigned short *)0x90008)     // [??]

 67 #define ORIG_VIDEO_EGA_BX (*(unsigned short *)0x9000a)     // ��ʾ�ڴ��С��ɫ��ģʽ��

 68 #define ORIG_VIDEO_EGA_CX (*(unsigned short *)0x9000c)     // ��ʾ�����Բ�����

 69

    // ������ʾ����ɫ/��ɫ��ʾģʽ���ͷ��ų�����

 70 #define VIDEO_TYPE_MDA    0x10    /* Monochrome Text Display     */  /* ��ɫ�ı�   */

 71 #define VIDEO_TYPE_CGA    0x11    /* CGA Display                 */  /* CGA��ʾ��  */

 72 #define VIDEO_TYPE_EGAM   0x20    /* EGA/VGA in Monochrome Mode  */  /* EGA/VGA��ɫ*/

 73 #define VIDEO_TYPE_EGAC   0x21    /* EGA/VGA in Color Mode       */  /* EGA/VGA��ɫ*/

 74

 75 #define NPAR 16                   // ת���ַ�������������������

 76

 77 int NR_CONSOLES = 0;              // ϵͳʵ��֧�ֵ��������̨������

 78

 79 extern void keyboard_interrupt(void);          // �����жϴ�������keyboard.S����

 80

    // ������Щ��̬�����DZ��ļ�������ʹ�õ�һЩȫ�ֱ�����

    // video_type;             ʹ�õ���ʾ���ͣ�

    // video_num_columns;      ��Ļ�ı�������

    // video_mem_base;         ������ʾ�ڴ����ַ��

    // video_mem_term;         ������ʾ�ڴ�ĩ�˵�ַ��

    // video_size_row;         ��Ļÿ��ʹ�õ��ֽ�����

    // video_num_lines;        ��Ļ�ı�������

    // video_page;             ������ʾҳ�棻

    // video_port_reg;         ��ʾ����ѡ��Ĵ����˿ڣ�

    // video_port_val;         ��ʾ�������ݼĴ����˿ڡ�

 81 static unsigned char    video_type;             /* Type of display being used   */

 82 static unsigned long    video_num_columns;      /* Number of text columns       */

 83 static unsigned long    video_mem_base;         /* Base of video memory         */

 84 static unsigned long    video_mem_term;         /* End of video memory          */

 85 static unsigned long    video_size_row;         /* Bytes per row                */

 86 static unsigned long    video_num_lines;        /* Number of test lines         */

 87 static unsigned char    video_page;             /* Initial video page           */

 88 static unsigned short   video_port_reg;         /* Video register select port   */

 89 static unsigned short   video_port_val;         /* Video register value port    */

 90 static int can_do_colour = 0;                   // ��־����ʹ�ò�ɫ���ܡ�

 91

    // �������̨�ṹ�����а���һ���������̨�ĵ�ǰ������Ϣ������vc_origin��vc_scr_end

    // �ǵ�ǰ���ڴ������������ִ̨�п��ٹ�������ʱʹ�õ���ʼ�к�ĩ�ж�Ӧ����ʾ�ڴ�λ�á�

    // vc_video_mem_start��vc_video_mem_end�ǵ�ǰ�������̨ʹ�õ���ʾ�ڴ����򲿷֡�

    // vc -- Virtual Console��

 92 static struct {

 93         unsigned short  vc_video_erase_char;    // �����ַ����Լ��ַ���0x0720��

 94         unsigned char   vc_attr;                // �ַ����ԡ�

 95         unsigned char   vc_def_attr;            // Ĭ���ַ����ԡ�

 96         int             vc_bold_attr;           // �����ַ����ԡ�

 97         unsigned long   vc_ques;                // �ʺ��ַ���

 98         unsigned long   vc_state;               // ����ת���������еĵ�ǰ״̬��

 99         unsigned long   vc_restate;             // ����ת���������е���һ״̬��

100         unsigned long   vc_checkin;

101         unsigned long   vc_origin;              /* Used for EGA/VGA fast scroll */

102         unsigned long   vc_scr_end;             /* Used for EGA/VGA fast scroll */

103         unsigned long   vc_pos;                 // ��ǰ����Ӧ����ʾ�ڴ�λ�á�

104         unsigned long   vc_x,vc_y;              // ��ǰ����С���ֵ��

105         unsigned long   vc_top,vc_bottom;       // ����ʱ�����кţ������кš�

106         unsigned long   vc_npar,vc_par[NPAR];   // ת�����в��������Ͳ������顣

107         unsigned long   vc_video_mem_start;     /* Start of video RAM           */

108         unsigned long   vc_video_mem_end;       /* End of video RAM (sort of)   */

109         unsigned int    vc_saved_x;             // ����Ĺ���кš�

110         unsigned int    vc_saved_y;             // ����Ĺ���кš�

111         unsigned int    vc_iscolor;             // ��ɫ��ʾ��־��

112         char *          vc_translate;           // ʹ�õ��ַ�����

113 } vc_cons [MAX_CONSOLES];

114

    // Ϊ�˱������ã����¶��嵱ǰ���ڴ�������̨��Ϣ�ķ��š�����ͬ�ϡ�����currcons��ʹ��

    // vc_cons[]�ṹ�ĺ��������еĵ�ǰ�����ն˺š�

115 #define origin          (vc_cons[currcons].vc_origin)  // ���ٹ���������ʼ�ڴ�λ�á�

116 #define scr_end         (vc_cons[currcons].vc_scr_end) // ���ٹ�������ĩ���ڴ�λ�á�

117 #define pos             (vc_cons[currcons].vc_pos)

118 #define top             (vc_cons[currcons].vc_top)

119 #define bottom          (vc_cons[currcons].vc_bottom)

120 #define x               (vc_cons[currcons].vc_x)

121 #define y               (vc_cons[currcons].vc_y)

122 #define state           (vc_cons[currcons].vc_state)

123 #define restate         (vc_cons[currcons].vc_restate)

124 #define checkin         (vc_cons[currcons].vc_checkin)

125 #define npar            (vc_cons[currcons].vc_npar)

126 #define par             (vc_cons[currcons].vc_par)

127 #define ques            (vc_cons[currcons].vc_ques)

128 #define attr            (vc_cons[currcons].vc_attr)

129 #define saved_x         (vc_cons[currcons].vc_saved_x)

130 #define saved_y         (vc_cons[currcons].vc_saved_y)

131 #define translate       (vc_cons[currcons].vc_translate)

132 #define video_mem_start (vc_cons[currcons].vc_video_mem_start)  // ʹ���Դ����ʼλ�á�

133 #define video_mem_end   (vc_cons[currcons].vc_video_mem_end)    // ʹ���Դ��ĩ��λ�á�

134 #define def_attr        (vc_cons[currcons].vc_def_attr)

135 #define video_erase_char  (vc_cons[currcons].vc_video_erase_char)      

136 #define iscolor         (vc_cons[currcons].vc_iscolor)

137

138 int blankinterval = 0;               // �趨����Ļ�������ʱ�䡣

139 int blankcount = 0;                  // ����ʱ�������

140

141 static void sysbeep(void);           // ϵͳ����������

142

143 /*

144  * this is what the terminal answers to a ESC-Z or csi0c

145  * query (= vt100 response).

146  */

    /*

     * �������ն˻�ӦESC-Z��csi0c�����Ӧ��=vt100��Ӧ����

     */

    // csi - ��������������(Control Sequence Introducer)��

    // ����ͨ�����Ͳ��������������0���豸���ԣ�DA���������У� 'ESC [c' �� 'ESC [0c' ��

    // Ҫ���ն�Ӧ��һ���豸���Կ������У�ESC Z�����������ͬ�����ն�����������������Ӧ

    // �����������У��� 'ESC [?1;2c' ����ʾ�ն��Ǿ��и߼���Ƶ���ܵ�VT100�����նˡ�

147 #define RESPONSE "\033[?1;2c"

148

    // ����ʹ�õ��ַ����������ϰ벿��ʱ��ͨ7����ASCII���룬��US�ַ������°벿�ֶ�Ӧ

    // VT100�ն��豸�е������ַ�������ʾͼ���������ַ�����

149 static char * translations[] = {

150 /* normal 7-bit ascii */

151         " !\"#$%&'()*+,-./0123456789:;<=>?"

152         "@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_"

153         "`abcdefghijklmnopqrstuvwxyz{|}~ ",

154 /* vt100 graphics */

155         " !\"#$%&'()*+,-./0123456789:;<=>?"

156         "@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^ "

157         "\004\261\007\007\007\007\370\361\007\007\275\267\326\323\327\304"

158         "\304\304\304\304\307\266\320\322\272\363\362\343\\007\234\007 "

159 };

160

161 #define NORM_TRANS (translations[0])

162 #define GRAF_TRANS (translations[1])

163

    //// ���ٹ�굱ǰλ�á�

    // ������currcons - ��ǰ�����ն˺ţ�new_x - ��������кţ�new_y - ��������кš�

    // ���µ�ǰ���λ�ñ��� x,y���������������ʾ�ڴ��еĶ�Ӧλ�� pos���ú��������ȼ��

    // ��������Ч�ԡ���������Ĺ���кų�����ʾ��������������߹���кŲ�������ʾ�����

    // ���������˳�������͸��µ�ǰ���������¹��λ�ö�Ӧ����ʾ�ڴ���λ��pos��

    // ע�⣬�����е����б���ʵ������vc_cons[currcons]�ṹ�е���Ӧ�ֶΡ����º�����ͬ��

164 /* NOTE! gotoxy thinks x==video_num_columns is ok */

    /* ע�⣡gotoxy������Ϊ x==video_num_columns ʱ����ȷ�� */

165 static inline void gotoxy(int currcons, int new_x,unsigned int new_y)

166 {

167         if (new_x > video_num_columns || new_y >= video_num_lines)

168                 return;

169         x = new_x;

170         y = new_y;

171         pos = origin + y*video_size_row + (x<<1);   // 1����2���ֽڱ�ʾ������x<<1��

172 }

173

    //// ���ù�����ʼ��ʾ�ڴ��ַ��

    // �ٴ����ѣ������б��������϶��� vc_cons[currcons] �ṹ�е���Ӧ�ֶΡ�

174 static inline void set_origin(int currcons)

175 {

    // �����ж���ʾ�����͡� ���� EGA/VGA �������ǿ���ָ�������з�Χ�����򣩽��й���������

    // ��MDA��ɫ��ʾ��ֻ�ܽ��������������������ֻ�� EGA/VGA ������Ҫ���ù�����ʼ����ʾ

    // �ڴ��ַ����ʼ���� origin ��Ӧ���У�������ʾ����������� EGA/VGA ��ɫģʽ��Ҳ����

    // EGA/VGA��ɫģʽ����ô��ֱ�ӷ��ء����⣬����ֻ��ǰ̨����̨���в�������˵�ǰ����̨

    // currcons������ǰ̨����̨ʱ�����Dz���Ҫ�����������ʼ�ж�Ӧ���ڴ����λ�á�

176         if (video_type != VIDEO_TYPE_EGAC && video_type != VIDEO_TYPE_EGAM)

177                 return;

178         if (currcons != fg_console)

179                 return;

    // Ȼ������ʾ�Ĵ���ѡ��˿�video_port_reg���12����ѡ����ʾ�������ݼĴ���r12������

    // д�������ʼ��ַ���ֽڡ����������ƶ�9λ��ʵ���ϱ�ʾ�����ƶ�8λ�ٳ���2����Ļ��1

    // ���ַ���2�ֽڱ�ʾ������ѡ����ʾ�������ݼĴ���r13��Ȼ��д�������ʼ��ַ���ֽڡ���

    // ���ƶ�1λ��ʾ����2��ͬ��������Ļ��1���ַ���2�ֽڱ�ʾ�����ֵ�����Ĭ����ʾ�ڴ�

    // ��ʼλ��video_mem_base���в������������ EGA/VGA ��ɫģʽ��viedo_mem_base = ����

    // �ڴ��ַ0xb8000��

180         cli();

181         outb_p(12, video_port_reg);    // ѡ�����ݼĴ���r12�����������ʼλ�ø��ֽڡ�

182         outb_p(0xff&((origin-video_mem_base)>>9), video_port_val);

183         outb_p(13, video_port_reg);    // ѡ�����ݼĴ���r13�����������ʼλ�õ��ֽڡ�

184         outb_p(0xff&((origin-video_mem_base)>>1), video_port_val);

185         sti();

186 }

187

    //// ���Ͼ���һ�С�

    // ����Ļ�������������ƶ�һ�У�������Ļ��������׳��ֵ����������ӿո��ַ�����������

    // �������1�С��μ������б���˵����

188 static void scrup(int currcons)

189 {

    // �����������������2�С�������������кŴ��ڵ���������кţ���������й��в���

    // �����������⣬����EGA/VGA�������ǿ���ָ�������з�Χ�����򣩽��й�����������MDA��

    // ɫ��ʾ��ֻ�ܽ������������������ú�����EGA��MDA��ʾ���ͽ��зֱ����������ʾ����

    // �� EGA���򻹷�Ϊ���������ƶ��������ڴ����ƶ����������ȴ�����ʾ����EGA/VGA��ʾ����

    // �������

190         if (bottom<=top)

191                 return;

192         if (video_type == VIDEO_TYPE_EGAC || video_type == VIDEO_TYPE_EGAM)

193         {

    // ����ƶ���ʼ��top=0���ƶ������ bottom = video_num_lines = 25�����ʾ������������

    // �ƶ������ǰ�������Ļ�������ϽǶ�Ӧ����ʼ�ڴ�λ��origin ����Ϊ������һ�ж�Ӧ���ڴ�

    // λ�ã�ͬʱҲ���ٵ�����ǰ����Ӧ���ڴ�λ���Լ���Ļĩ��ĩ���ַ�ָ��scr_end��λ�á�

    // ��������Ļ�����ڴ���ʼλ��ֵoriginд����ʾ�������С�

194                 if (!top && bottom == video_num_lines) {

195                         origin += video_size_row;

196                         pos += video_size_row;

197                         scr_end += video_size_row;

    // �����Ļ����ĩ������Ӧ����ʾ�ڴ�ָ��scr_end ������ʵ����ʾ�ڴ�ĩ�ˣ�����Ļ����

    // ����һ�����������ж�Ӧ���ڴ������ƶ�����ʾ�ڴ����ʼλ��video_mem_start��������

    // �������������ƶ����ֵ�����������ո��ַ���Ȼ�������Ļ�ڴ������ƶ�������������

    // ������ǰ��Ļ��Ӧ�ڴ����ʼָ�롢���λ��ָ�����Ļĩ�˶�Ӧ�ڴ�ָ��scr_end��

    // ���Ƕ����������Ƚ�����Ļ�ַ����� - 1���ж�Ӧ���ڴ������ƶ�����ʾ�ڴ���ʼλ��

    // video_mem_start����Ȼ���������ڴ�λ�ô�����һ�пո񣨲������ַ����ݡ�

    // %0 -eax(�����ַ�+����)��%1 -ecx��(��Ļ�ַ�����-1)����Ӧ���ַ���/2���Գ����ƶ�����

    // %2 -edi(��ʾ�ڴ���ʼλ��video_mem_start)��%3 -esi(��Ļ�����ڴ���ʼλ��origin)��

    // �ƶ�����[edi]��[esi]���ƶ�ecx�����֡�

198                         if (scr_end > video_mem_end) {

199                                 __asm__("cld\n\t"       // �巽��λ��

200                                         "rep\n\t"       // �ظ�����������ǰ��Ļ�ڴ�

201                                         "movsl\n\t"     // �����ƶ�����ʾ�ڴ���ʼ����

202                                         "movl _video_num_columns,%1\n\t"

203                                         "rep\n\t"       // ������������ո��ַ���

204                                         "stosw"

205                                         ::"a" (video_erase_char),

206                                         "c" ((video_num_lines-1)*video_num_columns>>1),

207                                         "D" (video_mem_start),

208                                         "S" (origin)

209                                         :"cx","di","si");

210                                 scr_end -= origin-video_mem_start;

211                                 pos -= origin-video_mem_start;

212                                 origin = video_mem_start;

    // ������������Ļĩ�˶�Ӧ���ڴ�ָ��scr_end û�г�����ʾ�ڴ��ĩ�� video_mem_end��

    // ��ֻ������������������ַ����ո��ַ�����

    // %0 -eax(�����ַ�+����)��%1 -ecx(��Ļ����)��%2 - edi�����1�п�ʼ����Ӧ�ڴ�λ�ã���

213                         } else {

214                                 __asm__("cld\n\t"

215                                         "rep\n\t"       // �ظ����������³�������

216                                         "stosw"         // ��������ַ�(�ո��ַ�)��

217                                         ::"a" (video_erase_char),

218                                         "c" (video_num_columns),

219                                         "D" (scr_end-video_size_row)

220                                         :"cx","di");

221                         }

    // Ȼ�������Ļ���������ڴ���ʼλ��ֵoriginд����ʾ�������С�

222                         set_origin(currcons);

    // �����ʾ���������ƶ�������ʾ��ָ����top��ʼ��bottom�����е������������ƶ�1�У�

    // ָ����top��ɾ������ʱֱ�ӽ���Ļ��ָ����top����Ļĩ�������ж�Ӧ����ʾ�ڴ�������

    // ���ƶ�1�У������������³��ֵ�������������ַ���

    // %0 - eax(�����ַ�+����)��%1 - ecx(top����1�п�ʼ��bottom������Ӧ���ڴ泤����)��

    // %2 - edi(top���������ڴ�λ��)��%3 - esi(top+1���������ڴ�λ��)��

223                 } else {

224                         __asm__("cld\n\t"

225                                 "rep\n\t"        // ѭ����������top+1��bottom��

226                                 "movsl\n\t"      // ����Ӧ���ڴ���Ƶ�top�п�ʼ����

227                                 "movl _video_num_columns,%%ecx\n\t"

228                                 "rep\n\t"        // ����������������ַ���

229                                 "stosw"

230                                 ::"a" (video_erase_char),

231                                 "c" ((bottom-top-1)*video_num_columns>>1),

232                                 "D" (origin+video_size_row*top),

233                                 "S" (origin+video_size_row*(top+1))

234                                 :"cx","di","si");

235                 }

236         }

    // �����ʾ���Ͳ���EGA������MDA ������ִ�������ƶ���������ΪMDA��ʾ���ƿ�ֻ��������

    // �������һ��Զ�����������ʾ��Χ������������Զ�����ָ�룬�������ﲻ����Ļ���ݶ�Ӧ��

    // �泬����ʾ�ڴ�������������������������EGA�������ƶ������ȫһ����

237         else            /* Not EGA/VGA */

238         {

239                 __asm__("cld\n\t"

240                         "rep\n\t"

241                         "movsl\n\t"

242                         "movl _video_num_columns,%%ecx\n\t"

243                         "rep\n\t"

244                         "stosw"

245                         ::"a" (video_erase_char),

246                         "c" ((bottom-top-1)*video_num_columns>>1),

247                         "D" (origin+video_size_row*top),

248                         "S" (origin+video_size_row*(top+1))

249                         :"cx","di","si");

250         }

251 }

252

    //// ���¾���һ�С�

    // ����Ļ�������������ƶ�һ�У���Ӧ��Ļ�����������������ƶ�1�С������ƶ���ʼ�е���

    // ������һ���С��μ������б���˵�������������� scrup()���ƣ�ֻ��Ϊ�����ƶ���ʾ�ڴ�

    // ����ʱ����������ݸ��ǵ����⣬���Ʋ�������������еģ����ȴ���Ļ������2�е����

    // һ���ַ���ʼ���Ƶ����һ�У��ٽ�������3�и��Ƶ�������2�еȵȡ���Ϊ��ʱ��EGA/

    // VGA��ʾ���ͺ�MDA���͵Ĵ���������ȫһ�������Ըú���ʵ����û�б�Ҫд������ͬ�Ĵ�

    // �롣������if��else�����еIJ�����ȫһ����

253 static void scrdown(int currcons)

254 {

    // ͬ���������������������2�С�������������кŴ��ڵ���������кţ���������й�

    // �в��������������⣬����EGA/VGA�������ǿ���ָ�������з�Χ�����򣩽��й�����������

    // MDA��ɫ��ʾ��ֻ�ܽ��������������������ڴ��������ƶ�����ƶ�����ǰ����̨ռ����ʾ��

    // ���ڴ����ʼλ�ã���˲��ᷢ����Ļ����ĩ������Ӧ����ʾ�ڴ�ָ��scr_end����ʵ����ʾ

    // �ڴ�ĩ�˵��������������ֻ��Ҫ������ͨ���ڴ������ƶ������

255         if (bottom <= top)

256                 return;

257         if (video_type == VIDEO_TYPE_EGAC || video_type == VIDEO_TYPE_EGAM)

258         {

    // %0 - eax(�����ַ�+����)��%1 - ecx(top�е� bottom-1 �е���������Ӧ���ڴ泤����)��

    // %2 - edi(�������½����һ������λ��)��%3 - esi(���ڵ�����2�����һ������λ��)��

    // �ƶ�����[esi]��[edi]���ƶ�ecx�����֡�

259                 __asm__("std\n\t"            // �÷���λ����

260                         "rep\n\t"            // �ظ������������ƶ���top�е�

261                         "movsl\n\t"          // bottom-1�ж�Ӧ���ڴ����ݡ�

262                         "addl $2,%%edi\n\t"  /* %edi has been decremented by 4 */

                                                 /* %edi�Ѽ�4����Ҳ�Ƿ���������ַ�*/

263                         "movl _video_num_columns,%%ecx\n\t"

264                         "rep\n\t"            // �������ַ������Ϸ������С�

265                         "stosw"

266                         ::"a" (video_erase_char),

267                         "c" ((bottom-top-1)*video_num_columns>>1),

268                         "D" (origin+video_size_row*bottom-4),

269                         "S" (origin+video_size_row*(bottom-1)-4)

270                         :"ax","cx","di","si");

271         }

    // �������EGA��ʾ���ͣ���ִ�����²�������������ȫһ������

272         else            /* Not EGA/VGA */

273         {

274                 __asm__("std\n\t"

275                         "rep\n\t"

276                         "movsl\n\t"

277                         "addl $2,%%edi\n\t"     /* %edi has been decremented by 4 */

278                         "movl _video_num_columns,%%ecx\n\t"

279                         "rep\n\t"

280                         "stosw"

281                         ::"a" (video_erase_char),

282                         "c" ((bottom-top-1)*video_num_columns>>1),

283                         "D" (origin+video_size_row*bottom-4),

284                         "S" (origin+video_size_row*(bottom-1)-4)

285                         :"ax","cx","di","si");

286         }

287 }

288

    //// �����ͬ��λ������һ�С�

    // ������û�д������һ���ϣ���ֱ���޸Ĺ�굱ǰ�б���y++������������Ӧ��ʾ�ڴ�

    // λ��pos������һ���ַ�����Ӧ���ڴ泤�ȣ����������Ҫ����Ļ������������һ�С�

    // ��������lf��line feed ���У���ָ���������ַ�LF��

289 static void lf(int currcons)

290 {

291         if (y+1<bottom) {

292                 y++;

293                 pos += video_size_row;        // ������Ļһ��ռ���ڴ���ֽ�����

294                 return;

295         }

296         scrup(currcons);                      // ����Ļ������������һ�С�

297 }

298

    //// �����ͬ������һ�С�

    // �����겻����Ļ��һ���ϣ���ֱ���޸Ĺ�굱ǰ�б���y--������������Ӧ��ʾ�ڴ�λ��

    // pos����ȥ��Ļ��һ���ַ�����Ӧ���ڴ泤���ֽ�����������Ҫ����Ļ������������һ�С�

    // ��������ri��reverse index ������������ָ�����ַ�RI��ת�����С�ESC M����

299 static void ri(int currcons)

300 {

301         if (y>top) {

302                 y--;

303                 pos -= video_size_row;        // ��ȥ��Ļһ��ռ���ڴ���ֽ�����

304                 return;

305         }

306         scrdown(currcons);                    // ����Ļ������������һ�С�

307 }

308

    // ���ص���1�У�0�У���

    // ��������Ӧ�ڴ�λ��pos����������к�*2 ����0�е���������ж�Ӧ���ڴ��ֽڳ��ȡ�

    // ��������cr��carriage return �س���ָ�������Ŀ����ַ��ǻس��ַ���

309 static void cr(int currcons)

310 {

311         pos -= x<<1;                          // ��ȥ0�е���괦ռ�õ��ڴ��ֽ�����

312         x=0;

313 }

314

    // �������ǰһ�ַ����ÿո��������del - delete ɾ������

    // ������û�д���0�У��򽫹���Ӧ�ڴ�λ��pos����2�ֽڣ���Ӧ��Ļ��һ���ַ�����

    // Ȼ�󽫵�ǰ��������ֵ��1�������������λ�ô��ַ�������

315 static void del(int currcons)

316 {

317         if (x) {

318                 pos -= 2;

319                 x--;

320                 *(unsigned short *)pos = video_erase_char;

321         }

322 }

323

    //// ɾ����Ļ������λ����صIJ��֡�

    // ANSI�������У�'ESC [ Ps J'��Ps =0 -ɾ����괦����Ļ�׶ˣ�1 -ɾ����Ļ��ʼ����괦��

    // 2 - ����ɾ����������������ָ���Ŀ������о������ֵ��ִ������λ����ص�ɾ��������

    // �����ڲ����ַ�����ʱ���λ�ò��䡣

    // ��������csi_J ��CSI - Control Sequence Introducer�����������������룩ָ���Կ���

    // ���С�CSI Ps J�����д�����

    // ������vpar - ��Ӧ�������������Ps��ֵ��

324 static void csi_J(int currcons, int vpar)

325 {

326         long count __asm__("cx");             // ��Ϊ�Ĵ���������

327         long start __asm__("di");

328

    // ���ȸ�����������ֱ�������Ҫɾ�����ַ�����ɾ����ʼ����ʾ�ڴ�λ�á�

329         switch (vpar) {

330                 case 0: /* erase from cursor to end of display */

331                         count = (scr_end-pos)>>1;   /* ������굽��Ļ�׶������ַ� */

332                         start = pos;

333                         break;

334                 case 1: /* erase from start to cursor */

335                         count = (pos-origin)>>1;  /* ɾ������Ļ��ʼ����괦���ַ� */

336                         start = origin;

337                         break;

338                 case 2: /* erase whole display */     /* ɾ��������Ļ�ϵ������ַ� */

339                         count = video_num_columns * video_num_lines;

340                         start = origin;

341                         break;

342                 default:

343                         return;

344         }

    // Ȼ��ʹ�ò����ַ���д��ɾ���ַ��ĵط���

    // %0 -ecx(ɾ�����ַ���count)��%1 -edi(ɾ��������ʼ��ַ)��%2 -eax������IJ����ַ�����

345         __asm__("cld\n\t"

346                 "rep\n\t"

347                 "stosw\n\t"

348                 ::"c" (count),

349                 "D" (start),"a" (video_erase_char)

350                 :"cx","di");

351 }

352

    //// ɾ��һ��������λ����صIJ��֡�

    // ANSIת���ַ����У�'ESC [ Ps K'��Ps = 0 ɾ������β��1 �ӿ�ʼɾ����2 ���ж�ɾ������

    // ���������ݲ���������������еIJ��ֻ������ַ���������������Ļ�������ַ�����Ӱ����

    // ���ַ����������ַ����������ڲ����ַ�����ʱ���λ�ò��䡣

    // ������par - ��Ӧ�������������Ps��ֵ��

353 static void csi_K(int currcons, int vpar)

354 {

355         long count __asm__("cx");         // ���üĴ���������

356         long start __asm__("di");

357

    // ���ȸ�����������ֱ�������Ҫɾ�����ַ�����ɾ����ʼ����ʾ�ڴ�λ�á�

358         switch (vpar) {

359                 case 0: /* erase from cursor to end of line */

360                         if (x>=video_num_columns)     /* ɾ����굽��β�����ַ� */

361                                 return;

362                         count = video_num_columns-x;

363                         start = pos;

364                         break;

365                 case 1: /* erase from start of line to cursor */

366                         start = pos - (x<<1);           /* ɾ�����п�ʼ����괦 */

367                         count = (x<video_num_columns)?x:video_num_columns;

368                         break;

369                 case 2: /* erase whole line */             /* �������ַ�ȫɾ�� */

370                         start = pos - (x<<1);

371                         count = video_num_columns;

372                         break;

373                 default:

374                         return;

375         }

    // Ȼ��ʹ�ò����ַ���дɾ���ַ��ĵط���

    // %0 - ecx(ɾ���ַ���count)��%1 -edi(ɾ��������ʼ��ַ)��%2 -eax������IJ����ַ�����

376         __asm__("cld\n\t"

377                 "rep\n\t"

378                 "stosw\n\t"

379                 ::"c" (count),

380                 "D" (start),"a" (video_erase_char)

381                 :"cx","di");

382 }

383

    //// ������ʾ�ַ����ԡ�

    // ANSIת�����У�'ESC [ Ps;Ps m'��Ps = 0 - Ĭ�����ԣ�1 - ���岢������4 - �»��ߣ�

    // 5 - ��˸��7 - ���ԣ�22 - �Ǵ��壻24 - ���»��ߣ�25 - ����˸��27 - ���ԣ�

    // 30--38 - ����ǰ��ɫ�ʣ�39 - Ĭ��ǰ��ɫ��White����40--48 - ���ñ���ɫ�ʣ�

    // 49 - Ĭ�ϱ���ɫ��Black����

    // �ÿ������и��ݲ��������ַ���ʾ���ԡ��Ժ����з��͵��ն˵��ַ�����ʹ������ָ������

    // �ԣ�ֱ���ٴ�ִ�б������������������ַ���ʾ�����ԡ�

384 void csi_m(int currcons )

385 {

386         int i;

387

    // һ�����������п��Դ��ж����ͬ�����������洢������par[]�С�����͸��ݽ��յ��IJ���

    // ����npar��ѭ��������������Ps��

    // ���Ps = 0����ѵ�ǰ�������̨�����ʾ���ַ���������ΪĬ������def_attr����ʼ��ʱ

    // def_attr�ѱ����ó�0x07���ڵװ��֣���

    // ���Ps = 1����ѵ�ǰ�������̨�����ʾ���ַ���������Ϊ�����������ʾ�� ����Dz�ɫ

    // ��ʾ������ַ����Ի���0x08���ַ���������ʾ������ǵ�ɫ��ʾ�������ַ����»�����ʾ��

    // ���Ps = 4����Բ�ɫ�͵�ɫ��ʾ���в�ͬ�Ĵ���������ʱ���Dz�ɫ��ʾ��ʽ�������ַ���

    // �»�����ʾ������Dz�ɫ��ʾ����ô��ԭ��vc_bold_attr������-1ʱ�͸�λ�䱳��ɫ������

    // �Ļ��Ͱ�ǰ��ɫȡ������ȡ����ǰ��ɫ�뱳��ɫ��ͬ���Ͱ�ǰ��ɫ��1��ȡ��һ����ɫ��

388         for (i=0;i<=npar;i++)

389                 switch (par[i]) {

390                         case 0: attr=def_attr;break;  /* default */

391                         case 1: attr=(iscolor?attr|0x08:attr|0x0f);break;  /* bold */

392                         /*case 4: attr=attr|0x01;break;*/  /* underline */

393                         case 4: /* bold */

394                           if (!iscolor)

395                             attr |= 0x01;            // ��ɫ����»�����ʾ��

396                           else

397                           { /* check if forground == background */

398                             if (vc_cons[currcons].vc_bold_attr != -1)

399                               attr = (vc_cons[currcons].vc_bold_attr&0x0f)|(0xf0&(attr));

400                             else

401                             { short newattr = (attr&0xf0)|(0xf&(~attr));

402                               attr = ((newattr&0xf)==((attr>>4)&0xf)?

403                                 (attr&0xf0)|(((attr&0xf)+1)%0xf):

404                                 newattr);

405                             }   

406                           }

407                           break;

    // ���Ps = 5����ѵ�ǰ�������̨�����ʾ���ַ�����Ϊ��˸�����������ֽڱ���λ7��1��

    // ���Ps = 7����ѵ�ǰ�������̨�����ʾ���ַ�����Ϊ���ԣ�����ǰ���ͱ���ɫ������

    // ���Ps = 22����ȡ������ַ��ĸ�������ʾ��ȡ��������ʾ����

    // ���Ps = 24������ڵ�ɫ��ʾ��ȡ������ַ����»�����ʾ�����ڲ�ɫ��ʾ����ȡ����ɫ��

    // ���Ps = 25����ȡ������ַ�����˸��ʾ��

    // ���Ps = 27����ȡ������ַ��ķ��ԡ�

    // ���Ps = 39����λ����ַ���ǰ��ɫΪĬ��ǰ��ɫ����ɫ����

    // ���Ps = 49����λ����ַ��ı���ɫΪĬ�ϱ���ɫ����ɫ����

408                         case 5: attr=attr|0x80;break;  /* blinking */

409                         case 7: attr=(attr<<4)|(attr>>4);break;  /* negative */

410                         case 22: attr=attr&0xf7;break; /* not bold */

411                         case 24: attr=attr&0xfe;break;  /* not underline */

412                         case 25: attr=attr&0x7f;break;  /* not blinking */

413                         case 27: attr=def_attr;break; /* positive image */

414                         case 39: attr=(attr & 0xf0)|(def_attr & 0x0f); break;

415                         case 49: attr=(attr & 0x0f)|(def_attr & 0xf0); break;

    // ��Ps��par[i]��Ϊ����ֵʱ����������ָ����ǰ��ɫ�򱳾�ɫ�����Ps = 30..37����������

    // ǰ��ɫ�����Ps=40..47���������ñ���ɫ���й���ɫֵ��μ������˵����

416                         default:

417                           if (!can_do_colour)

418                             break;

419                           iscolor = 1;

420                           if ((par[i]>=30) && (par[i]<=38))        // ����ǰ��ɫ��

421                             attr = (attr & 0xf0) | (par[i]-30);

422                           else  /* Background color */

423                             if ((par[i]>=40) && (par[i]<=48))      // ���ñ���ɫ��

424                               attr = (attr & 0x0f) | ((par[i]-40)<<4);

425                             else

426                                 break;

427                 }

428 }

429

    //// ������ʾ��ꡣ

    // ���ݹ���Ӧ��ʾ�ڴ�λ��pos��������ʾ������������ʾλ�á�

430 static inline void set_cursor(int currcons)

431 {

    // ��Ȼ������Ҫ������ʾ��꣬˵���м��̲����������Ҫ�ָ����к�����������ʱ����ֵ��

    // ���⣬��ʾ���Ŀ���̨������ǰ̨����̨���������ǰ������̨��currcons����ǰ̨��

    // ��̨�����̷��ء�

432         blankcount = blankinterval;           // ��λ���������ļ���ֵ��

433         if (currcons != fg_console)

434                 return;

    // Ȼ��ʹ�������Ĵ����˿�ѡ����ʾ�������ݼĴ���r14����굱ǰ��ʾλ�ø��ֽڣ�������

    // д���굱ǰλ�ø��ֽڣ������ƶ�9λ��ʾ���ֽ��Ƶ����ֽ��ٳ���2�����������Ĭ��

    // ��ʾ�ڴ�����ġ���ʹ�������Ĵ���ѡ��r15��������굱ǰλ�õ��ֽ�д�����С�

435         cli();

436         outb_p(14, video_port_reg);

437         outb_p(0xff&((pos-video_mem_base)>>9), video_port_val);

438         outb_p(15, video_port_reg);

439         outb_p(0xff&((pos-video_mem_base)>>1), video_port_val);

440         sti();

441 }

442

    // ���ع�ꡣ

    // �ѹ�����õ���ǰ�������̨���ڵ�ĩ�ˣ������ع������á�

443 static inline void hide_cursor(int currcons)

444 {

    // ����ʹ�������Ĵ����˿�ѡ����ʾ�������ݼĴ���r14����굱ǰ��ʾλ�ø��ֽڣ���Ȼ��

    // д���굱ǰλ�ø��ֽڣ������ƶ�9λ��ʾ���ֽ��Ƶ����ֽ��ٳ���2�����������Ĭ��

    // ��ʾ�ڴ�����ġ���ʹ�������Ĵ���ѡ��r15��������굱ǰλ�õ��ֽ�д�����С�

445         outb_p(14, video_port_reg);

446         outb_p(0xff&((scr_end-video_mem_base)>>9), video_port_val);

447         outb_p(15, video_port_reg);

448         outb_p(0xff&((scr_end-video_mem_base)>>1), video_port_val);

449 }

450

    //// ���Ͷ�VT100����Ӧ���С�

    // ��Ϊ��Ӧ���������ն������������豸���ԣ�DA��������ͨ�����Ͳ��������������0��DA

    // �������У�'ESC [ 0c' �� 'ESC Z'��Ҫ���ն˷���һ���豸���ԣ�DA���������У��ն���

    // ��85���϶����Ӧ�����У��� 'ESC [?1;2c'������Ӧ���������У������и����������ն�

    // �Ǿ��и߼���Ƶ���ܵ�VT100�����նˡ����������ǽ�Ӧ�����з������������У���ʹ��

    // copy_to_cooked()������������븨�������С�

451 static void respond(int currcons, struct tty_struct * tty)

452 {

453         char * p = RESPONSE;              // �����ڵ�147���ϡ�

454

455         cli();

456         while (*p) {                      // ��Ӧ�����з�������С�

457                 PUTCH(*p,tty->read_q);    // ���ַ����롣include/linux/tty.h��46�С�

458                 p++;

459         }

460         sti();                            // ת���ɹ淶ģʽ�����븨�������У���

461         copy_to_cooked(tty);              // tty_io.c��120�С�

462 }

463

    //// �ڹ�괦����һ�ո��ַ���

    // �ѹ�꿪ʼ���������ַ�����һ�񣬲��������ַ������ڹ�����ڴ���

464 static void insert_char(int currcons)

465 {

466         int i=x;

467         unsigned short tmp, old = video_erase_char;     // �����ַ��������ԣ���

468         unsigned short * p = (unsigned short *) pos;    // ����Ӧ�ڴ�λ�á�

469

470         while (i++<video_num_columns) {

471                 tmp=*p;

472                 *p=old;

473                 old=tmp;

474                 p++;

475         }

476 }

477

    //// �ڹ�괦����һ�С�

    // ����Ļ���ڴӹ�������е����ڵ׵��������¾���һ�С���꽫�����µĿ����ϡ�

478 static void insert_line(int currcons)

479 {

480         int oldtop,oldbottom;

481

    // ���ȱ�����Ļ���ھ�����ʼ��top�������bottomֵ��Ȼ��ӹ������������Ļ��������

    // ����һ�С����ָ���Ļ���ھ�����ʼ��top�������bottom��ԭ��ֵ��

482         oldtop=top;

483         oldbottom=bottom;

484         top=y;                             // ������Ļ������ʼ�кͽ����С�

485         bottom = video_num_lines;

486         scrdown(currcons);                 // �ӹ�꿪ʼ������Ļ�������¹���һ�С�

487         top=oldtop;

488         bottom=oldbottom;

489 }

490

    //// ɾ��һ���ַ���

    // ɾ����괦��һ���ַ�������ұߵ������ַ�����һ��

491 static void delete_char(int currcons)

492 {

493         int i;

494         unsigned short * p = (unsigned short *) pos;

495

    // ������ĵ�ǰ��λ��x������Ļ�����У��򷵻ء�����ӹ����һ���ַ���ʼ����ĩ����

    // �ַ�����һ��Ȼ�������һ���ַ�����������ַ���

496         if (x>=video_num_columns)

497                 return;

498         i = x;

499         while (++i < video_num_columns) {        // ����������ַ�����1��

500                 *p = *(p+1);

501                 p++;

502         }

503         *p = video_erase_char;                   // �����������ַ���

504 }

505

    //// ɾ����������С�

    // ɾ��������ڵ�һ�У����ӹ�������п�ʼ��Ļ�����Ͼ�һ�С�

506 static void delete_line(int currcons)

507 {

508         int oldtop,oldbottom;

509

    // ���ȱ�����Ļ������ʼ��top�������bottomֵ��Ȼ��ӹ������������Ļ�������Ϲ���

    // һ�С����ָ���Ļ������ʼ��top�������bottom��ԭ��ֵ��

510         oldtop=top;

511         oldbottom=bottom;

512         top=y;                                  // ������Ļ������ʼ�к�����С�

513         bottom = video_num_lines;

514         scrup(currcons);                        // �ӹ�꿪ʼ������Ļ�������Ϲ���һ�С�

515         top=oldtop;

516         bottom=oldbottom;

517 }

518

    //// �ڹ�괦����nr���ַ���

    // ANSIת���ַ����У�'ESC [ Pn @'���ڵ�ǰ��괦����1�������ո��ַ���Pn�Dz������

    // ������Ĭ����1����꽫��Ȼ���ڵ�1������Ŀո��ַ������ڹ�����ұ߽���ַ������ơ�

    // �����ұ߽���ַ�������ʧ��

    // ���� nr = ת���ַ������еIJ���Pn��

519 static void csi_at(int currcons, unsigned int nr)

520 {

    // ���������ַ�������һ���ַ��������Ϊһ���ַ������������ַ���nrΪ0�������1��

    // �ַ���Ȼ��ѭ������ָ�����ո��ַ���

521         if (nr > video_num_columns)

522                 nr = video_num_columns;

523         else if (!nr)

524                 nr = 1;

525         while (nr--)

526                 insert_char(currcons);

527 }

528

    //// �ڹ��λ�ô�����nr�С�

    // ANSIת���ַ����У�'ESC [ Pn L'���ÿ��������ڹ�괦����1�л���п��С�������ɺ�

    // ���λ�ò��䡣�����б�����ʱ��������¹��������ڵ��������ƶ�����������ʾҳ���о�

    // ��ʧ��

    // ���� nr = ת���ַ������еIJ���Pn��

529 static void csi_L(int currcons, unsigned int nr)

530 {

    // ������������������Ļ������������Ϊ��Ļ��ʾ����������������nrΪ0�������1�С�

    // Ȼ��ѭ������ָ������nr�Ŀ��С�

531         if (nr > video_num_lines)

532                 nr = video_num_lines;

533         else if (!nr)

534                 nr = 1;

535         while (nr--)

536                 insert_line(currcons);

537 }

538

    //// ɾ����괦��nr���ַ���

    // ANSIת�����У�'ESC [ Pn P'���ÿ������дӹ�괦ɾ��Pn���ַ�����һ���ַ���ɾ��ʱ��

    // ����������ַ������ơ�������ұ߽紦����һ�����ַ���������Ӧ�������һ�������ַ�

    // ��ͬ�����������˼򻯴�������ʹ���ַ���Ĭ�����ԣ��ڵװ��ֿո�0x0720�������ÿ��ַ���

    // ���� nr = ת���ַ������еIJ���Pn��

539 static void csi_P(int currcons, unsigned int nr)

540 {

    // ���ɾ�����ַ�������һ���ַ��������Ϊһ���ַ�������ɾ���ַ���nrΪ0����ɾ��1��

    // �ַ���Ȼ��ѭ��ɾ����괦ָ���ַ���nr��

541         if (nr > video_num_columns)

542                 nr = video_num_columns;

543         else if (!nr)

544                 nr = 1;

545         while (nr--)

546                 delete_char(currcons);

547 }

548

    //// ɾ����괦��nr�С�

    // ANSIת�����У�'ESC [ Pn M'���ÿ��������ڹ��������ڣ��ӹ�������п�ʼɾ��1�л��

    // �С����б�ɾ��ʱ�����������ڵı�ɾ�����µ��л������ƶ������һ������������1���С�

    // ��Pn������ʾҳ��ʣ�������������н�ɾ����Щʣ���У����Թ��������ⲻ�����á�

    // ���� nr = ת���ַ������еIJ���Pn��

549 static void csi_M(int currcons, unsigned int nr)

550 {

    // ���ɾ��������������Ļ������������Ϊ��Ļ��ʾ����������ɾ��������nrΪ0����ɾ��

    // 1�С�Ȼ��ѭ��ɾ��ָ������nr��

551         if (nr > video_num_lines)

552                 nr = video_num_lines;

553         else if (!nr)

554                 nr=1;

555         while (nr--)

556                 delete_line(currcons);

557 }

558

    //// ���浱ǰ���λ�á�

559 static void save_cur(int currcons)

560 {

561         saved_x=x;

562         saved_y=y;

563 }

564

    //// �ָ�����Ĺ��λ�á�

565 static void restore_cur(int currcons)

566 {

567         gotoxy(currcons,saved_x, saved_y);

568 }

569

570

    // ���ö�ٶ�����������con_write()�����д���ת�����л�������еĽ�����ESnormal�dz�

    // ʼ����״̬��Ҳ��ת���������д������ʱ��״̬��

    // ESnormal -  ��ʾ���ڳ�ʼ����״̬����ʱ�����յ�������ͨ��ʾ�ַ�������ַ�ֱ����ʾ

    //             ����Ļ�ϣ������յ����ǿ����ַ�������س��ַ�������Թ��λ�ý������á�

    //             ���մ�����һ��ת���������У�����Ҳ�᷵�ص���״̬��

    // ESesc    -  ��ʾ���յ�ת�����������ַ�ESC��0x1b = 033 = 27��������ڴ�״̬�½���

    //             ��һ��'['�ַ�����˵��ת�����������룬������ת��ESsquareȥ����������

    //             �Ͱѽ��յ����ַ���Ϊת������������������ѡ���ַ���ת������'ESC (' ��

    //             'ESC )'������ʹ�õ�����״̬ESsetgraph�������������豸�����ַ�������

    //             'ESC P'������ʹ�õ�����״̬ESsetterm��������

    // ESsquare -  ��ʾ�Ѿ����յ�һ���������������루'ESC ['������ʾ���յ�����һ��������

    //             �С����DZ�״ִ̬�в�������par[]�����ʼ�������������ʱ���յ�������һ

    //             ��'['�ַ������ʾ�յ���'ESC [['���С��������Ǽ��̹��ܼ����������У���

    //             ����ת�� Esfunckey ȥ����������������Ҫ׼�����տ������еIJ�����������

    //             ״̬Esgetpars��ֱ�ӽ����״̬ȥ���ղ��������еIJ����ַ���

    // ESgetpars - ��״̬��ʾ���Ǵ�ʱҪ���տ������еIJ���ֵ��������ʮ��������ʾ�����ǰ�

    //             ���յ��������ַ�ת������ֵ�����浽par[]�����С�����յ�һ���ֺ� ';'��

    //             ����ά���ڱ�״̬�����ѽ��յ��IJ���ֵ����������par[]��һ���С�������

    //             �����ַ���ֺţ�˵����ȡ�����в�������ô��ת�Ƶ�״̬ESgotparsȥ������

    // ESgotpars - ��ʾ�����Ѿ����յ�һ�������Ŀ������С���ʱ���ǿ��Ը��ݱ�״̬���յ��Ľ�

    //             β�ַ�����Ӧ�������н��д����������ڴ���֮ǰ�����������ESsquare ״̬

    //             �յ��� '?'��˵������������ն��豸˽�����С����ں˲���֧�ֶ��������е�

    //             ��������������ֱ�ӻָ��� ESnormal ״̬�������ȥִ����Ӧ�������С�����

    //             �д������Ͱ�״̬�ָ��� ESnormal��

    // ESfunckey - ��ʾ���ǽ��յ��˼����Ϲ��ܼ�������һ�����С����Dz�����ʾ�����ǻָ�����

    //             ��״̬ESnormal��

    // ESsetterm - ��ʾ�����豸�����ַ�������״̬��DCS������ʱ���յ��ַ� 'S'����ָ���ʼ

    //             ����ʾ�ַ����ԡ����յ����ַ���'L'��'l'��������ر�������ʾ��ʽ��

    // ESsetgraph -��ʾ�յ������ַ���ת������'ESC (' �� 'ESC )'�����Ƿֱ�����ָ��G0��G1

    //             ���õ��ַ�������ʱ���յ��ַ� '0'����ѡ��ͼ���ַ�����ΪG0��G1�����յ�

    //             ���ַ��� 'B'����ѡ����ͨASCII�ַ�����ΪG0��G1���ַ�����

571 enum { ESnormal, ESesc, ESsquare, ESgetpars, ESgotpars, ESfunckey,

572         ESsetterm, ESsetgraph };

573

    //// ����̨д������

    // ���ն˶�Ӧ��ttyд���������ȡ�ַ������ÿ���ַ����з��������ǿ����ַ���ת������

    // ���У�����й�궨λ���ַ�ɾ���ȵĿ��ƴ�����������ͨ�ַ���ֱ���ڹ�괦��ʾ��

    // ���� tty�ǵ�ǰ����̨ʹ�õ�tty�ṹָ�롣

574 void con_write(struct tty_struct * tty)

575 {

576         int nr;

577         char c;

578         int currcons;

579     

    // �ú������ȸ��ݵ�ǰ����̨ʹ�õ�tty��tty���е���λ��ȡ�ö�Ӧ�Ŀ���̨��currcons��

    // Ȼ��������CHARS()��Ŀǰttyд�����к��е��ַ���nr����ѭ��ȡ�����е�ÿ���ַ�����

    // ���������������ǰ����̨���ڽ��յ����̻���򷢳�����ͣ����簴��Ctrl-S��������

    // ֹͣ״̬����ô��������ֹͣ����д�����е��ַ����˳����������⣬���ȡ�����ǿ����ַ�

    // CAN��24���� SUB��26������ô������ת�����������ڼ��յ��ģ������в���ִ�ж�������

    // ֹ��ͬʱ��ʾ�����ַ���ע�⣬con_write()����ֻ����ȡ�����ַ���ʱд�����е�ǰ����

    // ���ַ������п�����һ�����б��ŵ�д�����ڼ��ȡ�ַ�������˱�����ǰһ���˳�ʱstate

    // �п��������ڴ���ת���������е�����״̬�ϡ�

580         currcons = tty - tty_table;

581         if ((currcons>=MAX_CONSOLES) || (currcons<0))

582                 panic("con_write: illegal tty");

583           

584         nr = CHARS(tty->write_q);               // ȡд�������ַ�������tty.h�ļ��С�

585         while (nr--) {

586                 if (tty->stopped)

587                         break;

588                 GETCH(tty->write_q,c);          // ȡ1�ַ���c�С�

589                 if (c == 24 || c == 26)         // �����ַ� CAN��SUB -  ȡ�����滻��

590                         state = ESnormal;

591                 switch(state) {

    // �����д������ȡ�����ַ�����ͨ��ʾ�ַ����룬��ֱ�Ӵӵ�ǰӳ���ַ�����ȡ����Ӧ����ʾ

    // �ַ������ŵ���ǰ�����������ʾ�ڴ�λ�ô�����ֱ����ʾ���ַ���Ȼ��ѹ��λ������һ��

    // �ַ�λ�á�����أ�����ַ����ǿ����ַ�Ҳ������չ�ַ�����(31<c<127)����ô������ǰ��

    // �괦����ĩ�˻�ĩ�����⣬�򽫹���Ƶ�����ͷ�С����������λ�ö�Ӧ���ڴ�ָ��pos��Ȼ

    // ���ַ�cд����ʾ�ڴ���pos���������������1�У�ͬʱҲ��pos��Ӧ���ƶ�2���ֽڡ�

592                         case ESnormal:

593                                 if (c>31 && c<127) {              // ����ͨ��ʾ�ַ���

594                                         if (x>=video_num_columns) {     // Ҫ���У�

595                                                 x -= video_num_columns;

596                                                 pos -= video_size_row;

597                                                 lf(currcons);

598                                         }

599                                         __asm__("movb %2,%%ah\n\t"      // д�ַ���

600                                                 "movw %%ax,%1\n\t"

601                                                 ::"a" (translate[c-32]),

602                                                 "m" (*(short *)pos),

603                                                 "m" (attr)

604                                                 :"ax");

605                                         pos += 2;

606                                         x++;

    // ����ַ�c��ת���ַ�ESC����ת��״̬state��ESesc��637�У���

607                                 } else if (c==27)             // ESC - ת������ַ���

608                                         state=ESesc;

    // ���c�ǻ��з�LF(10)����ֱ�Ʊ���VT(11)����ҳ��FF(12)�������ƶ�����1�С�

609                                 else if (c==10 || c==11 || c==12)

610                                         lf(currcons);

    // ���c�ǻس���CR(13)���򽫹���ƶ���ͷ�У�0�У���

611                                 else if (c==13)               // CR - �س���

612                                         cr(currcons);

    // ���c��DEL(127)���򽫹������ַ�����(�ÿո��ַ����)����������Ƶ�������λ�á�

613                                 else if (c==ERASE_CHAR(tty))

614                                         del(currcons);

    // ���c��BS(backspace,8)���򽫹������1�񣬲���Ӧ��������Ӧ�ڴ�λ��ָ��pos��

615                                 else if (c==8) {              // BS - ���ˡ�

616                                         if (x) {

617                                                 x--;

618                                                 pos -= 2;

619                                         }

    // ����ַ�c��ˮƽ�Ʊ���HT(9)���򽫹���Ƶ�8�ı������ϡ�����ʱ�������������Ļ���

    // �������򽫹���Ƶ���һ���ϡ�

620                                 } else if (c==9) {            // HT - ˮƽ�Ʊ���

621                                         c=8-(x&7);

622                                         x += c;

623                                         pos += c<<1;

624                                         if (x>video_num_columns) {

625                                                 x -= video_num_columns;

626                                                 pos -= video_size_row;

627                                                 lf(currcons);

628                                         }

629                                         c=9;

    // ����ַ�c�������BEL(7)������÷�����������������������

630                                 } else if (c==7)               // BEL - ���塣

631                                         sysbeep();

    // ���c�ǿ����ַ�SO��14����SI��15��������Ӧѡ���ַ���G1��G0��Ϊ��ʾ�ַ�����

632                                 else if (c == 14)              // SO - ������ʹ��G1��

633                                         translate = GRAF_TRANS;

634                                 else if (c == 15)              // SI - ������ʹ��G0��

635                                         translate = NORM_TRANS;

636                                 break;

    // �����ESnormal״̬�յ�ת���ַ�ESC(0x1b = 033 = 27)����ת����״̬��������״̬��C1

    // �п����ַ���ת���ַ����д������������Ĭ�ϵ�״̬����ESnormal��

637                         case ESesc:

638                                 state = ESnormal;

639                                 switch (c)

640                                 {

641                                   case '[':            // ESC [ - ��CSI���С�

642                                         state=ESsquare;

643                                         break;

644                                   case 'E':            // ESC E - �������1�л�0�С�

645                                         gotoxy(currcons,0,y+1);

646                                         break;

647                                   case 'M':            // ESC M - �������1�С�

648                                         ri(currcons);

649                                         break;

650                                   case 'D':            // ESC D - �������1�С�

651                                         lf(currcons);

652                                         break;

653                                   case 'Z':            // ESC Z - �豸���Բ�ѯ��

654                                         respond(currcons,tty);

655                                         break;

656                                   case '7':            // ESC 7 - ������λ�á�

657                                         save_cur(currcons);

658                                         break;

659                                   case '8':            // ESC 8 - �ָ�����Ĺ��ԭλ�á�

660                                         restore_cur(currcons);

661                                         break;

662                                   case '(':  case ')': // ESC (��ESC ) - ѡ���ַ�����

663                                         state = ESsetgraph;            

664                                         break;

665                                   case 'P':            // ESC P - �����ն˲�����

666                                         state = ESsetterm; 

667                                         break;

668                                   case '#':            // ESC # - �޸��������ԡ�

669                                         state = -1;

670                                         break;         

671                                   case 'c':            // ESC c - ��λ���ն˳�ʼ���á�

672                                         tty->termios = DEF_TERMIOS;

673                                         state = restate = ESnormal;

674                                         checkin = 0;

675                                         top = 0;

676                                         bottom = video_num_lines;

677                                         break;

678                                  /* case '>':   Numeric keypad */

679                                  /* case '=':   Appl. keypad */

680                                 }      

681                                 break;

    // �����״̬ESesc����ת���ַ�ESC��ʱ�յ��ַ�'['���������CSI�������У�����ת��״

    // ̬ESsequare�����������ȶ�ESCת�����б������������par[]���㣬��������nparָ��

    // ��������������ǿ�ʼ����ȡ����״̬ESgetpars��������յ����ַ�����'?'����ֱ��ת

    // ��״̬ESgetparsȥ�����������յ����ַ���'?'��˵������������ն��豸˽�����У�����

    // ����һ�������ַ�������ȥ����һ�ַ����ٵ�״̬ ESgetpars ȥ�������봦�������ʱ����

    // �����ַ�����'['����ô�����յ��˼��̹��ܼ����������У�����������һ״̬ΪESfunckey��

    // ����ֱ�ӽ���ESgetpars״̬����������

682                         case ESsquare:

683                                 for(npar=0;npar<NPAR;npar++)     // ��ʼ���������顣

684                                         par[npar]=0;

685                                 npar=0;

686                                 state=ESgetpars;

687                                 if (c =='['/* Function key */ // 'ESC [['�ǹ��ܼ���

688                                 { state=ESfunckey;

689                                   break;

690                                 } 

691                                 if (ques=(c=='?'))

692                                         break;

    // ��״̬��ʾ���Ǵ�ʱҪ���տ������еIJ���ֵ��������ʮ��������ʾ�����ǰѽ��յ���������

    // ��ת������ֵ�����浽par[]�����С�����յ�һ���ֺ� ';'������ά���ڱ�״̬�����ѽ�

    // �յ��IJ���ֵ����������par[]��һ���С������������ַ���ֺţ�˵����ȡ�����в�������

    // ô��ת�Ƶ�״̬ESgotparsȥ������

693                         case ESgetpars:

694                                 if (c==';' && npar<NPAR-1) {

695                                         npar++;

696                                         break;

697                                 } else if (c>='0' && c<='9') {

698                                         par[npar]=10*par[npar]+c-'0';

699                                         break;

700                                 } else state=ESgotpars;

    // ESgotpars״̬��ʾ�����Ѿ����յ�һ�������Ŀ������С���ʱ���ǿ��Ը��ݱ�״̬���յ���

    // ��β�ַ�����Ӧ�������н��д����������ڴ���֮ǰ�����������ESsquare ״̬�յ���'?'��

    // ˵������������ն��豸˽�����С����ں˲�֧�ֶ��������еĴ�������������ֱ�ӻָ���

    // ESnormal ״̬�������ȥִ����Ӧ�������С������д������Ͱ�״̬�ָ��� ESnormal��

701                         case ESgotpars:

702                                 state = ESnormal;

703                                 if (ques)

704                                 { ques =0;

705                                   break;

706                                 } 

707                                 switch(c) {

    // ���c���ַ�'G'��'`'����par[]�е�1�����������кš����кŲ�Ϊ�㣬�򽫹������1��

708                                         case 'G': case '`':  // CSI Pn G -���ˮƽ�ƶ���

709                                                 if (par[0]) par[0]--;

710                                                 gotoxy(currcons,par[0],y);

711                                                 break;

    // ���c��'A'�����1����������������Ƶ�������������Ϊ0������1�С�

712                                         case 'A':            // CSI Pn A - ������ơ�

713                                                 if (!par[0]) par[0]++;

714                                                 gotoxy(currcons,x,y-par[0]);

715                                                 break;

    // ���c��'B'��'e'�����1����������������Ƶ�������������Ϊ0������1�С�

716                                         case 'B': case 'e':  // CSI Pn B - ������ơ�

717                                                 if (!par[0]) par[0]++;

718                                                 gotoxy(currcons,x,y+par[0]);

719                                                 break;

    // ���c��'C'��'a'�����1����������������Ƶĸ�����������Ϊ0������1��

720                                         case 'C': case 'a':  // CSI Pn C - ������ơ�

721                                                 if (!par[0]) par[0]++;

722                                                 gotoxy(currcons,x+par[0],y);

723                                                 break;

    // ���c��'D'�����1����������������Ƶĸ�����������Ϊ0������1��

724                                         case 'D':            // CSI Pn D - ������ơ�

725                                                 if (!par[0]) par[0]++;

726                                                 gotoxy(currcons,x-par[0],y);

727                                                 break;

    // ���c��'E'�����1������������������ƶ������������ص�0�С�������Ϊ0������1�С�

728                                         case 'E':       // CSI Pn E - ������ƻ�0�С�

729                                                 if (!par[0]) par[0]++;

730                                                 gotoxy(currcons,0,y+par[0]);

731                                                 break;

    // ���c��'F'�����1������������������ƶ������������ص�0�С�������Ϊ0������1�С�

732                                         case 'F':       // CSI Pn F - ������ƻ�0�С�

733                                                 if (!par[0]) par[0]++;

734                                                 gotoxy(currcons,0,y-par[0]);

735                                                 break;

    // ���c��'d'�����1������������������ڵ��кţ���0��������

736                                         case 'd':       // CSI Pn d - �ڵ�ǰ������λ�á�

737                                                 if (par[0]) par[0]--;

738                                                 gotoxy(currcons,x,par[0]);

739                                                 break;

    // ���c��'H'��'f'�����1��������������Ƶ����кţ���2��������������Ƶ����кš�

740                                         case 'H': case 'f':  // CSI Pn H - ��궨λ��

741                                                 if (par[0]) par[0]--;

742                                                 if (par[1]) par[1]--;

743                                                 gotoxy(currcons,par[1],par[0]);

744                                                 break;

    // ����ַ�c��'J'�����1�����������Թ������λ�������ķ�ʽ��

    // ���У�'ESC [ Ps J'��Ps=0 ɾ����굽��Ļ�׶ˣ�1 ɾ����Ļ��ʼ����괦��2 ����ɾ������

745                                         case 'J':       // CSI Pn J - ��Ļ�����ַ���

746                                                 csi_J(currcons,par[0]);

747                                                 break;

    // ����ַ�c��'K'�����һ�����������Թ������λ�ö������ַ�����ɾ�������ķ�ʽ��

    // ת�����У�'ESC [ Ps K'��Ps = 0 ɾ������β��1 �ӿ�ʼɾ����2 ���ж�ɾ������

748                                         case 'K':       // CSI Pn K - ���ڲ����ַ���

749                                                 csi_K(currcons,par[0]);

750                                                 break;

    // ����ַ�c��'L'����ʾ�ڹ��λ�ô�����n�У��������� 'ESC [ Pn L'����

751                                         case 'L':       // CSI Pn L - �����С�

752                                                 csi_L(currcons,par[0]);

753                                                 break;

    // ����ַ�c��'M'����ʾ�ڹ��λ�ô�ɾ��n�У��������� 'ESC [ Pn M'����

754                                         case 'M':       // CSI Pn M - ɾ���С�

755                                                 csi_M(currcons,par[0]);

756                                                 break;

    // ����ַ�c��'P'����ʾ�ڹ��λ�ô�ɾ��n���ַ����������� 'ESC [ Pn P'����

757                                         case 'P':       // CSI Pn P - ɾ���ַ���

758                                                 csi_P(currcons,par[0]);

759                                                 break;

    // ����ַ�c��'@'����ʾ�ڹ��λ�ô�����n���ַ����������� 'ESC [ Pn @' ����

760                                         case '@':       // CSI Pn @ - �����ַ���

761                                                 csi_at(currcons,par[0]);

762                                                 break;

    // ����ַ�c��'m'����ʾ�ı��괦�ַ�����ʾ���ԣ�����Ӵ֡����»��ߡ���˸�����Եȡ�

    // ת�����У�'ESC [ Pn m'��n=0 ������ʾ��1 �Ӵ֣�4 ���»��ߣ�7 ���ԣ�27 ������ʾ�ȡ�

763                                         case 'm':       // CSI Ps m - ������ʾ�ַ����ԡ�

764                                                 csi_m(currcons);

765                                                 break;

    // ����ַ�c��'r'�����ʾ�������������ù�������ʼ�кź���ֹ�кš�

766                                         case 'r':       // CSI Pn;Pn r - ���ù������½硣

767                                                 if (par[0]) par[0]--;

768                                                 if (!par[1]) par[1] = video_num_lines;

769                                                 if (par[0] < par[1] &&

770                                                     par[1] <= video_num_lines) {

771                                                         top=par[0];

772                                                         bottom=par[1];

773                                                 }

774                                                 break;

    // ����ַ�c��'s'�����ʾ���浱ǰ�������λ�á�

775                                         case 's':       // CSI s - ������λ�á�

776                                                 save_cur(currcons);

777                                                 break;

    // ����ַ�c��'u'�����ʾ�ָ���굽ԭ�����λ�ô���

778                                         case 'u':       // CSI u - �ָ�����Ĺ��λ�á�

779                                                 restore_cur(currcons);

780                                                 break;

    // ����ַ�c��'l'��'b'����ֱ��ʾ������Ļ�������ʱ������ô����ַ���ʾ����ʱ������

    // ����par[1]��par[2]������ֵ�����Ƿֱ����Ϊpar[1]= par[0]+13��par[2]= par[0]+17��

    // ����������£����c���ַ�'l'����ôpar[0]���ǿ�ʼ����ʱ˵�ӳٵķ����������c��

    // �ַ�'b'����ôpar[0]�������õĴ����ַ�����ֵ��

781                                         case 'l': /* blank interval */

782                                         case 'b': /* bold attribute */

783                                                   if (!((npar >= 2) &&

784                                                   ((par[1]-13) == par[0]) &&

785                                                   ((par[2]-17) == par[0])))

786                                                     break;

787                                                 if ((c=='l')&&(par[0]>=0)&&(par[0]<=60))

788                                                 { 

789                                                   blankinterval = HZ*60*par[0];

790                                                   blankcount = blankinterval;

791                                                 }

792                                                 if (c=='b')

793                                                   vc_cons[currcons].vc_bold_attr

794                                                     = par[0];

795                                 }

796                                 break;

    // ״̬ESfunckey��ʾ���ǽ��յ��˼����Ϲ��ܼ�������һ�����С����Dz�����ʾ�����ǻָ���

    // ����״̬ESnormal��

797                         case ESfunckey:             // ���̹��ܼ��롣

798                                 state = ESnormal;

799                                 break;

    // ״̬ESsetterm��ʾ�����豸�����ַ�������״̬��DCS������ʱ���յ��ַ� 'S'����ָ���

    // ʼ����ʾ�ַ����ԡ����յ����ַ���'L'��'l'��������ر�������ʾ��ʽ��

800                         case ESsetterm:  /* Setterm functions. */

801                                 state = ESnormal;

802                                 if (c == 'S') {

803                                         def_attr = attr;

804                                         video_erase_char = (video_erase_char&0x0ff) |

                                                               (def_attr<<8);

805                                 } else if (c == 'L')

806                                         ; /*linewrap on*/

807                                 else if (c == 'l')

808                                         ; /*linewrap off*/

809                                 break;

    // ״̬ESsetgraph��ʾ�յ������ַ���ת������'ESC (' �� 'ESC )'�����Ƿֱ�����ָ��G0��

    // G1���õ��ַ�������ʱ���յ��ַ�'0'����ѡ��ͼ���ַ�����ΪG0��G1�����յ����ַ���'B'��

    // ��ѡ����ͨASCII�ַ�����ΪG0��G1���ַ�����

810                         case ESsetgraph:        // 'CSI ( 0'��'CSI ( B' - ѡ���ַ�����

811                                 state = ESnormal;

812                                 if (c == '0')

813                                         translate = GRAF_TRANS;

814                                 else if (c == 'B')

815                                         translate = NORM_TRANS;

816                                 break;

817                         default:

818                                 state = ESnormal;

819                 }

820         }

821         set_cursor(currcons);  // �������������õĹ��λ�ã�������ʾ�������й��λ�á�

822 }

823

824 /*

825  *  void con_init(void);

826  *

827  * This routine initalizes console interrupts, and does nothing

828  * else. If you want the screen to clear, call tty_write with

829  * the appropriate escape-sequece.

830  *

831  * Reads the information preserved by setup.s to determine the current display

832  * type and sets everything accordingly.

833  */

    /*

     * void con_init(void);

     *

     * ����ӳ����ʼ������̨�жϣ�����ʲô�������������������Ļ�ɾ��Ļ�����ʹ��

     * �ʵ���ת���ַ����е���tty_write()������

     *

     * ��ȡsetup.s���򱣴����Ϣ������ȷ����ǰ��ʾ�����ͣ���������������ز�����

     */

834 void con_init(void)

835 {

836         register unsigned char a;

837         char *display_desc = "????";

838         char *display_ptr;

839         int currcons = 0;                         // ��ǰ�������̨�š�

840         long base, term;

841         long video_memory;

842

    // ���ȸ���setup.s����ȡ�õ�ϵͳӲ�����������������60--68�У���ʼ������������ר��

    // �ľ�̬ȫ�ֱ�����

843         video_num_columns = ORIG_VIDEO_COLS;      // ��ʾ����ʾ�ַ�������

844         video_size_row = video_num_columns * 2;   // ÿ���ַ���ʹ�õ��ֽ�����

845         video_num_lines = ORIG_VIDEO_LINES;       // ��ʾ����ʾ�ַ�������

846         video_page = ORIG_VIDEO_PAGE;             // ��ǰ��ʾҳ�档

847         video_erase_char = 0x0720;                // �����ַ���0x20���ַ���0x07���ԣ���

848         blankcount = blankinterval;               // Ĭ�ϵĺ������ʱ�䣨���������

849        

    // Ȼ�������ʾģʽ�ǵ�ɫ���Dz�ɫ�ֱ�������ʹ�õ���ʾ�ڴ���ʼλ���Լ���ʾ�Ĵ�������

    // �˿ںź���ʾ�Ĵ������ݶ˿ںš������õ�BIOS��ʾ��ʽ����7�����ʾ�ǵ�ɫ��ʾ����

850         if (ORIG_VIDEO_MODE == 7)                /* Is this a monochrome display? */

851         {

852                 video_mem_base = 0xb0000;        // ���õ���ӳ���ڴ���ʼ��ַ��

853                 video_port_reg = 0x3b4;          // ���õ��������Ĵ����˿ڡ�

854                 video_port_val = 0x3b5;          // ���õ������ݼĴ����˿ڡ�

 

    // �������Ǹ���BIOS�ж�int 0x10����0x12��õ���ʾģʽ��Ϣ���ж���ʾ���ǵ�ɫ��ʾ��

    // ���Dz�ɫ��ʾ������ʹ�������жϹ������õ���BX�Ĵ�������ֵ������0x10����˵����EGA

    // ������˳�ʼ��ʾ����Ϊ EGA��ɫ����Ȼ EGA �����н϶���ʾ�ڴ棬���ڵ�ɫ��ʽ�����ֻ

    // �����õ�ַ��Χ��0xb0000--0xb8000֮�����ʾ�ڴ档Ȼ������ʾ�������ַ���Ϊ'EGAm'��

    // ������ϵͳ��ʼ���ڼ���ʾ�������ַ�������ʾ����Ļ�����Ͻǡ�

    // ע�⣬����ʹ����bx�ڵ����ж�int 0x10ǰ���Ƿ񱻸ı�ķ������жϿ������͡���BL��

    // �жϵ��ú�ֵ���ı䣬��ʾ��ʾ��֧��Ah=12h���ܵ��ã���EGA����Ƴ�����VGA�����͵�

    // ��ʾ�������жϵ��÷���ֵδ�䣬��ʾ��ʾ����֧��������ܣ���˵����һ�㵥ɫ��ʾ����

855                 if ((ORIG_VIDEO_EGA_BX & 0xff) != 0x10)

856                 {

857                         video_type = VIDEO_TYPE_EGAM;  // ������ʾ���ͣ�EGA��ɫ����

858                         video_mem_term = 0xb8000;      // ������ʾ�ڴ�ĩ�˵�ַ��

859                         display_desc = "EGAm";         // ������ʾ�����ַ�����

860                 }

    // ���BX�Ĵ�����ֵ����0x10����˵���ǵ�ɫ��ʾ��MDA������8KB��ʾ�ڴ档

861                 else

862                 {

863                         video_type = VIDEO_TYPE_MDA;   // ������ʾ����(MDA��ɫ)��

864                         video_mem_term = 0xb2000;      // ������ʾ�ڴ�ĩ�˵�ַ��

865                         display_desc = "*MDA";         // ������ʾ�����ַ�����

866                 }

867         }

    // �����ʾ��ʽ��Ϊ7��˵���Dz�ɫ��ʾ������ʱ�ı���ʽ��������ʾ�ڴ���ʼ��ַΪ0xb8000��

    // ��ʾ���������Ĵ����˿ڵ�ַΪ 0x3d4�����ݼĴ����˿ڵ�ַΪ 0x3d5��

868         else                            /* If not, it is color. */

869         {

870                 can_do_colour = 1;                     // ���ò�ɫ��ʾ��־��

871                 video_mem_base = 0xb8000;              // ��ʾ�ڴ���ʼ��ַ��

872                 video_port_reg  = 0x3d4;               // ���ò�ɫ��ʾ�����Ĵ����˿ڡ�

873                 video_port_val  = 0x3d5;               // ���ò�ɫ��ʾ���ݼĴ����˿ڡ�

    // ���ж���ʾ��������BX������0x10����˵����EGA��ʾ������ʱ����32KB��ʾ�ڴ����

    // ��0xb8000-0xc0000��������˵����CGA��ʾ����ֻ��ʹ��8KB��ʾ�ڴ棨0xb8000-0xba000����

874                 if ((ORIG_VIDEO_EGA_BX & 0xff) != 0x10)

875                 {

876                         video_type = VIDEO_TYPE_EGAC;  // ������ʾ���ͣ�EGA��ɫ����

877                         video_mem_term = 0xc0000;      // ������ʾ�ڴ�ĩ�˵�ַ��

878                         display_desc = "EGAc";         // ������ʾ�����ַ�����

879                 }

880                 else

881                 {

882                         video_type = VIDEO_TYPE_CGA;   // ������ʾ���ͣ�CGA����

883                         video_mem_term = 0xba000;      // ������ʾ�ڴ�ĩ�˵�ַ��

884                         display_desc = "*CGA";         // ������ʾ�����ַ�����

885                 }

886         }

    // �������������㵱ǰ��ʾ���ڴ��Ͽ��Կ�����������̨������Ӳ������������������̨��

    // ����������ʾ�ڴ���video_memory����ÿ���������̨ռ�õ��ֽ�����ÿ���������̨ռ�õ�

    // ��ʾ�ڴ���������Ļ��ʾ���� video_num_lines ����ÿ���ַ�ռ�е��ֽ���video_size_row��

    // ���Ӳ������������������̨��������ϵͳ�޶����������MAX_CONSOLES���Ͱ��������̨

    // ��������ΪMAX_CONSOLES����������������������̨����Ϊ0��������Ϊ1�������ܰɣ�����

    // �������ʾ�ڴ��������жϳ����������̨�����õ�ÿ���������̨ռ����ʾ�ڴ��ֽ�����

887         video_memory = video_mem_term - video_mem_base;

888         NR_CONSOLES = video_memory / (video_num_lines * video_size_row);

889         if (NR_CONSOLES > MAX_CONSOLES)           // MAX_CONSOLES = 8��

890                 NR_CONSOLES = MAX_CONSOLES;

891         if (!NR_CONSOLES)

892                 NR_CONSOLES = 1;

893         video_memory /= NR_CONSOLES;              // ÿ���������̨ռ����ʾ�ڴ��ֽ�����

894

895         /* Let the user known what kind of display driver we are using */

            /* ��ʼ�����ڹ����ı�������Ҫ����EGA/VGA�� */

896        

    // Ȼ����������Ļ�����Ͻ���ʾ�����ַ��������õķ�����ֱ�ӽ��ַ���д����ʾ�ڴ����Ӧ

    // λ�ô������Ƚ���ʾָ��display_ptrָ����Ļ��1���Ҷ˲�4���ַ�����ÿ���ַ���2��

    // �ֽڣ���˼�8����Ȼ��ѭ�������ַ������ַ�������ÿ����1���ַ����տ�1�������ֽڡ�

897         display_ptr = ((char *)video_mem_base) + video_size_row - 8;

898         while (*display_desc)

899         {

900                 *display_ptr++ = *display_desc++;

901                 display_ptr++;

902         }

903        

904         /* Initialize the variables used for scrolling (mostly EGA/VGA) */

            /* ��ʼ�����ڹ����ı���(��Ҫ����EGA/VGA) */

905        

    // ע�⣬��ʱ��ǰ�������̨��currcons�ѱ���ʼ��λ0���������ʵ�����dz�ʼ��0�������

    // ��̨�Ľṹvc_cons[0]�е������ֶ�ֵ�����磬�������origin��ǰ���115�����ѱ�����Ϊ

    // vc_cons[0].vc_origin��������������0�ſ���̨��Ĭ�Ϲ�����ʼ�ڴ�λ�� video_mem_start

    // ��Ĭ�Ϲ���ĩ���ڴ�λ�ã�ʵ��������Ҳ����0�ſ���̨ռ�õIJ�����ʾ�ڴ�����Ȼ���ʼ

    // ����0���������̨���������Ժͱ�־ֵ��

906         base = origin = video_mem_start = video_mem_base;  // Ĭ�Ϲ�����ʼ�ڴ�λ�á�

907         term = video_mem_end = base + video_memory;        // 0����Ļ�ڴ�ĩ��λ�á�

908         scr_end = video_mem_start + video_num_lines * video_size_row; // ����ĩ��λ�á�

909         top     = 0;                           // ��ʼ���ù���ʱ�����кź͵����кš�

910         bottom  = video_num_lines;

911         attr = 0x07;                           // ��ʼ������ʾ�ַ����ԣ��ڵװ��֣���

912         def_attr = 0x07;                       // ����Ĭ����ʾ�ַ����ԡ�

913         restate = state = ESnormal;            // ��ʼ��ת�����в����ĵ�ǰ����һ״̬��

914         checkin = 0;

915         ques = 0;                              // �յ��ʺ��ַ���־��

916         iscolor = 0;                           // ��ɫ��ʾ��־��

917         translate = NORM_TRANS;                // ʹ�õ��ַ�������ͨASCII�������

918         vc_cons[0].vc_bold_attr = -1;          // �����ַ����Ա�־��-1��ʾ���ã���

919

    // ��������0�ſ���̨��ǰ�������λ�ú͹���Ӧ���ڴ�λ��pos������ѭ����������ļ�

    // ���������̨�ṹ�IJ���ֵ�����˸���ռ�õ���ʾ�ڴ濪ʼ�ͽ���λ�ò�ͬ�����ǵij�ʼֵ��

    // ���϶���0�ſ���̨��ͬ��

920         gotoxy(currcons,ORIG_X,ORIG_Y);

921         for (currcons = 1; currcons<NR_CONSOLES; currcons++) {

922                 vc_cons[currcons] = vc_cons[0];     // ����0�Žṹ�IJ�����

923                 origin = video_mem_start = (base += video_memory);

924                 scr_end = origin + video_num_lines * video_size_row;

925                 video_mem_end = (term += video_memory);

926                 gotoxy(currcons,0,0);                // ��궼��ʼ������Ļ���Ͻ�λ�á�

927         }

    // ������õ�ǰǰ̨����̨����Ļԭ�㣨���Ͻǣ�λ�ú���ʾ�������й����ʾλ�ã������ü�

    // ���ж�0x21��������������&keyboard_interrupt�Ǽ����жϴ������̵�ַ����Ȼ��ȡ���ж�

    // ����оƬ8259A �жԼ����жϵ����Σ�������Ӧ���̷����� IRQ1 �����źš����λ���̿�

    // �������������̿�ʼ����������

928         update_screen();                         // ����ǰ̨ԭ������ù��λ�á�

929         set_trap_gate(0x21,&keyboard_interrupt); // �μ�system.h����36�п�ʼ��

930         outb_p(inb_p(0x21)&0xfd,0x21);           // ȡ���Լ����жϵ����Σ�����IRQ1��

931         a=inb_p(0x61);                           // ��ȡ���̶˿�0x61��8255A�˿�PB����

932         outb_p(a|0x80,0x61);                     // ���ý�ֹ���̹�����λ7��λ����

933         outb_p(a,0x61);                          // ���������̹��������Ը�λ���̡�

934 }

935

    // ���µ�ǰǰ̨����̨��

    // ��ǰ̨����̨ת��Ϊfg_consoleָ�����������̨��fg_console�����õ�ǰ̨�������̨�š�

936 void update_screen(void)

937 {

938         set_origin(fg_console);                 // ���ù�����ʼ��ʾ�ڴ��ַ��

939         set_cursor(fg_console);                 // ������ʾ�������й����ʾ�ڴ�λ�á�

940 }

941

942 /* from bsd-net-2: */

943

    //// ֹͣ������

    // ��λ8255A PB�˿ڵ�λ1��λ0���μ�kernel/sched.c�����Ķ�ʱ�����˵����

944 void sysbeepstop(void)

945 {

946         /* disable counter 2 */  /* ��ֹ��ʱ��2 */

947         outb(inb_p(0x61)&0xFC, 0x61);

948 }

949

950 int beepcount = 0;              // ����ʱ����઼�����

951

    // ��ͨ������

    // 8255AоƬPB�˿ڵ�λ1�����������Ŀ����źţ�λ0����8253��ʱ��2�����źţ��ö�ʱ

    // �������������������������Ϊ������������Ƶ�ʡ����Ҫʹ��������������Ҫ���������ȿ�

    // �� PB�˿ڣ�0x61��λ1�� λ0����λ����Ȼ�����ö�ʱ��2ͨ������һ���Ķ�ʱƵ�ʼ��ɡ�

    // �μ�boot/setup.s�����8259AоƬ��̷�����kernel/sched.c�����Ķ�ʱ�����˵����

952 static void sysbeep(void)

953 {

954         /* enable counter 2 */          /* ������ʱ��2 */

955         outb_p(inb_p(0x61)|3, 0x61);

956         /* set command for counter 2, 2 byte write */    /* �����ö�ʱ��2���� */

957         outb_p(0xB6, 0x43);             // ��ʱ��оƬ�����ּĴ����˿ڡ�

958         /* send 0x637 for 750 HZ */     /* ����Ƶ��Ϊ750HZ������Ͷ�ʱֵ0x637 */

959         outb_p(0x37, 0x42);             // ͨ��2���ݶ˿ڷֱ��ͼ����ߵ��ֽڡ�

960         outb(0x06, 0x42);

961         /* 1/8 second */                /* ����ʱ��Ϊ1/8�� */

962         beepcount = HZ/8;      

963 }

964

    //// ������Ļ��

    // ����Ļ���ݸ��Ƶ�����ָ�����û�������arg�С�

    // ����arg��������;��һ�����ڴ��ݿ���̨�ţ�������Ϊ�û�������ָ�롣

965 int do_screendump(int arg)

966 {

967         char *sptr, *buf = (char *)arg;

968         int currcons, l;

969

    // ����������֤�û��ṩ�Ļ�����������������������ʵ���չ��Ȼ����俪ʼ��ȡ������̨

    // ��currcons�����жϿ���̨����Ч֮�󣬾ͰѸÿ���̨��Ļ�������ڴ����ݸ��Ƶ��û�����

    // ���С�

970         verify_area(buf,video_num_columns*video_num_lines);

971         currcons = get_fs_byte(buf);

972         if ((currcons<1) || (currcons>NR_CONSOLES))

973                 return -EIO;

974         currcons--;

975         sptr = (char *) origin;

976         for (l=video_num_lines*video_num_columns; l>0 ; l--)

977                 put_fs_byte(*sptr++,buf++);    

978         return(0);

979 }

980

    // ����������

    // ���û���blankIntervalʱ������û�а��κΰ���ʱ������Ļ�������Ա�����Ļ��

981 void blank_screen()

982 {

983         if (video_type != VIDEO_TYPE_EGAC && video_type != VIDEO_TYPE_EGAM)

984                 return;

985 /* blank here. I can't find out how to do it, though */

986 }

987

    // �ָ���������Ļ��

    // ���û������κΰ���ʱ���ͻָ����ں���״̬����Ļ��ʾ���ݡ�

988 void unblank_screen()

989 {

990         if (video_type != VIDEO_TYPE_EGAC && video_type != VIDEO_TYPE_EGAM)

991                 return;

992 /* unblank here */

993 }

994

    //// ����̨��ʾ������

    // �ú����������ں���ʾ����printk()��kernel/printk.c���������ڵ�ǰǰ̨����̨����ʾ

    // �ں���Ϣ������������ѭ��ȡ���������е��ַ����������ַ������Կ��ƹ���ƶ���ֱ����

    // ʾ����Ļ�ϡ�

    // ���� b��null��β���ַ���������ָ�롣

995 void console_print(const char * b)

996 {

997         int currcons = fg_console;

998         char c;

999

    // ѭ����ȡ������b�е��ַ��������ǰ�ַ�c�ǻ��з�����Թ��ִ�лس����в�����Ȼ��

    // ȥ������һ���ַ�������ǻس�������ֱ��ִ�лس�������Ȼ��ȥ������һ���ַ���

1000         while (c = *(b++)) {

1001                 if (c == 10) {

1002                         cr(currcons);

1003                         lf(currcons);

1004                         continue;

1005                 }

1006                 if (c == 13) {

1007                         cr(currcons);

1008                         continue;

1009                 }

    // �ڶ�ȡ��һ�����ǻس������ַ���������ֵ�ǰ�����λ��x�Ѿ�������Ļ��ĩ�ˣ�����

    // ����۷�����һ�п�ʼ����Ȼ����ַ��ŵ����������ʾ�ڴ�λ�ô���������Ļ����ʾ������

    // �ٰѹ������һ��λ�ã�Ϊ��ʾ��һ���ַ���׼����

1010                 if (x>=video_num_columns) {

1011                         x -= video_num_columns;

1012                         pos -= video_size_row;

1013                         lf(currcons);

1014                 }

    // �Ĵ���al������Ҫ��ʾ���ַ�������������ֽڷŵ�ah�У�Ȼ���ax���ݴ洢������ڴ�

    // λ��pos�������ڹ�괦��ʾ�ַ���

1015                 __asm__("movb %2,%%ah\n\t"         // �����ֽڷŵ�ah�С�

1016                         "movw %%ax,%1\n\t"         // ax���ݷŵ�pos����

1017                         ::"a" (c),

1018                         "m" (*(short *)pos),

1019                         "m" (attr)

1020                         :"ax");

1021                 pos += 2;

1022                 x++;

1023         }

1024         set_cursor(currcons); // ������õĹ���ڴ�λ�ã�������ʾ�������й��λ�á�

1025 }

1026


 


 

10.3 ����10-3 linux/kernel/chr_drv/serial.c


  1 /*

  2  *  linux/kernel/serial.c

  3  *

  4  *  (C) 1991  Linus Torvalds

  5  */

  6

  7 /*

  8  *      serial.c

  9  *

 10  * This module implements the rs232 io functions

 11  *      void rs_write(struct tty_struct * queue);

 12  *      void rs_init(void);

 13  * and all interrupts pertaining to serial IO.

 14  */

    /*

     *     serial.c

     * �ó�������ʵ��rs232�������������

     *     void rs_write(struct tty_struct *queue);

     *     void rs_init(void);

     * �Լ��봮��IO�й�ϵ�������жϴ�������

     */

 15

 16 #include <linux/tty.h>    // ttyͷ�ļ����������й�tty_io������ͨ�ŷ���IJ�����������

 17 #include <linux/sched.h>  // ���ȳ���ͷ�ļ�������������ṹtask_struct������0���ݵȡ�

 18 #include <asm/system.h>   // ϵͳͷ�ļ����������û��޸�������/�ж��ŵȵ�Ƕ��ʽ���ꡣ

 19 #include <asm/io.h>       // ioͷ�ļ�������Ӳ���˿�����/���������䡣

 20

 21 #define WAKEUP_CHARS (TTY_BUF_SIZE/4)  // ��д�����к���WAKEUP_CHARS���ַ�ʱ�Ϳ�ʼ���͡�

 22

 23 extern void rs1_interrupt(void);       // ���п�1���жϴ�������rs_io.s, 34�У���

 24 extern void rs2_interrupt(void);       // ���п�2���жϴ�������rs_io.s, 38�У���

 25

    //// ��ʼ�����ж˿�

    // ����ָ�����ж˿ڵĴ��䲨���ʣ�2400bps������������д���ּĴ���������������ж�Դ��

    // ���⣬�����2�ֽڵIJ���������ʱ��������������·���ƼĴ�����DLABλ��λ7����

    // ������port�Ǵ��ж˿ڻ���ַ������1 - 0x3F8������2 - 0x2F8��

 26 static void init(int port)

 27 {

 28         outb_p(0x80,port+3);    /* set DLAB of line control reg */

 29         outb_p(0x30,port);      /* LS of divisor (48 -> 2400 bps */

 30         outb_p(0x00,port+1);    /* MS of divisor */

 31         outb_p(0x03,port+3);    /* reset DLAB */

 32         outb_p(0x0b,port+4);    /* set DTR,RTS, OUT_2 */

 33         outb_p(0x0d,port+1);    /* enable all intrs but writes */

 34         (void)inb(port);        /* read data port to reset things (?) */

 35 }

 36

    //// ��ʼ�������жϳ���ʹ��нӿڡ�

    // �ж���������IDT�е������������ú�set_intr_gate()��include/asm/system.h��ʵ�֡�

 37 void rs_init(void)

 38 {

    // �����������������������пڵ��ж�����������rs1_interrupt�Ǵ���1���жϴ�������ָ�롣

    // ����1ʹ�õ��ж���int 0x24������2����int 0x23���μ���2-2��system.h�ļ���

 39         set_intr_gate(0x24,rs1_interrupt);   // ���ô��п�1���ж�������(IRQ4�ź�)��

 40         set_intr_gate(0x23,rs2_interrupt);   // ���ô��п�2���ж�������(IRQ3�ź�)��

 41         init(tty_table[64].read_q->data);    // ��ʼ�����п�1(.data�Ƕ˿ڻ���ַ)��

 42         init(tty_table[65].read_q->data);    // ��ʼ�����п�2��

 43         outb(inb_p(0x21)&0xE7,0x21);         // ������8259A��ӦIRQ3��IRQ4�ж�����

 44 }

 45

 46 /*

 47  * This routine gets called when tty_write has put something into

 48  * the write_queue. It must check wheter the queue is empty, and

 49  * set the interrupt register accordingly

 50  *

 51  *      void _rs_write(struct tty_struct * tty);

 52  */

    /*

     * ��tty_write()�ѽ����ݷ������(д)����ʱ�����������ӳ����ڸ�

     * �ӳ����б������ȼ��д�����Ƿ�Ϊ�գ�Ȼ��������Ӧ�жϼĴ�����

     */

    //// �������ݷ��������

    // �ú���ʵ����ֻ�ǿ������ͱ��ּĴ����ѿ��жϱ�־���˺󵱷��ͱ��ּĴ�����ʱ��UART�ͻ�

    // �����ж����󡣶��ڸô����жϴ��������У������ȡ��д����βָ�봦���ַ������������

    // �ͱ��ּĴ����С�һ��UART�Ѹ��ַ������˳�ȥ�����ͱ��ּĴ����ֻ��ն������ж�����

    // ����ֻҪд�����л����ַ���ϵͳ�ͻ��ظ�����������̣����ַ�һ��һ���ط��ͳ�ȥ����д

    // �����������ַ��������˳�ȥ��д���б���ˣ��жϴ�������ͻ���ж������Ĵ����еķ���

    // ���ּĴ����ж�������־��λ�����Ӷ��ٴν�ֹ���ͱ��ּĴ����������ж����󡣴˴Ρ�ѭ����

    // ���Ͳ���Ҳ��֮������

 53 void rs_write(struct tty_struct * tty)

 54 {

    // ���д���в��գ������ȴ�0x3f9����0x2f9����ȡ�ж������Ĵ������ݣ����Ϸ��ͱ��ּĴ���

    // �ж�������־��λ1������д�ظüĴ����������������ͱ��ּĴ�����ʱUART���ܹ�������

    // ��������͵��ַ��������жϡ�write_q.data���Ǵ��ж˿ڻ���ַ��

 55         cli();

 56         if (!EMPTY(tty->write_q))

 57                 outb(inb_p(tty->write_q->data+1)|0x02,tty->write_q->data+1);

 58         sti();

 59 }

 60


 


 

10.4 ����10-4 linux/kernel/chr_drv/rs_io.s


  1 /*

  2  *  linux/kernel/rs_io.s

  3  *

  4  *  (C) 1991  Linus Torvalds

  5  */

  6

  7 /*

  8  *      rs_io.s

  9  *

 10  * This module implements the rs232 io interrupts.

 11  */

    /*

     * ��ģ��ʵ��rs232��������жϴ�������

     */

 12

 13 .text

 14 .globl _rs1_interrupt,_rs2_interrupt

 15

    // size�Ƕ�д���л��������ֽڳ��ȡ���ֵ������2�Ĵη������ұ�����tty_io.c�е�ƥ�䡣

 16 size    = 1024                          /* must be power of two !

 17                                            and must match the value

 18                                            in tty_io.c!!! */

 19

 20 /* these are the offsets into the read/write buffer structures */

    /* ������Щ�Ƕ�д������нṹ�е�ƫ���� */

    // ��Ӧ include/linux/tty.h �ļ��� tty_queue �ṹ�и��ֶε��ֽ�ƫ����������rs_addr

    // ��Ӧtty_queue�ṹ��data�ֶΡ����ڴ����ն˻�����У����ֶδ���Ŵ��ж˿ڻ���ַ��

 21 rs_addr = 0                      // ���ж˿ں��ֶ�ƫ�ƣ��˿���0x3f8��0x2f8����

 22 head = 4                         // ��������ͷָ���ֶ�ƫ�ơ�

 23 tail = 8                         // ��������βָ���ֶ�ƫ�ơ�

 24 proc_list = 12                   // �ȴ��û���Ľ����ֶ�ƫ�ơ�

 25 buf = 16                         // �������ֶ�ƫ�ơ�

 26

    // ��һ��д������������ں˾ͻ��Ҫ��д�������ַ��Ľ�������Ϊ�ȴ�״̬����д�������

    // �л�ʣ�����256���ַ�ʱ���жϴ�������Ϳ��Ի�����Щ�ȴ����̼�����д�����з��ַ���

 27 startup = 256                    /* chars left in write queue when we restart it */

                                     /* ���������¿�ʼдʱ����������໹ʣ���ַ�������*/

 28

 29 /*

 30  * These are the actual interrupt routines. They look where

 31  * the interrupt is coming from, and take appropriate action.

 32  */

    /*

     * ��Щ��ʵ�ʵ��жϴ������򡣳������ȼ���жϵ���Դ��Ȼ��ִ��

     * ��Ӧ�Ĵ�����

     */

    //// ���ж˿�1�жϴ���������ڵ㡣

    // ��ʼ��ʱrs1_interrupt��ַ�������ж�������0x24�У���Ӧ8259A���ж�����IRQ4���š�

    // �������Ȱ�tty���д����ն�1������1����д�������ָ��ĵ�ַ��ջ��tty_io.c��81����

    // Ȼ����ת��rs_int���������������������ô���1�ʹ���2�Ĵ������빫�á��ַ��������

    // �ṹtty_queue��ʽ��μ�include/linux/tty.h����22�С�

 33 .align 2

 34 _rs1_interrupt:

 35         pushl $_table_list+8    // tty���д���1��д�������ָ���ַ��ջ��

 36         jmp rs_int

 37 .align 2

    //// ���ж˿�2�жϴ���������ڵ㡣

 38 _rs2_interrupt:

 39         pushl $_table_list+16   // tty���д���2��д�������ָ���ַ��ջ��

 

    // ��δ��������öμĴ���ds��esָ���ں����ݶΣ�Ȼ��Ӷ�Ӧ��д�������data�ֶ�ȡ��

    // ���ж˿ڻ���ַ���õ�ַ��2�����жϱ�ʶ�Ĵ���IIR�Ķ˿ڵ�ַ����λ0 = 0����ʾ����

    // Ҫ�������жϡ����Ǹ���λ2��λ1ʹ��ָ����ת��������Ӧ�ж�Դ���ʹ����ӳ�����ÿ

    // ���ӳ����л��ڴ������λUART ����Ӧ�ж�Դ�����ӳ��򷵻غ���δ����ѭ���ж���

    // ���������ж�Դ��λ0 = 0��������������жϻ��������ж�Դ����IIR��λ0��Ȼ��0��

    // �����жϴ���������ٵ�����Ӧ�ж�Դ�ӳ������������ֱ�����𱾴��жϵ������ж�Դ��

    // ����������λ����ʱUART���Զ�������IIR��λ0 =1����ʾ���޴��������жϣ������ж�

    // �������򼴿��˳���

 40 rs_int:

 41         pushl %edx

 42         pushl %ecx

 43         pushl %ebx

 44         pushl %eax

 45         push %es

 46         push %ds                /* as this is an interrupt, we cannot */

 47         pushl $0x10             /* know that bs is ok. Load it */

 48         pop %ds                 /* ��������һ���жϳ������Dz�֪��ds�Ƿ���ȷ��*/

 49         pushl $0x10             /* ���Լ������ǣ���ds��esָ���ں����ݶΣ� */

 50         pop %es

 51         movl 24(%esp),%edx      // ȡ����35��39����ջ����Ӧ���ڻ������ָ���ַ��

 52         movl (%edx),%edx        // ȡ��������нṹָ�루��ַ����edx��

 53         movl rs_addr(%edx),%edx // ȡ����1���򴮿�2���˿ڻ���ַ��edx��

 54         addl $2,%edx            /* interrupt ident. reg */  /* ָ���жϱ�ʶ�Ĵ��� */

                                    // �жϱ�ʶ�Ĵ����˿ڵ�ַ��0x3fa��0x2fa����

 55 rep_int:

 56         xorl %eax,%eax

 57         inb %dx,%al             // ȡ�жϱ�ʶ�ֽڣ����ж��ж���Դ����4���ж��������

 58         testb $1,%al            // �����ж����޴������жϣ�λ0 = 0���жϣ���

 59         jne end                 // ���޴������жϣ�����ת���˳�������end��

 60         cmpb $6,%al             /* this shouldn't happen, but ... */ /*�ⲻ�ᷢ��������*/

 61         ja end                  // alֵ����6������ת��end��û������״̬����

 62         movl 24(%esp),%ecx      // �����ӳ���֮ǰ�ѻ������ָ���ַ����ecx��

 63         pushl %edx              // ��ʱ�����жϱ�ʶ�Ĵ����˿ڵ�ַ��

 64         subl $2,%edx            // edx�лָ����ڻ���ֵַ0x3f8��0x2f8����

 65         call jmp_table(,%eax,2) /* NOTE! not *4, bit0 is 0 already */

    // ���������ָ�����д������ж�ʱ��al��λ0=0��λ2��λ1���ж����ͣ�����൱���Ѿ���

    // �ж����ͳ���2�������ٳ�2�������ת������79�У���Ӧ���ж����͵�ַ������ת������ȥ

    // ����Ӧ�������ж���Դ��4�֣�modem״̬�����仯��Ҫд�����ͣ��ַ���Ҫ�������գ��ַ���

    // ��·״̬�����仯�����������ַ��ж�ͨ�����÷��ͱ��ּĴ�����־ʵ�֡���serial.c����

    // �У���д���������������ʱ��rs_write()�����ͻ��޸��ж������Ĵ������ݣ������Ϸ��ͱ�

    // �ּĴ����ж�������־���Ӷ���ϵͳ��Ҫ�����ַ�ʱ�������жϷ�����

 66         popl %edx               // �ָ��жϱ�ʶ�Ĵ����˿ڵ�ַ0x3fa����0x2fa����

 67         jmp rep_int             // ��ת�������ж����޴������жϲ�����Ӧ������

 

 68 end:    movb $0x20,%al          // �ж��˳����������жϿ��������ͽ����ж�ָ��EOI��

 69         outb %al,$0x20          /* EOI */

 70         pop %ds

 71         pop %es

 72         popl %eax

 73         popl %ebx

 74         popl %ecx

 75         popl %edx

 76         addl $4,%esp            # jump over _table_list entry   # ��������ָ���ַ��

 77         iret

 78

    // ���ж����ʹ����ӳ����ַ��ת��������4���ж���Դ��

    // modem״̬�仯�жϣ�д�ַ��жϣ����ַ��жϣ���·״̬�������жϡ�

 79 jmp_table:

 80         .long modem_status,write_char,read_char,line_status

 81

    // ����modem״̬�����仯�������˴��жϡ�ͨ����modem״̬�Ĵ���MSR������и�λ������

 82 .align 2

 83 modem_status:

 84         addl $6,%edx            /* clear intr by reading modem status reg */

 85         inb %dx,%al             /* ͨ����modem״̬�Ĵ������и�λ��0x3fe�� */

 86         ret

 87

    // ������·״̬�����仯��������δ����жϡ�ͨ������·״̬�Ĵ���LSR������и�λ������

 88 .align 2

 89 line_status:

 90         addl $5,%edx            /* clear intr by reading line status reg. */

 91         inb %dx,%al             /* ͨ������·״̬�Ĵ������и�λ��0x3fd�� */

 92         ret

 93

    // ����UARTоƬ���յ��ַ�����������жϡ��Խ��ջ���Ĵ���ִ�ж������ɸ�λ���ж�Դ��

    // ����ӳ��򽫽��յ����ַ��ŵ����������read_qͷָ�루head�����������ø�ָ��ǰ��һ

    // ���ַ�λ�á���headָ���Ѿ����ﻺ����ĩ�ˣ��������۷�����������ʼ����������C��

    // ��do_tty_interrupt()��Ҳ��copy_to_cooked()�����Ѷ�����ַ�������������淶ģʽ��

    // ����У������������secondary���С�

 94 .align 2

 95 read_char:

 96         inb %dx,%al             // ��ȡ���ջ���Ĵ���RBR���ַ���al��

 97         movl %ecx,%edx          // ��ǰ���ڻ������ָ���ַ��edx��

 98         subl $_table_list,%edx  // ��ǰ���ڶ���ָ���ַ - �������ָ�����ַ ��edx��

 99         shrl $3,%edx            // ��ֵ/8���ô��ںš����ڴ���1��1�����ڴ���2��2��

100         movl (%ecx),%ecx         # read-queue    // ȡ��������нṹ��ַ��ecx��

101         movl head(%ecx),%ebx    // ȡ�������л���ͷָ����ebx��

102         movb %al,buf(%ecx,%ebx) // ���ַ����ڻ�������ͷָ����ָλ�ô���

103         incl %ebx               // ��ͷָ��ǰ�ƣ����ƣ�һ�ֽڡ�

104         andl $size-1,%ebx       // �û��������ȶ�ͷָ��ȡģ������

105         cmpl tail(%ecx),%ebx    // ������ͷָ����βָ��Ƚϡ�

106         je 1f                   // ��ָ���ƶ�����ȣ���ʾ����������������ͷָ�룬��ת��

107         movl %ebx,head(%ecx)    // �����޸Ĺ���ͷָ�롣

108 1:      addl $63,%edx           // ���ں�ת����tty�ţ�63��64������Ϊ������ջ��

109         pushl %edx

110         call _do_tty_interrupt  // ����tty�жϴ���C������tty_io.c��342�У���

111         addl $4,%esp            // ������ջ�����������ء�

112         ret

113

    // ���������˷��ͱ��ּĴ��������жϱ�־������˴��жϡ�˵����Ӧ�����ն˵�д�ַ������

    // �������ַ���Ҫ���͡����Ǽ����д�����е�ǰ�����ַ��������ַ�����С��256��������

    // �ȴ�д�������̡�Ȼ���д�������β��ȡ��һ���ַ����ͣ��������ͱ���βָ�롣���д��

    // ������ѿգ�����ת��write_buffer_empty������д������пյ������

114 .align 2

115 write_char:

116         movl 4(%ecx),%ecx             # write-queue  // ȡд������нṹ��ַ��ecx��

117         movl head(%ecx),%ebx         // ȡд����ͷָ����ebx��

118         subl tail(%ecx),%ebx         // ͷָ�� - βָ�� = �������ַ�����

119         andl $size-1,%ebx             # nr chars in queue

120         je write_buffer_empty        // ��ͷָ�� = βָ�룬˵��д���пգ���ת������

121         cmpl $startup,%ebx           // �������ַ���������256����

122         ja 1f                        // ��������ת������

123         movl proc_list(%ecx),%ebx     # wake up sleeping process  # ���ѵȴ��Ľ��̡�

                                         // ȡ�ȴ��ö��еĽ���ָ�룬���ж��Ƿ�Ϊ�ա�

124         testl %ebx,%ebx               # is there any?    # �еȴ�д�Ľ�����

125         je 1f                        // �ǿյģ�����ǰ��ת�����1����

126         movl $0,(%ebx)               // ���򽫽�����Ϊ������״̬�����ѽ��̣���

127 1:      movl tail(%ecx),%ebx         // ȡβָ�롣

128         movb buf(%ecx,%ebx),%al      // �ӻ�����βָ�봦ȡһ�ַ���al��

129         outb %al,%dx                 // ��˿�0x3f8��0x2f8��д�����ͱ��ּĴ����С�

130         incl %ebx                    // βָ��ǰ�ơ�

131         andl $size-1,%ebx            // βָ������������ĩ�ˣ����ۻء�

132         movl %ebx,tail(%ecx)         // �������޸Ĺ���βָ�롣

133         cmpl head(%ecx),%ebx         // βָ����ͷָ��Ƚϣ�

134         je write_buffer_empty        // ����ȣ���ʾ�����ѿգ�����ת��

135         ret

    // ����д�������write_q�ѿյ���������еȴ�д�ô����ն˵Ľ�������֮��Ȼ�����η�

    // �ͱ��ּĴ������жϣ����÷��ͱ��ּĴ�����ʱ�����жϡ�

    // �����ʱд�������write_q�ѿգ���ʾ��ǰ���ַ���Ҫ���͡���������Ӧ�����������顣

    // ���ȿ�����û�н������ȴ�д���пճ���������оͻ���֮�����⣬��Ϊ����ϵͳ�����ַ�

    // ��Ҫ���ͣ����Դ�ʱ����Ҫ��ʱ��ֹ���ͱ��ּĴ���THR��ʱ�����жϡ��������ַ�������

    // д���������ʱ��serial.c�е�rs_write()�������ٴ��������ͱ��ּĴ�����ʱ�����жϣ�

    // ���UART���ֻᡰ�Զ�������ȡд��������е��ַ��������ͳ�ȥ��

136 .align 2

137 write_buffer_empty:

138         movl proc_list(%ecx),%ebx     # wake up sleeping process # ���ѵȴ��Ľ��̡�

                                         // ȡ�ȴ��ö��еĽ��̵�ָ�룬���ж��Ƿ�Ϊ�ա�

139         testl %ebx,%ebx               # is there any?    # �еȴ��Ľ�����

140         je 1f                        // �ޣ�����ǰ��ת�����1����

141         movl $0,(%ebx)               // ���򽫽�����Ϊ������״̬�����ѽ��̣���

142 1:      incl %edx                    // ָ��˿�0x3f9��0x2f9����

143         inb %dx,%al                  // ��ȡ�ж������Ĵ���IER��

144         jmp 1f                       // �����ӳ١�

145 1:      jmp 1f                       /* ���η��ͱ��ּĴ������жϣ�λ1�� */

146 1:      andb $0xd,%al                /* disable transmit interrupt */

147         outb %al,%dx                 // д��0x3f9(0x2f9)��

148         ret



 

10.5 ����10-5 linux/kernel/chr_drv/tty_io.c


  1 /*

  2  *  linux/kernel/tty_io.c

  3  *

  4  *  (C) 1991  Linus Torvalds

  5  */

  6

  7 /*

  8  * 'tty_io.c' gives an orthogonal feeling to tty's, be they consoles

  9  * or rs-channels. It also implements echoing, cooked mode etc.

 10  *

 11  * Kill-line thanks to John T Kohl, who also corrected VMIN = VTIME = 0.

 12  */

    /*

    * 'tty_io.c'��tty�ն�һ�ַ���صĸо������������ǿ���̨���Ǵ����նˡ�

    * �ó���ͬ��ʵ���˻��ԡ��淶(��)ģʽ�ȡ�

    *

    * Kill-line���⣬ҪллJohn T Kohl����ͬʱ�������˵� VMIN = VTIME = 0 ʱ�����⡣

    */

 13

 14 #include <ctype.h>        // �ַ�����ͷ�ļ���������һЩ�й��ַ������жϺ�ת���ĺꡣ

 15 #include <errno.h>        // �����ͷ�ļ�������ϵͳ�и��ֳ����š�

 16 #include <signal.h>       // �ź�ͷ�ļ��������źŷ��ų������źŽṹ�����������ԭ�͡�

 17 #include <unistd.h>       // unistd.h�DZ�׼���ų����������ļ����������˸��ֺ�����

 18

    // ������ʱ���棨alarm���ź����ź�λͼ�ж�Ӧ�ı�������λ��

 19 #define ALRMMASK (1<<(SIGALRM-1))

 20

 21 #include <linux/sched.h>  // ���ȳ���ͷ�ļ�������������ṹtask_struct������0���ݵȡ�

 22 #include <linux/tty.h>    // ttyͷ�ļ����������й�tty_io������ͨ�ŷ���IJ�����������

 23 #include <asm/segment.h>  // �β���ͷ�ļ����������йضμĴ���������Ƕ��ʽ��ຯ����

 24 #include <asm/system.h>   // ϵͳͷ�ļ����������û��޸�������/�ж��ŵ�Ƕ��ʽ���ꡣ

 25

    // ��ֹ�����飨������鷢���źţ�������pgrpָ��������ţ�sigָ���źţ�privȨ�ޡ�

    // ����ָ��������pgrp�е�ÿ�����̷���ָ���ź�sig��ֻҪ��һ�����̷��ͳɹ����ͻ�

    // ����0���������û���ҵ�ָ���������pgrp���κ�һ�����̣��򷵻س�����-ESRCH����

    // �ҵ����������pgrp�Ľ��̣����Ƿ����ź�ʧ�ܣ��򷵻ط���ʧ�ܵĴ����롣

 26 int kill_pg(int pgrp, int sig, int priv);               // kernel/exit.c��171�С�

    // �ж�һ���������Ƿ��ǹ¶����̡���������򷵻�0��������򷵻�1��

 27 int is_orphaned_pgrp(int pgrp);                         // kernel/exit.c��232�С�

 28

    // ��ȡtermios�ṹ������ģʽ��־��֮һ�����������ж�һ����־���Ƿ�����λ��־��

 29 #define _L_FLAG(tty,f)  ((tty)->termios.c_lflag & f)    // ����ģʽ��־��

 30 #define _I_FLAG(tty,f)  ((tty)->termios.c_iflag & f)    // ����ģʽ��־��

 31 #define _O_FLAG(tty,f)  ((tty)->termios.c_oflag & f)    // ���ģʽ��־��

 32

    // ȡtermios�ṹ�ն����⣨���أ�ģʽ��־���е�һ����־��

 33 #define L_CANON(tty)    _L_FLAG((tty),ICANON)    // ȡ�淶ģʽ��־��

 34 #define L_ISIG(tty)     _L_FLAG((tty),ISIG)      // ȡ�źű�־��

 35 #define L_ECHO(tty)     _L_FLAG((tty),ECHO)      // ȡ�����ַ���־��

 36 #define L_ECHOE(tty)    _L_FLAG((tty),ECHOE)     // �淶ģʽʱȡ���Բ�����־��

 37 #define L_ECHOK(tty)    _L_FLAG((tty),ECHOK)     // �淶ģʽʱȡKILL������ǰ�б�־��

 38 #define L_ECHOCTL(tty)  _L_FLAG((tty),ECHOCTL)   // ȡ���Կ����ַ���־��

 39 #define L_ECHOKE(tty)   _L_FLAG((tty),ECHOKE)    // �淶ģʽʱȡKILL�����в����Ա�־��

 40 #define L_TOSTOP(tty)   _L_FLAG((tty),TOSTOP)    // ���ں�̨�������SIGTTOU�źš�

 41

    // ȡtermios�ṹ����ģʽ��־���е�һ����־��

 42 #define I_UCLC(tty)     _I_FLAG((tty),IUCLC)     // ȡ��д��Сдת����־��

 43 #define I_NLCR(tty)     _I_FLAG((tty),INLCR)     // ȡ���з�NLת�س���CR��־��

 44 #define I_CRNL(tty)     _I_FLAG((tty),ICRNL)     // ȡ�س���CRת���з�NL��־��

 45 #define I_NOCR(tty)     _I_FLAG((tty),IGNCR)     // ȡ���Իس���CR��־��

 46 #define I_IXON(tty)     _I_FLAG((tty),IXON)      // ȡ�����������־XON��

 47

    // ȡtermios�ṹ���ģʽ��־���е�һ����־��

 48 #define O_POST(tty)     _O_FLAG((tty),OPOST)     // ȡִ�����������־��

 49 #define O_NLCR(tty)     _O_FLAG((tty),ONLCR)     // ȡ���з�NLת�س����з�CR-NL��־��

 50 #define O_CRNL(tty)     _O_FLAG((tty),OCRNL)     // ȡ�س���CRת���з�NL��־��

 51 #define O_NLRET(tty)    _O_FLAG((tty),ONLRET)    // ȡ���з�NLִ�лس����ܵı�־��

 52 #define O_LCUC(tty)     _O_FLAG((tty),OLCUC)     // ȡСдת��д�ַ���־��

 53

    // ȡtermios�ṹ���Ʊ�־���в����ʡ�CBAUD�Dz����������루0000017����

 54 #define C_SPEED(tty)    ((tty)->termios.c_cflag & CBAUD)

    // �ж�tty�ն��Ƿ��ѹ��ߣ�hang up�������䴫�䲨�����Ƿ�ΪB0��0����

 55 #define C_HUP(tty)      (C_SPEED((tty)) == B0)

 56

    // ȡ��Сֵ�ꡣ

 57 #ifndef MIN

 58 #define MIN(a,b) ((a) < (b) ? (a) : (b))

 59 #endif

 60

    // ���涨��tty�ն�ʹ�õĻ�����нṹ����tty_queues �� tty�ն˱��ṹ����tty_table��

    // QUEUES��tty�ն�ʹ�õĻ���������������α�ն˷��������֣�master��slave����ÿ��

    // tty�ն�ʹ��3��tty ������У����Ƿֱ������ڻ�����̻�������Ķ����� read_queue��

    // ���ڻ�����Ļ���������д���� write_queue���Լ����ڱ���淶ģʽ�ַ��ĸ����������

    // secondary��

 61 #define QUEUES  (3*(MAX_CONSOLES+NR_SERIALS+2*NR_PTYS))  // ��54�

 62 static struct tty_queue tty_queues[QUEUES];              // tty����������顣

 63 struct tty_struct tty_table[256];                        // tty���ṹ���顣

 64

    // �����趨�������͵�tty�ն���ʹ�û�����нṹ��tty_queues[]�����е���ʼ��λ�á�

    // 8���������̨�ն�ռ��tty_queues[]���鿪ͷ24�3 X MAX_CONSOLES����0 -- 23����

    // ���������ն�ռ������6�3 X NR_SERIALS����24 -- 29����

    // 4����α�ն�ռ������12�3 X NR_PTYS����30 -- 41����

    // 4����α�ն�ռ������12�3 X NR_PTYS����42 -- 53����

 65 #define con_queues tty_queues

 66 #define rs_queues ((3*MAX_CONSOLES) + tty_queues)

 67 #define mpty_queues ((3*(MAX_CONSOLES+NR_SERIALS)) + tty_queues)

 68 #define spty_queues ((3*(MAX_CONSOLES+NR_SERIALS+NR_PTYS)) + tty_queues)

 69

    // �����趨��������tty�ն���ʹ�õ�tty�ṹ��tty_table[]�����е���ʼ��λ�á�

    // 8���������̨�ն˿���tty_table[]���鿪ͷ64�0 -- 63����

    // ���������ն�ʹ������2�64 -- 65����

    // 4����α�ն�ʹ�ô�128��ʼ������64�128 -- 191����

    // 4����α�ն�ʹ�ô�192��ʼ������64�192 -- 255����

 70 #define con_table tty_table                // �������̨�ն�tty�����ų�����

 71 #define rs_table (64+tty_table)            // �����ն�tty����

 72 #define mpty_table (128+tty_table)         // ��α�ն�tty����

 73 #define spty_table (192+tty_table)         // ��α�ն�tty����

 74

 75 int fg_console = 0;              // ��ǰǰ̨����̨�ţ���Χ0--7����

 76

 77 /*

 78  * these are the tables used by the machine code handlers.

 79  * you can implement virtual consoles.

 80  */

    /*

     * �����ǻ�������ʹ�õĻ�����нṹ��ַ����ͨ���޸��������

     * �����ʵ���������̨��

     */

    // tty��д������нṹ��ַ������rs_io.s����ʹ�ã�����ȡ�ö�д������нṹ�ĵ�ַ��

 81 struct tty_queue * table_list[]={

 82         con_queues + 0, con_queues + 1,       // ǰ̨����̨����д���нṹ��ַ��

 83         rs_queues + 0, rs_queues + 1,         // �����ն�1����д���нṹ��ַ��

 84         rs_queues + 3, rs_queues + 4          // �����ն�2����д���нṹ��ַ��

 85         };

 86

    //// �ı�ǰ̨����̨��

    // ��ǰ̨����̨�趨Ϊָ�����������̨��

    // ������new_console - ָ�����¿���̨�š�

 87 void change_console(unsigned int new_console)

 88 {

    // �������ָ���Ŀ���̨�Ѿ���ǰ̨���߲�����Ч�����˳����������õ�ǰǰ̨����̨�ţ�ͬ

    // ʱ����table_list[]�е�ǰ̨����̨����д���нṹ��ַ�������µ�ǰǰ̨����̨��Ļ��

 89         if (new_console == fg_console || new_console >= NR_CONSOLES)

 90                 return;

 91         fg_console = new_console;

 92         table_list[0] = con_queues + 0 + fg_console*3;

 93         table_list[1] = con_queues + 1 + fg_console*3;

 94         update_screen();                    // kernel/chr_drv/console.c��936�С�

 95 }

 96

    //// ������л����������ý��̽�����ж�˯��״̬��

    // ������queue - ָ�����е�ָ�롣

    // ������ȡ���л��������ַ�֮ǰ��Ҫ���ô˺���������֤�������ǰ����û���ź�Ҫ������

    // ����ָ���Ķ��л������գ����ý��̽�����ж�˯��״̬�����ö��еĽ��̵ȴ�ָ��ָ��

    // �ý��̡�

 97 static void sleep_if_empty(struct tty_queue * queue)

 98 {

 99         cli();

100         while (!(current->signal & ~current->blocked) && EMPTY(queue))

101                 interruptible_sleep_on(&queue->proc_list);

102         sti();

103 }

104

    //// �����л����������ý��̽�����жϵ�˯��״̬��

    // ������queue - ָ�����е�ָ�롣

    // �����������л�������д���ַ�֮ǰ��Ҫ���ô˺����ж϶��������

105 static void sleep_if_full(struct tty_queue * queue)

106 {

    // ������л����������򷵻��˳�������������û���ź���Ҫ���������Ҷ��л������п���ʣ

    // �������� < 128�����ý��̽�����ж�˯��״̬�����øö��еĽ��̵ȴ�ָ��ָ��ý��̡�

107         if (!FULL(queue))

108                 return;

109         cli();

110         while (!(current->signal & ~current->blocked) && LEFT(queue)<128)

111                 interruptible_sleep_on(&queue->proc_list);

112         sti();

113 }

114

    //// �ȴ�������

    // ���ǰ̨����̨�����л������գ����ý��̽�����ж�˯��״̬��

115 void wait_for_keypress(void)

116 {

117         sleep_if_empty(tty_table[fg_console].secondary);

118 }

119

    //// ���Ƴɹ淶ģʽ�ַ����С�

    // �����ն�termios�ṹ�����õĸ��ֱ�־����ָ��tty�ն˶����л������е��ַ�����ת��

    // �ɹ淶ģʽ����ģʽ���ַ�������ڸ������У��淶ģʽ���У��С�

    // ������tty - ָ���ն˵�tty�ṹָ�롣

120 void copy_to_cooked(struct tty_struct * tty)

121 {

122         signed char c;

123

    // ���ȼ�鵱ǰ�ն�tty�ṹ�л������ָ���Ƿ���Ч�������������ָ�붼��NULL����˵��

    // �ں�tty��ʼ�����������⡣

124         if (!(tty->read_q || tty->write_q || tty->secondary)) {

125                 printk("copy_to_cooked: missing queues\n\r");

126                 return;

127         }

    // �������Ǹ����ն�termios�ṹ�е�����ͱ��ر�־���Դ�tty�����л�������ȡ����ÿ��

    // �ַ������ʵ��Ĵ�����Ȼ����븨������secondary�С�������ѭ�����У������ʱ������

    // �������Ѿ�ȡ�ջ��߸������л������Ѿ������ַ������˳�ѭ���塣�������ʹӶ����л�

    // ����βָ�봦ȡһ�ַ�������βָ��ǰ��һ���ַ�λ�á�Ȼ����ݸ��ַ�����ֵ���д�����

    // ���⣬���������_POSIX_VDISABLE��\0������ô�ڶ��ַ����������ң����ַ�����ֵ����

    // _POSIX_VDISABLE��ֵʱ����ʾ��ֹʹ����Ӧ��������ַ��Ĺ��ܡ�

128         while (1) {

129                 if (EMPTY(tty->read_q))

130                         break;

131                 if (FULL(tty->secondary))

132                         break;

133                 GETCH(tty->read_q,c);         // ȡһ�ַ���c����ǰ��βָ�롣

    // ������ַ��ǻس���CR��13������ô���س�ת���б�־CRNL��λ�����ַ�ת��Ϊ���з�

    // NL��10��������������Իس���־NOCR��λ������Ը��ַ����������������ַ��������

    // ���ǻ��з�NL��10�������һ���ת�س���־NLCR��λ������ת��Ϊ�س���CR��13����

134                 if (c==13) {

135                         if (I_CRNL(tty))

136                                 c=10;

137                         else if (I_NOCR(tty))

138                                 continue;

139                 } else if (c==10 && I_NLCR(tty))

140                         c=13;

    // �����дתСд�����־UCLC��λ���򽫸��ַ�ת��ΪСд�ַ���

141                 if (I_UCLC(tty))

142                         c=tolower(c);

    // �������ģʽ��־���й淶ģʽ��־CANON ����λ����Զ�ȡ���ַ��������´����� ���ȣ�

    // ������ַ��Ǽ�����ֹ�����ַ�KILL(^U)�����������ĵ�ǰ��ִ��ɾ��������ɾ��һ����

    // ����ѭ���������ǣ���� tty�������в��գ�����ȡ���ĸ������������һ���ַ����ǻ���

    // ��NL��10�������Ҹ��ַ������ļ������ַ���^D������ѭ��ִ�����д��룺

    // ������ػ��Ա�־ECHO ��λ����ô�����ַ��ǿ����ַ���ֵ < 32��������ttyд�����з�

    // ����������ַ�ERASE��^H����Ȼ���ٷ���һ�������ַ�ERASE�����ҵ��ø�ttyд��������

    // д�����е������ַ�������ն���Ļ�ϡ� ���⣬��Ϊ�����ַ��ڷ���д����ʱ��Ҫ��2����

    // �ڱ�ʾ������^V�������Ҫ���ر�Կ����ַ������һ��ERASE�����tty��������ͷָ��

    // ����1�ֽڡ����⣬���������_POSIX_VDISABLE��\0������ô�ڶ��ַ����������ң����ַ�

    // ����ֵ���� _POSIX_VDISABLE��ֵʱ����ʾ��ֹʹ����Ӧ��������ַ��Ĺ��ܡ�

143                 if (L_CANON(tty)) {

144                         if ((KILL_CHAR(tty) != _POSIX_VDISABLE) &&

145                             (c==KILL_CHAR(tty))) {

146                                 /* deal with killing the input line */

147                                 while(!(EMPTY(tty->secondary) ||

148                                         (c=LAST(tty->secondary))==10 ||

149                                         ((EOF_CHAR(tty) != _POSIX_VDISABLE) &&

150                                          (c==EOF_CHAR(tty))))) {

151                                         if (L_ECHO(tty)) {   // �����ػ��Ա�־��λ��

152                                                 if (c<32)    // �����ַ�Ҫɾ2�ֽڡ�

153                                                         PUTCH(127,tty->write_q);

154                                                 PUTCH(127,tty->write_q);

155                                                 tty->write(tty);

156                                         }

157                                         DEC(tty->secondary->head);

158                                 }

159                                 continue;         // ������ȡ���������ַ����д�����

160                         }

    // ������ַ���ɾ�������ַ�ERASE��^H������ô�����tty�ĸ�������Ϊ�գ����������һ��

    // �ַ��ǻ��з�NL(10)���������ļ�����������������������ַ���������ػ��Ա�־ECHO��

    // λ����ô�����ַ��ǿ����ַ���ֵ< 32��������tty��д�����з�������ַ�ERASE���ٷ���

    // һ�������ַ�ERASE�����ҵ��ø�tty��д���������tty��������ͷָ�����1�ֽڣ���

    // �����������ַ���ͬ���أ����������_POSIX_VDISABLE��\0������ô�ڶ��ַ����������ң�

    // ���ַ�����ֵ���� _POSIX_VDISABLE ��ֵʱ����ʾ��ֹʹ����Ӧ��������ַ��Ĺ��ܡ�

161                         if ((ERASE_CHAR(tty) != _POSIX_VDISABLE) &&

162                             (c==ERASE_CHAR(tty))) {

163                                 if (EMPTY(tty->secondary) ||

164                                    (c=LAST(tty->secondary))==10 ||

165                                    ((EOF_CHAR(tty) != _POSIX_VDISABLE) &&

166                                     (c==EOF_CHAR(tty))))

167                                         continue;

168                                 if (L_ECHO(tty)) {          // �����ػ��Ա�־��λ��

169                                         if (c<32)

170                                                 PUTCH(127,tty->write_q);

171                                         PUTCH(127,tty->write_q);

172                                         tty->write(tty);

173                                 }

174                                 DEC(tty->secondary->head);

175                                 continue;

176                         }

177                 }

    // ���������IXON��־����ʹ�ն�ֹͣ/��ʼ��������ַ������á����û�����ô˱�־����

    // ôֹͣ�Ϳ�ʼ�ַ�������Ϊһ���ַ������̶�ȡ������δ����У������ȡ���ַ���ֹͣ��

    // ��STOP��^S��������tty ֹͣ��־����tty ��ͣ�����ͬʱ��������������ַ���������

    // ���������У������������������ַ�������ַ��ǿ�ʼ�ַ�START��^Q������λttyֹͣ

    // ��־���ָ�tty�����ͬʱ�����ÿ����ַ������������������ַ���

    // ���ڿ���̨��˵�������tty->write()��console.c�е�con_write()��������˿���̨��

    // ���ڷ���stopped=1����������ͣ����Ļ����ʾ���ַ���chr_drv/console.c����586�У���

    // ����α�ն�Ҳ�������������ն�stopped��־������ͣд������chr_drv/pty.c����24�У���

    // ���ڴ����նˣ�ҲӦ���ڷ����ն˹����и����ն�stopped��־��ͣ���ͣ�������δʵ�֡�

178                 if (I_IXON(tty)) {

179                         if ((STOP_CHAR(tty) != _POSIX_VDISABLE) &&

180                             (c==STOP_CHAR(tty))) {

181                                 tty->stopped=1;

182                                 tty->write(tty);

183                                 continue;

184                         }

185                         if ((START_CHAR(tty) != _POSIX_VDISABLE) &&

186                             (c==START_CHAR(tty))) {

187                                 tty->stopped=0;

188                                 tty->write(tty);

189                                 continue;

190                         }

191                 }

    // ������ģʽ��־����ISIG��־��λ����ʾ�ն˼��̿��Բ����źţ������յ������ַ�INTR��

    // QUIT��SUSP �� DSUSP ʱ����ҪΪ���̲�����Ӧ���źš� ������ַ��Ǽ����жϷ���^C����

    // ����ǰ����֮�����������н��̷��ͼ����ж��ź�SIGINT��������������һ�ַ��� �����

    // �ַ����˳�����^\��������ǰ����֮�����������н��̷��ͼ����˳��ź�SIGQUIT��������

    // ������һ�ַ�������ַ�����ͣ����^Z��������ǰ���̷�����ͣ�ź�SIGTSTP��ͬ��������

    // ����_POSIX_VDISABLE��\0������ô�ڶ��ַ����������ң����ַ�����ֵ����_POSIX_VDISABLE

    // ��ֵʱ����ʾ��ֹʹ����Ӧ��������ַ��Ĺ��ܡ����²��ن����� :-)

192                 if (L_ISIG(tty)) {

193                         if ((INTR_CHAR(tty) != _POSIX_VDISABLE) &&

194                             (c==INTR_CHAR(tty))) {

195                                 kill_pg(tty->pgrp, SIGINT, 1);

196                                 continue;

197                         }

198                         if ((QUIT_CHAR(tty) != _POSIX_VDISABLE) &&

199                             (c==QUIT_CHAR(tty))) {

200                                 kill_pg(tty->pgrp, SIGQUIT, 1);

201                                 continue;

202                         }

203                         if ((SUSPEND_CHAR(tty) != _POSIX_VDISABLE) &&

204                             (c==SUSPEND_CHAR(tty))) {

205                                 if (!is_orphaned_pgrp(tty->pgrp))

206                                         kill_pg(tty->pgrp, SIGTSTP, 1);

207                                 continue;

208                         }

209                 }

    // ������ַ��ǻ��з�NL��10�����������ļ�������EOF��4��^D������ʾһ���ַ��Ѵ����꣬

    // ��Ѹ�����������е�ǰ�����ַ�����ֵsecondary.data��1������ں���tty_read()��ȡ

    // ��һ���ַ�����ֵ���ᱻ��1���μ�315�С�

210                 if (c==10 || (EOF_CHAR(tty) != _POSIX_VDISABLE &&

211                               c==EOF_CHAR(tty)))

212                         tty->secondary->data++;

    // �������ģʽ��־���л��Ա�־ECHO����λ״̬����ô������ַ��ǻ��з�NL��10������

    // ���з�NL��10���ͻس���CR��13������ttyд���л������У�����ַ��ǿ����ַ���ֵ<32��

    // ���һ��Կ����ַ���־ECHOCTL��λ�����ַ�'^'���ַ� c+64 ����ttyд�����У�Ҳ����

    // ��ʾ^C��^H��)�����򽫸��ַ�ֱ�ӷ���ttyд��������С������ø�ttyд����������

213                 if (L_ECHO(tty)) {

214                         if (c==10) {

215                                 PUTCH(10,tty->write_q);

216                                 PUTCH(13,tty->write_q);

217                         } else if (c<32) {

218                                 if (L_ECHOCTL(tty)) {

219                                         PUTCH('^',tty->write_q);

220                                         PUTCH(c+64,tty->write_q);

221                                 }

222                         } else

223                                 PUTCH(c,tty->write_q);

224                         tty->write(tty);

225                 }

    // ÿһ��ѭ��ĩ�����������ַ����븨�������С�

226                 PUTCH(c,tty->secondary);

227         }

    // ������˳�ѭ������ѵȴ��ø���������еĽ��̣�����еĻ�����

228         wake_up(&tty->secondary->proc_list);

229 }

230

231 /*

232  * Called when we need to send a SIGTTIN or SIGTTOU to our process

233  * group

234  *

235  * We only request that a system call be restarted if there was if the

236  * default signal handler is being used.  The reason for this is that if

237  * a job is catching SIGTTIN or SIGTTOU, the signal handler may not want

238  * the system call to be restarted blindly.  If there is no way to reset the

239  * terminal pgrp back to the current pgrp (perhaps because the controlling

240  * tty has been released on logout), we don't want to be in an infinite loop

241  * while restarting the system call, and have it always generate a SIGTTIN

242  * or SIGTTOU.  The default signal handler will cause the process to stop

243  * thus avoiding the infinite loop problem.  Presumably the job-control

244  * cognizant parent will fix things up before continuging its child process.

245  */

    /* ����Ҫ�����ź�SIGTTIN �� SIGTTOU �����ǽ����������н���ʱ�ͻ���øú�����

     *

     * �ڽ���ʹ��Ĭ���źŴ����������£����ǽ�Ҫ��һ��ϵͳ���ñ��������������

     * ��ϵͳ�������źŶ����жϡ���������ԭ���ǣ����һ����ҵ���ڲ���SIGTTIN

     * �� SIGTTOU�źţ���ô��Ӧ�źž��������ϣ��ϵͳ���ñ�äĿ���������������

     * û�������������ն˵�pgrp��λ����ǰpgrp���������������logoutʱ�����ն�

     * �ѱ��ͷţ�����ô���Dz���ϣ������������ϵͳ����ʱ����һ������ѭ���У�����

     * ���Dz��� SIGTTIN �� SIGTTOU �źš�Ĭ�ϵ��źž����ʹ�ý���ֹͣ���������

     * ��������ѭ�����⡣��������ʶ����ҵ���Ƶĸ����̻��ڼ���ִ�����ӽ���֮ǰ

     * ������㶨��

     */

    //// ��ʹ���ն˵Ľ����������н��̷����źš�

    // �ں�̨�������е�һ�����̷��ʿ����ն�ʱ���ú����������̨�������е����н��̷���

    // SIGTTIN��SIGTTOU�źš����ۺ�̨�������еĽ����Ƿ��Ѿ���������Ե����������źţ�

    // ��ǰ���̶��������˳���д���������ء�

246 int tty_signal(int sig, struct tty_struct *tty)

247 {

    // ���Dz�ϣ��ֹͣһ���¶��������еĽ��̣��μ��ļ�kernel/exit.c�е�232���ϵ�˵������

    // ��������ǰ�������ǹ¶������飬�ͳ������ء��������ǰ���������н��̷���ָ����

    // ��sig��

248         if (is_orphaned_pgrp(current->pgrp))

249                 return -EIO;            /* don't stop an orphaned pgrp */

250         (void) kill_pg(current->pgrp,sig,1);    // �����ź�sig��

    // �������źű���ǰ�������������Σ������߱���ǰ���̺��Ե�����������ء��������

    // ��ǰ���̶��ź�sig�������µĴ����������ô�ͷ������ǿɱ��жϵ���Ϣ������ͷ�����

    // ϵͳ����������������Լ���ִ�е���Ϣ��

251         if ((current->blocked & (1<<(sig-1))) ||

252             ((int) current->sigaction[sig-1].sa_handler == 1))

253                 return -EIO;            /* Our signal will be ignored */

254         else if (current->sigaction[sig-1].sa_handler)

255                 return -EINTR;          /* We _will_ be interrupted :-) */

256         else

257                 return -ERESTARTSYS;    /* We _will_ be interrupted :-) */

258                                         /* (but restart after we continue) */

259 }

260

    //// tty��������

    // ���ն˸�����������ж�ȡָ���������ַ����ŵ��û�ָ���Ļ������С�

    // ������channel - ���豸�ţ�buf �C �û�������ָ�룻nr - �����ֽ�����

    // �����Ѷ��ֽ�����

261 int tty_read(unsigned channel, char * buf, int nr)

262 {

263         struct tty_struct * tty;

264         struct tty_struct * other_tty = NULL;

265         char c, * b=buf;

266         int minimum,time;

267

    // �����жϲ�����Ч�Բ�ȡ�ն˵�tty�ṹָ�롣���tty�ն˵������������ָ�붼��NULL��

    // �򷵻�EIO������Ϣ�����tty�ն���һ��α�նˣ�����ȡ����һ����Ӧα�ն˵�tty�ṹ

    // other_tty��

268         if (channel > 255)

269                 return -EIO;

270         tty = TTY_TABLE(channel);

271         if (!(tty->write_q || tty->read_q || tty->secondary))

272                 return -EIO;

    // �����ǰ����ʹ�õ����������ڴ�����tty�նˣ������ն˵Ľ������ȴ�뵱ǰ������Ų�

    // ͬ����ʾ��ǰ�����Ǻ�̨�������е�һ�����̣������̲���ǰ̨����������Ҫֹͣ��ǰ����

    // ������н��̡�����������Ҫ��ǰ�����鷢��SIGTTIN�źţ������صȴ���Ϊǰ̨����

    // �����ִ�ж�������

273         if ((current->tty == channel) && (tty->pgrp != current->pgrp))

274                 return(tty_signal(SIGTTIN, tty));

    // �����ǰ�ն���α�նˣ���ô��Ӧ����һ��α�ն˾���other_tty��������tty����α�նˣ�

    // ��ôother_tty���Ƕ�Ӧ�Ĵ�α�նˣ���֮ҲȻ��

275         if (channel & 0x80)

276                 other_tty = tty_table + (channel ^ 0x40);

 

    // Ȼ����� VTIME ��VMIN ��Ӧ�Ŀ����ַ�����ֵ���ö��ַ�������ʱ��ʱֵtime��������

    // Ҫ��ȡ���ַ�����minimum���ڷǹ淶ģʽ�£��������dz�ʱ��ʱֵ��VMIN��ʾΪ�������

    // ��������Ҫ��ȡ�������ַ�������VTIME��һ��1/10�������ʱֵ��

277         time = 10L*tty->termios.c_cc[VTIME];       // ���ö�������ʱ��ʱֵ��

278         minimum = tty->termios.c_cc[VMIN];         // ������Ҫ��ȡ���ַ�������

    // ���tty�ն˴��ڹ淶ģʽ����������СҪ��ȡ�ַ���minimum ���ڽ��������ַ���nr��ͬ

    // ʱ�ѽ��̶�ȡnr�ַ��ij�ʱʱ��ֵ����Ϊ����ֵ�����ᳬʱ��������˵���ն˴��ڷǹ淶ģ

    // ʽ�£�����ʱ���������ٶ�ȡ�ַ���minimum��������ʱ���ý��Ƕ���ʱ��ʱֵΪ���޴���

    // �ý����ȶ�ȡ���������������ַ�������������ַ������� minimum �Ļ��������������

    // ָ���ij�ʱֵtime �����ý��̵Ķ���ʱֵ timeout������ȴ���ȡ�����ַ����μ�328�С�

    // ����ʱû���������ٶ�ȡ�ַ���minimum��Ϊ0������������Ϊ���������ַ���nr��������

    // �������˳�ʱ��ʱֵtime�Ļ����Ͱѽ��̶��ַ���ʱ��ʱֵtimeout����Ϊϵͳ��ǰʱ��ֵ

    //  + ָ���ij�ʱֵtime��ͬʱ��λtime�� ���⣬����������õ����ٶ�ȡ�ַ���minimum��

    // �ڽ�������ȡ���ַ���nr������minimum=nr�������ڹ淶ģʽ�µĶ�ȡ������������VTIME

    // ��VMIN��Ӧ�����ַ�ֵ��Լ���Ϳ��ƣ����ǽ��ڷǹ淶ģʽ����ģʽ�������������á�

279         if (L_CANON(tty)) {

280                 minimum = nr;

281                 current->timeout = 0xffffffff;

282                 time = 0;

283         } else if (minimum)

284                 current->timeout = 0xffffffff;

285         else {

286                 minimum = nr;

287                 if (time)

288                         current->timeout = time + jiffies;

289                 time = 0;

290         }

291         if (minimum>nr)

292                 minimum = nr;                   // ����ȡҪ����ַ�����

 

    // �������ǿ�ʼ�Ӹ���������ѭ��ȡ���ַ����ŵ��û�������buf �С����������ֽ�������0��

    // ��ִ������ѭ����������ѭ�������У������ǰ�ն���α�նˣ���ô���Ǿ�ִ�����Ӧ����

    // һ��α�ն˵�д��������������һ��α�ն˰��ַ�д�뵱ǰα�ն˸������л������С�����

    // ��һ�ն˰�д���л��������ַ����Ƶ���ǰα�ն˶����л������У������й�̺���ת����

    // ���뵱ǰα�ն˸��������С�

293         while (nr>0) {

294                 if (other_tty)

295                         other_tty->write(other_tty);

    // ���tty�����������Ϊ�գ����������˹淶ģʽ��־����tty�����л�����δ�������Ҹ�

    // ���������ַ�����Ϊ0����ô�����û�����ù����̶��ַ���ʱֵ��Ϊ0�������ߵ�ǰ����

    // Ŀǰ�յ��źţ������˳�ѭ���塣����������ն���һ����α�նˣ��������Ӧ����α�ն�

    // �Ѿ��Ҷϣ���ô����Ҳ�˳�ѭ���塣�������������������������Ǿ��õ�ǰ���̽������

    // ��˯��״̬�����غ�������������ڹ淶ģʽʱ�ں�����Ϊ��λΪ�û��ṩ���ݣ�����ڸ�

    // ģʽ�¸��������б���������һ���ַ��ɹ�ȡ�ã���secondary.data������1���С�

296                 cli();

297                 if (EMPTY(tty->secondary) || (L_CANON(tty) &&

298                     !FULL(tty->read_q) && !tty->secondary->data)) {

299                         if (!current->timeout ||

300                           (current->signal & ~current->blocked)) {

301                                 sti();

302                                 break;

303                         }

304                         if (IS_A_PTY_SLAVE(channel) && C_HUP(other_tty))

305                                 break;

306                         interruptible_sleep_on(&tty->secondary->proc_list);

307                         sti();

308                         continue;

309                 }

310                 sti();

    // ���濪ʼ��ʽִ��ȡ�ַ�����������ַ���nr���εݼ���ֱ��nr=0���߸����������Ϊ�ա�

    // �����ѭ�������У�����ȡ������������ַ�c�����Ұѻ������βָ��tail�����ƶ�һ��

    // �ַ�λ�á������ȡ�ַ����ļ���������^D�������ǻ��з�NL��10������Ѹ������������

    // �����ַ�����ֵ��1�� ������ַ����ļ���������^D�����ҹ淶ģʽ��־����λ״̬������

    // �ϱ�ѭ��������˵�����ڻ�û�������ļ�����������������ԭʼ���ǹ淶��ģʽ��������ģ

    // ʽ���û����ַ�����Ϊ��ȡ����Ҳ��ʶ�����еĿ����ַ������ļ��������������ǽ��ַ�

    // ֱ�ӷ����û����ݻ����� buf�У����������ַ�����1����ʱ��������ַ�����Ϊ0���ж�

    // ѭ�������⣬����ն˴��ڹ淶ģʽ���Ҷ�ȡ���ַ��ǻ��з�NL��10������Ҳ�˳�ѭ����

    // ����֮�⣬ֻҪ��û��ȡ�������ַ���nr���Ҹ������в��գ��ͼ���ȡ�����е��ַ���

311                 do {

312                         GETCH(tty->secondary,c);

313                         if ((EOF_CHAR(tty) != _POSIX_VDISABLE &&

314                              c==EOF_CHAR(tty)) || c==10)

315                                 tty->secondary->data--;

316                         if ((EOF_CHAR(tty) != _POSIX_VDISABLE &&

317                              c==EOF_CHAR(tty)) && L_CANON(tty))

318                                 break;

319                         else {

320                                 put_fs_byte(c,b++);

321                                 if (!--nr)

322                                         break;

323                         }

324                         if (c==10 && L_CANON(tty))

325                                 break;

326                 } while (nr>0 && !EMPTY(tty->secondary));

    // ִ�е��ˣ���ô��� tty �ն˴��ڹ淶ģʽ�£�˵�����ǿ��ܶ����˻��з������������ļ�

    // ������������Ǵ��ڷǹ淶ģʽ�£���ô˵�������Ѿ���ȡ��nr���ַ������߸��������Ѿ�

    // ��ȡ���ˡ������������Ȼ��ѵȴ������еĽ��̣�Ȼ�󿴿��Ƿ����ù���ʱ��ʱֵtime����

    // ����ʱ��ʱֵtime��Ϊ0�����Ǿ�Ҫ��ȴ�һ����ʱ�����������̿��԰��ַ�д��������С�

    // �������ý��̶���ʱ��ʱֵΪϵͳ��ǰʱ��jiffies + ����ʱֵtime����Ȼ������ն˴���

    // �淶ģʽ�������Ѿ���ȡ��nr���ַ������ǾͿ���ֱ���˳������ѭ���ˡ�

327                 wake_up(&tty->read_q->proc_list);

328                 if (time)

329                         current->timeout = time+jiffies;

330                 if (L_CANON(tty) || b-buf >= minimum)

331                         break;

332         }

    // ��ʱ��ȡtty�ַ�ѭ��������������˸�λ���̵Ķ�ȡ��ʱ��ʱֵtimeout�������ʱ��ǰ��

    // �����յ��źŲ��һ�û�ж�ȡ���κ��ַ���������������ϵͳ���úŷ��ء�����ͷ����Ѷ�ȡ

    // ���ַ���(b-buf)��

333         current->timeout = 0;

334         if ((current->signal & ~current->blocked) && !(b-buf))

335                 return -ERESTARTSYS;

336         return (b-buf);

337 }

338

    //// ttyд������

    // ���û��������е��ַ�����ttyд���л������С�

    // ������channel - ���豸�ţ�buf - ������ָ�룻nr - д�ֽ�����

    // ������д�ֽ�����

339 int tty_write(unsigned channel, char * buf, int nr)

340 {

341         static cr_flag=0;

342         struct tty_struct * tty;

343         char c, *b=buf;

344

    // �����жϲ�����Ч�Բ�ȡ�ն˵�tty�ṹָ�롣���tty�ն˵������������ָ�붼��NULL��

    // �򷵻�EIO������Ϣ��

345         if (channel > 255)

346                 return -EIO;

347         tty = TTY_TABLE(channel);

348         if (!(tty->write_q || tty->read_q || tty->secondary))

349                 return -EIO;

    // ������ն˱���ģʽ��־����������TOSTOP����ʾ��̨�������ʱ��Ҫ�����ź�SIGTTOU��

    // �����ǰ����ʹ�õ����������ڴ�����tty�նˣ������ն˵Ľ������ȴ�뵱ǰ������Ų�

    // ͬ������ʾ��ǰ�����Ǻ�̨�������е�һ�����̣������̲���ǰ̨����������Ҫֹͣ��ǰ��

    // ��������н��̡�����������Ҫ��ǰ�����鷢��SIGTTOU�źţ������صȴ���Ϊǰ̨��

    // �������ִ��д������

350         if (L_TOSTOP(tty) &&

351             (current->tty == channel) && (tty->pgrp != current->pgrp))

352                 return(tty_signal(SIGTTOU, tty));

    // �������ǿ�ʼ���û�������buf��ѭ��ȡ���ַ����ŵ�д���л������С�����д�ֽ�������0��

    // ��ִ������ѭ����������ѭ�������У������ʱttyд������������ǰ���̽�����жϵ�˯

    // ��״̬�������ǰ�������ź�Ҫ���������˳�ѭ���塣

353         while (nr>0) {

354                 sleep_if_full(tty->write_q);

355                 if (current->signal & ~current->blocked)

356                         break;

    // ��Ҫд���ַ���nr������0����ttyд���л�������������ѭ��ִ�����²��������ȴ��û�

    // ��������ȡ1�ֽڡ�����ն����ģʽ��־���е�ִ�����������־ OPOST ��λ����ִ�ж�

    // �ַ��ĺ���������

357                 while (nr>0 && !FULL(tty->write_q)) {

358                         c=get_fs_byte(b);

359                         if (O_POST(tty)) {

    // ������ַ��ǻس���'\r'��CR��13�����һس���ת���з���־OCRNL��λ���򽫸��ַ�����

    // ���з�'\n'��NL��10��������������ַ��ǻ��з�'\n'��NL��10�����һ���ת�س����ܱ�־

    // ONLRET��λ�Ļ����򽫸��ַ����ɻس���'\r'��CR��13����

360                                 if (c=='\r' && O_CRNL(tty))

361                                         c='\n';

362                                 else if (c=='\n' && O_NLRET(tty))

363                                         c='\r';

    // ������ַ��ǻ��з�'\n' ���һس���־cr_flagû����λ��������ת�س�-���б�־ONLCR

    // ��λ�Ļ�����cr_flag��־��λ������һ�س�������д�����С�Ȼ�����������һ���ַ���

    // ���Сдת��д��־OLCUC��λ�Ļ����ͽ����ַ�ת�ɴ�д�ַ���

364                                 if (c=='\n' && !cr_flag && O_NLCR(tty)) {

365                                         cr_flag = 1;

366                                         PUTCH(13,tty->write_q);

367                                         continue;

368                                 }

369                                 if (O_LCUC(tty))              // Сдת�ɴ�д�ַ���

370                                         c=toupper(c);

371                         }

    // ���Ű��û����ݻ���ָ��bǰ��1�ֽڣ���д�ֽ�����1�ֽڣ���λcr_flag��־��������

    // �ֽڷ���ttyд�����С�

372                         b++; nr--;

373                         cr_flag = 0;

374                         PUTCH(c,tty->write_q);

375                 }

    // ��Ҫ����ַ�ȫ��д�꣬����д����������������˳�ѭ������ʱ����ö�Ӧttyд������

    // ��д���л������е��ַ���ʾ�ڿ���̨��Ļ�ϣ�����ͨ�����ж˿ڷ��ͳ�ȥ�������ǰ��

    // ����tty�ǿ���̨�նˣ���ôtty->write()���õ���con_write()�����tty�Ǵ����նˣ�

    // ��tty->write()���õ���rs_write()�������������ֽ�Ҫд����ȴ�д�������ַ�ȡ�ߡ�

    // ����������õ��ȳ�����ȥִ����������

376                 tty->write(tty);

377                 if (nr>0)

378                         schedule();

379         }

380         return (b-buf);                 // ��󷵻�д����ֽ�����

381 }

382

383 /*

384  * Jeh, sometimes I really like the 386.

385  * This routine is called from an interrupt,

386  * and there should be absolutely no problem

387  * with sleeping even in an interrupt (I hope).

388  * Of course, if somebody proves me wrong, I'll

389  * hate intel for all time :-). We'll have to

390  * be careful and see to reinstating the interrupt

391  * chips before calling this, though.

392  *

393  * I don't think we sleep here under normal circumstances

394  * anyway, which is good, as the task sleeping might be

395  * totally innocent.

396  */

    /*

     * �ǣ���ʱ����ú�ϲ��386�����ӳ��򱻴�һ���жϴ���������

     * ���ã����Ҽ�ʹ���жϴ���������˯��ҲӦ�þ���û�����⣨��

     * ϣ����ˣ�����Ȼ���������֤�����Ǵ��ģ���ô�ҽ�����intel

     * һ����J���������DZ���С�ģ��ڵ��ø��ӳ���֮ǰ��Ҫ�ָ��жϡ�

     *

     * �Ҳ���Ϊ��ͨ�������»ᴦ������˯�ߣ������ܺã���Ϊ����˯��

     * ����ȫ����ġ�

     */

    //// tty�жϴ������ú��� - �ַ��淶ģʽ������

    // ������tty - ָ����tty�ն˺š�

    // ��ָ��tty�ն˶��л������е��ַ����ƻ�ת���ɹ淶(��)ģʽ�ַ�������ڸ��������С�

    // �ú������ڴ��ڶ��ַ��жϣ�rs_io.s��109���ͼ����жϣ�kerboard.S��69���б����á�

397 void do_tty_interrupt(int tty)

398 {

399         copy_to_cooked(TTY_TABLE(tty));

400 }

401

    //// �ַ��豸��ʼ���������գ�Ϊ�Ժ���չ��׼����

402 void chr_dev_init(void)

403 {

404 }

405

    //// tty�ն˳�ʼ��������

    // ��ʼ�������ն˻�����У���ʼ�������ն˺Ϳ���̨�նˡ�

406 void tty_init(void)

407 {

408         int i;

409

    // ���ȳ�ʼ�������ն˵Ļ�����нṹ�����ó�ֵ�����ڴ����ն˵Ķ�/д������У������ǵ�

    // data�ֶ�����Ϊ���ж˿ڻ���ֵַ������1��0x3f8������2��0x2f8��Ȼ���ȳ�����������

    // �ն˵�tty�ṹ�����������ַ�����c_cc[]���õij�ֵ������include/linux/tty.h�ļ��С�

410         for (i=0 ; i < QUEUES ; i++)

411                 tty_queues[i] = (struct tty_queue) {0,0,0,0,""};

412         rs_queues[0] = (struct tty_queue) {0x3f8,0,0,0,""};

413         rs_queues[1] = (struct tty_queue) {0x3f8,0,0,0,""};

414         rs_queues[3] = (struct tty_queue) {0x2f8,0,0,0,""};

415         rs_queues[4] = (struct tty_queue) {0x2f8,0,0,0,""};

416         for (i=0 ; i<256 ; i++) {

417                 tty_table[i] =  (struct tty_struct) {

418                         {0, 0, 0, 0, 0, INIT_C_CC},

419                         0, 0, 0, NULL, NULL, NULL, NULL

420                 };

421         }

    // ���ų�ʼ������̨�նˣ�console.c��834�У����� con_init()�����������Ϊ������Ҫ��

    // ����ʾ�����ͺ���ʾ�ڴ�������ȷ��ϵͳ���������̨������NR_CONSOLES����ֵ���������

    // �Ŀ���̨tty �ṹ��ʼ��ѭ���С����ڿ���̨��tty �ṹ��425--430����tty�ṹ�а�����

    // termios�ṹ�ֶΡ���������ģʽ��־������ʼ��ΪICRNL��־�����ģʽ��־����ʼ��Ϊ��

    // �к�����־OPOST�Ͱ�NLת����CRNL�ı�־ONLCR������ģʽ��־������ʼ������IXON��

    // ICANON��ECHO��ECHOCTL��ECHOKE��־�������ַ�����c_cc[]�����ú��г�ʼֵINIT_C_CC��

    // 435���ϳ�ʼ������̨�ն�tty�ṹ�еĶ����塢д����͸���������нṹ�����Ƿֱ�ָ��

    // tty ������нṹ����tty_table[]�е���Ӧ�ṹ��μ�61--73���ϵ����˵����

422         con_init();

423         for (i = 0 ; i<NR_CONSOLES ; i++) {

424                 con_table[i] = (struct tty_struct) {

425                         {ICRNL,       /* change incoming CR to NL */   /* CRתNL */

426                         OPOST|ONLCR,  /* change outgoing NL to CRNL */ /*NLתCRNL*/

427                         0,                                    // ����ģʽ��־����

428                         IXON | ISIG | ICANON | ECHO | ECHOCTL | ECHOKE, // ���ر�־����

429                         0,            /* console termio */    // ��·��̣�0 -- TTY��

430                         INIT_C_CC},                           // �����ַ�����c_cc[]��

431                         0,            /* initial pgrp */      // ������ʼ������pgrp��

432                         0,            /* initial session */   // ��ʼ�Ự��session��

433                         0,            /* initial stopped */   // ��ʼֹͣ��־stopped��

434                         con_write,                            // ����̨д������

435                         con_queues+0+i*3,con_queues+1+i*3,con_queues+2+i*3

436                 };

437         }

    // Ȼ���ʼ�������ն˵�tty�ṹ���ֶΡ�450�г�ʼ�������ն�tty �ṹ�еĶ�/д�͸�����

    // ����нṹ�����Ƿֱ�ָ��tty ������нṹ����tty_table[]�е���Ӧ�ṹ��μ�61--

    // 73���ϵ����˵����

438         for (i = 0 ; i<NR_SERIALS ; i++) {

439                 rs_table[i] = (struct tty_struct) {

440                         {0, /* no translation */   // ����ģʽ��־����0������ת����

441                         0,  /* no translation */   // ���ģʽ��־����0������ת����

442                         B2400 | CS8,        // ����ģʽ��־����2400bps��8λ����λ��

443                         0,                         // ����ģʽ��־����

444                         0,                         // ��·��̣�0 -- TTY��

445                         INIT_C_CC},                // �����ַ����顣

446                         0,                         // ������ʼ�����顣

447                         0,                         // ��ʼ�Ự�顣

448                         0,                         // ��ʼֹͣ��־��

449                         rs_write,                  // �����ն�д������

450                         rs_queues+0+i*3,rs_queues+1+i*3,rs_queues+2+i*3  // �������С�

451                 };

452         }

    // Ȼ���ٳ�ʼ��α�ն�ʹ�õ�tty�ṹ��α�ն������ʹ�õģ���һ������master��α�ն���

    // ��һ���ӣ�slave��α�նˡ���˶����Ƕ�Ҫ���г�ʼ�����á���ѭ���У��������ȳ�ʼ��

    // ÿ����α�ն˵�tty�ṹ��Ȼ���ٳ�ʼ�����Ӧ�Ĵ�α�ն˵�tty�ṹ��

453         for (i = 0 ; i<NR_PTYS ; i++) {

454                 mpty_table[i] = (struct tty_struct) {

455                         {0, /* no translation */   // ����ģʽ��־����0������ת����

456                         0,  /* no translation */   // ���ģʽ��־����0������ת����

457                         B9600 | CS8,       // ����ģʽ��־����9600bps��8λ����λ��

458                         0,                         // ����ģʽ��־����

459                         0,                         // ��·��̣�0 -- TTY��

460                         INIT_C_CC},                // �����ַ����顣

461                         0,                         // ������ʼ�����顣

462                         0,                         // ������ʼ�Ự�顣

463                         0,                         // ��ʼֹͣ��־��

464                         mpty_write,                // ��α�ն�д������

465                         mpty_queues+0+i*3,mpty_queues+1+i*3,mpty_queues+2+i*3

466                 };

467                 spty_table[i] = (struct tty_struct) {

468                         {0, /* no translation */   // ����ģʽ��־����0������ת����

469                         0,  /* no translation */   // ���ģʽ��־����0������ת����

470                         B9600 | CS8,       // ����ģʽ��־����9600bps��8λ����λ��

471                         IXON | ISIG | ICANON,      // ����ģʽ��־����

472                         0,                         // ��·��̣�0 -- TTY��

473                         INIT_C_CC},                // �����ַ����顣

474                         0,                         // ������ʼ�����顣

475                         0,                         // ������ʼ�Ự�顣

476                         0,                         // ��ʼֹͣ��־��

477                         spty_write,                // ��α�ն�д������

478                         spty_queues+0+i*3,spty_queues+1+i*3,spty_queues+2+i*3

479                 };

480         }

    // ����ʼ�������жϴ�������ʹ��нӿ�1��2��serial.c��37�У�������ʾϵͳ���е�����

    // ����̨��NR_CONSOLES ��α�ն���NR_PTYS��

481         rs_init();

482         printk("%d virtual consoles\n\r",NR_CONSOLES);

483         printk("%d pty's\n\r",NR_PTYS);

484 }

485


 


 

10.6 ����10-6 linux/kernel/chr_drv/tty_ioctl.c


  1 /*

  2  *  linux/kernel/chr_drv/tty_ioctl.c

  3  *

  4  *  (C) 1991  Linus Torvalds

  5  */

  6

  7 #include <errno.h>        // �����ͷ�ļ�������ϵͳ�и��ֳ����š�

  8 #include <termios.h>      // �ն������������ͷ�ļ�����Ҫ��������첽ͨ�ſڵ��ն˽ӿڡ�

  9

 10 #include <linux/sched.h>  // ���ȳ���ͷ�ļ�����������ṹtask_struct������0�����ݵȡ�

 11 #include <linux/kernel.h> // �ں�ͷ�ļ�������һЩ�ں˳��ú�����ԭ�ζ��塣

 12 #include <linux/tty.h>    // ttyͷ�ļ��������й�tty_io������ͨ�ŷ��������������

 13

 14 #include <asm/io.h>       // ioͷ�ļ�������Ӳ���˿�����/���������䡣

 15 #include <asm/segment.h>  // �β���ͷ�ļ����������йضμĴ���������Ƕ��ʽ��ຯ����

 16 #include <asm/system.h>   // ϵͳͷ�ļ����������û��޸�������/�ж��ŵȵ�Ƕ��ʽ���ꡣ

 17

    // ���ݽ������pgrpȡ�ý����������ĻỰ�š�������kernel/exit.c��161�С�

 18 extern int session_of_pgrp(int pgrp);

    // ��ʹ��ָ��tty�ն˵Ľ����������н��̷����źš�������chr_drv/tty_io.c��246�С�

 19 extern int tty_signal(int sig, struct tty_struct *tty);

 20

    // ���Dz������������飨���Ϊ�������飩���������벨�������ӵĶ�Ӧ��ϵ�μ��б���˵����

    // ���粨������2400bpsʱ����Ӧ��������48��0x30����9600bps��������12��0x1c����

 21 static unsigned short quotient[] = {

 22         0, 2304, 1536, 1047, 857,

 23         768, 576, 384, 192, 96,

 24         64, 48, 24, 12, 6, 3

 25 };

 26

    //// �޸Ĵ��䲨���ʡ�

    // ������tty - �ն˶�Ӧ��tty���ݽṹ��

    // �ڳ��������־DLAB��λ����£�ͨ���˿�0x3f8��0x3f9��UART�ֱ�д�벨�������ӵ�

    // �ֽں͸��ֽڡ�д����ٸ�λDLABλ�����ڴ���2���������˿ڷֱ���0x2f8��0x2f9��

 27 static void change_speed(struct tty_struct * tty)

 28 {

 29         unsigned short port,quot;

 30

    // �������ȼ�����tty ָ�����ն��Ƿ��Ǵ����նˣ����������˳������ڴ����ն˵�tty��

    // ��������������data �ֶδ���Ŵ��ж˿ڻ�ַ��0x3f8��0x2f8������һ�����̨�ն˵�

    // tty�ṹ��read_q.data�ֶ�ֵΪ0��Ȼ����ն�termios�ṹ�Ŀ���ģʽ��־����ȡ������

    // �õIJ����������ţ����ݴ˴Ӳ�������������quotient[]��ȡ�ö�Ӧ�IJ���������ֵquot��

    // CBAUD�ǿ���ģʽ��־���в�����λ�����롣

 31         if (!(port = tty->read_q->data))

 32                 return;

 33         quot = quotient[tty->termios.c_cflag & CBAUD];

    // ���ŰѲ���������quotд�봮�ж˿ڶ�ӦUARTоƬ�IJ����������������С���д֮ǰ����

    // ��Ҫ����·���ƼĴ��� LCR �ij���������ʱ���λDLAB��λ7����1��Ȼ��� 16λ�IJ���

    // �����ӵ͸��ֽڷֱ�д��˿� 0x3f8��0x3f9 ���ֱ��Ӧ���������ӵ͡����ֽ�����������

    // ����ٸ�λLCR��DLAB��־λ��

 34         cli();

 35         outb_p(0x80,port+3);        /* set DLAB */   // �������ó���������־DLAB��

 36         outb_p(quot & 0xff,port);   /* LS of divisor */   // ������ӵ��ֽڡ�

 37         outb_p(quot >> 8,port+1);   /* MS of divisor */   // ������Ӹ��ֽڡ�

 38         outb(0x03,port+3);          /* reset DLAB */      // ��λDLAB��

 39         sti();

 40 }

 41

    //// ˢ��tty������С�

    // ������queue - ָ���Ļ������ָ�롣

    // �����е�ͷָ�����βָ�룬�Ӷ��ﵽ��ջ�������Ŀ�ġ�

 42 static void flush(struct tty_queue * queue)

 43 {

 44         cli();

 45         queue->head = queue->tail;

 46         sti();

 47 }

 48

    //// �ȴ��ַ����ͳ�ȥ��

 49 static void wait_until_sent(struct tty_struct * tty)

 50 {

 51         /* do nothing - not implemented */   /* ʲô��û�� - ��δʵ�� */

 52 }

 53

    //// ����BREAK���Ʒ���

 54 static void send_break(struct tty_struct * tty)

 55 {

 56         /* do nothing - not implemented */   /* ʲô��û�� - ��δʵ�� */

 57 }

 58

    //// ȡ�ն�termios�ṹ��Ϣ��

    // ������tty - ָ���ն˵�tty�ṹָ�룻termios - ���termios�ṹ���û���������

 59 static int get_termios(struct tty_struct * tty, struct termios * termios)

 60 {

 61         int i;

 62

    // ������֤�û�������ָ����ָ�ڴ��������Ƿ��㹻���粻��������ڴ档Ȼ����ָ���ն�

    // ��termios�ṹ��Ϣ���û��������С���󷵻�0��

 63         verify_area(termios, sizeof (*termios));       // kernel/fork.c��24�С�

 64         for (i=0 ; i< (sizeof (*termios)) ; i++)

 65                 put_fs_byte( ((char *)&tty->termios)[i] , i+(char *)termios );

 66         return 0;

 67 }

 68

    //// �����ն�termios�ṹ��Ϣ��

    // ������tty - ָ���ն˵�tty�ṹָ�룻termios - �û�������termios�ṹָ�롣

 69 static int set_termios(struct tty_struct * tty, struct termios * termios,

 70                         int channel)

 71 {

 72         int i, retsig;

 73

 74         /* If we try to set the state of terminal and we're not in the

 75            foreground, send a SIGTTOU.  If the signal is blocked or

 76            ignored, go ahead and perform the operation.  POSIX 7.2) */

            /* �����ͼ�����ն˵�״̬����ʱ�ն˲���ǰ̨����ô���Ǿ���Ҫ����

               һ��SIGTTOU�źš�������źű��������λ��ߺ����ˣ���ֱ��ִ��

               ���β�����  POSIX 7.2  */

    // �����ǰ����ʹ�õ�tty�ն˵Ľ����������̵Ľ�����Ų�ͬ������ǰ�����ն˲���ǰ̨��

    // ��ʾ��ǰ������ͼ�޸IJ��ܿ��Ƶ��ն˵�termios�ṹ����˸���POSIX��׼��Ҫ��������

    // Ҫ����SIGTTOU�ź���ʹ������ն˵Ľ�������ʱִֹͣ�У������������޸�termios�ṹ��

    // ��������źź���tty_signal()����ֵ��ERESTARTSYS��EINTR�����һ����ִ�б��β�����

 77         if ((current->tty == channel) && (tty->pgrp != current->pgrp)) {

 78                 retsig = tty_signal(SIGTTOU, tty);     // chr_drv/tty_io.c��246�С�

 79                 if (retsig == -ERESTARTSYS || retsig == -EINTR)

 80                         return retsig;

 81         }

    // ���Ű��û���������termios�ṹ��Ϣ���Ƶ�ָ���ն�tty�ṹ��termios�ṹ�С���Ϊ��

    // ���п������޸����ն˴��пڴ��䲨���ʣ����������ٸ���termios�ṹ�еĿ���ģʽ��־

    // c_cflag�еIJ�������Ϣ�޸Ĵ���UARTоƬ�ڵĴ��䲨���ʡ���󷵻�0��

 82         for (i=0 ; i< (sizeof (*termios)) ; i++)

 83                 ((char *)&tty->termios)[i]=get_fs_byte(i+(char *)termios);

 84         change_speed(tty);

 85         return 0;

 86 }

 87

    //// ��ȡtermio�ṹ�е���Ϣ��

    // ������tty - ָ���ն˵�tty�ṹָ�룻termio - ����termio�ṹ��Ϣ���û���������

 88 static int get_termio(struct tty_struct * tty, struct termio * termio)

 89 {

 90         int i;

 91         struct termio tmp_termio;

 92

    // ������֤�û��Ļ�����ָ����ָ�ڴ��������Ƿ��㹻���粻��������ڴ档Ȼ��termios

    // �ṹ����Ϣ���Ƶ���ʱ termio �ṹ�С��������ṹ������ͬ�������롢��������ƺͱ���

    // ��־���������Ͳ�ͬ��ǰ�ߵ���long�������ߵ���short������ȸ��Ƶ���ʱtermio�ṹ

    // ��Ŀ����Ϊ�˽�����������ת����

 93         verify_area(termio, sizeof (*termio));

 94         tmp_termio.c_iflag = tty->termios.c_iflag;

 95         tmp_termio.c_oflag = tty->termios.c_oflag;

 96         tmp_termio.c_cflag = tty->termios.c_cflag;

 97         tmp_termio.c_lflag = tty->termios.c_lflag;

 98         tmp_termio.c_line = tty->termios.c_line;

 99         for(i=0 ; i < NCC ; i++)

100                 tmp_termio.c_cc[i] = tty->termios.c_cc[i];

    // ������ֽڵذ���ʱtermio�ṹ�е���Ϣ���Ƶ��û�termio�ṹ�������С�������0��

101         for (i=0 ; i< (sizeof (*termio)) ; i++)

102                 put_fs_byte( ((char *)&tmp_termio)[i] , i+(char *)termio );

103         return 0;

104 }

105

106 /*

107  * This only works as the 386 is low-byt-first

108  */

    /*

     * ����termio���ú����������ڵ��ֽ���ǰ��386 CPU��

     */

    //// �����ն�termio�ṹ��Ϣ��

    // ������tty - ָ���ն˵�tty�ṹָ�룻termio - �û���������termio�ṹ��

    // ���û�������termio����Ϣ���Ƶ��ն˵�termios�ṹ�С�����0 ��

109 static int set_termio(struct tty_struct * tty, struct termio * termio,

110                         int channel)

111 {

112         int i, retsig;

113         struct termio tmp_termio;

114

    // ��set_termios()һ�����������ʹ�õ��ն˵Ľ����������̵Ľ�����Ų�ͬ������ǰ��

    // ���ն˲���ǰ̨����ʾ��ǰ������ͼ�޸IJ��ܿ��Ƶ��ն˵�termios�ṹ����˸���POSIX

    // ��׼��Ҫ��������Ҫ����SIGTTOU�ź���ʹ������ն˵Ľ�������ʱִֹͣ�У�����������

    // �޸�termios�ṹ����������źź���tty_signal()����ֵ��ERESTARTSYS��EINTR�����

    // һ����ִ�б��β�����

115         if ((current->tty == channel) && (tty->pgrp != current->pgrp)) {

116                 retsig = tty_signal(SIGTTOU, tty);

117                 if (retsig == -ERESTARTSYS || retsig == -EINTR)

118                         return retsig;

119         }

    // ���Ÿ����û���������termio�ṹ��Ϣ����ʱtermio�ṹ�С�Ȼ���ٽ�termio�ṹ����Ϣ

    // ���Ƶ�tty�� termios �ṹ�С���������Ŀ����Ϊ�˶�����ģʽ��־�������ͽ���ת������

    // �� termio�Ķ���������ת����termios�ij��������͡������ֽṹ��c_line��c_cc[]�ֶ�

    // ����ȫ��ͬ�ġ�

120         for (i=0 ; i< (sizeof (*termio)) ; i++)

121                 ((char *)&tmp_termio)[i]=get_fs_byte(i+(char *)termio);

122         *(unsigned short *)&tty->termios.c_iflag = tmp_termio.c_iflag;

123         *(unsigned short *)&tty->termios.c_oflag = tmp_termio.c_oflag;

124         *(unsigned short *)&tty->termios.c_cflag = tmp_termio.c_cflag;

125         *(unsigned short *)&tty->termios.c_lflag = tmp_termio.c_lflag;

126         tty->termios.c_line = tmp_termio.c_line;

127         for(i=0 ; i < NCC ; i++)

128                 tty->termios.c_cc[i] = tmp_termio.c_cc[i];

    // �����Ϊ�û��п������޸����ն˴��пڴ��䲨���ʣ����������ٸ���termios�ṹ�еĿ���

    // ģʽ��־c_cflag�еIJ�������Ϣ�޸Ĵ���UARTоƬ�ڵĴ��䲨���ʣ�������0��

129         change_speed(tty);

130         return 0;

131 }

132

    //// tty�ն��豸����������ƺ�����

    // ������dev - �豸�ţ�cmd - ioctl���arg - ��������ָ�롣

    // �ú������ȸ��ݲ����������豸���ҳ���Ӧ�ն˵�tty�ṹ��Ȼ����ݿ�������cmd�ֱ����

    // ������

133 int tty_ioctl(int dev, int cmd, int arg)

134 {

135         struct tty_struct * tty;

136         int     pgrp;

137

    // ���ȸ����豸��ȡ��tty���豸�ţ��Ӷ�ȡ���ն˵�tty�ṹ�������豸����5�������նˣ���

    // ����̵�tty�ֶμ���tty���豸�š���ʱ������̵�tty���豸���Ǹ����������ý���û��

    // �����նˣ������ܷ�����ioctl���ã�������ʾ������Ϣ��ͣ����������豸�Ų���5����4��

    // ���ǾͿ��Դ��豸����ȡ�����豸�š����豸�ſ�����0������̨�նˣ���1������1�նˣ���

    // 2������2�նˣ���

138         if (MAJOR(dev) == 5) {

139                 dev=current->tty;

140                 if (dev<0)

141                         panic("tty_ioctl: dev<0");

142         } else

143                 dev=MINOR(dev);

    // Ȼ��������豸�ź�tty�������ǿ�ȡ�ö�Ӧ�ն˵�tty�ṹ��������ttyָ���Ӧ���豸

    // �ŵ�tty�ṹ��Ȼ���ٸ��ݲ����ṩ��ioctl����cmd���зֱ�����144�к�벿������

    // �������豸��dev��tty_table[]����ѡ���Ӧ��tty�ṹ�����dev = 0����ʾ����ʹ��

    // ǰ̨�նˣ����ֱ��ʹ���ն˺�fg_console ��Ϊ tty_table[] ������ȡ tty�ṹ�����

    // dev����0����ô��Ҫ������������ǣ��� dev �������ն˺ţ��� dev �Ǵ����ն˺Ż���

    // α�ն˺š����������ն���tty�ṹ�� tty_table[]���������� dev-1��0 -- 63��������

    // ���������նˣ������ǵ� tty�ṹ��������� dev�����磬���dev = 64����ʾ��һ����

    // ���ն�1������tty �ṹ���� ttb_table[dev]�� ���dev = 1�����Ӧ�ն˵�tty�ṹ��

    // tty_table[0]���μ�tty_io.c�����70 -- 73�С�

144         tty = tty_table + (dev ? ((dev < 64)? dev-1:dev) : fg_console);

145         switch (cmd) {

    // ȡ��Ӧ�ն�termios�ṹ��Ϣ����ʱ����arg���û�������ָ�롣

146                 case TCGETS:

147                         return get_termios(tty,(struct termios *) arg);

    // ������termios�ṹ��Ϣ֮ǰ����Ҫ�ȵȴ�����������������ݴ�����ϣ�����ˢ�£���գ�

    // ������С��ٽ���ִ�����������ն�termios�ṹ�IJ�����

148                 case TCSETSF:

149                         flush(tty->read_q); /* fallthrough */  /* ���ż���ִ�� */

    // �������ն�termios����Ϣ֮ǰ����Ҫ�ȵȴ�����������������ݴ����꣨�ľ����������޸�

    // ������Ӱ����������������Ҫʹ��������ʽ��

150                 case TCSETSW:

151                         wait_until_sent(tty); /* fallthrough */

    // ������Ӧ�ն�termios�ṹ��Ϣ����ʱ����arg�DZ���termios�ṹ���û�������ָ�롣

152                 case TCSETS:

153                         return set_termios(tty,(struct termios *) arg, dev);

    // ȡ��Ӧ�ն�termio�ṹ�е���Ϣ����ʱ����arg���û�������ָ�롣

154                 case TCGETA:

155                         return get_termio(tty,(struct termio *) arg);

    // ������termio �ṹ��Ϣ֮ǰ����Ҫ�ȵȴ�����������������ݴ�����ϣ�����ˢ�£���գ�

    // ������С��ٽ���ִ�����������ն�termio �ṹ�IJ�����

156                 case TCSETAF:

157                         flush(tty->read_q); /* fallthrough */  /* ���ż���ִ�� */

    // �������ն�termios����Ϣ֮ǰ����Ҫ�ȵȴ�����������������ݴ����꣨�ľ����������޸�

    // ������Ӱ����������������Ҫʹ��������ʽ��

158                 case TCSETAW:

159                         wait_until_sent(tty); /* fallthrough */

    // ������Ӧ�ն�termio�ṹ��Ϣ����ʱ����arg�DZ���termio�ṹ���û�������ָ�롣

160                 case TCSETA:

161                         return set_termio(tty,(struct termio *) arg, dev);

    // �������argֵ��0����ȴ�������д�����ϣ��գ���������һ��break��

162                 case TCSBRK:

163                         if (!arg) {

164                                 wait_until_sent(tty);

165                                 send_break(tty);

166                         }

167                         return 0;

    // ��ʼ/ֹͣ�����ơ��������arg��TCOOFF��Terminal Control Output OFF��������������

    // ����� TCOON����ָ������������ڹ����ָ����ͬʱ��Ҫ��д�����е��ַ��������

    // �ӿ��û�������Ӧ�ٶȡ����arg��TCIOFF��Terminal Control Input ON������������룻

    // �����TCION�������¿�����������롣

168                 case TCXONC:

169                         switch (arg) {

170                         case TCOOFF:

171                                 tty->stopped = 1;    // ֹͣ�ն������

172                                 tty->write(tty);     // д������������

173                                 return 0;

174                         case TCOON:

175                                 tty->stopped = 0;    // �ָ��ն������

176                                 tty->write(tty);

177                                 return 0;

    // �������arg��TCIOFF����ʾҪ���ն�ֹͣ���룬�����������ն�д�����з���STOP�ַ���

    // ���ն��յ����ַ�ʱ�ͻ���ͣ���롣���������TCION����ʾҪ����һ��START�ַ�������

    // �˻ָ����䡣

    // STOP_CHAR(tty)����Ϊ ((tty)->termios.c_cc[VSTOP])����ȡ�ն�termios�ṹ�����ַ���

    // ���Ӧ��ֵ�����ں˶�����_POSIX_VDISABLE��\0������ô��ijһ��ֵ����_POSIX_VDISABLE

    // ��ֵʱ����ʾ��ֹʹ����Ӧ�������ַ����������ֱ���жϸ�ֵ�Ƿ�Ϊ0 ��ȷ��Ҫ��Ҫ��ͣ

    // ֹ�����ַ������ն�д�����С�����ͬ��

178                         case TCIOFF:

179                                 if (STOP_CHAR(tty))

180                                         PUTCH(STOP_CHAR(tty),tty->write_q);

181                                 return 0;

182                         case TCION:

183                                 if (START_CHAR(tty))

184                                         PUTCH(START_CHAR(tty),tty->write_q);

185                                 return 0;

186                         }

187                         return -EINVAL; /* not implemented */

    // ˢ����д�������û�з��͡������յ���û�ж������ݡ��������arg��0����ˢ�£���գ�

    // ������У������1����ˢ��������У������2����ˢ�������������С�

188                 case TCFLSH:

189                         if (arg==0)

190                                 flush(tty->read_q);

191                         else if (arg==1)

192                                 flush(tty->write_q);

193                         else if (arg==2) {

194                                 flush(tty->read_q);

195                                 flush(tty->write_q);

196                         } else

197                                 return -EINVAL;

198                         return 0;

    // �����ն˴�����·ר��ģʽ��

199                 case TIOCEXCL:

200                         return -EINVAL; /* not implemented */   /* δʵ�� */

    // ��λ�ն˴�����·ר��ģʽ��

201                 case TIOCNXCL:

202                         return -EINVAL; /* not implemented */

    // ����ttyΪ�����նˡ���TIOCNOTTY - ��Ҫ�����նˣ���

203                 case TIOCSCTTY:

204                         return -EINVAL; /* set controlling term NI */  /* δʵ�� */

    // ��ȡ�ն˽�����ţ�����ȡǰ̨������ţ��� ������֤�û����������ȣ�Ȼ�����ն�tty

    // ��pgrp�ֶε��û�����������ʱ����arg���û�������ָ�롣

205                 case TIOCGPGRP:                       // ʵ�ֿ⺯��tcgetpgrp()��

206                         verify_area((void *) arg,4);

207                         put_fs_long(tty->pgrp,(unsigned long *) arg);

208                         return 0;

    // �����ն˽������pgrp��������ǰ̨������ţ��� ��ʱ����arg ���û��������н������

    // pgrp ��ָ�롣ִ�и������ǰ�������ǽ��̱����п����նˡ� �����ǰ����û�п����նˣ�

    // ����dev ����������նˣ����߿����ն����ڵ�ȷ�����ڴ������ն�dev�������̵ĻỰ��

    // ����ն�dev�ĻỰ�Ų�ͬ���򷵻����ն˴�����Ϣ��

209                 case TIOCSPGRP:                       // ʵ�ֿ⺯��tcsetpgrp()��

210                         if ((current->tty < 0) ||

211                             (current->tty != dev) ||

212                             (tty->session != current->session))

213                                 return -ENOTTY;

    // Ȼ�����Ǿʹ��û���������ȡ�������õĽ�����ţ����Ը���ŵ���Ч�Խ�����֤�������

    // ��pgrpС��0���򷵻���Ч��Ŵ�����Ϣ����� pgrp�ĻỰ���뵱ǰ���̵IJ�ͬ���򷵻�

    // ���ɴ�����Ϣ���������ǿ��������ն˵Ľ������Ϊprgp����ʱprgp��Ϊǰ̨�����顣

214                         pgrp=get_fs_long((unsigned long *) arg);

215                         if (pgrp < 0)

216                                 return -EINVAL;

217                         if (session_of_pgrp(pgrp) != current->session)

218                                 return -EPERM;

219                         tty->pgrp = pgrp;                      

220                         return 0;

    // ������������л�δ�ͳ����ַ�����������֤�û����������ȣ�Ȼ���ƶ������ַ������û���

    // ��ʱ����arg���û�������ָ�롣

221                 case TIOCOUTQ:

222                         verify_area((void *) arg,4);

223                         put_fs_long(CHARS(tty->write_q),(unsigned long *) arg);

224                         return 0;

    // ������������л�δ��ȡ���ַ�����������֤�û����������ȣ�Ȼ���ƶ������ַ������û���

    // ��ʱ����arg���û�������ָ�롣

225                 case TIOCINQ:

226                         verify_area((void *) arg,4);

227                         put_fs_long(CHARS(tty->secondary),

228                                 (unsigned long *) arg);

229                         return 0;

    // ģ���ն������������������һ��ָ���ַ���ָ����Ϊ��������������ַ������ն��ϼ���ġ�

    // �û������ڸÿ����ն��Ͼ��г����û�Ȩ�޻���ж�����Ȩ�ޡ�

230                 case TIOCSTI:

231                         return -EINVAL; /* not implemented */   /* δʵ�� */

    // ��ȡ�ն��豸���ڴ�С��Ϣ���μ�termios.h�е�winsize�ṹ����

232                 case TIOCGWINSZ:

233                         return -EINVAL; /* not implemented */

    // �����ն��豸���ڴ�С��Ϣ���μ�winsize�ṹ����

234                 case TIOCSWINSZ:

235                         return -EINVAL; /* not implemented */

    // ����MODEM״̬�������ߵĵ�ǰ״̬����λ��־�����μ�termios.h��185 -- 196�У���

236                 case TIOCMGET:

237                         return -EINVAL; /* not implemented */

    // ���õ���modem״̬�������ߵ�״̬��true��false����

238                 case TIOCMBIS:

239                         return -EINVAL; /* not implemented */

    // ��λ����MODEM״̬�������ߵ�״̬��

240                 case TIOCMBIC:

241                         return -EINVAL; /* not implemented */

    // ����MODEM״̬���ߵ�״̬�����ijһ����λ��λ����modem��Ӧ��״̬���߽���Ϊ��Ч��

242                 case TIOCMSET:

243                         return -EINVAL; /* not implemented */

    // ��ȡ�����ز�����־��1 - ������0 - �رգ���

244                 case TIOCGSOFTCAR:

245                         return -EINVAL; /* not implemented */

    // ���������ز�����־��1 - ������0 - �رգ���

246                 case TIOCSSOFTCAR:

247                         return -EINVAL; /* not implemented */

248                 default:

249                         return -EINVAL;

250         }

251 }

252


 


 

��11�� �������������

11.1 ����11-1 linux/kernel/math/math_emulate.c


  1 /*

  2  * linux/kernel/math/math_emulate.c

  3  *

  4  * (C) 1991 Linus Torvalds

  5  */

  6

  7 /*

  8  * Limited emulation 27.12.91 - mostly loads/stores, which gcc wants

  9  * even for soft-float, unless you use bruce evans' patches. The patches

 10  * are great, but they have to be re-applied for every version, and the

 11  * library is different for soft-float and 80387. So emulation is more

 12  * practical, even though it's slower.

 13  *

 14  * 28.12.91 - loads/stores work, even BCD. I'll have to start thinking

 15  * about add/sub/mul/div. Urgel. I should find some good source, but I'll

 16  * just fake up something.

 17  *

 18  * 30.12.91 - add/sub/mul/div/com seem to work mostly. I should really

 19  * test every possible combination.

 20  */

    /*

     * ���淶Χ���޵ij��� 91.12.27 - ���������һЩ����/�洢ָ�������ʹ��

     * ��Bruce Evans�IJ������򣬷���ʹʹ������ִ�и������㣬gccҲ��Ҫ��Щ

     * ָ�Bruce�IJ�������dz��ã���ÿ�θ���gcc�汾�㶼���������������

     * ���Ҷ�����������ʵ�ֺ�80387����ʹ�õĿ��Dz�ͬ�ġ����ʹ�÷����Ǹ�Ϊʵ

     * �ʵķ��������ܷ��淽��������

     *

     * 91.12.28 - ����/�洢Э������ָ��������ˣ���ʹ��BCD���Ҳ��ʹ�á��ҽ�

     * ��ʼ����ʵ�� add/sub/mul/div ָ�������Ӧ����һЩ�õ����ϣ���������

     * �һ��ȷ���һЩ������

     *

     * 91.12.30 - add/sub/mul/div/com ��Щָ���������������ʹ���ˡ�����Ӧ

     * �ò���ÿ��ָ����ܵ���ϲ�����

     */

 21

 22 /*

 23  * This file is full of ugly macros etc: one problem was that gcc simply

 24  * didn't want to make the structures as they should be: it has to try to

 25  * align them. Sickening code, but at least I've hidden the ugly things

 26  * in this one file: the other files don't need to know about these things.

 27  *

 28  * The other files also don't care about ST(x) etc - they just get addresses

 29  * to 80-bit temporary reals, and do with them as they please. I wanted to

 30  * hide most of the 387-specific things here.

 31  */

    /*

     * ��������е�������Щ��Ť�ĺ꣺����֮һ��gcc���Dz���ѽṹ��������Ӧ��

     * ��Ϊ�����ӣ�gcc ��ͼ�Խṹ���ж��봦�����������ᣬ�����������Ѿ�������

     * ���ŵĴ��붼��������ôһ���ļ����ˣ����������ļ�����Ҫ�˽���Щ��Ϣ��

     *

     * �����ij���Ҳ����Ҫ֪��ST(x)��80387�ڲ��ṹ - ����ֻ��Ҫ�õ�80λ��ʱ

     * ʵ���ĵ�ַ�Ϳ���������������뾡������������������387ר����Ϣ��

     */

 32

 33 #include <signal.h>       // �ź�ͷ�ļ��������źŷ��ţ��źŽṹ���źŲ�������ԭ�͡�

 34

 35 #define __ALIGNED_TEMP_REAL 1

 36 #include <linux/math_emu.h> // Э������ͷ�ļ���������ʱʵ���ṹ��387�Ĵ���������ȡ�

 37 #include <linux/kernel.h>   // �ں�ͷ�ļ�������һЩ�ں˳��ú�����ԭ�ζ��塣

 38 #include <asm/segment.h>    // �β���ͷ�ļ����������йضμĴ���������Ƕ��ʽ��ຯ����

 39

 40 #define bswapw(x) __asm__("xchgb %%al,%%ah":"=a" (x):"" ((short)x)) // ����2�ֽ�λ�á�

 41 #define ST(x) (*__st((x)))                            // ȡ�����ST(x)�ۼ���ֵ��

 42 #define PST(x) ((const temp_real *) __st((x)))        // ȡ�����ST(x)�ۼ�����ָ�롣

 43

 44 /*

 45  * We don't want these inlined - it gets too messy in the machine-code.

 46  */

    /*

     * ���Dz�������Щ��ΪǶ������ - ��Ϊ���ʹ�õ��Ļ�����̫���ҡ�

     */

    // ������Щ����ͬ���Ƹ���ָ��ķ��溯����

 47 static void fpop(void);

 48 static void fpush(void);

 49 static void fxchg(temp_real_unaligned * a, temp_real_unaligned * b);

 50 static temp_real_unaligned * __st(int i);

 51

    // ִ�и���ָ����档

    // �ú������ȼ������I387�ṹ״̬�ּĴ������Ƿ���δ���ε��쳣��־��λ���������״

    // ̬����æ��־B�������á�Ȼ���ָ��ָ�뱣����������ȡ������ָ�� EIP ���� 2�ֽڸ���

    // ָ����� code�����ŷ������� code���������京����д�������Բ�ͬ��������ֵ��Linus

    // ʹ���˼�����ͬ�� switch �������з��洦����

    // ������info�ṹ��ָ�롣

 52 static void do_emu(struct info * info)

 53 {

 54         unsigned short code;

 55         temp_real tmp;

 56         char * address;

 57

    // �ú������ȼ������I387�ṹ״̬�ּĴ������Ƿ���δ���ε��쳣��־��λ�����о�����

    // ״̬���е�æ��־ B��λ15��������λ B��־��Ȼ�����ǰ�ָ��ָ�뱣���������ٿ���ִ

    // �б������Ĵ����Ƿ����û����롣������ǣ��������ߵĴ����ѡ��������� 0x0f����˵��

    // �ں����д���ʹ���˸���ָ���������ʾ������ָ����� CS��EIP ֵ����Ϣ���ں�����Ҫ

    // ��ѧ��������ͣ����

 58         if (I387.cwd & I387.swd & 0x3f)

 59                 I387.swd |= 0x8000;                  // ����æ��־B��

 60         else

 61                 I387.swd &= 0x7fff;                  // ��æ��־B��

 62         ORIG_EIP = EIP;                              // ���渡��ָ��ָ�롣

 63 /* 0x0007 means user code space */

 64         if (CS != 0x000F) {                          // �����û�������ͣ����

 65                 printk("math_emulate: %04x:%08x\n\r",CS,EIP);

 66                 panic("Math emulation needed in kernel");

 67         }

    // Ȼ������ȡ������ָ�� EIP ���� 2�ֽڸ���ָ����� code�� ����Intel CPU�洢����ʱ��

    // ��Сͷ����Little endien����ǰ�ģ���ʱȡ���Ĵ���������ָ��ĵ�1����2�ֽ�˳��ߵ���

    // ���������Ҫ����һ�� code �������ֽڵ�˳��Ȼ�������ε���1�������ֽ��е� ESC λ

    // ��������11011�������ŰѸ���ָ��ָ��EIP���浽TSS��i387�ṹ�е�fip�ֶ��У���CS

    // ���浽 fcs�ֶ��У�ͬʱ����΢�������ĸ���ָ����� code �ŵ� fcs �ֶεĸ� 16 λ�С�

    // ������Щֵ��Ϊ���ڳ��ַ���Ĵ������쳣ʱ���������ʹ����ʵ��Э������һ�����д�����

    // �����EIPָ�����ĸ���ָ����������

 68         code = get_fs_word((unsigned short *) EIP);  // ȡ2�ֽڵĸ���ָ����롣

 69         bswapw(code);                                // �����ߵ��ֽڡ�

 70         code &= 0x7ff;                               // ���δ����е�ESC�롣

 71         I387.fip = EIP;                              // ����ָ��ָ�롣

 72         *(unsigned short *) &I387.fcs = CS;          // ��������ѡ�����

 73         *(1+(unsigned short *) &I387.fcs) = code;    // ������롣

 74         EIP += 2;                                    // ָ��ָ��ָ����һ���ֽڡ�

    // Ȼ���������ֵcode���������京����д�������Բ�ͬ��������ֵ��Linusʹ���˼�����ͬ

    // �� switch �������д��������ȣ���ָ��������Ǿ��й̶�����ֵ����Ĵ������޹أ�����

    // �����洦����

 75         switch (code) {

 76                 case 0x1d0: /* fnop */    /* �ղ���ָ��FNOP */

 77                         return;

 78                 case 0x1d1: case 0x1d2: case 0x1d3:  // ��Чָ����롣���źţ��˳���

 79                 case 0x1d4: case 0x1d5: case 0x1d6: case 0x1d7:

 80                         math_abort(info,1<<(SIGILL-1));

 81                 case 0x1e0:               // FCHS - �ı�ST����λ����ST = -ST��

 82                         ST(0).exponent ^= 0x8000;

 83                         return;

 84                 case 0x1e1:               // FABS - ȡ����ֵ����ST = |ST|��

 85                         ST(0).exponent &= 0x7fff;

 86                         return;

 87                 case 0x1e2: case 0x1e3:   // ��Чָ����롣���źţ��˳���

 88                         math_abort(info,1<<(SIGILL-1));

 89                 case 0x1e4:               // FTST - ����TS��ͬʱ����״̬����Cn��

 90                         ftst(PST(0));

 91                         return;

 92                 case 0x1e5:               // FXAM - ���TSֵ��ͬʱ�޸�״̬����Cn��

 93                         printk("fxam not implemented\n\r");  // δʵ�֡����ź��˳���

 94                         math_abort(info,1<<(SIGILL-1));

 95                 case 0x1e6: case 0x1e7:   // ��Чָ����롣���źţ��˳���

 96                         math_abort(info,1<<(SIGILL-1));

 97                 case 0x1e8:               // FLD1 - ���س���1.0 ���ۼ���ST��

 98                         fpush();

 99                         ST(0) = CONST1;

100                         return;

101                 case 0x1e9:               // FLDL2T - ���س���Log2(10) ���ۼ���ST��

102                         fpush();

103                         ST(0) = CONSTL2T;

104                         return;

105                 case 0x1ea:               // FLDL2E - ���س���Log2(e) ���ۼ���ST��

106                         fpush();

107                         ST(0) = CONSTL2E;

108                         return;

109                 case 0x1eb:               // FLDPI - ���س���Pi ���ۼ���ST��

110                         fpush();

111                         ST(0) = CONSTPI;

112                         return;

113                 case 0x1ec:               // FLDLG2 - ���س���Log10(2) ���ۼ���ST��

114                         fpush();

115                         ST(0) = CONSTLG2;

116                         return;

117                 case 0x1ed:               // FLDLN2 - ���س���Loge(2) ���ۼ���ST��

118                         fpush();

119                         ST(0) = CONSTLN2;

120                         return;

121                 case 0x1ee:               // FLDZ - ���س���0.0 ���ۼ���ST��

122                         fpush();

123                         ST(0) = CONSTZ;

124                         return;

125                 case 0x1ef:               // ��Ч��δʵ�ַ���ָ����롣���źţ��˳���

126                         math_abort(info,1<<(SIGILL-1));

127                 case 0x1f0: case 0x1f1: case 0x1f2: case 0x1f3:

128                 case 0x1f4: case 0x1f5: case 0x1f6: case 0x1f7:

129                 case 0x1f8: case 0x1f9: case 0x1fa: case 0x1fb:

130                 case 0x1fc: case 0x1fd: case 0x1fe: case 0x1ff:

131                         printk("%04x fxxx not implemented\n\r",code + 0xc800);

132                         math_abort(info,1<<(SIGILL-1));

133                 case 0x2e9:               // FUCOMPP - �޴���Ƚϡ�

134                         fucom(PST(1),PST(0));

135                         fpop(); fpop();

136                         return;

137                 case 0x3d0: case 0x3d1:   // FNOP - ��387��!!Ӧ����0x3e0, 0x3e1��

138                         return;

139                 case 0x3e2:               // FCLEX - ��״̬�����쳣��־��

140                         I387.swd &= 0x7f00;

141                         return;

142                 case 0x3e3:               // FINIT - ��ʼ��Э��������

143                         I387.cwd = 0x037f;

144                         I387.swd = 0x0000;

145                         I387.twd = 0x0000;

146                         return;

147                 case 0x3e4:               // FNOP - ��80387��

148                         return;

149                 case 0x6d9:               // FCOMPP - ST(1)��ST�Ƚϣ���ջ�������Ρ�

150                         fcom(PST(1),PST(0));

151                         fpop(); fpop();

152                         return;

153                 case 0x7e0:               // FSTSW AX - ���浱ǰ״̬�ֵ�AX�Ĵ����С�

154                         *(short *) &EAX = I387.swd;

155                         return;

156         }

 

    // ���濪ʼ������2�ֽ����3������REG��ָ���11011,XXXXXXXX,REG��ʽ�Ĵ��롣

157         switch (code >> 3) {

158                 case 0x18:                // FADD ST, ST(i)��

159                         fadd(PST(0),PST(code & 7),&tmp);

160                         real_to_real(&tmp,&ST(0));

161                         return;

162                 case 0x19:                // FMUL ST, ST(i)��

163                         fmul(PST(0),PST(code & 7),&tmp);

164                         real_to_real(&tmp,&ST(0));

165                         return;

166                 case 0x1a:                // FCOM ST(i)��

167                         fcom(PST(code & 7),&tmp);

168                         real_to_real(&tmp,&ST(0));

169                         return;

170                 case 0x1b:                // FCOMP ST(i)��

171                         fcom(PST(code & 7),&tmp);

172                         real_to_real(&tmp,&ST(0));

173                         fpop();

174                         return;

175                 case 0x1c:                // FSUB ST, ST(i)��

176                         real_to_real(&ST(code & 7),&tmp);

177                         tmp.exponent ^= 0x8000;

178                         fadd(PST(0),&tmp,&tmp);

179                         real_to_real(&tmp,&ST(0));

180                         return;

181                 case 0x1d:                // FSUBR ST, ST(i)��

182                         ST(0).exponent ^= 0x8000;

183                         fadd(PST(0),PST(code & 7),&tmp);

184                         real_to_real(&tmp,&ST(0));

185                         return;

186                 case 0x1e:                // FDIV ST, ST(i)��

187                         fdiv(PST(0),PST(code & 7),&tmp);

188                         real_to_real(&tmp,&ST(0));

189                         return;

190                 case 0x1f:                // FDIVR ST, ST(i)��

191                         fdiv(PST(code & 7),PST(0),&tmp);

192                         real_to_real(&tmp,&ST(0));

193                         return;

194                 case 0x38:                // FLD ST(i)��

195                         fpush();

196                         ST(0) = ST((code & 7)+1);

197                         return;

198                 case 0x39:                // FXCH ST(i)��

199                         fxchg(&ST(0),&ST(code & 7));

200                         return;

201                 case 0x3b:                // FSTP ST(i)��

202                         ST(code & 7) = ST(0);

203                         fpop();

204                         return;

205                 case 0x98:                // FADD ST(i), ST��

206                         fadd(PST(0),PST(code & 7),&tmp);

207                         real_to_real(&tmp,&ST(code & 7));

208                         return;

209                 case 0x99:                // FMUL ST(i), ST��

210                         fmul(PST(0),PST(code & 7),&tmp);

211                         real_to_real(&tmp,&ST(code & 7));

212                         return;

213                 case 0x9a:                // FCOM ST(i)��

214                         fcom(PST(code & 7),PST(0));

215                         return;

216                 case 0x9b:                // FCOMP ST(i)��

217                         fcom(PST(code & 7),PST(0));

218                         fpop();

219                         return;                

220                 case 0x9c:                // FSUBR ST(i), ST��

221                         ST(code & 7).exponent ^= 0x8000;

222                         fadd(PST(0),PST(code & 7),&tmp);

223                         real_to_real(&tmp,&ST(code & 7));

224                         return;

225                 case 0x9d:                // FSUB ST(i), ST��

226                         real_to_real(&ST(0),&tmp);

227                         tmp.exponent ^= 0x8000;

228                         fadd(PST(code & 7),&tmp,&tmp);

229                         real_to_real(&tmp,&ST(code & 7));

230                         return;

231                 case 0x9e:                // FDIVR ST(i), ST��

232                         fdiv(PST(0),PST(code & 7),&tmp);

233                         real_to_real(&tmp,&ST(code & 7));

234                         return;

235                 case 0x9f:                // FDIV ST(i), ST��

236                         fdiv(PST(code & 7),PST(0),&tmp);

237                         real_to_real(&tmp,&ST(code & 7));

238                         return;

239                 case 0xb8:                // FFREE ST(i)��δʵ�֡�

240                         printk("ffree not implemented\n\r");

241                         math_abort(info,1<<(SIGILL-1));

242                 case 0xb9:                // FXCH ST(i)��

243                         fxchg(&ST(0),&ST(code & 7));

244                         return;

245                 case 0xba:                // FST ST(i)��

246                         ST(code & 7) = ST(0);

247                         return;

248                 case 0xbb:                // FSTP ST(i)��

249                         ST(code & 7) = ST(0);

250                         fpop();

251                         return;

252                 case 0xbc:                // FUCOM ST(i)��

253                         fucom(PST(code & 7),PST(0));

254                         return;

255                 case 0xbd:                // FUCOMP ST(i)��

256                         fucom(PST(code & 7),PST(0));

257                         fpop();

258                         return;

259                 case 0xd8:                // FADDP ST(i), ST��

260                         fadd(PST(code & 7),PST(0),&tmp);

261                         real_to_real(&tmp,&ST(code & 7));

262                         fpop();

263                         return;

264                 case 0xd9:                // FMULP ST(i), ST��

265                         fmul(PST(code & 7),PST(0),&tmp);

266                         real_to_real(&tmp,&ST(code & 7));

267                         fpop();

268                         return;

269                 case 0xda:                // FCOMP ST(i)��

270                         fcom(PST(code & 7),PST(0));

271                         fpop();

272                         return;

273                 case 0xdc:                // FSUBRP ST(i), ST��

274                         ST(code & 7).exponent ^= 0x8000;

275                         fadd(PST(0),PST(code & 7),&tmp);

276                         real_to_real(&tmp,&ST(code & 7));

277                         fpop();

278                         return;

279                 case 0xdd:                // FSUBP ST(i), ST��

280                         real_to_real(&ST(0),&tmp);

281                         tmp.exponent ^= 0x8000;

282                         fadd(PST(code & 7),&tmp,&tmp);

283                         real_to_real(&tmp,&ST(code & 7));

284                         fpop();

285                         return;

286                 case 0xde:                // FDIVRP ST(i), ST��

287                         fdiv(PST(0),PST(code & 7),&tmp);

288                         real_to_real(&tmp,&ST(code & 7));

289                         fpop();

290                         return;

291                 case 0xdf:                // FDIVP ST(i), ST��

292                         fdiv(PST(code & 7),PST(0),&tmp);

293                         real_to_real(&tmp,&ST(code & 7));

294                         fpop();

295                         return;

296                 case 0xf8:                // FFREE ST(i)��δʵ�֡�

297                         printk("ffree not implemented\n\r");

298                         math_abort(info,1<<(SIGILL-1));

299                         fpop();

300                         return;

301                 case 0xf9:                // FXCH ST(i)��

302                         fxchg(&ST(0),&ST(code & 7));

303                         return;

304                 case 0xfa:                // FSTP ST(i)��

305                 case 0xfb:                // FSTP ST(i)��

306                         ST(code & 7) = ST(0);

307                         fpop();

308                         return;

309         }

 

    // ������2���ֽ�λ7--6��MOD��λ2--0��R/M��ָ��� 11011,XXX,MOD,XXX,R/M ��ʽ��

    // ���롣MOD�ڸ��ӳ����д�����������������ô�������0xe7��0b11100111�����ε�MOD��

310         switch ((code>>3) & 0xe7) {

311                 case 0x22:                // FST  - ���浥����ʵ������ʵ������

312                         put_short_real(PST(0),info,code);

313                         return;

314                 case 0x23:                // FSTP  - ���浥����ʵ������ʵ������

315                         put_short_real(PST(0),info,code);

316                         fpop();

317                         return;

318                 case 0x24:                // FLDENV - ����Э������״̬�Ϳ��ƼĴ����ȡ�

319                         address = ea(info,code);

320                         for (code = 0 ; code < 7 ; code++) {

321                                 ((long *) & I387)[code] =

322                                    get_fs_long((unsigned long *) address);

323                                 address += 4;

324                         }

325                         return;

326                 case 0x25:                // FLDCW - ���ؿ����֡�

327                         address = ea(info,code);

328                         *(unsigned short *) &I387.cwd =

329                                 get_fs_word((unsigned short *) address);

330                         return;

331                 case 0x26:                // FSTENV - ����Э������״̬�Ϳ��ƼĴ����ȡ�

332                         address = ea(info,code);

333                         verify_area(address,28);

334                         for (code = 0 ; code < 7 ; code++) {

335                                 put_fs_long( ((long *) & I387)[code],

336                                         (unsigned long *) address);

337                                 address += 4;

338                         }

339                         return;

340                 case 0x27:                // FSTCW - ��������֡�

341                         address = ea(info,code);

342                         verify_area(address,2);

343                         put_fs_word(I387.cwd,(short *) address);

344                         return;

345                 case 0x62:                // FIST - �������������

346                         put_long_int(PST(0),info,code);

347                         return;

348                 case 0x63:                // FISTP - �������������

349                         put_long_int(PST(0),info,code);

350                         fpop();

351                         return;

352                 case 0x65:                // FLD - ������չ����ʱ��ʵ����

353                         fpush();

354                         get_temp_real(&tmp,info,code);

355                         real_to_real(&tmp,&ST(0));

356                         return;

357                 case 0x67:                // FSTP - ������չʵ����

358                         put_temp_real(PST(0),info,code);

359                         fpop();

360                         return;

361                 case 0xa2:                // FST - ����˫����ʵ����

362                         put_long_real(PST(0),info,code);

363                         return;

364                 case 0xa3:                // FSTP - ����˫����ʵ����

365                         put_long_real(PST(0),info,code);

366                         fpop();

367                         return;

368                 case 0xa4:                // FRSTOR - �ָ�����108�ֽڵļĴ������ݡ�

369                         address = ea(info,code);

370                         for (code = 0 ; code < 27 ; code++) {

371                                 ((long *) & I387)[code] =

372                                    get_fs_long((unsigned long *) address);

373                                 address += 4;

374                         }

375                         return;

376                 case 0xa6:                // FSAVE - ��������108�ֽڼĴ������ݡ�

377                         address = ea(info,code);

378                         verify_area(address,108);

379                         for (code = 0 ; code < 27 ; code++) {

380                                 put_fs_long( ((long *) & I387)[code],

381                                         (unsigned long *) address);

382                                 address += 4;

383                         }

384                         I387.cwd = 0x037f;

385                         I387.swd = 0x0000;

386                         I387.twd = 0x0000;

387                         return;

388                 case 0xa7:                // FSTSW - ����״̬�֡�

389                         address = ea(info,code);

390                         verify_area(address,2);

391                         put_fs_word(I387.swd,(short *) address);

392                         return;

393                 case 0xe2:                // FIST - �������������

394                         put_short_int(PST(0),info,code);

395                         return;

396                 case 0xe3:                // FISTP - �������������

397                         put_short_int(PST(0),info,code);

398                         fpop();

399                         return;

400                 case 0xe4:                // FBLD - ����BCD��������

401                         fpush();

402                         get_BCD(&tmp,info,code);

403                         real_to_real(&tmp,&ST(0));

404                         return;

405                 case 0xe5:                // FILD - ���س���������

406                         fpush();

407                         get_longlong_int(&tmp,info,code);

408                         real_to_real(&tmp,&ST(0));

409                         return;

410                 case 0xe6:                // FBSTP - ����BCD��������

411                         put_BCD(PST(0),info,code);

412                         fpop();

413                         return;

414                 case 0xe7:                // BISTP - ���泤��������

415                         put_longlong_int(PST(0),info,code);

416                         fpop();

417                         return;

418         }

    // ���洦����2�ม��ָ����ȸ���ָ������λ10--9��MFֵȡָ�����͵�����Ȼ�����

    // OPA��OPB�����ֵ���зֱ����������� 11011,MF,000,XXX,R/M��ʽ��ָ����롣

419         switch (code >> 9) {

420                 case 0:                   // MF = 00����ʵ����32λʵ������

421                         get_short_real(&tmp,info,code);

422                         break;

423                 case 1:                   // MF = 01����������32λ��������

424                         get_long_int(&tmp,info,code);

425                         break;

426                 case 2:                   // MF = 10����ʵ����64λʵ������

427                         get_long_real(&tmp,info,code);

428                         break;

429                 case 4:                   // MF = 11����������64λ����������Ӧ��case 3��

430                         get_short_int(&tmp,info,code);

431         }

    // ��������ָ���2�ֽ��е�OPB���롣

432         switch ((code>>3) & 0x27) {

433                 case 0:                   // FADD��

434                         fadd(&tmp,PST(0),&tmp);

435                         real_to_real(&tmp,&ST(0));

436                         return;

437                 case 1:                   // FMUL��

438                         fmul(&tmp,PST(0),&tmp);

439                         real_to_real(&tmp,&ST(0));

440                         return;

441                 case 2:                   // FCOM��

442                         fcom(&tmp,PST(0));

443                         return;

444                 case 3:                   // FCOMP��

445                         fcom(&tmp,PST(0));

446                         fpop();

447                         return;

448                 case 4:                   // FSUB��

449                         tmp.exponent ^= 0x8000;

450                         fadd(&tmp,PST(0),&tmp);

451                         real_to_real(&tmp,&ST(0));

452                         return;

453                 case 5:                   // FSUBR��

454                         ST(0).exponent ^= 0x8000;

455                         fadd(&tmp,PST(0),&tmp);

456                         real_to_real(&tmp,&ST(0));

457                         return;

458                 case 6:                   // FDIV��

459                         fdiv(PST(0),&tmp,&tmp);

460                         real_to_real(&tmp,&ST(0));

461                         return;

462                 case 7:                   // FDIVR��

463                         fdiv(&tmp,PST(0),&tmp);

464                         real_to_real(&tmp,&ST(0));

465                         return;

466         }

    // �������� 11011,XX,1,XX,000,R/M ��ָ����롣

467         if ((code & 0x138) == 0x100) {         // FLD��FILD��

468                         fpush();

469                         real_to_real(&tmp,&ST(0));

470                         return;

471         }

   // �����Ϊ��Чָ�

472         printk("Unknown math-insns: %04x:%08x %04x\n\r",CS,EIP,code);

473         math_abort(info,1<<(SIGFPE-1));

474 }

475

    // CPU�쳣�ж�int7���õ�80387����ӿں�����

    // ����ǰ����û��ʹ�ù�Э��������������ʹ��Э��������־used_math��Ȼ���ʼ��80387

    // �Ŀ����֡�״̬�ֺ������֡����ʹ���ж�int7���ñ������ķ��ص�ַָ����Ϊ��������

    // ����ָ�����������do_emu()��

    // ���� ___false �� _orig_eip��

476 void math_emulate(long ___false)

477 {

478         if (!current->used_math) {

479                 current->used_math = 1;

480                 I387.cwd = 0x037f;

481                 I387.swd = 0x0000;

482                 I387.twd = 0x0000;

483         }

484 /* &___false points to info->___orig_eip, so subtract 1 to get info */

485         do_emu((struct info *) ((&___false) - 1));

486 }

487

    // ��ֹ���������

    // ����������Чָ��������δʵ�ֵ�ָ�����ʱ���ú������Ȼָ������ԭEIP��������ָ��

    // �źŸ���ǰ���̡����ջָ��ָ���ж�int7 �������̵��ñ������ķ��ص�ַ��ֱ�ӷ��ص�

    // �жϴ��������С�

488 void __math_abort(struct info * info, unsigned int signal)

489 {

490         EIP = ORIG_EIP;

491         current->signal |= signal;

492         __asm__("movl %0,%%esp ; ret"::"g" ((long) info));

493 }

494

    // �ۼ���ջ����������

    // ��״̬��TOP�ֶ�ֵ��1������7ȡģ��

495 static void fpop(void)

496 {

497         unsigned long tmp;

498

499         tmp = I387.swd & 0xffffc7ff;

500         I387.swd += 0x00000800;

501         I387.swd &= 0x00003800;

502         I387.swd |= tmp;

503 }

504

    // �ۼ���ջ��ջ������

    // ��״̬��TOP�ֶμ�1������7��������7ȡģ��

505 static void fpush(void)

506 {

507         unsigned long tmp;

508

509         tmp = I387.swd & 0xffffc7ff;

510         I387.swd += 0x00003800;

511         I387.swd &= 0x00003800;

512         I387.swd |= tmp;

513 }

514

    // ���������ۼ����Ĵ�����ֵ��

515 static void fxchg(temp_real_unaligned * a, temp_real_unaligned * b)

516 {

517         temp_real_unaligned c;

518

519         c = *a;

520         *a = *b;

521         *b = c;

522 }

523

    // ȡST(i)���ڴ�ָ�롣

    // ȡ״̬����TOP�ֶ�ֵ������ָ�����������ݼĴ����Ų�ȡģ����󷵻�ST(i)��Ӧ��ָ�롣

524 static temp_real_unaligned * __st(int i)

525 {

526         i += I387.swd >> 11;           // ȡ״̬����TOP�ֶ�ֵ��

527         i &= 7;

528         return (temp_real_unaligned *) (i*10 + (char *)(I387.st_space));

529 }

530


 


 

11.2 ����11-2 linux/kernel/math/error.c


  1 /*

  2  * linux/kernel/math/error.c

  3  *

  4  * (C) 1991 Linus Torvalds

  5  */

  6

  7 #include <signal.h>       // �ź�ͷ�ļ��������źŷ��ų������źŽṹ���źŲ�������ԭ�͡�

  8

  9 #include <linux/sched.h>  // ���ȳ���ͷ�ļ�����������ṹtask_struct������0���ݵȡ�

 10

    // Э�����������ж�int16���õĴ���������

    // ��Э��������⵽�Լ���������ʱ���ͻ�ͨ��ERROR����֪ͨCPU������������ڴ���Э����

    // �������ij����źš�����תȥִ�� math_error()�����غ���ת�����ret_from_sys_call

    // ������ִ�С�

 11 void math_error(void)

 12 {

 13         __asm__("fnclex");          // ��80387���״̬���������쳣��־λ��æλ��

 14         if (last_task_used_math)    // ��ʹ����Э��������������Э�����������źš�

 15                 last_task_used_math->signal |= 1<<(SIGFPE-1);

 16 }

 17


 


 

11.3 ����11-3 linux/kernel/math/ea.c


  1 /*

  2  * linux/kernel/math/ea.c

  3  *

  4  * (C) 1991 Linus Torvalds

  5  */

  6

  7 /*

  8  * Calculate the effective address.

  9  */

    /*

     * ������Ч��ַ��

     */

 10

 11 #include <stddef.h>         // ��׼����ͷ�ļ���������ʹ�������е�offsetof()���塣

 12

 13 #include <linux/math_emu.h> // Э������ͷ�ļ���������ʱʵ���ṹ��387�Ĵ���������ȡ�

 14 #include <asm/segment.h>    // �β���ͷ�ļ����������йضμĴ���������Ƕ��ʽ��ຯ����

 15

    // info�ṹ�и����Ĵ����ڽṹ�е�ƫ��λ�á�offsetof()������ָ���ֶ��ڽṹ�е�ƫ��λ

    // �á��μ�include/stddef.h�ļ���

 16 static int __regoffset[] = {

 17         offsetof(struct info,___eax),

 18         offsetof(struct info,___ecx),

 19         offsetof(struct info,___edx),

 20         offsetof(struct info,___ebx),

 21         offsetof(struct info,___esp),

 22         offsetof(struct info,___ebp),

 23         offsetof(struct info,___esi),

 24         offsetof(struct info,___edi)

 25 };

 26

    // ȡinfo�ṹ��ָ��λ�ô��Ĵ������ݡ�

 27 #define REG(x) (*(long *)(__regoffset[(x)]+(char *) info))

 28

    // ��2�ֽ�Ѱַģʽ�е�2������ָʾ�ֽ�SIB��Scale��Index��Base����ֵ��

 29 static char * sib(struct info * info, int mod)

 30 {

 31         unsigned char ss,index,base;

 32         long offset = 0;

 33

    // ���ȴ��û��������ȡ��SIB�ֽڣ�Ȼ��ȡ�������ֶα���λֵ��

 34         base = get_fs_byte((char *) EIP);

 35         EIP++;

 36         ss = base >> 6;                    // �������Ӵ�Сss��

 37         index = (base >> 3) & 7;           // ����ֵ��������index��

 38         base &= 7;                         // ����ַ����base��

    // �����������Ϊ0b100����ʾ������ƫ��ֵ����������ƫ��ֵoffset=��Ӧ�Ĵ�������*�������ӡ�

 39         if (index == 4)

 40                 offset = 0;

 41         else

 42                 offset = REG(index);

 43         offset <<= ss;

    // �����һMODRM�ֽ��е�MOD��Ϊ�㣬����Base������0b101�����ʾ��ƫ��ֵ��baseָ����

    // �Ĵ����С����ƫ��offset��Ҫ�ټ���base��Ӧ�Ĵ����е����ݡ�

 44         if (mod || base != 5)

 45                 offset += REG(base);

    // ���MOD=1�����ʾƫ��ֵΪ1�ֽڡ�������MOD=2������base=0b101����ƫ��ֵΪ4�ֽڡ�

 46         if (mod == 1) {

 47                 offset += (signed char) get_fs_byte((char *) EIP);

 48                 EIP++;

 49         } else if (mod == 2 || base == 5) {

 50                 offset += (signed) get_fs_long((unsigned long *) EIP);

 51                 EIP += 4;

 52         }

    // ��󱣴沢����ƫ��ֵ��

 53         I387.foo = offset;

 54         I387.fos = 0x17;

 55         return (char *) offset;

 56 }

 57

    // ����ָ����Ѱַģʽ�ֽڼ�����Ч��ֵַ��

 58 char * ea(struct info * info, unsigned short code)

 59 {

 60         unsigned char mod,rm;

 61         long * tmp = &EAX;

 62         int offset = 0;

 63

    // ����ȡ�����е�MOD�ֶκ�R/M�ֶ�ֵ�����MOD=0b11����ʾ�ǵ��ֽ�ָ�û��ƫ���ֶΡ�

    // ���R/M�ֶ�=0b100������MOD��Ϊ0b11����ʾ��2�ֽڵ�ַģʽѰַ����˵���sib()��

    // ��ƫ��ֵ�����ؼ��ɡ�

 64         mod = (code >> 6) & 3;          // MOD�ֶΡ�

 65         rm = code & 7;                  // R/M�ֶΡ�

 66         if (rm == 4 && mod != 3)

 67                 return sib(info,mod);

    // ���R/M�ֶ�Ϊ0b101������MODΪ0����ʾ�ǵ��ֽڵ�ַģʽ�����Һ���32�ֽ�ƫ��ֵ��

    // ����ȡ���û�������4�ֽ�ƫ��ֵ�����沢����֮��

 68         if (rm == 5 && !mod) {

 69                 offset = get_fs_long((unsigned long *) EIP);

 70                 EIP += 4;

 71                 I387.foo = offset;

 72                 I387.fos = 0x17;

 73                 return (char *) offset;

 74         }

    // ������������������MOD���д���������ȡ��R/M�����Ӧ�Ĵ������ݵ�ֵ��Ϊָ��tmp��

    // ����MOD=0����ƫ��ֵ������MOD=1���������1�ֽ�ƫ��ֵ������MOD=2���������4�ֽ�

    // ƫ��ֵ����󱣴沢������Ч��ֵַ��

 75         tmp = & REG(rm);

 76         switch (mod) {

 77                 case 0: offset = 0; break;

 78                 case 1:

 79                         offset = (signed char) get_fs_byte((char *) EIP);

 80                         EIP++;

 81                         break;

 82                 case 2:

 83                         offset = (signed) get_fs_long((unsigned long *) EIP);

 84                         EIP += 4;

 85                         break;

 86                 case 3:

 87                         math_abort(info,1<<(SIGILL-1));

 88         }

 89         I387.foo = offset;

 90         I387.fos = 0x17;

 91         return offset + (char *) *tmp;

 92 }

 93


 


 

11.4 ����11-4 linux/kernel/math/convert.c


  1 /*

  2  * linux/kernel/math/convert.c

  3  *

  4  * (C) 1991 Linus Torvalds

  5  */

  6

  7 #include <linux/math_emu.h> // Э������ͷ�ļ���������ʱʵ���ṹ��387�Ĵ���������ȡ�

  8

  9 /*

 10  * NOTE!!! There is some "non-obvious" optimisations in the temp_to_long

 11  * and temp_to_short conversion routines: don't touch them if you don't

 12  * know what's going on. They are the adding of one in the rounding: the

 13  * overflow bit is also used for adding one into the exponent. Thus it

 14  * looks like the overflow would be incorrectly handled, but due to the

 15  * way the IEEE numbers work, things are correct.

 16  *

 17  * There is no checking for total overflow in the conversions, though (ie

 18  * if the temp-real number simply won't fit in a short- or long-real.)

 19  */

    /*

     * ע��!!! ��temp_to_long��temp_to_short��������ת���ӳ�������Щ�������ԡ�

     * ���Ż����������������Ͳ�Ҫ�����޸ġ���������������еļ�1�����λҲͬ

     * ����������ָ���м�1����˿���ȥ�������û�б���ȷ�ش�������������IEEE

     * ��������׼���涨���ݸ�ʽ�IJ�����ʽ����Щ��������ȷ�ġ�

     *

     * ��������û�ж�ת�������������������⣨Ҳ����ʱʵ���Ƿ��ܹ��򵥵ط����

     * ʵ����ʵ����ʽ�У���

     */

 20

    // ��ʵ��ת������ʱʵ����ʽ��

    // ��ʵ��������32λ������Ч����β����������23λ��ָ����8λ������1������λ��

 21 void short_to_temp(const short_real * a, temp_real * b)

 22 {

    // ���ȴ�����ת���Ķ�ʵ����0���������Ϊ0�������ö�Ӧ��ʱʵ��b����Ч��Ϊ0��Ȼ���

    // �ݶ�ʵ������λ������ʱʵ���ķ���λ����exponent�������Чλ��

 23         if (!(*a & 0x7fffffff)) {

 24                 b->a = b->b = 0;                      // ����ʱʵ������Ч�� = 0��

 25                 if (*a)

 26                         b->exponent = 0x8000;        // ���÷���λ��

 27                 else

 28                         b->exponent = 0;

 29                 return;

 30         }

    // ����һ���ʵ������ȷ����Ӧ��ʱʵ����ָ��ֵ��������Ҫ�õ�������ƫ�ñ�ʾ�����ĸ��

    // ��ʵ��ָ����ƫ������127������ʱʵ��ָ����ƫ������16383�������ȡ����ʵ����ָ��ֵ

    // ����Ҫ������е�ƫ����Ϊ 16383�� ��ʱ���γ�����ʱʵ����ʽ��ָ��ֵ exponent�����⣬

    // �����ʵ���Ǹ���������Ҫ������ʱʵ���ķ���λ��λ79������һ������β��ֵ�������ǰ�

    // ��ʵ������8λ����23λβ�������Чλ������ʱʵ����λ62��������ʱʵ��β����λ63

    // ����Ҫ����һ��1������Ҫ����0x80000000����������ʱʵ����32λ��Ч����

 31         b->exponent = ((*a>>23) & 0xff)-127+16383;   // ȡ����ʵ��ָ��λ������ƫ������

 32         if (*a<0)

 33                 b->exponent |= 0x8000;               // ��Ϊ���������÷���λ��

 34         b->b = (*a<<8) | 0x80000000;                 // ����β�������ӹ̶�1ֵ��

 35         b->a = 0;

 36 }

 37

    // ��ʵ��ת������ʱʵ����ʽ��

    // ������short_to_temp()��ȫһ����������ʵ��ָ��ƫ������1023��

 38 void long_to_temp(const long_real * a, temp_real * b)

 39 {

 40         if (!a->a && !(a->b & 0x7fffffff)) {

 41                 b->a = b->b = 0;                     // ����ʱʵ������Ч�� = 0��

 42                 if (a->b)

 43                         b->exponent = 0x8000;        // ���÷���λ��

 44                 else

 45                         b->exponent = 0;

 46                 return;

 47         }

 48         b->exponent = ((a->b >> 20) & 0x7ff)-1023+16383;  // ȡ��ʵ��ָ��������ƫ������

 49         if (a->b<0)

 50                 b->exponent |= 0x8000;               // ��Ϊ���������÷���λ��

 51         b->b = 0x80000000 | (a->b<<11) | (((unsigned long)a->a)>>21); // ����β������1��

 52         b->a = a->a<<11;

 53 }

 54

    // ��ʱʵ��ת���ɶ�ʵ����ʽ��

    // ������short_to_temp()�෴������Ҫ�������Ⱥ��������⡣

 55 void temp_to_short(const temp_real * a, short_real * b)

 56 {

    // ���ָ������Ϊ0����������޷���λ���ö�ʵ��Ϊ-0 ��0��

 57         if (!(a->exponent & 0x7fff)) {

 58                 *b = (a->exponent)?0x80000000:0;

 59                 return;

 60         }

    // �ȴ���ָ�����֡���������ʱʵ��ָ��ƫ������16383��Ϊ��ʵ����ƫ����127��

 61         *b = ((((long) a->exponent)-16383+127) << 23) & 0x7f800000;

 62         if (a->exponent < 0)                         // ���Ǹ��������÷���λ��

 63                 *b |= 0x80000000;

 64         *b |= (a->b >> 8) & 0x007fffff;              // ȡ��ʱʵ����Ч����23λ��

    // ���ݿ������е���������ִ�����������

 65         switch (ROUNDING) {

 66                 case ROUND_NEAREST:

 67                         if ((a->b & 0xff) > 0x80)

 68                                 ++*b;

 69                         break;

 70                 case ROUND_DOWN:

 71                         if ((a->exponent & 0x8000) && (a->b & 0xff))

 72                                 ++*b;

 73                         break;

 74                 case ROUND_UP:

 75                         if (!(a->exponent & 0x8000) && (a->b & 0xff))

 76                                 ++*b;

 77                         break;

 78         }

 79 }

 80

    // ��ʱʵ��ת���ɳ�ʵ����

 81 void temp_to_long(const temp_real * a, long_real * b)

 82 {

 83         if (!(a->exponent & 0x7fff)) {

 84                 b->a = 0;

 85                 b->b = (a->exponent)?0x80000000:0;

 86                 return;

 87         }

 88         b->b = (((0x7fff & (long) a->exponent)-16383+1023) << 20) & 0x7ff00000;

 89         if (a->exponent < 0)

 90                 b->b |= 0x80000000;

 91         b->b |= (a->b >> 11) & 0x000fffff;

 92         b->a = a->b << 21;

 93         b->a |= (a->a >> 11) & 0x001fffff;

 94         switch (ROUNDING) {

 95                 case ROUND_NEAREST:

 96                         if ((a->a & 0x7ff) > 0x400)

 97                                 __asm__("addl $1,%0 ; adcl $0,%1"

 98                                         :"=r" (b->a),"=r" (b->b)

 99                                         :"" (b->a),"1" (b->b));

100                         break;

101                 case ROUND_DOWN:

102                         if ((a->exponent & 0x8000) && (a->b & 0xff))

103                                 __asm__("addl $1,%0 ; adcl $0,%1"

104                                         :"=r" (b->a),"=r" (b->b)

105                                         :"" (b->a),"1" (b->b));

106                         break;

107                 case ROUND_UP:

108                         if (!(a->exponent & 0x8000) && (a->b & 0xff))

109                                 __asm__("addl $1,%0 ; adcl $0,%1"

110                                         :"=r" (b->a),"=r" (b->b)

111                                         :"" (b->a),"1" (b->b));

112                         break;

113         }

114 }

115

    // ��ʱʵ��ת������ʱ������ʽ��

    // ��ʱ����Ҳ��10�ֽڱ�ʾ�����е�8�ֽ����޷�������ֵ����2�ֽڱ�ʾָ��ֵ�ͷ���λ��

    // �����2�ֽ������ЧλΪ1�����ʾ�Ǹ�������λ0����ʾ��������

116 void real_to_int(const temp_real * a, temp_int * b)

117 {

118         int shift =  16383 + 63 - (a->exponent & 0x7fff);

119         unsigned long underflow;

120

121         b->a = b->b = underflow = 0;

122         b->sign = (a->exponent < 0);

123         if (shift < 0) {

124                 set_OE();

125                 return;

126         }

127         if (shift < 32) {

128                 b->b = a->b; b->a = a->a;

129         } else if (shift < 64) {

130                 b->a = a->b; underflow = a->a;

131                 shift -= 32;

132         } else if (shift < 96) {

133                 underflow = a->b;

134                 shift -= 64;

135         } else

136                 return;

137         __asm__("shrdl %2,%1,%0"

138                 :"=r" (underflow),"=r" (b->a)

139                 :"c" ((char) shift),"" (underflow),"1" (b->a));

140         __asm__("shrdl %2,%1,%0"

141                 :"=r" (b->a),"=r" (b->b)

142                 :"c" ((char) shift),"" (b->a),"1" (b->b));

143         __asm__("shrl %1,%0"

144                 :"=r" (b->b)

145                 :"c" ((char) shift),"" (b->b));

146         switch (ROUNDING) {

147                 case ROUND_NEAREST:

148                         __asm__("addl %4,%5 ; adcl $0,%0 ; adcl $0,%1"

149                                 :"=r" (b->a),"=r" (b->b)

150                                 :"" (b->a),"1" (b->b)

151                                 ,"r" (0x7fffffff + (b->a & 1))

152                                 ,"m" (*&underflow));

153                         break;

154                 case ROUND_UP:

155                         if (!b->sign && underflow)

156                                 __asm__("addl $1,%0 ; adcl $0,%1"

157                                         :"=r" (b->a),"=r" (b->b)

158                                         :"" (b->a),"1" (b->b));

159                         break;

160                 case ROUND_DOWN:

161                         if (b->sign && underflow)

162                                 __asm__("addl $1,%0 ; adcl $0,%1"

163                                         :"=r" (b->a),"=r" (b->b)

164                                         :"" (b->a),"1" (b->b));

165                         break;

166         }

167 }

168

    // ��ʱ����ת������ʱʵ����ʽ��

169 void int_to_real(const temp_int * a, temp_real * b)

170 {

    // ����ԭֵ������������ת������ʱʵ��ʱָ��������Ҫ����ƫ����16383�⣬��Ҫ����63��

    // ��ʾ��Ч��Ҫ����2��63�η�������������ֵ��

171         b->a = a->a;

172         b->b = a->b;

173         if (b->a || b->b)

174                 b->exponent = 16383 + 63 + (a->sign? 0x8000:0);

175         else {

176                 b->exponent = 0;

177                 return;

178         }

    // �Ը�ʽת�������ʱʵ�����й�񻯴�����������Ч�������Чλ����0��

179         while (b->b >= 0) {

180                 b->exponent--;

181                 __asm__("addl %0,%0 ; adcl %1,%1"

182                         :"=r" (b->a),"=r" (b->b)

183                         :"" (b->a),"1" (b->b));

184         }

185 }

186


 


 

11.5 ����11-5 linux/kernel/math/add.c


  1 /*

  2  * linux/kernel/math/add.c

  3  *

  4  * (C) 1991 Linus Torvalds

  5  */

  6

  7 /*

  8  * temporary real addition routine.

  9  *

 10  * NOTE! These aren't exact: they are only 62 bits wide, and don't do

 11  * correct rounding. Fast hack. The reason is that we shift right the

 12  * values by two, in order not to have overflow (1 bit), and to be able

 13  * to move the sign into the mantissa (1 bit). Much simpler algorithms,

 14  * and 62 bits (61 really - no rounding) accuracy is usually enough. The

 15  * only time you should notice anything weird is when adding 64-bit

 16  * integers together. When using doubles (52 bits accuracy), the

 17  * 61-bit accuracy never shows at all.

 18  */

    /*

     * ��ʱʵ���ӷ��ӳ���

     *

     * ע�⣡ ��Щ������ȷ������ֻ��62���ؿ��ȣ����Ҳ��ܽ�����ȷ�����������

     * ��Щ���Dzݾ�֮����ԭ����Ϊ�˲��������1���أ������ǰ�ֵ������2λ��

     * ����ʹ�÷���λ��1���أ��ܹ�����β���С����Ƿdz��򵥵��㷨������62λ

     * ��ʵ������61λ - û�����룩�ľ���ͨ��Ҳ�㹻�ˡ�ֻ�е����64λ������

     * ���ʱ�Żᷢ��һЩ��ֵ����⡣��ʹ��˫���ȣ�52���ؾ��ȣ�����ʱ������

     * Զ�����ܳ���61���ؾ��ȵġ�

     */

 19

 20 #include <linux/math_emu.h> // Э������ͷ�ļ���������ʱʵ���ṹ��387�Ĵ���������ȡ�

 21

    // ��һ�����ĸ����������Ʋ��룩��ʾ��

    // ����ʱʵ��β������Ч����ȡ�����ټ�1��

    // ����a����ʱʵ���ṹ������a��b�ֶ������ʵ������Ч����

 22 #define NEGINT(a) \

 23 __asm__("notl %0 ; notl %1 ; addl $1,%0 ; adcl $0,%1" \

 24         :"=r" (a->a),"=r" (a->b) \

 25         :"" (a->a),"1" (a->b))

 26

    // β�����Ż���

    // ������ʱʵ���任��ָ����������ʾ��ʽ���Ա��ڷ������㡣��������������Ϊ�����ʽ��

 27 static void signify(temp_real * a)

 28 {

    // ��64λ������β������2λ�����ָ����Ҫ��2������Ϊָ���ֶ�exponent����߱���λ��

    // ����λ��������ָ��ֵС���㣬˵�������Ǹ������������β���ò����ʾ��ȡ������Ȼ���

    // ָ��ȡ��ֵ����ʱβ���в��������ƹ�2λ����Ч�������һ�������ֵ�ķ���λ��

    // 30���ϣ�%0 - a->a��%1 - a->b�����ָ�shrdl $2, %1, %0��ִ��˫���ȣ�64λ�����ƣ�

    // �������β��<b,a>����2λ�����ڸ��ƶ���������ı�%1��a->b���е�ֵ����˻���Ҫ����

    // ��������2λ��

 29         a->exponent += 2;

 30         __asm__("shrdl $2,%1,%0 ; shrl $2,%1"   // ʹ��˫����ָ���β������2λ��

 31                 :"=r" (a->a),"=r" (a->b)

 32                 :"" (a->a),"1" (a->b));

 33         if (a->exponent < 0)                   // �Ǹ�������β���ò����ʾ��ȡ��ֵ����

 34                 NEGINT(a);

 35         a->exponent &= 0x7fff;                 // ȥ������λ�����У���

 36 }

 37

    // β���Ƿ��Ż���

    // �������ʽת��Ϊ��ʱʵ����ʽ������ָ����������ʾ��ʵ��ת��Ϊ��ʱʵ����ʽ��

 38 static void unsignify(temp_real * a)

 39 {

    // ����ֵΪ0�������ô�����ֱ�ӷ��ء����������ȸ�λ��ʱʵ����ʽ�ķ���λ��Ȼ���ж�

    // β���ĸ�λlong�ֶ�a->b�Ƿ���з���λ�����У����� exponent �ֶ����ӷ���λ��ͬʱ

    // ��β�����޷�������ʽ��ʾ��ȡ����������β�����й�񻯴�����ͬʱָ��ֵ����Ӧ�ݼ���

    // ��ִ�����Ʋ�����ʹ��β�������Чλ��Ϊ0�����a->bֵ����Ϊ��ֵ����

 40         if (!(a->a || a->b)) {                 // ��ֵΪ0�ͷ��ء�

 41                 a->exponent = 0;

 42                 return;

 43         }

 44         a->exponent &= 0x7fff;                 // ȥ������λ�����У���

 45         if (a->b < 0) {                        // �Ǹ�������β��ȡ��ֵ��

 46                 NEGINT(a);

 47                 a->exponent |= 0x8000;         // ��ʱʵ�������÷���λ��

 48         }

 49         while (a->b >= 0) {

 50                 a->exponent--;                 // ��β�����й�񻯴�����

 51                 __asm__("addl %0,%0 ; adcl %1,%1"

 52                         :"=r" (a->a),"=r" (a->b)

 53                         :"" (a->a),"1" (a->b));

 54         }

 55 }

 56

    // ���渡��ӷ�ָ�����㡣

    // ��ʱʵ������ src1 + src2 �� result��

 57 void fadd(const temp_real * src1, const temp_real * src2, temp_real * result)

 58 {

 59         temp_real a,b;

 60         int x1,x2,shift;

 61

    // ����ȡ��������ָ��ֵx1��x2��ȥ������λ����Ȼ���ñ���a�����������ֵ��shiftΪָ��

    // ��ֵ�������2�ı���ֵ����

 62         x1 = src1->exponent & 0x7fff;

 63         x2 = src2->exponent & 0x7fff;

 64         if (x1 > x2) {

 65                 a = *src1;

 66                 b = *src2;

 67                 shift = x1-x2;

 68         } else {

 69                 a = *src2;

 70                 b = *src1;

 71                 shift = x2-x1;

 72         }

    // ���������̫�󣬴��ڵ���2��64�η��������ǿ��Ժ���С���Ǹ�������bֵ������ֱ�ӷ�

    // ��aֵ���ɡ������������ڵ���2��32�η�����ô���ǿ��Ժ���Сֵb�еĵ�32λֵ��

    // �������ǰ� b�ĸ�long�ֶ�ֵ b.b����32λ�����ŵ�b.a�С�Ȼ���b��ָ��ֵ��Ӧ����

    // ��32�η�����ָ����ֵ��ȥ32����������֮����ӵ���������β��������������ͬ�����С�

 73         if (shift >= 64) {

 74                 *result = a;

 75                 return;

 76         }

 77         if (shift >= 32) {

 78                 b.a = b.b;

 79                 b.b = 0;

 80                 shift -= 32;

 81         }

    // �����ٽ���ϸ�µص������Խ�������ߵ�������ͬ�����������ǰ�Сֵb��β������shift

    // ������λ���������ߵ�ָ����ͬ������ͬһ���������¡����ǾͿ��Զ�β��������������ˡ�

    // ���֮ǰ������Ҫ�Ȱ�����ת���ɷ��������ʽ���ڼӷ�������ٱ任����ʱʵ����ʽ��

 82         __asm__("shrdl %4,%1,%0 ; shrl %4,%1"              // ˫���ȣ�64λ�����ơ�

 83                 :"=r" (b.a),"=r" (b.b)

 84                 :"" (b.a),"1" (b.b),"c" ((char) shift));

 85         signify(&a);                                       // �任��ʽ��

 86         signify(&b);

 87         __asm__("addl %4,%0 ; adcl %5,%1"                  // ִ�мӷ����㡣

 88                 :"=r" (a.a),"=r" (a.b)

 89                 :"" (a.a),"1" (a.b),"g" (b.a),"g" (b.b));

 90         unsignify(&a);                                     // �ٱ任����ʱʵ����ʽ��

 91         *result = a;

 92 }

 93


 


 

11.6 ����11-6 linux/kernel/math/compare.c


  1 /*

  2  * linux/kernel/math/compare.c

  3  *

  4  * (C) 1991 Linus Torvalds

  5  */

  6

  7 /*

  8  * temporary real comparison routines

  9  */

    /*

     * �ۼ�������ʱʵ���Ƚ��ӳ���

     */

 10

 11 #include <linux/math_emu.h> // Э������ͷ�ļ���������ʱʵ���ṹ��387�Ĵ���������ȡ�

 12

    // ��λ״̬���е�C3��C2��C1��C0����λ��

 13 #define clear_Cx() (I387.swd &= ~0x4500)

 14

    // ����ʱʵ��a���й�񻯴���������ʾ��ָ������Ч����ʽ��

    // ���磺102.345 ��ʾ�� 1.02345 X 102�� 0.0001234 ��ʾ�� 1.234 X 10-4����Ȼ����������

    // �����Ʊ�ʾ��

 15 static void normalize(temp_real * a)

 16 {

 17         int i = a->exponent & 0x7fff;           // ȡָ��ֵ����ȥ����λ����

 18         int sign = a->exponent & 0x8000;        // ȡ����λ��

 19

    // �����ʱʵ��a��64λ��Ч����β����Ϊ0����ô˵��a����0��������a��ָ���������ء�

 20         if (!(a->a || a->b)) {

 21                 a->exponent = 0;

 22                 return;

 23         }

    // ���a��β���������0ֵ����λ����ô��β�����ƣ�ͬʱ����ָ��ֵ���ݼ�����ֱ��β��

    // ��b�ֶ������ЧλMSB��1λ�ã���ʱb����Ϊ��ֵ��������������Ϸ���λ��

 24         while (i && a->b >= 0) {

 25                 i--;

 26                 __asm__("addl %0,%0 ; adcl %1,%1"

 27                         :"=r" (a->a),"=r" (a->b)

 28                         :"" (a->a),"1" (a->b));

 29         }

 30         a->exponent = i | sign;

 31 }

 32

    // ���渡��ָ��FTST��

    // ��ջ���ۼ���ST(0)��0�Ƚϣ������ݱȽϽ����������λ����ST > 0.0����C3��C2��C0

    // �ֱ�Ϊ000����ST < 0.0��������λΪ001����ST == 0.0��������λ��100�������ɱȽϣ�

    // ������λΪ111��

 33 void ftst(const temp_real * a)

 34 {

 35         temp_real b;

 36

    // ������״̬����������־λ�����ԱȽ�ֵb��ST�����й�񻯴�������b�������㲢������

    // �˷���λ���Ǹ�����������������λC0��������������λC3��

 37         clear_Cx();

 38         b = *a;

 39         normalize(&b);

 40         if (b.a || b.b || b.exponent) {

 41                 if (b.exponent < 0)

 42                         set_C0();

 43         } else

 44                 set_C3();

 45 }

 46

    // ���渡��ָ��FCOM��

    // �Ƚ���������src1��src2�������ݱȽϽ����������λ����src1 > src2����C3��C2��C0

    // �ֱ�Ϊ000����src1 < src2��������λΪ001����������ȣ�������λ��100��

 47 void fcom(const temp_real * src1, const temp_real * src2)

 48 {

 49         temp_real a;

 50

 51         a = *src1;

 52         a.exponent ^= 0x8000;                   // ����λȡ����

 53         fadd(&a,src2,&a);                       // ������ӣ����������

 54         ftst(&a);                               // ���Խ������������λ��

 55 }

 56

    // ���渡��ָ��FUCOM���޴���Ƚϣ���

    // ���ڲ�����֮һ��NaN�ıȽϡ�

 57 void fucom(const temp_real * src1, const temp_real * src2)

 58 {

 59         fcom(src1,src2);

 60 }

 61


 


 

11.7 ����11-7 linux/kernel/math/get_put.c


  1 /*

  2  * linux/kernel/math/get_put.c

  3  *

  4  * (C) 1991 Linus Torvalds

  5  */

  6

  7 /*

  8  * This file handles all accesses to user memory: getting and putting

  9  * ints/reals/BCD etc. This is the only part that concerns itself with

 10  * other than temporary real format. All other cals are strictly temp_real.

 11  */

    /*

     * �����������ж��û��ڴ�ķ��ʣ���ȡ�ʹ���ָ��/ʵ��ֵ/BCD��ֵ�ȡ�����

     * �漰��ʱʵ������������ʽ���еIJ��֡�������������ȫ��ʹ����ʱʵ����ʽ��

     */

 12 #include <signal.h>       // �ź�ͷ�ļ��������źŷ��ţ��źŽṹ���źŲ�������ԭ�͡�

 13

 14 #include <linux/math_emu.h> // Э������ͷ�ļ���������ʱʵ���ṹ��387�Ĵ���������ȡ�

 15 #include <linux/kernel.h>   // �ں�ͷ�ļ�������һЩ�ں˳��ú�����ԭ�ζ��塣

 16 #include <asm/segment.h>    // �β���ͷ�ļ����������йضμĴ���������Ƕ��ʽ��ຯ����

 17

    // ȡ�û��ڴ��еĶ�ʵ����������ʵ������

    // ���ݸ���ָ�������Ѱַģʽ�ֽ��е����ݺ�info�ṹ�е�ǰ�Ĵ����е����ݣ�ȡ�ö�ʵ��

    // ������Ч��ַ��math/ea.c����Ȼ����û���������ȡ��Ӧʵ��ֵ�������û���ʵ��ת����

    // ��ʱʵ����math/convert.c����

    // ������tmp �C ת������ʱʵ�����ָ�룻info �C info�ṹָ�룻code �C ָ����롣

 18 void get_short_real(temp_real * tmp,

 19         struct info * info, unsigned short code)

 20 {

 21         char * addr;

 22         short_real sr;

 23

 24         addr = ea(info,code);                        // ������Ч��ַ��

 25         sr = get_fs_long((unsigned long *) addr);    // ȡ�û��������е�ֵ��

 26         short_to_temp(&sr,tmp);                      // ת������ʱʵ����ʽ��

 27 }

 28

    // ȡ�û��ڴ��еij�ʵ����˫����ʵ������

    // ���ȸ��ݸ���ָ�������Ѱַģʽ�ֽ��е����ݺ�info�ṹ�е�ǰ�Ĵ����е����ݣ�ȡ�ó�

    // ʵ��������Ч��ַ��math/ea.c����Ȼ����û���������ȡ��Ӧʵ��ֵ�������û�ʵ��ֵת

    // ������ʱʵ����math/convert.c����

    // ������tmp �C ת������ʱʵ�����ָ�룻info �C info�ṹָ�룻code �C ָ����롣

 29 void get_long_real(temp_real * tmp,

 30         struct info * info, unsigned short code)

 31 {

 32         char * addr;

 33         long_real lr;

 34

 35         addr = ea(info,code);                             // ȡָ���е���Ч��ֵַ��

 36         lr.a = get_fs_long((unsigned long *) addr);       // ȡ��8�ֽ�ʵ����

 37         lr.b = get_fs_long(1 + (unsigned long *) addr);

 38         long_to_temp(&lr,tmp);                            // ת������ʱʵ����ʽ��

 39 }

 40

    // ȡ�û��ڴ��е���ʱʵ����

    // ���ȸ��ݸ���ָ�������Ѱַģʽ�ֽ��е����ݺ�info�ṹ�е�ǰ�Ĵ����е����ݣ�ȡ����

    // ʱʵ��������Ч��ַ��math/ea.c����Ȼ����û���������ȡ��Ӧ��ʱʵ��ֵ��

    // ������tmp �C ת������ʱʵ�����ָ�룻info �C info�ṹָ�룻code �C ָ����롣

 41 void get_temp_real(temp_real * tmp,

 42         struct info * info, unsigned short code)

 43 {

 44         char * addr;

 45

 46         addr = ea(info,code);                             // ȡָ���е���Ч��ֵַ��

 47         tmp->a = get_fs_long((unsigned long *) addr);

 48         tmp->b = get_fs_long(1 + (unsigned long *) addr);

 49         tmp->exponent = get_fs_word(4 + (unsigned short *) addr);

 50 }

 51

    // ȡ�û��ڴ��еĶ�������ת������ʱʵ����ʽ��

    // ��ʱ����Ҳ��10�ֽڱ�ʾ�����е�8�ֽ����޷�������ֵ����2�ֽڱ�ʾָ��ֵ�ͷ���λ��

    // �����2�ֽ������ЧλΪ1�����ʾ�Ǹ������������Чλ��0����ʾ��������

    // �ú������ȸ��ݸ���ָ�������Ѱַģʽ�ֽ��е����ݺ� info�ṹ�е�ǰ�Ĵ����е����ݣ�

    // ȡ�ö�����������Ч��ַ��math/ea.c����Ȼ����û���������ȡ��Ӧ����ֵ��������Ϊ��ʱ

    // ������ʽ��������ʱ����ֵת������ʱʵ����math/convert.c����

    // ������tmp �C ת������ʱʵ�����ָ�룻info �C info�ṹָ�룻code �C ָ����롣

 52 void get_short_int(temp_real * tmp,

 53         struct info * info, unsigned short code)

 54 {

 55         char * addr;

 56         temp_int ti;

 57

 58         addr = ea(info,code);               // ȡָ���е���Ч��ֵַ��

 59         ti.a = (signed short) get_fs_word((unsigned short *) addr);

 60         ti.b = 0;

 61         if (ti.sign = (ti.a < 0))           // ���Ǹ�������������ʱ��������λ��

 62                 ti.a = - ti.a;              // ��ʱ������β��������Ϊ�޷�������

 63         int_to_real(&ti,tmp);               // ����ʱ����ת������ʱʵ����ʽ��

 64 }

 65

    // ȡ�û��ڴ��еij�������ת������ʱʵ����ʽ��

    // ���ȸ��ݸ���ָ�������Ѱַģʽ�ֽ��е����ݺ�info�ṹ�е�ǰ�Ĵ����е����ݣ�ȡ�ó�

    // ����������Ч��ַ��math/ea.c����Ȼ����û���������ȡ��Ӧ����ֵ��������Ϊ��ʱ������

    // ʽ��������ʱ����ֵת������ʱʵ����math/convert.c����

    // ������tmp �C ת������ʱʵ�����ָ�룻info �C info�ṹָ�룻code �C ָ����롣

 66 void get_long_int(temp_real * tmp,

 67         struct info * info, unsigned short code)

 68 {

 69         char * addr;

 70         temp_int ti;

 71

 72         addr = ea(info,code);               // ȡָ���е���Ч��ֵַ��

 73         ti.a = get_fs_long((unsigned long *) addr);

 74         ti.b = 0;

 75         if (ti.sign = (ti.a < 0))           // ���Ǹ�������������ʱ��������λ��

 76                 ti.a = - ti.a;              // ��ʱ������β��������Ϊ�޷�������

 77         int_to_real(&ti,tmp);               // ����ʱ����ת������ʱʵ����ʽ��

 78 }

 79

    // ȡ�û��ڴ��е�64λ��������ת������ʱʵ����ʽ��

    // ���ȸ��ݸ���ָ�������Ѱַģʽ�ֽ��е����ݺ�info �ṹ�е�ǰ�Ĵ����е����ݣ�ȡ��

    // 64λ������������Ч��ַ��math/ea.c����Ȼ����û���������ȡ��Ӧ����ֵ��������Ϊ��

    // ʱ������ʽ������ٰ���ʱ����ֵת������ʱʵ����math/convert.c����

    // ������tmp �C ת������ʱʵ�����ָ�룻info �C info�ṹָ�룻code �C ָ����롣

 80 void get_longlong_int(temp_real * tmp,

 81         struct info * info, unsigned short code)

 82 {

 83         char * addr;

 84         temp_int ti;

 85

 86         addr = ea(info,code);                            // ȡָ���е���Ч��ֵַ��

 87         ti.a = get_fs_long((unsigned long *) addr);      // ȡ�û�64λ��������

 88         ti.b = get_fs_long(1 + (unsigned long *) addr);

 89         if (ti.sign = (ti.b < 0))                   // ���Ǹ�����������ʱ��������λ��

 90                 __asm__("notl %0 ; notl %1\n\t"     // ͬʱȡ����1�ͽ�λ������

 91                         "addl $1,%0 ; adcl $0,%1"

 92                         :"=r" (ti.a),"=r" (ti.b)

 93                         :"" (ti.a),"1" (ti.b));

 94         int_to_real(&ti,tmp);                       // ����ʱ����ת������ʱʵ����ʽ��

 95 }

 96

    // ��һ��64λ����������N����10��

    // �������������BCD����ֵת������ʱʵ����ʽ�����С������ǣ�N<<1 + N<<3��

 97 #define MUL10(low,high) \

 98 __asm__("addl %0,%0 ; adcl %1,%1\n\t" \

 99 "movl %0,%%ecx ; movl %1,%%ebx\n\t" \

100 "addl %0,%0 ; adcl %1,%1\n\t" \

101 "addl %0,%0 ; adcl %1,%1\n\t" \

102 "addl %%ecx,%0 ; adcl %%ebx,%1" \

103 :"=a" (low),"=d" (high) \

104 :"" (low),"1" (high):"cx","bx")

105

    // 64λ�ӷ���

    // ��32λ���޷�����val�ӵ�64λ�� <high,low> �С�

106 #define ADD64(val,low,high) \

107 __asm__("addl %4,%0 ; adcl $0,%1":"=r" (low),"=r" (high) \

108 :"" (low),"1" (high),"r" ((unsigned long) (val)))

109

    // ȡ�û��ڴ��е�BCD����ֵ��ת������ʱʵ����ʽ��

    // �ú������ȸ��ݸ���ָ�������Ѱַģʽ�ֽ��е����ݺ�info �ṹ�е�ǰ�Ĵ����е����ݣ�

    // ȡ�� BCD��������Ч��ַ��math/ea.c����Ȼ����û���������ȡ 10�ֽ���ӦBCD��ֵ����

    // ��1�ֽ����ڷ��ţ���ͬʱת������ʱ������ʽ��������ʱ����ֵת������ʱʵ����

    // ������tmp �C ת������ʱʵ�����ָ�룻info �C info�ṹָ�룻code �C ָ����롣

110 void get_BCD(temp_real * tmp, struct info * info, unsigned short code)

111 {

112         int k;

113         char * addr;

114         temp_int i;

115         unsigned char c;

116

    // ȡ��BCD����ֵ�����ڴ���Ч��ַ��Ȼ������1��BCD���ֽڣ������Чλ����ʼ������

    // ��ȡ��BCD����ֵ�ķ���λ����������ʱ�����ķ���λ��Ȼ���9�ֽڵ�BCD��ֵת����

    // ��ʱ������ʽ������ٰ���ʱ����ֵת������ʱʵ����

117         addr = ea(info,code);                      // ȡ��Ч��ַ��

118         addr += 9;                                 // ָ�����һ������10�����ֽڡ�

119         i.sign = 0x80 & get_fs_byte(addr--);       // ȡ���з���λ��

120         i.a = i.b = 0;

121         for (k = 0; k < 9; k++) {                  // ת������ʱ������ʽ��

122                 c = get_fs_byte(addr--);

123                 MUL10(i.a, i.b);

124                 ADD64((c>>4), i.a, i.b);

125                 MUL10(i.a, i.b);

126                 ADD64((c&0xf), i.a, i.b);

127         }

128         int_to_real(&i,tmp);                       // ת������ʱʵ����ʽ��

129 }

130

    // ���������Զ̣������ȣ�ʵ����ʽ���浽�û��������С�

    // �ú������ȸ��ݸ���ָ�������Ѱַģʽ�ֽ��е����ݺ�info �ṹ�е�ǰ�Ĵ����е����ݣ�

    // ȡ�ñ���������Ч��ַaddr��Ȼ�����ʱʵ����ʽ�Ľ��ת���ɶ�ʵ����ʽ���洢����Ч

    // ��ַaddr����

    // ������tmp �C ��ʱʵ����ʽ���ֵ��info �C info�ṹָ�룻code �C ָ����롣

131 void put_short_real(const temp_real * tmp,

132         struct info * info, unsigned short code)

133 {

134         char * addr;

135         short_real sr;

136

137         addr = ea(info,code);                       // ȡ��Ч��ַ��

138         verify_area(addr,4);                        // Ϊ��������֤������ڴ档

139         temp_to_short(tmp,&sr);                     // ���ת���ɶ�ʵ����ʽ��

140         put_fs_long(sr,(unsigned long *) addr);     // �洢���ݵ��û��ڴ�����

141 }

142

    // ���������Գ���˫���ȣ�ʵ����ʽ���浽�û��������С�

    // �ú������ȸ��ݸ���ָ�������Ѱַģʽ�ֽ��е����ݺ�info �ṹ�е�ǰ�Ĵ����е����ݣ�

    // ȡ�ñ���������Ч��ַaddr��Ȼ�����ʱʵ����ʽ�Ľ��ת���ɳ�ʵ����ʽ�����洢����

    // Ч��ַaddr����

    // ������tmp �C ��ʱʵ����ʽ���ֵ��info �C info�ṹָ�룻code �C ָ����롣

143 void put_long_real(const temp_real * tmp,

144         struct info * info, unsigned short code)

145 {

146         char * addr;

147         long_real lr;

148

149         addr = ea(info,code);                         // ȡ��Ч��ַ��

150         verify_area(addr,8);                          // Ϊ��������֤������ڴ档

151         temp_to_long(tmp,&lr);                       // ���ת���ɳ�ʵ����ʽ��

152         put_fs_long(lr.a, (unsigned long *) addr);   // �洢���ݵ��û��ڴ�����

153         put_fs_long(lr.b, 1 + (unsigned long *) addr);

154 }

155

    // ������������ʱʵ����ʽ���浽�û��������С�

    // �ú������ȸ��ݸ���ָ�������Ѱַģʽ�ֽ��е����ݺ�info �ṹ�е�ǰ�Ĵ����е����ݣ�

    // ȡ�ñ���������Ч��ַaddr��Ȼ�����ʱʵ���洢����Ч��ַaddr����

    // ������tmp �C ��ʱʵ����ʽ���ֵ��info �C info�ṹָ�룻code �C ָ����롣

156 void put_temp_real(const temp_real * tmp,

157         struct info * info, unsigned short code)

158 {

159         char * addr;

160

161         addr = ea(info,code);                        // ȡ��Ч��ַ��

162         verify_area(addr,10);                        // Ϊ��������֤������ڴ档

163         put_fs_long(tmp->a, (unsigned long *) addr); // �洢���ݵ��û��ڴ�����

164         put_fs_long(tmp->b, 1 + (unsigned long *) addr);

165         put_fs_word(tmp->exponent, 4 + (short *) addr);

166 }

167

    // ���������Զ�������ʽ���浽�û��������С�

    // �ú������ȸ��ݸ���ָ�������Ѱַģʽ�ֽ��е����ݺ�info �ṹ�е�ǰ�Ĵ����е����ݣ�

    // ȡ�ñ���������Ч��ַaddr��Ȼ�����ʱʵ����ʽ�Ľ��ת������ʱ������ʽ������Ǹ�

    // ����������������λ�������������浽�û��ڴ��С�

    // ������tmp �C ��ʱʵ����ʽ���ֵ��info �C info�ṹָ�룻code �C ָ����롣

168 void put_short_int(const temp_real * tmp,

169         struct info * info, unsigned short code)

170 {

171         char * addr;

172         temp_int ti;

173

174         addr = ea(info,code);                        // ȡ��Ч��ַ��

175         real_to_int(tmp,&ti);                        // ת������ʱ������ʽ��

176         verify_area(addr,2);                         // ��֤�����洢�ڴ档

177         if (ti.sign)                                 // ���з���λ����ȡ����ֵ��

178                 ti.a = -ti.a;

179         put_fs_word(ti.a,(short *) addr);            // �洢���û��������С�

180 }

181

    // ���������Գ�������ʽ���浽�û��������С�

    // �ú������ȸ��ݸ���ָ�������Ѱַģʽ�ֽ��е����ݺ�info �ṹ�е�ǰ�Ĵ����е����ݣ�

    // ȡ�ñ���������Ч��ַaddr��Ȼ�����ʱʵ����ʽ�Ľ��ת������ʱ������ʽ������Ǹ�

    // ����������������λ�������������浽�û��ڴ��С�

    // ������tmp �C ��ʱʵ����ʽ���ֵ��info �C info�ṹָ�룻code �C ָ����롣

182 void put_long_int(const temp_real * tmp,

183         struct info * info, unsigned short code)

184 {

185         char * addr;

186         temp_int ti;

187

188         addr = ea(info,code);                        // ȡ��Ч��ַ��

189         real_to_int(tmp,&ti);                        // ת������ʱ������ʽ��

190         verify_area(addr,4);                         // ��֤�����洢�ڴ档

191         if (ti.sign)                                 // ���з���λ����ȡ����ֵ��

192                 ti.a = -ti.a;

193         put_fs_long(ti.a,(unsigned long *) addr);    // �洢���û��������С�

194 }

195

    // ����������64λ������ʽ���浽�û��������С�

    // �ú������ȸ��ݸ���ָ�������Ѱַģʽ�ֽ��е����ݺ�info �ṹ�е�ǰ�Ĵ����е����ݣ�

    // ȡ�ñ���������Ч��ַaddr��Ȼ�����ʱʵ����ʽ�Ľ��ת������ʱ������ʽ������Ǹ�

    // ����������������λ�������������浽�û��ڴ��С�

    // ������tmp �C ��ʱʵ����ʽ���ֵ��info �C info�ṹָ�룻code �C ָ����롣

196 void put_longlong_int(const temp_real * tmp,

197         struct info * info, unsigned short code)

198 {

199         char * addr;

200         temp_int ti;

201

202         addr = ea(info,code);                        // ȡ��Ч��ַ��

203         real_to_int(tmp,&ti);                        // ת������ʱ������ʽ��

204         verify_area(addr,8);                         // ��֤�洢����

205         if (ti.sign)                                 // ���Ǹ�������ȡ����1��

206                 __asm__("notl %0 ; notl %1\n\t"

207                         "addl $1,%0 ; adcl $0,%1"

208                         :"=r" (ti.a),"=r" (ti.b)

209                         :"" (ti.a),"1" (ti.b));

210         put_fs_long(ti.a,(unsigned long *) addr);       // �洢���û��������С�

211         put_fs_long(ti.b,1 + (unsigned long *) addr);

212 }

213

    // �޷�����<high, low>����10����������rem�С�

214 #define DIV10(low,high,rem) \

215 __asm__("divl %6 ; xchgl %1,%2 ; divl %6" \

216         :"=d" (rem),"=a" (low),"=b" (high) \

217         :"" (0),"1" (high),"2" (low),"c" (10))

218

    // ����������BCD���ʽ���浽�û��������С�

    // �ú������ȸ��ݸ���ָ�������Ѱַģʽ�ֽ��е����ݺ�info �ṹ�е�ǰ�Ĵ����е����ݣ�

    // ȡ�ñ���������Ч��ַaddr������֤����10�ֽ�BCD����û��ռ䡣Ȼ�����ʱʵ����ʽ

    // �Ľ��ת����BCD���ʽ�����ݲ����浽�û��ڴ��С�����Ǹ�����������ߴ洢�ֽڵ����

    // ��Чλ��

    // ������tmp �C ��ʱʵ����ʽ���ֵ��info �C info�ṹָ�룻code �C ָ����롣

219 void put_BCD(const temp_real * tmp,struct info * info, unsigned short code)

220 {

221         int k,rem;

222         char * addr;

223         temp_int i;

224         unsigned char c;

225

226         addr = ea(info,code);                        // ȡ��Ч��ַ��

227         verify_area(addr,10);                        // ��֤�洢�ռ�������

228         real_to_int(tmp,&i);                         // ת������ʱ������ʽ��

229         if (i.sign)                           // ���Ǹ����������÷����ֽ������Чλ��

230                 put_fs_byte(0x80, addr+9);

231         else                                         // ��������ֽ�����Ϊ0��

232                 put_fs_byte(0, addr+9);

233         for (k = 0; k < 9; k++) {                    // ��ʱ����ת����BCD�벢���档

234                 DIV10(i.a,i.b,rem);

235                 c = rem;

236                 DIV10(i.a,i.b,rem);

237                 c += rem<<4;

238                 put_fs_byte(c,addr++);

239         }

240 }

241


 


 

11.8 ����11-8 linux/kernel/math/mul.c


  1 /*

  2  * linux/kernel/math/mul.c

  3  *

  4  * (C) 1991 Linus Torvalds

  5  */

  6

  7 /*

  8  * temporary real multiplication routine.

  9  */

    /*

     * ��ʱʵ���˷��ӳ���

     */

 10

 11 #include <linux/math_emu.h> // Э������ͷ�ļ���������ʱʵ���ṹ��387�Ĵ���������ȡ�

 12

    // ��cָ�봦��16�ֽ�ֵ����1λ����2����

 13 static void shift(int * c)

 14 {

 15         __asm__("movl (%0),%%eax ; addl %%eax,(%0)\n\t"

 16                 "movl 4(%0),%%eax ; adcl %%eax,4(%0)\n\t"

 17                 "movl 8(%0),%%eax ; adcl %%eax,8(%0)\n\t"

 18                 "movl 12(%0),%%eax ; adcl %%eax,12(%0)"

 19                 ::"r" ((long) c):"ax");

 20 }

 21

    // 2����ʱʵ����ˣ��������cָ�봦��16�ֽڣ���

 22 static void mul64(const temp_real * a, const temp_real * b, int * c)

 23 {

 24         __asm__("movl (%0),%%eax\n\t"

 25                 "mull (%1)\n\t"

 26                 "movl %%eax,(%2)\n\t"

 27                 "movl %%edx,4(%2)\n\t"

 28                 "movl 4(%0),%%eax\n\t"

 29                 "mull 4(%1)\n\t"

 30                 "movl %%eax,8(%2)\n\t"

 31                 "movl %%edx,12(%2)\n\t"

 32                 "movl (%0),%%eax\n\t"

 33                 "mull 4(%1)\n\t"

 34                 "addl %%eax,4(%2)\n\t"

 35                 "adcl %%edx,8(%2)\n\t"

 36                 "adcl $0,12(%2)\n\t"

 37                 "movl 4(%0),%%eax\n\t"

 38                 "mull (%1)\n\t"

 39                 "addl %%eax,4(%2)\n\t"

 40                 "adcl %%edx,8(%2)\n\t"

 41                 "adcl $0,12(%2)"

 42                 ::"b" ((long) a),"c" ((long) b),"D" ((long) c)

 43                 :"ax","dx");

 44 }

 45

    // ���渡��ָ��FMUL��

    // ��ʱʵ��src1 * scr2 �� result����

 46 void fmul(const temp_real * src1, const temp_real * src2, temp_real * result)

 47 {

 48         int i,sign;

 49         int tmp[4] = {0,0,0,0};

 50

    // ����ȷ��������˵ķ��š�����ֵ�������߷���λ���ֵ��Ȼ�����˺��ָ��ֵ�����ʱ

    // ָ��ֵ��Ҫ��ӡ���������ָ��ʹ��ƫִ����ʽ���棬��������ָ�����ʱƫ����Ҳ������

    // ���Σ������Ҫ����һ��ƫ����ֵ����ʱʵ����ƫ������16383����

 51         sign = (src1->exponent ^ src2->exponent) & 0x8000;

 52         i = (src1->exponent & 0x7fff) + (src2->exponent & 0x7fff) - 16383 + 1;

    // ������ָ������˸�ֵ����ʾ������˺�������硣����ֱ�ӷ��ش����ŵ���ֵ��

    // ������ָ������0x7fff����ʾ�������磬��������״̬������쳣��־λ�������ء�

 53         if (i<0) {

 54                 result->exponent = sign;

 55                 result->a = result->b = 0;

 56                 return;

 57         }

 58         if (i>0x7fff) {

 59                 set_OE();

 60                 return;

 61         }

    // �������β����˺�����Ϊ0����Խ��β�����й�񻯴����������ƽ��β��ֵ��ʹ��

    // �����ЧλΪ1��ͬʱ��Ӧ�ص���ָ��ֵ�����������β����˺�16�ֽڵĽ��β��Ϊ0��

    // ��Ҳ����ָ��ֵΪ0��������˽����������ʱʵ������result�С�

 62         mul64(src1,src2,tmp);

 63         if (tmp[0] || tmp[1] || tmp[2] || tmp[3])

 64                 while (i && tmp[3] >= 0) {

 65                         i--;

 66                         shift(tmp);

 67                 }

 68         else

 69                 i = 0;

 70         result->exponent = i | sign;

 71         result->a = tmp[2];

 72         result->b = tmp[3];

 73 }

 74


 


 

11.9 ����11-9 linux/kernel/math/div.c


  1 /*

  2  * linux/kernel/math/div.c

  3  *

  4  * (C) 1991 Linus Torvalds

  5  */

  6

  7 /*

  8  * temporary real division routine.

  9  */

 10

 11 #include <linux/math_emu.h> // Э������ͷ�ļ���������ʱʵ���ṹ��387�Ĵ���������ȡ�

 12

    // ��ָ��cָ���4�ֽ�����������1λ��

 13 static void shift_left(int * c)

 14 {

 15         __asm__ __volatile__("movl (%0),%%eax ; addl %%eax,(%0)\n\t"

 16                 "movl 4(%0),%%eax ; adcl %%eax,4(%0)\n\t"

 17                 "movl 8(%0),%%eax ; adcl %%eax,8(%0)\n\t"

 18                 "movl 12(%0),%%eax ; adcl %%eax,12(%0)"

 19                 ::"r" ((long) c):"ax");

 20 }

 21

    // ��ָ��cָ���4�ֽ�����������1λ��

 22 static void shift_right(int * c)

 23 {

 24         __asm__("shrl $1,12(%0) ; rcrl $1,8(%0) ; rcrl $1,4(%0) ; rcrl $1,(%0)"

 25                 ::"r" ((long) c));

 26 }

 27

    // �������㡣

    // 16�ֽڼ������㣬a - b �� a���������Ƿ��н�λ��CF=1������ok�����޽�λ��CF=0��

    // ��ok = 1������ok=0��

 28 static int try_sub(int * a, int * b)

 29 {

 30         char ok;

 31

 32         __asm__ __volatile__("movl (%1),%%eax ; subl %%eax,(%2)\n\t"

 33                 "movl 4(%1),%%eax ; sbbl %%eax,4(%2)\n\t"

 34                 "movl 8(%1),%%eax ; sbbl %%eax,8(%2)\n\t"

 35                 "movl 12(%1),%%eax ; sbbl %%eax,12(%2)\n\t"

 36                 "setae %%al":"=a" (ok):"c" ((long) a),"d" ((long) b));

 37         return ok;

 38 }

 39

    // 16�ֽڳ�����

    // ���� a /b �� c�����ü���ģ����ֽڳ�����

 40 static void div64(int * a, int * b, int * c)

 41 {

 42         int tmp[4];

 43         int i;

 44         unsigned int mask = 0;

 45

 46         c += 4;

 47         for (i = 0 ; i<64 ; i++) {

 48                 if (!(mask >>= 1)) {

 49                         c--;

 50                         mask = 0x80000000;

 51                 }

 52                 tmp[0] = a[0]; tmp[1] = a[1];

 53                 tmp[2] = a[2]; tmp[3] = a[3];

 54                 if (try_sub(b,tmp)) {

 55                         *c |= mask;

 56                         a[0] = tmp[0]; a[1] = tmp[1];

 57                         a[2] = tmp[2]; a[3] = tmp[3];

 58                 }

 59                 shift_right(b);

 60         }

 61 }

 62

    // ���渡��ָ��FDIV��

 63 void fdiv(const temp_real * src1, const temp_real * src2, temp_real * result)

 64 {

 65         int i,sign;

 66         int a[4],b[4],tmp[4] = {0,0,0,0};

 67

 68         sign = (src1->exponent ^ src2->exponent) & 0x8000;

 69         if (!(src2->a || src2->b)) {

 70                 set_ZE();

 71                 return;

 72         }

 73         i = (src1->exponent & 0x7fff) - (src2->exponent & 0x7fff) + 16383;

 74         if (i<0) {

 75                 set_UE();

 76                 result->exponent = sign;

 77                 result->a = result->b = 0;

 78                 return;

 79         }

 80         a[0] = a[1] = 0;

 81         a[2] = src1->a;

 82         a[3] = src1->b;

 83         b[0] = b[1] = 0;

 84         b[2] = src2->a;

 85         b[3] = src2->b;

 86         while (b[3] >= 0) {

 87                 i++;

 88                 shift_left(b);

 89         }

 90         div64(a,b,tmp);

 91         if (tmp[0] || tmp[1] || tmp[2] || tmp[3]) {

 92                 while (i && tmp[3] >= 0) {

 93                         i--;

 94                         shift_left(tmp);

 95                 }

 96                 if (tmp[3] >= 0)

 97                         set_DE();

 98         } else

 99                 i = 0;

100         if (i>0x7fff) {

101                 set_OE();

102                 return;

103         }

104         if (tmp[0] || tmp[1])

105                 set_PE();

106         result->exponent = i | sign;

107         result->a = tmp[2];

108         result->b = tmp[3];

109 }

110


 


 

��12�� �ļ�ϵͳ����

12.1 ����12-1 linux/fs/buffer.c


  1 /*

  2  *  linux/fs/buffer.c

  3  *

  4  *  (C) 1991  Linus Torvalds

  5  */

  6

  7 /*

  8  *  'buffer.c' implements the buffer-cache functions. Race-conditions have

  9  * been avoided by NEVER letting a interrupt change a buffer (except for the

 10  * data, of course), but instead letting the caller do it. NOTE! As interrupts

 11  * can wake up a caller, some cli-sti sequences are needed to check for

 12  * sleep-on-calls. These should be extremely quick, though (I hope).

 13  */

    /*

     * 'buffer.c'����ʵ�ֻ��������ٻ��湦�ܡ�ͨ�������жϴ������̸ı仺�����������õ�

     * ������ִ�У������˾�����������Ȼ���ı��������⣩��ע�⣡�����жϿ��Ի���һ����

     * ���ߣ���˾���Ҫ�����ж�ָ�cli-sti��������������ڵ��ö�˯�ߡ�����Ҫ�dz��ؿ�

     * ����ϣ������������

     */

 14

 15 /*

 16  * NOTE! There is one discordant note here: checking floppies for

 17  * disk change. This is where it fits best, I think, as it should

 18  * invalidate changed floppy-disk-caches.

 19  */

    /*

     * ע�⣡��һ������Ӧ�����������������Ƿ�����������������Ƿ���

     * �ó�����õĵط��ˣ���Ϊ����Ҫʹ�Ѹ������̻���ʧЧ��

     */

 20

 21 #include <stdarg.h>       // ��׼����ͷ�ļ����Ժ����ʽ������������б�����Ҫ˵����-��

                              // ����(va_list)��������(va_start, va_arg��va_end)������

                              // vsprintf��vprintf��vfprintf������

 22 

 23 #include <linux/config.h> // �ں�����ͷ�ļ�������������Ժ�Ӳ�����ͣ�HD_TYPE����ѡ�

 24 #include <linux/sched.h>  // ���ȳ���ͷ�ļ�������������ṹtask_struct������0�����ݣ�

                              // ����һЩ�й��������������úͻ�ȡ��Ƕ��ʽ��ຯ������䡣

 25 #include <linux/kernel.h> // �ں�ͷ�ļ�������һЩ�ں˳��ú�����ԭ�ζ��塣

 26 #include <asm/system.h>   // ϵͳͷ�ļ������������û��޸�������/�ж��ŵȵ�Ƕ����ꡣ

 27 #include <asm/io.h>       // ioͷ�ļ�������Ӳ���˿�����/���������䡣

 28

    // ����end���ɱ���ʱ�����ӳ���ld���ɣ����ڱ����ں˴����ĩ�ˣ���ָ���ں�ģ��ĩ��

    // λ�ã��μ�����!δ�ҵ�����Դ����Ҳ���Դӱ����ں�ʱ���ɵ� System.map�ļ��в����������������

    // �����ٻ�������ʼ���ں˴���ĩ��λ�á�

    // ��33���ϵ�buffer_wait�����ǵȴ����л�����˯�ߵ��������ͷָ�롣���뻺���ͷ

    // ���ṹ��b_waitָ������ò�ͬ������������һ����������������ϵͳȱ�����ÿ��л�

    // ���ʱ����ǰ����ͻᱻ���ӵ�buffer_wait˯�ߵȴ������С���b_wait����ר�Ź��ȴ�

    // ָ������飨��b_wait��Ӧ�Ļ���飩������ʹ�õĵȴ�����ͷָ�롣

 29 extern int end;

 30 struct buffer_head * start_buffer = (struct buffer_head *) &end;

 31 struct buffer_head * hash_table[NR_HASH];        // NR_HASH = 307�

 32 static struct buffer_head * free_list;           // ���л��������ͷָ�롣

 33 static struct task_struct * buffer_wait = NULL;  // �ȴ����л�����˯�ߵ�������С�

 

    // ���涨��ϵͳ�������к��еĻ������������NR_BUFFERS��һ��������linux/fs.hͷ

    // �ļ���48�еĺ꣬��ֵ���DZ�����nr_buffers��������fs.h�ļ���172������Ϊȫ�ֱ�����

    // ��д����ͨ������һ�������ƣ�Linus������д������Ϊ�����������д�����������ر�ʾ

    // nr_buffers��һ�����ں˳�ʼ��֮���ٸı�ġ��������������ڳ�ʼ������buffer_init()

    // �б����ã���371�У���

 34 int NR_BUFFERS = 0;                              // ϵͳ���л���������

 35

    //// �ȴ�ָ������������

    // ���ָ���Ļ����bh�Ѿ��������ý��̲����жϵ�˯���ڸû����ĵȴ�����b_wait�С�

    // �ڻ�������ʱ����ȴ������ϵ����н��̽������ѡ���Ȼ���ڹر��жϣ�cli��֮��ȥ˯

    // �ߵģ���������������Ӱ����������������������Ӧ�жϡ���Ϊÿ�����̶����Լ���TSS��

    // �б����˱�־�Ĵ���EFLAGS��ֵ�������ڽ����л�ʱCPU�е�ǰEFLAGS��ֵҲ��֮�ı䡣

    // ʹ��sleep_on()����˯��״̬�Ľ�����Ҫ��wake_up()��ȷ�ػ��ѡ�

 36 static inline void wait_on_buffer(struct buffer_head * bh)

 37 {

 38         cli();                            // ���жϡ�

 39         while (bh->b_lock)                // ����ѱ���������̽���˯�ߣ��ȴ��������

 40                 sleep_on(&bh->b_wait);

 41         sti();                            // ���жϡ�

 42 }

 43

    //// �豸����ͬ����

    // ͬ���豸���ڴ���ٻ��������ݡ����У�sync_inodes()������inode.c��59�С�

 44 int sys_sync(void)

 45 {

 46         int i;

 47         struct buffer_head * bh;

 48

    // ���ȵ���i�ڵ�ͬ�����������ڴ�i�ڵ���������޸Ĺ���i�ڵ�д����ٻ����С�Ȼ��

    // ɨ�����и��ٻ����������ѱ��޸ĵĻ�������д�����󣬽�����������д�����У�����

    // ���ٻ����е��������豸�е�ͬ����

 49         sync_inodes();                           /* write out inodes into buffers */

 50         bh = start_buffer;                       // bhָ�򻺳�����ʼ����

 51         for (i=0 ; i<NR_BUFFERS ; i++,bh++) {

 52                 wait_on_buffer(bh);              // �ȴ�����������������������Ļ�����

 53                 if (bh->b_dirt)

 54                         ll_rw_block(WRITE,bh);   // ����д�豸������

 55         }

 56         return 0;

 57 }

 58

    //// ��ָ���豸���и��ٻ����������豸�����ݵ�ͬ��������

    // �ú��������������ٻ����������л���顣����ָ���豸dev�Ļ���飬���������ѱ��޸�

    // ����д�����У�ͬ����������Ȼ����ڴ���i�ڵ������д����ٻ����С�֮���ٶ�ָ����

    // ��devִ��һ����������ͬ��д�̲�����

 59 int sync_dev(int dev)

 60 {

 61         int i;

 62         struct buffer_head * bh;

 63

    // ���ȶԲ���ָ�����豸ִ������ͬ�����������豸�ϵ���������ٻ������е�����ͬ����

    // ������ɨ����ٻ����������л���飬��ָ���豸dev�Ļ���飬�ȼ�����Ƿ��ѱ�������

    // ���ѱ�������˯�ߵȴ��������Ȼ�����ж�һ�θû�����Ƿ���ָ���豸�Ļ���鲢��

    // ���޸Ĺ���b_dirt��־��λ�������ǾͶ���ִ��д�̲�������Ϊ������˯���ڼ�û����

    // �п����ѱ��ͷŻ��߱�Ų�����ã������ڼ���ִ��ǰ��Ҫ�ٴ��ж�һ�¸û�����Ƿ���

    // ָ���豸�Ļ���飬

 64         bh = start_buffer;                       // bhָ�򻺳�����ʼ����

 65         for (i=0 ; i<NR_BUFFERS ; i++,bh++) {   

 66                 if (bh->b_dev != dev)            // �����豸dev�Ļ�����������

 67                         continue;

 68                 wait_on_buffer(bh);              // �ȴ�����������������������Ļ�����

 69                 if (bh->b_dev == dev && bh->b_dirt)

 70                         ll_rw_block(WRITE,bh);

 71         }

    // �ٽ�i�ڵ�����д����ٻ��塣��i�ڵ��inode_table�е�inode�뻺���е���Ϣͬ����

 72         sync_inodes();

    // Ȼ���ڸ��ٻ����е����ݸ���֮���ٰ��������豸�е�����ͬ���������������ͬ������

    // ��Ϊ������ں�ִ��Ч�ʡ���һ�黺����ͬ�������������ں������ࡰ��顱��ɾ���ʹ��

    // i�ڵ��ͬ�������ܹ���Чִ�С����λ�����ͬ�����������Щ����i�ڵ�ͬ���������ֱ�

    // ��Ļ�������豸������ͬ����

 73         bh = start_buffer;

 74         for (i=0 ; i<NR_BUFFERS ; i++,bh++) {

 75                 if (bh->b_dev != dev)

 76                         continue;

 77                 wait_on_buffer(bh);

 78                 if (bh->b_dev == dev && bh->b_dirt)

 79                         ll_rw_block(WRITE,bh);

 80         }

 81         return 0;

 82 }

 83

    //// ʹָ���豸�ڸ��ٻ������е�������Ч��

    // ɨ����ٻ����������л���顣��ָ���豸�Ļ���鸴λ����Ч(����)��־�����޸ı�־��

 84 void inline invalidate_buffers(int dev)

 85 {

 86         int i;

 87         struct buffer_head * bh;

 88

 89         bh = start_buffer;

 90         for (i=0 ; i<NR_BUFFERS ; i++,bh++) {

 91                 if (bh->b_dev != dev)             // �������ָ���豸�Ļ���飬��

 92                         continue;                 // ����ɨ����һ�顣

 93                 wait_on_buffer(bh);               // �ȴ��û���������������ѱ���������

    // ���ڽ���ִ�й�˯�ߵȴ���������Ҫ���ж�һ�»������Ƿ���ָ���豸�ġ�

 94                 if (bh->b_dev == dev)

 95                         bh->b_uptodate = bh->b_dirt = 0;

 96         }

 97 }

 98

 99 /*

100  * This routine checks whether a floppy has been changed, and

101  * invalidates all buffer-cache-entries in that case. This

102  * is a relatively slow routine, so we have to try to minimize using

103  * it. Thus it is called only upon a 'mount' or 'open'. This

104  * is the best way of combining speed and utility, I think.

105  * People changing diskettes in the middle of an operation deserve

106  * to loose :-)

107  *

108  * NOTE! Although currently this is only for floppies, the idea is

109  * that any additional removable block-device will use this routine,

110  * and that mount/open needn't know that floppies/whatever are

111  * special.

112  */

    /*

     * ���ӳ�����һ�������Ƿ��ѱ�����������Ѿ�������ʹ���ٻ������������

     * ��Ӧ�����л�������Ч�����ӳ��������˵��������������Ҫ������ʹ������

     * ���Խ���ִ��'mount'��'open'ʱ�ŵ��������������ǽ��ٶȺ�ʵ�������ϵ�

     * ��÷��������ڲ��������и������̣��ͻᵼ�����ݵĶ�ʧ�����Ǿ�����ȡJ��

     *

     * ע�⣡����Ŀǰ���ӳ�����������̣��Ժ��κο��ƶ����ʵĿ��豸����ʹ�ø�

     * ����mount/open��������Ҫ֪�������̻�������ʲô������ʡ�

     */

    //// �������Ƿ����������Ѹ�����ʹ��Ӧ���ٻ�������Ч��

113 void check_disk_change(int dev)

114 {

115         int i;

116

    // ���ȼ��һ���Dz��������豸����Ϊ���ڽ�֧�����̿��ƶ����ʡ�����������˳���Ȼ��

    // ���������Ƿ��Ѹ��������û�����˳���floppy_change()��blk_drv/floppy.c��139�С�

117         if (MAJOR(dev) != 2)

118                 return;

119         if (!floppy_change(dev & 0x03))

120                 return;

    // �����Ѿ������������ͷŶ�Ӧ�豸��i�ڵ�λͼ���߼���λͼ��ռ�ĸ��ٻ���������ʹ��

    // �豸��i�ڵ�����ݿ���Ϣ��ռ��ĸ��ٻ������Ч��

121         for (i=0 ; i<NR_SUPER ; i++)

122                 if (super_block[i].s_dev == dev)

123                         put_super(super_block[i].s_dev);

124         invalidate_inodes(dev);

125         invalidate_buffers(dev);

126 }

127

    // �������д�����hash��ɢ�У����������hash����ļ���ꡣ

    // hash������Ҫ�����Ǽ��ٲ��ұȽ�Ԫ�������ѵ�ʱ�䡣ͨ����Ԫ�صĴ洢λ����ؼ���֮��

    // ����һ����Ӧ��ϵ��hash�����������ǾͿ���ֱ��ͨ�������������̲�ѯ��ָ����Ԫ�ء���

    // ��hash������ָ��������Ҫ�Ǿ���ȷ��ɢ�е��κ�������ĸ��ʻ�����ȡ����������ķ���

    // �ж��֣�����Linux 0.12��Ҫ�����˹ؼ��ֳ�������������Ϊ����Ѱ�ҵĻ����������������

    // ���豸��dev�ͻ�����block�������Ƶ�hash�����϶���Ҫ�����������ؼ�ֵ����������

    // �ؼ��ֵ�������ֻ�Ǽ���ؼ�ֵ��һ�ַ������ٶԹؼ�ֵ����MOD����Ϳ��Ա�֤��������

    // ��õ���ֵ�����ں��������Χ�ڡ�

128 #define _hashfn(dev,block) (((unsigned)(dev^block))%NR_HASH)

129 #define hash(dev,block) hash_table[_hashfn(dev,block)]

130

    //// ��hash���кͿ��л�����������߻���顣

    // hash������˫�������ṹ�����л���������˫��ѭ�������ṹ��

131 static inline void remove_from_queues(struct buffer_head * bh)

132 {

133 /* remove from hash-queue */

    /* ��hash�������Ƴ������ */

134         if (bh->b_next)

135                 bh->b_next->b_prev = bh->b_prev;

136         if (bh->b_prev)

137                 bh->b_prev->b_next = bh->b_next;

    // ����û������Ǹö��е�ͷһ���飬����hash���Ķ�Ӧ��ָ�򱾶����е���һ����������

138         if (hash(bh->b_dev,bh->b_blocknr) == bh)

139                 hash(bh->b_dev,bh->b_blocknr) = bh->b_next;

140 /* remove from free list */

    /* �ӿ��л��������Ƴ������ */

141         if (!(bh->b_prev_free) || !(bh->b_next_free))

142                 panic("Free block list corrupted");

143         bh->b_prev_free->b_next_free = bh->b_next_free;

144         bh->b_next_free->b_prev_free = bh->b_prev_free;

    // �����������ͷָ�򱾻�������������ָ����һ��������

145         if (free_list == bh)

146                 free_list = bh->b_next_free;

147 }

148

    //// �����������������β����ͬʱ����hash�����С�

149 static inline void insert_into_queues(struct buffer_head * bh)

150 {

151 /* put at end of free list */

    /* ���ڿ�������ĩβ�� */

152         bh->b_next_free = free_list;

153         bh->b_prev_free = free_list->b_prev_free;

154         free_list->b_prev_free->b_next_free = bh;

155         free_list->b_prev_free = bh;

156 /* put the buffer in new hash-queue if it has a device */

    /* ����û�����Ӧһ���豸�����������hash������ */

    // ��ע�⵱hash��ij���1�β�����ʱ��hash()����ֵ�϶�ΪNULL����˴�ʱ��161����

    // �õ���bh->b_next�϶���NULL�����Ե�163����Ӧ����bh->b_next��ΪNULLʱ���ܸ�

    // b_prev��bhֵ������163��ǰӦ�������жϡ�if (bh->b_next)�����ô���0.96���

    // �ű�������

157         bh->b_prev = NULL;

158         bh->b_next = NULL;

159         if (!bh->b_dev)

160                 return;

161         bh->b_next = hash(bh->b_dev,bh->b_blocknr);

162         hash(bh->b_dev,bh->b_blocknr) = bh;

163         bh->b_next->b_prev = bh;          // �˾�ǰӦ���ӡ�if (bh->b_next)���жϡ�

164 }

165

    //// ����hash���ڸ��ٻ�����Ѱ�Ҹ����豸��ָ����ŵĻ������顣

    // ����ҵ��򷵻ػ��������ָ�룬���򷵻�NULL��

166 static struct buffer_head * find_buffer(int dev, int block)

167 {              

168         struct buffer_head * tmp;

169

    // ����hash����Ѱ��ָ���豸�źͿ�ŵĻ���顣

170         for (tmp = hash(dev,block) ; tmp != NULL ; tmp = tmp->b_next)

171                 if (tmp->b_dev==dev && tmp->b_blocknr==block)

172                         return tmp;

173         return NULL;

174 }

175

176 /*

177  * Why like this, I hear you say... The reason is race-conditions.

178  * As we don't lock buffers (unless we are readint them, that is),

179  * something might happen to it while we sleep (ie a read-error

180  * will force it bad). This shouldn't really happen currently, but

181  * the code is ready.

182  */

    /*

     * ����Ϊʲô���������ӵģ�����������... ԭ���Ǿ�����������������û�ж�

     * ����������������������ڶ�ȡ�����е����ݣ�����ô�����ǣ����̣�˯��ʱ

     * �������ܻᷢ��һЩ���⣨����һ�������󽫵��¸û�����������Ŀǰ

     * �������ʵ�����Dz��ᷢ���ģ��������Ĵ����Ѿ�׼�����ˡ�

     */

    //// ����hash���ڸ��ٻ�������Ѱ��ָ���Ļ���顣���ҵ���Ըû�������������ؿ�ͷָ�롣

183 struct buffer_head * get_hash_table(int dev, int block)

184 {

185         struct buffer_head * bh;

186

187         for (;;) {

    // �ڸ��ٻ�����Ѱ�Ҹ����豸��ָ����Ļ������飬���û���ҵ��򷵻�NULL���˳���

188                 if (!(bh=find_buffer(dev,block)))

189                         return NULL;

    // �Ըû�����������ü��������ȴ��û�������������ѱ������������ھ�����˯��״̬��

    // ����б�Ҫ����֤�û�������ȷ�ԣ������ػ����ͷָ�롣

190                 bh->b_count++;

191                 wait_on_buffer(bh);

192                 if (bh->b_dev == dev && bh->b_blocknr == block)

193                         return bh;

    // �����˯��ʱ�û�����������豸�Ż��ŷ����˸ı䣬�������������ü���������Ѱ�ҡ�

194                 bh->b_count--;

195         }

196 }

197

198 /*

199  * Ok, this is getblk, and it isn't very clear, again to hinder

200  * race-conditions. Most of the code is seldom used, (ie repeating),

201  * so it should be much more efficient than it looks.

202  *

203  * The algoritm is changed: hopefully better, and an elusive bug removed.

204  */

    /*

     * OK��������getblk�������ú������߼������Ǻ�������ͬ��Ҳ����ΪҪ����

     * �����������⡣���д󲿷ִ�������õ���(�����ظ��������)�������Ӧ��

     * �ȿ���ȥ��������Ч�öࡣ

     *

     * �㷨�Ѿ����˸ı䣺ϣ���ܸ��ã�����һ��������ĥ�Ĵ����Ѿ�ȥ����

     */

    // ���������ͬʱ�жϻ��������޸ı�־��������־�����Ҷ����޸ı�־��Ȩ��Ҫ��������־

    // ��

205 #define BADNESS(bh) (((bh)->b_dirt<<1)+(bh)->b_lock)

    //// ȡ���ٻ�����ָ���Ļ���顣

    // ���ָ�����豸�źͿ�ţ��Ļ������Ƿ��Ѿ��ڸ��ٻ����С����ָ�����Ѿ��ڸ��ٻ����У�

    // �򷵻ض�Ӧ������ͷָ���˳���������ڣ�����Ҫ�ڸ��ٻ���������һ����Ӧ�豸�źͿ�ŵ�

    // ���������Ӧ������ͷָ�롣

206 struct buffer_head * getblk(int dev,int block)

207 {

208         struct buffer_head * tmp, * bh;

209

210 repeat:

    // ����hash�������ָ�����Ѿ��ڸ��ٻ����У��򷵻ض�Ӧ������ͷָ�룬�˳���

211         if (bh = get_hash_table(dev,block))

212                 return bh;

    // ɨ��������ݿ�������Ѱ�ҿ��л�������

    // ������tmpָ����������ĵ�һ�����л�����ͷ��

213         tmp = free_list;

214         do {

    // ����û���������ʹ�ã����ü���������0���������ɨ����һ�����b_count=0�Ŀ飬

    // �����ٻ����е�ǰû�����õĿ鲻һ�����Ǹɾ��ģ�b_dirt=0����û�������ģ�b_lock=0����

    // ��ˣ����ǻ�����Ҫ����������жϺ�ѡ�����統һ�������д��һ�����ݺ���ͷ��ˣ�

    // ���Ǹÿ�b_count = 0����b_lock������0����һ������ִ�� breada()Ԥ��������ʱ��ֻҪ

    // ll_rw_block()����������ͻ�ݼ�b_count������ʱʵ����Ӳ�̷��ʲ������ܻ��ڽ��У�

    // ��˴�ʱb_lock=1����b_count=0��

215                 if (tmp->b_count)

216                         continue;

    // �������ͷָ��bhΪ�գ�����tmp��ָ����ͷ�ı�־(�޸ġ�����)Ȩ��С��bhͷ��־��Ȩ

    // �أ�����bhָ��tmp�����ͷ�� �����tmp�����ͷ����������û���޸�Ҳû��������

    // ־��λ����˵����Ϊָ���豸�ϵĿ�ȡ�ö�Ӧ�ĸ��ٻ���飬���˳�ѭ�����������Ǿͼ���

    // ִ�б�ѭ���������ܷ��ҵ�һ��BADNESS()��С�Ļ���졣

217                 if (!bh || BADNESS(tmp)<BADNESS(bh)) {

218                         bh = tmp;

219                         if (!BADNESS(tmp))

220                                 break;

221                 }

222 /* and repeat until we find something good */  /* �ظ�����ֱ���ҵ��ʺϵĻ���� */

223         } while ((tmp = tmp->b_next_free) != free_list);

    // ���ѭ����鷢�����л���鶼���ڱ�ʹ�ã����л�����ͷ�����ü�����>0���У���˯��

    // �ȴ��п��л������á����п��л�������ʱ�����̻ᱻ��ȷ�ػ��ѡ�Ȼ�����Ǿ���ת��

    // ������ʼ�����²��ҿ��л���顣

224         if (!bh) {

225                 sleep_on(&buffer_wait);

226                 goto repeat;                   // ��ת��210�С�

227         }

    // ִ�е����˵�������Ѿ��ҵ���һ���Ƚ��ʺϵĿ��л�����ˡ������ȵȴ��û���������

    //������ѱ������Ļ��������������˯�߽׶θû������ֱ���������ʹ�õĻ���ֻ���ظ�����

    // Ѱ�ҹ��̡�

228         wait_on_buffer(bh);

229         if (bh->b_count)                       // �ֱ�ռ�ã���

230                 goto repeat;

    // ����û������ѱ��޸ģ�������д�̣����ٴεȴ�������������ͬ���أ����û������ֱ�

    // ��������ʹ�õĻ���ֻ�����ظ�����Ѱ�ҹ��̡�

231         while (bh->b_dirt) {

232                 sync_dev(bh->b_dev);

233                 wait_on_buffer(bh);

234                 if (bh->b_count)               // �ֱ�ռ�ã���

235                         goto repeat;

236         }

237 /* NOTE!! While we slept waiting for this block, somebody else might */

238 /* already have added "this" block to the cache. check it */

    /* ע�⣡��������Ϊ�˵ȴ��û�����˯��ʱ���������̿����Ѿ����û���� */

     * ��������ٻ����У���������ҲҪ�Դ˽��м�顣*/

    // �ڸ��ٻ���hash���м��ָ���豸�Ϳ�Ļ�����Ƿ������˯��֮���Ѿ��������ȥ�����

    // �ǵĻ������ٴ��ظ�����Ѱ�ҹ��̡�

239         if (find_buffer(dev,block))

240                 goto repeat;

241 /* OK, FINALLY we know that this buffer is the only one of it's kind, */

242 /* and that it's unused (b_count=0), unlocked (b_lock=0), and clean */

    /* OK����������֪���û������ָ��������Ψһһ�飬����Ŀǰ��û�б�ռ�� */

    /* (b_count=0)��Ҳδ������(b_lock=0)�������Ǹɾ��ģ�δ���޸ĵģ�*/

    // ����������ռ�ô˻���顣�����ü���Ϊ1����λ�޸ı�־����Ч(����)��־��

243         bh->b_count=1;

244         bh->b_dirt=0;

245         bh->b_uptodate=0;

    // ��hash���кͿ��п��������Ƴ��û�����ͷ���øû���������ָ���豸�����ϵ�ָ���顣

    // Ȼ����ݴ��µ��豸�źͿ�����²������������hash������λ�ô��������շ��ػ���

    // ͷָ�롣

246         remove_from_queues(bh);

247         bh->b_dev=dev;

248         bh->b_blocknr=block;

249         insert_into_queues(bh);

250         return bh;

251 }

252

    //// �ͷ�ָ������顣

    // �ȴ��û���������Ȼ�����ü����ݼ�1������ȷ�ػ��ѵȴ����л����Ľ��̡�

253 void brelse(struct buffer_head * buf)

254 {

255         if (!buf)                // �������ͷָ����Ч�򷵻ء�

256                 return;

257         wait_on_buffer(buf);

258         if (!(buf->b_count--))

259                 panic("Trying to free free buffer");

260         wake_up(&buffer_wait);

261 }

262

263 /*

264  * bread() reads a specified block and returns the buffer that contains

265  * it. It returns NULL if the block was unreadable.

266  */

    /*

     * ���豸�϶�ȡָ�������ݿ鲢���غ������ݵĻ����������ָ���Ŀ鲻����

     * �򷵻�NULL��

     */

    //// ���豸�϶�ȡ���ݿ顣

    // �ú�������ָ�����豸��dev�����ݿ��block�������ڸ��ٻ�����������һ�黺��顣

    // ����û�������Ѿ���������Ч�����ݾ�ֱ�ӷ��ظû����ָ�룬����ʹ��豸�ж�ȡ

    // ָ�������ݿ鵽�û�����в����ػ����ָ�롣

267 struct buffer_head * bread(int dev,int block)

268 {

269         struct buffer_head * bh;

270

    // �ڸ��ٻ�����������һ�黺��顣�������ֵ��NULL�����ʾ�ں˳�����ͣ����Ȼ������

    // �ж������Ƿ����п������ݡ� ����û��������������Ч�ģ��Ѹ��µģ�����ֱ��ʹ�ã�

    // �򷵻ء�

271         if (!(bh=getblk(dev,block)))

272                 panic("bread: getblk returned NULL\n");

273         if (bh->b_uptodate)

274                 return bh;

    // �������Ǿ͵��õײ���豸��дll_rw_block()�������������豸������Ȼ��ȴ�ָ��

    // ���ݿ鱻���룬���ȴ���������������˯������֮������û������Ѹ��£��򷵻ػ���

    // ��ͷָ�룬�˳�������������豸����ʧ�ܣ������ͷŸû�����������NULL���˳���

275         ll_rw_block(READ,bh);

276         wait_on_buffer(bh);

277         if (bh->b_uptodate)

278                 return bh;

279         brelse(bh);

280         return NULL;

281 }

282

    //// �����ڴ�顣

    // ��from��ַ����һ�飨1024�ֽڣ����ݵ�toλ�á�

283 #define COPYBLK(from,to) \

284 __asm__("cld\n\t" \

285         "rep\n\t" \

286         "movsl\n\t" \

287         ::"c" (BLOCK_SIZE/4),"S" (from),"D" (to) \

288         :"cx","di","si")

289

290 /*

291  * bread_page reads four buffers into memory at the desired address. It's

292  * a function of its own, as there is some speed to be got by reading them

293  * all at the same time, not waiting for one to be read, and then another

294  * etc.

295  */

    /*

     * bread_pageһ�ζ��ĸ���������ݶ����ڴ�ָ���ĵ�ַ��������һ�������ĺ�����

     * ��Ϊͬʱ��ȡ�Ŀ���Ի���ٶ��ϵĺô������õ��Ŷ�һ�飬�ٶ�һ���ˡ�

     */

    //// ���豸��һ��ҳ�棨4������飩�����ݵ�ָ���ڴ��ַ����

    // ����address�DZ���ҳ�����ݵĵ�ַ��dev��ָ�����豸�ţ�b[4]�Ǻ���4���豸���ݿ��

    // �����顣�ú���������mm/memory.c�ļ���do_no_page()�����У���386�У���

296 void bread_page(unsigned long address,int dev,int b[4])

297 {

298         struct buffer_head * bh[4];

299         int i;

300

    // �ú���ѭ��ִ��4�Σ����ݷ�������b[]�е�4����Ŵ��豸dev�ж�ȡһҳ���ݷŵ�ָ��

    // �ڴ�λ�� address���� ���ڲ���b[i]��������Ч��ţ��������ȴӸ��ٻ�����ȡָ���豸

    // �Ϳ�ŵĻ���顣����������������Ч��δ���£���������豸������豸�϶�ȡ��Ӧ��

    // �ݿ顣����b[i]��Ч�Ŀ������ȥ�����ˡ���˱�������ʵ���Ը���ָ����b[]�еĿ��

    // �����ȡ1��4�����ݿ顣

301         for (i=0 ; i<4 ; i++)

302                 if (b[i]) {                      // �������Ч��

303                         if (bh[i] = getblk(dev,b[i]))

304                                 if (!bh[i]->b_uptodate)

305                                         ll_rw_block(READ,bh[i]);

306                 } else

307                         bh[i] = NULL;

    // ���4��������ϵ�����˳���Ƶ�ָ����ַ�����ڽ��и��ƣ�ʹ�ã������֮ǰ����

    // ��Ҫ˯�ߵȴ��������������������Ļ��������⣬��Ϊ����˯�߹��ˣ��������ǻ���Ҫ

    // �ڸ���֮ǰ�ټ��һ�»�����е������Ƿ�����Ч�ġ�����������ǻ���Ҫ�ͷŻ���顣

308         for (i=0 ; i<4 ; i++,address += BLOCK_SIZE)

309                 if (bh[i]) {

310                         wait_on_buffer(bh[i]);   // �ȴ���������(���������Ļ�)��

311                         if (bh[i]->b_uptodate)   // ���������������Ч�Ļ����ơ�

312                                 COPYBLK((unsigned long) bh[i]->b_data,address);

313                         brelse(bh[i]);           // �ͷŸû�������

314                 }

315 }

316

317 /*

318  * Ok, breada can be used as bread, but additionally to mark other

319  * blocks for reading as well. End the argument list with a negative

320  * number.

321  */

    /*

     * OK��breada������breadһ��ʹ�ã���������Ԥ��һЩ�顣�ú��������б�

     * ��Ҫʹ��һ�����������������б��Ľ�����

     */

    //// ��ָ���豸��ȡָ����һЩ�顣

    // �������������ɱ䣬��һϵ��ָ���Ŀ�š��ɹ�ʱ���ص�1��Ļ����ͷָ�룬���򷵻�

    // NULL��

322 struct buffer_head * breada(int dev,int first, ...)

323 {

324         va_list args;

325         struct buffer_head * bh, *tmp;

326

    // ����ȡ�ɱ�������е�1����������ţ������ŴӸ��ٻ�������ȡָ���豸�Ϳ�ŵĻ���

    // �顣����û����������Ч�����±�־δ��λ�����򷢳����豸���ݿ�����

327         va_start(args,first);

328         if (!(bh=getblk(dev,first)))

329                 panic("bread: getblk returned NULL\n");

330         if (!bh->b_uptodate)

331                 ll_rw_block(READ,bh);

    // Ȼ��˳��ȡ�ɱ������������Ԥ����ţ�����������ͬ���������������á�ע�⣬336����

    // ��һ��bug�����е�bhӦ����tmp�����bugֱ����0.96����ں˴����вű�����������

    // ���⣬��Ϊ������Ԥ���������ݿ飬ֻ��������ٻ��������������Ͼ�ʹ�ã����Ե�337

    // �������Ҫ�������ü����ݼ��ͷŵ��ÿ飨��Ϊgetblk()���������ӻ�������ü���ֵ����

332         while ((first=va_arg(args,int))>=0) {

333                 tmp=getblk(dev,first);

334                 if (tmp) {

335                         if (!tmp->b_uptodate)

336                                 ll_rw_block(READA,bh);    // bh Ӧ����tmp��

337                         tmp->b_count--;                   // ��ʱ�ͷŵ���Ԥ���顣

338                 }

339         }

    // ��ʱ�ɱ�����������в���������ϡ����ǵȴ���1������������������ѱ����������ڵ�

    // ���˳�֮�������������������Ȼ��Ч���򷵻ػ�����ͷָ���˳��������ͷŸû���������

    // NULL���˳���

340         va_end(args);

341         wait_on_buffer(bh);

342         if (bh->b_uptodate)

343                 return bh;

344         brelse(bh);

345         return (NULL);

346 }

347

    //// ��������ʼ��������

    // ����buffer_end�ǻ������ڴ�ĩ�ˡ����ھ���16MB�ڴ��ϵͳ��������ĩ�˱�����Ϊ4MB��

    // ������8MB�ڴ��ϵͳ��������ĩ�˱�����Ϊ2MB���ú����ӻ�������ʼλ��start_buffer

    // ���ͻ�����ĩ��buffer_end���ֱ�ͬʱ���ã���ʼ���������ͷ�ṹ�Ͷ�Ӧ�����ݿ顣ֱ��

    // �������������ڴ汻������ϡ��μ������б�ǰ���ʾ��ͼ��

348 void buffer_init(long buffer_end)

349 {

350         struct buffer_head * h = start_buffer;

351         void * b;

352         int i;

353

    // ���ȸ��ݲ����ṩ�Ļ������߶�λ��ȷ��ʵ�ʻ������߶�λ��b������������߶˵���1Mb��

    // ����Ϊ��640KB - 1MB����ʾ�ڴ�� BIOSռ�ã�����ʵ�ʿ��û������ڴ�߶�λ��Ӧ����

    // 640KB�����򻺳����ڴ�߶�һ������1MB��

354         if (buffer_end == 1<<20)

355                 b = (void *) (640*1024);

356         else

357                 b = (void *) buffer_end;

    // ��δ������ڳ�ʼ�����������������л����ѭ������������ȡϵͳ�л������Ŀ��������

    // �����Ǵӻ������߶˿�ʼ����1KB��С�Ļ���飬���ͬʱ�ڻ������Ͷ˽��������û����

    // �Ľṹbuffer_head��������Щbuffer_head���˫��������

    // h��ָ�򻺳�ͷ�ṹ��ָ�룬��h+1��ָ���ڴ��ַ��������һ������ͷ��ַ��Ҳ����˵��

    // ָ��h����ͷ��ĩ���⡣Ϊ�˱�֤���㹻���ȵ��ڴ����洢һ������ͷ�ṹ����Ҫb��ָ��

    // ���ڴ���ַ >= h����ͷ��ĩ�ˣ���Ҫ�� >= h+1��

358         while ( (b -= BLOCK_SIZE) >= ((void *) (h+1)) ) {

359                 h->b_dev = 0;               // ʹ�øû������豸�š�

360                 h->b_dirt = 0;              // ���־����������޸ı�־��

361                 h->b_count = 0;             // ��������ü�����

362                 h->b_lock = 0;              // �����������־��

363                 h->b_uptodate = 0;          // �������±�־�����������Ч��־����

364                 h->b_wait = NULL;           // ָ��ȴ��û��������Ľ��̡�

365                 h->b_next = NULL;           // ָ�������ͬhashֵ����һ������ͷ��

366                 h->b_prev = NULL;           // ָ�������ͬhashֵ��ǰһ������ͷ��

367                 h->b_data = (char *) b;     // ָ���Ӧ��������ݿ飨1024�ֽڣ���

368                 h->b_prev_free = h-1;       // ָ��������ǰһ�

369                 h->b_next_free = h+1;       // ָ����������һ�

370                 h++;                           // hָ����һ�»���ͷλ�á�

371                 NR_BUFFERS++;                  // �����������ۼӡ�

372                 if (b == (void *) 0x100000)    // ��b�ݼ�������1MB��������384KB��

373                         b = (void *) 0xA0000;  // ��bָ���ַ0xA0000(640KB)����

374         }

375         h--;                                // ��hָ�����һ����Ч�����ͷ��

376         free_list = start_buffer;           // �ÿ�������ͷָ��ͷһ������顣

377         free_list->b_prev_free = h;  // ����ͷ��b_prev_freeָ��ǰһ������һ���

378         h->b_next_free = free_list;         // h����һ��ָ��ָ���һ��γ�һ��������

    // ����ʼ��hash������ϣ����ɢ�б������ñ�������ָ��ΪNULL��

379         for (i=0;i<NR_HASH;i++)

380                 hash_table[i]=NULL;

381 }      

382


 


 

12.2 ���� 12-2  linux/fs/bitmap.c


  1 /*

  2  *  linux/fs/bitmap.c

  3  *

  4  *  (C) 1991  Linus Torvalds

  5  */

  6

  7 /* bitmap.c contains the code that handles the inode and block bitmaps */

    /* bitmap.c�����д���i�ڵ�ʹ��̿�λͼ�Ĵ��� */

  8 #include <string.h>       // �ַ���ͷ�ļ�����Ҫ������һЩ�й��ַ���������Ƕ�뺯����

  9                           // ����ʹ�������е�memset()������

 10 #include <linux/sched.h>  // ���ȳ���ͷ�ļ�����������ṹtask_struct������0���ݡ�

 11 #include <linux/kernel.h> // �ں�ͷ�ļ�������һЩ�ں˳��ú�����ԭ�ζ��塣

 12

    //// ��ָ����ַ��addr������һ��1024�ֽ��ڴ����㡣

    // ���룺eax = 0��ecx = �Գ���Ϊ��λ�����ݿ鳤�ȣ�BLOCK_SIZE/4����edi = ָ����ʼ��

    // ַaddr��

 13 #define clear_block(addr) \

 14 __asm__("cld\n\t" \                // �巽��λ��

 15         "rep\n\t" \                // �ظ�ִ�д洢���ݣ�0����

 16         "stosl" \

 17         ::"a" (0),"c" (BLOCK_SIZE/4),"D" ((long) (addr)):"cx","di")

 18

    //// ��ָ����ַ��ʼ�ĵ�nr��λƫ�ƴ��ı���λ��λ��nr�ɴ���32����������ԭ����λֵ��

    // ���룺%0 -eax������ֵ����%1 -eax(0)��%2 -nr��λƫ��ֵ��%3 -(addr)��addr�����ݡ�

    // ��20�ж�����һ���ֲ��Ĵ�������res���ñ�������������ָ����eax�Ĵ����У��Ա���

    // ��Ч���ʺͲ��������ֶ�������ķ�����Ҫ������Ƕ�������С���ϸ˵���μ�gcc�ֲ�

    // ����ָ���Ĵ����еı������������궨����һ��������ʽ���ñ���ʽֵ�����res��ֵ��

    // ��21���ϵ�btslָ�����ڲ��Բ����ñ���λ��Bit Test and Set�����ѻ���ַ��%3����

    // ����λƫ��ֵ��%2����ָ���ı���λֵ�ȱ��浽��λ��־CF�У�Ȼ�����øñ���λΪ1��

    // ָ��setb���ڸ��ݽ�λ��־CF���ò�������%al�������CF=1��%al =1������%al =0��

 19 #define set_bit(nr,addr) ({\

 20 register int res __asm__("ax"); \

 21 __asm__ __volatile__("btsl %2,%3\n\tsetb %%al": \

 22 "=a" (res):"" (0),"r" (nr),"m" (*(addr))); \

 23 res;})

 24

    //// ��λָ����ַ��ʼ�ĵ�nrλƫ�ƴ��ı���λ������ԭ����λֵ�ķ��롣

    // ���룺%0 -eax������ֵ����%1 -eax(0)��%2 -nr��λƫ��ֵ��%3 -(addr)��addr�����ݡ�

    // ��27���ϵ�btrlָ�����ڲ��Բ���λ����λ��Bit Test and Reset�����������������

    // btsl���ƣ����Ǹ�λָ������λ��ָ��setnb���ڸ��ݽ�λ��־CF���ò�������%al����

    // ���CF = 1��%al = 0������%al = 1��

 25 #define clear_bit(nr,addr) ({\

 26 register int res __asm__("ax"); \

 27 __asm__ __volatile__("btrl %2,%3\n\tsetnb %%al": \

 28 "=a" (res):"" (0),"r" (nr),"m" (*(addr))); \

 29 res;})

 30

    //// ��addr��ʼѰ�ҵ�1��0ֵ����λ��

    // ���룺%0 - ecx(����ֵ)��%1 - ecx(0)��%2 - esi(addr)��

    // ��addrָ����ַ��ʼ��λͼ��Ѱ�ҵ�1����0�ı���λ�����������addr�ı���λƫ��

    // ֵ���ء�addr�ǻ�����������ĵ�ַ��ɨ��Ѱ�ҵķ�Χ��1024�ֽڣ�8192����λ����

 31 #define find_first_zero(addr) ({ \

 32 int __res; \

 33 __asm__("cld\n" \                   // �巽��λ��

 34         "1:\tlodsl\n\t" \           // ȡ[esi]��eax��

 35         "notl %%eax\n\t" \          // eax��ÿλȡ����

 36         "bsfl %%eax,%%edx\n\t" \    // ��λ0ɨ��eax����1�ĵ�1��λ����ƫ��ֵ��edx��

 37         "je 2f\n\t" \               // ���eax��ȫ��0������ǰ��ת�����2��(40��)��

 38         "addl %%edx,%%ecx\n\t" \    // ƫ��ֵ����ecx��ecx��λͼ�׸�0ֵλ��ƫ��ֵ����

 39         "jmp 3f\n" \                // ��ǰ��ת�����3������������

 40         "2:\taddl $32,%%ecx\n\t" \  // δ�ҵ�0ֵλ����ecx��1�����ֵ�λƫ����32��

 41         "cmpl $8192,%%ecx\n\t" \    // �Ѿ�ɨ����8192����λ��1024�ֽڣ�����

 42         "jl 1b\n" \                 // ����û��ɨ����1�����ݣ�����ǰ��ת�����1����

 43         "3:" \                      // ��������ʱecx����λƫ������

 44         :"=c" (__res):"c" (0),"S" (addr):"ax","dx","si"); \

 45 __res;})

 46

    //// �ͷ��豸dev���������е��߼���block��

    // ��λָ���߼���block��Ӧ���߼���λͼ����λ���ɹ��򷵻�1�����򷵻�0��

    // ������dev���豸�ţ�block���߼���ţ��̿�ţ���

 47 int free_block(int dev, int block)

 48 {

 49         struct super_block * sb;

 50         struct buffer_head * bh;

 51

    // ����ȡ�豸dev���ļ�ϵͳ�ij�������Ϣ������������������ʼ�߼���ź��ļ�ϵͳ���߼�

    // ��������Ϣ�жϲ���block����Ч�ԡ����ָ���豸�����鲻���ڣ������ͣ�������߼���

    // ��С��������������1���߼���Ŀ�Ż��ߴ����豸�����߼�������Ҳ����ͣ����

 52         if (!(sb = get_super(dev)))                   // fs/super.c����56�С�

 53                 panic("trying to free block on nonexistent device");

 54         if (block < sb->s_firstdatazone || block >= sb->s_nzones)

 55                 panic("trying to free block not in datazone");

 56         bh = get_hash_table(dev,block);

    // Ȼ��� hash����Ѱ�Ҹÿ����ݡ����ҵ������ж�����Ч�ԣ��������޸ĺ͸��±�־���ͷ�

    // �����ݿ顣�öδ������Ҫ��;��������߼���Ŀǰ�����ڸ��ٻ������У����ͷŶ�Ӧ�Ļ�

    // ��顣

 57         if (bh) {

 58                 if (bh->b_count > 1) {     // ������ô�������1�������brelse()��

 59                         brelse(bh);        // b_count--���˳����ÿ黹�����á�

 60                         return 0;

 61                 }

 62                 bh->b_dirt=0;              // ����λ���޸ĺ��Ѹ��±�־��

 63                 bh->b_uptodate=0;

 64                 if (bh->b_count)           // ����ʱb_countΪ1�������brelse()�ͷ�֮��

 65                         brelse(bh);

 66         }

    // �������Ǹ�λblock���߼���λͼ�еı���λ����0�����ȼ���block����������ʼ�����

    // �����߼���ţ���1��ʼ��������Ȼ����߼���(����)λͼ���в�������λ��Ӧ�ı���λ��

    // �����Ӧ����λԭ������0�������ͣ��������1���������1024�ֽڣ���8192����λ��

    // ��� block/8192 ���ɼ����ָ���� block ���߼�λͼ�е��ĸ����ϡ��� block&8191 ��

    // �Եõ�block���߼���λͼ��ǰ���еı���ƫ��λ�á�

 67         block -= sb->s_firstdatazone - 1 ; // ��block = block - ( s_firstdatazone -1);

 68         if (clear_bit(block&8191,sb->s_zmap[block/8192]->b_data)) {

 69                 printk("block (%04x:%d) ",dev,block+sb->s_firstdatazone-1);

 70                 printk("free_block: bit already cleared\n");

 71         }

    // �������Ӧ�߼���λͼ���ڻ��������޸ı�־��

 72         sb->s_zmap[block/8192]->b_dirt = 1;

 73         return 1;

 74 }

 75

    ////���豸����һ���߼��飨�̿飬���飩��

    // ��������ȡ���豸�ij����飬���ڳ������е��߼���λͼ��Ѱ�ҵ�һ��0ֵ����λ������

    // һ�������߼��飩��Ȼ����λ��Ӧ�߼������߼���λͼ�еı���λ������Ϊ���߼����ڻ�

    // ������ȡ��һ���Ӧ����顣��󽫸û�������㣬���������Ѹ��±�־�����޸ı�־��

    // �������߼���š�����ִ�гɹ��򷵻��߼���ţ��̿�ţ������򷵻�0��

 76 int new_block(int dev)

 77 {

 78         struct buffer_head * bh;

 79         struct super_block * sb;

 80         int i,j;

 81

    // ���Ȼ�ȡ�豸dev�ij����顣���ָ���豸�ij����鲻���ڣ������ͣ����Ȼ��ɨ���ļ�

    // ϵͳ��8���߼���λͼ��Ѱ���׸�0ֵ����λ����Ѱ�ҿ����߼��飬��ȡ���ø��߼����

    // ��š� ���ȫ��ɨ����8���߼���λͼ�����б���λ��i >= 8 �� j >= 8192����û�ҵ�

    // 0ֵ����λ����λͼ���ڵĻ����ָ����Ч(bh = NULL)�� ����0�˳���û�п����߼��飩��

 82         if (!(sb = get_super(dev)))

 83                 panic("trying to get new block from nonexistant device");

 84         j = 8192;

 85         for (i=0 ; i<8 ; i++)

 86                 if (bh=sb->s_zmap[i])

 87                         if ((j=find_first_zero(bh->b_data))<8192)

 88                                 break;

 89         if (i>=8 || !bh || j>=8192)

 90                 return 0;

    // ���������ҵ������߼���j��Ӧ�߼���λͼ�еı���λ������Ӧ����λ�Ѿ���λ�������

    // ͣ���������ô��λͼ�Ķ�Ӧ�����������޸ı�־����Ϊ�߼���λͼ����ʾ������������

    // �߼����ռ����������߼���λͼ�б���λƫ��ֵ��ʾ����������ʼ������Ŀ�ţ����

    // ������Ҫ������������1���߼���Ŀ�ţ���jת�����߼���š���ʱ������߼������

    // ���豸�ϵ����߼���������˵��ָ���߼����ڶ�Ӧ�豸�ϲ����ڡ�����ʧ�ܣ�����0�˳���

 91         if (set_bit(j,bh->b_data))

 92                 panic("new_block: bit already set");

 93         bh->b_dirt = 1;

 94         j += i*8192 + sb->s_firstdatazone-1;

 95         if (j >= sb->s_nzones)

 96                 return 0;

    // Ȼ���ڸ��ٻ�������Ϊ���豸��ָ�����߼����ȡ��һ������飬�����ػ����ͷָ�롣

    // ��Ϊ��ȡ�õ��߼��������ô���һ��Ϊ1��getblk()�л����ã����������Ϊ1��ͣ����

    // ������߼������㣬���������Ѹ��±�־�����޸ı�־��Ȼ���ͷŶ�Ӧ����飬����

    // �߼���š�

 97         if (!(bh=getblk(dev,j)))

 98                 panic("new_block: cannot get block");

 99         if (bh->b_count != 1)

100                 panic("new block: count is != 1");

101         clear_block(bh->b_data);

102         bh->b_uptodate = 1;

103         bh->b_dirt = 1;

104         brelse(bh);

105         return j;

106 }

107

    //// �ͷ�ָ����i�ڵ㡣

    // �ú��������жϲ���������i�ڵ�ŵ���Ч�ԺͿ��ͷ��ԡ���i�ڵ���Ȼ��ʹ��������

    // ���ͷš�Ȼ�����ó�������Ϣ��i�ڵ�λͼ���в�������λi�ڵ�Ŷ�Ӧ��i�ڵ�λͼ��

    // ����λ�������i�ڵ�ṹ��

108 void free_inode(struct m_inode * inode)

109 {

110         struct super_block * sb;

111         struct buffer_head * bh;

112

    // �����жϲ�����������Ҫ�ͷŵ�i�ڵ���Ч�Ի�Ϸ��ԡ����i�ڵ�ָ��=NULL�����˳���

    // ���i�ڵ��ϵ��豸���ֶ�Ϊ0��˵���ýڵ�û��ʹ�á�������0��ն�Ӧi�ڵ���ռ�ڴ�

    // �������ء�memset()������ include/string.h ��395�п�ʼ���������ʾ��0��дinode

    // ָ��ָ������������ sizeof(*inode) ���ڴ�顣

113         if (!inode)

114                 return;

115         if (!inode->i_dev) {

116                 memset(inode,0,sizeof(*inode));

117                 return;

118         }

    // �����i�ڵ㻹�������������ã������ͷţ�˵���ں������⣬ͣ��������ļ�������

    // ��Ϊ0�����ʾ���������ļ�Ŀ¼����ʹ�øýڵ㣬���Ҳ��Ӧ�ͷţ���Ӧ�÷Żصȡ�

119         if (inode->i_count>1) {

120                 printk("trying to free inode with count=%d\n",inode->i_count);

121                 panic("free_inode");

122         }

123         if (inode->i_nlinks)

124                 panic("trying to free inode with links");

    // ���ж���i�ڵ�ĺ�����֮�����ǿ�ʼ�����䳬������Ϣ�����е�i�ڵ�λͼ���в�����

    // ����ȡi�ڵ������豸�ij����飬�����豸�Ƿ���ڡ�Ȼ���ж�i�ڵ�ŵķ�Χ�Ƿ���ȷ��

    // ��� i�ڵ�ŵ���0 �� ���ڸ��豸�� i�ڵ��������������0��i�ڵ㱣��û��ʹ�ã���

    // �����i�ڵ��Ӧ�Ľڵ�λͼ�����ڣ����������Ϊһ��������i�ڵ�λͼ�� 8192 ��

    // ��λ�����i_num>>13����i_num/8192�����Եõ���ǰi�ڵ�����ڵ�s_imap[]�����

    // ���̿顣

125         if (!(sb = get_super(inode->i_dev)))

126                 panic("trying to free inode on nonexistent device");

127         if (inode->i_num < 1 || inode->i_num > sb->s_ninodes)

128                 panic("trying to free inode 0 or nonexistant inode");

129         if (!(bh=sb->s_imap[inode->i_num>>13]))

130                 panic("nonexistent imap in superblock");

    // �������Ǹ�λi�ڵ��Ӧ�Ľڵ�λͼ�еı���λ������ñ���λ�Ѿ�����0������ʾ����

    // ������Ϣ�������i�ڵ�λͼ���ڻ��������޸ı�־������ո�i�ڵ�ṹ��ռ�ڴ�����

131         if (clear_bit(inode->i_num&8191,bh->b_data))

132                 printk("free_inode: bit already cleared.\n\r");

133         bh->b_dirt = 1;

134         memset(inode,0,sizeof(*inode));

135 }

136

    //// Ϊ�豸dev����һ����i�ڵ㡣��ʼ�������ظ���i�ڵ��ָ�롣

    // ���ڴ�i�ڵ���л�ȡһ������i�ڵ�������i�ڵ�λͼ����һ������i�ڵ㡣

137 struct m_inode * new_inode(int dev)

138 {

139         struct m_inode * inode;

140         struct super_block * sb;

141         struct buffer_head * bh;

142         int i,j;

143

    // ���ȴ��ڴ�i�ڵ����inode_table���л�ȡһ������i�ڵ������ȡָ���豸�ij�����

    // �ṹ�� Ȼ��ɨ�賬������8��i�ڵ�λͼ��Ѱ���׸�0����λ��Ѱ�ҿ��нڵ㣬��ȡ����

    // ��i�ڵ�Ľڵ�š����ȫ��ɨ���껹û�ҵ�������λͼ���ڵĻ������Ч��bh = NULL����

    // ��Ż���ǰ�����i�ڵ���е�i�ڵ㣬�����ؿ�ָ���˳���û�п���i�ڵ㣩��

144         if (!(inode=get_empty_inode()))             // fs/inode.c����197�С�

145                 return NULL;

146         if (!(sb = get_super(dev)))                 // fs/super.c����56�С�

147                 panic("new_inode with unknown device");

148         j = 8192;

149         for (i=0 ; i<8 ; i++)

150                 if (bh=sb->s_imap[i])

151                         if ((j=find_first_zero(bh->b_data))<8192)

152                                 break;

153         if (!bh || j >= 8192 || j+i*8192 > sb->s_ninodes) {

154                 iput(inode);

155                 return NULL;

156         }

    // ���������Ѿ��ҵ��˻�δʹ�õ�i�ڵ��j��������λi�ڵ�j��Ӧ��i�ڵ�λͼ��Ӧ��

    // ��λ������Ѿ���λ�����������Ȼ����i�ڵ�λͼ���ڻ�������޸ı�־������ʼ��

    // ��i�ڵ�ṹ��i_ctime��i�ڵ����ݸı�ʱ�䣩��

157         if (set_bit(j,bh->b_data))

158                 panic("new_inode: bit already set");

159         bh->b_dirt = 1;

160         inode->i_count=1;                       // ���ü�����

161         inode->i_nlinks=1;                      // �ļ�Ŀ¼����������

162         inode->i_dev=dev;                       // i�ڵ����ڵ��豸�š�

163         inode->i_uid=current->euid;             // i�ڵ������û�id��

164         inode->i_gid=current->egid;             // ��id��

165         inode->i_dirt=1;                        // ���޸ı�־��λ��

166         inode->i_num = j + i*8192;              // ��Ӧ�豸�е�i�ڵ�š�

167         inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME;  // ����ʱ�䡣

168         return inode;                           // ���ظ�i�ڵ�ָ�롣

169 }

170


 


 

12.3 ����12-3 linux/fs/truncate.c


  1 /*

  2  *  linux/fs/truncate.c

  3  *

  4  *  (C) 1991  Linus Torvalds

  5  */

  6

  7 #include <linux/sched.h>  // ���ȳ���ͷ�ļ�������������ṹtask_struct������0���ݵȡ�

  8

  9 #include <sys/stat.h>     // �ļ�״̬ͷ�ļ��������ļ����ļ�ϵͳ״̬�ṹstat{}�ͳ�����

 10

    //// �ͷ�����һ�μ�ӿ顣���ڲ�������

    // ����dev���ļ�ϵͳ�����豸���豸�ţ�block���߼���š��ɹ��򷵻�1�����򷵻�0��

 11 static int free_ind(int dev,int block)

 12 {

 13         struct buffer_head * bh;

 14         unsigned short * p;

 15         int i;

 16         int block_busy;                             // ���߼���û�б��ͷŵı�־��

 17

    // �����жϲ�������Ч�ԡ�����߼����Ϊ0���򷵻ء�Ȼ���ȡһ�μ�ӿ飬���ͷ����ϱ�

    // ��ʹ�õ������߼��飬Ȼ���ͷŸ�һ�μ�ӿ�Ļ���顣 ����free_block()�����ͷ��豸

    // ��ָ���߼���ŵĴ��̿飨fs/bitmap.c��47�У���

 18         if (!block)

 19                 return 1;

 20         block_busy = 0;

 21         if (bh=bread(dev,block)) {

 22                 p = (unsigned short *) bh->b_data;  // ָ�򻺳����������

 23                 for (i=0;i<512;i++,p++)             // ÿ���߼����Ͽ���512����š�

 24                         if (*p)

 25                                 if (free_block(dev,*p)) {  // �ͷ�ָ�����豸�߼��顣

 26                                         *p = 0;            // ���㡣

 27                                         bh->b_dirt = 1;    // �������޸ı�־��

 28                                 } else

 29                                         block_busy = 1;    // �����߼���û���ͷű�־��

 30                 brelse(bh);                            // Ȼ���ͷż�ӿ�ռ�õĻ���顣

 31         }

    // ����ͷ��豸�ϵ�һ�μ�ӿ顣������������߼���û�б��ͷţ��򷵻�0��ʧ�ܣ���

 32         if (block_busy)

 33                 return 0;

 34         else

 35                 return free_block(dev,block);      // �ɹ��򷵻�1�����򷵻�0��

 36 }

 37

    //// �ͷ����ж��μ�ӿ顣

    // ����dev���ļ�ϵͳ�����豸���豸�ţ�block���߼���š�

 38 static int free_dind(int dev,int block)

 39 {

 40         struct buffer_head * bh;

 41         unsigned short * p;

 42         int i;

 43         int block_busy;                             // ���߼���û�б��ͷŵı�־��

 44

    // �����жϲ�������Ч�ԡ�����߼����Ϊ0���򷵻ء�Ȼ���ȡ���μ�ӿ��һ���飬����

    // �����ϱ���ʹ�õ������߼��飬Ȼ���ͷŸ�һ����Ļ���顣

 45         if (!block)

 46                 return 1;

 47         block_busy = 0;

 48         if (bh=bread(dev,block)) {

 49                 p = (unsigned short *) bh->b_data;  // ָ�򻺳����������

 50                 for (i=0;i<512;i++,p++)             // ÿ���߼����Ͽ�����512�������顣

 51                         if (*p)

 52                                 if (free_ind(dev,*p)) {   // �ͷ�����һ�μ�ӿ顣

 53                                         *p = 0;           // ���㡣

 54                                         bh->b_dirt = 1;   // �������޸ı�־��

 55                                 } else

 56                                         block_busy = 1;   // �����߼���û���ͷű�־��

 57                 brelse(bh);                         // �ͷŶ��μ�ӿ�ռ�õĻ���顣

 58         }

    // ����ͷ��豸�ϵĶ��μ�ӿ顣������������߼���û�б��ͷţ��򷵻�0��ʧ�ܣ���

 59         if (block_busy)

 60                 return 0;

 61         else

 62                 return free_block(dev,block);

 63 }

 64

    //// �ض��ļ����ݺ�����

    // ���ڵ��Ӧ���ļ����Ƚ�Ϊ0�����ͷ�ռ�õ��豸�ռ䡣

 65 void truncate(struct m_inode * inode)

 66 {

 67         int i;

 68         int block_busy;                            // ���߼���û�б��ͷŵı�־��

 69

    // �����ж�ָ��i�ڵ���Ч�ԡ�������dz����ļ���Ŀ¼�ļ���������򷵻ء�

 70         if (!(S_ISREG(inode->i_mode) || S_ISDIR(inode->i_mode) ||

 71              S_ISLNK(inode->i_mode)))

 72                 return;

    // Ȼ���ͷ�i�ڵ��7��ֱ���߼��飬������7���߼�����ȫ���㡣����free_block()����

    // �ͷ��豸��ָ���߼���ŵĴ��̿飨fs/bitmap.c��47�У��������߼���æ��û�б��ͷ�

    // ���ÿ�æ��־block_busy��

 73 repeat:

 74         block_busy = 0;

 75         for (i=0;i<7;i++)

 76                 if (inode->i_zone[i]) {               // �����Ų�Ϊ0�����ͷ�֮��

 77                         if (free_block(inode->i_dev,inode->i_zone[i]))

 78                                 inode->i_zone[i]=0;   // ��ָ����0��

 79                         else

 80                                 block_busy = 1;       // ��û���ͷŵ����ñ�־��

 81                 }

 82         if (free_ind(inode->i_dev,inode->i_zone[7]))  // �ͷ�����һ�μ�ӿ顣

 83                 inode->i_zone[7] = 0;                 // ��ָ����0��

 84         else

 85                 block_busy = 1;                       // ��û���ͷŵ����ñ�־��

 86         if (free_dind(inode->i_dev,inode->i_zone[8])) // �ͷ����ж��μ�ӿ顣

 87                 inode->i_zone[8] = 0;                 // ��ָ����0��

 88         else

 89                 block_busy = 1;                       // ��û���ͷŵ����ñ�־��

    // �˺�����i�ڵ����޸ı�־��������������߼������ڡ�æ����û�б��ͷţ���ѵ�ǰ����

    // ����ʱ��Ƭ��0�����õ�ǰ�����ȱ��л�ȥ�����������̣��Ե�һ��������ִ���ͷŲ�����

 90         inode->i_dirt = 1;

 91         if (block_busy) {

 92                 current->counter = 0;                  // ��ǰ����ʱ��Ƭ��0��

 93                 schedule();

 94                 goto repeat;

 95         }

 96         inode->i_size = 0;                              // �ļ���С���㡣

    // ����������ļ��޸�ʱ���i�ڵ�ı�ʱ��Ϊ��ǰʱ�䡣�� CURRENT_TIME ������ͷ�ļ�

    // include/linux/sched.h��142�д�������Ϊ(startup_time + jiffies/HZ)������ȡ�ô�

    // 1970:0:0:0��ʼ������Ϊֹ������������

 97         inode->i_mtime = inode->i_ctime = CURRENT_TIME;

 98 }

 99

100


 


 

12.4 ����12-4 linux/fs/inode.c


  1 /*

  2  *  linux/fs/inode.c

  3  *

  4  *  (C) 1991  Linus Torvalds

  5  */

  6

  7 #include <string.h>       // �ַ���ͷ�ļ�����Ҫ������һЩ�й��ַ���������Ƕ�뺯����

  8 #include <sys/stat.h>     // �ļ�״̬ͷ�ļ��������ļ����ļ�ϵͳ״̬�ṹstat{}�ͳ�����

  9

 10 #include <linux/sched.h>  // ���ȳ���ͷ�ļ�������������ṹtask_struct������0�����ݣ�

                              // ����һЩ�й��������������úͻ�ȡ��Ƕ��ʽ��ຯ������䡣

 11 #include <linux/kernel.h> // �ں�ͷ�ļ�������һЩ�ں˳��ú�����ԭ�ζ��塣

 12 #include <linux/mm.h>     // �ڴ����ͷ�ļ�������ҳ���С�����һЩҳ���ͷź���ԭ�͡�

 13 #include <asm/system.h>   // ϵͳͷ�ļ������������û��޸�������/�ж��ŵȵ�Ƕ��ʽ���ꡣ

 14

    // �豸���ݿ�����ָ�����顣ÿ��ָ����ָ��ָ�����豸�ŵ��ܿ�������hd_sizes[]������

    // ��������ÿһ���Ӧ���豸��ȷ����һ�����豸����ӵ�е����ݿ�������1���С = 1KB����

 15 extern int *blk_size[];

 16

 17 struct m_inode inode_table[NR_INODE]={{0,},};    // �ڴ���i�ڵ����NR_INODE=32���

 18

 19 static void read_inode(struct m_inode * inode);  // ��ָ��i�ڵ�ŵ�i�ڵ���Ϣ��297�С�

 20 static void write_inode(struct m_inode * inode); // дi�ڵ���Ϣ�����ٻ����У�324�С�

 21

    //// �ȴ�ָ����i�ڵ���á�

    // ���i�ڵ��ѱ��������򽫵�ǰ������Ϊ�����жϵĵȴ�״̬�������ӵ���i�ڵ�ĵȴ���

    // ��i_wait�С�ֱ����i�ڵ��������ȷ�ػ��ѱ�����

 22 static inline void wait_on_inode(struct m_inode * inode)

 23 {

 24         cli();

 25         while (inode->i_lock)

 26                 sleep_on(&inode->i_wait);         // kernel/sched.c����199�С�

 27         sti();

 28 }

 29

    //// ��i�ڵ�����������ָ����i�ڵ㣩��

    // ���i�ڵ��ѱ��������򽫵�ǰ������Ϊ�����жϵĵȴ�״̬�������ӵ���i�ڵ�ĵȴ���

    // ��i_wait�С�ֱ����i�ڵ��������ȷ�ػ��ѱ�����Ȼ�����������

 30 static inline void lock_inode(struct m_inode * inode)

 31 {

 32         cli();

 33         while (inode->i_lock)

 34                 sleep_on(&inode->i_wait);

 35         inode->i_lock=1;                         // ��������־��

 36         sti();

 37 }

 38

    //// ��ָ����i�ڵ������

    // ��λi�ڵ��������־������ȷ�ػ��ѵȴ��ڴ�i�ڵ�ȴ�����i_wait�ϵ����н��̡�

 39 static inline void unlock_inode(struct m_inode * inode)

 40 {

 41         inode->i_lock=0;

 42         wake_up(&inode->i_wait);                // kernel/sched.c����204�С�

 43 }

 44

    //// �ͷ��豸dev���ڴ�i�ڵ���е�����i�ڵ㡣

    // ɨ���ڴ��е�i�ڵ�����飬�����ָ���豸ʹ�õ�i�ڵ���ͷ�֮��

 45 void invalidate_inodes(int dev)

 46 {

 47         int i;

 48         struct m_inode * inode;

 49

    // ������ָ��ָ���ڴ�i�ڵ���������Ȼ��ɨ��i�ڵ��ָ�������е�����i�ڵ㡣���

    // ����ÿ��i�ڵ㣬�ȵȴ���i�ڵ�������ã���Ŀǰ���������Ļ��������ж��Ƿ�����ָ��

    // �豸��i�ڵ㡣�����ָ���豸��i�ڵ㣬�򿴿����Ƿ񻹱�ʹ���ţ��������ü����Ƿ�

    // Ϊ0����������ʾ������Ϣ��Ȼ���ͷ�֮������i�ڵ���豸���ֶ�i_dev��0����50����

    // ��ָ�븳ֵ "0+inode_table " ��ͬ�� "inode_table"��"&inode_table[0] "����������д

    // ���ܸ�����һЩ��

 50         inode = 0+inode_table;                  // ָ��i�ڵ��ָ���������

 51         for(i=0 ; i<NR_INODE ; i++,inode++) {

 52                 wait_on_inode(inode);           // �ȴ���i�ڵ���ã���������

 53                 if (inode->i_dev == dev) {

 54                         if (inode->i_count)     // ������������Ϊ0������ʾ�������档

 55                                 printk("inode in use on removed disk\n\r");

 56                         inode->i_dev = inode->i_dirt = 0; // �ͷ�i�ڵ�(���豸��Ϊ0)��

 57                 }

 58         }

 59 }

 60

    //// ͬ������i�ڵ㡣

    // ���ڴ�i�ڵ��������i�ڵ����豸��i�ڵ���ͬ��������

 61 void sync_inodes(void)

 62 {

 63         int i;

 64         struct m_inode * inode;

 65

    // �������ڴ�i�ڵ����͵�ָ��ָ��i�ڵ�����Ȼ��ɨ������i�ڵ���еĽڵ㡣���

    // ����ÿ��i�ڵ㣬�ȵȴ���i�ڵ�������ã���Ŀǰ���������Ļ�����Ȼ���жϸ�i�ڵ�

    // �Ƿ��ѱ��޸IJ��Ҳ��ǹܵ��ڵ㡣������������򽫸�i�ڵ�д����ٻ������С�������

    // ��������buffer.c�����ʵ�ʱ��������д�����С�

 66         inode = 0+inode_table;                  // ��ָ������ָ��i�ڵ��ָ���������

 67         for(i=0 ; i<NR_INODE ; i++,inode++) {   // ɨ��i�ڵ��ָ�����顣

 68                 wait_on_inode(inode);           // �ȴ���i�ڵ���ã���������

 69                 if (inode->i_dirt && !inode->i_pipe)  // ��i�ڵ����޸��Ҳ��ǹܵ��ڵ㣬

 70                         write_inode(inode);           // ��д�̣�ʵ����д�뻺�����У���

 71         }

 72 }

 73

    //// �ļ����ݿ�ӳ�䵽�̿�Ĵ�����������blockλͼ����������bmap - block map��

    // ������inode �C �ļ���i�ڵ�ָ�룻block �C �ļ��е����ݿ�ţ�create - �������־��

    // �ú�����ָ�����ļ����ݿ�block��Ӧ���豸���߼����ϣ��������߼���š����������־

    // ��λ�������豸�϶�Ӧ�߼��鲻����ʱ�������´��̿飬�����ļ����ݿ�block��Ӧ���豸

    // �ϵ��߼���ţ��̿�ţ���

 74 static int _bmap(struct m_inode * inode,int block,int create)

 75 {

 76         struct buffer_head * bh;

 77         int i;

 78

    // �����жϲ����ļ����ݿ��block����Ч�ԡ�������С��0����ͣ���������Ŵ���ֱ��

    // ���� + ��ӿ��� + ���μ�ӿ����������ļ�ϵͳ��ʾ��Χ����ͣ����

 79         if (block<0)

 80                 panic("_bmap: block<0");

 81         if (block >= 7+512+512*512)

 82                 panic("_bmap: block>big");

    // Ȼ������ļ���ŵĴ�Сֵ���Ƿ������˴�����־�ֱ���д���������ÿ��С��7����ʹ

    // ��ֱ�ӿ��ʾ�����������־��λ������i�ڵ��ж�Ӧ�ÿ���߼��飨���Σ��ֶ�Ϊ0����

    // ����Ӧ�豸����һ���̿飨�߼��飩�����ҽ������߼���ţ��̿�ţ������߼����ֶ��С�

    // Ȼ������i�ڵ�ı�ʱ�䣬��i�ڵ����޸ı�־�� ��󷵻��߼���š� ����new_block()

    // ������bitmap.c�����е�76�п�ʼ����

 83         if (block<7) {

 84                 if (create && !inode->i_zone[block])

 85                         if (inode->i_zone[block]=new_block(inode->i_dev)) {

 86                                 inode->i_ctime=CURRENT_TIME; // ctime - Change time��

 87                                 inode->i_dirt=1;             // �������޸ı�־��

 88                         }

 89                 return inode->i_zone[block];

 90         }

    // ����ÿ��>=7����С��7+512����˵��ʹ�õ���һ�μ�ӿ顣�����һ�μ�ӿ���д�����

    // ����Ǵ��������Ҹ�i�ڵ��ж�Ӧ��ӿ��ֶ�i_zone[7]��0�������ļ����״�ʹ�ü�ӿ飬

    // ��������һ���̿����ڴ�ż�ӿ���Ϣ��������ʵ�ʴ��̿�������ӿ��ֶ��С� Ȼ����

    // ��i�ڵ����޸ı�־���޸�ʱ�䡣 �������ʱ������̿�ʧ�ܣ����ʱi�ڵ��ӿ��ֶ�

    // i_zone[7]Ϊ0���򷵻�0�����߲��Ǵ�������i_zone[7]ԭ����Ϊ0������i�ڵ���û�м�

    // �ӿ飬����ӳ����̿�ʧ�ܣ�����0�˳���

 91         block -= 7;

 92         if (block<512) {

 93                 if (create && !inode->i_zone[7])

 94                         if (inode->i_zone[7]=new_block(inode->i_dev)) {

 95                                 inode->i_dirt=1;

 96                                 inode->i_ctime=CURRENT_TIME;

 97                         }

 98                 if (!inode->i_zone[7])

 99                         return 0;

    // ���ڶ�ȡ�豸�ϸ�i�ڵ��һ�μ�ӿ顣��ȡ�ü�ӿ��ϵ�block���е��߼���ţ��̿�

    // �ţ�i��ÿһ��ռ2���ֽڡ�����Ǵ������Ҽ�ӿ�ĵ�block���е��߼����Ϊ0�Ļ���

    // ������һ���̿飬���ü�ӿ��еĵ�block����ڸ����߼����š�Ȼ����λ��ӿ����

    // �޸ı�־��������Ǵ�������i������Ҫӳ�䣨Ѱ�ң����߼���š�

100                 if (!(bh = bread(inode->i_dev,inode->i_zone[7])))

101                         return 0;

102                 i = ((unsigned short *) (bh->b_data))[block];

103                 if (create && !i)

104                         if (i=new_block(inode->i_dev)) {

105                                 ((unsigned short *) (bh->b_data))[block]=i;

106                                 bh->b_dirt=1;

107                         }

    // ����ͷŸü�ӿ�ռ�õĻ���飬�����ش������������ԭ�еĶ�Ӧblock���߼����š�

108                 brelse(bh);

109                 return i;

110         }

    // ���������е��ˣ���������ݿ����ڶ��μ�ӿ顣�䴦��������һ�μ�ӿ����ơ������Ƕ�

    // ���μ�ӿ�Ĵ��������Ƚ�block�ټ�ȥ��ӿ������ɵĿ�����512����Ȼ������Ƿ�����

    // �˴�����־���д�����Ѱ�Ҵ�����������´�������i�ڵ�Ķ��μ�ӿ��ֶ�Ϊ0��������

    // ��һ���̿����ڴ�Ŷ��μ�ӿ��һ������Ϣ��������ʵ�ʴ��̿��������μ�ӿ��ֶ�

    // �С�֮����i�ڵ����޸ı��ƺ��޸�ʱ�䡣ͬ���أ��������ʱ������̿�ʧ�ܣ����

    // ʱi�ڵ���μ�ӿ��ֶ�i_zone[8]Ϊ0���򷵻�0�����߲��Ǵ�������i_zone[8]ԭ����

    // Ϊ0������i�ڵ���û�м�ӿ飬����ӳ����̿�ʧ�ܣ�����0�˳���

111         block -= 512;

112         if (create && !inode->i_zone[8])

113                 if (inode->i_zone[8]=new_block(inode->i_dev)) {

114                         inode->i_dirt=1;

115                         inode->i_ctime=CURRENT_TIME;

116                 }

117         if (!inode->i_zone[8])

118                 return 0;

    // ���ڶ�ȡ�豸�ϸ�i�ڵ�Ķ��μ�ӿ顣��ȡ�ö��μ�ӿ��һ�����ϵ� (block/512)

    // ���е��߼����i������Ǵ������Ҷ��μ�ӿ��һ�����ϵ� (block/512) ���е��߼�

    // ���Ϊ0�Ļ�����������һ���̿飨�߼��飩��Ϊ���μ�ӿ�Ķ�����i�����ö��μ��

    // ���һ�����е� (block/512)����ڸö�����Ŀ��i��Ȼ����λ���μ�ӿ��һ������

    // �޸ı�־�����ͷŶ��μ�ӿ��һ���顣������Ǵ�������i������Ҫӳ�䣨Ѱ�ң�����

    // ����š�

119         if (!(bh=bread(inode->i_dev,inode->i_zone[8])))

120                 return 0;

121         i = ((unsigned short *)bh->b_data)[block>>9];

122         if (create && !i)

123                 if (i=new_block(inode->i_dev)) {

124                         ((unsigned short *) (bh->b_data))[block>>9]=i;

125                         bh->b_dirt=1;

126                 }

127         brelse(bh);

    // ������μ�ӿ�Ķ�������Ϊ0����ʾ������̿�ʧ�ܻ���ԭ����Ӧ��ž�Ϊ0����

    // ��0�˳�������ʹ��豸�϶�ȡ���μ�ӿ�Ķ����飬��ȡ�ö������ϵ�block���е���

    // ����ţ�����511��Ϊ���޶�blockֵ������511����

128         if (!i)

129                 return 0;

130         if (!(bh=bread(inode->i_dev,i)))

131                 return 0;

132         i = ((unsigned short *)bh->b_data)[block&511];

    // ����Ǵ������Ҷ�����ĵ�block�����߼����Ϊ0�Ļ���������һ���̿飨�߼��飩��

    // ��Ϊ���մ��������Ϣ�Ŀ顣���ö������еĵ�block����ڸ����߼�����(i)��Ȼ��

    // ��λ����������޸ı�־��

133         if (create && !i)

134                 if (i=new_block(inode->i_dev)) {

135                         ((unsigned short *) (bh->b_data))[block&511]=i;

136                         bh->b_dirt=1;

137                 }

    // ����ͷŸö��μ�ӿ�Ķ����飬���ش�����������Ļ�ԭ�еĶ�Ӧblock���߼����š�

138         brelse(bh);

139         return i;

140 }

141

    //// ȡ�ļ����ݿ�block���豸�϶�Ӧ���߼���š�

    // ������inode �C �ļ����ڴ�i�ڵ�ָ�룻block �C �ļ��е����ݿ�š�

    // �������ɹ��򷵻ض�Ӧ���߼���ţ����򷵻�0��

142 int bmap(struct m_inode * inode,int block)

143 {

144         return _bmap(inode,block,0);

145 }

146

    //// ȡ�ļ����ݿ�block���豸�϶�Ӧ���߼���š������Ӧ���߼��鲻���ھʹ���һ�顣

    // �������豸�϶�Ӧ���߼���š�

    // ������inode �C �ļ����ڴ�i�ڵ�ָ�룻block �C �ļ��е����ݿ�š�

    // �������ɹ��򷵻ض�Ӧ���߼���ţ����򷵻�0��

147 int create_block(struct m_inode * inode, int block)

148 {

149         return _bmap(inode,block,1);

150 }

151                 

    //// �Żأ����ã�һ��i�ڵ�(��д���豸)��

    // �ú�����Ҫ���ڰ�i�ڵ����ü���ֵ�ݼ�1���������ǹܵ�i�ڵ㣬���ѵȴ��Ľ��̡�

    // ���ǿ��豸�ļ�i�ڵ���ˢ���豸��������i�ڵ�����Ӽ���Ϊ0�����ͷŸ�i�ڵ�ռ��

    // �����д����߼��飬���ͷŸ�i�ڵ㡣

152 void iput(struct m_inode * inode)

153 {

    // �����жϲ���������i�ڵ����Ч�ԣ����ȴ�inode�ڵ����������������Ļ��������i

    // �ڵ�����ü���Ϊ0����ʾ��i�ڵ��Ѿ��ǿ��еġ��ں���Ҫ�������зŻز�����˵����

    // �����������������⡣������ʾ������Ϣ��ͣ����

154         if (!inode)

155                 return;

156         wait_on_inode(inode);

157         if (!inode->i_count)

158                 panic("iput: trying to free free inode");

    // ����ǹܵ�i�ڵ㣬���ѵȴ��ùܵ��Ľ��̣����ô�����1��������������򷵻ء�����

    // �ͷŹܵ�ռ�õ��ڴ�ҳ�棬����λ�ýڵ�����ü���ֵ�����޸ı�־�͹ܵ���־�������ء�

    // ���ڹܵ��ڵ㣬inode->i_size������ڴ�ҳ��ַ���μ�get_pipe_inode()��231��237�С�

159         if (inode->i_pipe) {

160                 wake_up(&inode->i_wait);

161                 wake_up(&inode->i_wait2);          //

162                 if (--inode->i_count)

163                         return;

164                 free_page(inode->i_size);

165                 inode->i_count=0;

166                 inode->i_dirt=0;

167                 inode->i_pipe=0;

168                 return;

169         }

    // ���i�ڵ��Ӧ���豸�� = 0���򽫴˽ڵ�����ü����ݼ�1�����ء��������ڹܵ�������

    // i�ڵ㣬��i�ڵ���豸��Ϊ0��

170         if (!inode->i_dev) {

171                 inode->i_count--;

172                 return;

173         }

    // ����ǿ��豸�ļ���i�ڵ㣬��ʱ�߼����ֶ�0��i_zone[0]�������豸�ţ���ˢ�¸��豸��

    // ���ȴ�i�ڵ������

174         if (S_ISBLK(inode->i_mode)) {

175                 sync_dev(inode->i_zone[0]);

176                 wait_on_inode(inode);

177         }

    // ���i�ڵ�����ü�������1��������ݼ�1���ֱ�ӷ��أ���Ϊ��i�ڵ㻹�������ã�����

    // �ͷţ��������˵��i�ڵ�����ü���ֵΪ1����Ϊ��157���Ѿ��жϹ����ü����Ƿ�Ϊ�㣩��

    // ���i�ڵ��������Ϊ0����˵��i�ڵ��Ӧ�ļ���ɾ���������ͷŸ�i�ڵ�������߼��飬

    // ���ͷŸ�i�ڵ㡣����free_inode()����ʵ���ͷ�i�ڵ����������λi�ڵ��Ӧ��i�ڵ�λ

    // ͼ����λ�����i�ڵ�ṹ���ݡ�

178 repeat:

179         if (inode->i_count>1) {

180                 inode->i_count--;

181                 return;

182         }

183         if (!inode->i_nlinks) {

184                 truncate(inode);

185                 free_inode(inode);         // bitmap.c ��108�п�ʼ����

186                 return;

187         }

    // �����i�ڵ��������޸ģ����д���¸�i�ڵ㣬���ȴ���i�ڵ����������������дi��

    // ��ʱ��Ҫ�ȴ�˯�ߣ���ʱ���������п����޸ĸ�i�ڵ㣬����ڽ��̱����Ѻ���Ҫ�ٴ��ظ�

    // ���������жϹ��̣�repeat����

188         if (inode->i_dirt) {

189                 write_inode(inode);        /* we can sleep - so do again */

190                 wait_on_inode(inode);      /* ��Ϊ����˯���ˣ�������Ҫ�ظ��ж� */

191                 goto repeat;

192         }

    // ��������ִ�е��ˣ���˵����i�ڵ�����ü���ֵi_count��1����������Ϊ�㣬��������

    // û�б��޸Ĺ�����˴�ʱֻҪ��i�ڵ����ü����ݼ�1�����ء���ʱ��i�ڵ��i_count=0��

    // ��ʾ���ͷš�

193         inode->i_count--;

194         return;

195 }

196

    //// ��i�ڵ����inode_table���л�ȡһ������i�ڵ��

    // Ѱ�����ü���countΪ0��i�ڵ㣬������д�̺����㣬������ָ�롣���ü�������1��

197 struct m_inode * get_empty_inode(void)

198 {

199         struct m_inode * inode;

200         static struct m_inode * last_inode = inode_table;   // ָ��i�ڵ����1�

201         int i;

202

    // �ڳ�ʼ��last_inodeָ��ָ��i�ڵ��ͷһ���ѭ��ɨ������i�ڵ�������last_inode

    // �Ѿ�ָ��i�ڵ�������1��֮������������ָ��i�ڵ����ʼ�����Լ���ѭ��Ѱ�ҿ���

    // i�ڵ����� last_inode��ָ���i�ڵ�ļ���ֵΪ0����˵�������ҵ�����i�ڵ��

    // ��inodeָ���i�ڵ㡣�����i�ڵ�����޸ı�־��������־��Ϊ0�������ǿ���ʹ�ø�

    // i�ڵ㣬�����˳�forѭ����

203         do {

204                 inode = NULL;

205                 for (i = NR_INODE; i ; i--) {                // NR_INODE = 32��

206                         if (++last_inode >= inode_table + NR_INODE)

207                                 last_inode = inode_table;

208                         if (!last_inode->i_count) {

209                                 inode = last_inode;

210                                 if (!inode->i_dirt && !inode->i_lock)

211                                         break;

212                         }

213                 }

    // ���û���ҵ�����i�ڵ㣨inode = NULL������i�ڵ����ӡ����������ʹ�ã���ͣ����

214                 if (!inode) {

215                         for (i=0 ; i<NR_INODE ; i++)

216                                 printk("%04x: %6d\t",inode_table[i].i_dev,

217                                         inode_table[i].i_num);

218                         panic("No free inodes in mem");

219                 }

    // �ȴ���i�ڵ����������ֱ������Ļ����������i�ڵ����޸ı�־����λ�Ļ����򽫸�

    // i�ڵ�ˢ�£�ͬ��������Ϊˢ��ʱ���ܻ�˯�ߣ������Ҫ�ٴ�ѭ���ȴ���i�ڵ������

220                 wait_on_inode(inode);

221                 while (inode->i_dirt) {

222                         write_inode(inode);

223                         wait_on_inode(inode);

224                 }

225         } while (inode->i_count);

    // ���i�ڵ��ֱ�����ռ�õĻ���i�ڵ�ļ���ֵ��Ϊ0�ˣ���������Ѱ�ҿ���i�ڵ㡣����

    // ˵�����ҵ�����Ҫ��Ŀ���i�ڵ���򽫸�i�ڵ����������㣬�������ü���Ϊ1������

    // ��i�ڵ�ָ�롣

226         memset(inode,0,sizeof(*inode));

227         inode->i_count = 1;

228         return inode;

229 }

230

    //// ��ȡ�ܵ��ڵ㡣

    // ����ɨ��i�ڵ����Ѱ��һ������i�ڵ��Ȼ��ȡ��һҳ�����ڴ湩�ܵ�ʹ�á�Ȼ�󽫵�

    // ����i�ڵ�����ü�����Ϊ2(���ߺ�д��)����ʼ���ܵ�ͷ��β����i�ڵ�Ĺܵ����ͱ�ʾ��

    // ����Ϊi�ڵ�ָ�룬���ʧ���򷵻�NULL��

231 struct m_inode * get_pipe_inode(void)

232 {

233         struct m_inode * inode;

234

    // ���ȴ��ڴ�i�ڵ����ȡ��һ������i�ڵ㡣����Ҳ�������i�ڵ��򷵻�NULL��Ȼ��Ϊ��

    // i�ڵ�����һҳ�ڴ棬���ýڵ��i_size�ֶ�ָ���ҳ�档�����û�п����ڴ棬���ͷŸ�

    // i�ڵ㣬������NULL��

235         if (!(inode = get_empty_inode()))

236                 return NULL;

237         if (!(inode->i_size=get_free_page())) {     // �ڵ��i_size�ֶ�ָ�򻺳�����

238                 inode->i_count = 0;

239                 return NULL;

240         }

    // Ȼ�����ø�i�ڵ�����ü���Ϊ2������λ��λ�ܵ�ͷβָ�롣i�ڵ��߼��������i_zone[]

    // ��i_zone[0]��i_zone[1]�зֱ�������Źܵ�ͷ�͹ܵ�βָ�롣�������i�ڵ��ǹܵ�i��

    // ���־�����ظ�i�ڵ�š�

241         inode->i_count = 2;     /* sum of readers/writers */   /* ��/д�����ܼ� */

242         PIPE_HEAD(*inode) = PIPE_TAIL(*inode) = 0;  // ��λ�ܵ�ͷβָ�롣

243         inode->i_pipe = 1;                          // �ýڵ�Ϊ�ܵ�ʹ�õı�־��

244         return inode;

245 }

246

    //// ȡ��һ��i�ڵ㡣

    // ������dev - �豸�ţ�nr - i�ڵ�š�

    // ���豸�϶�ȡָ���ڵ�ŵ�i�ڵ�ṹ���ݵ��ڴ�i�ڵ���У����ҷ��ظ�i�ڵ�ָ�롣

    // ������λ�ڸ��ٻ������е�i�ڵ������Ѱ�����ҵ�ָ���ڵ�ŵ�i�ڵ����ھ���һЩ�ж�

    // �����󷵻ظ�i�ڵ�ָ�롣������豸dev�϶�ȡָ��i�ڵ�ŵ�i�ڵ���Ϣ����i�ڵ��

    // �У������ظ�i�ڵ�ָ�롣

247 struct m_inode * iget(int dev,int nr)

248 {

249         struct m_inode * inode, * empty;

250

    // �����жϲ�����Ч�ԡ����豸����0��������ں˴������⣬��ʾ������Ϣ��ͣ����Ȼ��Ԥ

    // �ȴ�i�ڵ����ȡһ������i�ڵ㱸�á�

251         if (!dev)

252                 panic("iget with dev==0");

253         empty = get_empty_inode();

    // ����ɨ��i�ڵ����Ѱ�Ҳ���ָ���ڵ��nr��i�ڵ㡣�������ýڵ�����ô����������

    // ǰɨ��i�ڵ���豸�Ų�����ָ�����豸�Ż��߽ڵ�Ų�����ָ���Ľڵ�ţ������ɨ�衣

254         inode = inode_table;

255         while (inode < NR_INODE+inode_table) {

256                 if (inode->i_dev != dev || inode->i_num != nr) {

257                         inode++;

258                         continue;

259                 }

    // ����ҵ�ָ���豸��dev �ͽڵ�� nr ��i�ڵ㣬��ȴ��ýڵ����������������Ļ�����

    // �ڵȴ��ýڵ���������У�i�ڵ�����ܻᷢ���仯�������ٴν���������ͬ�жϡ������

    // ���˱仯�����ٴ�����ɨ������i�ڵ����

260                 wait_on_inode(inode);

261                 if (inode->i_dev != dev || inode->i_num != nr) {

262                         inode = inode_table;

263                         continue;

264                 }

    // �������ʾ�ҵ���Ӧ��i�ڵ㡣���ǽ���i�ڵ����ü�����1��Ȼ��������һ����飬����

    // �Ƿ�����һ���ļ�ϵͳ�İ�װ�㡣������Ѱ�ұ���װ�ļ�ϵͳ���ڵ㲢���ء������i�ڵ�

    // ��ȷ�������ļ�ϵͳ�İ�װ�㣬���ڳ����������Ѱ��װ�ڴ�i�ڵ�ij����顣���û����

    // ��������ʾ������Ϣ�����Żر�������ʼʱ��ȡ�Ŀ��нڵ�empty�����ظ�i�ڵ�ָ�롣

265                 inode->i_count++;

266                 if (inode->i_mount) {

267                         int i;

268

269                         for (i = 0 ; i<NR_SUPER ; i++)

270                                 if (super_block[i].s_imount==inode)

271                                         break;

272                         if (i >= NR_SUPER) {

273                                 printk("Mounted inode hasn't got sb\n");

274                                 if (empty)

275                                         iput(empty);

276                                 return inode;

277                         }

    // ִ�е������ʾ�Ѿ��ҵ���װ��inode�ڵ���ļ�ϵͳ�����顣���ǽ���i�ڵ�д�̷Żأ�

    // ���Ӱ�װ�ڴ�i�ڵ��ϵ��ļ�ϵͳ��������ȡ�豸�ţ�����i�ڵ��ΪROOT_INO����Ϊ1��

    // Ȼ������ɨ������i�ڵ�����Ի�ȡ�ñ���װ�ļ�ϵͳ�ĸ�i�ڵ���Ϣ��

278                         iput(inode);

279                         dev = super_block[i].s_dev;

280                         nr = ROOT_INO;

281                         inode = inode_table;

282                         continue;

283                 }

    // ���������ҵ�����Ӧ��i�ڵ㡣��˿��Է�����������ʼ����ʱ����Ŀ���i�ڵ㣬����

    // �ҵ���i�ڵ�ָ�롣

284                 if (empty)

285                         iput(empty);

286                 return inode;

287         }

    // ���������i�ڵ����û���ҵ�ָ����i�ڵ㣬������ǰ������Ŀ���i�ڵ�empty��i

    // �ڵ���н�����i�ڵ㡣������Ӧ�豸�϶�ȡ��i�ڵ���Ϣ�����ظ�i�ڵ�ָ�롣

288         if (!empty)

289                 return (NULL);

290         inode=empty;

291         inode->i_dev = dev;                  // ����i�ڵ���豸��

292         inode->i_num = nr;                   // ����i�ڵ�š�

293         read_inode(inode);

294         return inode;

295 }

296

    //// ��ȡָ��i�ڵ���Ϣ��

    // ���豸�϶�ȡ����ָ��i�ڵ���Ϣ��i�ڵ��̿飬Ȼ���Ƶ�ָ����i�ڵ�ṹ�С� Ϊ��

    // ȷ��i�ڵ����ڵ��豸�߼���ţ��򻺳�飩���������ȶ�ȡ��Ӧ�豸�ϵij����飬�Ի�ȡ

    // ���ڼ����߼���ŵ�ÿ��i�ڵ�����Ϣ INODES_PER_BLOCK�� �ڼ����i�ڵ����ڵ��߼���

    // �ź󣬾ͰѸ��߼������һ������С�Ȼ��ѻ��������Ӧλ�ô���i�ڵ����ݸ��Ƶ�����

    // ָ����λ�ô���

297 static void read_inode(struct m_inode * inode)

298 {

299         struct super_block * sb;

300         struct buffer_head * bh;

301         int block;

302

    // ����������i�ڵ㣬��ȡ�ýڵ������豸�ij����顣

303         lock_inode(inode);

304         if (!(sb=get_super(inode->i_dev)))

305                 panic("trying to read inode without dev");

    // ��i�ڵ����ڵ��豸�߼���� = (������ + ������) + i�ڵ�λͼռ�õĿ��� + �߼���λ

    // ͼռ�õĿ��� + (i�ڵ��-1)/ÿ�麬�е�i�ڵ�������Ȼi�ڵ�Ŵ�0��ʼ��ţ�����1

    // ��0��i�ڵ㲻�ã����Ҵ�����Ҳ�������Ӧ��0��i�ڵ�ṹ����˴��i�ڵ���̿��

    // ��1���ϱ������i�ڵ������1--16��i�ڵ�ṹ������0--15�ġ�������������i��

    // ��Ŷ�Ӧ��i�ڵ�ṹ�����̿�ʱ��Ҫ��1������B =(i�ڵ��-1)/ÿ�麬��i�ڵ�ṹ����

    // ���磬�ڵ��16��i�ڵ�ṹӦ����B=(16-1)/16 = 0�Ŀ��ϡ� �������Ǵ��豸�϶�ȡ��

    // i�ڵ����ڵ��߼��飬������ָ��i�ڵ����ݵ�inodeָ����ָλ�ô���

306         block = 2 + sb->s_imap_blocks + sb->s_zmap_blocks +

307                 (inode->i_num-1)/INODES_PER_BLOCK;

308         if (!(bh=bread(inode->i_dev,block)))

309                 panic("unable to read i-node block");

310         *(struct d_inode *)inode =

311                 ((struct d_inode *)bh->b_data)

312                         [(inode->i_num-1)%INODES_PER_BLOCK];

    // ����ͷŶ���Ļ���飬��������i�ڵ㡣���ڿ��豸�ļ�������Ҫ����i�ڵ���ļ����

    // ����ֵ��

313         brelse(bh);

314         if (S_ISBLK(inode->i_mode)) {

315                 int i = inode->i_zone[0];   // ���ڿ��豸�ļ���i_zone[0]�����豸�š�

316                 if (blk_size[MAJOR(i)])

317                         inode->i_size = 1024*blk_size[MAJOR(i)][MINOR(i)];

318                 else

319                         inode->i_size = 0x7fffffff;

320         }

321         unlock_inode(inode);

322 }

323

    //// ��i�ڵ���Ϣд�뻺�����С�

    // �ú����Ѳ���ָ����i�ڵ�д�뻺������Ӧ�Ļ�����У���������ˢ��ʱ��д�����С�Ϊ��

    // ȷ��i�ڵ����ڵ��豸�߼���ţ��򻺳�飩���������ȶ�ȡ��Ӧ�豸�ϵij����飬�Ի�ȡ

    // ���ڼ����߼���ŵ�ÿ��i�ڵ�����Ϣ INODES_PER_BLOCK�� �ڼ����i�ڵ����ڵ��߼���

    // �ź󣬾ͰѸ��߼������һ������С�Ȼ���i�ڵ����ݸ��Ƶ���������Ӧλ�ô���

324 static void write_inode(struct m_inode * inode)

325 {

326         struct super_block * sb;

327         struct buffer_head * bh;

328         int block;

329

    // ����������i�ڵ㣬�����i�ڵ�û�б��޸Ĺ����߸�i�ڵ���豸�ŵ����㣬�������

    // i�ڵ㣬���˳�������û�б��޸Ĺ���i�ڵ㣬�������뻺�����л��豸�е���ͬ�� Ȼ��

    // ��ȡ��i�ڵ�ij����顣

330         lock_inode(inode);

331         if (!inode->i_dirt || !inode->i_dev) {

332                 unlock_inode(inode);

333                 return;

334         }

335         if (!(sb=get_super(inode->i_dev)))

336                 panic("trying to write inode without device");

    // ��i�ڵ����ڵ��豸�߼���� = (������ + ������) + i�ڵ�λͼռ�õĿ��� + �߼���λ

    // ͼռ�õĿ��� + (i�ڵ��-1)/ÿ�麬�е�i�ڵ�����  ���Ǵ��豸�϶�ȡ��i�ڵ����ڵ�

    // �߼��飬������i�ڵ���Ϣ���Ƶ��߼����Ӧ��i�ڵ����λ�ô���

337         block = 2 + sb->s_imap_blocks + sb->s_zmap_blocks +

338                 (inode->i_num-1)/INODES_PER_BLOCK;

339         if (!(bh=bread(inode->i_dev,block)))

340                 panic("unable to read i-node block");

341         ((struct d_inode *)bh->b_data)

342                 [(inode->i_num-1)%INODES_PER_BLOCK] =

343                         *(struct d_inode *)inode;

    // Ȼ���û��������޸ı�־����i�ڵ������Ѿ��뻺�����е�һ�£�����޸ı�־���㡣Ȼ��

    // �ͷŸú���i�ڵ�Ļ���������������i�ڵ㡣

344         bh->b_dirt=1;

345         inode->i_dirt=0;

346         brelse(bh);

347         unlock_inode(inode);

348 }

349



 

12.5 ����12-5 linux/fs/super.c


  1 /*

  2  *  linux/fs/super.c

  3  *

  4  *  (C) 1991  Linus Torvalds

  5  */

  6

  7 /*

  8  * super.c contains code to handle the super-block tables.

  9  */

    /*

     * super.c�����к��д�����������Ĵ��롣

     */

 10 #include <linux/config.h> // �ں�����ͷ�ļ�������������Ժ�Ӳ�����ͣ�HD_TYPE����ѡ�

 11 #include <linux/sched.h>  // ���ȳ���ͷ�ļ�������������ṹtask_struct������0�����ݣ�

                              // ����һЩ�й��������������úͻ�ȡ��Ƕ��ʽ��ຯ������䡣

 12 #include <linux/kernel.h> // �ں�ͷ�ļ�������һЩ�ں˳��ú�����ԭ�ζ��塣

 13 #include <asm/system.h>   // ϵͳͷ�ļ������������û��޸�������/�ж��ŵȵ�Ƕ��ʽ���ꡣ

 14

 15 #include <errno.h>        // �����ͷ�ļ�������ϵͳ�и��ֳ����š�

 16 #include <sys/stat.h>     // �ļ�״̬ͷ�ļ��������ļ����ļ�ϵͳ״̬�ṹstat{}�ͳ�����

 17

    // ��ָ���豸ִ�и��ٻ������豸�����ݵ�ͬ��������fs/buffer.c��59�У���

 18 int sync_dev(int dev);

    // �ȴ�������kernel/chr_drv/tty_io.c��140�У���

 19 void wait_for_keypress(void);

 20

 21 /* set_bit uses setb, as gas doesn't recognize setc */

    /* set_bit()ʹ����setbָ���Ϊ��������gas����ʶ��ָ��setc */

    //// ����ָ��λƫ�ƴ�����λ��ֵ�������ظ�ԭ����λֵ��Ӧ��ȡ��Ϊtest_bit()����������

    // Ƕ��ʽ���ꡣ����bitnr�DZ���λƫ��ֵ��addr�Dz��Ա���λ��������ʼ��ַ��

    // %0 - ax(__res)��%1 - 0��%2 - bitnr��%3 - addr

    // ��23�ж�����һ���ֲ��Ĵ����������ñ�������������eax�Ĵ����У��Ա��ڸ�Ч���ʺ�

    // ��������24����ָ��bt ���ڶԱ���λ���в��ԣ�Bit Test��������ѵ�ַaddr��%3����

    // ����λƫ����bitnr��%2��ָ���ı���λ��ֵ�����λ��־CF �С� ָ��setb���ڸ��ݽ�

    // λ��־CF���ò�����%al�����CF = 1��%al = 1������%al = 0��

 22 #define set_bit(bitnr,addr) ({ \

 23 register int __res __asm__("ax"); \

 24 __asm__("bt %2,%3;setb %%al":"=a" (__res):"a" (0),"r" (bitnr),"m" (*(addr))); \

 25 __res; })

 26

 27 struct super_block super_block[NR_SUPER];   // ������ṹ�����飨NR_SUPER = 8����

 28 /* this is initialized in init/main.c */

    /* ROOT_DEV����init/main.c�б���ʼ�� */

 29 int ROOT_DEV = 0;                          // ���ļ�ϵͳ�豸�š�

 30

    // ����3��������lock_super()��free_super()��wait_on_super()����������inode.c��

    // ����ͷ3��������������ͬ��ֻ����������Ķ��󻻳��˳����顣

    //// ���������顣

    // ����������ѱ��������򽫵�ǰ������Ϊ�����жϵĵȴ�״̬�������ӵ��ó�����ȴ���

    // ��s_wait�С�ֱ���ó������������ȷ�ػ��ѱ�����Ȼ�����������

 31 static void lock_super(struct super_block * sb)

 32 {

 33         cli();                               // ���жϡ�

 34         while (sb->s_lock)                   // ����ó������Ѿ���������˯�ߵȴ���

 35                 sleep_on(&(sb->s_wait));     // kernel/sched.c����199�С�

 36         sb->s_lock = 1;                      // ���ó������������������־����

 37         sti();                               // ���жϡ�

 38 }

 39

    //// ��ָ�������������

    // ��λ�������������־������ȷ�ػ��ѵȴ��ڴ˳�����ȴ�����s_wait�ϵ����н��̡�

    // ���ʹ��ulock_super�����������ܸ�������

 40 static void free_super(struct super_block * sb)

 41 {

 42         cli();

 43         sb->s_lock = 0;                      // ��λ������־��

 44         wake_up(&(sb->s_wait));              // ���ѵȴ��ó�����Ľ��̡�

 45         sti();                               // wake_up()��kernel/sched.c����188�С�

 46 }

 47

    //// ˯�ߵȴ������������

    // ����������ѱ��������򽫵�ǰ������Ϊ�����жϵĵȴ�״̬�������ӵ��ó�����ĵȴ���

    // ��s_wait�С�ֱ���ó������������ȷ�ػ��ѱ�����

 48 static void wait_on_super(struct super_block * sb)

 49 {

 50         cli();

 51         while (sb->s_lock)                   // ����������Ѿ���������˯�ߵȴ���

 52                 sleep_on(&(sb->s_wait));

 53         sti();

 54 }

 55

    //// ȡָ���豸�ij����顣

    // �ڳ�����������飩������ָ���豸dev�ij�����ṹ��Ϣ�����ҵ��򷵻س������ָ�룬

    // ���򷵻ؿ�ָ�롣

 56 struct super_block * get_super(int dev)

 57 {

 58         struct super_block * s;              // s�dz��������ݽṹָ�롣

 59

    // �����жϲ��������豸����Ч�ԡ����豸��Ϊ0�򷵻ؿ�ָ�롣Ȼ����sָ�򳬼�������

    // ��ʼ������ʼ�����������������飬��Ѱ��ָ���豸dev�ij����顣 ��62���ϵ�ָ�븳

    // ֵ���"s = 0+super_block" ��ͬ�� "s = super_block"��"s = &super_block[0]"��

 60         if (!dev)

 61                 return NULL;

 62         s = 0+super_block;

 63         while (s < NR_SUPER+super_block)

    // �����ǰ��������ָ���豸�ij����飬���ó�������豸���ֶ�ֵ�뺯������ָ������ͬ��

    // ���ȵȴ��ó�������������ѱ��������������Ļ������ڵȴ��ڼ䣬�ó��������п��ܱ�

    // �����豸ʹ�ã���˵ȴ�����֮�������ж�һ���Ƿ���ָ���豸�ij����飬������򷵻�

    // �ó������ָ�롣��������¶Գ���������������һ�飬��˴�ʱs������ָ�򳬼�����

    // �鿪ʼ����

 64                 if (s->s_dev == dev) {

 65                         wait_on_super(s);

 66                         if (s->s_dev == dev)

 67                                 return s;

 68                         s = 0+super_block;

    // �����ǰ������ǣ�������һ����û���ҵ�ָ���ij����飬�򷵻ؿ�ָ�롣

 69                 } else

 70                         s++;

 71         return NULL;

 72 }

 73

    //// �ͷţ��Żأ�ָ���豸�ij����顣

    // �ͷ��豸��ʹ�õij������������s_dev=0�������ͷŸ��豸i�ڵ�λͼ���߼���λͼ��

    // ռ�õĸ��ٻ���顣����������Ӧ���ļ�ϵͳ�Ǹ��ļ�ϵͳ��������ij��i�ڵ����Ѿ���

    // װ���������ļ�ϵͳ�������ͷŸó����顣

 74 void put_super(int dev)

 75 {

 76         struct super_block * sb;

 77         int i;

 78

    // �����жϲ�������Ч�ԺͺϷ��ԡ����ָ���豸�Ǹ��ļ�ϵͳ�豸������ʾ������Ϣ����ϵ

    // ͳ�̸ı��ˣ�׼��������ս�ɡ��������ء�Ȼ���ڳ��������Ѱ��ָ���豸�ŵ��ļ�ϵͳ��

    // ���顣����Ҳ���ָ���豸�ij����飬�򷵻ء����⣬����ó�����ָ�����ļ�ϵͳ����װ

    // ����i�ڵ㻹û�б�������������ʾ������Ϣ�����ء����ļ�ϵͳж�أ�umount�������У�

    // s_imount���ȱ��ó�Null�Ժ�Ż���ñ��������μ���192�С�

 79         if (dev == ROOT_DEV) {

 80                 printk("root diskette changed: prepare for armageddon\n\r");

 81                 return;

 82         }

 83         if (!(sb = get_super(dev)))

 84                 return;

 85         if (sb->s_imount) {

 86                 printk("Mounted disk changed - tssk, tssk\n\r");

 87                 return;

 88         }

    // Ȼ�����ҵ�ָ���豸�ij�����֮�������������ó����飬���øó������Ӧ���豸���ֶ�

    // s_dev Ϊ0��Ҳ���ͷŸ��豸�ϵ��ļ�ϵͳ�����顣Ȼ���ͷŸó�����ռ�õ������ں���Դ��

    // ���ͷŸ��豸���ļ�ϵͳi�ڵ�λͼ���߼���λͼ�ڻ���������ռ�õĻ���顣���泣����

    // ��I_MAP_SLOTS��Z_MAP_SLOTS������8�����ڷֱ�ָ��i�ڵ�λͼ���߼���λͼռ�õĴ�

    // ���߼�������ע�⣬����Щ��������ݱ��޸Ĺ�������Ҫ��ͬ���������ܰѻ�����е�����

    // д���豸�С��������Ըó���������������ء�

 89         lock_super(sb);

 90         sb->s_dev = 0;                       // �ó�������С�

 91         for(i=0;i<I_MAP_SLOTS;i++)

 92                 brelse(sb->s_imap[i]);

 93         for(i=0;i<Z_MAP_SLOTS;i++)

 94                 brelse(sb->s_zmap[i]);

 95         free_super(sb);

 96         return;

 97 }

 98

    //// ��ȡָ���豸�ij����顣

    // ���ָ���豸dev�ϵ��ļ�ϵͳ�������Ѿ��ڳ�������У���ֱ�ӷ��ظó��������ָ�롣

    // ����ʹ��豸dev�϶�ȡ�����鵽������У������Ƶ���������С������س�����ָ�롣

 99 static struct super_block * read_super(int dev)

100 {

101         struct super_block * s;

102         struct buffer_head * bh;

103         int i,block;

104

    // �����жϲ�������Ч�ԡ����û��ָ���豸���򷵻ؿ�ָ�롣Ȼ������豸�Ƿ�ɸ���

    // ����Ƭ��Ҳ���Ƿ��������豸��������������̣�����ٻ������йظ��豸�����л����

    // ��ʧЧ����Ҫ����ʧЧ���������ͷ�ԭ�����ص��ļ�ϵͳ��

105         if (!dev)

106                 return NULL;

107         check_disk_change(dev);

    // ������豸�ij������Ѿ��ڳ�������У���ֱ�ӷ��ظó������ָ�롣���������ڳ���

    // ���������ҳ�һ������(Ҳ���ֶ�s_dev=0����)����������Ѿ�ռ���򷵻ؿ�ָ�롣

108         if (s = get_super(dev))

109                 return s;

110         for (s = 0+super_block ;; s++) {

111                 if (s >= NR_SUPER+super_block)

112                         return NULL;

113                 if (!s->s_dev)

114                         break;

115         }

    // �ڳ������������ҵ�����֮�󣬾ͽ��ó�����������ָ���豸dev�ϵ��ļ�ϵͳ�����Ƕ�

    // �ó�����ṹ�е��ڴ��ֶν��в��ֳ�ʼ��������

116         s->s_dev = dev;                      // ����dev�豸�ϵ��ļ�ϵͳ��

117         s->s_isup = NULL;

118         s->s_imount = NULL;

119         s->s_time = 0;

120         s->s_rd_only = 0;

121         s->s_dirt = 0;

    // Ȼ�������ó����飬�����豸�϶�ȡ��������Ϣ��bhָ��Ļ�����С�������λ�ڿ��豸

    // �ĵ�2���߼��飨1�ſ飩�У�����1���������̿飩����������������ʧ�ܣ����ͷ���

    // ��ѡ���ij����������е������s_dev=0����������������ؿ�ָ���˳�������ͽ���

    // ���϶�ȡ�ij�������Ϣ�ӻ�������������Ƶ�������������Ӧ��ṹ�С����ͷŴ�Ŷ�ȡ��

    // Ϣ�ĸ��ٻ���顣

122         lock_super(s);

123         if (!(bh = bread(dev,1))) {

124                 s->s_dev=0;

125                 free_super(s);

126                 return NULL;

127         }

128         *((struct d_super_block *) s) =

129                 *((struct d_super_block *) bh->b_data);

130         brelse(bh);

    // �������Ǵ��豸dev�ϵõ����ļ�ϵͳ�ij����飬���ǿ�ʼ���������������Ч�Բ�����

    // ���϶�ȡi�ڵ�λͼ���߼���λͼ����Ϣ���������ȡ�ij�������ļ�ϵͳħ���ֶβ��ԣ�

    // ˵���豸�ϲ�����ȷ���ļ�ϵͳ�����ͬ����һ�����ͷ�����ѡ���ij����������е����

    // ����������ؿ�ָ���˳������ڸð�Linux�ںˣ�ֻ֧��MINIX�ļ�ϵͳ1.0�汾����ħ

    // ����0x137f��

131         if (s->s_magic != SUPER_MAGIC) {

132                 s->s_dev = 0;

133                 free_super(s);

134                 return NULL;

135         }

    // ���濪ʼ��ȡ�豸��i�ڵ�λͼ���߼���λͼ���ݡ����ȳ�ʼ���ڴ泬����ṹ��λͼ�ռ䡣

    // Ȼ����豸�϶�ȡi�ڵ�λͼ���߼���λͼ��Ϣ��������ڳ������Ӧ�ֶ��С�i�ڵ�λͼ

    // �������豸��2�ſ鿪ʼ���߼����У���ռ��s_imap_blocks���顣�߼���λͼ��i�ڵ�λ

    // ͼ���ڿ�ĺ������У���ռ��s_zmap_blocks���顣

136         for (i=0;i<I_MAP_SLOTS;i++)                    // ��ʼ��������

137                 s->s_imap[i] = NULL;

138         for (i=0;i<Z_MAP_SLOTS;i++)

139                 s->s_zmap[i] = NULL;

140         block=2;

141         for (i=0 ; i < s->s_imap_blocks ; i++)         // ��ȡ�豸��i�ڵ�λͼ��

142                 if (s->s_imap[i]=bread(dev,block))

143                         block++;

144                 else

145                         break;

146         for (i=0 ; i < s->s_zmap_blocks ; i++)         // ��ȡ�豸���߼���λͼ��

147                 if (s->s_zmap[i]=bread(dev,block))

148                         block++;

149                 else

150                         break;

    // ���������λͼ����������λͼӦ��ռ�е��߼�������˵���ļ�ϵͳλͼ��Ϣ�����⣬����

    // ���ʼ��ʧ�ܡ����ֻ���ͷ�ǰ�����벢ռ�õ�������Դ�����ͷ�i�ڵ�λͼ���߼���λͼ

    // ռ�õĸ��ٻ���顢�ͷ�����ѡ���ij���������������ó�����������ؿ�ָ���˳���

151         if (block != 2+s->s_imap_blocks+s->s_zmap_blocks) {

152                 for(i=0;i<I_MAP_SLOTS;i++)             // �ͷ�λͼռ�õĸ��ٻ���顣

153                         brelse(s->s_imap[i]);

154                 for(i=0;i<Z_MAP_SLOTS;i++)

155                         brelse(s->s_zmap[i]);

156                 s->s_dev=0;                            // �ͷ�ѡ���ij����������

157                 free_super(s);                         // �����ó������

158                 return NULL;

159         }

    // ����һ�гɹ������⣬���ڶ����������i�ڵ�ĺ�������������豸�����е�i�ڵ��Ѿ�

    // ȫ��ʹ�ã�����Һ����᷵��0ֵ�����0��i�ڵ��Dz����õģ��������ォλͼ�е�1��

    // ����ͱ���λ����Ϊ1���Է�ֹ�ļ�ϵͳ����0��i�ڵ㡣ͬ���ĵ�����Ҳ���߼���λͼ��

    // ���λ����Ϊ1������������ó����飬�����س�����ָ�롣

160         s->s_imap[0]->b_data[0] |= 1;

161         s->s_zmap[0]->b_data[0] |= 1;

162         free_super(s);

163         return s;

164 }

165

    //// ж���ļ�ϵͳ��ϵͳ���ã���

    // ����dev_name���ļ�ϵͳ�����豸���豸�ļ�����

    // �ú������ȸ��ݲ��������Ŀ��豸�ļ�������豸�ţ�Ȼ��λ�ļ�ϵͳ�������е���Ӧ��

    // �Σ��ͷų������λͼռ�õĻ���飬���Ը��豸ִ�и��ٻ������豸�����ݵ�ͬ��������

    // ��ж�ز����ɹ��򷵻�0�����򷵻س����롣

166 int sys_umount(char * dev_name)

167 {

168         struct m_inode * inode;

169         struct super_block * sb;

170         int dev;

171

    // ���ȸ����豸�ļ����ҵ���Ӧ��i�ڵ㣬��ȡ���е��豸�š��豸�ļ��������豸���豸��

    // �DZ�������i�ڵ��i_zone[0]�еġ� �μ�����namei.c������ϵͳ����sys_mknod()�Ĵ�

    // ���445�С����⣬�����ļ�ϵͳ��Ҫ����ڿ��豸�ϣ����������ǿ��豸�ļ�����Ż�

    // �������i�ڵ�dev_i�����س����롣

172         if (!(inode=namei(dev_name)))

173                 return -ENOENT;

174         dev = inode->i_zone[0];

175         if (!S_ISBLK(inode->i_mode)) {

176                 iput(inode);                           // fs/inode.c����150�С�

177                 return -ENOTBLK;

178         }

    // OK����������Ϊ�˵õ��豸�Ŷ�ȡ�õ�i�ڵ������������ʹ�����������Żظ��豸�ļ�

    // ��i�ڵ㡣�������������һ��ж�ظ��ļ�ϵͳ�������Ƿ����㡣����豸���Ǹ��ļ�ϵͳ��

    // ���ܱ�ж�أ�����æ�����š�

179         iput(inode);

180         if (dev==ROOT_DEV)

181                 return -EBUSY;

    // ����ڳ��������û���ҵ����豸���ļ�ϵͳ�ij����飬�������ҵ����Ǹ��豸���ļ�ϵͳ

    // û�а�װ�����򷵻س����롣�����������ָ���ı���װ����i�ڵ㲢û����λ�䰲װ��־

    // i_mount������ʾ������Ϣ�� Ȼ�����һ��i�ڵ���������Ƿ��н�����ʹ�ø��豸�ϵ���

    // ����������򷵻�æ�����롣

182         if (!(sb=get_super(dev)) || !(sb->s_imount))

183                 return -ENOENT;

184         if (!sb->s_imount->i_mount)

185                 printk("Mounted inode has i_mount=0\n");

186         for (inode=inode_table+0 ; inode<inode_table+NR_INODE ; inode++)

187                 if (inode->i_dev==dev && inode->i_count)

188                                 return -EBUSY;

    // ���ڸ��豸���ļ�ϵͳ��ж���������õ����㣬������ǿ��Կ�ʼʵʩ������ж�ز����ˡ�

    // ���ȸ�λ����װ����i�ڵ�İ�װ��־���ͷŸ�i�ڵ㡣Ȼ���ó������б���װi�ڵ��ֶ�

    // Ϊ�գ����Ż��豸�ļ�ϵͳ�ĸ�i�ڵ㣬�����ó������б���װϵͳ��i�ڵ�ָ��Ϊ�ա�

189         sb->s_imount->i_mount=0;

190         iput(sb->s_imount);

191         sb->s_imount = NULL;

192         iput(sb->s_isup);

193         sb->s_isup = NULL;

    // ��������ͷŸ��豸�ϵij������Լ�λͼռ�õĸ��ٻ���飬���Ը��豸ִ�и��ٻ�������

    // �������ݵ�ͬ��������Ȼ�󷵻�0��ж�سɹ�����

194         put_super(dev);

195         sync_dev(dev);

196         return 0;

197 }

198

    //// ��װ�ļ�ϵͳ��ϵͳ���ã���

    // ����dev_name���豸�ļ�����dir_name�ǰ�װ����Ŀ¼����rw_flag����װ�ļ�ϵͳ�Ŀ�

    // ��д��־���������صĵط�������һ��Ŀ¼�������Ҷ�Ӧ��i�ڵ�û�б���������ռ�á�

    // �������ɹ��򷵻�0�����򷵻س����š�

199 int sys_mount(char * dev_name, char * dir_name, int rw_flag)

200 {

201         struct m_inode * dev_i, * dir_i;

202         struct super_block * sb;

203         int dev;

204

    // ���ȸ����豸�ļ����ҵ���Ӧ��i�ڵ㣬��ȡ�����е��豸�š����ڿ������豸�ļ����豸

    // ������i�ڵ��i_zone[0]�С����⣬�����ļ�ϵͳ�����ڿ��豸�У����������ǿ��豸

    // �ļ�����Żظ�ȡ�õ�i�ڵ�dev_i�����س����롣

205         if (!(dev_i=namei(dev_name)))

206                 return -ENOENT;

207         dev = dev_i->i_zone[0];

208         if (!S_ISBLK(dev_i->i_mode)) {

209                 iput(dev_i);

210                 return -EPERM;

211         }

    // OK����������Ϊ�˵õ��豸�Ŷ�ȡ�õ�i�ڵ�dev_i�����������ʹ�����������Żظ���

    // ���ļ���i�ڵ㡣�������������һ���ļ�ϵͳ��װ����Ŀ¼���Ƿ���Ч�����Ǹ��ݸ�����

    // Ŀ¼�ļ����ҵ���Ӧ��i�ڵ� dir_i�� �����i�ڵ�����ü�����Ϊ1�������������ã���

    // ���߸�i�ڵ�Ľڵ���Ǹ��ļ�ϵͳ�Ľڵ��1����Żظ�i�ڵ㷵�س����롣���⣬���

    // �ýڵ㲻��һ��Ŀ¼�ļ��ڵ㣬��Ҳ�Żظ�i�ڵ㣬���س����롣��Ϊ�ļ�ϵͳֻ�ܰ�װ��

    // һ��Ŀ¼���ϡ�

212         iput(dev_i);

213         if (!(dir_i=namei(dir_name)))

214                 return -ENOENT;

215         if (dir_i->i_count != 1 || dir_i->i_num == ROOT_INO) {

216                 iput(dir_i);

217                 return -EBUSY;

218         }

219         if (!S_ISDIR(dir_i->i_mode)) {                 // ��װ����Ҫ��һ��Ŀ¼����

220                 iput(dir_i);

221                 return -EPERM;

222         }

    // ���ڰ�װ��Ҳ�����ϣ����ǿ�ʼ��ȡҪ��װ�ļ�ϵͳ�ij�������Ϣ����������������ʧ

    // �ܣ���Żظð�װ��i�ڵ�dir_i�����س����롣һ���ļ�ϵͳ�ij���������ȴӳ������

    // �н���������������ڳ�������оʹ��豸�϶�ȡ��

223         if (!(sb=read_super(dev))) {

224                 iput(dir_i);

225                 return -EBUSY;

226         }

    // �ڵõ����ļ�ϵͳ������֮�����Ƕ����Ƚ��м��һ���������Ҫ����װ���ļ�ϵͳ�Ѿ�

    // ��װ�������ط�����Żظ�i�ڵ㣬���س����롣�����Ҫ��װ����i�ڵ��Ѿ���װ���ļ�

    // ϵͳ����װ��־�Ѿ���λ������Żظ�i�ڵ㣬Ҳ���س����롣

227         if (sb->s_imount) {

228                 iput(dir_i);

229                 return -EBUSY;

230         }

231         if (dir_i->i_mount) {

232                 iput(dir_i);

233                 return -EPERM;

234         }

    // ������ñ���װ�ļ�ϵͳ������ġ�����װ��i�ڵ㡱�ֶ�ָ��װ����Ŀ¼����i�ڵ㡣

    // �����ð�װλ��i�ڵ�İ�װ��־�ͽڵ����޸ı�־��Ȼ�󷵻�0����װ�ɹ�����

235         sb->s_imount=dir_i;

236         dir_i->i_mount=1;

237         dir_i->i_dirt=1;/* NOTE! we don't iput(dir_i) */ /*ע��!����û��iput(dir_i)*/

238         return 0;       /* we do that in umount */       /* �⽫��umount�ڲ��� */

239 }

240

    //// ��װ���ļ�ϵͳ��

    // �ú�������ϵͳ��ʼ��������һ���֡��������ȳ�ʼ���ļ�������file_table[]�ͳ������

    // �����飩��Ȼ���ȡ���ļ�ϵͳ�����飬��ȡ���ļ�ϵͳ��i�ڵ㡣 ���ͳ�Ʋ���ʾ������

    // ��ϵͳ�ϵĿ�����Դ�����п����Ϳ���i�ڵ������� �ú�������ϵͳ�������г�ʼ������ʱ

    // ��sys_setup()�����ã�blk_drv/hd.c��157�У���

241 void mount_root(void)

242 {

243         int i,free;

244         struct super_block * p;

245         struct m_inode * mi;

246

    // ������i�ڵ�ṹ����32�ֽڣ������ͣ�������ж����ڷ�ֹ�޸Ĵ���ʱ���ֲ�һ�������

247         if (32 != sizeof (struct d_inode))

248                 panic("bad i-node size");

    // ���ȳ�ʼ���ļ������飨��64���ϵͳͬʱֻ�ܴ�64���ļ����ͳ�����������ォ��

    // ���ļ��ṹ�е����ü�������Ϊ0����ʾ���У������ѳ�������и���ṹ���豸�ֶγ�ʼ

    // ��Ϊ0��Ҳ��ʾ���У���������ļ�ϵͳ�����豸�����̵Ļ�������ʾ��������ļ�ϵͳ�̣�

    // �����س����������ȴ�������

249         for(i=0;i<NR_FILE;i++)                         // ��ʼ���ļ�����

250                 file_table[i].f_count=0;

251         if (MAJOR(ROOT_DEV) == 2) {                    // ��ʾ������ļ�ϵͳ�̡�

252                 printk("Insert root floppy and press ENTER");

253                 wait_for_keypress();

254         }

255         for(p = &super_block[0] ; p < &super_block[NR_SUPER] ; p++) {

256                 p->s_dev = 0;                          // ��ʼ�����������

257                 p->s_lock = 0;

258                 p->s_wait = NULL;

259         }

    // �������ϡ����⡱�ij�ʼ������֮�����ǿ�ʼ��װ���ļ�ϵͳ�����ǴӸ��豸�϶�ȡ�ļ�

    // ϵͳ�����飬��ȡ���ļ�ϵͳ�ĸ�i�ڵ㣨1�Žڵ㣩���ڴ�i�ڵ���е�ָ�롣�������

    // �豸�ϳ�����ʧ�ܻ�ȡ���ڵ�ʧ�ܣ�����ʾ��Ϣ��ͣ����

260         if (!(p=read_super(ROOT_DEV)))

261                 panic("Unable to mount root");

262         if (!(mi=iget(ROOT_DEV,ROOT_INO)))           // ��fs.h��ROOT_INO����Ϊ1��

263                 panic("Unable to read root i-node");

    // �������ǶԳ�����͸�i�ڵ�������á��Ѹ�i�ڵ����ô�������3�Ρ���Ϊ����266����

    // Ҳ�����˸�i�ڵ㡣���⣬iget() ������i�ڵ����ü����ѱ�����Ϊ1��Ȼ���øó������

    // ����װ�ļ�ϵͳi�ڵ�ͱ���װ��i�ڵ��ֶ�Ϊ��i�ڵ㡣�����õ�ǰ���̵ĵ�ǰ����Ŀ¼

    // �͸�Ŀ¼i�ڵ㡣��ʱ��ǰ������1�Ž��̣�init���̣���

264         mi->i_count += 3 ;    /* NOTE! it is logically used 4 times, not 1 */

                                  /* ע�⣡���߼��Ͻ������ѱ�������4�Σ�������1�� */

265         p->s_isup = p->s_imount = mi;

266         current->pwd = mi;

267         current->root = mi;

    // Ȼ�����ǶԸ��ļ�ϵͳ�ϵ���Դ��ͳ�ƹ�����ͳ�Ƹ��豸�Ͽ��п����Ϳ���i�ڵ���������

    // ��i���ڳ������б������豸�߼���������Ȼ������߼���λͼ����Ӧ����λ��ռ�����ͳ

    // �Ƴ����п���������꺯��set_bit()ֻ���ڲ��Ա���λ���������ñ���λ��"i&8191" ����

    // ȡ��i�ڵ���ڵ�ǰλͼ���ж�Ӧ�ı���λƫ��ֵ��"i>>13" �ǽ�i����8192��Ҳ����һ��

    // ���̿�����ı���λ����

268         free=0;

269         i=p->s_nzones;

270         while (-- i >= 0)

271                 if (!set_bit(i&8191,p->s_zmap[i>>13]->b_data))

272                         free++;

    // ����ʾ���豸�Ͽ����߼�����/�߼�������֮��������ͳ���豸�Ͽ���i�ڵ�����������i

    // ���ڳ������б������豸��i�ڵ�����+1����1�ǽ�0�ڵ�Ҳͳ�ƽ�ȥ��Ȼ�����i�ڵ�λ

    // ͼ����Ӧ����λ��ռ��������������i�ڵ������������ʾ�豸�Ͽ��ÿ���i�ڵ�����i

    // �ڵ�������

273         printk("%d/%d free blocks\n\r",free,p->s_nzones);

274         free=0;

275         i=p->s_ninodes+1;

276         while (-- i >= 0)

277                 if (!set_bit(i&8191,p->s_imap[i>>13]->b_data))

278                         free++;

279         printk("%d/%d free inodes\n\r",free,p->s_ninodes);

280 }

281


 


 

12.6 ����12-6 linux/fs/namei.c


  1 /*

  2  *  linux/fs/namei.c

  3  *

  4  *  (C) 1991  Linus Torvalds

  5  */

  6

  7 /*

  8  * Some corrections by tytso.

  9  */

 10

 11 #include <linux/sched.h>  // ���ȳ���ͷ�ļ�������������ṹtask_struct������0�����ݵȡ�

 12 #include <linux/kernel.h> // �ں�ͷ�ļ�������һЩ�ں˳��ú�����ԭ�ζ��塣

 13 #include <asm/segment.h>  // �β���ͷ�ļ����������йضμĴ���������Ƕ��ʽ��ຯ����

 14

 15 #include <string.h>       // �ַ���ͷ�ļ�����Ҫ������һЩ�й��ַ���������Ƕ�뺯����

 16 #include <fcntl.h>        // �ļ�����ͷ�ļ����ļ������������IJ������Ƴ������ŵĶ��塣

 17 #include <errno.h>        // �����ͷ�ļ�������ϵͳ�и��ֳ����š�

 18 #include <const.h>        // ��������ͷ�ļ���Ŀǰ������i�ڵ���i_mode�ֶεĸ���־λ��

 19 #include <sys/stat.h>     // �ļ�״̬ͷ�ļ��������ļ����ļ�ϵͳ״̬�ṹstat{}�ͳ�����

 20

    // ���ļ������Ҷ�Ӧi�ڵ���ڲ�������

 21 static struct m_inode * _namei(const char * filename, struct m_inode * base,

 22         int follow_links);

 23

    // ��������Ҳ����ʽ�Ƿ��������һ������ʹ�÷�����������������һ����ʵ��������������

    // �����±�����ʾ�����������a[b]����ֵ��ͬ��ʹ��������ָ�루��ַ�����ϸ���ƫ�Ƶ�ַ

    // ����ʽ��ֵ *(a + b)��ͬʱ��֪��a[b]Ҳ���Ա�ʾ��b[a]����ʽ����˶����ַ���������ʽ

    // Ϊ "LoveYou"[2]������2["LoveYou"]���͵�ͬ��*("LoveYou" + 2)�����⣬�ַ���"LoveYou"

    // ���ڴ��б��洢��λ�þ������ַ�����������"LoveYou"[2]��ֵ���Ǹ��ַ���������ֵΪ2

    // ���ַ�"v"����Ӧ��ASCII��ֵ0x76�����ð˽��Ʊ�ʾ����0166����C�����У��ַ�Ҳ������

    // ��ASCII��ֵ����ʾ�����������ַ���ASCII��ֵǰ���һ����б�ܡ������ַ� "v"���Ա�ʾ

    // ��"\x76"����"\166"����˶��ڲ�����ʾ���ַ�������ASCII��ֵΪ0x00--0x1f�Ŀ����ַ���

    // �Ϳ�����ASCII��ֵ����ʾ��

    //

    // �����Ƿ���ģʽ�ꡣx��ͷ�ļ�include/fcntl.h�е�7�п�ʼ������ļ����ʣ��򿪣���־��

    // ���������ļ����ʱ�־x��ֵ������˫�����ж�Ӧ����ֵ��˫��������4���˽�����ֵ��ʵ

    // �ʱ�ʾ4�������ַ�����"\004\002\006\377"���ֱ��ʾ����д��ִ�е�Ȩ��Ϊ: r��w��rw

    // ��wxrwxrwx�����ҷֱ��Ӧx������ֵ0--3�� ���磬���xΪ2����ú귵�ذ˽���ֵ006��

    // ��ʾ�ɶ���д��rw�������⣬����O_ACCMODE = 00003��������ֵx�������롣

 24 #define ACC_MODE(x) ("\004\002\006\377"[(x)&O_ACCMODE])

 25

 26 /*

 27  * comment out this line if you want names > NAME_LEN chars to be

 28  * truncated. Else they will be disallowed.

 29  */

     /*

     * ��������ļ������� > NAME_LEN�����ַ����ص����ͽ����涨��ע�͵���

     */

 30 /* #define NO_TRUNCATE */

 31

 32 #define MAY_EXEC 1        // ��ִ��(�ɽ���)��

 33 #define MAY_WRITE 2       // ��д��

 34 #define MAY_READ 4        // �ɶ���

 35

 36 /*

 37  *      permission()

 38  *

 39  * is used to check for read/write/execute permissions on a file.

 40  * I don't know if we should look at just the euid or both euid and

 41  * uid, but that should be easily changed.

 42  */

    /*

     *     permission()

     *

     * �ú������ڼ��һ���ļ��Ķ�/д/ִ��Ȩ�ޡ��Ҳ�֪���Ƿ�ֻ����euid��

     * ������Ҫ���euid��uid���ߣ�������������޸ġ�

     */

    //// ����ļ���������Ȩ�ޡ�

    // ������inode - �ļ���i�ڵ�ָ�룻mask - �������������롣

    // ���أ��������ɷ���1�����򷵻�0��

 43 static int permission(struct m_inode * inode,int mask)

 44 {

 45         int mode = inode->i_mode;                   // �ļ��������ԡ�

 46

 47 /* special case: not even root can read/write a deleted file */

    /* �����������ʹ�dz����û���root��Ҳ���ܶ�/дһ���ѱ�ɾ�����ļ� */

    // ���i�ڵ��ж�Ӧ���豸������i�ڵ�����Ӽ���ֵ����0����ʾ���ļ��ѱ�ɾ�����򷵻ء�

    // ����������̵���Ч�û�id��euid����i�ڵ���û�id��ͬ����ȡ�ļ������ķ���Ȩ�ޡ�

    // ����������̵���Ч��id��egid����i�ڵ����id��ͬ����ȡ���û��ķ���Ȩ�ޡ�

 48         if (inode->i_dev && !inode->i_nlinks)

 49                 return 0;

 50         else if (current->euid==inode->i_uid)

 51                 mode >>= 6;

 52         else if (in_group_p(inode->i_gid))

 53                 mode >>= 3;

    // ����ж������ȡ�ĵķ���Ȩ������������ͬ�������dz����û����򷵻�1�����򷵻�0��

 54         if (((mode & mask & 0007) == mask) || suser())

 55                 return 1;

 56         return 0;

 57 }

 58

 59 /*

 60  * ok, we cannot use strncmp, as the name is not in our data space.

 61  * Thus we'll have to use match. No big problem. Match also makes

 62  * some sanity tests.

 63  *

 64  * NOTE! unlike strncmp, match returns 1 for success, 0 for failure.

 65  */

    /*

     * ok�����Dz���ʹ��strncmp�ַ����ȽϺ�������Ϊ���Ʋ������ǵ����ݿռ�

     * �������ں˿ռ䣩�� �������ֻ��ʹ�� match()�����ⲻ��match()ͬ��

     * Ҳ����һЩ�����IJ��ԡ�

     *

     * ע�⣡��strncmp��ͬ����match()�ɹ�ʱ����1��ʧ��ʱ����0��

     */

    //// ָ�������ַ����ȽϺ�����

    // ������len - �Ƚϵ��ַ������ȣ�name - �ļ���ָ�룻de - Ŀ¼��ṹ��

    // ���أ���ͬ����1����ͬ����0��

    // ��68���϶�����һ���ֲ��Ĵ�������same���ñ�������������eax�Ĵ����У��Ա��ڸ�Ч

    // ���ʡ�

 66 static int match(int len,const char * name,struct dir_entry * de)

 67 {

 68         register int same __asm__("ax");

 69

    // �����жϺ�����������Ч�ԡ����Ŀ¼��ָ��գ�����Ŀ¼��i�ڵ����0������Ҫ�Ƚϵ�

    // �ַ������ȳ����ļ������ȣ��򷵻�0����ƥ�䣩������Ƚϵij���len����0����Ŀ¼��

    // ���ļ����ĵ�1���ַ��� '.'������ֻ����ôһ���ַ�����ô���Ǿ���Ϊ����ͬ�ģ���˷�

    // ��1��ƥ�䣩�����Ҫ�Ƚϵij���lenС��NAME_LEN������Ŀ¼�����ļ������ȳ���len��

    // ��Ҳ����0����ƥ�䣩��

    // ��75���϶�Ŀ¼�����ļ��������Ƿ񳬹� len ���жϷ����Ǽ�� name[len] �Ƿ�ΪNULL��

    // �����ȳ���len����name[len]������һ������NULL����ͨ�ַ��������ڳ���Ϊlen���ַ�

    // ��name���ַ�name[len]��Ӧ����NULL��

 70         if (!de || !de->inode || len > NAME_LEN)

 71                 return 0;

 72         /* "" means "." ---> so paths like "/usr/lib//libc.a" work */

            /* "" ���� "." ������ ---> �������ܴ����� "/usr/lib//libc.a" ������·���� */

 73         if (!len && (de->name[0]=='.') && (de->name[1]=='\0'))

 74                 return 1;

 75         if (len < NAME_LEN && de->name[len])

 76                 return 0;

    // Ȼ��ʹ��Ƕ���������п��ٱȽϲ������������û����ݿռ䣨fs�Σ�ִ���ַ����ıȽ�

    // ������%0 - eax���ȽϽ��same����%1 - eax��eax��ֵ0����%2 - esi������ָ�룩��

    // %3 - edi��Ŀ¼����ָ�룩��%4 - ecx(�Ƚϵ��ֽڳ���ֵlen)��

 77         __asm__("cld\n\t"                 // �巽���־λ��

 78                 "fs ; repe ; cmpsb\n\t"   // �û��ռ�ִ��ѭ���Ƚ�[esi++]��[edi++]������

 79                 "setz %%al"               // ���ȽϽ��һ����zf=0������al=1��same=eax����

 80                 :"=a" (same)

 81                 :"" (0),"S" ((long) name),"D" ((long) de->name),"c" (len)

 82                 :"cx","di","si");

 83         return same;                      // ���رȽϽ����

 84 }

 85

 86 /*

 87  *      find_entry()

 88  *

 89  * finds an entry in the specified directory with the wanted name. It

 90  * returns the cache buffer in which the entry was found, and the entry

 91  * itself (as a parameter - res_dir). It does NOT read the inode of the

 92  * entry - you'll have to do that yourself if you want to.

 93  *

 94  * This also takes care of the few special cases due to '..'-traversal

 95  * over a pseudo-root and a mount point.

 96  */

    /*

     *     find_entry()

     *

     * ��ָ��Ŀ¼��Ѱ��һ��������ƥ���Ŀ¼�����һ�������ҵ�Ŀ¼��ĸ���

     * ������Լ�Ŀ¼�������Ϊһ������ - res_dir�����ú���������ȡĿ¼��

     * ��i�ڵ� - �����Ҫ�Ļ����Լ�������

     *

     * ������'..'Ŀ¼�����ڲ����ڼ�Ҳ��Լ�����������ֱ��� - �����Խ

     * һ��α��Ŀ¼�Լ���װ�㡣

     */

    //// ����ָ��Ŀ¼���ļ�����Ŀ¼�

    // ������*dir - ָ��Ŀ¼i�ڵ��ָ�룻name - �ļ�����namelen - �ļ������ȣ�

    // �ú�����ָ��Ŀ¼�����ݣ��ļ���������ָ���ļ�����Ŀ¼�����ָ���ļ�����'..'��

    // ������ݵ�ǰ���е�������ý������⴦�������ں�����������ָ���ָ������ã����

    // ��linux/sched.c��151��ǰ��ע�͡�

    // ���أ��ɹ��������ٻ�����ָ�룬����*res_dir�����ص�Ŀ¼��ṹָ�롣ʧ���򷵻�

    // ��ָ��NULL��

 97 static struct buffer_head * find_entry(struct m_inode ** dir,

 98         const char * name, int namelen, struct dir_entry ** res_dir)

 99 {

100         int entries;

101         int block,i;

102         struct buffer_head * bh;

103         struct dir_entry * de;

104         struct super_block * sb;

105

    // ͬ����������һ����Ҳ��Ҫ�Ժ�����������Ч�Խ����жϺ���֤�����������ǰ���30��

    // �����˷��ų���NO_TRUNCATE����ô����ļ������ȳ�����󳤶�NAME_LEN�����账����

    // ���û�ж����NO_TRUNCATE����ô���ļ������ȳ�����󳤶�NAME_LENʱ�ض�֮��

106 #ifdef NO_TRUNCATE

107         if (namelen > NAME_LEN)

108                 return NULL;

109 #else

110         if (namelen > NAME_LEN)

111                 namelen = NAME_LEN;

112 #endif

 

    // ���ȼ��㱾Ŀ¼��Ŀ¼������entries�� Ŀ¼i�ڵ� i_size�ֶ��к��б�Ŀ¼����������

    // ���ȣ���������һ��Ŀ¼��ij��ȣ�16�ֽڣ����ɵõ���Ŀ¼��Ŀ¼������Ȼ���ÿշ���

    // Ŀ¼��ṹָ�롣

113         entries = (*dir)->i_size / (sizeof (struct dir_entry));

114         *res_dir = NULL;

    // ���������Ƕ�Ŀ¼���ļ�����'..'������������⴦���������ǰ����ָ���ĸ�i�ڵ����

    // ��������ָ����Ŀ¼����˵�����ڱ�������˵�����Ŀ¼��������α��Ŀ¼��������ֻ�ܷ�

    // �ʸ�Ŀ¼�е�������ܺ��˵��丸Ŀ¼��ȥ��Ҳ�����ڸý��̱�Ŀ¼����ͬ���ļ�ϵͳ�ĸ�

    // Ŀ¼�����������Ҫ���ļ����޸�Ϊ'.'��

    // ���������Ŀ¼��i�ڵ�ŵ���ROOT_INO��1�ţ��Ļ���˵��ȷʵ���ļ�ϵͳ�ĸ�i�ڵ㡣

    // ��ȡ�ļ�ϵͳ�ij����顣�������װ����i�ڵ���ڣ����ȷŻ�ԭi�ڵ㣬Ȼ��Ա���װ��

    // ��i�ڵ���д���������������*dirָ��ñ���װ����i�ڵ㣻���Ҹ�i�ڵ����������1��

    // ���������������������ĵؽ����ˡ�͵������������:)

115 /* check for '..', as we might have to do some "magic" for it */

    /* ���Ŀ¼�� '..'����Ϊ���ǿ�����Ҫ����������⴦�� */

116         if (namelen==2 && get_fs_byte(name)=='.' && get_fs_byte(name+1)=='.') {

117 /* '..' in a pseudo-root results in a faked '.' (just change namelen) */

    /* α���е� '..' ��ͬһ���� '.'��ֻ��ı����ֳ��ȣ� */

118                 if ((*dir) == current->root)

119                         namelen=1;

120                 else if ((*dir)->i_num == ROOT_INO) {

121 /* '..' over a mount-point results in 'dir' being exchanged for the mounted

122    directory-inode. NOTE! We set mounted, so that we can iput the new dir */

    /* ��һ����װ���ϵ� '..' ������Ŀ¼����������װ�ļ�ϵͳ��Ŀ¼i�ڵ��ϡ�ע�⣡

       ��������������mounted��־����������ܹ��Żظ���Ŀ¼ */

123                         sb=get_super((*dir)->i_dev);

124                         if (sb->s_imount) {

125                                 iput(*dir);

126                                 (*dir)=sb->s_imount;

127                                 (*dir)->i_count++;

128                         }

129                 }

130         }

 

    // �������ǿ�ʼ��������������ָ���ļ�����Ŀ¼����ʲô�ط������������Ҫ��ȡĿ¼����

    // �ݣ���ȡ��Ŀ¼i�ڵ��Ӧ���豸�������е����ݿ飨�߼��飩��Ϣ����Щ�߼���Ŀ�ű�

    // ����i�ڵ�ṹ�� i_zone[9]�����С�������ȡ���е�1����š����Ŀ¼i�ڵ�ָ��ĵ�

    // һ��ֱ�Ӵ��̿��Ϊ0����˵����Ŀ¼��Ȼ�������ݣ��ⲻ���������Ƿ���NULL�˳�������

    // ���Ǿʹӽڵ������豸��ȡָ����Ŀ¼�����ݿ顣��Ȼ��������ɹ�����Ҳ����NULL�˳���

131         if (!(block = (*dir)->i_zone[0]))

132                 return NULL;

133         if (!(bh = bread((*dir)->i_dev,block)))

134                 return NULL;

 

    // ��ʱ���Ǿ��������ȡ��Ŀ¼i�ڵ����ݿ�������ƥ��ָ���ļ�����Ŀ¼�������deָ

    // �򻺳���е����ݿ鲿�֣����ڲ�����Ŀ¼��Ŀ¼�����������£�ѭ��ִ������������i��

    // Ŀ¼�е�Ŀ¼�������ţ���ѭ����ʼʱ��ʼ��Ϊ0��

135         i = 0;

136         de = (struct dir_entry *) bh->b_data;

137         while (i < entries) {

    // �����ǰĿ¼�����ݿ��Ѿ������꣬��û���ҵ�ƥ���Ŀ¼����ͷŵ�ǰĿ¼�����ݿ顣

    // �ٶ���Ŀ¼����һ���߼��顣�����Ϊ�գ���ֻҪ��û��������Ŀ¼�е�����Ŀ¼���

    // �����ÿ飬������Ŀ¼����һ�߼��顣���ÿ鲻�գ����� de ָ������ݿ飬Ȼ��������

    // ��������������141����i/DIR_ENTRIES_PER_BLOCK�ɵõ���ǰ������Ŀ¼������Ŀ¼��

    // ���еĿ�ţ���bmap()������inode.c����142�У���ɼ�������豸�϶�Ӧ���߼���š�

138                 if ((char *)de >= BLOCK_SIZE+bh->b_data) {

139                         brelse(bh);

140                         bh = NULL;

141                         if (!(block = bmap(*dir,i/DIR_ENTRIES_PER_BLOCK)) ||

142                             !(bh = bread((*dir)->i_dev,block))) {

143                                 i += DIR_ENTRIES_PER_BLOCK;

144                                 continue;

145                         }

146                         de = (struct dir_entry *) bh->b_data;

147                 }

    // ����ҵ�ƥ���Ŀ¼��Ļ����򷵻ظ�Ŀ¼��ṹָ��de�͸�Ŀ¼��i�ڵ�ָ��*dir��

    // ����Ŀ¼�����ݿ�ָ��bh�����˳����������������Ŀ¼�����ݿ��бȽ���һ��Ŀ¼�

148                 if (match(namelen,name,de)) {

149                         *res_dir = de;

150                         return bh;

151                 }

152                 de++;

153                 i++;

154         }

    // ���ָ��Ŀ¼�е�����Ŀ¼�������󣬻�û���ҵ���Ӧ��Ŀ¼����ͷ�Ŀ¼������

    // �飬��󷵻�NULL��ʧ�ܣ���

155         brelse(bh);

156         return NULL;

157 }

158

159 /*

160  *      add_entry()

161  *

162  * adds a file entry to the specified directory, using the same

163  * semantics as find_entry(). It returns NULL if it failed.

164  *

165  * NOTE!! The inode part of 'de' is left at 0 - which means you

166  * may not sleep between calling this and putting something into

167  * the entry, as someone else might have used it while you slept.

168  */

    /*

     *     add_entry()

     * ʹ����find_entry()ͬ���ķ�������ָ��Ŀ¼������һָ���ļ�����Ŀ

     * ¼����ʧ���򷵻�NULL��

     *

     * ע�⣡��'de'��ָ��Ŀ¼��ṹָ�룩��i�ڵ㲿�ֱ�����Ϊ0 - ���

     * ʾ�ڵ��øú�������Ŀ¼����������Ϣ֮�䲻��ȥ˯�ߡ� ��Ϊ���˯�ߣ�

     * ��ô������(����)���ܻ�ʹ���˸�Ŀ¼�

     */

    //// ����ָ����Ŀ¼���ļ�������Ŀ¼�

    // ������dir - ָ��Ŀ¼��i�ڵ㣻name - �ļ�����namelen - �ļ������ȣ�

    // ���أ����ٻ�����ָ�룻res_dir - ���ص�Ŀ¼��ṹָ�룻

169 static struct buffer_head * add_entry(struct m_inode * dir,

170         const char * name, int namelen, struct dir_entry ** res_dir)

171 {

172         int block,i;

173         struct buffer_head * bh;

174         struct dir_entry * de;

175

    // ͬ����������һ����Ҳ��Ҫ�Ժ�����������Ч�Խ����жϺ���֤�����������ǰ���30��

    // �����˷��ų���NO_TRUNCATE����ô����ļ������ȳ�����󳤶�NAME_LEN�����账����

    // ���û�ж����NO_TRUNCATE����ô���ļ������ȳ�����󳤶�NAME_LENʱ�ض�֮��

176         *res_dir = NULL;                  // ���ڷ���Ŀ¼��ṹָ�롣

177 #ifdef NO_TRUNCATE

178         if (namelen > NAME_LEN)

179                 return NULL;

180 #else

181         if (namelen > NAME_LEN)

182                 namelen = NAME_LEN;

183 #endif

    // �������ǿ�ʼ��������ָ��Ŀ¼������һ��ָ���ļ�����Ŀ¼����������Ҫ�ȶ�ȡĿ¼

    // �����ݣ���ȡ��Ŀ¼i�ڵ��Ӧ���豸�������е����ݿ飨�߼��飩��Ϣ����Щ�߼���Ŀ�

    // �ű�����i�ڵ�ṹ�� i_zone[9]�����С�������ȡ���е�1����š����Ŀ¼i�ڵ�ָ��

    // �ĵ�һ��ֱ�Ӵ��̿��Ϊ0����˵����Ŀ¼��Ȼ�������ݣ��ⲻ���������Ƿ���NULL�˳���

    // �������Ǿʹӽڵ������豸��ȡָ����Ŀ¼�����ݿ顣��Ȼ��������ɹ�����Ҳ����NULL

    // �˳������⣬��������ṩ���ļ������ȵ���0����Ҳ����NULL�˳���

184         if (!namelen)

185                 return NULL;

186         if (!(block = dir->i_zone[0]))

187                 return NULL;

188         if (!(bh = bread(dir->i_dev,block)))

189                 return NULL;

    // ��ʱ���Ǿ������Ŀ¼i�ڵ����ݿ���ѭ���������δʹ�õĿ�Ŀ¼�������Ŀ¼��ṹ

    // ָ��deָ�򻺳���е����ݿ鲿�֣�����һ��Ŀ¼�������i��Ŀ¼�е�Ŀ¼�������ţ�

    // ��ѭ����ʼʱ��ʼ��Ϊ0��

190         i = 0;

191         de = (struct dir_entry *) bh->b_data;

192         while (1) {

    // �����ǰĿ¼�����ݿ��Ѿ�������ϣ�����û���ҵ���Ҫ�Ŀ�Ŀ¼����ͷŵ�ǰĿ¼����

    // �ݿ飬�ٶ���Ŀ¼����һ���߼��顣�����Ӧ���߼��鲻���ھʹ���һ�顣����ȡ�򴴽���

    // ��ʧ���򷵻ؿա�����˴ζ�ȡ�Ĵ����߼������ݷ��صĻ����ָ��Ϊ�գ�˵������߼���

    // ��������Ϊ�����ڶ��´����Ŀտ飬���Ŀ¼������ֵ����һ���߼����������ɵ�Ŀ¼����

    // DIR_ENTRIES_PER_BLOCK�����������ÿ鲢��������������˵���¶���Ŀ�����Ŀ¼�����ݣ�

    // ������Ŀ¼��ṹָ��deָ��ÿ�Ļ�������ݲ��֣�Ȼ�������м�������������196��

    // �ϵ� i/DIR_ENTRIES_PER_BLOCK �ɼ���õ���ǰ������Ŀ¼��i ����Ŀ¼�ļ��еĿ�ţ�

    // ��create_block()������inode.c����147�У���ɶ�ȡ�򴴽������豸�϶�Ӧ���߼��顣

193                 if ((char *)de >= BLOCK_SIZE+bh->b_data) {

194                         brelse(bh);

195                         bh = NULL;

196                         block = create_block(dir,i/DIR_ENTRIES_PER_BLOCK);

197                         if (!block)

198                                 return NULL;

199                         if (!(bh = bread(dir->i_dev,block))) { // �����������ÿ������

200                                 i += DIR_ENTRIES_PER_BLOCK;

201                                 continue;

202                         }

203                         de = (struct dir_entry *) bh->b_data;

204                 }

    // �����ǰ��������Ŀ¼�����i����Ŀ¼�ṹ��С���ij���ֵ�Ѿ������˸�Ŀ¼i�ڵ���Ϣ

    // ��ָ����Ŀ¼���ݳ���ֵ i_size ����˵������Ŀ¼�ļ�������û������ɾ���ļ����µĿ�

    // Ŀ¼��������ֻ�ܰ���Ҫ���ӵ���Ŀ¼��ӵ�Ŀ¼�ļ����ݵ�ĩ�˴������ǶԸô�Ŀ

    // ¼��������ã��ø�Ŀ¼���i�ڵ�ָ��Ϊ�գ��������¸�Ŀ¼�ļ��ij���ֵ������һ��Ŀ

    // ¼��ij��ȣ���Ȼ������Ŀ¼��i�ڵ����޸ı�־���ٸ��¸�Ŀ¼�ĸı�ʱ��Ϊ��ǰʱ�䡣

205                 if (i*sizeof(struct dir_entry) >= dir->i_size) {

206                         de->inode=0;

207                         dir->i_size = (i+1)*sizeof(struct dir_entry);

208                         dir->i_dirt = 1;

209                         dir->i_ctime = CURRENT_TIME;

210                 }

    // ����ǰ������Ŀ¼�� de ��i�ڵ�Ϊ�գ����ʾ�ҵ�һ����δʹ�õĿ���Ŀ¼��������ӵ�

    // ��Ŀ¼����Ǹ���Ŀ¼���޸�ʱ��Ϊ��ǰʱ�䣬�����û������������ļ�������Ŀ¼���

    // �ļ����ֶΣ��ú��б�Ŀ¼�����Ӧ���ٻ�������޸ı�־�����ظ�Ŀ¼���ָ���Լ��ø�

    // �ٻ�����ָ�룬�˳���

211                 if (!de->inode) {

212                         dir->i_mtime = CURRENT_TIME;

213                         for (i=0; i < NAME_LEN ; i++)

214                                 de->name[i]=(i<namelen)?get_fs_byte(name+i):0;

215                         bh->b_dirt = 1;

216                         *res_dir = de;

217                         return bh;

218                 }

219                 de++;           // �����Ŀ¼���Ѿ���ʹ�ã�����������һ��Ŀ¼�

220                 i++;

221         }

    // ������ִ�в��������Ҳ����Linus��д��δ���ʱ���ȸ���������find_entry()����

    // �Ĵ��룬�����޸ijɱ�������J��

222         brelse(bh);

223         return NULL;

224 }

225

    //// ���ҷ������ӵ�i�ڵ㡣

    // ������dir - Ŀ¼i�ڵ㣻inode - Ŀ¼��i�ڵ㡣

    // ���أ����ط������ӵ��ļ���i�ڵ�ָ�롣��������NULL��

226 static struct m_inode * follow_link(struct m_inode * dir, struct m_inode * inode)

227 {

228         unsigned short fs;                       // ������ʱ����fs�μĴ���ֵ��

229         struct buffer_head * bh;

230

    // �����жϺ�����������Ч�ԡ����û�и���Ŀ¼i�ڵ㣬���Ǿ�ʹ�ý�������ṹ�����õ�

    // ��i�ڵ㣬������������1�����û�и���Ŀ¼��i�ڵ㣬��Ż�Ŀ¼i�ڵ�󷵻�NULL��

    // ���ָ��Ŀ¼���һ���������ӣ���ֱ�ӷ���Ŀ¼���Ӧ��i�ڵ�inode��

231         if (!dir) {

232                 dir = current->root;

233                 dir->i_count++;

234         }

235         if (!inode) {

236                 iput(dir);

237                 return NULL;

238         }

239         if (!S_ISLNK(inode->i_mode)) {

240                 iput(dir);

241                 return inode;

242         }

    // Ȼ��ȡfs�μĴ���ֵ��fsͨ��������ָ���������ݶε�ѡ���0x17�����fsû��ָ���û�

    // ���ݶΣ����߸�����Ŀ¼��i�ڵ��1��ֱ�ӿ��ŵ���0�������Ƕ�ȡ��1��ֱ�ӿ������

    // ��Ż�dir��inode����i�ڵ㲢����NULL�˳�������˵������fs��ָ���û����ݶΡ�����

    // �����Ѿ��ɹ��ض�ȡ�������������Ŀ¼����ļ����ݣ������ļ������Ѿ��� bh ָ��Ļ���

    // ���������С�ʵ���ϣ����������������н�����һ������ָ����ļ�·�����ַ�����

243         __asm__("mov %%fs,%0":"=r" (fs));

244         if (fs != 0x17 || !inode->i_zone[0] ||

245            !(bh = bread(inode->i_dev, inode->i_zone[0]))) {

246                 iput(dir);

247                 iput(inode);

248                 return NULL;

249         }

    // ��ʱ�����Ѿ�����Ҫ��������Ŀ¼���i�ڵ��ˣ����ǰ����Żء���������һ�����⣬�Ǿ�

    // ���ں˺����������û����ݶ��Ǵ�����û����ݿռ��еģ���ʹ���� fs �μĴ��������û�

    // �ռ䴫�����ݵ��ں˿ռ��С���������Ҫ����������ȴ���ں˿ռ��С����Ϊ����ȷ�ش���

    // λ���ں��е��û����ݣ�������Ҫ��fs�μĴ�����ʱָ���ں˿ռ䣬����fs =0x10������

    // ���ú�����������ٻָ�ԭfs��ֵ������ͷ���Ӧ����飬������ _namei()�����õ��ķ�

    // ������ָ����ļ�i�ڵ㡣

250         iput(inode);

251         __asm__("mov %0,%%fs"::"r" ((unsigned short) 0x10));

252         inode = _namei(bh->b_data,dir,0);

253         __asm__("mov %0,%%fs"::"r" (fs));

254         brelse(bh);

255         return inode;

256 }

257

258 /*

259  *      get_dir()

260  *

261  * Getdir traverses the pathname until it hits the topmost directory.

262  * It returns NULL on failure.

263  */

    /*

     *     get_dir()

     *

     * �ú������ݸ�����·��������������ֱ���ﵽ��˵�Ŀ¼��

     * ���ʧ���򷵻�NULL��

     */

    //// ��ָ��Ŀ¼��ʼ��Ѱָ��·������Ŀ¼�����ļ�������i�ڵ㡣

    // ������pathname - ·������inode - ָ����ʼĿ¼��i�ڵ㡣

    // ���أ�Ŀ¼���ļ���i�ڵ�ָ�롣ʧ��ʱ����NULL��

264 static struct m_inode * get_dir(const char * pathname, struct m_inode * inode)

265 {

266         char c;

267         const char * thisname;

268         struct buffer_head * bh;

269         int namelen,inr;

270         struct dir_entry * de;

271         struct m_inode * dir;

272

    // �����жϲ�����Ч�ԡ����������ָ��Ŀ¼��i�ڵ�ָ��inodeΪ�գ���ʹ�õ�ǰ���̵ĵ�

    // ǰ����Ŀ¼i�ڵ㡣����û�ָ��·�����ĵ�1���ַ���'/'����˵��·�����Ǿ���·������

    // ��Ӧ�ôӵ�ǰ��������ṹ�����õĸ�����α����i�ڵ㿪ʼ����������������Ҫ�ȷŻز�

    // ��ָ���Ļ����趨��Ŀ¼i�ڵ㣬��ȡ�ý���ʹ�õĸ�i�ڵ㡣Ȼ��Ѹ�i�ڵ�����ü���

    // ��1����ɾ��·�����ĵ�1���ַ� '/'�������Ϳ��Ա�֤��ǰ����ֻ�������趨�ĸ�i�ڵ�

    // ��Ϊ��������㡣

273         if (!inode) {

274                 inode = current->pwd;                // ���̵ĵ�ǰ����Ŀ¼i�ڵ㡣

275                 inode->i_count++;

276         }

277         if ((c=get_fs_byte(pathname))=='/') {

278                 iput(inode);                         // �Ż�ԭi�ڵ㡣

279                 inode = current->root;               // Ϊ����ָ���ĸ�i�ڵ㡣

280                 pathname++;

281                 inode->i_count++;

282         }

    // Ȼ�����·�����еĸ���Ŀ¼�����ֺ��ļ�������ѭ����������ѭ�����������У�������Ҫ

    // �Ե�ǰ���ڴ�����Ŀ¼�����ֵ� i�ڵ������Ч���жϣ����Ұѱ���thisname ָ��ǰ��

    // �ڴ�����Ŀ¼�����֡������i�ڵ������ǰ������Ŀ¼�����ֲ���Ŀ¼���ͣ�����û�п�

    // �����Ŀ¼�ķ������ɣ���Żظ�i�ڵ㣬������NULL�˳��� ��Ȼ�ڸս���ѭ��ʱ����ǰ

    // Ŀ¼��i�ڵ�inode���ǽ��̸�i�ڵ�����ǵ�ǰ����Ŀ¼��i�ڵ㣬�����Dz���ָ����ij

    // ��������ʼĿ¼��i�ڵ㡣

283         while (1) {

284                 thisname = pathname;

285                 if (!S_ISDIR(inode->i_mode) || !permission(inode,MAY_EXEC)) {

286                         iput(inode);

287                         return NULL;

288                 }

    // ÿ��ѭ�����Ǵ���·������һ��Ŀ¼�������ļ��������֡������ÿ��ѭ�������Ƕ�Ҫ��·

    // �����ַ����з����һ��Ŀ¼�������ļ������������Ǵӵ�ǰ·����ָ�� pathname ��ʼ��

    // ��������ַ���ֱ���ַ���һ����β����NULL��������һ��'/'�ַ�����ʱ���� namelen ��

    // ���ǵ�ǰ����Ŀ¼�����ֵij��ȣ������� thisname ��ָ���Ŀ¼�����ֵĿ�ʼ������ʱ��

    // ���ַ��ǽ�β��NULL��������Ѿ�������·����ĩβ�����ѵ������ָ��Ŀ¼�����ļ�����

    // �򷵻ظ�i�ڵ�ָ���˳���

    // ע�⣡���·���������һ������Ҳ��һ��Ŀ¼�����������û�м��� '/'�ַ���������

    // �᷵�ظ����Ŀ¼����i�ڵ㣡���磺����·����/usr/src/linux���ú�����ֻ����src/Ŀ

    // ¼����i�ڵ㡣

289                 for(namelen=0;(c=get_fs_byte(pathname++))&&(c!='/');namelen++)

290                         /* nothing */ ;

291                 if (!c)

292                         return inode;

    // �ڵõ���ǰĿ¼�����֣����ļ����������ǵ��ò���Ŀ¼���find_entry()�ڵ�ǰ��

    // ����Ŀ¼��Ѱ��ָ�����Ƶ�Ŀ¼����û���ҵ�����Żظ�i�ڵ㣬������NULL�˳���

    // Ȼ�����ҵ���Ŀ¼����ȡ����i�ڵ��inr���豸��idev���ͷŰ�����Ŀ¼��ĸ��ٻ���

    // �鲢�Żظ�i�ڵ㡣 Ȼ��ȡ�ڵ��inr��i�ڵ�inode�����Ը�Ŀ¼��Ϊ��ǰĿ¼����ѭ

    // ������·�����е���һĿ¼�����֣����ļ������������ǰ������Ŀ¼����һ����������

    // ������ʹ��follow_link()�Ϳ��Եõ���ָ���Ŀ¼������i�ڵ㡣

293                 if (!(bh = find_entry(&inode,thisname,namelen,&de))) {

294                         iput(inode);

295                         return NULL;

296                 }

297                 inr = de->inode;                    // ��ǰĿ¼�����ֵ�i�ڵ�š�

298                 brelse(bh);

299                 dir = inode;

300                 if (!(inode = iget(dir->i_dev,inr))) {      // ȡi�ڵ����ݡ�

301                         iput(dir);

302                         return NULL;

303                 }

304                 if (!(inode = follow_link(dir,inode)))

305                         return NULL;

306         }

307 }

308

309 /*

310  *      dir_namei()

311  *

312  * dir_namei() returns the inode of the directory of the

313  * specified name, and the name within that directory.

314  */

    /*

     *     dir_namei()

     *

     * dir_namei()��������ָ��Ŀ¼����i�ڵ�ָ�룬�Լ������

     * Ŀ¼�����ơ�

     */

    // ������pathname - Ŀ¼·������namelen - ·�������ȣ�name - ���ص����Ŀ¼����

    // base - ������ʼĿ¼��i�ڵ㡣

    // ���أ�ָ��Ŀ¼�����Ŀ¼��i�ڵ�ָ������Ŀ¼���Ƽ����ȡ�����ʱ����NULL��

    // ע�⣡��������Ŀ¼����ָ·���������ĩ�˵�Ŀ¼��

315 static struct m_inode * dir_namei(const char * pathname,

316         int * namelen, const char ** name, struct m_inode * base)

317 {

318         char c;

319         const char * basename;

320         struct m_inode * dir;

321

    // ����ȡ��ָ��·�������Ŀ¼��i�ڵ㡣Ȼ���·����pathname����������⣬������

    // һ��'/'�ַ�����������ַ����������䳤�ȣ����ҷ������Ŀ¼��i�ڵ�ָ�롣ע�⣡��

    // ��·�������һ���ַ���б���ַ�'/'����ô���ص�Ŀ¼��Ϊ�գ����ҳ���Ϊ0�������ص�i

    // �ڵ�ָ����Ȼָ�����һ��'/'�ַ�ǰĿ¼����i�ڵ㡣�μ���289���ϵġ�ע�⡱˵����

322         if (!(dir = get_dir(pathname,base)))      // base��ָ������ʼĿ¼i�ڵ㡣

323                 return NULL;

324         basename = pathname;

325         while (c=get_fs_byte(pathname++))

326                 if (c=='/')

327                         basename=pathname;

328         *namelen = pathname-basename-1;

329         *name = basename;

330         return dir;

331 }

332

    //// ȡָ��·������i�ڵ��ڲ�������

    // ������pathname - ·������base - �������Ŀ¼i�ڵ㣻follow_links - �Ƿ����

    // �������ӵı�־��1 - ��Ҫ��0����Ҫ��

    // ���أ���Ӧ��i�ڵ㡣

333 struct m_inode * _namei(const char * pathname, struct m_inode * base,

334         int follow_links)

335 {

336         const char * basename;

337         int inr,namelen;

338         struct m_inode * inode;

339         struct buffer_head * bh;

340         struct dir_entry * de;

341

    // ���Ȳ���ָ��·���������Ŀ¼��Ŀ¼�����õ���i�ڵ㡣�������ڣ��򷵻�NULL�˳���

    // ������ص�������ֵij�����0�����ʾ��·������һ��Ŀ¼��Ϊ���һ����˵����

    // ���Ѿ��ҵ���ӦĿ¼��i�ڵ㣬����ֱ�ӷ��ظ�i�ڵ��˳���������ص����ֳ��Ȳ���0��

    // ��������ָ������ʼĿ¼base���ٴε���dir_namei()��������������Ŀ¼���������ݷ���

    // ����Ϣ�������жϡ�

311         if (!(dir = dir_namei(pathname,&namelen,&basename)))

312                 return NULL;

313         if (!namelen)                   /* special case: '/usr/' etc */

314                 return dir;             /* ��Ӧ��'/usr/'����� */

342         if (!(base = dir_namei(pathname,&namelen,&basename,base)))

343                 return NULL;

344         if (!namelen)                   /* special case: '/usr/' etc */

345                 return base;

    // Ȼ���ڷ��صĶ���Ŀ¼��Ѱ��ָ���ļ���Ŀ¼���i�ڵ㡣ע�⣡��Ϊ������Ҳ��һ��Ŀ

    // ¼���������û�м�'/'���򲻻᷵�ظ����Ŀ¼��i�ڵ㣡 ���磺/usr/src/linux����ֻ

    // ���� src/Ŀ¼����i�ڵ㡣��Ϊ����dir_namei() ������'/'���������һ�����ֵ���һ��

    // �ļ��������������������Ҫ�������������ʹ��Ѱ��Ŀ¼��i�ڵ㺯��find_entry()����

    // ��������ʱde�к���Ѱ�ҵ���Ŀ¼��ָ�룬��dir�ǰ�����Ŀ¼���Ŀ¼��i�ڵ�ָ�롣

346         bh = find_entry(&base,basename,namelen,&de);

347         if (!bh) {

348                 iput(base);

349                 return NULL;

350         }

    // ����ȡ��Ŀ¼���i�ڵ�ţ����ͷŰ�����Ŀ¼��ĸ��ٻ���鲢�Ż�Ŀ¼i�ڵ㡣Ȼ��ȡ

    // ��Ӧ�ڵ�ŵ�i�ڵ㣬�޸��䱻����ʱ��Ϊ��ǰʱ�䣬�������޸ı�־����󷵻ظ�i�ڵ�

    // ָ��inode�������ǰ������Ŀ¼����һ����������������ʹ��follow_link()�õ���ָ���

    // Ŀ¼������i�ڵ㡣

351         inr = de->inode;

352         brelse(bh);

353         if (!(inode = iget(base->i_dev,inr))) {

354                 iput(base);

355                 return NULL;

356         }

357         if (follow_links)

358                 inode = follow_link(base,inode);

359         else

360                 iput(base);

361         inode->i_atime=CURRENT_TIME;

362         inode->i_dirt=1;

363         return inode;

364 }

365

    //// ȡָ��·������i�ڵ㣬������������ӡ�

    // ������pathname - ·������

    // ���أ���Ӧ��i�ڵ㡣

366 struct m_inode * lnamei(const char * pathname)

367 {

368         return _namei(pathname, NULL, 0);

369 }

370

371 /*

372  *      namei()

373  *

374  * is used by most simple commands to get the inode of a specified name.

375  * Open, link etc use their own routines, but this is enough for things

376  * like 'chmod' etc.

377  */

    /*

     *     namei()

     *

     * �ú������������������ȡ��ָ��·�����Ƶ�i�ڵ㡣open��link����ʹ������

     * �Լ�����Ӧ���������������޸�ģʽ'chmod'������������ú������㹻���ˡ�

     */

    //// ȡָ��·������i�ڵ㣬����������ӡ�

    // ������pathname - ·������

    // ���أ���Ӧ��i�ڵ㡣

378 struct m_inode * namei(const char * pathname)

379 {

380         return _namei(pathname,NULL,1);

381 }

382

383 /*

384  *      open_namei()

385  *

386  * namei for open - this is in fact almost the whole open-routine.

387  */

    /*

     *     open_namei()

     *

     * open()����ʹ�õ�namei���� - ����ʵ�����������Ĵ��ļ�����

     */

    //// �ļ���namei������

    // ����filename���ļ�·������flag�Ǵ��ļ���־����ȡֵO_RDONLY��ֻ������O_WRONLY

    // ��ֻд����O_RDWR����д�����Լ�O_CREAT����������O_EXCL���������ļ����벻���ڣ���

    // O_APPEND�����ļ�β�������ݣ�������һЩ��־����ϡ���������ô�����һ�����ļ�����

    // mode������ָ���ļ����������ԡ���Щ������S_IRWXU���ļ��������ж���д��ִ��Ȩ�ޣ���

    // S_IRUSR���û����ж��ļ�Ȩ�ޣ���S_IRWXG�����Ա���ж���д��ִ��Ȩ�ޣ��ȵȡ�������

    // �������ļ�����Щ����ֻӦ���ڽ������ļ��ķ��ʣ�������ֻ���ļ��Ĵ򿪵���Ҳ������һ

    // ���ɶ�д���ļ�������μ������ļ�sys/stat.h��fcntl.h��

    // ���أ��ɹ�����0�����򷵻س����룻res_inode - ���ض�Ӧ�ļ�·������i�ڵ�ָ�롣

388 int open_namei(const char * pathname, int flag, int mode,

389         struct m_inode ** res_inode)

390 {

391         const char * basename;

392         int inr,dev,namelen;

393         struct m_inode * dir, *inode;

394         struct buffer_head * bh;

395         struct dir_entry * de;

396

    // ���ȶԺ����������к����Ĵ���������ļ�����ģʽ��־��ֻ����0���������ļ������־

    // O_TRUNCȴ��λ�ˣ������ļ��򿪱�־������ֻд��־O_WRONLY����������ԭ�������ڽ���

    // ��־O_TRUNC�������ļ���д����²���Ч��Ȼ��ʹ�õ�ǰ���̵��ļ��������������룬��

    // �ε�����ģʽ�е���Ӧλ����������ͨ�ļ���־I_REGULAR���ñ�־�����ڴ򿪵��ļ�����

    // �ڶ���Ҫ�����ļ�ʱ����Ϊ���ļ���Ĭ�����ԡ��μ�����411���ϵ�ע�͡�

397         if ((flag & O_TRUNC) && !(flag & O_ACCMODE))

398                 flag |= O_WRONLY;

399         mode &= 0777 & ~current->umask;

400         mode |= I_REGULAR;              // �����ļ���־�����μ�include/const.h�ļ�����

    // Ȼ�����ָ����·����Ѱ�ҵ���Ӧ��i�ڵ㣬�Լ����Ŀ¼�����䳤�ȡ���ʱ������

    // Ŀ¼������Ϊ0�� ����'/usr/' ����·���������������ô���������Ƕ�д���������ļ���

    // �Ƚ�0�����ʾ���ڴ�һ��Ŀ¼���ļ�����������ֱ�ӷ��ظ�Ŀ¼��i�ڵ㲢����0�˳���

    // ����˵�����̲����Ƿ������ǷŻظ�i�ڵ㣬���س����롣

401         if (!(dir = dir_namei(pathname,&namelen,&basename,NULL)))

402                 return -ENOENT;

403         if (!namelen) {                 /* special case: '/usr/' etc */

404                 if (!(flag & (O_ACCMODE|O_CREAT|O_TRUNC))) {

405                         *res_inode=dir;

406                         return 0;

407                 }

408                 iput(dir);

409                 return -EISDIR;

410         }

    // ���Ÿ�������õ������Ŀ¼����i�ڵ�dir�������в���ȡ��·�����ַ�����������

    // ������Ӧ��Ŀ¼��ṹde����ͬʱ�õ���Ŀ¼�����ڵĸ��ٻ�����ָ�롣 ����ø��ٻ���

    // ָ��ΪNULL�����ʾû���ҵ���Ӧ�ļ�����Ŀ¼����ֻ�����Ǵ����ļ������� ��ʱ��

    // �����Ǵ����ļ�����Żظ�Ŀ¼��i�ڵ㣬���س������˳�������û��ڸ�Ŀ¼û��д��Ȩ

    // ������Żظ�Ŀ¼��i�ڵ㣬���س������˳���

411         bh = find_entry(&dir,basename,namelen,&de);

412         if (!bh) {

413                 if (!(flag & O_CREAT)) {

414                         iput(dir);

415                         return -ENOENT;

416                 }

417                 if (!permission(dir,MAY_WRITE)) {

418                         iput(dir);

419                         return -EACCES;

420                 }

    // ��������ȷ�����Ǵ�������������д�������ɡ� ������Ǿ���Ŀ¼i�ڵ��Ӧ�豸������

    // һ���µ�i�ڵ��·������ָ�����ļ�ʹ�á� ��ʧ����Ż�Ŀ¼��i�ڵ㣬������û�п�

    // ������롣����ʹ�ø��� i�ڵ㣬������г�ʼ���ã��ýڵ���û�id����Ӧ�ڵ����ģ

    // ʽ�������޸ı�־��Ȼ����ָ��Ŀ¼dir������һ����Ŀ¼�

421                 inode = new_inode(dir->i_dev);

422                 if (!inode) {

423                         iput(dir);

424                         return -ENOSPC;

425                 }

426                 inode->i_uid = current->euid;

427                 inode->i_mode = mode;

428                 inode->i_dirt = 1;

429                 bh = add_entry(dir,basename,namelen,&de);

    // ������ص�Ӧ�ú�����Ŀ¼��ĸ��ٻ�����ָ��ΪNULL�����ʾ����Ŀ¼�����ʧ�ܡ�����

    // ������i�ڵ���������Ӽ�����1���Żظ�i�ڵ���Ŀ¼��i�ڵ㲢���س������˳��� ����

    // ˵������Ŀ¼������ɹ��� �������������ø���Ŀ¼���һЩ��ʼֵ����i�ڵ��Ϊ������

    // ����i�ڵ�ĺ��룻���ø��ٻ��������޸ı�־�� Ȼ���ͷŸø��ٻ��������Ż�Ŀ¼��i��

    // �㡣������Ŀ¼���i�ڵ�ָ�룬���ɹ��˳���

430                 if (!bh) {

431                         inode->i_nlinks--;

432                         iput(inode);

433                         iput(dir);

434                         return -ENOSPC;

435                 }

436                 de->inode = inode->i_num;

437                 bh->b_dirt = 1;

438                 brelse(bh);

439                 iput(dir);

440                 *res_inode = inode;

441                 return 0;

442         }

    // �����棨411�У���Ŀ¼��ȡ�ļ�����ӦĿ¼��ṹ�IJ����ɹ�����bh��ΪNULL������˵

    // ��ָ���򿪵��ļ��Ѿ����ڡ�����ȡ����Ŀ¼���i�ڵ�ź��������豸�ţ����ͷŸø���

    // �������Լ��Ż�Ŀ¼��i�ڵ㡣�����ʱ��ռ������־O_EXCL��λ���������ļ��Ѿ����ڣ�

    // �򷵻��ļ��Ѵ��ڳ������˳���

443         inr = de->inode;

444         dev = dir->i_dev;

445         brelse(bh);

446         if (flag & O_EXCL) {

447                 iput(dir);

448                 return -EEXIST;

449         }

    // Ȼ�����Ƕ�ȡ��Ŀ¼���i�ڵ����ݡ�����i�ڵ���һ��Ŀ¼��i�ڵ㲢�ҷ���ģʽ��ֻ

    // д���д������û�з��ʵ�����Ȩ�ޣ���Żظ�i�ڵ㣬���ط���Ȩ�޳������˳���

450         if (!(inode = follow_link(dir,iget(dev,inr))))

451                 return -EACCES;

452         if ((S_ISDIR(inode->i_mode) && (flag & O_ACCMODE)) ||

453             !permission(inode,ACC_MODE(flag))) {

454                 iput(inode);

455                 return -EPERM;

456         }

    // �������Ǹ��¸�i�ڵ�ķ���ʱ���ֶ�ֵΪ��ǰʱ�䡣��������˽�0��־���򽫸�i��

    // ����ļ����Ƚ�Ϊ0����󷵻ظ�Ŀ¼��i�ڵ��ָ�룬������0���ɹ�����

457         inode->i_atime = CURRENT_TIME;

458         if (flag & O_TRUNC)

459                 truncate(inode);

460         *res_inode = inode;

461         return 0;

462 }

463

    //// ����һ���豸�����ļ�����ͨ�ļ��ڵ㣨node����

    // �ú�����������Ϊfilename����mode��devָ�����ļ�ϵͳ�ڵ㣨��ͨ�ļ����豸������

    // ���������ܵ�����

    // ������filename - ·������mode - ָ��ʹ�������Լ��������ڵ�����ͣ�dev - �豸�š�

    // ���أ��ɹ��򷵻�0�����򷵻س����롣

464 int sys_mknod(const char * filename, int mode, int dev)

465 {

466         const char * basename;

467         int namelen;

468         struct m_inode * dir, * inode;

469         struct buffer_head * bh;

470         struct dir_entry * de;

471        

    // ���ȼ��������ɺͲ�������Ч�Բ�ȡ·�����ж���Ŀ¼��i�ڵ㡣������dz����û�����

    // ���ط������ɳ����롣����Ҳ�����Ӧ·�����ж���Ŀ¼��i�ڵ㣬�򷵻س����롣�����

    // ���˵��ļ�������Ϊ0����˵��������·�������û��ָ���ļ������Żظ�Ŀ¼i�ڵ㣬��

    // �س������˳�������ڸ�Ŀ¼��û��д��Ȩ�ޣ���Żظ�Ŀ¼��i�ڵ㣬���ط������ɳ���

    // ���˳���������dz����û����򷵻ط������ɳ����롣

472         if (!suser())

473                 return -EPERM;

474         if (!(dir = dir_namei(filename,&namelen,&basename, NULL)))

475                 return -ENOENT;

476         if (!namelen) {

477                 iput(dir);

478                 return -ENOENT;

479         }

480         if (!permission(dir,MAY_WRITE)) {

481                 iput(dir);

482                 return -EPERM;

483         }

    // Ȼ����������һ��·����ָ�����ļ��Ƿ��Ѿ����ڡ����Ѿ��������ܴ���ͬ���ļ��ڵ㡣

    // �����Ӧ·�����������ļ�����Ŀ¼���Ѿ����ڣ����ͷŰ�����Ŀ¼��Ļ������鲢�Ż�

    // Ŀ¼��i�ڵ㣬�����ļ��Ѿ����ڵij������˳���

484         bh = find_entry(&dir,basename,namelen,&de);

485         if (bh) {

486                 brelse(bh);

487                 iput(dir);

488                 return -EEXIST;

489         }

    // �������Ǿ�����һ���µ�i�ڵ㣬�����ø�i�ڵ������ģʽ�����Ҫ�������ǿ��豸�ļ�

    // �������ַ��豸�ļ�������i�ڵ��ֱ���߼���ָ��0�����豸�š��������豸�ļ���˵��

    // ��i�ڵ��i_zone[0]�д�ŵ��Ǹ��豸�ļ��������豸���豸�š�Ȼ�����ø�i�ڵ����

    // ��ʱ�䡢����ʱ��Ϊ��ǰʱ�䣬������i�ڵ����޸ı�־��

490         inode = new_inode(dir->i_dev);

491         if (!inode) {           // �����ɹ���Ż�Ŀ¼i�ڵ㣬�����޿ռ�������˳���

492                 iput(dir);

493                 return -ENOSPC;

494         }

495         inode->i_mode = mode;

496         if (S_ISBLK(mode) || S_ISCHR(mode))

497                 inode->i_zone[0] = dev;

498         inode->i_mtime = inode->i_atime = CURRENT_TIME;

499         inode->i_dirt = 1;

    // ����Ϊ����µ�i�ڵ���Ŀ¼��������һ��Ŀ¼����ʧ�ܣ�������Ŀ¼��ĸ��ٻ���

    // ��ָ��ΪNULL������Ż�Ŀ¼��i�ڵ㣻���������i�ڵ��������Ӽ�����λ�����Żظ�

    // i�ڵ㣬���س������˳���

500         bh = add_entry(dir,basename,namelen,&de);

501         if (!bh) {

502                 iput(dir);

503                 inode->i_nlinks=0;

504                 iput(inode);

505                 return -ENOSPC;

506         }

    // ��������Ŀ¼�����Ҳ�ɹ��ˣ������������������Ŀ¼�����ݡ����Ŀ¼���i�ڵ���

    // �ε�����i�ڵ�ţ����ø��ٻ��������޸ı�־���Ż�Ŀ¼���µ�i�ڵ㣬�ͷŸ��ٻ���

    // ������󷵻�0(�ɹ�)��

507         de->inode = inode->i_num;

508         bh->b_dirt = 1;

509         iput(dir);

510         iput(inode);

511         brelse(bh);

512         return 0;

513 }

514

    ////  ����һ��Ŀ¼��

    // ������pathname - ·������mode - Ŀ¼ʹ�õ�Ȩ�����ԡ�

    // ���أ��ɹ��򷵻�0�����򷵻س����롣

515 int sys_mkdir(const char * pathname, int mode)

516 {

517         const char * basename;

518         int namelen;

519         struct m_inode * dir, * inode;

520         struct buffer_head * bh, *dir_block;

521         struct dir_entry * de;

522

    // ���ȼ���������Ч�Բ�ȡ·�����ж���Ŀ¼��i�ڵ㡣����Ҳ�����Ӧ·�����ж���Ŀ¼

    // ��i�ڵ㣬�򷵻س����롣�����˵��ļ�������Ϊ0����˵��������·�������û��ָ

    // ���ļ������Żظ�Ŀ¼i�ڵ㣬���س������˳�������ڸ�Ŀ¼��û��д��Ȩ�ޣ���Żظ�

    // Ŀ¼��i�ڵ㣬���ط������ɳ������˳���������dz����û����򷵻ط������ɳ����롣

523         if (!(dir = dir_namei(pathname,&namelen,&basename, NULL)))

524                 return -ENOENT;

525         if (!namelen) {

526                 iput(dir);

527                 return -ENOENT;

528         }

529         if (!permission(dir,MAY_WRITE)) {

530                 iput(dir);

531                 return -EPERM;

532         }

    // Ȼ����������һ��·����ָ����Ŀ¼���Ƿ��Ѿ����ڡ����Ѿ��������ܴ���ͬ��Ŀ¼�ڵ㡣

    // �����Ӧ·����������Ŀ¼����Ŀ¼���Ѿ����ڣ����ͷŰ�����Ŀ¼��Ļ������鲢�Ż�

    // Ŀ¼��i�ڵ㣬�����ļ��Ѿ����ڵij������˳����������Ǿ�����һ���µ�i�ڵ㣬������

    // ��i�ڵ������ģʽ���ø���i�ڵ��Ӧ���ļ�����Ϊ32�ֽ� ��2��Ŀ¼��Ĵ�С������

    // �ڵ����޸ı�־���Լ��ڵ���޸�ʱ��ͷ���ʱ�䡣2��Ŀ¼��ֱ�����'.'��'..'Ŀ¼��

533         bh = find_entry(&dir,basename,namelen,&de);

534         if (bh) {

535                 brelse(bh);

536                 iput(dir);

537                 return -EEXIST;

538         }

539         inode = new_inode(dir->i_dev);

540         if (!inode) {               // �����ɹ���Ż�Ŀ¼��i�ڵ㣬�����޿ռ�����롣

541                 iput(dir);

542                 return -ENOSPC;

543         }

544         inode->i_size = 32;

545         inode->i_dirt = 1;

546         inode->i_mtime = inode->i_atime = CURRENT_TIME;

    // ����Ϊ����i�ڵ�����һ���ڱ���Ŀ¼�����ݵĴ��̿飬����i�ڵ�ĵ�һ��ֱ�ӿ�ָ���

    // �ڸÿ�š��������ʧ����Żض�ӦĿ¼��i�ڵ㣻��λ�������i�ڵ����Ӽ������Żظ�

    // �µ�i�ڵ㣬����û�пռ�������˳��������ø��µ�i�ڵ����޸ı�־��

547         if (!(inode->i_zone[0]=new_block(inode->i_dev))) {

548                 iput(dir);

549                 inode->i_nlinks--;

550                 iput(inode);

551                 return -ENOSPC;

552         }

553         inode->i_dirt = 1;

    // ���豸�϶�ȡ������Ĵ��̿飨Ŀ���ǰѶ�Ӧ��ŵ����ٻ������У�������������Żض�Ӧ

    // Ŀ¼��i�ڵ㣻�ͷ�����Ĵ��̿飻��λ�������i�ڵ����Ӽ������Żظ��µ�i�ڵ㣬��

    // ��û�пռ�������˳���

554         if (!(dir_block=bread(inode->i_dev,inode->i_zone[0]))) {

555                 iput(dir);

556                 inode->i_nlinks--;

557                 iput(inode);

558                 return -ERROR;

559         }

    // Ȼ�������ڻ�����н�����������Ŀ¼�ļ��е�2��Ĭ�ϵ���Ŀ¼�'.'��'..'���ṹ��

    // �ݡ�������deָ����Ŀ¼������ݿ飬Ȼ���ø�Ŀ¼���i�ڵ���ֶε����������i

    // �ڵ�ţ������ֶε���"."�� Ȼ��deָ����һ��Ŀ¼��ṹ�����ڸýṹ�д���ϼ�Ŀ¼

    // �� i�ڵ�ź�����".."��Ȼ�����øø��ٻ�������޸ı�־�����ͷŸû���顣�ٳ�ʼ��

    // ������i�ڵ��ģʽ�ֶΣ����ø�i�ڵ����޸ı�־��

560         de = (struct dir_entry *) dir_block->b_data;

561         de->inode=inode->i_num;                     // ����'.'Ŀ¼�

562         strcpy(de->name,".");

563         de++;

564         de->inode = dir->i_num;                     // ����'..'Ŀ¼�

565         strcpy(de->name,"..");

566         inode->i_nlinks = 2;

567         dir_block->b_dirt = 1;

568         brelse(dir_block);

569         inode->i_mode = I_DIRECTORY | (mode & 0777 & ~current->umask);

570         inode->i_dirt = 1;

    // ����������ָ��Ŀ¼��������һ��Ŀ¼����ڴ���½�Ŀ¼��i�ڵ��Ŀ¼�������ʧ

    // �ܣ�������Ŀ¼��ĸ��ٻ�����ָ��ΪNULL������Ż�Ŀ¼��i�ڵ㣻�������i�ڵ���

    // �����Ӽ�����λ�����Żظ�i�ڵ㡣���س������˳���

571         bh = add_entry(dir,basename,namelen,&de);

572         if (!bh) {

573                 iput(dir);

574                 inode->i_nlinks=0;

575                 iput(inode);

576                 return -ENOSPC;

577         }

    // ��������Ŀ¼���i�ڵ��ֶε�����i�ڵ�ţ����ø��ٻ�������޸ı�־���Ż�Ŀ¼

    // ���µ�i�ڵ㣬�ͷŸ��ٻ���������󷵻�0���ɹ�����

578         de->inode = inode->i_num;

579         bh->b_dirt = 1;

580         dir->i_nlinks++;

581         dir->i_dirt = 1;

582         iput(dir);

583         iput(inode);

584         brelse(bh);

585         return 0;

586 }

587

588 /*

589  * routine to check that the specified directory is empty (for rmdir)

590  */

    /*

     * ���ڼ��ָ����Ŀ¼�Ƿ�Ϊ�յ��ӳ�������rmdirϵͳ���ã���

     */

    //// ���ָ��Ŀ¼�Ƿ�ա�

    // ������inode - ָ��Ŀ¼��i�ڵ�ָ�롣

    // ���أ�1 �C Ŀ¼���ǿյģ�0 - ���ա�

591 static int empty_dir(struct m_inode * inode)

592 {

593         int nr,block;

594         int len;

595         struct buffer_head * bh;

596         struct dir_entry * de;

597

    // ���ȼ���ָ��Ŀ¼������Ŀ¼���������鿪ʼ�����ض�Ŀ¼������Ϣ�Ƿ���ȷ��һ��Ŀ¼

    // ��Ӧ��������2��Ŀ¼���"."��".."�� ���Ŀ¼���������2�����߸�Ŀ¼i�ڵ�ĵ�

    // 1��ֱ�ӿ�û��ָ���κδ��̿�ţ����߸�ֱ�ӿ������������ʾ������Ϣ���豸dev ��Ŀ

    // ¼����������0(ʧ��)��

598         len = inode->i_size / sizeof (struct dir_entry);      // Ŀ¼��Ŀ¼�������

599         if (len<2 || !inode->i_zone[0] ||

600             !(bh=bread(inode->i_dev,inode->i_zone[0]))) {

601                 printk("warning - bad directory on dev %04x\n",inode->i_dev);

602                 return 0;

603         }

    // ��ʱbh��ָ������к���Ŀ¼�����ݡ�������Ŀ¼��ָ��deָ�򻺳���е�1��Ŀ¼�

    // ���ڵ�1��Ŀ¼�"."��������i�ڵ���ֶ�inodeӦ�õ��ڵ�ǰĿ¼��i�ڵ�š�����

    // ��2��Ŀ¼�".."��������i�ڵ���ֶ� inode Ӧ�õ�����һ��Ŀ¼��i�ڵ�ţ�����

    // Ϊ0����������1��Ŀ¼���i�ڵ���ֶ�ֵ�����ڸ�Ŀ¼��i�ڵ�ţ����ߵ�2��Ŀ¼

    // ���i�ڵ���ֶ�Ϊ�㣬��������Ŀ¼��������ֶβ��ֱ����"."��".."������ʾ������

    // ����Ϣ���豸dev��Ŀ¼������������0��

604         de = (struct dir_entry *) bh->b_data;

605         if (de[0].inode != inode->i_num || !de[1].inode ||

606             strcmp(".",de[0].name) || strcmp("..",de[1].name)) {

607                 printk("warning - bad directory on dev %04x\n",inode->i_dev);

608                 return 0;

609         }

    // Ȼ��������nr����Ŀ¼����ţ���0��ʼ�ƣ���deָ�������Ŀ¼���ѭ������Ŀ¼

    // ���������еģ�len - 2����Ŀ¼�����û��Ŀ¼���i�ڵ���ֶβ�Ϊ0����ʹ�ã���

610         nr = 2;

611         de += 2;

612         while (nr<len) {

    // ����ÿ���̿��е�Ŀ¼���Ѿ�ȫ�������ϣ����ͷŸô��̿�Ļ���飬����ȡĿ¼����

    // �ļ�����һ�麬��Ŀ¼��Ĵ��̿顣��ȡ�ķ����Ǹ��ݵ�ǰ����Ŀ¼����� nr �������

    // ӦĿ¼����Ŀ¼�����ļ��е����ݿ�ţ�nr/DIR_ENTRIES_PER_BLOCK����Ȼ��ʹ�� bmap()

    // ����ȡ�ö�Ӧ���̿�� block����ʹ�ö��豸�̿麯��bread() ����Ӧ�̿���뻺����У�

    // �����ظû�����ָ�롣������ȡ����Ӧ�̿�û��ʹ�ã����Ѿ����ã����ļ��Ѿ�ɾ���ȣ���

    // ���������һ�飬�������������������0��������deָ���������׸�Ŀ¼�

613                 if ((void *) de >= (void *) (bh->b_data+BLOCK_SIZE)) {

614                         brelse(bh);

615                         block=bmap(inode,nr/DIR_ENTRIES_PER_BLOCK);

616                         if (!block) {

617                                 nr += DIR_ENTRIES_PER_BLOCK;

618                                 continue;

619                         }

620                         if (!(bh=bread(inode->i_dev,block)))

621                                 return 0;

622                         de = (struct dir_entry *) bh->b_data;

623                 }

    // ����deָ��ĵ�ǰĿ¼������Ŀ¼���i�ڵ���ֶβ�����0�����ʾ��Ŀ¼��Ŀǰ��

    // ��ʹ�ã����ͷŸø��ٻ�����������0�˳�����������û�в�ѯ���Ŀ¼�е�����Ŀ¼�

    // ���Ŀ¼�����nr��1��deָ����һ��Ŀ¼�������⡣

624                 if (de->inode) {

625                         brelse(bh);

626                         return 0;

627                 }

628                 de++;

629                 nr++;

630         }

    // ִ�е�����˵����Ŀ¼��û���ҵ����õ�Ŀ¼��(��Ȼ����ͷ��������)�����ͷŻ���鷵��1��

631         brelse(bh);

632         return 1;

633 }

634

    //// ɾ��Ŀ¼��

    // ������ name - Ŀ¼����·��������

    // ���أ�����0��ʾ�ɹ������򷵻س����š�

635 int sys_rmdir(const char * name)

636 {

637         const char * basename;

638         int namelen;

639         struct m_inode * dir, * inode;

640         struct buffer_head * bh;

641         struct dir_entry * de;

642

    // ���ȼ���������Ч�Բ�ȡ·�����ж���Ŀ¼��i�ڵ㡣����Ҳ�����Ӧ·�����ж���Ŀ¼

    // ��i�ڵ㣬�򷵻س����롣�����˵��ļ�������Ϊ0����˵��������·�������û��ָ

    // ���ļ������Żظ�Ŀ¼i�ڵ㣬���س������˳�������ڸ�Ŀ¼��û��д��Ȩ�ޣ���Żظ�

    // Ŀ¼��i�ڵ㣬���ط������ɳ������˳���������dz����û����򷵻ط������ɳ����롣

643         if (!(dir = dir_namei(name,&namelen,&basename, NULL)))

644                 return -ENOENT;

645         if (!namelen) {

646                 iput(dir);

647                 return -ENOENT;

648         }

649         if (!permission(dir,MAY_WRITE)) {

650                 iput(dir);

651                 return -EPERM;

652         }

    // Ȼ�����ָ��Ŀ¼��i�ڵ��Ŀ¼�����ú���find_entry()Ѱ�Ҷ�ӦĿ¼������ذ�����

    // Ŀ¼��Ļ����ָ��bh��������Ŀ¼���Ŀ¼��i�ڵ�ָ��dir�͸�Ŀ¼��ָ��de���ٸ���

    // ��Ŀ¼��de �е�i�ڵ������ iget()�����õ���Ӧ��i�ڵ� inode�������Ӧ·��������

    // ��Ŀ¼����Ŀ¼����ڣ����ͷŰ�����Ŀ¼��ĸ��ٻ��������Ż�Ŀ¼�� i�ڵ㣬������

    // ���Ѿ����ڳ����룬���˳������ȡĿ¼���i�ڵ��������Ż�Ŀ¼�� i�ڵ㣬���ͷź�

    // ��Ŀ¼��ĸ��ٻ����������س����š�

653         bh = find_entry(&dir,basename,namelen,&de);

654         if (!bh) {

655                 iput(dir);

656                 return -ENOENT;

657         }

658         if (!(inode = iget(dir->i_dev, de->inode))) {

659                 iput(dir);

660                 brelse(bh);

661                 return -EPERM;

662         }

    // ��ʱ�������а���Ҫ��ɾ��Ŀ¼���Ŀ¼i�ڵ�dir��Ҫ��ɾ��Ŀ¼���i�ڵ�inode��Ҫ

    // ��ɾ��Ŀ¼��ָ��de����������ͨ������3����������Ϣ�ļ������֤ɾ�������Ŀ����ԡ�

   

    // ����Ŀ¼����������ɾ����־���ҽ��̵���Ч�û�id��euid������root�����ҽ��̵���Ч

    // �û�id��euid�������ڸ�i�ڵ���û�id�����ʾ��ǰ����û��Ȩ��ɾ����Ŀ¼�����Ƿ�

    // �ذ���Ҫɾ��Ŀ¼����Ŀ¼ i�ڵ�͸�Ҫɾ��Ŀ¼�� i�ڵ㣬Ȼ���ͷŸ��ٻ�����������

    // �����롣

663         if ((dir->i_mode & S_ISVTX) && current->euid &&

664             inode->i_uid != current->euid) {

665                 iput(dir);

666                 iput(inode);

667                 brelse(bh);

668                 return -EPERM;

669         }

    // ���Ҫ��ɾ����Ŀ¼��i�ڵ���豸�Ų����ڰ�����Ŀ¼���Ŀ¼���豸�ţ����߸ñ�ɾ��

    // Ŀ¼���������Ӽ������� 1����ʾ�з������ӵȣ�������ɾ����Ŀ¼�������ͷŰ���Ҫɾ

    // ��Ŀ¼����Ŀ¼i�ڵ�͸�Ҫɾ��Ŀ¼��i�ڵ㣬�ͷŸ��ٻ���飬���س����롣

670         if (inode->i_dev != dir->i_dev || inode->i_count>1) {

671                 iput(dir);

672                 iput(inode);

673                 brelse(bh);

674                 return -EPERM;

675         }

    // ���Ҫ��ɾ��Ŀ¼��Ŀ¼��i�ڵ�͵��ڰ�������ɾ��Ŀ¼��Ŀ¼i�ڵ㣬���ʾ��ͼɾ��

    // "."Ŀ¼�����Dz������ġ����ǷŻذ���Ҫɾ��Ŀ¼����Ŀ¼i�ڵ��Ҫɾ��Ŀ¼��i�ڵ㣬

    // �ͷŸ��ٻ���飬���س����롣

676         if (inode == dir) {     /* we may not delete ".", but "../dir" is ok */

677                 iput(inode);

678                 iput(dir);

679                 brelse(bh);

680                 return -EPERM;

681         }

    // ��Ҫ��ɾ��Ŀ¼i�ڵ�����Ա����ⲻ��һ��Ŀ¼����ɾ��������ǰ����ȫ�����ڡ�����

    // �Żذ���ɾ��Ŀ¼����Ŀ¼i�ڵ�͸�Ҫɾ��Ŀ¼��i�ڵ㣬�ͷŸ��ٻ���飬���س����롣

682         if (!S_ISDIR(inode->i_mode)) {

683                 iput(inode);

684                 iput(dir);

685                 brelse(bh);

686                 return -ENOTDIR;

687         }

    // �����豻ɾ����Ŀ¼���գ���Ҳ����ɾ�������ǷŻذ���Ҫɾ��Ŀ¼����Ŀ¼i�ڵ�͸�Ҫ

    // ɾ��Ŀ¼��i�ڵ㣬�ͷŸ��ٻ���飬���س����롣

688         if (!empty_dir(inode)) {

689                 iput(inode);

690                 iput(dir);

691                 brelse(bh);

692                 return -ENOTEMPTY;

693         }

    // ����һ����Ŀ¼����Ŀ¼��������Ӧ��Ϊ2�����ӵ��ϲ�Ŀ¼�ͱ�Ŀ¼���������豻ɾ��Ŀ

    // ¼��i�ڵ��������������2������ʾ������Ϣ����ɾ��������Ȼ����ִ�С������ø��豻

    // ɾ��Ŀ¼��Ŀ¼���i�ڵ���ֶ�Ϊ0����ʾ��Ŀ¼���ʹ�ã����ú��и�Ŀ¼��ĸ���

    // ��������޸ı�־�����ͷŸû���顣Ȼ�����ñ�ɾ��Ŀ¼i�ڵ��������Ϊ0����ʾ���У���

    // ����i�ڵ����޸ı�־��

694         if (inode->i_nlinks != 2)

695                 printk("empty directory has nlink!=2 (%d)",inode->i_nlinks);

696         de->inode = 0;

697         bh->b_dirt = 1;

698         brelse(bh);

699         inode->i_nlinks=0;

700         inode->i_dirt=1;

    // �ٽ�������ɾ��Ŀ¼����Ŀ¼��i�ڵ����Ӽ�����1���޸���ı�ʱ����޸�ʱ��Ϊ��ǰʱ

    // �䣬���øýڵ����޸ı�־�����Żذ���Ҫɾ��Ŀ¼����Ŀ¼i�ڵ�͸�Ҫɾ��Ŀ¼��i

    // �ڵ㣬����0��ɾ�������ɹ�����

701         dir->i_nlinks--;

702         dir->i_ctime = dir->i_mtime = CURRENT_TIME;

703         dir->i_dirt=1;

704         iput(dir);

705         iput(inode);

706         return 0;

707 }

708

    //// ɾ�����ͷţ��ļ�����Ӧ��Ŀ¼�

    // ���ļ�ϵͳɾ��һ�����֡�������ļ������һ�����ӣ�����û�н������򿪸��ļ������

    // �ļ�Ҳ����ɾ�������ͷ���ռ�õ��豸�ռ䡣

    // ������name - �ļ�����·��������

    // ���أ��ɹ��򷵻�0�����򷵻س����š�

709 int sys_unlink(const char * name)

710 {

711         const char * basename;

712         int namelen;

713         struct m_inode * dir, * inode;

714         struct buffer_head * bh;

715         struct dir_entry * de;

716

    // ���ȼ���������Ч�Բ�ȡ·�����ж���Ŀ¼��i�ڵ㡣����Ҳ�����Ӧ·�����ж���Ŀ¼

    // �� i�ڵ㣬�򷵻س����롣�����˵��ļ�������Ϊ0����˵��������·�������û��ָ

    // ���ļ������Żظ�Ŀ¼i�ڵ㣬���س������˳�������ڸ�Ŀ¼��û��д��Ȩ�ޣ���Żظ�

    // Ŀ¼��i�ڵ㣬���ط������ɳ������˳�������Ҳ�����Ӧ·��������Ŀ¼��i�ڵ㣬��

    // �س����롣

717         if (!(dir = dir_namei(name,&namelen,&basename, NULL)))

718                 return -ENOENT;

719         if (!namelen) {

720                 iput(dir);

721                 return -ENOENT;

722         }

723         if (!permission(dir,MAY_WRITE)) {

724                 iput(dir);

725                 return -EPERM;

726         }

    // Ȼ�����ָ��Ŀ¼��i�ڵ��Ŀ¼�����ú���find_entry()Ѱ�Ҷ�ӦĿ¼������ذ�����

    // Ŀ¼��Ļ����ָ��bh��������Ŀ¼���Ŀ¼��i�ڵ�ָ��dir�͸�Ŀ¼��ָ��de���ٸ���

    // ��Ŀ¼��de �е�i�ڵ������ iget()�����õ���Ӧ��i�ڵ� inode�������Ӧ·��������

    // ��Ŀ¼����Ŀ¼����ڣ����ͷŰ�����Ŀ¼��ĸ��ٻ��������Ż�Ŀ¼�� i�ڵ㣬������

    // ���Ѿ����ڳ����룬���˳������ȡĿ¼���i�ڵ��������Ż�Ŀ¼�� i�ڵ㣬���ͷź�

    // ��Ŀ¼��ĸ��ٻ����������س����š�

727         bh = find_entry(&dir,basename,namelen,&de);

728         if (!bh) {

729                 iput(dir);

730                 return -ENOENT;

731         }

732         if (!(inode = iget(dir->i_dev, de->inode))) {

733                 iput(dir);

734                 brelse(bh);

735                 return -ENOENT;

736         }

    // ��ʱ�������а���Ҫ��ɾ��Ŀ¼���Ŀ¼i�ڵ�dir��Ҫ��ɾ��Ŀ¼���i�ڵ�inode��Ҫ

    // ��ɾ��Ŀ¼��ָ��de����������ͨ������3����������Ϣ�ļ������֤ɾ�������Ŀ����ԡ�

   

    // ����Ŀ¼����������ɾ����־���ҽ��̵���Ч�û�id��euid������root�����ҽ��̵�euid

    // �����ڸ�i�ڵ���û�id�����ҽ��̵�euidҲ������Ŀ¼i�ڵ���û�id�����ʾ��ǰ��

    // ��û��Ȩ��ɾ����Ŀ¼�����ǷŻذ���Ҫɾ��Ŀ¼����Ŀ¼i�ڵ�͸�Ҫɾ��Ŀ¼��i�ڵ㣬

    // Ȼ���ͷŸ��ٻ���飬���س����롣

737         if ((dir->i_mode & S_ISVTX) && !suser() &&

738             current->euid != inode->i_uid &&

739             current->euid != dir->i_uid) {

740                 iput(dir);

741                 iput(inode);

742                 brelse(bh);

743                 return -EPERM;

744         }

    // �����ָ���ļ�����һ��Ŀ¼����Ҳ����ɾ�����Żظ�Ŀ¼i�ڵ�͸��ļ���Ŀ¼���i��

    // �㣬�ͷŰ�����Ŀ¼��Ļ���飬���س����š�

745         if (S_ISDIR(inode->i_mode)) {

746                 iput(inode);

747                 iput(dir);

748                 brelse(bh);

749                 return -EPERM;

750         }

    // �����i�ڵ�����Ӽ���ֵ�Ѿ�Ϊ0������ʾ������Ϣ����������Ϊ1��

751         if (!inode->i_nlinks) {

752                 printk("Deleting nonexistent file (%04x:%d), %d\n",

753                         inode->i_dev,inode->i_num,inode->i_nlinks);

754                 inode->i_nlinks=1;

755         }

    // �������ǿ���ɾ���ļ�����Ӧ��Ŀ¼���ˡ����ǽ����ļ���Ŀ¼���е�i�ڵ���ֶ���Ϊ0��

    // ��ʾ�ͷŸ�Ŀ¼������ð�����Ŀ¼��Ļ�������޸ı�־���ͷŸø��ٻ���顣

756         de->inode = 0;

757         bh->b_dirt = 1;

758         brelse(bh);

    // Ȼ����ļ�����Ӧi�ڵ����������1�������޸ı�־�����¸ı�ʱ��Ϊ��ǰʱ�䡣����

    // �ظ�i�ڵ��Ŀ¼��i�ڵ㣬����0���ɹ�����������ļ������һ�����ӣ���i�ڵ�����

    // ����1�����0�����Ҵ�ʱû�н������򿪸��ļ�����ô�ڵ���iput()�Ż�i�ڵ�ʱ������

    // ��Ҳ����ɾ�������ͷ���ռ�õ��豸�ռ䡣�μ�fs/inode.c����183�С�

759         inode->i_nlinks--;

760         inode->i_dirt = 1;

761         inode->i_ctime = CURRENT_TIME;

762         iput(inode);

763         iput(dir);

764         return 0;

765 }

766

    //// �����������ӡ�

    // Ϊһ���Ѵ����ļ�����һ���������ӣ�Ҳ��Ϊ������ - hard link����

    // ������oldname - ԭ·������newname - �µ�·������

    // ���أ����ɹ��򷵻�0�����򷵻س����š�

767 int sys_symlink(const char * oldname, const char * newname)

768 {

769         struct dir_entry * de;

770         struct m_inode * dir, * inode;

771         struct buffer_head * bh, * name_block;

772         const char * basename;

773         int namelen, i;

774         char c;

775

    // ���Ȳ�����·���������Ŀ¼��i�ڵ�dir�������������ļ������䳤�ȡ����Ŀ¼��

    // i�ڵ�û���ҵ����򷵻س����š������·�����в������ļ�������Ż���·����Ŀ¼��i

    // �ڵ㣬���س����š����⣬����û�û������Ŀ¼��д��Ȩ�ޣ���Ҳ���ܽ������ӣ����Ƿ�

    // ����·����Ŀ¼��i�ڵ㣬���س����š�

776         dir = dir_namei(newname,&namelen,&basename, NULL);

777         if (!dir)

778                 return -EACCES;

779         if (!namelen) {

780                 iput(dir);

781                 return -EPERM;

782         }

783         if (!permission(dir,MAY_WRITE)) {

784                 iput(dir);

785                 return -EACCES;

786         }

    // ����������Ŀ¼ָ���豸������һ���µ�i�ڵ㣬�����ø�i�ڵ�ģʽΪ�������������Լ�

    // ���̹涨��ģʽ�����롣�������ø�i�ڵ����޸ı�־��

787         if (!(inode = new_inode(dir->i_dev))) {

788                 iput(dir);

789                 return -ENOSPC;

790         }

791         inode->i_mode = S_IFLNK | (0777 & ~current->umask);

792         inode->i_dirt = 1;

    // Ϊ�˱����������·�����ַ�����Ϣ��������ҪΪ��i�ڵ�����һ�����̿飬����i�ڵ��

    // ��1��ֱ�ӿ��i_zone[0]���ڵõ����߼���š�Ȼ����i�ڵ����޸ı�־���������ʧ��

    // ��Żض�ӦĿ¼��i�ڵ㣻��λ�������i�ڵ����Ӽ������Żظ��µ�i�ڵ㣬����û�п�

    // ��������˳���

793         if (!(inode->i_zone[0]=new_block(inode->i_dev))) {

794                 iput(dir);

795                 inode->i_nlinks--;

796                 iput(inode);

797                 return -ENOSPC;

798         }

799         inode->i_dirt = 1;

    // Ȼ����豸�϶�ȡ������Ĵ��̿飨Ŀ���ǰѶ�Ӧ��ŵ����ٻ������У�������������Ż�

    // ��ӦĿ¼��i�ڵ㣻��λ�������i�ڵ����Ӽ������Żظ��µ�i�ڵ㣬����û�пռ����

    // ���˳���

800         if (!(name_block=bread(inode->i_dev,inode->i_zone[0]))) {

801                 iput(dir);

802                 inode->i_nlinks--;

803                 iput(inode);

804                 return -ERROR;

805         }

    // �������ǿ��԰ѷ����������ַ�����������̿����ˡ��̿鳤��Ϊ1024�ֽڣ����Ĭ�Ϸ���

    // �������������Ҳֻ����1024�ֽڡ����ǰ��û��ռ��еķ����������ַ������Ƶ��̿�����

    // �Ļ�����У����û�������޸ı�־��Ϊ��ֹ�û��ṩ���ַ���û����null��β�������ڻ�

    // ������������һ���ֽڴ�����һ��NULL��Ȼ���ͷŸû���飬������i�ڵ��Ӧ�ļ�����

    // �ݳ��ȵ��ڷ����������ַ������ȣ�����i�ڵ����޸ı�־��

806         i = 0;

807         while (i < 1023 && (c=get_fs_byte(oldname++)))

808                 name_block->b_data[i++] = c;

809         name_block->b_data[i] = 0;

810         name_block->b_dirt = 1;

811         brelse(name_block);

812         inode->i_size = i;

813         inode->i_dirt = 1;

    // Ȼ����������һ��·����ָ���ķ��������ļ����Ƿ��Ѿ����ڡ����Ѿ��������ܴ���ͬ��

    // Ŀ¼��i�ڵ㡣�����Ӧ���������ļ����Ѿ����ڣ����ͷŰ�����Ŀ¼��Ļ������飬��λ

    // �������i�ڵ����Ӽ��������Ż�Ŀ¼��i�ڵ㣬�����ļ��Ѿ����ڵij������˳���

814         bh = find_entry(&dir,basename,namelen,&de);

815         if (bh) {

816                 inode->i_nlinks--;

817                 iput(inode);

818                 brelse(bh);

819                 iput(dir);

820                 return -EEXIST;

821         }

    // ����������ָ��Ŀ¼��������һ��Ŀ¼����ڴ���½����������ļ�����i�ڵ�ź�Ŀ¼

    // �������ʧ�ܣ�������Ŀ¼��ĸ��ٻ�����ָ��ΪNULL������Ż�Ŀ¼��i�ڵ㣻�������

    // i�ڵ��������Ӽ�����λ�����Żظ�i�ڵ㡣���س������˳���

822         bh = add_entry(dir,basename,namelen,&de);

823         if (!bh) {

824                 inode->i_nlinks--;

825                 iput(inode);

826                 iput(dir);

827                 return -ENOSPC;

828         }

    // ��������Ŀ¼���i�ڵ��ֶε�����i�ڵ�ţ����ø��ٻ�������޸ı�־���ͷŸ��ٻ�

    // ��飬�Ż�Ŀ¼���µ�i�ڵ㣬��󷵻�0���ɹ�����

829         de->inode = inode->i_num;

830         bh->b_dirt = 1;

831         brelse(bh);

832         iput(dir);

833         iput(inode);

834         return 0;

835 }

836

    //// Ϊ�ļ�����һ���ļ���Ŀ¼�

    // Ϊһ���Ѵ��ڵ��ļ�����һ�������ӣ�Ҳ��ΪӲ���� - hard link����

    // ������oldname - ԭ·������newname - �µ�·������

    // ���أ����ɹ��򷵻�0�����򷵻س����š�

837 int sys_link(const char * oldname, const char * newname)

838 {

839         struct dir_entry * de;

840         struct m_inode * oldinode, * dir;

841         struct buffer_head * bh;

842         const char * basename;

843         int namelen;

844

    // ���ȶ�ԭ�ļ���������Ч����֤����Ӧ�ô��ڲ��Ҳ���һ��Ŀ¼��������������ȡԭ�ļ�·

    // ������Ӧ��i�ڵ�oldinode�����Ϊ0�����ʾ���������س����š����ԭ·������Ӧ����

    // һ��Ŀ¼������Żظ�i�ڵ㣬Ҳ���س����š�

845         oldinode=namei(oldname);

846         if (!oldinode)

847                 return -ENOENT;

848         if (S_ISDIR(oldinode->i_mode)) {

849                 iput(oldinode);

850                 return -EPERM;

851         }

    // Ȼ�������·���������Ŀ¼��i�ڵ�dir�������������ļ������䳤�ȡ����Ŀ¼��

    // i�ڵ�û���ҵ�����Ż�ԭ·������i�ڵ㣬���س����š������·�����в������ļ�����

    // ��Ż�ԭ·����i�ڵ����·����Ŀ¼��i�ڵ㣬���س����š�

852         dir = dir_namei(newname,&namelen,&basename, NULL);

853         if (!dir) {

854                 iput(oldinode);

855                 return -EACCES;

856         }

857         if (!namelen) {

858                 iput(oldinode);

859                 iput(dir);

860                 return -EPERM;

861         }

    // ���Dz��ܿ��豸����Ӳ���ӡ���������·��������Ŀ¼���豸����ԭ·�������豸��

    // ��һ������Ż���·����Ŀ¼��i�ڵ��ԭ·������i�ڵ㣬���س����š����⣬����û�

    // û������Ŀ¼��д��Ȩ�ޣ���Ҳ���ܽ������ӣ����ǷŻ���·����Ŀ¼��i�ڵ��ԭ·����

    // ��i�ڵ㣬���س����š�

862         if (dir->i_dev != oldinode->i_dev) {

863                 iput(dir);

864                 iput(oldinode);

865                 return -EXDEV;

866         }

867         if (!permission(dir,MAY_WRITE)) {

868                 iput(dir);

869                 iput(oldinode);

870                 return -EACCES;

871         }

    // ���ڲ�ѯ����·�����Ƿ��Ѿ����ڣ����������Ҳ���ܽ������ӡ������ͷŰ������Ѵ���Ŀ

    // ¼��ĸ��ٻ���飬�Ż���·����Ŀ¼��i�ڵ��ԭ·������i�ڵ㣬���س����š�

872         bh = find_entry(&dir,basename,namelen,&de);

873         if (bh) {

874                 brelse(bh);

875                 iput(dir);

876                 iput(oldinode);

877                 return -EEXIST;

878         }

    // �������������������ˣ�������������Ŀ¼������һ��Ŀ¼���ʧ����Żظ�Ŀ¼��i��

    // ���ԭ·������i�ڵ㣬���س����š������ʼ���ø�Ŀ¼���i�ڵ�ŵ���ԭ·������i

    // �ڵ�ţ����ð���������Ŀ¼��Ļ�������޸ı�־���ͷŸû���飬�Ż�Ŀ¼��i�ڵ㡣

879         bh = add_entry(dir,basename,namelen,&de);

880         if (!bh) {

881                 iput(dir);

882                 iput(oldinode);

883                 return -ENOSPC;

884         }

885         de->inode = oldinode->i_num;

886         bh->b_dirt = 1;

887         brelse(bh);

888         iput(dir);

    // �ٽ�ԭ�ڵ�����Ӽ�����1���޸���ı�ʱ��Ϊ��ǰʱ�䣬������i�ڵ����޸ı�־�����

    // �Ż�ԭ·������i�ڵ㣬������0���ɹ�����

889         oldinode->i_nlinks++;

890         oldinode->i_ctime = CURRENT_TIME;

891         oldinode->i_dirt = 1;

892         iput(oldinode);

893         return 0;

894 }

895


 


 

12.7 ����12-7 linux/fs/file_table.c


  1 /*

  2  *  linux/fs/file_table.c

  3  *

  4  *  (C) 1991  Linus Torvalds

  5  */

  6

  7 #include <linux/fs.h>     // �ļ�ϵͳͷ�ļ��������ļ����ṹ��file,buffer_head,m_inode�ȣ���

  8

  9 struct file file_table[NR_FILE];  // �ļ�������(64��)��

 10


 

 


 

12.8 ����12-8 linux/fs/block_dev.c


  1 /*

  2  *  linux/fs/block_dev.c

  3  *

  4  *  (C) 1991  Linus Torvalds

  5  */

  6

  7 #include <errno.h>        // �����ͷ�ļ�������ϵͳ�и��ֳ����š�

  8

  9 #include <linux/sched.h>  // ���ȳ���ͷ�ļ�������������ṹtask_struct������0�����ݣ�

                              // ����һЩ�й��������������úͻ�ȡ��Ƕ��ʽ��ຯ������䡣

 10 #include <linux/kernel.h> // �ں�ͷ�ļ�������һЩ�ں˳��ú�����ԭ�ζ��塣

 11 #include <asm/segment.h>  // �β���ͷ�ļ����������йضμĴ���������Ƕ��ʽ��ຯ����

 12 #include <asm/system.h>   // ϵͳͷ�ļ������������û��޸�������/�ж��ŵȵ�Ƕ��ʽ���ꡣ

 13

    // �豸���ݿ�����ָ�����顣ÿ��ָ����ָ��ָ�����豸�ŵ��ܿ�������hd_sizes[]������

    // ��������ÿһ���Ӧ���豸��ȷ����һ�����豸����ӵ�е����ݿ�������1���С = 1KB����

 14 extern int *blk_size[];              // blk_drv/ll_rw_blk.c��49�С�

 15

    //// ���ݿ�д���� - ��ָ���豸�Ӹ���ƫ�ƴ�д��ָ���������ݡ�

    // ������dev - �豸�ţ�pos - �豸�ļ���ƫ����ָ�룻buf - �û��ռ��л�������ַ��

    // count - Ҫ���͵��ֽ�����

    // ������д���ֽ�������û��д���κ��ֽڻ�������򷵻س����š�

    // �����ں���˵��д����������ٻ�������д�����ݡ�ʲôʱ����������д���豸���ɸ��ٻ�

    // �������������������ġ����⣬��Ϊ���豸���Կ�Ϊ��λ���ж�д����˶���д��ʼλ��

    // �����ڿ���ʼ��ʱ����Ҫ�Ƚ���ʼ�ֽ����ڵ������������Ȼ����Ҫд�����ݴ�д��ʼ��

    // ��д���ÿ飬�ٽ�������һ������д�̣������ɸ��ٻ������ȥ��������

 16 int block_write(int dev, long * pos, char * buf, int count)

 17 {

    // �������ļ���λ��pos����ɿ�ʼ��д�̿�Ŀ����block���������д��1�ֽ��ڸÿ���

    // ��ƫ��λ��offset��

 18         int block = *pos >> BLOCK_SIZE_BITS;         // pos�����ļ����ݿ�š�

 19         int offset = *pos & (BLOCK_SIZE-1);          // pos�����ݿ���ƫ��ֵ��

 20         int chars;

 21         int written = 0;

 22         int size;

 23         struct buffer_head * bh;

 24         register char * p;                   // �ֲ��Ĵ���������������ڼĴ����С�

 25

    // ��дһ�����豸�ļ�ʱ��Ҫ��д�������ݿ�����Ȼ���ܳ���ָ���豸��������������ݿ���

    // ���������������ȡ��ָ���豸�Ŀ�����size���ȽϺ����ƺ�������������д�����ݳ��ȡ�

    // ���ϵͳ��û�ж��豸ָ�����ȣ���ʹ��Ĭ�ϳ���0x7fffffff��2GB���飩��

 26         if (blk_size[MAJOR(dev)])

 27                 size = blk_size[MAJOR(dev)][MINOR(dev)];

 28         else

 29                 size = 0x7fffffff;

    // Ȼ�����Ҫд����ֽ���count��ѭ��ִ�����²�����ֱ������ȫ��д�롣��ѭ��ִ�й���

    // �У�����ǰд�����ݵĿ���Ѿ����ڻ����ָ���豸���ܿ������򷵻���д�ֽ������˳���

    // Ȼ���ټ����ڵ�ǰ���������ݿ��п�д����ֽ����������Ҫд����ֽ������һ�飬��

    // ô��ֻ��дcount�ֽڡ��������Ҫд1���������ݣ���ֱ������1����ٻ���飬������

    // �����ݷ��뼴�ɡ��������Ҫ���뽫��д�벿�����ݵ����ݿ飬��Ԥ�����������ݡ�Ȼ��

    // ��ŵ��� 1��Ϊ�´β�������׼���������������ʧ�ܣ��򷵻���д�ֽ��������û��д

    // ���κ��ֽڣ��򷵻س����ţ���������

 30         while (count>0) {

 31                 if (block >= size)

 32                         return written?written:-EIO;

 33                 chars = BLOCK_SIZE - offset;            // �����д����ֽ�����

 34                 if (chars > count)

 35                         chars=count;

 36                 if (chars == BLOCK_SIZE)

 37                         bh = getblk(dev,block);         // buffer.c ��206��322�С�

 38                 else

 39                         bh = breada(dev,block,block+1,block+2,-1);

 40                 block++;

 41                 if (!bh)

 42                         return written?written:-EIO;

    // �����Ȱ�ָ��pָ��������ݵĻ�����п�ʼд�����ݵ�λ�ô��������һ��ѭ��д�����

    // �ݲ���һ�飬����ӿ鿪ʼ����д���޸ģ�������ֽڣ����������Ԥ������offsetΪ�㡣

    // �˺��ļ���ƫ��ָ��posǰ�ƴ˴ν�Ҫд���ֽ���chars�����ۼ���ЩҪд���ֽ�����ͳ

    // ��ֵwritten�С��ٰѻ���Ҫд�ļ���ֵcount ��ȥ�˴�Ҫд���ֽ���chars��Ȼ�����Ǵ�

    // �û�����������chars���ֽڵ�pָ��ĸ��ٻ�����п�ʼд���λ�ô���������������

    // �û����������޸ı�־�����ͷŸû�������Ҳ���û��������ü����ݼ�1����

 43                 p = offset + bh->b_data;

 44                 offset = 0;

 45                 *pos += chars;

 46                 written += chars;                     // �ۼ�д���ֽ�����

 47                 count -= chars;

 48                 while (chars-->0)

 49                         *(p++) = get_fs_byte(buf++);

 50                 bh->b_dirt = 1;

 51                 brelse(bh);

 52         }

 53         return written;                           // ������д����ֽ����������˳���

 54 }

 55

    //// ���ݿ������ - ��ָ���豸��λ�ô�����ָ���������ݵ��û��������С�

    // ������dev - �豸�ţ�pos - �豸�ļ���ƫ����ָ�룻buf - �û��ռ��л�������ַ��

    // count - Ҫ���͵��ֽ�����

    // �����Ѷ����ֽ�������û�ж����κ��ֽڻ�������򷵻س����š�

 56 int block_read(int dev, unsigned long * pos, char * buf, int count)

 57 {

 58         int block = *pos >> BLOCK_SIZE_BITS;

 59         int offset = *pos & (BLOCK_SIZE-1);

 60         int chars;

 61         int size;

 62         int read = 0;

 63         struct buffer_head * bh;

 64         register char * p;                    // �ֲ��Ĵ���������������ڼĴ����С�

 65

    // �ڶ�һ�����豸�ļ�ʱ��Ҫ����������ݿ�����Ȼ���ܳ���ָ���豸��������������ݿ���

    // ���������������ȡ��ָ���豸�Ŀ�����size���ȽϺ����ƺ������������Ķ������ݳ��ȡ�

    // ���ϵͳ��û�ж��豸ָ�����ȣ���ʹ��Ĭ�ϳ���0x7fffffff��2GB���飩��

 66         if (blk_size[MAJOR(dev)])

 67                 size = blk_size[MAJOR(dev)][MINOR(dev)];

 68         else

 69                 size = 0x7fffffff;

    // Ȼ�����Ҫ������ֽ���count��ѭ��ִ�����²�����ֱ������ȫ�����롣��ѭ��ִ�й���

    // �У�����ǰ�������ݵĿ���Ѿ����ڻ����ָ���豸���ܿ������򷵻��Ѷ��ֽ������˳���

    // Ȼ���ټ����ڵ�ǰ���������ݿ����������ֽ����������Ҫ������ֽ���������һ�飬��

    // ô��ֻ���count�ֽڡ�Ȼ����ö��麯��breada()������Ҫ�����ݿ飬��Ԥ�����������ݣ�

    // ����������������򷵻��Ѷ��ֽ��������û�ж����κ��ֽڣ��򷵻س����š�Ȼ�󽫿��

    // ����1��Ϊ�´β�������׼���������������ʧ�ܣ��򷵻���д�ֽ��������û�ж�����

    // ���ֽڣ��򷵻س����ţ���������

 70         while (count>0) {

 71                 if (block >= size)

 72                         return read?read:-EIO;

 73                 chars = BLOCK_SIZE-offset;

 74                 if (chars > count)

 75                         chars = count;

 76                 if (!(bh = breada(dev,block,block+1,block+2,-1)))

 77                         return read?read:-EIO;

 78                 block++;

    // �����Ȱ�ָ��pָ������̿�Ļ�����п�ʼ�������ݵ�λ�ô��������һ��ѭ����������

    // ���ݲ���һ�飬����ӿ���ʼ����ȡ�����ֽڣ����������Ԥ������offsetΪ�㡣 �˺�

    // �ļ���ƫ��ָ��posǰ�ƴ˴ν�Ҫ�����ֽ���chars�������ۼ���ЩҪ�����ֽ�����ͳ��ֵ

    // read�С��ٰѻ���Ҫ���ļ���ֵcount��ȥ�˴�Ҫ�����ֽ���chars��Ȼ�����ǴӸ��ٻ���

    // ����pָ��Ŀ�ʼ����λ�ô�����chars���ֽڵ��û��������У�ͬʱ���û�������ָ��ǰ

    // �ơ����θ��������ͷŸû���顣

 79                 p = offset + bh->b_data;

 80                 offset = 0;

 81                 *pos += chars;

 82                 read += chars;                   // �ۼƶ����ֽ�����

 83                 count -= chars;

 84                 while (chars-->0)

 85                         put_fs_byte(*(p++),buf++);

 86                 brelse(bh);

 87         }

 88         return read;                             // �����Ѷ�ȡ���ֽ����������˳���

 89 }

 90


 


 

12.9 ����12-9 linux/fs/file_dev.c


  1 /*

  2  *  linux/fs/file_dev.c

  3  *

  4  *  (C) 1991  Linus Torvalds

  5  */

  6

  7 #include <errno.h>        // �����ͷ�ļ�������ϵͳ�и��ֳ����š�

  8 #include <fcntl.h>        // �ļ�����ͷ�ļ��������ļ������������IJ������Ƴ������ŵĶ��塣

  9

 10 #include <linux/sched.h>  // ���ȳ���ͷ�ļ�������������ṹtask_struct������0�����ݵȡ�

 11 #include <linux/kernel.h> // �ں�ͷ�ļ�������һЩ�ں˳��ú�����ԭ�ζ��塣

 12 #include <asm/segment.h>  // �β���ͷ�ļ����������йضμĴ���������Ƕ��ʽ��ຯ����

 13

 14 #define MIN(a,b) (((a)<(b))?(a):(b))         // ȡa,b�е���Сֵ��

 15 #define MAX(a,b) (((a)>(b))?(a):(b))         // ȡa,b�е����ֵ��

 16

    //// �ļ������� - ����i�ڵ���ļ��ṹ����ȡ�ļ������ݡ�

    // ��i�ڵ����ǿ���֪���豸�ţ���filp�ṹ����֪���ļ��е�ǰ��дָ��λ�á�bufָ����

    // ���ռ��л�������λ�ã�count����Ҫ��ȡ���ֽ����� ����ֵ��ʵ�ʶ�ȡ���ֽ����������

    // �ţ�С��0����

 17 int file_read(struct m_inode * inode, struct file * filp, char * buf, int count)

 18 {

 19         int left,chars,nr;

 20         struct buffer_head * bh;

 21

    // �����жϲ�������Ч�ԡ�����Ҫ��ȡ���ֽڼ���countС�ڵ����㣬�򷵻�0��������Ҫ��

    // ȡ���ֽ���������0����ѭ��ִ�����������ֱ������ȫ���������������⡣�ڶ�ѭ������

    // �����У����Ǹ���i�ڵ���ļ����ṹ��Ϣ�������� bmap() �õ������ļ���ǰ��дλ�õ�

    // ���ݿ����豸�϶�Ӧ���߼����nr����nr��Ϊ0�����i�ڵ�ָ�����豸�϶�ȡ���߼��顣

    // ���������ʧ�����˳�ѭ������nrΪ0����ʾָ�������ݿ鲻���ڣ��û����ָ��ΪNULL��

    // (filp->f_pos)/BLOCK_SIZE ���ڼ�����ļ���ǰָ���������ݿ�š�

 22         if ((left=count)<=0)

 23                 return 0;

 24         while (left) {

 25                 if (nr = bmap(inode,(filp->f_pos)/BLOCK_SIZE)) { // inode.c��140�С�

 26                         if (!(bh=bread(inode->i_dev,nr)))

 27                                 break;

 28                 } else

 29                         bh = NULL;

    // �������Ǽ����ļ���дָ�������ݿ��е�ƫ��ֵnr�����ڸ����ݿ�������ϣ����ȡ���ֽ���

    // Ϊ (BLOCK_SIZE - nr)��Ȼ������ڻ����ȡ���ֽ���left���Ƚϣ�����Сֵ��Ϊ���β���

    // ���ȡ���ֽ���chars����� (BLOCK_SIZE - nr) > left����˵���ÿ�����Ҫ��ȡ�����һ

    // �����ݣ���֮����Ҫ��ȡ��һ�����ݡ�֮�������д�ļ�ָ�롣 ָ��ǰ�ƴ˴ν���ȡ����

    // ����chars��ʣ���ֽڼ���left��Ӧ��ȥchars��

 30                 nr = filp->f_pos % BLOCK_SIZE;

 31                 chars = MIN( BLOCK_SIZE-nr , left );

 32                 filp->f_pos += chars;

 33                 left -= chars;

    // ��������豸�϶��������ݣ���pָ�򻺳���п�ʼ��ȡ���ݵ�λ�ã����Ҹ���chars�ֽ�

    // ���û�������buf�С��������û�������������chars��0ֵ�ֽڡ�

 34                 if (bh) {

 35                         char * p = nr + bh->b_data;

 36                         while (chars-->0)

 37                                 put_fs_byte(*(p++),buf++);

 38                         brelse(bh);

 39                 } else {

 40                         while (chars-->0)

 41                                 put_fs_byte(0,buf++);

 42                 }

 43         }

    // �޸ĸ�i�ڵ�ķ���ʱ��Ϊ��ǰʱ�䡣���ض�ȡ���ֽ���������ȡ�ֽ���Ϊ0���򷵻س����š�

    // CURRENT_TIME�Ƕ�����include/linux/sched.h��142���ϵĺ꣬���ڼ���UNIXʱ�䡣����

    // 1970��1��1��0ʱ0�뿪ʼ������ǰ��ʱ�䡣��λ���롣

 44         inode->i_atime = CURRENT_TIME;

 45         return (count-left)?(count-left):-ERROR;

 46 }

 47

    //// �ļ�д���� - ����i�ڵ���ļ��ṹ��Ϣ�����û�����д���ļ��С�

    // ��i�ڵ����ǿ���֪���豸�ţ�����file�ṹ����֪���ļ��е�ǰ��дָ��λ�á�bufָ��

    // �û�̬�л�������λ�ã�countΪ��Ҫд����ֽ����� ����ֵ��ʵ��д����ֽ����������

    // �ţ�С��0����

 48 int file_write(struct m_inode * inode, struct file * filp, char * buf, int count)

 49 {

 50         off_t pos;

 51         int block,c;

 52         struct buffer_head * bh;

 53         char * p;

 54         int i=0;

 55

 56 /*

 57  * ok, append may not work when many processes are writing at the same time

 58  * but so what. That way leads to madness anyway.

 59  */

    /*

     * ok�����������ͬʱдʱ��append�������ܲ��У�����������������������������

     * ���»���һ�š�

     */

    // ����ȷ������д���ļ���λ�á������Ҫ���ļ����������ݣ����ļ���дָ���Ƶ��ļ�β

    // ��������ͽ����ļ���ǰ��дָ�봦д�롣

 60         if (filp->f_flags & O_APPEND)

 61                 pos = inode->i_size;

 62         else

 63                 pos = filp->f_pos;

    // Ȼ������д���ֽ���i���տ�ʼʱΪ0��С��ָ��д���ֽ���countʱ��ѭ��ִ�����²�����

    // ��ѭ�����������У�������ȡ�ļ����ݿ�� ( pos/BLOCK_SIZE ) ���豸�϶�Ӧ���߼����

    // block�������Ӧ���߼��鲻���ھʹ���һ�顣����õ����߼���� = 0�����ʾ����ʧ�ܣ�

    // �����˳�ѭ�����������Ǹ��ݸ��߼���Ŷ�ȡ�豸�ϵ���Ӧ�߼��飬������Ҳ�˳�ѭ����

 64         while (i<count) {

 65                 if (!(block = create_block(inode,pos/BLOCK_SIZE)))

 66                         break;

 67                 if (!(bh=bread(inode->i_dev,block)))

 68                         break;

    // ��ʱ�����ָ��bh��ָ��ն�����ļ����ݿ顣����������ļ���ǰ��дָ���ڸ����ݿ���

    // ��ƫ��ֵc������ָ��pָ�򻺳���п�ʼд�����ݵ�λ�ã����øû�������޸ı�־������

    // ���е�ǰָ�룬�ӿ�ʼ��дλ�õ���ĩ����д��c =(BLOCK_SIZE - c)���ֽڡ���c����ʣ��

    // ����д����ֽ��� (count - i)����˴�ֻ����д��c = (count - i)���ֽڼ��ɡ�

 69                 c = pos % BLOCK_SIZE;

 70                 p = c + bh->b_data;

 71                 bh->b_dirt = 1;

 72                 c = BLOCK_SIZE-c;

 73                 if (c > count-i) c = count-i;

    // ��д������֮ǰ��������Ԥ�����ú���һ��ѭ������Ҫ��д�ļ��е�λ�á�������ǰ�pos

    // ָ��ǰ�ƴ˴���д����ֽ����������ʱposλ��ֵ�������ļ���ǰ���ȣ����޸�i�ڵ���

    // �ļ������ֶΣ�����i�ڵ����޸ı�־��Ȼ��Ѵ˴�Ҫд����ֽ���c�ۼӵ���д���ֽڼ�

    // ��ֵi�У���ѭ���ж�ʹ�á����Ŵ��û�������buf�и���c���ֽڵ����ٻ������pָ��

    // �Ŀ�ʼλ�ô������������ͷŸû���顣

 74                 pos += c;

 75                 if (pos > inode->i_size) {

 76                         inode->i_size = pos;

 77                         inode->i_dirt = 1;

 78                 }

 79                 i += c;

 80                 while (c-->0)

 81                         *(p++) = get_fs_byte(buf++);

 82                 brelse(bh);

 83         }

    // �������Ѿ�ȫ��д���ļ�������д���������з�������ʱ�ͻ��˳�ѭ������ʱ���Ǹ����ļ�

    // �޸�ʱ��Ϊ��ǰʱ�䣬�������ļ���дָ�롣����˴β����������ļ�β�������ݣ������

    // ����дָ���������ǰ��дλ��pos�����������ļ�i�ڵ���޸�ʱ��Ϊ��ǰʱ�䡣���

    // ��д����ֽ�������д���ֽ���Ϊ0���򷵻س�����-1��

 84         inode->i_mtime = CURRENT_TIME;

 85         if (!(filp->f_flags & O_APPEND)) {

 86                 filp->f_pos = pos;

 87                 inode->i_ctime = CURRENT_TIME;

 88         }

 89         return (i?i:-1);

 90 }

 91


 


 

12.10 ����12-10 linux/fs/pipe.c


  1 /*

  2  *  linux/fs/pipe.c

  3  *

  4  *  (C) 1991  Linus Torvalds

  5  */

  6

  7 #include <signal.h>       // �ź�ͷ�ļ��������źŷ��ų������źŽṹ����������ԭ�͡�

  8 #include <errno.h>        // �����ͷ�ļ�������ϵͳ�и��ֳ����š�

  9 #include <termios.h>      // �ն������������ͷ�ļ�����Ҫ��������첽ͨ�ſڵ��ն˽ӿڡ�

 10

 11 #include <linux/sched.h>  // ���ȳ���ͷ�ļ�������������ṹtask_struct������0���ݵȡ�

 12 #include <linux/mm.h>     /* for get_free_page */    /* ʹ�����е�get_free_page */

 13 #include <asm/segment.h>  // �β���ͷ�ļ����������йضμĴ���������Ƕ��ʽ��ຯ����

 14 #include <linux/kernel.h> // �ں�ͷ�ļ�������һЩ�ں˳��ú�����ԭ�ζ��塣

 15

    //// �ܵ�������������

    // ����inode�ǹܵ���Ӧ��i�ڵ㣬buf���û����ݻ�����ָ�룬count�Ƕ�ȡ���ֽ�����

 16 int read_pipe(struct m_inode * inode, char * buf, int count)

 17 {

 18         int chars, size, read = 0;

 19

    // �����Ҫ��ȡ���ֽڼ���count����0�����Ǿ�ѭ��ִ�����²�������ѭ�������������У�

    // ����ǰ�ܵ���û�����ݣ�size=0�������ѵȴ��ýڵ�Ľ��̣���ͨ����д�ܵ����̡����

    // ��û��д�ܵ��ߣ��� i�ڵ����ü���ֵС��2���򷵻��Ѷ��ֽ����˳��������ǰ�յ��з�

    // �����źţ������̷����Ѷ�ȡ�ֽ����˳�������û���յ��κ����ݣ��򷵻���������ϵͳ

    // ���ú��˳���������ý����ڸùܵ���˯�ߣ����Եȴ���Ϣ�ĵ�������PIPE_SIZE������

    // include/linux/fs.h�С����ڡ���������ϵͳ���á�����μ�kernel/signal.c����

 20         while (count>0) {

 21                 while (!(size=PIPE_SIZE(*inode))) {      // ȡ�ܵ������ݳ���ֵ��

 22                         wake_up(& PIPE_WRITE_WAIT(*inode));

 23                         if (inode->i_count != 2)    /* are there any writers? */

 24                                 return read;

 25                         if (current->signal & ~current->blocked)

 26                                 return read?read:-ERESTARTSYS;

 27                         interruptible_sleep_on(& PIPE_READ_WAIT(*inode));

 28                 }

    // ��ʱ˵���ܵ������������������ݡ���������ȡ�ܵ�βָ�뵽������ĩ�˵��ֽ���chars��

    // �������ڻ���Ҫ��ȡ���ֽ���count�����������count�����chars���ڵ�ǰ�ܵ��к�

    // �����ݵij��� size����������� size�� Ȼ�������ֽ���count��ȥ�˴οɶ����ֽ���

    // chars�����ۼ��Ѷ��ֽ���read��

 29                 chars = PAGE_SIZE-PIPE_TAIL(*inode);

 30                 if (chars > count)

 31                         chars = count;

 32                 if (chars > size)

 33                         chars = size;

 34                 count -= chars;

 35                 read += chars;

    // ����sizeָ��ܵ�βָ�봦����������ǰ�ܵ�βָ�루ǰ��chars�ֽڣ�����βָ�볬��

    // �ܵ�ĩ�����ƻء�Ȼ�󽫹ܵ��е����ݸ��Ƶ��û��������С����ڹܵ�i�ڵ㣬��i_size

    // �ֶ����ǹܵ������ָ�롣

 36                 size = PIPE_TAIL(*inode);

 37                 PIPE_TAIL(*inode) += chars;

 38                 PIPE_TAIL(*inode) &= (PAGE_SIZE-1);

 39                 while (chars-->0)

 40                         put_fs_byte(((char *)inode->i_size)[size++],buf++);

 41         }

    // ���˴ζ��ܵ��������������ѵȴ��ùܵ��Ľ��̣������ض�ȡ���ֽ�����

 42         wake_up(& PIPE_WRITE_WAIT(*inode));

 43         return read;

 44 }

 45        

    //// �ܵ�д����������

    // ����inode�ǹܵ���Ӧ��i�ڵ㣬buf�����ݻ�����ָ�룬count�ǽ�д��ܵ����ֽ�����

 46 int write_pipe(struct m_inode * inode, char * buf, int count)

 47 {

 48         int chars, size, written = 0;

 49

    // ���Ҫд����ֽ���count������0����ô���Ǿ�ѭ��ִ�����²�������ѭ�����������У�

    // �����ǰ�ܵ����Ѿ����ˣ����пռ� size = 0�������ѵȴ��ùܵ��Ľ��̣�ͨ������

    // ���Ƕ��ܵ����̡� �����û�ж��ܵ��ߣ���i�ڵ����ü���ֵС��2������ǰ���̷���

    // SIGPIPE�źţ���������д����ֽ����˳�����д��0�ֽڣ��򷵻� -1�������õ�ǰ����

    // �ڸùܵ���˯�ߣ��Եȴ����ܵ���������ȡ���ݣ��Ӷ��ùܵ��ڳ��ռ䡣��PIPE_SIZE()��

    // PIPE_HEAD()�ȶ������ļ�include/linux/fs.h�С�

 50         while (count>0) {

 51                 while (!(size=(PAGE_SIZE-1)-PIPE_SIZE(*inode))) {

 52                         wake_up(& PIPE_READ_WAIT(*inode));

 53                         if (inode->i_count != 2) { /* no readers */

 54                                 current->signal |= (1<<(SIGPIPE-1));

 55                                 return written?written:-1;

 56                         }

 57                         sleep_on(& PIPE_WRITE_WAIT(*inode));

 58                 }

    // ����ִ�е������ʾ�ܵ����������п�д�ռ�size����������ȡ�ܵ�ͷָ�뵽������ĩ�˿�

    // ���ֽ���chars��д�ܵ������Ǵӹܵ�ͷָ�봦��ʼд�ġ����chars���ڻ���Ҫд����ֽ�

    // ��count����������� count�� ��� chars���ڵ�ǰ�ܵ��п��пռ䳤��size�����������

    // size��Ȼ�����Ҫд���ֽ���count��ȥ�˴ο�д����ֽ���chars������д���ֽ����ۼӵ�

    // written�С�

 59                 chars = PAGE_SIZE-PIPE_HEAD(*inode);

 60                 if (chars > count)

 61                         chars = count;

 62                 if (chars > size)

 63                         chars = size;

 64                 count -= chars;

 65                 written += chars;

    // ����sizeָ��ܵ�����ͷָ�봦����������ǰ�ܵ�����ͷ��ָ�루ǰ��chars�ֽڣ�����ͷ

    // ָ�볬���ܵ�ĩ�����ƻء�Ȼ����û�����������chars���ֽڵ��ܵ�ͷָ�뿪ʼ���� ����

    // �ܵ�i�ڵ㣬��i_size�ֶ����ǹܵ������ָ�롣

 66                 size = PIPE_HEAD(*inode);

 67                 PIPE_HEAD(*inode) += chars;

 68                 PIPE_HEAD(*inode) &= (PAGE_SIZE-1);

 69                 while (chars-->0)

 70                         ((char *)inode->i_size)[size++]=get_fs_byte(buf++);

 71         }

    // ���˴�д�ܵ��������������ѵȴ��ܵ��Ľ��̣�������д����ֽ������˳���

 72         wake_up(& PIPE_READ_WAIT(*inode));

 73         return written;

 74 }

 75

    //// �����ܵ�ϵͳ���á�

    // ��fildes��ָ�������д���һ���ļ��������������������ļ����ָ��һ�ܵ�i�ڵ㡣

    // ������filedes -�ļ�������顣fildes[0]���ڶ��ܵ����ݣ�fildes[1]��ܵ�д�����ݡ�

    // �ɹ�ʱ����0������ʱ����-1��

 76 int sys_pipe(unsigned long * fildes)

 77 {

 78         struct m_inode * inode;

 79         struct file * f[2];                     // �ļ��ṹ���顣

 80         int fd[2];                              // �ļ�������顣

 81         int i,j;

 82

    // ���ȴ�ϵͳ�ļ�����ȡ������������ü����ֶ�Ϊ0��������ֱ��������ü���Ϊ1��

    // ��ֻ��1����������ͷŸ�����ü�����λ������û���ҵ�����������򷵻� -1��

 83         j=0;

 84         for(i=0;j<2 && i<NR_FILE;i++)

 85                 if (!file_table[i].f_count)

 86                         (f[j++]=i+file_table)->f_count++;

 87         if (j==1)

 88                 f[0]->f_count=0;

 89         if (j<2)

 90                 return -1;

    // �������ȡ�õ������ļ����ṹ��ֱ����һ�ļ�����ţ���ʹ�����ļ��ṹָ�������

    // ����ֱ�ָ���������ļ��ṹ�����ļ�������Ǹ�����������š����Ƶأ����ֻ��һ����

    // ���ļ���������ͷŸþ�����ÿ���Ӧ����������û���ҵ��������о�������ͷ�����

    // ��ȡ�������ļ��ṹ���λ���ü���ֵ���������� -1��

 91         j=0;

 92         for(i=0;j<2 && i<NR_OPEN;i++)

 93                 if (!current->filp[i]) {

 94                         current->filp[ fd[j]=i ] = f[j];

 95                         j++;

 96                 }

 97         if (j==1)

 98                 current->filp[fd[0]]=NULL;

 99         if (j<2) {

100                 f[0]->f_count=f[1]->f_count=0;

101                 return -1;

102         }

    // Ȼ�����ú���get_pipe_inode()����һ���ܵ�ʹ�õ�i�ڵ㣬��Ϊ�ܵ�����һҳ�ڴ���Ϊ��

    // ������������ɹ�������Ӧ�ͷ������ļ�������ļ��ṹ�������-1��

103         if (!(inode=get_pipe_inode())) {          // fs/inode.c����231�п�ʼ����

104                 current->filp[fd[0]] =

105                         current->filp[fd[1]] = NULL;

106                 f[0]->f_count = f[1]->f_count = 0;

107                 return -1;

108         }

   // ����ܵ�i�ڵ�����ɹ�����������ļ��ṹ���г�ʼ�������������Ƕ�ָ��ͬһ���ܵ�i��

   // �㣬���Ѷ�дָ�붼���㡣��1���ļ��ṹ���ļ�ģʽ��Ϊ������2���ļ��ṹ���ļ�ģʽ��

   // Ϊд������ļ�������鸴�Ƶ���Ӧ���û��ռ������У��ɹ�����0���˳���

109         f[0]->f_inode = f[1]->f_inode = inode;

110         f[0]->f_pos = f[1]->f_pos = 0;

111         f[0]->f_mode = 1;               /* read */

112         f[1]->f_mode = 2;               /* write */

113         put_fs_long(fd[0],0+fildes);

114         put_fs_long(fd[1],1+fildes);

115         return 0;

116 }

117

    //// �ܵ�io���ƺ�����

    // ������pino - �ܵ�i�ڵ�ָ�룻cmd - �������arg - ������

    // ��������0��ʾִ�гɹ������򷵻س����롣

118 int pipe_ioctl(struct m_inode *pino, int cmd, int arg)

119 {

    // ���������ȡ�ܵ��е�ǰ�ɶ����ݳ��ȣ���ѹܵ����ݳ���ֵ�����û�����ָ����λ�ô���

    // ������0�����򷵻���Ч��������롣

120         switch (cmd) {

121                 case FIONREAD:

122                         verify_area((void *) arg,4);

123                         put_fs_long(PIPE_SIZE(*pino),(unsigned long *) arg);

124                         return 0;

125                 default:

126                         return -EINVAL;

127         }

128 }

129


 


 

12.11 ����12-11 linux/fs/char_dev.c


  1 /*

  2  *  linux/fs/char_dev.c

  3  *

  4  *  (C) 1991  Linus Torvalds

  5  */

  6

  7 #include <errno.h>        // �����ͷ�ļ�������ϵͳ�и��ֳ����š�

  8 #include <sys/types.h>    // ����ͷ�ļ��������˻�����ϵͳ�������͡�

  9

 10 #include <linux/sched.h>  // ���ȳ���ͷ�ļ�����������ṹtask_struct������0���ݵȡ�

 11 #include <linux/kernel.h> // �ں�ͷ�ļ�������һЩ�ں˳��ú�����ԭ�ζ��塣

 12

 13 #include <asm/segment.h>  // �β���ͷ�ļ����������йضμĴ���������Ƕ��ʽ��ຯ����

 14 #include <asm/io.h>       // ioͷ�ļ�������Ӳ���˿�����/���������䡣

 15

 16 extern int tty_read(unsigned minor,char * buf,int count);     // �ն˶���

 17 extern int tty_write(unsigned minor,char * buf,int count);    // �ն�д��

 18

    // �����ַ��豸��д����ָ�����͡�

 19 typedef (*crw_ptr)(int rw,unsigned minor,char * buf,int count,off_t * pos);

 20

    //// �����ն˶�д����������

    // ������rw - ��д���minor - �ն����豸�ţ�buf - ��������cout - ��д�ֽ�����

    // pos - ��д������ǰָ�룬�����ն˲�������ָ�����á�

    // ���أ�ʵ�ʶ�д���ֽ�������ʧ���򷵻س����롣

 21 static int rw_ttyx(int rw,unsigned minor,char * buf,int count,off_t * pos)

 22 {

 23         return ((rw==READ)?tty_read(minor,buf,count):

 24                 tty_write(minor,buf,count));

 25 }

 26

    //// �ն˶�д����������

    // ͬ��rw_ttyx()��ֻ�������˶Խ����Ƿ��п����ն˵ļ�⡣

 27 static int rw_tty(int rw,unsigned minor,char * buf,int count, off_t * pos)

 28 {

    // ������û�ж�Ӧ�Ŀ����նˣ��򷵻س����š���������ն˶�д����rw_ttyx()��������

    // ʵ�ʶ�д�ֽ�����

 29         if (current->tty<0)

 30                 return -EPERM;

 31         return rw_ttyx(rw,current->tty,buf,count,pos);

 32 }

 33

    //// �ڴ����ݶ�д��δʵ�֡�

 34 static int rw_ram(int rw,char * buf, int count, off_t *pos)

 35 {

 36         return -EIO;

 37 }

 38

    //// �����ڴ����ݶ�д����������δʵ�֡�

 39 static int rw_mem(int rw,char * buf, int count, off_t * pos)

 40 {

 41         return -EIO;

 42 }

 43

    //// �ں������ڴ����ݶ�д������δʵ�֡�

 44 static int rw_kmem(int rw,char * buf, int count, off_t * pos)

 45 {

 46         return -EIO;

 47 }

 48

    // �˿ڶ�д����������

    // ������rw - ��д���buf - ��������cout - ��д�ֽ�����pos - �˿ڵ�ַ��

    // ���أ�ʵ�ʶ�д���ֽ�����

 49 static int rw_port(int rw,char * buf, int count, off_t * pos)

 50 {

 51         int i=*pos;

 52

    // ������Ҫ���д���ֽ��������Ҷ˿ڵ�ַС��64kʱ��ѭ��ִ�е����ֽڵĶ�д������

    // ���Ƕ������Ӷ˿�i�ж�ȡһ�ֽ����ݲ��ŵ��û��������С�����д��������

    // �����ݻ�������ȡһ�ֽ�������˿�i��

 53         while (count-->0 && i<65536) {

 54                 if (rw==READ)

 55                         put_fs_byte(inb(i),buf++);

 56                 else

 57                         outb(get_fs_byte(buf++),i);

 58                 i++;                               // ǰ��һ���˿ڡ�[??]

 59         }

    // Ȼ������/д���ֽ�����������Ӧ��дָ�룬�����ض�/д���ֽ�����

 60         i -= *pos;

 61         *pos += i;

 62         return i;

 63 }

 64

    //// �ڴ��д�����������ڴ����豸����1�������������0-5���豸�Ĵ�����

 65 static int rw_memory(int rw, unsigned minor, char * buf, int count, off_t * pos)

 66 {

    // �����ڴ��豸���豸�ţ��ֱ���ò�ͬ���ڴ��д������

 67         switch(minor) {

 68                 case 0:        // ��Ӧ�豸�ļ����� /dev/ram0��/dev/ramdisk��

 69                         return rw_ram(rw,buf,count,pos);

 70                 case 1:        // /dev/ram1��/dev/mem��ram��

 71                         return rw_mem(rw,buf,count,pos);

 72                 case 2:        // /dev/ram2��/dev/kmem��

 73                         return rw_kmem(rw,buf,count,pos);

 74                 case 3:        // /dev/null��

 75                         return (rw==READ)?0:count;      /* rw_null */

 76                 case 4:        // /dev/port��

 77                         return rw_port(rw,buf,count,pos);

 78                 default:

 79                         return -EIO;

 80         }

 81 }

 82

    // ����ϵͳ���豸������

 83 #define NRDEVS ((sizeof (crw_table))/(sizeof (crw_ptr)))

 84

    // �ַ��豸��д����ָ�����

 85 static crw_ptr crw_table[]={

 86         NULL,           /* nodev */             /* ���豸(���豸) */

 87         rw_memory,      /* /dev/mem etc */      /* /dev/mem�� */

 88         NULL,           /* /dev/fd */           /* /dev/fd���� */

 89         NULL,           /* /dev/hd */           /* /dev/hdӲ�� */

 90         rw_ttyx,        /* /dev/ttyx */         /* /dev/ttyx�����ն� */

 91         rw_tty,         /* /dev/tty */          /* /dev/tty�ն� */

 92         NULL,           /* /dev/lp */           /* /dev/lp��ӡ�� */

 93         NULL};          /* unnamed pipes */     /* δ�����ܵ� */

 94

    //// �ַ��豸��д����������

    // ������rw -��д���dev -�豸�ţ�buf -��������count -��д�ֽ�����pos -��дָ�롣

    // ���أ�ʵ�ʶ�/д�ֽ�����

 95 int rw_char(int rw,int dev, char * buf, int count, off_t * pos)

 96 {

 97         crw_ptr call_addr;

 98

    // ����豸�ų���ϵͳ�豸�����򷵻س����롣������豸û�ж�Ӧ�Ķ�/д������Ҳ���س�

    // ���롣������ö�Ӧ�豸�Ķ�д����������������ʵ�ʶ�/д���ֽ�����

 99         if (MAJOR(dev)>=NRDEVS)

100                 return -ENODEV;

101         if (!(call_addr=crw_table[MAJOR(dev)]))

102                 return -ENODEV;

103         return call_addr(rw,MINOR(dev),buf,count,pos);

104 }

105


 


 

12.12 ����12-12 linux/fs/read_write.c


  1 /*

  2  *  linux/fs/read_write.c

  3  *

  4  *  (C) 1991  Linus Torvalds

  5  */

  6

  7 #include <sys/stat.h>     // �ļ�״̬ͷ�ļ��������ļ����ļ�ϵͳ״̬�ṹstat{}�ͳ�����

  8 #include <errno.h>        // �����ͷ�ļ�������ϵͳ�и��ֳ����š�

  9 #include <sys/types.h>    // ����ͷ�ļ��������˻�����ϵͳ�������͡�

 10

 11 #include <linux/kernel.h> // �ں�ͷ�ļ�������һЩ�ں˳��ú�����ԭ�ζ��塣

 12 #include <linux/sched.h>  // ���ȳ���ͷ�ļ�����������ṹtask_struct������0���ݵȡ�

 13 #include <asm/segment.h>  // �β���ͷ�ļ����������йضμĴ���������Ƕ��ʽ��ຯ����

 14

    // �ַ��豸��д������fs/char_dev.c����95�С�

 15 extern int rw_char(int rw,int dev, char * buf, int count, off_t * pos);

    // ���ܵ�����������fs/pipe.c����13�С�

 16 extern int read_pipe(struct m_inode * inode, char * buf, int count);

    // д�ܵ�����������fs/pipe.c����41�С�

 17 extern int write_pipe(struct m_inode * inode, char * buf, int count);

    // ���豸������������fs/block_dev.c����47�С�

 18 extern int block_read(int dev, off_t * pos, char * buf, int count);

    // ���豸д����������fs/block_dev.c����14�С�

 19 extern int block_write(int dev, off_t * pos, char * buf, int count);

    // ���ļ�����������fs/file_dev.c����17�С�

 20 extern int file_read(struct m_inode * inode, struct file * filp,

 21                 char * buf, int count);

    // д�ļ�����������fs/file_dev.c����48�С�

 22 extern int file_write(struct m_inode * inode, struct file * filp,

 23                 char * buf, int count);

 24

    //// �ض�λ�ļ���дָ��ϵͳ���á�

    // ����fd���ļ������offset���µ��ļ���дָ��ƫ��ֵ��origin��ƫ�Ƶ���ʼλ�ã�����

    // ����ѡ��SEEK_SET��0�����ļ���ʼ������SEEK_CUR��1���ӵ�ǰ��дλ�ã���SEEK_END��

    // 2�����ļ�β������

 25 int sys_lseek(unsigned int fd,off_t offset, int origin)

 26 {

 27         struct file * file;

 28         int tmp;

 29

    // �����жϺ����ṩ�IJ�����Ч�ԡ�����ļ����ֵ���ڳ��������ļ���NR_OPEN(20)��

    // ���߸þ�����ļ��ṹָ��Ϊ�գ����߶�Ӧ�ļ��ṹ��i�ڵ��ֶ�Ϊ�գ�����ָ���豸�ļ�

    // ָ���Dz��ɶ�λ�ģ��򷵻س����벢�˳�������ļ���Ӧ��i�ڵ��ǹܵ��ڵ㣬�򷵻س���

    // ���˳�����Ϊ�ܵ�ͷβָ�벻�������ƶ���

 30         if (fd >= NR_OPEN || !(file=current->filp[fd]) || !(file->f_inode)

 31            || !IS_SEEKABLE(MAJOR(file->f_inode->i_dev)))

 32                 return -EBADF;

 33         if (file->f_inode->i_pipe)

 34                 return -ESPIPE;

    // Ȼ��������õĶ�λ��־���ֱ����¶�λ�ļ���дָ�롣

 35         switch (origin) {

    // origin = SEEK_SET��Ҫ�����ļ���ʼ����Ϊԭ�������ļ���дָ�롣��ƫ��ֵС���㣬���

    // �����ش����롣���������ļ���дָ�����offset��

 36                 case 0:

 37                         if (offset<0) return -EINVAL;

 38                         file->f_pos=offset;

 39                         break;

    // origin = SEEK_CUR��Ҫ�����ļ���ǰ��дָ�봦��Ϊԭ���ض�λ��дָ�롣����ļ���ǰָ

    // �����ƫ��ֵС��0���򷵻س������˳��������ڵ�ǰ��дָ���ϼ���ƫ��ֵ��

 40                 case 1:

 41                         if (file->f_pos+offset<0) return -EINVAL;

 42                         file->f_pos += offset;

 43                         break;

    // origin = SEEK_END��Ҫ�����ļ�ĩβ��Ϊԭ���ض�λ��дָ�롣��ʱ���ļ���С����ƫ��ֵ

    // С�����򷵻س������˳��������ض�λ��дָ��Ϊ�ļ����ȼ���ƫ��ֵ��

 44                 case 2:

 45                         if ((tmp=file->f_inode->i_size+offset) < 0)

 46                                 return -EINVAL;

 47                         file->f_pos = tmp;

 48                         break;

    // ��origin ������Ч�����س������˳���

 49                 default:

 50                         return -EINVAL;

 51         }

 52         return file->f_pos;                 // ��󷵻��ض�λ����ļ���дָ��ֵ��

 53 }

 54

    //// ���ļ�ϵͳ���á�

    // ����fd���ļ������buf�ǻ�������count�������ֽ�����

 55 int sys_read(unsigned int fd,char * buf,int count)

 56 {

 57         struct file * file;

 58         struct m_inode * inode;

 59

    // �������ȶԲ�����Ч�Խ����жϡ�����ļ����ֵ���ڳ��������ļ���NR_OPEN������

    // ��Ҫ��ȡ���ֽڼ���ֵС��0�����߸þ�����ļ��ṹָ��Ϊ�գ��򷵻س����벢�˳�����

    // ���ȡ���ֽ���count����0���򷵻�0�˳�

 60         if (fd>=NR_OPEN || count<0 || !(file=current->filp[fd]))

 61                 return -EINVAL;

 62         if (!count)

 63                 return 0;

    // Ȼ����֤������ݵĻ������ڴ����ơ���ȡ�ļ���i�ڵ㡣���ڸ��ݸ�i�ڵ�����ԣ��ֱ�

    // ������Ӧ�Ķ��������������ǹܵ��ļ��������Ƕ��ܵ��ļ�ģʽ������ж��ܵ�����������

    // ���򷵻ض�ȡ���ֽ��������򷵻س����룬�˳���������ַ����ļ�������ж��ַ��豸��

    // ���������ض�ȡ���ַ���������ǿ��豸�ļ�����ִ�п��豸�������������ض�ȡ���ֽ�����

 64         verify_area(buf,count);

 65         inode = file->f_inode;

 66         if (inode->i_pipe)

 67                 return (file->f_mode&1)?read_pipe(inode,buf,count):-EIO;

 68         if (S_ISCHR(inode->i_mode))

 69                 return rw_char(READ,inode->i_zone[0],buf,count,&file->f_pos);

 70         if (S_ISBLK(inode->i_mode))

 71                 return block_read(inode->i_zone[0],&file->f_pos,buf,count);

    // �����Ŀ¼�ļ������dz����ļ�����������֤��ȡ�ֽ���count����Ч�Բ����е���������

    // ȡ�ֽ��������ļ���ǰ��дָ��ֵ�����ļ����ȣ����������ö�ȡ�ֽ���Ϊ �ļ�����-��ǰ

    // ��дָ��ֵ������ȡ������0���򷵻�0�˳�����Ȼ��ִ���ļ������������ض�ȡ���ֽ���

    // ���˳���

 72         if (S_ISDIR(inode->i_mode) || S_ISREG(inode->i_mode)) {

 73                 if (count+file->f_pos > inode->i_size)

 74                         count = inode->i_size - file->f_pos;

 75                 if (count<=0)

 76                         return 0;

 77                 return file_read(inode,file,buf,count);

 78         }

    // ִ�е����˵�������޷��ж��ļ������ԡ����ӡ�ڵ��ļ����ԣ������س������˳���

 79         printk("(Read)inode->i_mode=%06o\n\r",inode->i_mode);

 80         return -EINVAL;

 81 }

 82

    //// д�ļ�ϵͳ���á�

    // ����fd���ļ������buf���û���������count����д�ֽ�����

 83 int sys_write(unsigned int fd,char * buf,int count)

 84 {

 85         struct file * file;

 86         struct m_inode * inode;

 87        

    // ͬ���أ����������жϺ�����������Ч�ԡ���������ļ����ֵ���ڳ��������ļ���

    // NR_OPEN��������Ҫд����ֽڼ���С��0�����߸þ�����ļ��ṹָ��Ϊ�գ��򷵻س���

    // �벢�˳���������ȡ���ֽ���count����0���򷵻�0�˳�

 88         if (fd>=NR_OPEN || count <0 || !(file=current->filp[fd]))

 89                 return -EINVAL;

 90         if (!count)

 91                 return 0;

    // Ȼ����֤������ݵĻ������ڴ����ơ���ȡ�ļ���i�ڵ㡣���ڸ��ݸ�i�ڵ�����ԣ��ֱ�

    // ������Ӧ�Ķ��������������ǹܵ��ļ���������д�ܵ��ļ�ģʽ�������д�ܵ�����������

    // ���򷵻�д����ֽ��������򷵻س������˳���������ַ��豸�ļ��������д�ַ��豸��

    // ��������д����ַ����˳�������ǿ��豸�ļ�������п��豸д������������д����ֽ�

    // ���˳������dz����ļ�����ִ���ļ�д������������д����ֽ������˳���

 92         inode=file->f_inode;

 93         if (inode->i_pipe)

 94                 return (file->f_mode&2)?write_pipe(inode,buf,count):-EIO;

 95         if (S_ISCHR(inode->i_mode))

 96                 return rw_char(WRITE,inode->i_zone[0],buf,count,&file->f_pos);

 97         if (S_ISBLK(inode->i_mode))

 98                 return block_write(inode->i_zone[0],&file->f_pos,buf,count);

 99         if (S_ISREG(inode->i_mode))

100                 return file_write(inode,file,buf,count);

    // ִ�е����˵�������޷��ж��ļ������ԡ����ӡ�ڵ��ļ����ԣ������س������˳���

101         printk("(Write)inode->i_mode=%06o\n\r",inode->i_mode);

102         return -EINVAL;

103 }

104


 


 

12.13 ����12-13 linux/fs/open.c


  1 /*

  2  *  linux/fs/open.c

  3  *

  4  *  (C) 1991  Linus Torvalds

  5  */

  6

  7 #include <string.h>       // �ַ���ͷ�ļ�����Ҫ������һЩ�й��ַ���������Ƕ�뺯����

  8 #include <errno.h>        // �����ͷ�ļ�������ϵͳ�и��ֳ����š�

  9 #include <fcntl.h>        // �ļ�����ͷ�ļ��������ļ������������������Ƴ������Ŷ��塣

 10 #include <sys/types.h>    // ����ͷ�ļ������������ϵͳ���ļ�ϵͳͳ����Ϣ�ṹ�����͡�

 11 #include <utime.h>        // �û�ʱ��ͷ�ļ���������ʺ��޸�ʱ��ṹ�Լ�utime()ԭ�͡�

 12 #include <sys/stat.h>     // �ļ�״̬ͷ�ļ��������ļ�״̬�ṹstat{}�ͷ��ų����ȡ�

 13

 14 #include <linux/sched.h>  // ���ȳ���ͷ�ļ�����������ṹtask_struct������0���ݵȡ�

 15 #include <linux/tty.h>    // ttyͷ�ļ����������й�tty_io������ͨ�ŷ���IJ�����������

 16 #include <linux/kernel.h> // �ں�ͷ�ļ�������һЩ�ں˳��ú�����ԭ�ζ��塣

 17

 18 #include <asm/segment.h>  // �β���ͷ�ļ����������йضμĴ���������Ƕ��ʽ��ຯ����

 19

    //// ȡ�ļ�ϵͳ��Ϣ��

    // ����dev�Ǻ����Ѱ�װ�ļ�ϵͳ���豸�š�ubuf��һ��ustat�ṹ������ָ�룬���ڴ��

    // ϵͳ���ص��ļ�ϵͳ��Ϣ����ϵͳ�������ڷ����Ѱ�װ��mounted���ļ�ϵͳ��ͳ����Ϣ��

    // �ɹ�ʱ����0������ubufָ���ustate�ṹ�������ļ�ϵͳ�ܿ��п����Ϳ���i�ڵ�����

    // ustat�ṹ������include/sys/types.h�С�

 20 int sys_ustat(int dev, struct ustat * ubuf)

 21 {

 22         return -ENOSYS;                // �����룺���ܻ�δʵ�֡�

 23 }

 24

    //// �����ļ����ʺ��޸�ʱ�䡣

    // ����filename���ļ�����times�Ƿ��ʺ��޸�ʱ��ṹָ�롣

    // ���timesָ�벻ΪNULL����ȡutimbuf�ṹ�е�ʱ����Ϣ�������ļ��ķ��ʺ��޸�ʱ�䡣

    // ���timesָ����NULL����ȡϵͳ��ǰʱ��������ָ���ļ��ķ��ʺ��޸�ʱ����

 25 int sys_utime(char * filename, struct utimbuf * times)

 26 {

 27         struct m_inode * inode;

 28         long actime,modtime;

 29

    // �ļ���ʱ����Ϣ��������i�ڵ��ӡ�����������ȸ����ļ���ȡ�ö�Ӧi�ڵ㡣���û����

    // �����򷵻س����롣����ṩ�ķ��ʺ��޸�ʱ��ṹָ��times��ΪNULL����ӽṹ�ж�ȡ

    // �û����õ�ʱ��ֵ���������ϵͳ��ǰʱ���������ļ��ķ��ʺ��޸�ʱ�䡣

 30         if (!(inode=namei(filename)))

 31                 return -ENOENT;

 32         if (times) {

 33                 actime = get_fs_long((unsigned long *) &times->actime);

 34                 modtime = get_fs_long((unsigned long *) &times->modtime);

 35         } else

 36                 actime = modtime = CURRENT_TIME;

    // Ȼ���޸�i�ڵ��еķ���ʱ���ֶκ��޸�ʱ���ֶΡ�������i�ڵ����޸ı�־���Żظ�i��

    // �㣬������0��

 37         inode->i_atime = actime;

 38         inode->i_mtime = modtime;

 39         inode->i_dirt = 1;

 40         iput(inode);

 41         return 0;

 42 }

 43

 44 /*

 45  * XXX should we use the real or effective uid?  BSD uses the real uid,

 46  * so as to make this call useful to setuid programs.

 47  */

    /*

     * XXX ���Ǹ�����ʵ�û�id��ruid��������Ч�û�id��euid����BSDϵͳʹ����

     * ��ʵ�û�id����ʹ�õ��ÿ��Թ�setuid����ʹ�á�

     * ��ע��POSIX��׼����ʹ����ʵ�û�ID����

     * ��ע1��Ӣ��ע�Ϳ�ʼ�� 'XXX' ��ʾ��Ҫ��ʾ����

     */

    //// ����ļ��ķ���Ȩ�ޡ�

    // ����filename���ļ�����mode�Ǽ��ķ������ԣ�����3����Ч����λ��ɣ�R_OK(ֵ4)��

    // W_OK(2)��X_OK(1) ��F_OK(0) ��ɣ��ֱ��ʾ����ļ��Ƿ�ɶ�����д����ִ�к��ļ���

    // ����ڡ�������������Ļ����򷵻�0�����򷵻س����롣

 48 int sys_access(const char * filename,int mode)

 49 {

 50         struct m_inode * inode;

 51         int res, i_mode;

 52

    // �ļ��ķ���Ȩ����ϢҲͬ���������ļ���i�ڵ�ṹ�У��������Ҫ��ȡ�ö�Ӧ�ļ�����i

    // �ڵ㡣���ķ�������mode�ɵ�3λ��ɣ������Ҫ���ϰ˽���0007��������и߱���λ��

    // ����ļ�����Ӧ��i�ڵ㲻���ڣ��򷵻�û������Ȩ�޳����롣��i�ڵ���ڣ���ȡi�ڵ�

    // ���ļ������룬���Żظ�i�ڵ㡣���⣬57������䡰iput(inode);��������61��֮��

 53         mode &= 0007;

 54         if (!(inode=namei(filename)))

 55                 return -EACCES;                    // �����룺�޷���Ȩ�ޡ�

 56         i_mode = res = inode->i_mode & 0777;

 57         iput(inode);

    // �����ǰ�����û��Ǹ��ļ�����������ȡ�ļ��������ԡ����������ǰ�����û�����ļ���

    // ��ͬ��һ�飬��ȡ�ļ������ԡ����򣬴�ʱres���3�����������˷��ʸ��ļ����������ԡ�

    // [[?? ����Ӧres >>3 ??]

 58         if (current->uid == inode->i_uid)

 59                 res >>= 6;

 60         else if (current->gid == inode->i_gid)

 61                 res >>= 6;

    // ��ʱres�����3�����Ǹ��ݵ�ǰ�����û����ļ��Ĺ�ϵѡ������ķ�������λ����������

    // ���ж���3���ء�����ļ����Ծ��в�������ѯ������λmode����������ɣ�����0

 62         if ((res & 0007 & mode) == mode)

 63                 return 0;

 64         /*

 65          * XXX we are doing this test last because we really should be

 66          * swapping the effective with the real user id (temporarily),

 67          * and then calling suser() routine.  If we do call the

 68          * suser() routine, it needs to be called last.

 69          */

            /*

             * XXX ��������������IJ��ԣ���Ϊ����ʵ������Ҫ������Ч�û�ID��

             * ��ʵ�û�ID����ʱ�أ���Ȼ��ŵ���suser()�������������ȷʵҪ����

             * suser()����������Ҫ���ű����á�

             */

    // �����ǰ�û�IDΪ0�������û�������������ִ��λ��0�����ļ����Ա��κ���ִ�С���

    // �����򷵻�0�����򷵻س����롣

 70         if ((!current->uid) &&

 71             (!(mode & 1) || (i_mode & 0111)))

 72                 return 0;

 73         return -EACCES;                           // �����룺�޷���Ȩ�ޡ�

 74 }

 75

    //// �ı䵱ǰ����Ŀ¼ϵͳ���á�

    // ����filename��Ŀ¼����

    // �����ɹ��򷵻�0�����򷵻س����롣

 76 int sys_chdir(const char * filename)

 77 {

 78         struct m_inode * inode;

 79

    // �ı䵱ǰ����Ŀ¼����Ҫ��ѽ�������ṹ�ĵ�ǰ����Ŀ¼�ֶ�ָ�����Ŀ¼����i�ڵ㡣

    // �����������ȡĿ¼����i�ڵ㡣���Ŀ¼����Ӧ��i�ڵ㲻���ڣ��򷵻س����롣�����

    // i�ڵ㲻��һ��Ŀ¼i�ڵ㣬��Żظ�i�ڵ㣬�����س����롣

 80         if (!(inode = namei(filename)))

 81                 return -ENOENT;                    // �����룺�ļ���Ŀ¼�����ڡ�

 82         if (!S_ISDIR(inode->i_mode)) {

 83                 iput(inode);

 84                 return -ENOTDIR;                   // �����룺����Ŀ¼����

 85         }

    // Ȼ���ͷŽ���ԭ����Ŀ¼i�ڵ㣬��ʹ��ָ�������õĹ���Ŀ¼i�ڵ㡣����0��

 86         iput(current->pwd);

 87         current->pwd = inode;

 88         return (0);

 89 }

 90

    //// �ı��Ŀ¼ϵͳ���á�

    // ��ָ����Ŀ¼�����ó�Ϊ��ǰ���̵ĸ�Ŀ¼'/'��

    // ��������ɹ��򷵻�0�����򷵻س����롣

 91 int sys_chroot(const char * filename)

 92 {

 93         struct m_inode * inode;

 94

    // �õ������ڸı䵱ǰ��������ṹ�еĸ�Ŀ¼�ֶ�root������ָ���������Ŀ¼����i�ڵ㡣

    // ���Ŀ¼����Ӧ��i�ڵ㲻���ڣ��򷵻س����롣�����i�ڵ㲻��Ŀ¼i�ڵ㣬��Żظ�

    // i�ڵ㣬Ҳ���س����롣

 95         if (!(inode=namei(filename)))

 96                 return -ENOENT;

 97         if (!S_ISDIR(inode->i_mode)) {

 98                 iput(inode);

 99                 return -ENOTDIR;

100         }

    // Ȼ���ͷŵ�ǰ���̵ĸ�Ŀ¼i�ڵ㣬����������Ϊָ��Ŀ¼����i�ڵ㣬����0��

101         iput(current->root);

102         current->root = inode;

103         return (0);

104 }

105

    //// �޸��ļ�����ϵͳ���á�

    // ����filename���ļ�����mode���µ��ļ����ԡ�

    // �������ɹ��򷵻�0�����򷵻س����롣

106 int sys_chmod(const char * filename,int mode)

107 {

108         struct m_inode * inode;

109

    // �õ���Ϊָ���ļ������µķ�������mode���ļ��ķ����������ļ�����Ӧ��i�ڵ��У����

    // ��������ȡ�ļ�����Ӧ��i�ڵ㡣���i�ڵ㲻���ڣ��򷵻س����루�ļ���Ŀ¼�����ڣ���

    // �����ǰ���̵���Ч�û�id���ļ�i�ڵ���û�id��ͬ������Ҳ���dz����û�����Żظ�

    // �ļ�i�ڵ㣬���س����루û�з���Ȩ�ޣ���

110         if (!(inode=namei(filename)))

111                 return -ENOENT;

112         if ((current->euid != inode->i_uid) && !suser()) {

113                 iput(inode);

114                 return -EACCES;

115         }

    // ������������ø�i�ڵ���ļ����ԣ����ø�i�ڵ����޸ı�־���Żظ�i�ڵ㣬����0��

116         inode->i_mode = (mode & 07777) | (inode->i_mode & ~07777);

117         inode->i_dirt = 1;

118         iput(inode);

119         return 0;

120 }

121

    //// �޸��ļ�����ϵͳ���á�

    // ����filename���ļ�����uid���û���ʶ��(�û�ID)��gid����ID��

    // �������ɹ��򷵻�0�����򷵻س����롣

122 int sys_chown(const char * filename,int uid,int gid)

123 {

124         struct m_inode * inode;

125

    // �õ������������ļ�i�ڵ��е��û�����ID���������Ҫȡ�ø����ļ�����i�ڵ㡣�����

    // ������i�ڵ㲻���ڣ��򷵻س����루�ļ���Ŀ¼�����ڣ��������ǰ���̲��dz����û���

    // ��Żظ�i�ڵ㣬�����س����루û�з���Ȩ�ޣ���

126         if (!(inode=namei(filename)))

127                 return -ENOENT;

128         if (!suser()) {

129                 iput(inode);

130                 return -EACCES;

131         }

    // �������Ǿ��ò����ṩ��ֵ�������ļ�i�ڵ���û�ID����ID������i�ڵ��Ѿ��޸ı�־��

    // �Żظ�i�ڵ㣬����0��

132         inode->i_uid=uid;

133         inode->i_gid=gid;

134         inode->i_dirt=1;

135         iput(inode);

136         return 0;

137 }

138

    //// ����ַ��豸���͡�

    // �ú��������������ļ���ϵͳ����sys_open()�����ڼ�����򿪵��ļ���tty�ն��ַ���

    // ��ʱ����Ҫ�Ե�ǰ���̵����úͶ�tty�������á�

    // ����0��⴦���ɹ�������-1��ʾʧ�ܣ���Ӧ�ַ��豸���ܴ򿪡�

139 static int check_char_dev(struct m_inode * inode, int dev, int flag)

140 {

141         struct tty_struct *tty;

142         int min;                                     // ���豸�š�

143

    // ֻ�������豸����4��/dev/ttyxx�ļ�����5��/dev/tty�ļ����������/dev/tty�����豸

    // ����0�����һ�������п����նˣ������ǽ��̿����ն��豸��ͬ��������/dev/tty�豸��

    // һ�������豸������Ӧ������ʵ��ʹ�õ�/dev/ttyxx�豸֮һ������һ��������˵��������

    // �����նˣ���ô��������ṹ�е�tty�ֶν���4���豸��ijһ�����豸�š�

    // ����򿪲������ļ��� /dev/tty����MAJOR(dev) = 5������ô������min = ��������ṹ

    // �е�tty�ֶΣ���ȡ4���豸�����豸�š���������򿪵���ij��4���豸����ֱ��ȡ����

    // �豸�š�����õ��� 4���豸���豸��С��0����ô˵������û�п����նˣ������豸�Ŵ�

    // ���򷵻� -1����ʾ���ڽ���û�п����նˣ����߲��ܴ�����豸��

144         if (MAJOR(dev) == 4 || MAJOR(dev) == 5) {

145                 if (MAJOR(dev) == 5)

146                         min = current->tty;

147                 else

148                         min = MINOR(dev);

149                 if (min < 0)

150                         return -1;

    // ��α�ն��豸�ļ�ֻ�ܱ����̶�ռʹ�á�������豸�ű�����һ����α�նˣ����Ҹô��ļ�

    // i �ڵ����ü������� 1����˵�����豸�ѱ���������ʹ�á���˲����ٴ򿪸��ַ��豸�ļ���

    // ���Ƿ��� -1������������tty�ṹָ��ttyָ��tty���ж�Ӧ�ṹ������ļ�������

    // ־flag�в�����������ն˱�־O_NOCTTY�����ҽ����ǽ��������죬���ҵ�ǰ����û�п���

    // �նˣ�����tty�ṹ��session�ֶ�Ϊ0����ʾ���ն˻������κν�����Ŀ����նˣ�����ô

    // ������Ϊ������������ն��豸 min Ϊ������նˡ��������ý�������ṹ�ն��豸���ֶ�

    // ttyֵ����min���������ö�Ӧtty�ṹ�ĻỰ��session�ͽ������pgrp�ֱ���ڽ��̵Ļ�

    // ���źͽ�����š�

151                 if ((IS_A_PTY_MASTER(min)) && (inode->i_count>1))

152                         return -1;

153                 tty = TTY_TABLE(min);

154                 if (!(flag & O_NOCTTY) &&

155                     current->leader &&

156                     current->tty<0 &&

157                     tty->session==0) {

158                         current->tty = min;

159                         tty->session= current->session;

160                         tty->pgrp = current->pgrp;

161                 }

    // ������ļ�������־flag�к���O_NONBLOCK������������־����������Ҫ�Ը��ַ��ն�

    // �豸����������ã�����Ϊ�����������Ҫ��ȡ�������ַ���Ϊ0�����ó�ʱ��ʱֵΪ0��

    // �����ն��豸���óɷǹ淶ģʽ����������ʽֻ�ܹ����ڷǹ淶ģʽ���ڴ�ģʽ�µ�VMIN

    // ��VTIME������Ϊ0ʱ�������������ж���֧�����̾Ͷ�ȡ�����ַ��������̷��ء��μ�

    // include/termios.h�ļ����˵����

162                 if (flag & O_NONBLOCK) {

163                         TTY_TABLE(min)->termios.c_cc[VMIN] =0;

164                         TTY_TABLE(min)->termios.c_cc[VTIME] =0;

165                         TTY_TABLE(min)->termios.c_lflag &= ~ICANON;

166                 }

167         }

168         return 0;

169 }

170

    //// �򿪣��򴴽����ļ�ϵͳ���á�

    // ����filename���ļ�����flag�Ǵ��ļ���־������ȡֵ��O_RDONLY��ֻ������O_WRONLY

    // ��ֻд����O_RDWR����д�����Լ�O_CREAT����������O_EXCL���������ļ����벻���ڣ���

    // O_APPEND�����ļ�β�������ݣ�������һЩ��־����ϣ���������ô�����һ�����ļ�����

    // mode������ָ���ļ����������ԡ���Щ������S_IRWXU���ļ��������ж���д��ִ��Ȩ�ޣ���

    // S_IRUSR���û����ж��ļ�Ȩ�ޣ���S_IRWXG�����Ա���ж���д��ִ��Ȩ�ޣ��ȵȡ�������

    // �������ļ�����Щ����ֻӦ���ڽ������ļ��ķ��ʣ�������ֻ���ļ��Ĵ򿪵���Ҳ������һ

    // ���ɶ�д���ļ������������ò����ɹ����򷵻��ļ����(�ļ�������)�����򷵻س����롣

    // �μ�sys/stat.h��fcntl.h��

171 int sys_open(const char * filename,int flag,int mode)

172 {

173         struct m_inode * inode;

174         struct file * f;

175         int i,fd;

176

    // ���ȶԲ������д��������û����õ��ļ�ģʽ�ͽ���ģʽ���������룬�������ɵ��ļ�ģʽ��

    // Ϊ��Ϊ���ļ�����һ���ļ��������Ҫ�������̽ṹ���ļ��ṹָ�����飬�Բ���һ����

    // ����������������fd���Ǿ��ֵ�����Ѿ�û�п�����򷵻س����루������Ч����

177         mode &= 0777 & ~current->umask;

178         for(fd=0 ; fd<NR_OPEN ; fd++)

179                 if (!current->filp[fd])                       // �ҵ������

180                         break;

181         if (fd>=NR_OPEN)

182                 return -EINVAL;

    // Ȼ���������õ�ǰ���̵�ִ��ʱ�ر��ļ������close_on_exec��λͼ����λ��Ӧ�ı���λ��

    // close_on_exec ��һ�����������ļ������λͼ��־��ÿ������λ����һ�����ŵ��ļ���

    // ����������ȷ���ڵ���ϵͳ���� execve()ʱ��Ҫ�رյ��ļ������������ʹ�� fork()����

    // ������һ���ӽ���ʱ��ͨ�����ڸ��ӽ����е���execve()��������ִ����һ���³��򡣴�ʱ

    // �ӽ����п�ʼִ���³�����һ���ļ������close_on_exec�еĶ�Ӧ����λ����λ����ô

    // ��ִ��execve()ʱ�ö�Ӧ�ļ���������رգ�������ļ������ʼ�մ��ڴ�״̬������

    // һ���ļ�ʱ��Ĭ��������ļ�������ӽ�����Ҳ���ڴ�״̬���������Ҫ��λ��Ӧ����λ��

    // Ȼ��Ϊ���ļ����ļ�����Ѱ��һ�����нṹ�������fָ���ļ������鿪ʼ����������

    // ���ļ��ṹ����ü���Ϊ0��������Ѿ�û�п����ļ����ṹ��򷵻س����롣���⣬

    // ��184���ϵ�ָ�븳ֵ "0+file_table " ��ͬ�� "file_table" �� "&file_table[0]"��

    // ��������д���ܸ�������һЩ��

183         current->close_on_exec &= ~(1<<fd);

184         f=0+file_table;

185         for (i=0 ; i<NR_FILE ; i++,f++)

186                 if (!f->f_count) break;

187         if (i>=NR_FILE)

188                 return -EINVAL;

    // ��ʱ�����ý��̶�Ӧ�ļ����fd���ļ��ṹָ��ָ�����������ļ��ṹ�������ļ����ü���

    // ����1��Ȼ����ú���open_namei()ִ�д򿪲�����������ֵС��0����˵�������������ͷ�

    // �����뵽���ļ��ṹ�����س�����i�����ļ��򿪲����ɹ�����inode���Ѵ��ļ���i�ڵ�

    // ָ�롣

189         (current->filp[fd]=f)->f_count++;

190         if ((i=open_namei(filename,flag,mode,&inode))<0) {

191                 current->filp[fd]=NULL;

192                 f->f_count=0;

193                 return i;

194         }

    // �����Ѵ��ļ�i�ڵ�������ֶΣ����ǿ���֪���ļ������͡����ڲ�ͬ���͵��ļ�������

    // ��Ҫ��һЩ�ر����� ����򿪵����ַ��豸�ļ�����ô���Ǿ�Ҫ����check_char_dev()

    // ��������鵱ǰ�����Ƿ��ܴ�����ַ��豸�ļ��������������������0������ô��

    // check_char_dev()�л���ݾ����ļ��򿪱�־Ϊ�������ÿ����նˡ� �����������

    // ʹ�ø��ַ��豸�ļ�����ô����ֻ���ͷ�����������ļ���;����Դ�����س����롣

195 /* ttys are somewhat special (ttyxx major==4, tty major==5) */

    /* ttys��Щ���⣨ttyxx�����豸��==4��tty�����豸��==5��*/

196         if (S_ISCHR(inode->i_mode))

197                 if (check_char_dev(inode,inode->i_zone[0],flag)) {

198                         iput(inode);

199                         current->filp[fd]=NULL;

200                         f->f_count=0;

201                         return -EAGAIN;          // �����ţ���Դ��ʱ�����á�

202                 }

    // ����򿪵��ǿ��豸�ļ���������Ƭ�Ƿ��������������������Ҫ�ø��ٻ������и��豸

    // �����л����ʧЧ��

203 /* Likewise with block-devices: check for floppy_change */

    /* ͬ�����ڿ��豸�ļ�����Ҫ�����Ƭ�Ƿ񱻸��� */

204         if (S_ISBLK(inode->i_mode))

205                 check_disk_change(inode->i_zone[0]);

    // �������dz�ʼ�����ļ����ļ��ṹ�������ļ��ṹ���Ժͱ�־���þ�����ü���Ϊ1����

    // ����i�ڵ��ֶ�Ϊ���ļ���i�ڵ㣬��ʼ���ļ���дָ��Ϊ0����󷵻��ļ�����š�

206         f->f_mode = inode->i_mode;

207         f->f_flags = flag;

208         f->f_count = 1;

209         f->f_inode = inode;

210         f->f_pos = 0;

211         return (fd);

212 }

213

    //// �����ļ�ϵͳ���á�

    // ����pathname��·������mode�������sys_open()������ͬ��

    // �ɹ��򷵻��ļ���������򷵻س����롣

214 int sys_creat(const char * pathname, int mode)

215 {

216         return sys_open(pathname, O_CREAT | O_TRUNC, mode);

217 }

218

    // �ر��ļ�ϵͳ���á�

    // ����fd���ļ������

    // �ɹ��򷵻�0�����򷵻س����롣

219 int sys_close(unsigned int fd)

220 {      

221         struct file * filp;

222

    // ���ȼ�������Ч�ԡ����������ļ����ֵ���ڳ���ͬʱ�ܴ򿪵��ļ���NR_OPEN���򷵻�

    // �����루������Ч����Ȼ��λ���̵�ִ��ʱ�ر��ļ����λͼ��Ӧλ�������ļ������Ӧ

    // ���ļ��ṹָ����NULL���򷵻س����롣

223         if (fd >= NR_OPEN)

224                 return -EINVAL;

225         current->close_on_exec &= ~(1<<fd);

226         if (!(filp = current->filp[fd]))

227                 return -EINVAL;

    // �����ø��ļ�������ļ��ṹָ��ΪNULL�����ڹر��ļ�֮ǰ����Ӧ�ļ��ṹ�еľ������

    // �����Ѿ�Ϊ0����˵���ں˳�����ͣ�������򽫶�Ӧ�ļ��ṹ�����ü�����1����ʱ�������

    // ��Ϊ0����˵����������������ʹ�ø��ļ������Ƿ���0���ɹ�����������ü����ѵ���0��

    // ˵�����ļ��Ѿ�û�н������ã����ļ��ṹ�ѱ�Ϊ���С����ͷŸ��ļ�i�ڵ㣬����0��

228         current->filp[fd] = NULL;

229         if (filp->f_count == 0)

230                 panic("Close: file count is 0");

231         if (--filp->f_count)

232                 return (0);

233         iput(filp->f_inode);

234         return (0);

235 }

236


 


 

12.14 ����12-14 linux/fs/exec.c


  1 /*

  2  *  linux/fs/exec.c

  3  *

  4  *  (C) 1991  Linus Torvalds

  5  */

  6

  7 /*

  8  * #!-checking implemented by tytso.

  9  */

    /*

     * #!��ʼ�Ľű�����ļ����벿������tytsoʵ�ֵġ�

     */

 10

 11 /*

 12  * Demand-loading implemented 01.12.91 - no need to read anything but

 13  * the header into memory. The inode of the executable is put into

 14  * "current->executable", and page faults do the actual loading. Clean.

 15  *

 16  * Once more I can proudly say that linux stood up to being changed: it

 17  * was less than 2 hours work to get demand-loading completely implemented.

 18  */

    /*

     * ����ʱ����ʵ����1991.12.1 - ֻ�轫ִ���ļ�ͷ�������ڴ�����뽫����

     * ִ���ļ������ؽ��ڴ档ִ���ļ���i�ڵ㱻���ڵ�ǰ���̵Ŀ�ִ���ֶ���

     * "current->executable"��ҳ�쳣�����ִ���ļ���ʵ�ʼ��ز��������������

     *

     * �ҿ�����һ���Ժ���˵��linux�������޸ģ�ֻ���˲���2Сʱ�Ĺ���ʱ���

     * ��ȫʵ����������ش�����

     */

 19

 20 #include <signal.h>       // �ź�ͷ�ļ��������źŷ��ų������źŽṹ���źŲ�������ԭ�͡�

 21 #include <errno.h>        // �����ͷ�ļ�������ϵͳ�и��ֳ����š�

 22 #include <string.h>       // �ַ���ͷ�ļ�����Ҫ������һЩ�й��ַ���������Ƕ�뺯����

 23 #include <sys/stat.h>     // �ļ�״̬ͷ�ļ��������ļ�״̬�ṹstat{}�ͷ��ų����ȡ�

 24 #include <a.out.h>        // a.outͷ�ļ���������a.outִ���ļ���ʽ��һЩ�ꡣ

 25

 26 #include <linux/fs.h>     // �ļ�ϵͳͷ�ļ��������ļ����ṹ��file��m_inode���ȡ�

 27 #include <linux/sched.h>  // ���ȳ���ͷ�ļ�������������ṹtask_struct������0���ݵȡ�

 28 #include <linux/kernel.h> // �ں�ͷ�ļ�������һЩ�ں˳��ú�����ԭ�ζ��塣

 29 #include <linux/mm.h>     // �ڴ����ͷ�ļ�������ҳ���С�����һЩҳ���ͷź���ԭ�͡�

 30 #include <asm/segment.h>  // �β���ͷ�ļ����������йضμĴ���������Ƕ��ʽ��ຯ����

 31

 32 extern int sys_exit(int exit_code);     // �˳�����ϵͳ���á�

 33 extern int sys_close(int fd);           // �ر��ļ�ϵͳ���á�

 34

 35 /*

 36  * MAX_ARG_PAGES defines the number of pages allocated for arguments

 37  * and envelope for the new program. 32 should suffice, this gives

 38  * a maximum env+arg of 128kB !

 39  */

    /*

     * MAX_ARG_PAGES������Ϊ�³������ĸ������ͻ�������ʹ�õ�����ڴ�ҳ����

     * 32ҳ�ڴ�Ӧ���㹻�ˣ���ʹ�û����Ͳ�����env+arg���ռ���ܺʹﵽ128kB!

     */

 

 40 #define MAX_ARG_PAGES 32

 41

    //// ʹ�ÿ��ļ�ϵͳ���á�

    // ������library - ���ļ�����

    // Ϊ����ѡ��һ�����ļ������滻���̵�ǰ���ļ�i�ڵ��ֶ�ֵΪ����ָ�����ļ�����i�ڵ�

    // ָ�롣���libraryָ��Ϊ�գ���ѽ��̵�ǰ�Ŀ��ļ��ͷŵ���

    // ���أ��ɹ�����0�����򷵻س����롣

 42 int sys_uselib(const char * library)

 43 {

 44         struct m_inode * inode;

 45         unsigned long base;

 46

    // �����жϵ�ǰ�����Ƿ���ͨ���̡�����ͨ���鿴��ǰ���̵Ŀռ䳤���������ġ���Ϊ��ͨ��

    // �̵Ŀռ䳤�ȱ�����ΪTASK_SIZE��64MB��������������߼���ַ�ռ䳤�Ȳ�����TASK_SIZE

    // �򷵻س����루��Ч������������ȡ���ļ�i�ڵ�inode�������ļ���ָ��գ�������inode

    // ����NULL��

 47         if (get_limit(0x17) != TASK_SIZE)

 48                 return -EINVAL;

 49         if (library) {

 50                 if (!(inode=namei(library)))            /* get library inode */

 51                         return -ENOENT;                 /* ȡ���ļ�i�ڵ� */

 52         } else

 53                 inode = NULL;

 54 /* we should check filetypes (headers etc), but we don't */

    /* ����Ӧ�ü��һ���ļ����ͣ���ͷ����Ϣ�ȣ����������ǻ�û���������� */

    // Ȼ��Żؽ���ԭ���ļ�i�ڵ㣬��Ԥ�ý��̿�i�ڵ��ֶ�Ϊ�ա�����ȡ�ý��̵Ŀ��������

    // λ�ã����ͷ�ԭ������ҳ������ռ�õ��ڴ�ҳ�档����ý��̿�i�ڵ��ֶ�ָ���¿�i��

    // �㣬������0���ɹ�����

 55         iput(current->library);

 56         current->library = NULL;

 57         base = get_base(current->ldt[2]);

 58         base += LIBRARY_OFFSET;

 59         free_page_tables(base,LIBRARY_SIZE);

 60         current->library = inode;

 61         return 0;

 62 }

 63

 64 /*

 65  * create_tables() parses the env- and arg-strings in new user

 66  * memory and creates the pointer tables from them, and puts their

 67  * addresses on the "stack", returning the new stack pointer value.

 68  */

    /*

     * create_tables()�������������ڴ��н������������Ͳ����ַ������ɴ�

     * ����ָ������������ǵĵ�ַ�ŵ�"ջ"�ϣ�Ȼ�󷵻���ջ��ָ��ֵ��

     */

    //// ��������ջ�д��������ͻ�������ָ�����

    // ������p -���ݶ��в����ͻ�����Ϣƫ��ָ�룻argc - ����������envc - ��������������

    // ���أ�ջָ��ֵ��

 69 static unsigned long * create_tables(char * p,int argc,int envc)

 70 {

 71         unsigned long *argv,*envp;

 72         unsigned long * sp;

 73

    // ջָ������4�ֽڣ�1�ڣ�Ϊ�߽����Ѱַ�ģ������������ spΪ4��������ֵ����ʱsp

    // λ�ڲ�����������ĩ�ˡ�Ȼ�������Ȱ�sp ���£��͵�ַ�����ƶ�����ջ�пճ���������

    // ָ��ռ�õĿռ䣬���û�������ָ��envp ָ��ô�����ճ���һ��λ�������������һ

    // ��NULLֵ������ָ���1��sp������ָ������ֽ�ֵ��4�ֽڣ����ٰ�sp�����ƶ����ճ�

    // �����в���ָ��ռ�õĿռ䣬����argv ָ��ָ��ô���ͬ������մ���һ��λ�����ڴ��

    // һ��NULLֵ����ʱspָ�����ָ������ʼ�������ǽ�����������ָ��envp�������в�

    // ����ָ���Լ������в�������ֵ�ֱ�ѹ��ջ�С�

 74         sp = (unsigned long *) (0xfffffffc & (unsigned long) p);

 75         sp -= envc+1;                              // ��sp = sp - (envc+1);

 76         envp = sp;

 77         sp -= argc+1;

 78         argv = sp;

 79         put_fs_long((unsigned long)envp,--sp);

 80         put_fs_long((unsigned long)argv,--sp);

 81         put_fs_long((unsigned long)argc,--sp);

    // �ٽ������и�����ָ��ͻ���������ָ��ֱ����ǰ��ճ�������Ӧ�ط������ֱ����һ

    // ��NULLָ�롣

 82         while (argc-->0) {

 83                 put_fs_long((unsigned long) p,argv++);

 84                 while (get_fs_byte(p++)) /* nothing */ ; // pָ��ָ����һ����������

 85         }

 86         put_fs_long(0,argv);

 87         while (envc-->0) {

 88                 put_fs_long((unsigned long) p,envp++);

 89                 while (get_fs_byte(p++)) /* nothing */ ; // pָ��ָ����һ����������

 90         }

 91         put_fs_long(0,envp);

 92         return sp;                         // ���ع���ĵ�ǰ��ջָ�롣

 93 }

 94

 95 /*

 96  * count() counts the number of arguments/envelopes

 97  */

    /*

     * count()�������������в���/���������ĸ�����

     */

    //// �������������

    // ������argv - ����ָ�����飬���һ��ָ������NULL��

    // ͳ�Ʋ���ָ��������ָ��ĸ��������ں�����������ָ���ָ������ã���μ�����

    // kernel/sched.c�е�171��ǰ��ע�͡�

    // ���أ�����������

 98 static int count(char ** argv)

 99 {

100         int i=0;

101         char ** tmp;

102

103         if (tmp = argv)

104                 while (get_fs_long((unsigned long *) (tmp++)))

105                         i++;

106

107         return i;

108 }

109

110 /*

111  * 'copy_string()' copies argument/envelope strings from user

112  * memory to free pages in kernel mem. These are in a format ready

113  * to be put directly into the top of new user memory.

114  *

115  * Modified by TYT, 11/24/91 to add the from_kmem argument, which specifies

116  * whether the string and the string array are from user or kernel segments:

117  *

118  * from_kmem     argv *        argv **

119  *    0          user space    user space

120  *    1          kernel space  user space

121  *    2          kernel space  kernel space

122  *

123  * We do this by playing games with the fs segment register.  Since it

124  * it is expensive to load a segment register, we try to avoid calling

125  * set_fs() unless we absolutely have to.

126  */

    /*

     * 'copy_string()'�������û��ڴ�ռ俽������/�����ַ������ں˿���ҳ���С�

     * ��Щ�Ѿ���ֱ�ӷŵ����û��ڴ��еĸ�ʽ��

     *

     * ��TYT(Tytso)��1991.11.24���޸ģ�������from_kmem�������ò���ָ����

     * �ַ������ַ��������������û��λ����ں˶Ρ�

     *

     * from_kmem   ָ��argv *    �ַ��� argv **

     *    0         �û��ռ�      �û��ռ�

     *    1         �ں˿ռ�      �û��ռ�

     *    2         �ں˿ռ�      �ں˿ռ�

     *

     * ������ͨ�������fs�μĴ����������ġ����ڼ���һ���μĴ�������̫�ߣ�

     * �������Ǿ����������set_fs()������ʵ�ڱ�Ҫ��

     */

    //// ����ָ�������IJ����ַ����������ͻ����ռ��С�

    // ������argc - �����ӵIJ���������argv - ����ָ�����飻page - �����ͻ����ռ�ҳ��ָ��

    // ���顣p -�������ռ���ƫ��ָ�룬ʼ��ָ���Ѹ��ƴ���ͷ����from_kmem -�ַ�����Դ��־��

    // �� do_execve()�����У�p��ʼ��Ϊָ�������(128kB)�ռ�����һ�����ִ��������ַ���

    // ���Զ�ջ������ʽ���������и��ƴ�ŵġ���� pָ������Ÿ�����Ϣ�����Ӷ��𽥼�С��

    // ��ʼ��ָ������ַ�����ͷ�����ַ�����Դ��־from_kmemӦ����TYTΪ�˸�execve()����

    // ִ�нű��ļ��Ĺ��ܶ��¼ӵIJ�������û�����нű��ļ��Ĺ���ʱ�����в����ַ���������

    // �����ݿռ��С�

    // ���أ������ͻ����ռ䵱ǰͷ��ָ�롣�������򷵻�0��

127 static unsigned long copy_strings(int argc,char ** argv,unsigned long *page,

128                 unsigned long p, int from_kmem)

129 {

130         char *tmp, *pag;

131         int len, offset = 0;

132         unsigned long old_fs, new_fs;

133

    // ����ȡ��ǰ�μĴ���ds��ָ���ں����ݶΣ���fsֵ���ֱ𱣴浽����new_fs��old_fs�С�

    // ����ַ������ַ������飨ָ�룩�����ں˿ռ䣬������fs�μĴ���ָ���ں����ݶΡ�

134         if (!p)

135                 return 0;       /* bullet-proofing */  /* ƫ��ָ����֤ */

136         new_fs = get_ds();

137         old_fs = get_fs();

138         if (from_kmem==2)           // ��������ָ�����ں˿ռ�������fsָ���ں˿ռ䡣

139                 set_fs(new_fs);

    // Ȼ��ѭ���������������������һ����������ʼ���ƣ����Ƶ�ָ��ƫ�Ƶ�ַ������ѭ���У�

    // ����ȡ��Ҫ���Ƶĵ�ǰ�ַ���ָ�롣����ַ������û��ռ���ַ������飨�ַ���ָ�룩��

    // �ں˿ռ䣬������fs�μĴ���ָ���ں����ݶΣ�ds���������ں����ݿռ���ȡ���ַ���ָ��

    // tmp֮������ָ̻�fs�μĴ���ԭֵ��fs��ָ���û��ռ䣩���������޸�fsֵ��ֱ�Ӵ�

    // �û��ռ�ȡ�ַ���ָ�뵽tmp��

140         while (argc-- > 0) {

141                 if (from_kmem == 1)      // ����ָ�����ں˿ռ䣬��fsָ���ں˿ռ䡣

142                         set_fs(new_fs);

143                 if (!(tmp = (char *)get_fs_long(((unsigned long *)argv)+argc)))

144                         panic("argc is wrong");

145                 if (from_kmem == 1)      // ����ָ�����ں˿ռ䣬��fsָ���û��ռ䡣

146                         set_fs(old_fs);

    // Ȼ����û��ռ�ȡ���ַ�����������ò����ַ�������len�� �˺�tmpָ����ַ���ĩ�ˡ�

    // ������ַ������ȳ�����ʱ�����ͻ����ռ��л�ʣ��Ŀ��г��ȣ���ռ䲻���ˡ����ǻָ�

    // fs�μĴ���ֵ��������ı�Ļ���������0��������Ϊ�����ͻ����ռ�����128KB������ͨ

    // �������ܷ������������

147                 len=0;                         /* remember zero-padding */

148                 do {                           /* ����֪��������NULL�ֽڽ�β�� */

149                         len++;

150                 } while (get_fs_byte(tmp++));

151                 if (p-len < 0) {               /* this shouldn't happen - 128kB */

152                         set_fs(old_fs);        /* ���ᷢ��-��Ϊ��128kB�Ŀռ� */

153                         return 0;

154                 }

    // ����������������ַ��ذ��ַ������Ƶ������ͻ����ռ�ĩ�˴�����ѭ�������ַ������ַ�

    // �����У���������Ҫ�жϲ����ͻ����ռ�����Ӧλ�ô��Ƿ��Ѿ����ڴ�ҳ�档�����û�о�

    // ��Ϊ������1ҳ�ڴ�ҳ�档ƫ����offset������Ϊ��һ��ҳ���еĵ�ǰָ��ƫ��ֵ�� ��Ϊ

    // �տ�ʼִ�б�����ʱ��ƫ�Ʊ���offset����ʼ��Ϊ0������(offset-1 < 0)�϶�������ʹ��

    // offset���±�����Ϊ��ǰpָ����ҳ�淶Χ�ڵ�ƫ��ֵ��

155                 while (len) {

156                         --p; --tmp; --len;

157                         if (--offset < 0) {

158                                 offset = p % PAGE_SIZE;

159                                 if (from_kmem==2) // �������ں˿ռ���fsָ���û��ռ䡣

160                                         set_fs(old_fs);

    // �����ǰƫ��ֵp���ڵĴ��ռ�ҳ��ָ�������� page[p/PAGE_SIZE] ==0����ʾ��ʱpָ��

    // �����Ŀռ��ڴ�ҳ�滹�����ڣ���������һ�����ڴ�ҳ��������ҳ��ָ������ָ�����飬ͬ

    // ʱҲʹҳ��ָ��pagָ�����ҳ�档�����벻������ҳ���򷵻�0��

161                                 if (!(pag = (char *) page[p/PAGE_SIZE]) &&

162                                     !(pag = (char *) page[p/PAGE_SIZE] =

163                                       (unsigned long *) get_free_page()))

164                                         return 0;

165                                 if (from_kmem==2) // �������ں˿ռ���fsָ���ں˿ռ䡣

166                                         set_fs(new_fs);

167

168                         }

    // Ȼ���fs���и����ַ�����1�ֽڵ������ͻ����ռ��ڴ�ҳ��pag��offset����

169                         *(pag + offset) = get_fs_byte(tmp);

170                 }

171         }

    // ����ַ������ַ����������ں˿ռ䣬��ָ�fs�μĴ���ԭֵ����󣬷��ز����ͻ�����

    // �����Ѹ��Ʋ�����ͷ��ƫ��ֵ��

172         if (from_kmem==2)

173                 set_fs(old_fs);

174         return p;

175 }

176

    //// �޸�����ľֲ������������ݡ�

    // �޸ľֲ���������LDT���������Ķλ�ַ�Ͷ��޳������������ͻ����ռ�ҳ����������ݶ�

    // ĩ�ˡ�

    // ������text_size - ִ���ļ�ͷ����a_text�ֶθ����Ĵ���γ���ֵ��

    // page - �����ͻ����ռ�ҳ��ָ�����顣

    // ���أ����ݶ��޳�ֵ��64MB����

177 static unsigned long change_ldt(unsigned long text_size,unsigned long * page)

178 {

179         unsigned long code_limit,data_limit,code_base,data_base;

180         int i;

181

    // ���ȰѴ�������ݶγ��Ⱦ�����Ϊ64MB�� Ȼ��ȡ��ǰ���ֲ̾���������������������д�

    // ��λ�ַ������λ�ַ�����ݶλ�ַ��ͬ����ʹ����Щ��ֵ�������þֲ����д���κ�����

    // ���������еĻ�ַ�Ͷ��޳���������ע�⣬���ڱ����ص��³���Ĵ�������ݶλ�ַ��ԭ��

    // �����ͬ�����û�б�Ҫ���ظ�ȥ�������ǣ�����186��188���ϵ��������öλ�ַ�����

    // ���࣬��ʡ�ԡ�

182         code_limit = TASK_SIZE;

183         data_limit = TASK_SIZE;

184         code_base = get_base(current->ldt[1]);  // include/linux/sched.h����226�С�

185         data_base = code_base;

186         set_base(current->ldt[1],code_base);

187         set_limit(current->ldt[1],code_limit);

188         set_base(current->ldt[2],data_base);

189         set_limit(current->ldt[2],data_limit);

190 /* make sure fs points to the NEW data segment */

    /* Ҫȷ��fs�μĴ�����ָ���µ����ݶ� */

    // fs�μĴ����з���ֲ������ݶ���������ѡ���(0x17)����Ĭ�������fs��ָ���������ݶΡ�

191         __asm__("pushl $0x17\n\tpop %%fs"::);

    // Ȼ�󽫲����ͻ����ռ��Ѵ�����ݵ�ҳ�棨�����MAX_ARG_PAGESҳ��128kB���ŵ����ݶ�ĩ

    // �ˡ� �����Ǵӽ��̿ռ�����λ�ÿ�ʼ������һҳһҳ�طš����ļ�����ռ�ý��̿ռ����

    // 4MB������put_dirty_page()���ڰ�����ҳ��ӳ�䵽�����߼��ռ��С���mm/memory.c�С�

192         data_base += data_limit - LIBRARY_SIZE;

193         for (i=MAX_ARG_PAGES-1 ; i>=0 ; i--) {

194                 data_base -= PAGE_SIZE;

195                 if (page[i])                           // ����ҳ����ڣ��ͷ��ø�ҳ�档

196                         put_dirty_page(page[i],data_base);

197         }

198         return data_limit;                             // ��󷵻����ݶ��޳���64MB����

199 }

200

201 /*

202  * 'do_execve()' executes a new program.

203  *

204  * NOTE! We leave 4MB free at the top of the data-area for a loadable

205  * library.

206  */

    /*

     * 'do_execve()'����ִ��һ���³���

     */

    //// execve()ϵͳ�жϵ��ú��������ز�ִ���ӽ��̣��������򣩡�

    // �ú�����ϵͳ�жϵ��ã�int 0x80�����ܺ�__NR_execve���õĺ����������IJ����ǽ���ϵͳ

    // ���ô������̺�ֱ�����ñ�ϵͳ���ô������̣�system_call.s��200�У��͵��ñ�����֮ǰ

    // ��system_call.s����203�У���ѹ��ջ�е�ֵ����Щֵ������

    // �� ��86--88����ѵ�edx��ecx��ebx�Ĵ���ֵ���ֱ��Ӧ**envp��**argv��*filename��

    // �� ��94�е���sys_call_table��sys_execve������ָ�룩ʱѹ��ջ�ĺ������ص�ַ��tmp����

    // �� ��202���ڵ��ñ�����do_execveǰ��ջ��ָ��ջ�е���ϵͳ�жϵij������ָ��eip��

    // ������

    // eip - ����ϵͳ�жϵij������ָ�룬�μ�kernel/system_call.s����ʼ���ֵ�˵����

    // tmp - ϵͳ�ж����ڵ���_sys_execveʱ�ķ��ص�ַ�����ã�

    // filename - ��ִ�г����ļ���ָ�룻

    // argv - �����в���ָ�������ָ�룻

    // envp - ��������ָ�������ָ�롣

    // ���أ�������óɹ����򲻷��أ��������ó����ţ�������-1��

207 int do_execve(unsigned long * eip,long tmp,char * filename,

208         char ** argv, char ** envp)

209 {

210         struct m_inode * inode;

211         struct buffer_head * bh;

212         struct exec ex;

213         unsigned long page[MAX_ARG_PAGES];         // �����ͻ������ռ�ҳ��ָ�����顣

214         int i,argc,envc;

215         int e_uid, e_gid;                          // ��Ч�û�ID����Ч��ID��

216         int retval;

217         int sh_bang = 0;                           // �����Ƿ���Ҫִ�нű�����

218         unsigned long p=PAGE_SIZE*MAX_ARG_PAGES-4; // pָ������ͻ����ռ����󲿡�

219

    // ����ʽ����ִ���ļ������л���֮ǰ���������ȸ�Щ���¡��ں�׼����128KB��32��ҳ�棩

    // �ռ�����Ż�ִ���ļ��������в����ͻ����ַ��������а�p��ʼ���ó�λ��128KB�ռ��

    // ���1�����ִ����ڳ�ʼ�����ͻ����ռ�IJ��������У�p������ָ����128KB�ռ��еĵ�

    // ǰλ�á�

    // ���⣬����eip[1]�ǵ��ñ���ϵͳ���õ�ԭ�û��������μĴ���CSֵ�����еĶ�ѡ���

    // ��Ȼ�����ǵ�ǰ����Ĵ����ѡ�����0x000f���������Ǹ�ֵ����ô CSֻ�ܻ����ں˴���

    // �ε�ѡ��� 0x0008�� �����Ǿ��Բ������ģ���Ϊ�ں˴����dz�פ�ڴ�����ܱ��滻���ġ�

    // ����������eip[1] ��ֵȷ���Ƿ�������������Ȼ���ٳ�ʼ��128KB�IJ����ͻ�������

    // �䣬�������ֽ����㣬��ȡ��ִ���ļ���i�ڵ㡣�ٸ��ݺ��������ֱ����������в�����

    // �����ַ����ĸ���argc��envc�����⣬ִ���ļ������dz����ļ���

220         if ((0xffff & eip[1]) != 0x000f)

221                 panic("execve called from supervisor mode");

222         for (i=0 ; i<MAX_ARG_PAGES ; i++)       /* clear page-table */

223                 page[i]=0;

224         if (!(inode=namei(filename)))           /* get executables inode */

225                 return -ENOENT;

226         argc = count(argv);                     // �����в���������

227         envc = count(envp);                     // �����ַ�������������

228        

229 restart_interp:

230         if (!S_ISREG(inode->i_mode)) {    /* must be regular file */

231                 retval = -EACCES;

232                 goto exec_error2;        //�����dz����ļ����ó����룬��ת��376�С�

233         }

    // �����鵱ǰ�����Ƿ���Ȩ����ָ����ִ���ļ���������ִ���ļ�i�ڵ��е����ԣ�������

    // �����Ƿ���Ȩִ�������ڰ�ִ���ļ�i�ڵ�������ֶ�ֵȡ��i�к��������Ȳ鿴������

    // �Ƿ������ˡ�����-�û�-ID����set-user_id����־ �͡�����-��-ID����set-group-id����

    // ־����������־��Ҫ����һ���û��ܹ�ִ����Ȩ�û����糬���û�root���ij�������ı�

    // ����ij���passwd�ȡ����set-user-id��־��λ�������ִ�н��̵���Ч�û�ID��euid��

    // �����ó�ִ���ļ����û�ID���������óɵ�ǰ���̵�euid�����ִ���ļ�set-group-id��

    // ��λ�Ļ�����ִ�н��̵���Ч��ID��egid��������Ϊִ���ļ�����ID���������óɵ�ǰ����

    // ��egid��������ʱ���������жϳ�����ֵ�����ڱ���e_uid��e_gid�С�

234         i = inode->i_mode;

235         e_uid = (i & S_ISUID) ? inode->i_uid : current->euid;

236         e_gid = (i & S_ISGID) ? inode->i_gid : current->egid;

 

    // ���ڸ��ݽ��̵�euid��egid��ִ���ļ��ķ������Խ��бȽϡ����ִ���ļ��������н���

    // ���û�������ļ�����ֵi����6λ����ʱ�����3λ���ļ������ķ���Ȩ�ޱ�־�������

    // �����ִ���ļ��뵱ǰ���̵��û�����ͬ�飬��ʹ����ֵ���3λ��ִ���ļ����û��ķ���

    // Ȩ�ޱ�־�������ʱ���������3λ���������û����ʸ�ִ���ļ���Ȩ�ޡ�

    // Ȼ�����Ǹ���������i�����3����ֵ���жϵ�ǰ�����Ƿ���Ȩ���������ִ���ļ������

    // ѡ������Ӧ�û�û�����и��ļ���Ȩ����λ0��ִ��Ȩ�ޣ������������û�Ҳû���κ�Ȩ��

    // ���ߵ�ǰ�����û����dz����û����������ǰ����û��Ȩ���������ִ���ļ��������ò���

    // ִ�г����룬����ת��exec_error2��ȥ���˳�������

237         if (current->euid == inode->i_uid)

238                 i >>= 6;

239         else if (in_group_p(inode->i_gid))

240                 i >>= 3;

241         if (!(i & 1) &&

242             !((inode->i_mode & 0111) && suser())) {

243                 retval = -ENOEXEC;

244                 goto exec_error2;

245         }

    // ����ִ�е����˵����ǰ����������ָ��ִ���ļ���Ȩ�ޡ���˴����↑ʼ������Ҫȡ��

    // ִ���ļ�ͷ�����ݲ��������е���Ϣ�������������л���������������һ��shell������ִ

    // �нű��������ȶ�ȡִ���ļ���1�����ݵ����ٻ�����С� �����ƻ�������ݵ�ex�С�

    // ���ִ���ļ���ʼ�������ֽ����ַ�'#!'����˵��ִ���ļ���һ���ű��ı��ļ����������

    // �нű��ļ������Ǿ���Ҫִ�нű��ļ��Ľ��ͳ�������shell���򣩡�ͨ���ű��ļ��ĵ�

    // һ���ı�Ϊ��#��/bin/bash������ָ�������нű��ļ���Ҫ�Ľ��ͳ������з����Ǵӽű�

    // �ļ���1�У����ַ�'#!'����ȡ�����еĽ��ͳ�����������IJ��������еĻ�����Ȼ����

    // Щ�����ͽű��ļ����Ž�ִ���ļ�����ʱ�ǽ��ͳ��򣩵������в����ռ��С�����֮ǰ����

    // ��Ȼ��Ҫ�ȰѺ���ָ����ԭ�������в����ͻ����ַ����ŵ�128KB�ռ��У������ィ������

    // �������в�����ŵ�����ǰ��λ�ô�����Ϊ��������ã���������ں�ִ�нű��ļ��Ľ���

    // ����������������úý��ͳ���Ľű��ļ����Ȳ�����ȡ�����ͳ����i�ڵ㲢��ת��

    // 229��ȥִ�н��ͳ�������������Ҫ��ת��ִ�й��Ĵ���229��ȥ�����������ȷ�ϲ���

    // ���˽ű��ļ�֮����Ҫ����һ����ֹ�ٴ�ִ������Ľű����������־sh_bang ���ں����

    // �����иñ�־Ҳ������ʾ�����Ѿ����ú�ִ���ļ��������в�������Ҫ�ظ����á�

246         if (!(bh = bread(inode->i_dev,inode->i_zone[0]))) {

247                 retval = -EACCES;

248                 goto exec_error2;

249         }

250         ex = *((struct exec *) bh->b_data);     /* read exec-header */

251         if ((bh->b_data[0] == '#') && (bh->b_data[1] == '!') && (!sh_bang)) {

252                 /*

253                  * This section does the #! interpretation.

254                  * Sorta complicated, but hopefully it will work.  -TYT

255                  */

                    /*

                     * �ⲿ�ִ�����'#!'�Ľ��ͣ���Щ���ӣ���ϣ���ܹ�����-TYT

                     */

256

257                 char buf[128], *cp, *interp, *i_name, *i_arg;

258                 unsigned long old_fs;

259

    // �����↑ʼ�����Ǵӽű��ļ�����ȡ���ͳ�����������������ѽ��ͳ����������ͳ���IJ���

    // �ͽű��ļ�����Ϸ��뻷���������С����ȸ��ƽű��ļ�ͷ1���ַ�'#!'������ַ�����buf

    // �У����к��нű����ͳ�����������/bin/sh����Ҳ���ܻ��������ͳ���ļ���������Ȼ���

    // buf�е����ݽ��д�����ɾ����ʼ�Ŀո��Ʊ�����

260                 strncpy(buf, bh->b_data+2, 127);

261                 brelse(bh);

262                 iput(inode);                     // �ͷŻ���鲢�Żؽű��ļ�i�ڵ㡣

263                 buf[127] = '\0';

264                 if (cp = strchr(buf, '\n')) {

265                         *cp = '\0';       // ��1�����з�����NULL��ȥ���ո��Ʊ�����

266                         for (cp = buf; (*cp == ' ') || (*cp == '\t'); cp++);

267                 }

268                 if (!cp || *cp == '\0') {        // ������û���������ݣ��������

269                         retval = -ENOEXEC;       /* No interpreter name found */

270                         goto exec_error1;        /* û���ҵ��ű����ͳ����� */

271                 }

    // ��ʱ���ǵõ��˿�ͷ�ǽű����ͳ�������һ�����ݣ��ַ�����������������С�����ȡ��һ��

    // �ַ�������Ӧ���ǽ��ͳ���������ʱi_nameָ������ơ������ͳ����������ַ���������Ӧ

    // ���ǽ��ͳ���IJ�������������i_argָ��ô���

272                 interp = i_name = cp;

273                 i_arg = 0;

274                 for ( ; *cp && (*cp != ' ') && (*cp != '\t'); cp++) {

275                         if (*cp == '/')

276                                 i_name = cp+1;

277                 }

278                 if (*cp) {

279                         *cp++ = '\0';            // ���ͳ�����β����NULL�ַ���

280                         i_arg = cp;              // i_argָ����ͳ��������

281                 }

282                 /*

283                  * OK, we've parsed out the interpreter name and

284                  * (optional) argument.

285                  */

                    /*

                     * OK�������Ѿ����������ͳ�����ļ����Լ�(��ѡ��)������

                     */

    // ��������Ҫ��������������Ľ��ͳ�����i_name �������i_arg �ͽű��ļ�����Ϊ���ͳ�

    // ��IJ����Ž������Ͳ������С���������������Ҫ�Ѻ����ṩ��ԭ��һЩ�����ͻ����ַ���

    // �ȷŽ�ȥ��Ȼ���ٷ�������������ġ�������������в�����˵�����ԭ���IJ�����"-arg1

    //  -arg2"�����ͳ�������"bash"���������"-iarg1 -iarg2"���ű��ļ�������ԭ����ִ����

    // ��������"example.sh"����ô�ڷ�������IJ���֮���µ�������������������

    //         ��bash -iarg1 -iarg2 example.sh -arg1 -arg2��

    // �������ǰ�sh_bang��־���ϣ�Ȼ��Ѻ��������ṩ��ԭ�в����ͻ����ַ������뵽�ռ��С�

    // �����ַ����Ͳ��������ֱ���envc ��argc-1�����ٸ��Ƶ�һ��ԭ�в�����ԭ����ִ���ļ�

    // ����������Ľű��ļ�����[[?? ���Կ�����ʵ�������Dz���Ҫȥ���д����ű��ļ���������

    // ����ȫ���Ը���argc������������ԭ��ִ���ļ����������ڵĽű��ļ���������Ϊ��λ��ͬ

    // һ��λ���� ]]��ע�⣡����ָ��p���Ÿ�����Ϣ���Ӷ�����С��ַ�����ƶ������������

    // ���ƴ�����ִ����󣬻�����������Ϣ��λ�ڳ��������в�������Ϣ����Ϸ������� pָ��

    // ����ĵ�1����������copy_strings()���һ��������0��ָ�������ַ������û��ռ䡣

286                 if (sh_bang++ == 0) {

287                         p = copy_strings(envc, envp, page, p, 0);

288                         p = copy_strings(--argc, argv+1, page, p, 0);

289                 }

290                 /*

291                  * Splice in (1) the interpreter's name for argv[0]

292                  *           (2) (optional) argument to interpreter

293                  *           (3) filename of shell script

294                  *

295                  * This is done in reverse order, because of how the

296                  * user environment and arguments are stored.

297                  */

                    /*

                     * ƴ�� (1) argv[0]�зŽ��ͳ��������

                     *      (2) (��ѡ��)���ͳ���IJ���

                     *      (3) �ű����������

                     *

                     * ������������д����ģ��������û������Ͳ����Ĵ�ŷ�ʽ��ɵġ�

                     */

    // �������������ƽű��ļ��������ͳ���IJ����ͽ��ͳ����ļ����������ͻ����ռ��С�

    // �����������ó����룬��ת��exec_error1�����⣬���ڱ����������ṩ�Ľű��ļ���

    // filename���û��ռ䣬�����︳��copy_strings()�Ľű��ļ�����ָ�����ں˿ռ䣬��

    // ����������ַ������������һ���������ַ�����Դ��־����Ҫ�����ó�1�����ַ�����

    // �ں˿ռ䣬��copy_strings()�����һ������Ҫ���ó�2��������ĵ�301��304�С�

298                 p = copy_strings(1, &filename, page, p, 1);

299                 argc++;

300                 if (i_arg) {                      // ���ƽ��ͳ���Ķ��������

301                         p = copy_strings(1, &i_arg, page, p, 2);

302                         argc++;

303                 }

304                 p = copy_strings(1, &i_name, page, p, 2);

305                 argc++;

306                 if (!p) {

307                         retval = -ENOMEM;

308                         goto exec_error1;

309                 }

310                 /*

311                  * OK, now restart the process with the interpreter's inode.

312                  */

                    /*

                     * OK������ʹ�ý��ͳ����i�ڵ��������̡�

                     */

    // �������ȡ�ý��ͳ����i�ڵ�ָ�룬Ȼ����ת��204��ȥִ�н��ͳ���Ϊ�˻�ý��ͳ�

    // ���i�ڵ㣬������Ҫʹ��namei()���������Ǹú�����ʹ�õIJ������ļ������Ǵ��û���

    // �ݿռ�õ��ģ����ӶμĴ���fs��ָ�ռ���ȡ�á�����ڵ���namei()����֮ǰ������Ҫ

    // ����ʱ��fsָ���ں����ݿռ䣬���ú����ܴ��ں˿ռ�õ����ͳ�����������namei()

    // ���غ�ָ�fs��Ĭ�����á����������������ʱ����ԭfs�μĴ�����ԭָ���û����ݶΣ�

    // ��ֵ���������ó�ָ���ں����ݶΣ�Ȼ��ȡ���ͳ����i�ڵ㡣֮���ٻָ�fs��ԭֵ����

    // ��ת��restart_interp��204�У������´����µ�ִ���ļ� -- �ű��ļ��Ľ��ͳ���

313                 old_fs = get_fs();

314                 set_fs(get_ds());

315                 if (!(inode=namei(interp))) {        /* get executables inode */

316                         set_fs(old_fs);              /* ȡ�ý��ͳ����i�ڵ� */

317                         retval = -ENOENT;

318                         goto exec_error1;

319                 }

320                 set_fs(old_fs);

321                 goto restart_interp;

322         }

 

    // ��ʱ������е�ִ���ļ�ͷ�ṹ�����Ѿ����Ƶ���ex �С� �������ͷŸû���飬����ʼ��

    // ex�е�ִ��ͷ��Ϣ�����жϴ���������Linux 0.12�ں���˵������֧��ZMAGICִ���ļ���

    // ʽ������ִ���ļ����붼���߼���ַ0 ��ʼִ�У���˲�֧�ֺ��д���������ض�λ��Ϣ��

    // ִ���ļ�����Ȼ�����ִ���ļ�ʵ��̫�����ִ���ļ���ȱ��ȫ����ô����Ҳ������������

    // ��˶��������������ִ�г������ִ���ļ���������ҳ��ִ���ļ���ZMAGIC�������ߴ�

    // ��������ض�λ���ֳ��Ȳ�����0������(�����+���ݶ�+��) ���ȳ���50MB������ִ���ļ�

    // ����С�� (�����+���ݶ�+���ű�����+ִ��ͷ����) ���ȵ��ܺ͡�

323         brelse(bh);

324         if (N_MAGIC(ex) != ZMAGIC || ex.a_trsize || ex.a_drsize ||

325                 ex.a_text+ex.a_data+ex.a_bss>0x3000000 ||

326                 inode->i_size < ex.a_text+ex.a_data+ex.a_syms+N_TXTOFF(ex)) {

327                 retval = -ENOEXEC;

328                 goto exec_error2;

329         }

    // ���⣬���ִ���ļ��д��뿪ʼ��û��λ��1��ҳ�棨1024�ֽڣ��߽紦����Ҳ����ִ�С�

    // ��Ϊ����ҳ��Demand paging������Ҫ�����ִ���ļ�����ʱ��ҳ��Ϊ��λ�����Ҫ��ִ��

    // �ļ�ӳ���д�������ݶ���ҳ��߽紦��ʼ��

330         if (N_TXTOFF(ex) != BLOCK_SIZE) {

331                 printk("%s: N_TXTOFF != BLOCK_SIZE. See a.out.h.", filename);

332                 retval = -ENOEXEC;

333                 goto exec_error2;

334         }

    // ���sh_bang��־û�����ã�����ָ�������������в����ͻ����ַ����������ͻ����ռ�

    // �С���sh_bang��־�Ѿ����ã�������ǽ����нű����ͳ��򣬴�ʱ��������ҳ���Ѿ����ƣ�

    // �����ٸ��ơ�ͬ������sh_bangû����λ����Ҫ���ƵĻ�����ô��ʱָ��p���Ÿ�����Ϣ��

    // �Ӷ�����С��ַ�����ƶ���������������ƴ�����ִ����󣬻�����������Ϣ��λ�ڳ���

    // ��������Ϣ����Ϸ�������pָ�����ĵ�1������������ʵ�ϣ�p��128KB�����ͻ�����

    // ���е�ƫ��ֵ��������p=0�����ʾ��������������ռ�ҳ���Ѿ���ռ�������ɲ����ˡ�

335         if (!sh_bang) {

336                 p = copy_strings(envc,envp,page,p,0);

337                 p = copy_strings(argc,argv,page,p,0);

338                 if (!p) {

339                         retval = -ENOMEM;

340                         goto exec_error2;

341                 }

342         }

343 /* OK, This is the point of no return */

344 /* note that current->library stays unchanged by an exec */

    /* OK�����濪ʼ��û�з��صĵط��� */

    // ǰ��������Ժ��������ṩ����Ϣ����Ҫ����ִ���ļ��������в����ͻ����ռ���������ã�

    // ����û��Ϊִ���ļ�����ʲôʵ���ԵĹ���������û������Ϊִ���ļ���ʼ����������ṹ

    // ��Ϣ������ҳ���ȹ������������Ǿ�������Щ����������ִ���ļ�ֱ��ʹ�õ�ǰ���̵ġ���

    // �ǡ�������ǰ���̽��������ִ���ļ��Ľ��̣����������Ҫ�����ͷŵ�ǰ����ռ�õ�ijЩ

    // ϵͳ��Դ�������ر�ָ�����Ѵ��ļ���ռ�õ�ҳ�����ڴ�ҳ��ȡ�Ȼ�����ִ���ļ�ͷ��

    // ����Ϣ�޸ĵ�ǰ����ʹ�õľֲ���������LDT�������������ݣ��������ô���κ����ݶ���

    // �������޳���������ǰ�洦���õ���e_uid��e_gid����Ϣ�����ý�������ṹ����ص���

    // �Ρ�����ִ�б���ϵͳ���ó���ķ��ص�ַ eip[]ָ��ִ���ļ��д������ʼλ�ô�����

    // ������ϵͳ�����˳����غ�ͻ�ȥ������ִ���ļ��Ĵ����ˡ�ע�⣬��Ȼ��ʱ��ִ���ļ���

    // ������ݻ�û�д��ļ��м��ص��ڴ��У���������ͻ������Ѿ���copy_strings() ��ʹ��

    // get_free_page()�����������ڴ�ҳ���������ݣ�����change_ldt()������ʹ��put_page()

    // ���˽����߼��ռ��ĩ�˴������⣬��create_tables()��Ҳ���������û�ջ�ϴ�Ų���

    // �ͻ���ָ���������ȱҳ�쳣���Ӷ��ڴ��������Ҳ��ʹ�Ϊ�û�ջ�ռ�ӳ�������ڴ�ҳ��

    //

    // �����������ȷŻؽ���ԭִ�г����i�ڵ㣬�����ý���executable �ֶ�ָ����ִ���ļ�

    // ��i�ڵ㡣Ȼ��λԭ���̵������źŴ��������������SIG_IGN������븴λ���ٸ�����

    // ����ִ��ʱ�ر��ļ������close_on_exec��λͼ��־���ر�ָ���Ĵ��ļ�����λ�ñ�־��

345         if (current->executable)

346                 iput(current->executable);

347         current->executable = inode;

348         current->signal = 0;

349         for (i=0 ; i<32 ; i++) {

350                 current->sigaction[i].sa_mask = 0;

351                 current->sigaction[i].sa_flags = 0;

352                 if (current->sigaction[i].sa_handler != SIG_IGN)

353                         current->sigaction[i].sa_handler = NULL;

354         }

355         for (i=0 ; i<NR_OPEN ; i++)

356                 if ((current->close_on_exec>>i)&1)

357                         sys_close(i);

358         current->close_on_exec = 0;

    // Ȼ����ݵ�ǰ����ָ���Ļ���ַ���޳����ͷ�ԭ������Ĵ���κ����ݶ�����Ӧ���ڴ�ҳ��

    // ָ���������ڴ�ҳ�漰ҳ����������ʱ��ִ���ļ���û��ռ�����ڴ����κ�ҳ�棬����ڴ�

    // ��������������ִ���ļ�����ʱ�ͻ�����ȱҳ�쳣�жϣ���ʱ�ڴ�������򼴻�ִ��ȱҳ��

    // ����Ϊ��ִ���ļ������ڴ�ҳ����������ҳ������Ұ����ִ���ļ�ҳ������ڴ��С�

    // ������ϴ�����ʹ����Э��������ָ����ǵ�ǰ���̣������ÿգ�����λʹ����Э������

    // �ı�־��

359         free_page_tables(get_base(current->ldt[1]),get_limit(0x0f));

360         free_page_tables(get_base(current->ldt[2]),get_limit(0x17));

361         if (last_task_used_math == current)

362                 last_task_used_math = NULL;

363         current->used_math = 0;

    // Ȼ�����Ǹ�����ִ���ļ�ͷ�ṹ�еĴ��볤���ֶ� a_text ��ֵ�޸ľֲ�������������ַ��

    // ���޳�������128KB �IJ����ͻ����ռ�ҳ����������ݶ�ĩ�ˡ�ִ���������֮��p��ʱ

    // ���ij������ݶ���ʼ��Ϊԭ���ƫ��ֵ������ָ������ͻ����ռ����ݿ�ʼ��������ת����

    // Ϊջָ��ֵ��Ȼ������ڲ�����create_tables() ��ջ�ռ��д��������Ͳ�������ָ�����

    // �������main()��Ϊ����ʹ�ã������ظ�ջָ�롣

364         p += change_ldt(ex.a_text,page);

365         p -= LIBRARY_SIZE + MAX_ARG_PAGES*PAGE_SIZE;

366         p = (unsigned long) create_tables((char *)p,argc,envc);

 

    // �������޸Ľ��̸��ֶ�ֵΪ��ִ���ļ�����Ϣ�������������ṹ����β�ֶ�end_code��

    // ��ִ���ļ��Ĵ���γ��� a_text������β�ֶ� end_data ����ִ���ļ��Ĵ���γ��ȼ���

    // �ݶγ��ȣ�a_data + a_text����������̶ѽ�β�ֶ�brk = a_text + a_data + a_bss��

    // brk����ָ�����̵�ǰ���ݶΣ�����δ��ʼ�����ݲ��֣�ĩ��λ�ã����ں�Ϊ���̷����ڴ�

    // ʱָ�����俪ʼλ�á�Ȼ�����ý���ջ��ʼ�ֶ�Ϊջָ������ҳ�棬���������ý��̵���Ч

    // �û�id����Ч��id��

367         current->brk = ex.a_bss +

368                 (current->end_data = ex.a_data +

369                 (current->end_code = ex.a_text));

370         current->start_stack = p & 0xfffff000;

371         current->suid = current->euid = e_uid;

372         current->sgid = current->egid = e_gid;

    // ���ԭ����ϵͳ�жϵij����ڶ�ջ�ϵĴ���ָ���滻Ϊָ����ִ�г������ڵ㣬����ջ

    // ָ���滻Ϊ��ִ���ļ���ջָ�롣�˺󷵻�ָ�������Щջ���ݲ�ʹ��CPUȥִ����ִ��

    // �ļ�����˲��᷵�ص�ԭ����ϵͳ�жϵij�����ȥ�ˡ�

373         eip[0] = ex.a_entry;    /* eip, magic happens :-) */  /* eip��ħ����������*/

374         eip[3] = p;             /* stack pointer */           /* esp����ջָ�� */

375         return 0;

376 exec_error2:

377         iput(inode);                       // �Ż�i�ڵ㡣

378 exec_error1:

379         for (i=0 ; i<MAX_ARG_PAGES ; i++)

380                 free_page(page[i]);        // �ͷŴ�Ų����ͻ��������ڴ�ҳ�档

381         return(retval);                    // ���س����롣

382 }

383


 


 

12.15 ����12-15 linux/fs/stat.c


  1 /*

  2  *  linux/fs/stat.c

  3  *

  4  *  (C) 1991  Linus Torvalds

  5  */

  6

  7 #include <errno.h>        // �����ͷ�ļ�������ϵͳ�и��ֳ����š�

  8 #include <sys/stat.h>     // �ļ�״̬ͷ�ļ��������ļ�״̬�ṹstat{}�ͳ�����

  9

 10 #include <linux/fs.h>     // �ļ�ϵͳͷ�ļ��������ļ����ṹ��file��m_inode���ȡ�

 11 #include <linux/sched.h>  // ���ȳ���ͷ�ļ�������������ṹtask_struct������0���ݵȡ�

 12 #include <linux/kernel.h> // �ں�ͷ�ļ�������һЩ�ں˳��ú�����ԭ�ζ��塣

 13 #include <asm/segment.h>  // �β���ͷ�ļ����������йضμĴ���������Ƕ��ʽ��ຯ����

 14

    //// �����ļ�״̬��Ϣ��

    // ����inode���ļ�i�ڵ㣬statbuf���û����ݿռ���stat�ļ�״̬�ṹָ�룬���ڴ��ȡ

    // �õ�״̬��Ϣ��

 15 static void cp_stat(struct m_inode * inode, struct stat * statbuf)

 16 {

 17         struct stat tmp;

 18         int i;

 19

    // ������֤(�����)������ݵ��ڴ�ռ䡣Ȼ����ʱ������Ӧ�ڵ��ϵ���Ϣ��

 20         verify_area(statbuf,sizeof (struct stat));

 21         tmp.st_dev = inode->i_dev;        // �ļ����ڵ��豸�š�

 22         tmp.st_ino = inode->i_num;        // �ļ�i�ڵ�š�

 23         tmp.st_mode = inode->i_mode;      // �ļ����ԡ�

 24         tmp.st_nlink = inode->i_nlinks;   // �ļ���������

 25         tmp.st_uid = inode->i_uid;        // �ļ����û�ID��

 26         tmp.st_gid = inode->i_gid;        // �ļ�����ID��

 27         tmp.st_rdev = inode->i_zone[0];   // �豸�ţ����������ַ��ļ�����豸�ļ�����

 28         tmp.st_size = inode->i_size;      // �ļ��ֽڳ��ȣ�����ļ��dz����ļ�����

 29         tmp.st_atime = inode->i_atime;    // ������ʱ�䡣

 30         tmp.st_mtime = inode->i_mtime;    // ����޸�ʱ�䡣

 31         tmp.st_ctime = inode->i_ctime;    // ���i�ڵ��޸�ʱ�䡣

    // �����Щ״̬��Ϣ���Ƶ��û��������С�

 32         for (i=0 ; i<sizeof (tmp) ; i++)

 33                 put_fs_byte(((char *) &tmp)[i],i + (char *) statbuf);

 34 }

 35

    //// �ļ�״̬ϵͳ���á�

    // ���ݸ������ļ�����ȡ����ļ�״̬��Ϣ��

    // ����filename��ָ�����ļ�����statbuf�Ǵ��״̬��Ϣ�Ļ�����ָ�롣

    // ���أ��ɹ�����0���������򷵻س����롣

 36 int sys_stat(char * filename, struct stat * statbuf)

 37 {

 38         struct m_inode * inode;

 39

    // ���ȸ����ļ����ҳ���Ӧ��i�ڵ㡣Ȼ��i�ڵ��ϵ��ļ�״̬��Ϣ���Ƶ��û��������У�

    // ���Żظ�i�ڵ㡣

 40         if (!(inode=namei(filename)))

 41                 return -ENOENT;

 42         cp_stat(inode,statbuf);

 43         iput(inode);

 44         return 0;

 45 }

 46

    //// �ļ�״̬ϵͳ���á�

    // ���ݸ������ļ�����ȡ����ļ�״̬��Ϣ���ļ�·�������з��������ļ�������ȡ�����ļ�

    // ��״̬��

    // ����filename��ָ�����ļ�����statbuf�Ǵ��״̬��Ϣ�Ļ�����ָ�롣

    // ���أ��ɹ�����0���������򷵻س����롣

 47 int sys_lstat(char * filename, struct stat * statbuf)

 48 {

 49         struct m_inode * inode;

 50

    // ���ȸ����ļ����ҳ���Ӧ��i�ڵ㡣Ȼ��i�ڵ��ϵ��ļ�״̬��Ϣ���Ƶ��û��������У�

    // ���Żظ�i�ڵ㡣

 51         if (!(inode = lnamei(filename)))     // ȡָ��·����i�ڵ㣬������������ӡ�

 52                 return -ENOENT;

 53         cp_stat(inode,statbuf);

 54         iput(inode);

 55         return 0;

 56 }

 57

    //// �ļ�״̬ϵͳ���á�

    // ���ݸ������ļ������ȡ����ļ�״̬��Ϣ��

    // ����fd��ָ���ļ��ľ��(������)��statbuf�Ǵ��״̬��Ϣ�Ļ�����ָ�롣

    // ���أ��ɹ�����0���������򷵻س����롣

 58 int sys_fstat(unsigned int fd, struct stat * statbuf)

 59 {

 60         struct file * f;

 61         struct m_inode * inode;

 62

    // ����ȡ�ļ������Ӧ���ļ��ṹ��Ȼ����еõ��ļ���i�ڵ㡣Ȼ��i�ڵ��ϵ��ļ�״

    // ̬��Ϣ���Ƶ��û��������С�����ļ����ֵ����һ�����������ļ���NR_OPEN����

    // �߸þ�����ļ��ṹָ��Ϊ�գ����߶�Ӧ�ļ��ṹ��i�ڵ��ֶ�Ϊ�գ�����������س���

    // �벢�˳���

 63         if (fd >= NR_OPEN || !(f=current->filp[fd]) || !(inode=f->f_inode))

 64                 return -EBADF;

 65         cp_stat(inode,statbuf);

 66         return 0;

 67 }

 68

    //// �����������ļ�ϵͳ���á�

    // �õ��ö�ȡ���������ļ������ݣ����÷���������ָ���ļ���·�����ַ����������ŵ�ָ��

    // ���ȵ��û��������С���������̫С���ͻ�ضϷ������ӵ����ݡ�

    // ������path -- ���������ļ�·������buf -- �û���������bufsiz -- ���������ȡ�

    // ���أ��ɹ��򷵻ط��뻺�����е��ַ�������ʧ���򷵻س����롣

 69 int sys_readlink(const char * path, char * buf, int bufsiz)

 70 {

 71         struct m_inode * inode;

 72         struct buffer_head * bh;

 73         int i;

 74         char c;

 75

    // ���ȼ�����֤������������Ч�ԣ���������е������û��������ֽڳ���bufsi������

    // 1--1023֮�䡣Ȼ��ȡ�÷��������ļ�����i�ڵ㣬����ȡ���ļ��ĵ�1���������ݡ�֮

    // ��Ż�i�ڵ㡣

 76         if (bufsiz <= 0)

 77                 return -EBADF;

 78         if (bufsiz > 1023)

 79                 bufsiz = 1023;

 80         verify_area(buf,bufsiz);

 81         if (!(inode = lnamei(path)))

 82                 return -ENOENT;

 83         if (inode->i_zone[0])

 84                 bh = bread(inode->i_dev, inode->i_zone[0]);

 85         else

 86                 bh = NULL;

 87         iput(inode);

    // �����ȡ�ļ��������ݳɹ�����������и������bufsiz���ַ����û��������С�������

    // NULL�ַ�������ͷŻ���飬�����ظ��Ƶ��ֽ�����

 88         if (!bh)

 89                 return 0;

 90         i = 0;

 91         while (i<bufsiz && (c = bh->b_data[i])) {

 92                 i++;

 93                 put_fs_byte(c,buf++);

 94         }

 95         brelse(bh);

 96         return i;

 97 }

 98


 


 

12.16 ����12-16 linux/fs/fcntl.c


  1 /*

  2  *  linux/fs/fcntl.c

  3  *

  4  *  (C) 1991  Linus Torvalds

  5  */

  6

  7 #include <string.h>       // �ַ���ͷ�ļ�����Ҫ������һЩ�й��ַ���������Ƕ�뺯����

  8 #include <errno.h>        // �����ͷ�ļ�������ϵͳ�и��ֳ����š�

  9 #include <linux/sched.h>  // ���ȳ���ͷ�ļ�������������ṹtask_struct������0���ݵȡ�

 10 #include <linux/kernel.h> // �ں�ͷ�ļ�������һЩ�ں˳��ú�����ԭ�ζ��塣

 11 #include <asm/segment.h>  // �β���ͷ�ļ����������йضμĴ���������Ƕ��ʽ��ຯ����

 12

 13 #include <fcntl.h>        // �ļ�����ͷ�ļ��������ļ������������IJ������Ƴ������š�

 14 #include <sys/stat.h>     // �ļ�״̬ͷ�ļ��������ļ�״̬�ṹstat{}�ͳ�����

 15

 16 extern int sys_close(int fd);     // �ر��ļ�ϵͳ���á�(fs/open.c, 192)

 17

    //// �����ļ�������ļ�����������

    // ����fd�������Ƶ��ļ������argָ�����ļ��������С��ֵ��

    // �������ļ����������롣

 18 static int dupfd(unsigned int fd, unsigned int arg)

 19 {

    // ���ȼ�麯����������Ч�ԡ�����ļ����ֵ����һ�����������ļ���NR_OPEN������

    // �þ�����ļ��ṹ�����ڣ��򷵻س����벢�˳������ָ�����¾��ֵarg����������

    // ������Ҳ���س����벢�˳���ע�⣬ʵ�����ļ�������ǽ����ļ��ṹָ�������������š�

 20         if (fd >= NR_OPEN || !current->filp[fd])

 21                 return -EBADF;

 22         if (arg >= NR_OPEN)

 23                 return -EINVAL;

    // Ȼ���ڵ�ǰ���̵��ļ��ṹָ��������Ѱ�������ŵ��ڻ����arg������û��ʹ�õ����

    // �ҵ����¾��ֵarg���������ļ�������û�п�������򷵻س����벢�˳���

 24         while (arg < NR_OPEN)

 25                 if (current->filp[arg])

 26                         arg++;

 27                 else

 28                         break;

 29         if (arg >= NR_OPEN)

 30                 return -EMFILE;

    // ��������ҵ��Ŀ�������������ִ��ʱ�رձ�־λͼclose_on_exec�и�λ�þ��λ��

    // ��������exec()�ຯ��ʱ������ر���dup()�����ľ����������ļ��ṹָ�����ԭ��

    // ��fd��ָ�룬���ҽ��ļ����ü�����1����󷵻��µ��ļ����arg��

 31         current->close_on_exec &= ~(1<<arg);

 32         (current->filp[arg] = current->filp[fd])->f_count++;

 33         return arg;

 34 }

 35

    //// �����ļ����ϵͳ���á�

    // ����ָ���ļ����oldfd�����ļ����ֵ����newfd�����newfd�Ѵ򿪣������ȹر�֮��

    // ������oldfd -- ԭ�ļ������newfd - ���ļ������

    // �������ļ����ֵ��

 36 int sys_dup2(unsigned int oldfd, unsigned int newfd)

 37 {

 38         sys_close(newfd);             // �����newfd�Ѿ��򿪣������ȹر�֮��

 39         return dupfd(oldfd,newfd);    // ���Ʋ������¾����

 40 }

 41

    //// �����ļ����ϵͳ���á�

    // ����ָ���ļ����oldfd���¾����ֵ�ǵ�ǰ��С��δ�þ��ֵ��

    // ������fildes -- �����Ƶ��ļ������

    // �������ļ����ֵ��

 42 int sys_dup(unsigned int fildes)

 43 {

 44         return dupfd(fildes,0);

 45 }

 46

    //// �ļ�����ϵͳ���ú�����

    // ����fd���ļ������cmd�ǿ�������μ�include/fcntl.h��23-30�У���arg����Բ�

    // ͬ�������в�ͬ�ĺ��塣���ڸ��ƾ������F_DUPFD��arg�����ļ������ȡ����Сֵ����

    // �������ļ������ͷ��ʱ�־����F_SETFL��arg���µ��ļ������ͷ���ģʽ�������ļ�����

    // ����F_GETLK��F_SETLK��F_SETLKW��arg��ָ��flock�ṹ��ָ�롣�����ں���û��ʵ��

    // �ļ��������ܡ�

    // ���أ��������������в���������-1�����ɹ�����ôF_DUPFD �������ļ������ F_GETFD

    // �����ļ�����ĵ�ǰִ��ʱ�رձ�־close_on_exec��F_GETFL�����ļ������ͷ��ʱ�־��

 47 int sys_fcntl(unsigned int fd, unsigned int cmd, unsigned long arg)

 48 {      

 49         struct file * filp;

 50

    // ���ȼ��������ļ��������Ч�ԡ�Ȼ����ݲ�ͬ����cmd ���зֱ����� ����ļ����

    // ֵ����һ�����������ļ���NR_OPEN�����߸þ�����ļ��ṹָ��Ϊ�գ��򷵻س�����

    // ���˳���

 51         if (fd >= NR_OPEN || !(filp = current->filp[fd]))

 52                 return -EBADF;

 53         switch (cmd) {

 54                 case F_DUPFD:      // �����ļ������

 55                         return dupfd(fd,arg);

 56                 case F_GETFD:      // ȡ�ļ������ִ��ʱ�رձ�־��

 57                         return (current->close_on_exec>>fd)&1;

 58                 case F_SETFD:  // ����ִ��ʱ�رձ�־��argλ0��λ�����ã�����رա�

 59                         if (arg&1)

 60                                 current->close_on_exec |= (1<<fd);

 61                         else

 62                                 current->close_on_exec &= ~(1<<fd);

 63                         return 0;

 64                 case F_GETFL:      // ȡ�ļ�״̬��־�ͷ���ģʽ��

 65                         return filp->f_flags;

 66                 case F_SETFL: // �����ļ�״̬�ͷ���ģʽ������arg�������ӡ���������־����

 67                         filp->f_flags &= ~(O_APPEND | O_NONBLOCK);

 68                         filp->f_flags |= arg & (O_APPEND | O_NONBLOCK);

 69                         return 0;

 70                 case F_GETLK:   case F_SETLK:   case F_SETLKW:    // δʵ�֡�

 71                         return -1;

 72                 default:

 73                         return -1;

 74         }

 75 }

 76


 


 

12.17 ����12-17 linux/fs/ioctl.c


  1 /*

  2  *  linux/fs/ioctl.c

  3  *

  4  *  (C) 1991  Linus Torvalds

  5  */

  6

  7 #include <string.h>       // �ַ���ͷ�ļ�����Ҫ������һЩ�й��ַ���������Ƕ�뺯����

  8 #include <errno.h>        // �����ͷ�ļ�������ϵͳ�и��ֳ����š�

  9 #include <sys/stat.h>     // �ļ�״̬ͷ�ļ��������ļ�״̬�ṹstat{}�ͳ�����

 10

 11 #include <linux/sched.h>  // ���ȳ���ͷ�ļ�������������ṹtask_struct������0���ݵȡ�

 12

 13 extern int tty_ioctl(int dev, int cmd, int arg);    // chr_drv/tty_ioctl.c����133�С�

 14 extern int pipe_ioctl(struct m_inode *pino, int cmd, int arg);  // fs/pipe.c����118�С�

 15

    // ���������������(ioctl)����ָ�����͡�

 16 typedef int (*ioctl_ptr)(int dev,int cmd,int arg);

 17

    // ȡϵͳ���豸�����ĺꡣ

 18 #define NRDEVS ((sizeof (ioctl_table))/(sizeof (ioctl_ptr)))

 19

    // ioctl��������ָ�����

 20 static ioctl_ptr ioctl_table[]={

 21         NULL,           /* nodev */

 22         NULL,           /* /dev/mem */

 23         NULL,           /* /dev/fd */

 24         NULL,           /* /dev/hd */

 25         tty_ioctl,      /* /dev/ttyx */

 26         tty_ioctl,      /* /dev/tty */

 27         NULL,           /* /dev/lp */

 28         NULL};          /* named pipes */

 29        

 30

    //// ϵͳ���ú��� - ����������ƺ�����

    // �ú��������жϲ����������ļ��������Ƿ���Ч��Ȼ����ݶ�Ӧi�ڵ����ļ������ж��ļ�

    // ���ͣ������ݾ����ļ����͵�����صĴ���������

    // ������fd - �ļ���������cmd - �����룻arg - ������

    // ���أ��ɹ��򷵻�0�����򷵻س����롣

 31 int sys_ioctl(unsigned int fd, unsigned int cmd, unsigned long arg)

 32 {      

 33         struct file * filp;

 34         int dev,mode;

 35

    // �����жϸ������ļ�����������Ч�ԡ�����ļ������������ɴ򿪵��ļ��������߶�Ӧ����

    // �����ļ��ṹָ��Ϊ�գ��򷵻س������˳���

 36         if (fd >= NR_OPEN || !(filp = current->filp[fd]))

 37                 return -EBADF;

    // ����ļ��ṹ��Ӧ���ǹܵ�i�ڵ㣬����ݽ����Ƿ���Ȩ�����ùܵ�ȷ���Ƿ�ִ�йܵ�IO

    // ���Ʋ���������Ȩִ�������pipe_ioctl()�����򷵻���Ч�ļ������롣

 38         if (filp->f_inode->i_pipe)

 39                 return (filp->f_mode&1)?pipe_ioctl(filp->f_inode,cmd,arg):-EBADF;

    // �������������ļ���ȡ��Ӧ�ļ������ԣ����ݴ��ж��ļ������͡�������ļ��Ȳ����ַ���

    // ���ļ���Ҳ���ǿ��豸�ļ����򷵻س������˳��������ַ�����豸�ļ�������ļ���i��

    // ����ȡ�豸�š�����豸�Ŵ���ϵͳ���е��豸�����򷵻س����š�

 40         mode=filp->f_inode->i_mode;

 41         if (!S_ISCHR(mode) && !S_ISBLK(mode))

 42                 return -EINVAL;

 43         dev = filp->f_inode->i_zone[0];

 44         if (MAJOR(dev) >= NRDEVS)

 45                 return -ENODEV;

    // Ȼ�����IO���Ʊ�ioctl_table��ö�Ӧ�豸��ioctl����ָ�룬�����øú������������

    // ����ioctl����ָ�����û�ж�Ӧ�������򷵻س����롣

 46         if (!ioctl_table[MAJOR(dev)])

 47                 return -ENOTTY;

 48         return ioctl_table[MAJOR(dev)](dev,cmd,arg);

 49 }

 50


 


 

12.18 ����12-18 linux/fs/select.c


  1 /*

  2  * This file contains the procedures for the handling of select

  3  *

  4  * Created for Linux based loosely upon Mathius Lattner's minix

  5  * patches by Peter MacDonald. Heavily edited by Linus.

  6  */

    /*

     * ���ļ����д���select()ϵͳ���õĹ��̡�

     *

     * ����Peter MacDonald����Mathius Lattner�ṩ��MINIXϵͳ�IJ���

     * �����޸Ķ��ɡ�

     */

  7

  8 #include <linux/fs.h>

  9 #include <linux/kernel.h>

 10 #include <linux/tty.h>

 11 #include <linux/sched.h>

 12

 13 #include <asm/segment.h>

 14 #include <asm/system.h>

 15

 16 #include <sys/stat.h>

 17 #include <sys/types.h>

 18 #include <string.h>

 19 #include <const.h>

 20 #include <errno.h>

 21 #include <sys/time.h>

 22 #include <signal.h>

 23

 24 /*

 25  * Ok, Peter made a complicated, but straightforward multiple_wait() function.

 26  * I have rewritten this, taking some shortcuts: This code may not be easy to

 27  * follow, but it should be free of race-conditions, and it's practical. If you

 28  * understand what I'm doing here, then you understand how the linux sleep/wakeup

 29  * mechanism works.

 30  *

 31  * Two very simple procedures, add_wait() and free_wait() make all the work. We

 32  * have to have interrupts disabled throughout the select, but that's not really

 33  * such a loss: sleeping automatically frees interrupts when we aren't in this

 34  * task.

 35  */

    /*

     * OK��Peter�����˸��ӵ���ֱ�۵Ķ��_wait()�������Ҷ���Щ���������˸�д����ʹ֮

     * ����ࣺ��Щ������ܲ����׿�������������Ӧ�ò�����ھ����������⣬���Һ�ʵ�ʡ�

     * �����������������ƵĴ��룬��ô��˵�����Ѿ�����Linux��˯��/���ѵĹ������ơ�

     *

     * �����ܼ򵥵Ĺ��̣�add_wait()��free_wait()ִ������Ҫ������������select����

     * ���������Dz��ò���ֹ�жϡ��������������������̫�����ʧ����Ϊ�����Dz���ִ��

     * ������ʱ˯��״̬���Զ����ͷ��жϣ������������ʹ���Լ�EFLAGS�е��жϱ�־����

     */

 36

 37 typedef struct {

 38         struct task_struct * old_task;

 39         struct task_struct ** wait_address;

 40 } wait_entry;

 41

 42 typedef struct {

 43         int nr;

 44         wait_entry entry[NR_OPEN*3];

 45 } select_table;

 46

    // ��δ׼�����������ĵȴ�����ָ�����ȴ���wait_table�С�����*wait_address��������

    // ����صĵȴ�����ͷָ�롣����tty���������secondary�ĵȴ�����ͷָ����proc_list��

    // ���� p��do_select()�ж���ĵȴ����ṹָ�롣

 47 static void add_wait(struct task_struct ** wait_address, select_table * p)

 48 {

 49         int i;

 50

    // �����ж��������Ƿ��ж�Ӧ�ĵȴ����У������򷵻ء�Ȼ���ڵȴ�������������ָ���ĵȴ�

    // ����ָ���Ƿ��Ѿ��ڵȴ��������ù��������ù�Ҳ���̷��ء�����ж���Ҫ����Թܵ��ļ�

    // ��������������һ���ܵ��ڵȴ����Խ��ж���������ô��ض��������̽���д������

 51         if (!wait_address)

 52                 return;

 53         for (i = 0 ; i < p->nr ; i++)

 54                 if (p->entry[i].wait_address == wait_address)

 55                         return;

    // Ȼ�����ǰ���������Ӧ�ȴ����е�ͷָ�뱣���ڵȴ���wait_table�У�ͬʱ�õȴ������

    // old_task�ֶ�ָ��ȴ�����ͷָ��ָ�������������ΪNULL�������õȴ�����ͷָ��ָ

    // ��ǰ�������ѵȴ�����Ч�����ֵnr��1�����ڵ�179�б���ʼ��Ϊ0����

 56         p->entry[p->nr].wait_address = wait_address;

 57         p->entry[p->nr].old_task = * wait_address;

 58         *wait_address = current;

 59         p->nr++;

 60 }

 61

    // ��յȴ����������ǵȴ����ṹָ�롣��������do_select()������˯�ߺ󱻻��ѷ���ʱ������

    // ����204��207�У������ڻ��ѵȴ����д��ڸ����ȴ������ϵ�������������kernel/sched.c

    // ��sleep_on()�����ĺ�벿�ִ��뼸����ȫ��ͬ����ο���sleep_on()������˵����

 62 static void free_wait(select_table * p)

 63 {

 64         int i;

 65         struct task_struct ** tpp;

 66

    // ����ȴ����и����nr ����Ч���¼�ĵȴ�����ͷָ��������������������ӽ��ĵȴ�

    // ���������������̵��� sleep_on() ������˯���ڸõȴ������ϣ������ʱ�ȴ�����ͷָ��

    // ָ��IJ��ǵ�ǰ���̣���ô���Ǿ���Ҫ�Ȼ�����Щ���񡣲��������ǽ��ȴ�����ͷ��ָ������

    // ��Ϊ����״̬��state = 0���������Լ�����Ϊ�����жϵȴ�״̬�����Լ�Ҫ�ȴ���Щ��������

    // �е����񱻻��Ѷ�ִ��ʱ�����ѱ�����Ȼ������ִ�е��ȳ���

 67         for (i = 0; i < p->nr ; i++) {

 68                 tpp = p->entry[i].wait_address;

 69                 while (*tpp && *tpp != current) {

 70                         (*tpp)->state = 0;

 71                         current->state = TASK_UNINTERRUPTIBLE;

 72                         schedule();

 73                 }

    // ִ�е����˵���ȴ�����ǰ�������еĵȴ�����ͷָ���ֶ�wait_addressָ��ǰ����

    // ����Ϊ�գ���������������⣬������ʾ������Ϣ��Ȼ�������õȴ�����ͷָ��ָ��������

    // ǰ�������е����񣨵�76�У�������ʱ��ͷָ��ȷʵָ��һ�����������NULL����˵��

    // �����л�������*tpp��Ϊ�գ������ǽ����������óɾ���״̬������֮�����ѵȴ�����

    // ��Ч��������ֶ�nr���㡣

 74                 if (!*tpp)

 75                         printk("free_wait: NULL");

 76                 if (*tpp = p->entry[i].old_task)

 77                         (**tpp).state = 0;

 78         }

 79         p->nr = 0;

 80 }

 81

    // �����ļ�i�ڵ��ж��ļ��Ƿ����ַ��ն��豸�ļ��������򷵻���tty�ṹָ�룬���򷵻�NULL��

 82 static struct tty_struct * get_tty(struct m_inode * inode)

 83 {

 84         int major, minor;

 85

    // ��������ַ��豸�ļ��򷵻�NULL��������豸�Ų���5�������նˣ���4���򷵻�NULL��

 86         if (!S_ISCHR(inode->i_mode))

 87                 return NULL;

 88         if ((major = MAJOR(inode->i_zone[0])) != 5 && major != 4)

 89                 return NULL;

    // ������豸����5����ô���ն��豸�ŵ��ڽ��̵�tty�ֶ�ֵ������͵����ַ��豸�ļ����豸�š�

    // ����ն��豸��С��0����ʾ����û�п����ն˻�û��ʹ���նˣ����Ƿ���NULL�����򷵻ض�Ӧ��

    // tty�ṹָ�롣

 90         if (major == 5)

 91                 minor = current->tty;

 92         else

 93                 minor = MINOR(inode->i_zone[0]);

 94         if (minor < 0)

 95                 return NULL;

 96         return TTY_TABLE(minor);

 97 }

 98

 99 /*

100  * The check_XX functions check out a file. We know it's either

101  * a pipe, a character device or a fifo (fifo's not implemented)

102  */

    /*

     * check_XX�������ڼ��һ���ļ�������֪�����ļ�Ҫô�ǹܵ��ļ���

     * Ҫô���ַ��豸�ļ�������Ҫô��һ��FIFO��FIFO��δʵ�֣���

     */

    // �����ļ������Ƿ�׼���ã����ն˶��������secondary�Ƿ����ַ��ɶ������߹ܵ��ļ��Ƿ�

    // ���ա�����wait�ǵȴ���ָ�룻inode���ļ�i�ڵ�ָ�롣���������ɽ��ж������򷵻�1����

    // �򷵻�0��

103 static int check_in(select_table * wait, struct m_inode * inode)

104 {

105         struct tty_struct * tty;

106

    // ���ȸ����ļ�i�ڵ����get_tty()����ļ��Ƿ���һ��tty�նˣ��ַ����豸�ļ����������

    // �����ն˶��������secondary���Ƿ����ַ��ɹ���ȡ�������򷵻�1������ʱsecondaryΪ

    // ����ѵ�ǰ�������ӵ�secondary�ĵȴ�����proc_list�ϲ�����0������ǹܵ��ļ������ж�

    // Ŀǰ�ܵ����Ƿ����ַ��ɶ��������򷵻�1����û�У��ܵ��գ���ѵ�ǰ�������ӵ��ܵ�i�ڵ�

    // �ĵȴ������ϲ�����0��ע�⣬PIPE_EMPTY()��ʹ�ùܵ���ǰͷβָ��λ�����жϹܵ��Ƿ�ա�

    // �ܵ�i�ڵ��i_zone[0]��i_zone[1]�ֶηֱ����Źܵ���ǰ��ͷβָ�롣

107         if (tty = get_tty(inode))

108                 if (!EMPTY(tty->secondary))

109                         return 1;

110                 else

111                         add_wait(&tty->secondary->proc_list, wait);

112         else if (inode->i_pipe)

113                 if (!PIPE_EMPTY(*inode))

114                         return 1;

115                 else

116                         add_wait(&inode->i_wait, wait);

117         return 0;

118 }

119

    // ����ļ�д�����Ƿ�׼���ã����ն�д�������write_q���Ƿ��п���λ�ÿ�д�����ߴ�ʱ��

    // ���ļ��Ƿ���������wait�ǵȴ���ָ�룻inode���ļ�i�ڵ�ָ�롣���������ɽ���д������

    // ����1�����򷵻�0��

120 static int check_out(select_table * wait, struct m_inode * inode)

121 {

122         struct tty_struct * tty;

123

    // ���ȸ����ļ�i�ڵ����get_tty()����ļ��Ƿ���һ��tty�նˣ��ַ����豸�ļ����������

    // �����ն�д�������write_q���Ƿ��пռ��д�룬�����򷵻�1����û�пտռ���ѵ�ǰ��

    // �����ӵ�write_q�ĵȴ�����proc_list�ϲ�����0������ǹܵ��ļ����ж�Ŀǰ�ܵ����Ƿ���

    // ���пռ��д���ַ��������򷵻�1����û�У��ܵ�������ѵ�ǰ�������ӵ��ܵ�i�ڵ�ĵȴ�

    // �����ϲ�����0��

124         if (tty = get_tty(inode))

125                 if (!FULL(tty->write_q))

126                         return 1;

127                 else

128                         add_wait(&tty->write_q->proc_list, wait);

129         else if (inode->i_pipe)

130                 if (!PIPE_FULL(*inode))

131                         return 1;

132                 else

133                         add_wait(&inode->i_wait, wait);

134         return 0;

135 }

136

    // ����ļ��Ƿ����쳣״̬�������ն��豸�ļ���Ŀǰ�ں����Ƿ���0�����ڹܵ��ļ������

    // ��ʱ�����ܵ�����������һ�����ѱ��رգ��򷵻�1������Ͱѵ�ǰ�������ӵ��ܵ�i�ڵ�

    // �ĵȴ������ϲ�����0������0������wait�ǵȴ���ָ�룻inode���ļ�i�ڵ�ָ�롣������

    // �쳣�����򷵻�1�����򷵻�0��

137 static int check_ex(select_table * wait, struct m_inode * inode)

138 {

139         struct tty_struct * tty;

140

141         if (tty = get_tty(inode))

142                 if (!FULL(tty->write_q))

143                         return 0;

144                 else

145                         return 0;

146         else if (inode->i_pipe)

147                 if (inode->i_count < 2)

148                         return 1;

149                 else

150                         add_wait(&inode->i_wait,wait);

151         return 0;

152 }

153

    // do_select() ���ں�ִ��select()ϵͳ���õ�ʵ�ʴ����������ú������ȼ�����������и���

    // ����������Ч�ԣ�Ȼ��ֱ�����������������������麯��check_XX()��ÿ�����������м�

    // �飬ͬʱͳ�����������е�ǰ�Ѿ�׼���õ������������������κ�һ���������Ѿ�׼���ã���

    // �����ͻ����̷��أ�������̾ͻ��ڱ������н���˯��״̬�����ڹ��˳�ʱʱ���������ij��

    // ���������ڵȴ������ϵĽ��̱����Ѷ�ʹ�����̼������С�

154 int do_select(fd_set in, fd_set out, fd_set ex,

155         fd_set *inp, fd_set *outp, fd_set *exp)

156 {

157         int count;                                 // ��׼���õ���������������ֵ��

158         select_table wait_table;                   // �ȴ����ṹ��

159         int i;

160         fd_set mask;

161

    // ���Ȱ�3�������������л��������mask�еõ�������������Ч����������λ�����롣 Ȼ��

    // ѭ���жϵ�ǰ���̸����������Ƿ���Ч���Ұ��������������ڡ���ѭ���У�ÿ�ж���һ������

    // ���ͻ��mask����1λ����˸���mask�������Ч����λ���ǾͿ����ж���Ӧ�������Ƿ���

    // �û����������������С���Ч��������Ӧ����һ���ܵ��ļ���������������һ���ַ��豸�ļ�

    // ��������������һ��FIFO���������������͵Ķ���Ϊ��Ч������������EBADF����

162         mask = in | out | ex;

163         for (i = 0 ; i < NR_OPEN ; i++,mask >>= 1) {

164                 if (!(mask & 1))                 // ����������������������ж���һ����

165                         continue;

166                 if (!current->filp[i])           // �����ļ�δ�򿪣��򷵻�����������

167                         return -EBADF;

168                 if (!current->filp[i]->f_inode)  // ���ļ�i�ڵ�ָ��գ��򷵻ش���š�

169                         return -EBADF;

170                 if (current->filp[i]->f_inode->i_pipe) // ���ǹܵ��ļ�������������Ч��

171                         continue;

172                 if (S_ISCHR(current->filp[i]->f_inode->i_mode)) // �ַ��豸�ļ���Ч��

173                         continue;

174                 if (S_ISFIFO(current->filp[i]->f_inode->i_mode)) // FIFOҲ��Ч��

175                         continue;

176                 return -EBADF;                   // ���඼��Ϊ��Ч�����������ء�

177         }

    // ���濪ʼѭ�����3�����������еĸ����������Ƿ�׼���ã����Բ���������ʱmask������ǰ

    // ���ڴ����������������롣ѭ���е�3������check_in()��check_out()��check_ex()�ֱ���

    // ���ж��������Ƿ��Ѿ�׼���á���һ���������Ѿ�׼���ã���������������������ö�Ӧ����

    // λ�����Ұ���׼������������������ֵcount��1����183��forѭ������е� mask += mask

    // ��Ч�� mask<< 1��

178 repeat:

179         wait_table.nr = 0;

180         *inp = *outp = *exp = 0;

181         count = 0;

182         mask = 1;

183         for (i = 0 ; i < NR_OPEN ; i++, mask += mask) {

    // �����ʱ�жϵ��������ڶ��������������У����Ҹ��������Ѿ�׼���ÿ��Խ��ж����������

    // ������������������in�ж�Ӧ����λ��Ϊ1��ͬʱ����׼������������������ֵcount��1��

184                 if (mask & in)

185                         if (check_in(&wait_table,current->filp[i]->f_inode)) {

186                                 *inp |= mask;            // �������������ö�Ӧ����λ��

187                                 count++;                 // ��׼��������������������

188                         }

    // �����ʱ�жϵ���������д�������������У����Ҹ��������Ѿ�׼���ÿ��Խ���д���������

    // ������������������out�ж�Ӧ����λ��Ϊ1��ͬʱ����׼������������������ֵcount��1��

189                 if (mask & out)

190                         if (check_out(&wait_table,current->filp[i]->f_inode)) {

191                                 *outp |= mask;

192                                 count++;

193                         }

    // �����ʱ�жϵ����������쳣���������У����Ҹ��������Ѿ����쳣���֣���Ѹ�����������

    // ������ex�ж�Ӧ����λ��Ϊ1��ͬʱ����׼������������������ֵcount��1��

194                 if (mask & ex)

195                         if (check_ex(&wait_table,current->filp[i]->f_inode)) {

196                                 *exp |= mask;

197                                 count++;

198                         }

199         }

    // �ڶԽ��������������жϴ���������û�з�������׼���õ���������count==0�������Ҵ�ʱ

    // ����û���յ��κη������źţ����Ҵ�ʱ�еȴ��ŵ����������ߵȴ�ʱ�仹û�г�ʱ����ô��

    // �ǾͰѵ�ǰ����״̬���óɿ��ж�˯��״̬��Ȼ��ִ�е��Ⱥ���ȥִ���������񡣵��ں���һ

    // �ε���ִ�б�����ʱ�͵���free_wait()������صȴ������ϱ�����ǰ�������Ȼ����ת��

    // repeat��Ŵ���178�У��ٴ����¼���Ƿ������ǹ��ĵģ����������еģ���������׼���á�

200         if (!(current->signal & ~current->blocked) &&

201             (wait_table.nr || current->timeout) && !count) {

202                 current->state = TASK_INTERRUPTIBLE;

203                 schedule();

204                 free_wait(&wait_table);        // �����񱻻��ѷ��غ�����↑ʼִ�С�

205                 goto repeat;

206         }

    // �����ʱcount������0�����߽��յ����źţ����ߵȴ�ʱ�䵽����û����Ҫ�ȴ�����������

    // ��ô���Ǿ͵���free_wait()���ѵȴ������ϵ�����Ȼ�󷵻���׼���õ�����������ֵ��

207         free_wait(&wait_table);

208         return count;

209 }

210

211 /*

212  * Note that we cannot return -ERESTARTSYS, as we change our input

213  * parameters. Sad, but there you are. We could do some tweaking in

214  * the library function ...

215  */

    /*

     * ע�����Dz��ܷ���-ERESTARTSYS����Ϊ���ǻ���select���й����иı�

     * �������ֵ��*timeout�����ܲ��ң�����Ҳֻ�ܽ��������ʵ����������

     * �����ڿ⺯������Щ����...

     */

    // selectϵͳ���ú������ú����еĴ�����Ҫ�������select���ܲ���ǰ��IJ������ƺ�ת��

    // ������select��Ҫ�Ĺ�����do_select()��������ɡ�sys_select()�����ȸ��ݲ�����������

    // ������ָ����û����ݿռ�� select() �������õIJ����ֽ⸴�Ƶ��ں˿ռ䣬Ȼ��������Ҫ

    // �ȴ��ij�ʱʱ��ֵtimeout�����ŵ���do_select() ִ�� select���ܣ����غ�ͰѴ������

    // �ٸ��ƻ��û��ռ��С�

    // ����bufferָ���û���������select()�����ĵ�1�����������������ֵС��0��ʾִ��ʱ

    // ���ִ����������ֵ����0�����ʾ�ڹ涨�ȴ�ʱ����û��������׼���ò������������ֵ

    // ����0�����ʾ��׼���õ�������������

216 int sys_select( unsigned long *buffer )

217 {

218 /* Perform the select(nd, in, out, ex, tv) system call. */

    /* ִ��select(nd, in, out, ex, tv)ϵͳ���� */

    // ���ȶ��弸���ֲ����������ڰ�ָ�������������select()���������ֽ⿪����

219         int i;

220         fd_set res_in, in = 0, *inp;                 // ����������������

221         fd_set res_out, out = 0, *outp;              // д��������������

222         fd_set res_ex, ex = 0, *exp;                 // �쳣��������������

223         fd_set mask;                                 // ��������������ֵ��Χ��nd�������롣

224         struct timeval *tvp;                         // �ȴ�ʱ��ṹָ�롣

225         unsigned long timeout;

226

    // Ȼ����û��������Ѳ����ֱ���븴�Ƶ��ֲ�ָ������У���������������ָ���Ƿ���Ч�ֱ�

    // ȡ��3����������in��������out��д����ex���쳣�������� mask Ҳ��һ����������������

    // ����3�����������������������ֵ+1������1������nd��ֵ�����������ó��û�������ĵ�

    // �����������������롣���磬��nd = 4����mask = 0b00001111����32���أ���

227         mask = ~((~0) << get_fs_long(buffer++));

228         inp = (fd_set *) get_fs_long(buffer++);

229         outp = (fd_set *) get_fs_long(buffer++);

230         exp = (fd_set *) get_fs_long(buffer++);

231         tvp = (struct timeval *) get_fs_long(buffer);

232

233         if (inp)                                   // ��ָ����Ч����ȡ����������������

234                 in = mask & get_fs_long(inp);

235         if (outp)                                  // ��ָ����Ч����ȡд��������������

236                 out = mask & get_fs_long(outp);

237         if (exp)                                   // ��ָ����Ч����ȡ�쳣����������

238                 ex = mask & get_fs_long(exp);

    // ���������dz��Դ�ʱ��ṹ��ȡ���ȴ���˯�ߣ�ʱ��ֵtimeout�����Ȱ�timeout��ʼ�������

    // �����ޣ�ֵ��Ȼ����û����ݿռ�ȡ�ø�ʱ��ṹ�����õ�ʱ��ֵ����ת���ͼ���ϵͳ��ǰ�δ�

    // ֵjiffies�����õ���Ҫ�ȴ���ʱ��δ���ֵ timeout�������ô�ֵ�����õ�ǰ����Ӧ�õȴ�

    // ����ʱ�����⣬��241����tv_usec�ֶ���΢��ֵ����������1000000��ɵõ���Ӧ�������ٳ�

    // ��ϵͳÿ��δ���HZ������tv_usecת���ɵδ�ֵ��

239         timeout = 0xffffffff;

240         if (tvp) {

241                 timeout = get_fs_long((unsigned long *)&tvp->tv_usec)/(1000000/HZ);

242                 timeout += get_fs_long((unsigned long *)&tvp->tv_sec) * HZ;

243                 timeout += jiffies;

244         }

245         current->timeout = timeout;                 // ���õ�ǰ����Ӧ����ʱ�ĵδ�ֵ��

    // select()��������Ҫ������do_select()����ɡ��ڵ��øú���֮��Ĵ������ڰѴ����������

    // ���û��������У����ظ��û���Ϊ�˱�����־����������ڵ���do_select()ǰ��Ҫ��ֹ�жϣ�

    // ���ڸú������غ��ٿ����жϡ�

    // �����do_select()����֮����̵ĵȴ���ʱ�ֶ�timeout�����ڵ�ǰϵͳ��ʱ�δ�ֵjiffies��

    // ˵���ڳ�ʱ֮ǰ�Ѿ���������׼���ã��������������ȼ��µ���ʱ��ʣ���ʱ��ֵ��������ǻ�

    // �����ֵ���ظ��û���������̵ĵȴ���ʱ�ֶ�timeout�Ѿ�С�ڻ���ڵ�ǰϵͳjiffies����

    // ʾdo_select()���������ڳ�ʱ�����أ���˰�ʣ��ʱ��ֵ����Ϊ0��

246         cli();                                  // ��ֹ��Ӧ�жϡ�

247         i = do_select(in, out, ex, &res_in, &res_out, &res_ex);

248         if (current->timeout > jiffies)

249                 timeout = current->timeout - jiffies;

250         else

251                 timeout = 0;

252         sti();                                  // �����ж���Ӧ��

    // ���������ǰѽ��̵ij�ʱ�ֶ����㡣���do_select()���ص���׼��������������С��0����ʾ

    // ִ�г��������Ƿ����������š�Ȼ�����ǰѴ������������������ݺ��ӳ�ʱ��ṹ����д�ص�

    // �û����ݻ���ռ䡣��дʱ��ṹ����ʱ����Ҫ�Ƚ��δ�ʱ�䵥λ��ʾ��ʣ���ӳ�ʱ��ת������

    // ��΢��ֵ��

253         current->timeout = 0;

254         if (i < 0)

255                 return i;

256         if (inp) {

257                 verify_area(inp, 4);

258                 put_fs_long(res_in,inp);       // �ɶ�����������

259         }

260         if (outp) {

261                 verify_area(outp,4);

262                 put_fs_long(res_out,outp);     // ��д����������

263         }

264         if (exp) {

265                 verify_area(exp,4);

266                 put_fs_long(res_ex,exp);       // �����쳣��������������

267         }

268         if (tvp) {

269                 verify_area(tvp, sizeof(*tvp));

270                 put_fs_long(timeout/HZ, (unsigned long *) &tvp->tv_sec);  // �롣

271                 timeout %= HZ;

272                 timeout *= (1000000/HZ);

273                 put_fs_long(timeout, (unsigned long *) &tvp->tv_usec);  // ΢�롣

274         }

    // �����ʱ��û����׼���õ��������������յ���ij���������źţ��򷵻ر��жϴ���š�

    // ���򷵻���׼���õ�����������ֵ��

275         if (!i && (current->signal & ~current->blocked))

276                 return -EINTR;

277         return i;

278 }

279


 


 

��13�� �ڴ��������

13.1 ����13-1 linux/mm/memory.c


  1 /*

  2  *  linux/mm/memory.c

  3  *

  4  *  (C) 1991  Linus Torvalds

  5  */

  6

  7 /*

  8  * demand-loading started 01.12.91 - seems it is high on the list of

  9  * things wanted, and it should be easy to implement. - Linus

 10  */

    /*

     * ��������Ǵ�91.12.1��ʼ��д�� - �ڳ�����Ʊ����ƺ�������Ҫ�ij���

     * ����Ӧ���Ǻ����ױ��Ƶ� - Linus

     */

 11

 12 /*

 13  * Ok, demand-loading was easy, shared pages a little bit tricker. Shared

 14  * pages started 02.12.91, seems to work. - Linus.

 15  *

 16  * Tested sharing by executing about 30 /bin/sh: under the old kernel it

 17  * would have taken more than the 6M I have free, but it worked well as

 18  * far as I could see.

 19  *

 20  * Also corrected some "invalidate()"s - I wasn't doing enough of them.

 21  */

    /*

     * OK����������DZȽ����ױ�д�ģ�������ҳ��ȴ��Ҫ�е㼼�ɡ�����ҳ�������

     * 91.12.2��ʼ��д�ģ������ܹ����� - Linus��

     *

     * ͨ��ִ�д�Լ30��/bin/sh�Թ������������˲��ԣ������ں˵�����Ҫռ�ö���

     * 6M���ڴ棬��Ŀǰȴ���á����ڿ��������úܺá�

     *

     * ��"invalidate()"����Ҳ���������� - ���ⷽ���һ����IJ�����

     */

 22

 23 /*

 24  * Real VM (paging to/from disk) started 18.12.91. Much more work and

 25  * thought has to go into this. Oh, well..

 26  * 19.12.91  -  works, somewhat. Sometimes I get faults, don't know why.

 27  *              Found it. Everything seems to work now.

 28  * 20.12.91  -  Ok, making the swap-device changeable like the root.

 29  */

    /*

     * 91.12.18��ʼ��д�����������ڴ����VM������ҳ�浽/�Ӵ��̣�����Ҫ�Դ�

     * ���Ǻܶಢ����Ҫ���ܶ๤�����Ǻǣ�Ҳֻ�������ˡ�

     * 91.12.19  -  ��ij�̶ֳ��Ͽ��Թ����ˣ�����ʱ���������֪����ô���¡�

     *              �ҵ������ˣ����ں���һ�ж��ܹ����ˡ�

     * 91.12.20  -  OK���ѽ����豸�޸ijɿɸ��ĵ��ˣ�������ļ��豸������

     */

 30

 31 #include <signal.h>       // �ź�ͷ�ļ��������źŷ��ų������źŽṹ���źź���ԭ�͡�

 32

 33 #include <asm/system.h>   // ϵͳͷ�ļ����������û��޸�������/�ж��ŵ�Ƕ����ꡣ

 34

 35 #include <linux/sched.h>  // ���ȳ���ͷ�ļ�����������ṹtask_struct������0�����ݡ�

 36 #include <linux/head.h>   // headͷ�ļ���������������ļ򵥽ṹ���ͼ���ѡ���������

 37 #include <linux/kernel.h> // �ں�ͷ�ļ�������һЩ�ں˳��ú�����ԭ�ζ��塣

 38

    // CODE_SPACE(addr) ((((addr)+0xfff)&~0xfff)<current->start_code+current->end_code)��

    // �ú������жϸ������Ե�ַ�Ƿ�λ�ڵ�ǰ���̵Ĵ�����У���(((addr)+4095)&~4095)������

    // ȡ�����Ե�ַaddr�����ڴ�ҳ���ĩ�˵�ַ���μ�265�С�

 39 #define CODE_SPACE(addr) ((((addr)+4095)&~4095) < \

 40 current->start_code + current->end_code)

 41

 42 unsigned long HIGH_MEMORY = 0;          // ȫ�ֱ��������ʵ�������ڴ���߶˵�ַ��

 43

    // ��from������1ҳ�ڴ浽to����4K�ֽڣ���

 44 #define copy_page(from,to) \

 45 __asm__("cld ; rep ; movsl"::"S" (from),"D" (to),"c" (1024):"cx","di","si")

 46

    // �����ڴ�ӳ���ֽ�ͼ��1�ֽڴ���1ҳ�ڴ棩��ÿ��ҳ���Ӧ���ֽ����ڱ�־ҳ�浱ǰ������

    // ��ռ�ã���������������ӳ��15Mb���ڴ�ռ䡣�ڳ�ʼ������mem_init()�У����ڲ�����

    // �����ڴ���ҳ���λ�þ���Ԥ�ȱ����ó�USED��100����

 47 unsigned char mem_map [ PAGING_PAGES ] = {0,};

 48

 49 /*

 50  * Free a page of memory at physical address 'addr'. Used by

 51  * 'free_page_tables()'

 52  */

    /*

     * �ͷ�������ַ'addr'����һҳ�ڴ档���ں���'free_page_tables()'��

     */

    //// �ͷ�������ַaddr��ʼ��1ҳ���ڴ档

    // ������ַ1MB���µ��ڴ�ռ������ں˳���ͻ��壬����Ϊ����ҳ����ڴ�ռ䡣���

    // ����addr��Ҫ����1MB��

 53 void free_page(unsigned long addr)

 54 {

    // �����жϲ���������������ַaddr�ĺ����ԡ����������ַaddrС���ڴ�Ͷˣ�1MB����

    // ���ʾ���ں˳������ٻ����У��Դ˲��账�������������ַaddr >= ϵͳ��������

    // �ڴ���߶ˣ�����ʾ������Ϣ�����ں�ֹͣ������

 55         if (addr < LOW_MEM) return;

 56         if (addr >= HIGH_MEMORY)

 57                 panic("trying to free nonexistent page");

    // ����Բ���addr��֤ͨ������ô�͸������������ַ��������ڴ�Ͷ˿�ʼ������ڴ�

    // ҳ��š�ҳ��� = (addr �C LOW_MEM)/4096���ɼ�ҳ��Ŵ�0�ſ�ʼ���𡣴�ʱaddr

    // �д����ҳ��š������ҳ��Ŷ�Ӧ��ҳ��ӳ���ֽڲ�����0�����1���ء���ʱ��ӳ��

    // �ֽ�ֵӦ��Ϊ0����ʾҳ�����ͷš������Ӧҳ���ֽ�ԭ������0����ʾ������ҳ�汾��

    // ���ǿ��еģ�˵���ں˴�������⡣������ʾ������Ϣ��ͣ����

 58         addr -= LOW_MEM;

 59         addr >>= 12;

 60         if (mem_map[addr]--) return;

 61         mem_map[addr]=0;

 62         panic("trying to free free page");

 63 }

 64

 65 /*

 66  * This function frees a continuos block of page tables, as needed

 67  * by 'exit()'. As does copy_page_tables(), this handles only 4Mb blocks.

 68  */

    /*

     * ���溯���ͷ�ҳ���������ڴ�飬'exit()'��Ҫ�ú�������copy_page_tables()

     * ���ƣ��ú���������4Mb���ȵ��ڴ�顣

     */

    //// ����ָ�������Ե�ַ���޳���ҳ�����������ͷŶ�Ӧ�ڴ�ҳ��ָ�����ڴ�鲢�ñ�����С�

    // ҳĿ¼λ��������ַ0��ʼ������1024�ÿ��4�ֽڣ���ռ4K�ֽڡ�ÿ��Ŀ¼��ָ��һ

    // ��ҳ�����ں�ҳ����������ַ0x1000����ʼ��������Ŀ¼�ռ䣩����4��ҳ����ÿ��ҳ����

    // 1024�ÿ��4�ֽڡ����Ҳռ4K��1ҳ���ڴ档�����̣��������ں˴����еĽ���0��1��

    // ��ҳ����ռ�ݵ�ҳ���ڽ��̱�����ʱ���ں�Ϊ�������ڴ�������õ���ÿ��ҳ�����Ӧ1ҳ

    // �����ڴ棬���һ��ҳ������ӳ��4MB�������ڴ档

    // ������from - ��ʼ���Ի���ַ��size - �ͷŵ��ֽڳ��ȡ�

 69 int free_page_tables(unsigned long from,unsigned long size)

 70 {

 71         unsigned long *pg_table;

 72         unsigned long * dir, nr;

 73

    // ���ȼ�����from���������Ի���ַ�Ƿ���4MB�ı߽紦����Ϊ�ú���ֻ�ܴ������������

    // ��from = 0���������˵����ͼ�ͷ��ں˺ͻ�����ռ�ռ䡣

 74         if (from & 0x3fffff)

 75                 panic("free_page_tables called with wrong alignment");

 76         if (!from)

 77                 panic("Trying to free up swapper memory space");

    // Ȼ��������size�����ij�����ռ��ҳĿ¼������4MB�Ľ�λ����������Ҳ����ռҳ������

    // ��Ϊ1��ҳ���ɹ���4MB�����ڴ棬��������������22λ�ķ�ʽ����Ҫ���Ƶ��ڴ泤��ֵ

    // ����4MB�����м���0x3fffff����4Mb -1�����ڵõ���λ���������������������������

    // ���1�����磬���ԭsize = 4.01Mb����ô�ɵõ����size = 2�� ���ż������������

    // ����ַ��Ӧ����ʼĿ¼���Ӧ��Ŀ¼��� = from >> 22����Ϊÿ��ռ4�ֽڣ���������

    // ҳĿ¼����������ַ0��ʼ��ţ����ʵ��Ŀ¼��ָ�� = Ŀ¼���<<2��Ҳ��(from>>20)��

    // ��������0xffcȷ��Ŀ¼��ָ�뷶Χ��Ч��

 78         size = (size + 0x3fffff) >> 22;

 79         dir = (unsigned long *) ((from>>20) & 0xffc); /* _pg_dir = 0 */

 

    // ��ʱ size ���ͷŵ�ҳ����������ҳĿ¼��������dir����ʼĿ¼��ָ�롣���ڿ�ʼѭ��

    // ����ҳĿ¼������ͷ�ÿ��ҳ���е�ҳ��������ǰĿ¼����Ч��Pλ=0������ʾ��

    // Ŀ¼��û��ʹ�ã���Ӧ��ҳ�������ڣ��������������һ��Ŀ¼������Ŀ¼����ȡ��

    // ҳ����ַ pg_table�����Ը�ҳ���е� 1024 ��������д������ͷ���Чҳ���Pλ=1��

    // ��Ӧ�������ڴ�ҳ�棬���ߴӽ����豸���ͷ���Чҳ���Pλ=0����Ӧ��ҳ�棬���ͷ�

    // �����豸�ж�Ӧ���ڴ�ҳ�棨��Ϊҳ������Ѿ�������ȥ����Ȼ��Ѹ�ҳ�������㣬����

    // ��������һҳ�����һ��ҳ�����б��������Ͼ��ͷŸ�ҳ������ռ�ݵ��ڴ�ҳ�棬

    // ������������һҳĿ¼����ˢ��ҳ�任���ٻ��壬������0��

 80         for ( ; size-->0 ; dir++) {

 81                 if (!(1 & *dir))

 82                         continue;

 83                 pg_table = (unsigned long *) (0xfffff000 & *dir);  // ȡҳ����ַ��

 84                 for (nr=0 ; nr<1024 ; nr++) {

 85                         if (*pg_table) {             // ����ָҳ�������ݲ�Ϊ0����

 86                                 if (1 & *pg_table)   // ��������Ч�����ͷŶ�Ӧҳ��

 87                                         free_page(0xfffff000 & *pg_table);

 88                                 else                 // �����ͷŽ����豸�ж�Ӧҳ��

 89                                         swap_free(*pg_table >> 1);

 90                                 *pg_table = 0;       // ��ҳ�����������㡣

 91                         }

 92                         pg_table++;                  // ָ��ҳ������һ�

 93                 }

 94                 free_page(0xfffff000 & *dir);        // �ͷŸ�ҳ����ռ�ڴ�ҳ�档

 95                 *dir = 0;                            // ��Ӧҳ����Ŀ¼�����㡣

 96         }

 97         invalidate();                                // ˢ��CPUҳ�任���ٻ��塣

 98         return 0;

 99 }

100

101 /*

102  *  Well, here is one of the most complicated functions in mm. It

103  * copies a range of linerar addresses by copying only the pages.

104  * Let's hope this is bug-free, 'cause this one I don't want to debug :-)

105  *

106  * Note! We don't copy just any chunks of memory - addresses have to

107  * be divisible by 4Mb (one page-directory entry), as this makes the

108  * function easier. It's used only by fork anyway.

109  *

110  * NOTE 2!! When from==0 we are copying kernel space for the first

111  * fork(). Then we DONT want to copy a full page-directory entry, as

112  * that would lead to some serious memory waste - we just copy the

113  * first 160 pages - 640kB. Even that is more than we need, but it

114  * doesn't take any more memory - we don't copy-on-write in the low

115  * 1 Mb-range, so the pages can be shared with the kernel. Thus the

116  * special case for nr=xxxx.

117  */

    /*

     * ���ˣ��������ڴ����mm����Ϊ���ӵij���֮һ����ͨ��ֻ�����ڴ�ҳ��

     * ������һ����Χ�����Ե�ַ�е����ݡ� ϣ��������û�д�����Ϊ�Ҳ���

     * �ٵ�����������:-)��

     *

     * ע�⣡���Dz��������κ��ڴ�� - �ڴ��ĵ�ַ��Ҫ��4Mb�ı���������

     * һ��ҳĿ¼���Ӧ���ڴ泤�ȣ�����Ϊ����������ʹ�����ܼ򵥡� ������

     * ����������fork()ʹ�á�

     *

     * ע��2���� ��from==0ʱ��˵������Ϊ��һ��fork()���ø����ں˿ռ䡣

     * ��ʱ���ǾͲ��븴������ҳĿ¼���Ӧ���ڴ棬��Ϊ�������ᵼ���ڴ���

     * ���˷� - ����ֻ�븴�ƿ�ͷ160��ҳ�� - ��Ӧ 640kB����ʹ�Ǹ�����Щ

     * ҳ��Ҳ�Ѿ��������ǵ����󣬵��ⲻ��ռ�ø�����ڴ� - �ڵ� 1Mb �ڴ�

     * ��Χ�����Dz�ִ��дʱ���Ʋ�����������Щҳ��������ں˹����������

     * ��nr=xxxx�����������nr�ڳ�����ָҳ��������

     */

    //// ����ҳĿ¼�����ҳ���

    // ����ָ�����Ե�ַ�ͳ����ڴ��Ӧ��ҳĿ¼���ҳ����Ӷ������Ƶ�ҳĿ¼��ҳ����Ӧ

    // ��ԭ�����ڴ�ҳ����������ҳ��ӳ�������ʹ�á�����ʱ����������ҳ���������ҳ����

    // ԭ�����ڴ��������������˺��������̣������̺����ӽ��̣��������ڴ�����ֱ����һ��

    // ����ִ��д����ʱ���ں˲Ż�Ϊд�������̷����µ��ڴ�ҳ��дʱ���ƻ��ƣ���

    // ����from��to �����Ե�ַ��size����Ҫ���ƣ����������ڴ泤�ȣ���λ���ֽڡ�

118 int copy_page_tables(unsigned long from,unsigned long to,long size)

119 {

120         unsigned long * from_page_table;

121         unsigned long * to_page_table;

122         unsigned long this_page;

123         unsigned long * from_dir, * to_dir;

124         unsigned long new_page;

125         unsigned long nr;

126

    // ���ȼ�����������Դ��ַfrom��Ŀ�ĵ�ַto����Ч�ԡ�Դ��ַ��Ŀ�ĵ�ַ����Ҫ��4Mb

    // �ڴ�߽��ַ�ϡ����������������������Ҫ������Ϊһ��ҳ����1024��ɹ���4Mb�ڴ档

    // Դ��ַ from ��Ŀ�ĵ�ַ to ֻ���������Ҫ����ܱ�֤��һ��ҳ���ĵ�1�ʼ����ҳ��

    // �������ҳ����������������Ч�ġ�  Ȼ��ȡ��Դ��ַ��Ŀ�ĵ�ַ����ʼĿ¼��ָ��

    // ��from_dir��to_dir�����ٸ��ݲ��������ij���size����Ҫ���Ƶ��ڴ��ռ�õ�ҳ����

    // ����Ŀ¼���������μ�ǰ���78��79�еĽ��͡�

127         if ((from&0x3fffff) || (to&0x3fffff))

128                 panic("copy_page_tables called with wrong alignment");

129         from_dir = (unsigned long *) ((from>>20) & 0xffc); /* _pg_dir = 0 */

130         to_dir = (unsigned long *) ((to>>20) & 0xffc);

131         size = ((unsigned) (size+0x3fffff)) >> 22;

    // �ڵõ���Դ��ʼĿ¼��ָ��from_dir��Ŀ����ʼĿ¼��ָ��to_dir�Լ���Ҫ���Ƶ�ҳ��

    // ���� size �����濪ʼ��ÿ��ҳĿ¼����������1ҳ�ڴ��������Ӧ��ҳ�������ҿ�ʼ

    // ҳ����Ʋ��������Ŀ��Ŀ¼��ָ����ҳ���Ѿ����ڣ�P=1��������������� ���ԴĿ

    // ¼����Ч����ָ����ҳ�������ڣ�P=0���������ѭ��������һ��ҳĿ¼�

132         for( ; size-->0 ; from_dir++,to_dir++) {

133                 if (1 & *to_dir)

134                         panic("copy_page_tables: already exist");

135                 if (!(1 & *from_dir))

136                         continue;

 

    // ����֤�˵�ǰԴĿ¼���Ŀ��������֮������ȡԴĿ¼����ҳ����ַfrom_page_table��

    // Ϊ�˱���Ŀ��Ŀ¼���Ӧ��ҳ������Ҫ�����ڴ���������1ҳ�����ڴ�ҳ�����ȡ����ҳ��

    // ����get_free_page() ����0����˵��û�����뵽�����ڴ�ҳ�棬�������ڴ治�������Ƿ�

    // ��-1ֵ�˳���

137                 from_page_table = (unsigned long *) (0xfffff000 & *from_dir);

138                 if (!(to_page_table = (unsigned long *) get_free_page()))

139                         return -1;      /* Out of memory, see freeing */

 

    // ������������Ŀ��Ŀ¼����Ϣ�������3λ��λ������ǰĿ��Ŀ¼�����7����ʾ��Ӧ

    // ҳ��ӳ����ڴ�ҳ�����û����ģ����ҿɶ�д�����ڣ�Usr, R/W, Present���� �����U/S

    // λ��0����R/W��û�����á���� U/S��1���� R/W��0����ô�������û���Ĵ����ֻ��

    // ��ҳ�档���U/S��R/W����λ������ж�д��Ȩ�ޣ���Ȼ����Ե�ǰ������ҳĿ¼���Ӧ

    // ��ҳ����������Ҫ���Ƶ�ҳ����������������ں˿ռ䣬����踴��ͷ160ҳ��Ӧ��ҳ����

    // ��nr= 160������Ӧ�ڿ�ʼ640KB�����ڴ档������Ҫ����һ��ҳ���е�����1024��ҳ����

    // ��nr= 1024������ӳ��4MB�����ڴ档

140                 *to_dir = ((unsigned long) to_page_table) | 7;

141                 nr = (from==0)?0xA0:1024;

 

    // ��ʱ���ڵ�ǰҳ������ʼѭ������ָ����nr���ڴ�ҳ������ȡ��Դҳ�������ݣ����

    // ��ǰԴҳ��û��ʹ�ã�������Ϊ0�������ø��Ƹñ������������һ�

142                 for ( ; nr-- > 0 ; from_page_table++,to_page_table++) {

143                         this_page = *from_page_table;

144                         if (!this_page)

145                                 continue;

    // ����ñ��������ݣ����������λP=0����ñ����Ӧ��ҳ������ڽ����豸�С���������

    // ��1ҳ�ڴ棬���ӽ����豸�ж����ҳ�棨�������豸���еĻ�����Ȼ�󽫸�ҳ����Ƶ�

    // Ŀ��ҳ�����С����޸�Դҳ��������ָ�����������ڴ�ҳ�������ñ����־Ϊ��ҳ���ࡱ

    // ����7��Ȼ�����������һҳ�������λҳ������ R/W ��־��λ1��0��������ҳ����

    // ��Ӧ���ڴ�ҳ��ֻ����Ȼ�󽫸�ҳ����Ƶ�Ŀ��ҳ���С�

146                         if (!(1 & this_page)) {

147                                 if (!(new_page = get_free_page()))

148                                         return -1;

149                                 read_swap_page(this_page>>1, (char *) new_page);

150                                 *to_page_table = this_page;

151                                 *from_page_table = new_page | (PAGE_DIRTY | 7);

152                                 continue;

153                         }

154                         this_page &= ~2;

155                         *to_page_table = this_page;

 

    // �����ҳ������ָ����ҳ��ĵ�ַ��1MB���ϣ�����Ҫ�����ڴ�ҳ��ӳ������mem_map[]��

    // ���Ǽ���ҳ��ţ�������Ϊ������ҳ��ӳ��������Ӧ�����������ô�����������λ��1MB

    // ���µ�ҳ�棬˵�����ں�ҳ�棬��˲���Ҫ��mem_map[]�������á���Ϊ mem_map[]����

    // �ڹ������ڴ����е�ҳ��ʹ������� ��˶����ں��ƶ�������0�в��ҵ���fork()����

    // ����1ʱ����������init()�������ڴ�ʱ���Ƶ�ҳ�滹��Ȼ�����ں˴��������������

    // �ж��е���䲻��ִ�У�����0 ��ҳ����Ȼ������ʱ��д��ֻ�е����� fork() �ĸ�����

    // ���봦�����ڴ�����ҳ��λ�ô���1MB��ʱ�Ż�ִ�С����������Ҫ�ڽ��̵���execve()��

    // ��װ��ִ�����³������ʱ�Ż���֡�

    // 157����京������Դҳ������ָ�ڴ�ҳҲΪֻ������Ϊ���ڿ�ʼ�����������̹����ڴ�

    // ���ˡ�������1��������Ҫ����д�����������ͨ��ҳ�쳣д��������Ϊִ��д�����Ľ�

    // �̷���1ҳ�¿���ҳ�棬Ҳ������дʱ���ƣ�copy on write��������

156                         if (this_page > LOW_MEM) {

157                                 *from_page_table = this_page; // ��Դҳ����Ҳֻ����

158                                 this_page -= LOW_MEM;

159                                 this_page >>= 12;

160                                 mem_map[this_page]++;

161                         }

162                 }

163         }

164         invalidate();                            // ˢ��ҳ�任���ٻ��塣

165         return 0;

166 }

167

168 /*

169  * This function puts a page in memory at the wanted address.

170  * It returns the physical address of the page gotten, 0 if

171  * out of memory (either when trying to access page-table or

172  * page.)

173  */

    /*

     * ���溯����һ�ڴ�ҳ����ã�ӳ�䣩��ָ�����Ե�ַ����������ҳ��

     * ��������ַ������ڴ治��(�ڷ���ҳ����ҳ��ʱ)���򷵻�0��

     */

    // ��һ�����ڴ�ҳ��ӳ�䵽���Ե�ַ�ռ�ָ������

    // ����˵�ǰ����Ե�ַ�ռ���ָ����ַaddress����ҳ��ӳ�䵽���ڴ���ҳ��page�ϡ���Ҫ

    // �����������ҳĿ¼���ҳ����������ָ��ҳ�����Ϣ�����ɹ��򷵻�����ҳ���ַ�� ��

    // ����ȱҳ�쳣��C����do_no_page() �л���ô˺���������ȱҳ������쳣�������κ�ȱ

    // ҳԵ�ʶ���ҳ�����޸�ʱ��������Ҫˢ��CPU��ҳ�任���壨���Translation Lookaside

    // Buffer - TLB������ʹҳ�����б�־P����0�޸ij�1����Ϊ��Чҳ��ᱻ���壬��˵�

    // �޸���һ����Ч��ҳ����ʱ����Ҫˢ�¡��ڴ˾ͱ���Ϊ���õ���Invalidate()������

    // ����page�Ƿ�������ڴ�����ijһҳ�棨ҳ֡��ҳ�򣩵�ָ�룻address�����Ե�ַ��

174 static unsigned long put_page(unsigned long page,unsigned long address)

175 {

176         unsigned long tmp, *page_table;

177

178 /* NOTE !!! This uses the fact that _pg_dir=0 */

    /* ע��!!! ����ʹ����ҳĿ¼������ַ_pg_dir=0������ */

179

    // �����жϲ������������ڴ�ҳ��page ����Ч�ԡ������ҳ��λ�õ���LOW_MEM��1MB����

    // ����ϵͳʵ�ʺ����ڴ�߶� HIGH_MEMORY���򷢳����档LOW_MEM �����ڴ��������е���

    // С��ʼλ�á���ϵͳ�����ڴ�С�ڻ����6MBʱ�����ڴ�����ʼ��LOW_MEM�����ٲ鿴һ

    // �¸� pageҳ���Ƿ����Ѿ������ҳ�棬���ж������ڴ�ҳ��ӳ���ֽ�ͼ mem_map[]����

    // Ӧ�ֽ��Ƿ��Ѿ���λ����û�����跢�����档

180         if (page < LOW_MEM || page >= HIGH_MEMORY)

181                 printk("Trying to put page %p at %p\n",page,address);

182         if (mem_map[(page-LOW_MEM)>>12] != 1)

183                 printk("mem_map disagrees with %p at %p\n",page,address);

 

    // Ȼ����ݲ���ָ�������Ե�ַaddress��������ҳĿ¼���ж�Ӧ��Ŀ¼��ָ�룬������ȡ��

    // ����ҳ����ַ�� �����Ŀ¼����Ч��P=1������ָ����ҳ�����ڴ��У������ȡ��ָ��ҳ��

    // ��ַ�ŵ�page_table �����С���������һ����ҳ���ҳ��ʹ�ã����ڶ�ӦĿ¼��������Ӧ

    // ��־��7 �C User��U/S��R/W����Ȼ�󽫸�ҳ����ַ�ŵ�page_table�����С�

184         page_table = (unsigned long *) ((address>>20) & 0xffc);

185         if ((*page_table)&1)

186                 page_table = (unsigned long *) (0xfffff000 & *page_table);

187         else {

188                 if (!(tmp=get_free_page()))

189                         return 0;

190                 *page_table = tmp | 7;

191                 page_table = (unsigned long *) tmp;

192         }

    // ������ҵ���ҳ�� page_table ���������ҳ�������ݣ���������ҳ��page�ĵ�ַ�����

    // ��ͬʱ��λ3����־��U/S��W/R��P������ҳ������ҳ���е�����ֵ�������Ե�ַλ21 --

    // λ12��ɵ�10���ص�ֵ��ÿ��ҳ��������1024�0 -- 0x3ff����

193         page_table[(address>>12) & 0x3ff] = page | 7;

194 /* no need for invalidate */

    /* ����Ҫˢ��ҳ�任���ٻ��� */

195         return page;                    // ��������ҳ���ַ��

196 }

197

198 /*

199  * The previous function doesn't work very well if you also want to mark

200  * the page dirty: exec.c wants this, as it has earlier changed the page,

201  * and we want the dirty-status to be correct (for VM). Thus the same

202  * routine, but this time we mark it dirty too.

203  */

    /*

     * �����Ҳ������ҳ�����޸ı�־������һ�����������ò��Ǻܺã�exec.c����

     * ��Ҫ�������á���Ϊexec.c�к������ڷ���ҳ��֮ǰ�޸Ĺ�ҳ�����ݡ�Ϊ��ʵ

     * ��VM��������Ҫ����ȷ�������޸�״̬��־����������������������ͬ�ĺ�

     * �������Ǹú����ڷ���ҳ��ʱ���ҳ���־Ϊ���޸�״̬��

     */

    // ��һ�������޸Ĺ��������ڴ�ҳ��ӳ�䵽���Ե�ַ�ռ�ָ������

    // �ú�������һ������put_page()������ȫһ�������˱�������223������ҳ��������ʱ��

    // ͬʱ��������ҳ�����޸ı�־��λ6��PAGE_DIRTY����

204 unsigned long put_dirty_page(unsigned long page, unsigned long address)

205 {

206         unsigned long tmp, *page_table;

207

208 /* NOTE !!! This uses the fact that _pg_dir=0 */

209

210         if (page < LOW_MEM || page >= HIGH_MEMORY)

211                 printk("Trying to put page %p at %p\n",page,address);

212         if (mem_map[(page-LOW_MEM)>>12] != 1)

213                 printk("mem_map disagrees with %p at %p\n",page,address);

214         page_table = (unsigned long *) ((address>>20) & 0xffc);

215         if ((*page_table)&1)

216                 page_table = (unsigned long *) (0xfffff000 & *page_table);

217         else {

218                 if (!(tmp=get_free_page()))

219                         return 0;

220                 *page_table = tmp|7;

221                 page_table = (unsigned long *) tmp;

222         }

223         page_table[(address>>12) & 0x3ff] = page | (PAGE_DIRTY | 7);

224 /* no need for invalidate */

225         return page;

226 }

227

    //// ȡ��д����ҳ�溯��������ҳ�쳣�жϹ�����д�����쳣�Ĵ�����дʱ���ƣ���

    // ���ں˴�������ʱ���½����븸���̱����óɹ�������������ڴ�ҳ�棬����������Щҳ��

    // �������ó�ֻ��ҳ�档�����½��̻�ԭ������Ҫ���ڴ�ҳ��д����ʱ��CPU �ͻ��⵽���

    // ���������ҳ��д�����쳣������������������ں˾ͻ������ж�Ҫд��ҳ���Ƿ񱻹�����

    // ��û�����ҳ�����óɿ�дȻ���˳�����ҳ���dz��ڹ���״̬������Ҫ��������һ��ҳ�沢

    // ���Ʊ�дҳ�����ݣ��Թ�д���̵���ʹ�á�������ȡ����

    // �������Ϊҳ����ָ�룬��������ַ��[ un_wp_page -- Un-Write Protect Page]

228 void un_wp_page(unsigned long * table_entry)

229 {

230         unsigned long old_page,new_page;

231

    // ����ȡ����ָ����ҳ����������ҳ��λ�ã���ַ�����жϸ�ҳ���Ƿ��ǹ���ҳ�档���ԭ

    // ҳ���ַ�����ڴ�Ͷ� LOW_MEM����ʾ�����ڴ����У�����������ҳ��ӳ���ֽ�ͼ������

    // ֵΪ1����ʾҳ���������1�Σ�ҳ��û�б������������ڸ�ҳ���ҳ�������� R/W ��־

    // ����д������ˢ��ҳ�任���ٻ��壬Ȼ�󷵻ء���������ڴ�ҳ���ʱֻ��һ������ʹ�ã�

    // ���Ҳ����ں��еĽ��̣���ֱ�Ӱ����Ը�Ϊ��д���ɣ���������������һ����ҳ�档

232         old_page = 0xfffff000 & *table_entry;      // ȡָ��ҳ����������ҳ���ַ��

233         if (old_page >= LOW_MEM && mem_map[MAP_NR(old_page)]==1) {

234                 *table_entry |= 2;

235                 invalidate();

236                 return;

237         }

    // �������Ҫ�����ڴ���������һҳ����ҳ���ִ��д�����Ľ��̵���ʹ�ã�ȡ��ҳ�湲����

    // ���ԭҳ������ڴ�Ͷˣ�����ζ�� mem_map[] > 1��ҳ���ǹ����ģ�����ԭҳ���ҳ

    // ��ӳ���ֽ�����ֵ�ݼ�1��Ȼ��ָ��ҳ�������ݸ���Ϊ��ҳ���ַ�����ÿɶ�д�ȱ�־

    // ��U/S��R/W��P������ˢ��ҳ�任���ٻ���֮�����ԭҳ�����ݸ��Ƶ���ҳ�档

238         if (!(new_page=get_free_page()))

239                 oom();                             // Out of Memory���ڴ治��������

240         if (old_page >= LOW_MEM)

241                 mem_map[MAP_NR(old_page)]--;

242         copy_page(old_page,new_page);

243         *table_entry = new_page | 7;

244         invalidate();

245 }      

246

247 /*

248  * This routine handles present pages, when users try to write

249  * to a shared page. It is done by copying the page to a new address

250  * and decrementing the shared-page counter for the old page.

251  *

252  * If it's in code space we exit with a segment error.

253  */

    /*

     * ���û���ͼ��һ����ҳ����дʱ���ú��������Ѵ��ڵ��ڴ�ҳ�棨дʱ���ƣ���

     * ����ͨ����ҳ�渴�Ƶ�һ���µ�ַ�ϲ��ҵݼ�ԭҳ��Ĺ�������ֵʵ�ֵġ�

     *

     * ������ڴ���ռ䣬���Ǿ���ʾ�γ�����Ϣ���˳���

     */

    //// ִ��д����ҳ�洦����

    // ��д����ҳ�洦����������ҳ�쳣�жϴ��������е��õ�C��������page.s�����б����á�

    // ��������error_code �� address �ǽ�����дд����ҳ��ʱ�� CPU�����쳣���Զ����ɵġ�

    // error_codeָ���������ͣ��μ����¿�ʼ���ġ��ڴ�ҳ������쳣��һ�ڣ�address�Dz���

    // �쳣��ҳ�����Ե�ַ��д����ҳ��ʱ�踴��ҳ�棨дʱ���ƣ���

254 void do_wp_page(unsigned long error_code,unsigned long address)

255 {

    // �����ж�CPU���ƼĴ���CR2����������ҳ���쳣�����Ե�ַ��ʲô��Χ�С����address

    // С�� TASK_SIZE��0x4000000����64MB������ʾ�쳣ҳ��λ�����ں˻�����0������1����

    // �����Ե�ַ��Χ�ڣ����Ƿ���������Ϣ���ں˷�Χ�ڴ汻д����������� (address�C��ǰ

    // ���̴�����ʼ��ַ)����һ�����̵ij��ȣ�64MB������ʾaddress��ָ�����Ե�ַ��������

    // �쳣�Ľ������Ե�ַ�ռ䷶Χ�ڣ����ڷ���������Ϣ���˳���

256         if (address < TASK_SIZE)

257                 printk("\n\rBAD! KERNEL MEMORY WP-ERR!\n\r");

258         if (address - current->start_code > TASK_SIZE) {

259                 printk("Bad things happen: page error in do_wp_page\n\r");

260                 do_exit(SIGSEGV);

261         }

262 #if 0

263 /* we cannot do this yet: the estdio library writes to code space */

264 /* stupid, stupid. I really want the libc.a from GNU */

    /* �������ڻ���������������Ϊestdio����ڴ���ռ�ִ��д���� */

    /* ����̫�޴��ˡ��������GNU�õ�libc.a�⡣*/

    // ������Ե�ַλ�ڽ��̵Ĵ���ռ��У�����ִֹ�г�����Ϊ������ֻ���ġ�

265         if (CODE_SPACE(address))

266                 do_exit(SIGSEGV);

267 #endif

    // �������溯��un_wp_page()������ȡ��ҳ�汣������������ҪΪ��׼���ò�����������

    // ���Ե�ַaddressָ��ҳ����ҳ���е�ҳ����ָ�룬����㷽���ǣ�

    // �� ((address>>10) & 0xffc)������ָ�����Ե�ַ��ҳ������ҳ���е�ƫ�Ƶ�ַ����Ϊ

    // �������Ե�ַ�ṹ��(address>>12) ����ҳ�����е���������ÿ��ռ4���ֽڣ���˳�

    // 4��(address>>12)<<2 = (address>>10)&0xffc �Ϳɵõ�ҳ�����ڱ��е�ƫ�Ƶ�ַ��

    // �����&0xffc�������Ƶ�ַ��Χ��һ��ҳ���ڡ� ����Ϊֻ�ƶ���10λ��������2λ

    // �����Ե�ַ��12 λ�е����2λ��ҲӦ���ε��� ��������Ե�ַ��ҳ������ҳ����ƫ

    // �Ƶ�ֱַ��һЩ�ı�ʾ������(((address>>12) & 0x3ff)<<2 )��

    // �� (0xfffff000 & *((address>>20) &0xffc))������ȡĿ¼����ҳ���ĵ�ֵַ�����У�

    // ((address>>20) &0xffc)����ȡ���Ե�ַ�е�Ŀ¼��������Ŀ¼���е�ƫ��λ�á���Ϊ

    // address>>22 ��Ŀ¼������ֵ����ÿ��4���ֽڣ���˳���4�� (address>>22)<<2

    // = (address>>20) ����ָ������Ŀ¼���е�ƫ�Ƶ�ַ�� &0xffc��������Ŀ¼������ֵ

    // �����2λ����Ϊֻ�ƶ���20λ��������2λ��ҳ�����������ݣ�Ӧ�����ε�����

    // *((address>>20) &0xffc) ����ȡָ��Ŀ¼���������ж�Ӧҳ����������ַ���������

    // 0xffffff000�������ε�ҳĿ¼�������е�һЩ��־λ��Ŀ¼���12λ����ֱ�۱�ʾΪ

    // (0xffffff000 & *((unsigned long *) (((address>>22) & 0x3ff)<<2)))��

    // �� �ɢ���ҳ������ҳ����ƫ�Ƶ�ַ���� ����Ŀ¼���������ж�Ӧҳ����������ַ����

    // �õ�ҳ�����ָ�루������ַ��������Թ�����ҳ����и��ơ�

268         un_wp_page((unsigned long *)

269                 (((address>>10) & 0xffc) + (0xfffff000 &

270                 *((unsigned long *) ((address>>20) &0xffc)))));

271

272 }

273

    //// дҳ����֤��

    // ��ҳ�治��д������ҳ�档��fork.c�е�34�б��ڴ���֤ͨ�ú���verify_area()���á�

    // ����address��ָ��ҳ����4G�ռ��е����Ե�ַ��

274 void write_verify(unsigned long address)

275 {

276         unsigned long page;

277

    // ����ȡָ�����Ե�ַ��Ӧ��ҳĿ¼�����Ŀ¼���еĴ���λ��P���ж�Ŀ¼���Ӧ��ҳ��

    // �Ƿ���ڣ�����λP=1?�����������ڣ�P=0���򷵻ء�������������Ϊ���ڲ����ڵ�ҳ��û

    // �й�����дʱ���ƿ��ԣ�����������Դ˲����ڵ�ҳ��ִ��д����ʱ��ϵͳ�ͻ���Ϊȱҳ��

    // ����ȥִ��do_no_page()����Ϊ����ط�ʹ�� put_page()����ӳ��һ������ҳ�档

    // ���ų����Ŀ¼����ȡҳ����ַ������ָ��ҳ����ҳ���е�ҳ����ƫ��ֵ���ö�Ӧ��ַ��ҳ

    // ����ָ�롣�ڸñ����а����Ÿ������Ե�ַ��Ӧ������ҳ�档

278         if (!( (page = *((unsigned long *) ((address>>20) & 0xffc)) )&1))

279                 return;

280         page &= 0xfffff000;

281         page += ((address>>10) & 0xffc);

    // Ȼ���жϸ�ҳ�����е�λ1��R/W����λ0��P����־�������ҳ�治��д��R/W=0���Ҵ��ڣ�

    // ��ô��ִ�й�������͸���ҳ�������дʱ���ƣ�������ʲôҲ������ֱ���˳���

282         if ((3 & *(unsigned long *) page) == 1)  /* non-writeable, present */

283                 un_wp_page((unsigned long *) page);

284         return;

285 }

286

    //// ȡ��һҳ�����ڴ�ҳ��ӳ�䵽ָ�����Ե�ַ����

    // get_free_page()��������ȡ�������ڴ�����һҳ�����ڴ档���������򲻽��ǻ�ȡ��һҳ

    // �����ڴ�ҳ�棬����һ������put_page()��������ҳ��ӳ�䵽ָ�������Ե�ַ����

    // ����address��ָ��ҳ������Ե�ַ��

287 void get_empty_page(unsigned long address)

288 {

289         unsigned long tmp;

290

    // ������ȡ��һ����ҳ�棬���߲��ܽ���ȡҳ����õ�ָ����ַ��������ʾ�ڴ治������Ϣ��

    // 292����Ӣ��ע�͵ĺ����ǣ�free_page()�����IJ���tmp��0Ҳû�й�ϵ���ú��������

    // �������������ء�

291         if (!(tmp=get_free_page()) || !put_page(tmp,address)) {

292                 free_page(tmp);         /* 0 is ok - ignored */

293                 oom();

294         }

295 }

296

297 /*

298  * try_to_share() checks the page at address "address" in the task "p",

299  * to see if it exists, and if it is clean. If so, share it with the current

300  * task.

301  *

302  * NOTE! This assumes we have checked that p != current, and that they

303  * share the same executable or library.

304  */

    /*

     * try_to_share()������"p"�м��λ�ڵ�ַ"address"����ҳ�棬��ҳ���Ƿ���ڣ�

     * �Ƿ�ɾ�������Ǹɾ��Ļ������뵱ǰ��������

     *

     * ע�⣡���������Ѽٶ�p !=��ǰ���񣬲������ǹ���ͬһ��ִ�г��������

     */

    //// ���ԶԵ�ǰ����ָ����ַ����ҳ����й���������

    // ��ǰ���������p��ͬһִ�д��룬Ҳ������Ϊ��ǰ��������p����ִ��fork����������

    // ���̣�������ǵĴ�������һ�������δ�����ݶ����������޸���ô���ݶ�����ҲӦһ����

    // ���� address �ǽ����е��߼���ַ�����ǵ�ǰ�������� p ���̹���ҳ����߼�ҳ���ַ��

    // ����p�ǽ�������ҳ��Ľ��̡����p����address����ҳ����ڲ���û�б��޸Ĺ��Ļ���

    // ���õ�ǰ������p���̹���֮��ͬʱ����Ҫ��ָ֤���ĵ�ַ���Ƿ��Ѿ�������ҳ�棬����

    // ����������������أ�1 - ҳ�湲�������ɹ���0 - ʧ�ܡ�

305 static int try_to_share(unsigned long address, struct task_struct * p)

306 {

307         unsigned long from;

308         unsigned long to;

309         unsigned long from_page;

310         unsigned long to_page;

311         unsigned long phys_addr;

312

    // ���ȷֱ����ָ������p�к͵�ǰ�������߼���ַaddress��Ӧ��ҳĿ¼�Ϊ�˼��㷽��

    // �����ָ���߼���ַaddress����'�߼�'ҳĿ¼��ţ����Խ��̿ռ䣨0 - 64MB�������ҳ

    // Ŀ¼��š���'�߼�'ҳĿ¼��ż��Ͻ���p ��CPU 4G���Կռ�����ʼ��ַ��Ӧ��ҳĿ¼�

    // ���õ�����p�е�ַ address ��ҳ������Ӧ��4G ���Կռ��е�ʵ��ҳĿ¼��from_page��

    // ��'�߼�'ҳĿ¼��ż��ϵ�ǰ����CPU 4G ���Կռ�����ʼ��ַ��Ӧ��ҳĿ¼��������

    // �õ���ǰ�����е�ַaddress��ҳ������Ӧ��4G���Կռ��е�ʵ��ҳĿ¼��to_page��

313         from_page = to_page = ((address>>20) & 0xffc);

314         from_page += ((p->start_code>>20) & 0xffc);      // p����Ŀ¼�

315         to_page += ((current->start_code>>20) & 0xffc);  // ��ǰ����Ŀ¼�

 

    // �ڵõ�p���̺͵�ǰ����address��Ӧ��Ŀ¼�������ֱ�Խ���p�͵�ǰ���̽��д�����

    // �������ȶ�p���̵ı�����в�����Ŀ����ȡ��p������ address��Ӧ�������ڴ�ҳ���ַ��

    // ���Ҹ�����ҳ����ڣ����Ҹɾ���û�б��޸Ĺ������ࣩ��

    // ��������ȡĿ¼�����ݡ������Ŀ¼����Ч��P=0������ʾĿ¼���Ӧ�Ķ���ҳ�������ڣ�

    // ���Ƿ��ء�����ȡ��Ŀ¼���Ӧҳ����ַfrom���Ӷ�������߼���ַaddress��Ӧ��ҳ����

    // ָ�룬��ȡ����ҳ����������ʱ������phys_addr�С�

316 /* is there a page-directory at from? */

    /* ��from���Ƿ����ҳĿ¼�*/

317         from = *(unsigned long *) from_page;           // p����Ŀ¼�����ݡ�

318         if (!(from & 1))

319                 return 0;

320         from &= 0xfffff000;                            // ҳ����ַ��

321         from_page = from + ((address>>10) & 0xffc);    // ҳ����ָ�롣

322         phys_addr = *(unsigned long *) from_page;      // ҳ�������ݡ�

    // ���ſ���ҳ����ӳ�������ҳ���Ƿ���ڲ��Ҹɾ��� 0x41 ��Ӧҳ�����е�D��Dirty����

    // P��Present����־�����ҳ�治�ɾ�����Ч�򷵻ء�Ȼ�����ǴӸñ�����ȡ������ҳ���ַ

    // �ٱ�����phys_addr�С���������ټ��һ���������ҳ���ַ����Ч�ԣ�������Ӧ�ó���

    // �������������ֵַ��Ҳ��Ӧ��С���ڴ�Ͷ�(1MB)��

323 /* is the page clean and present? */

    /* ����ҳ��ɾ����Ҵ�����*/

324         if ((phys_addr & 0x41) != 0x01)

325                 return 0;

326         phys_addr &= 0xfffff000;                       // ����ҳ���ַ��

327         if (phys_addr >= HIGH_MEMORY || phys_addr < LOW_MEM)

328                 return 0;

 

    // �������ȶԵ�ǰ���̵ı�����в�����Ŀ����ȡ�õ�ǰ������address��Ӧ��ҳ�����ַ��

    // ���Ҹ�ҳ���û��ӳ������ҳ�棬����P=0��

    // ����ȡ��ǰ����ҳĿ¼��������to�������Ŀ¼����Ч��P=0������Ŀ¼���Ӧ�Ķ���ҳ��

    // �����ڣ�������һ����ҳ�������ҳ����������Ŀ¼��to_page���ݣ�����ָ����ڴ�ҳ�档

329         to = *(unsigned long *) to_page;               // ��ǰ����Ŀ¼�����ݡ�

330         if (!(to & 1))

331                 if (to = get_free_page())

332                         *(unsigned long *) to_page = to | 7;

333                 else

334                         oom();

    // ����ȡĿ¼���е�ҳ����ַ��to������ҳ��������ֵ<<2����ҳ�����ڱ���ƫ�Ƶ�ַ���õ�

    // ҳ�����ַ��to_page����Ը�ҳ��������ʱ���Ǽ������Ӧ������ҳ���Ѿ����ڣ�

    // ��ҳ����Ĵ���λP=1����˵��ԭ�������빲������p�ж�Ӧ������ҳ�棬�����������Լ�

    // �Ѿ�ռ���ˣ�ӳ���У�����ҳ�档����˵���ں˳�����������

335         to &= 0xfffff000;                              // ҳ����ַ��

336         to_page = to + ((address>>10) & 0xffc);        // ҳ�����ַ��

337         if (1 & *(unsigned long *) to_page)

338                 panic("try_to_share: to_page already exists");

 

    // ���ҵ��˽���p���߼���ַaddress����Ӧ�ĸɾ����Ҵ��ڵ�����ҳ�棬����Ҳȷ���˵�ǰ

    // �������߼���ַ address ����Ӧ�Ķ���ҳ�����ַ֮���������ڶ����ǽ��й���������

    // �����ܼ򵥣��������ȶ�p���̵�ҳ��������޸ģ�������д������R/W=0��ֻ������־��

    // Ȼ���õ�ǰ���̸��� p���̵����ҳ�����ʱ��ǰ�����߼���ַ address ��ҳ�漴��

    // ӳ�䵽p�����߼���ַaddress��ҳ��ӳ�������ҳ���ϡ�

339 /* share them: write-protect */

    /* �����ǽ��й���������д���� */

340         *(unsigned long *) from_page &= ~2;

341         *(unsigned long *) to_page = *(unsigned long *) from_page;

    // ���ˢ��ҳ�任���ٻ��塣��������������ҳ���ҳ��ţ�������Ӧҳ��ӳ���ֽ���������

    // �����õ���1����󷵻�1����ʾ���������ɹ���

342         invalidate();

343         phys_addr -= LOW_MEM;

344         phys_addr >>= 12;                              // ��ҳ��š�

345         mem_map[phys_addr]++;

346         return 1;

347 }

348

349 /*

350  * share_page() tries to find a process that could share a page with

351  * the current one. Address is the address of the wanted page relative

352  * to the current data space.

353  *

354  * We first check if it is at all feasible by checking executable->i_count.

355  * It should be >1 if there are other tasks sharing this inode.

356  */

    /*

     * share_page()��ͼ�ҵ�һ�����̣��������뵱ǰ���̹���ҳ�档����address��

     * ��ǰ�������ݿռ�������������ijҳ���ַ��

     *

     * ��������ͨ�����executable->i_count����֤�Ƿ���С���������������ѹ���

     * ��inode������Ӧ�ô���1��

     */

    //// ����ҳ�洦����

    // �ڷ���ȱҳ�쳣ʱ�����ȿ����ܷ�������ͬһ��ִ���ļ����������̽���ҳ�湲��������

    // �ú��������ж�ϵͳ���Ƿ�����һ������Ҳ�����е�ǰ����һ����ִ���ļ������У�����

    // ϵͳ��ǰ����������Ѱ���������������ҵ�������������ͳ������乲��ָ����ַ����

    // ҳ�档��ϵͳ��û�������������������뵱ǰ������ͬ��ִ���ļ�����ô����ҳ�������

    // ǰ�����������ڣ���˺��������˳����ж�ϵͳ���Ƿ�����һ������Ҳ��ִ��ͬһ��ִ��

    // �ļ��ķ��������ý����������ݽṹ�е� executable �ֶΣ���library�ֶΣ������ֶ�

    // ָ���������ִ�г��򣨻�ʹ�õĿ��ļ������ڴ��е� i�ڵ㡣���ݸ� i�ڵ�����ô���

    // i_count ���ǿ��Խ��������жϡ� ���ڵ��i_countֵ����1�������ϵͳ������������

    // ��������ͬһ��ִ���ļ�������ļ��������ǿ����ٶ�����ṹ��������������Ƚ��Ƿ�

    // ����ͬ�� executable�ֶΣ��� library�ֶΣ������ȷ�����������������ִͬ���ļ�

    // �������

    // ����inode�������й���ҳ�����ִ���ļ����ڴ�i�ڵ㡣address�ǽ����е��߼���ַ��

    // ���ǵ�ǰ��������p���̹���ҳ����߼�ҳ���ַ������1 �C���������ɹ���0 - ʧ�ܡ�

357 static int share_page(struct m_inode * inode, unsigned long address)

358 {

359         struct task_struct ** p;

360

    // ���ȼ��һ�²���ָ�����ڴ� i�ڵ����ü���ֵ��������ڴ� i�ڵ�����ü���ֵ����

    // 1��executable->i_count =1������i�ڵ�ָ��գ���ʾ��ǰϵͳ��ֻ��1������������

    // ��ִ���ļ������ṩ��i�ڵ���Ч������޹������ԣ�ֱ���˳�������

361         if (inode->i_count < 2 || !inode)

362                 return 0;

    // ��������������������������Ѱ���뵱ǰ���̿ɹ���ҳ��Ľ��̣���������ִͬ���ļ�

    // ����һ�����̣������Զ�ָ����ַ��ҳ����й������������߼���ַaddressС�ڽ��̿�

    // �ļ����߼���ַ�ռ����ʼ��ַLIBRARY_OFFSET�������������ҳ���ڽ���ִ���ļ���Ӧ

    // ���߼���ַ�ռ䷶Χ�ڣ����Ǽ��һ��ָ��i�ڵ��Ƿ�����̵�ִ���ļ�i�ڵ㣨������

    // ��executable��ͬ��������ͬ�����Ѱ�ҡ��������߼���ַaddress���ڵ��ڽ��̿��ļ�

    // ���߼���ַ�ռ����ʼ��ַLIBRARY_OFFSET���������Ҫ������ҳ���ڽ���ʹ�õĿ��ļ�

    // �У����Ǽ��ָ���ڵ� inode �Ƿ�����̵Ŀ��ļ� i�ڵ���ͬ��������ͬ�����Ѱ�ҡ�

    // ����ҵ�ij������p����executable��library��ָ���Ľڵ�inode��ͬ�������ҳ��

    // ��̽����try_to_share() ����ҳ�湲���������������ɹ�����������1�����򷵻�0��

    // ��ʾ����ҳ�����ʧ�ܡ�

363         for (p = &LAST_TASK ; p > &FIRST_TASK ; --p) {

364                 if (!*p)                         // �������������У������Ѱ�ҡ�

365                         continue;

366                 if (current == *p)               // ������ǵ�ǰ����Ҳ����Ѱ�ҡ�

367                         continue;

368                 if (address < LIBRARY_OFFSET) {

369                         if (inode != (*p)->executable)   // ����ִ���ļ�i�ڵ㡣

370                                 continue;

371                 } else {

372                         if (inode != (*p)->library)      // ����ʹ�ÿ��ļ�i�ڵ㡣

373                                 continue;

374                 }

375                 if (try_to_share(address,*p))    // ���Թ���ҳ�档

376                         return 1;

377         }

378         return 0;

379 }

380

    //// ִ��ȱҳ������

    // ���ʲ�����ҳ��Ĵ���������ҳ�쳣�жϴ��������е��ô˺�������page.s�����б����á�

    // ��������error_code �� address �ǽ����ڷ���ҳ��ʱ�� CPU��ȱҳ�����쳣���Զ����ɡ�

    // error_codeָ���������ͣ��μ����¿�ʼ���ġ��ڴ�ҳ������쳣��һ�ڣ�address�Dz���

    // �쳣��ҳ�����Ե�ַ��

    // �ú������Ȳ鿴��ȱҳ�Ƿ��ڽ����豸�У������򽻻����������������Ѽ��ص���ͬ�ļ�

    // ����ҳ�湲��������ֻ�����ڽ��̶�̬�����ڴ�ҳ���ֻ��ӳ��һҳ�����ڴ�ҳ���ɡ�����

    // ���������ɹ�����ôֻ�ܴ���Ӧ�ļ��ж�����ȱ������ҳ�浽ָ�����Ե�ַ����

381 void do_no_page(unsigned long error_code,unsigned long address)

382 {

383         int nr[4];

384         unsigned long tmp;

385         unsigned long page;

386         int block,i;

387         struct m_inode * inode;

388

    // �����ж�CPU���ƼĴ���CR2����������ҳ���쳣�����Ե�ַ��ʲô��Χ�С����address

    // С�� TASK_SIZE��0x4000000����64MB������ʾ�쳣ҳ��λ�����ں˻�����0������1����

    // �����Ե�ַ��Χ�ڣ����Ƿ���������Ϣ���ں˷�Χ�ڴ汻д����������� (address�C��ǰ

    // ���̴�����ʼ��ַ)����һ�����̵ij��ȣ�64MB������ʾaddress��ָ�����Ե�ַ��������

    // �쳣�Ľ������Ե�ַ�ռ䷶Χ�ڣ����ڷ���������Ϣ���˳���

389         if (address < TASK_SIZE)

390                 printk("\n\rBAD!! KERNEL PAGE MISSING\n\r");

391         if (address - current->start_code > TASK_SIZE) {

392                 printk("Bad things happen: nonexistent page error in do_no_page\n\r");

393                 do_exit(SIGSEGV);

394         }

    // Ȼ�����ָ�������Ե�ַaddress������Ӧ�Ķ���ҳ����ָ�룬�����ݸ�ҳ���������ж�

    // address����ҳ���Ƿ��ڽ����豸�С����������ҳ�沢�˳�������������ȡָ�����Ե�ַ

    // address��Ӧ��Ŀ¼�����ݡ������Ӧ�Ķ���ҳ�����ڣ���ȡ����Ŀ¼���ж���ҳ���ĵ�ַ��

    // ����ҳ����ƫ��ֵ���õ����Ե�ַaddress��ҳ���Ӧ��ҳ�����ָ�룬�Ӷ����ҳ������

    // �ݡ���ҳ�������ݲ�Ϊ0����ҳ�������λP=0����˵����ҳ����ָ��������ҳ��Ӧ���ڽ�

    // ���豸�С����Ǵӽ����豸�е���ָ��ҳ����˳�������

395         page = *(unsigned long *) ((address >> 20) & 0xffc); // ȡĿ¼�����ݡ�

396         if (page & 1) {

397                 page &= 0xfffff000;                          // ����ҳ����ַ��

398                 page += (address >> 10) & 0xffc;             // ҳ����ָ�롣

399                 tmp = *(unsigned long *) page;               // ҳ�������ݡ�

400                 if (tmp && !(1 & tmp)) {

401                         swap_in((unsigned long *) page);     // �ӽ����豸��ҳ�档

402                         return;

403                 }

404         }

    // ����ȡ���Կռ���ָ����ַaddress��ҳ���ַ�������ָ�����Ե�ַ�ڽ��̿ռ��������

    // ���̻�ַ��ƫ�Ƴ���ֵtmp������Ӧ���߼���ַ���Ӷ��������ȱҳҳ����ִ���ļ�ӳ����

    // ���ڿ��ļ��еľ�����ʼ���ݿ�š�

405         address &= 0xfffff000;                           // address��ȱҳҳ���ַ��

406         tmp = address - current->start_code;             // ȱҳҳ���Ӧ�߼���ַ��

 

    // ���ȱҳ��Ӧ���߼���ַtmp���ڿ�ӳ���ļ��ڽ����߼��ռ��е���ʼλ�ã�˵��ȱ�ٵ�ҳ

    // ���ڿ�ӳ���ļ��С����Ǵӵ�ǰ�����������ݽṹ�п���ȡ�ÿ�ӳ���ļ���i�ڵ�library��

    // ���������ȱҳ�ڿ��ļ��е���ʼ���ݿ��block�����ȱҳ��Ӧ���߼���ַtmpС�ڽ���

    // ��ִ��ӳ���ļ����߼���ַ�ռ��ĩ��λ�ã���˵��ȱ�ٵ�ҳ���ڽ���ִ���ļ�ӳ���У���

    // �ǿ��Դӵ�ǰ�����������ݻ�����ȡ��ִ���ļ���i�ڵ��executable�����������ȱҳ

    // ��ִ���ļ�ӳ���е���ʼ���ݿ��block�����߼���ַtmp�Ȳ���ִ���ļ�ӳ��ĵ�ַ��Χ

    // �ڣ�Ҳ���ڿ��ļ��ռ䷶Χ�ڣ���˵��ȱҳ�ǽ��̷��ʶ�̬������ڴ�ҳ���������£����

    // û�ж�Ӧi�ڵ�����ݿ�ţ����ÿգ���

    // ��Ϊ���豸�ϴ�ŵ�ִ���ļ�ӳ���1�������dz���ͷ�ṹ������ڶ�ȡ���ļ�ʱ��Ҫ����

    // ��1�����ݡ�������Ҫ���ȼ���ȱҳ���ڵ����ݿ�š���Ϊÿ�����ݳ���ΪBLOCK_SIZE =

    // 1KB�����һҳ�ڴ�ɴ��4�����ݿ顣�����߼���ַtmp�������ݿ��С�ټ�1���ɵó�

    // ȱ�ٵ�ҳ����ִ��ӳ���ļ��е���ʼ���block��

407         if (tmp >= LIBRARY_OFFSET ) {

408                 inode = current->library;          // ���ļ�i�ڵ��ȱҳ��ʼ��š�

409                 block = 1 + (tmp-LIBRARY_OFFSET) / BLOCK_SIZE;

410         } else if (tmp < current->end_data) {

411                 inode = current->executable;       // ִ���ļ�i�ڵ��ȱҳ��ʼ��š�

412                 block = 1 + tmp / BLOCK_SIZE;

413         } else {

414                 inode = NULL;                      // �Ƕ�̬��������ݻ�ջ�ڴ�ҳ�档

415                 block = 0;

416         }

    // ���ǽ��̷����䶯̬�����ҳ���Ϊ�˴��ջ��Ϣ�������ȱҳ�쳣����ֱ������һҳ��

    // ���ڴ�ҳ�沢ӳ�䵽���Ե�ַaddress�����ɡ�����˵����ȱҳ���ڽ���ִ���ļ������

    // ����Χ�ڣ����Ǿͳ��Թ���ҳ����������ɹ����˳��������ɹ���ֻ������һҳ�����ڴ�

    // ҳ��page��Ȼ����豸�϶�ȡִ���ļ��е���Ӧҳ�沢���ã�ӳ�䣩������ҳ���߼���ַ

    // tmp����

417         if (!inode) {                              // �Ƕ�̬����������ڴ�ҳ�档

418                 get_empty_page(address);

419                 return;

420         }

421         if (share_page(inode,tmp))                 // �����߼���ַtmp��ҳ��Ĺ�����

422                 return;

423         if (!(page = get_free_page()))             // ����һҳ�����ڴ档

424                 oom();

425 /* remember that 1 block is used for header */

    /* ��ס��������ͷҪʹ��1�����ݿ� */

    // ���������ź�ִ���ļ���i�ڵ㣬���ǾͿ��Դ�ӳ��λͼ���ҵ���Ӧ���豸�ж�Ӧ���豸

    // �߼���ţ�������nr[]�����У�������bread_page()���ɰ���4���߼�����뵽����ҳ��

    // page�С�

426         for (i=0 ; i<4 ; block++,i++)

427                 nr[i] = bmap(inode,block);

428         bread_page(page,inode->i_dev,nr);

 

    // �ڶ��豸�߼������ʱ�����ܻ��������һ�����������ִ���ļ��еĶ�ȡҳ��λ�ÿ�����

    // �ļ�β����1��ҳ��ij��ȡ���˾Ϳ��ܶ���һЩ���õ���Ϣ������IJ������ǰ��ⲿ�ֳ�

    // ��ִ���ļ�end_data�Ժ�IJ��ֽ������㴦������Ȼ������ҳ����ĩ�˳���1ҳ��˵����

    // �Ǵ�ִ���ļ�ӳ���ж�ȡ��ҳ�棬���Ǵӿ��ļ��ж�ȡ�ģ���˲���ִ�����������

429         i = tmp + 4096 - current->end_data;          // �������ֽڳ���ֵ��

430         if (i>4095)                                  // ��ĩ�˳���1ҳ�������㡣

431                 i = 0;

432         tmp = page + 4096;                           // tmpָ��ҳ��ĩ�ˡ�

433         while (i-- > 0) {                            // ҳ��ĩ��i�ֽ����㡣

434                 tmp--;

435                 *(char *)tmp = 0;

436         }

    // ��������ȱҳ�쳣��һҳ����ҳ��ӳ�䵽ָ�����Ե�ַaddress�����������ɹ��ͷ��ء�

    // ������ͷ��ڴ�ҳ����ʾ�ڴ治����

437         if (put_page(page,address))

438                 return;

439         free_page(page);

440         oom();

441 }

442

    //// �����ڴ������ʼ����

    // �ú�����1MB�����ڴ�������ҳ��Ϊ��λ���й���ǰ�ij�ʼ�����ù�����һ��ҳ�泤��Ϊ

    // 4KB�ֽڡ��ú����� 1MB�������������ڴ滮�ֳ�һ����ҳ�棬��ʹ��һ��ҳ��ӳ���ֽ�

    // ����mem_map[] ������������Щҳ�档���ھ���16MB�ڴ������Ļ����������鹲��3840

    // �� ((16MB - 1MB)/4KB)�����ɹ���3840������ҳ�档ÿ��һ�������ڴ�ҳ�汻ռ��ʱ��

    // �� mem_map[]�ж�Ӧ�ĵ��ֽ�ֵ��1�����ͷ�һ������ҳ�棬�ͰѶ�Ӧ�ֽ�ֵ��1�� ����

    // ��ֵΪ 0�����ʾ��Ӧҳ����У� ���ֽ�ֵ���ڻ����1�����ʾ��Ӧҳ�汻ռ�û򱻲�

    // ͬ������ռ�á�

    // �ڸð汾�� Linux�ں��У�����ܹ��� 16MB�������ڴ棬����16MB���ڴ潫���ò��á�

    // ���ھ���16MB�ڴ��PC��ϵͳ����û������������ RAMDISK������� start_memͨ��

    // ��4MB��end_mem��16MB����˴�ʱ���ڴ�����Χ��4MB��16MB������3072������ҳ���

    // �����䡣����Χ0 - 1MB�ڴ�ռ������ں�ϵͳ����ʵ�ں�ֻʹ��0 ��640Kb��ʣ�µIJ�

    // �ֱ����ָ��ٻ�����豸�ڴ�ռ�ã���

    // ����start_mem�ǿ�����ҳ���������ڴ�����ʼ��ַ����ȥ��RAMDISK��ռ�ڴ�ռ䣩��

    // end_mem��ʵ�������ڴ�����ַ������ַ��Χstart_mem��end_mem�����ڴ�����

443 void mem_init(long start_mem, long end_mem)

444 {

445         int i;

446

    // ���Ƚ�1MB��16MB��Χ�������ڴ�ҳ���Ӧ���ڴ�ӳ���ֽ���������Ϊ��ռ��״̬������

    // ���ֽ�ֵȫ�����ó�USED��100����PAGING_PAGES������Ϊ(PAGING_MEMORY>>12)����1MB

    // �������������ڴ��ҳ����ڴ�ҳ����(15MB/4KB = 3840)��

447         HIGH_MEMORY = end_mem;                     // �����ڴ���߶ˣ�16MB����

448         for (i=0 ; i<PAGING_PAGES ; i++)

449                 mem_map[i] = USED;

    // Ȼ��������ڴ�����ʼ�ڴ� start_mem ��ҳ���Ӧ�ڴ�ӳ���ֽ����������i�����ڴ���

    // ҳ��������ʱ mem_map[] ����ĵ�i������Ӧ���ڴ����е�1��ҳ�档������ڴ�����

    // ҳ���Ӧ�����������㣨��ʾ���У������ھ���16MB�����ڴ��ϵͳ��mem_map[] �ж�Ӧ

    // 4Mb--16Mb���ڴ���������㡣

450         i = MAP_NR(start_mem);                     // ���ڴ�����ʼλ�ô�ҳ��š�

451         end_mem -= start_mem;

452         end_mem >>= 12;                            // ���ڴ����е���ҳ������

453         while (end_mem-->0)

454                 mem_map[i++]=0;                    // ���ڴ���ҳ���Ӧ�ֽ�ֵ���㡣

455 }

456

    // ��ʾϵͳ�ڴ���Ϣ��

    // �����ڴ�ӳ���ֽ����� mem_map[] �е���Ϣ�Լ�ҳĿ¼��ҳ������ͳ��ϵͳ��ʹ�õ��ڴ�ҳ

    // ���������ڴ������������ڴ�ҳ�������ú����� chr_drv/keyboard.S�����186�б����á�

    // �������¡�Shift + Scroll Lock����ϼ�ʱ����ʾϵͳ�ڴ�ͳ����Ϣ��

457 void show_mem(void)

458 {

459         int i,j,k,free=0,total=0;

460         int shared=0;

461         unsigned long * pg_tbl;

462

    // �����ڴ�ӳ���ֽ�����mem_map[]��ͳ��ϵͳ���ڴ���ҳ������total���Լ����п���ҳ��

    // ��free�ͱ�������ҳ����shared������Щ��Ϣ��ʾ��

463         printk("Mem-info:\n\r");

464         for(i=0 ; i<PAGING_PAGES ; i++) {

465                 if (mem_map[i] == USED)              // 1MB�����ڴ�ϵͳռ�õ�ҳ�档

466                         continue;

467                 total++;

468                 if (!mem_map[i])

469                         free++;                      // ���ڴ�������ҳ��ͳ�ơ�

470                 else

471                         shared += mem_map[i]-1;      // ������ҳ�������ֽ�ֵ>1����

472         }

473         printk("%d free pages of %d\n\r",free,total);

474         printk("%d pages shared\n\r",shared);

 

    // ͳ�ƴ�������ҳ�����߼�ҳ������ҳĿ¼��ǰ4��ں˴���ʹ�ã�����Ϊͳ�Ʒ�Χ�����

    // ɨ�账����ҳĿ¼��ӵ�5�ʼ��������ѭ����������ҳĿ¼���ǰ4���������Ӧ

    // �Ķ���ҳ�����ڣ���ô��ͳ�ƶ���ҳ������ռ�õ��ڴ�ҳ�棨484�У���Ȼ��Ը�ҳ������

    // ��ҳ�����Ӧҳ���������ͳ�ơ�

475         k = 0;                                           // һ������ռ��ҳ��ͳ��ֵ��

476         for(i=4 ; i<1024 ;) {

477                 if (1&pg_dir[i]) {

    // �����ҳĿ¼���Ӧ����ҳ����ַ���ڻ�����������ڴ��ַHIGH_MEMORY����˵����Ŀ¼��

    // �����⡣������ʾ��Ŀ¼����Ϣ������������һ��Ŀ¼���

478                         if (pg_dir[i]>HIGH_MEMORY) {         // Ŀ¼�����ݲ�������

479                                 printk("page directory[%d]: %08X\n\r",

480                                         i,pg_dir[i]);

481                                 continue;                // continue֮ǰ�����i++��

482                         }

    // ���ҳĿ¼���Ӧ����ҳ���ġ���ַ������LOW_MEM����1MB�������һ������ռ�õ�����

    // �ڴ�ҳͳ��ֵk��1����ϵͳռ�õ����������ڴ�ҳͳ��ֵfree��1��Ȼ��ȡ��Ӧҳ����ַ

    // pg_tbl�����Ը�ҳ��������ҳ�������ͳ�ơ������ǰҳ������ָ����ҳ����ڲ��Ҹ�����

    // ҳ�桰��ַ������LOW_MEM����ô�ͽ�ҳ�����Ӧҳ������ͳ��ֵ��

483                         if (pg_dir[i]>LOW_MEM)

484                                 free++,k++;              // ͳ��ҳ��ռ��ҳ�档

485                         pg_tbl=(unsigned long *) (0xfffff000 & pg_dir[i]);

486                         for(j=0 ; j<1024 ; j++)

487                                 if ((pg_tbl[j]&1) && pg_tbl[j]>LOW_MEM)

    // ����������ҳ���ַ���ڻ�����������ڴ��ַHIGH_MEMORY����˵����ҳ�������������⣬

    // ������ʾ��ҳ�������ݡ�����ҳ�����Ӧҳ������ͳ��ֵ����

488                                         if (pg_tbl[j]>HIGH_MEMORY)

489                                                 printk("page_dir[%d][%d]: %08X\n\r",

490                                                         i,j, pg_tbl[j]);

491                                         else

492                                                 k++,free++;  // ͳ��ҳ�����Ӧҳ�档

493                 }

    // ��ÿ���������Կռ䳤����64MB������һ������ռ��16��Ŀ¼��������ÿͳ����16��

    // Ŀ¼��Ͱѽ��̵�����ṹռ�õ�ҳ��ͳ�ƽ���������ʱk=0���ʾ��ǰ��16��ҳĿ¼����

    // Ӧ�Ľ�����ϵͳ�в����ڣ�û�д��������Ѿ���ֹ���� ����ʾ�˶�Ӧ���̺ź���ռ�õ�����

    // �ڴ�ҳͳ��ֵk�󣬽�k���㣬������ͳ����һ������ռ�õ��ڴ�ҳ������

494                 i++;

495                 if (!(i&15) && k) {                // k !=0 ��ʾ��Ӧ���̴��ڡ�

496                         k++,free++;     /* one page/process for task_struct */

497                         printk("Process %d: %d pages\n\r",(i>>4)-1,k);

498                         k = 0;

499                 }

500         }

    // �����ʾϵͳ������ʹ�õ��ڴ�ҳ������ڴ������ܵ��ڴ�ҳ������

501         printk("Memory found: %d (%d)\n\r",free-shared,total);

502 }

503


 


 

13.2 ����13-2 linux/mm/page.s


  1 /*

  2  *  linux/mm/page.s

  3  *

  4  *  (C) 1991  Linus Torvalds

  5  */

  6

  7 /*

  8  * page.s contains the low-level page-exception code.

  9  * the real work is done in mm.c

 10  */

    /*

     * page.s��������ײ�ҳ�쳣�������롣ʵ�ʹ�����memory.c����ɡ�

     */

 11

 12 .globl _page_fault           # ����Ϊȫ�ֱ���������traps.c����������ҳ�쳣��������

 13

 14 _page_fault:

 15         xchgl %eax,(%esp)    # ȡ�����뵽eax��

 16         pushl %ecx

 17         pushl %edx

 18         push %ds

 19         push %es

 20         push %fs

 21         movl $0x10,%edx      # ���ں����ݶ�ѡ�����

 22         mov %dx,%ds

 23         mov %dx,%es

 24         mov %dx,%fs

 25         movl %cr2,%edx       # ȡ����ҳ���쳣�����Ե�ַ��

 26         pushl %edx           # �������Ե�ַ�ͳ�����ѹ��ջ�У���Ϊ�����ú����IJ�����

 27         pushl %eax

 28         testl $1,%eax        # ����ҳ���ڱ�־P��λ0�����������ȱҳ������쳣����ת��

 29         jne 1f

 30         call _do_no_page     # ����ȱҳ����������mm/memory.c,365�У���

 31         jmp 2f

 32 1:      call _do_wp_page     # ����д��������������mm/memory.c,247�У���

 33 2:      addl $8,%esp         # ����ѹ��ջ����������������ջ�мĴ������˳��жϡ�

 34         pop %fs

 35         pop %es

 36         pop %ds

 37         popl %edx

 38         popl %ecx

 39         popl %eax

 40         iret


 


 

13.3 ����13-3 linux/mm/swap.c


  1 /*

  2  *  linux/mm/swap.c

  3  *

  4  *  (C) 1991  Linus Torvalds

  5  */

  6

  7 /*

  8  * This file should contain most things doing the swapping from/to disk.

  9  * Started 18.12.91

 10  */

    /*

     * ������Ӧ�ð������󲿷�ִ���ڴ潻���Ĵ��루���ڴ浽���̻�֮����

     * ��91��12��18�տ�ʼ���ơ�

     */

 11

 12 #include <string.h>       // �ַ���ͷ�ļ���������һЩ�й��ڴ���ַ���������Ƕ�뺯����

 13

 14 #include <linux/mm.h>     // �ڴ����ͷ�ļ�������ҳ�泤�ȣ���һЩ�ڴ��������ԭ�͡�

 15 #include <linux/sched.h>  // ���ȳ���ͷ�ļ�������������ṹtask_struct������0�����ݣ�

                              // ����һЩ�й��������������úͻ�ȡ��Ƕ��ʽ��ຯ������䡣

 16 #include <linux/head.h>   // headͷ�ļ��������˶��������ļ򵥽ṹ���ͼ���ѡ���������

 17 #include <linux/kernel.h> // �ں�ͷ�ļ�������һЩ�ں˳��ú�����ԭ�Ͷ��塣

 18

    // ÿ���ֽ�8λ�����1ҳ��4096�ֽڣ�����32768������λ����1������λ��Ӧ1ҳ�ڴ棬

    // �����ɹ���32768��ҳ�棬��Ӧ128MB�ڴ�������

 19 #define SWAP_BITS (4096<<3)

 20

    // ����λ�����ꡣͨ��������ͬ��"op"���ɶ����ָ������λ���в��ԡ����û�������ֲ�����

    // ����addr��ָ�����Ե�ַ��nr��ָ����ַ����ʼ�ı���λƫ��λ���ú�Ѹ�����ַaddr��

    // ��nr������λ��ֵ�����λ��־�����û�λ�ñ���λ�����ؽ�λ��־ֵ����ԭ����λֵ����

    // ��25���ϵ�һ��ָ����"op"�ַ��IJ�ͬ������γɲ�ͬ��ָ�

    // ��"op"= ""ʱ������ָ��bt �C ��Bit Test�����Բ���ԭֵ���ý�λλ��

    // ��"op"="s"ʱ������ָ��bts - ��Bit Test and Set�����ñ���λֵ����ԭֵ���ý�λλ��

    // ��"op"="r"ʱ������ָ��btr - ��Bit Test and Reset����λ����λֵ��ԭֵ���ý�λλ��

    // ���룺%0 �C ������ֵ)��%1 -λƫ��(nr)��%2 �C��ַ(addr)��%3 �C �Ӳ����Ĵ�����ֵ(0)��

    // ��Ƕ������ѻ���ַ��%2���ͱ���ƫ��ֵ��%1����ָ���ı���λֵ�ȱ��浽��λ��־CF�У�

    // Ȼ�����ã���λ���ñ���λ��ָ��adcl�Ǵ���λλ�ӣ����ڸ��ݽ�λλCF���ò�������%0����

    // ���CF = 1 �򷵻ؼĴ���ֵ = 1�����򷵻ؼĴ���ֵ = 0 ��

 21 #define bitop(name,op) \

 22 static inline int name(char * addr,unsigned int nr) \

 23 { \

 24 int __res; \

 25 __asm__ __volatile__("bt" op " %1,%2; adcl $0,%0" \

 26 :"=g" (__res) \

 27 :"r" (nr),"m" (*(addr)),"0" (0)); \

 28 return __res; \

 29 }

 30

    // ������ݲ�ͬ��op�ַ�����3����Ƕ������

 31 bitop(bit,"")                // ������Ƕ���� bit(char * addr, unsigned int nr)��

 32 bitop(setbit,"s")            // ������Ƕ���� setbit(char * addr, unsigned int nr)��

 33 bitop(clrbit,"r")            // ������Ƕ���� clrbit(char * addr, unsigned int nr)��

 34

 35 static char * swap_bitmap = NULL;

 36 int SWAP_DEV = 0;                            // �ں˳�ʼ��ʱ���õĽ����豸�š�

 37

 38 /*

 39  * We never page the pages in task[0] - kernel memory.

 40  * We page all other pages.

 41  */

    /*

     * ���ǴӲ���������0��task[0]����ҳ�� �C ���������ں�ҳ�档

     * ����ֻ������ҳ����н���������

     */

    // ��1�������ڴ�ҳ�档��������0ĩ�ˣ�64MB������ʼ�������ڴ�ҳ�档

 42 #define FIRST_VM_PAGE (TASK_SIZE>>12)              // = 64MB/4KB = 16384��

 43 #define LAST_VM_PAGE (1024*1024)                   // = 4GB/4KB  = 1048576��

 44 #define VM_PAGES (LAST_VM_PAGE - FIRST_VM_PAGE)    // = 1032192����0��ʼ�ƣ���

 45

    // ����1ҳ����ҳ�档

    // ɨ����������ӳ��λͼ������Ӧλͼ������λ0���⣩������ֵΪ1�ĵ�һ������λ�ţ�

    // ��Ŀǰ���еĽ���ҳ��š��������ɹ��򷵻ؽ���ҳ��ţ����򷵻�0��

 46 static int get_swap_page(void)

 47 {

 48         int nr;

 49

 50         if (!swap_bitmap)

 51                 return 0;

 52         for (nr = 1; nr < 32768 ; nr++)

 53                 if (clrbit(swap_bitmap,nr))

 54                         return nr;                // ����Ŀǰ���еĽ���ҳ��š�

 55         return 0;

 56 }

 57

    // �ͷŽ����豸��ָ���Ľ���ҳ�档

    // �ڽ���λͼ������ָ��ҳ��Ŷ�Ӧ�ı���λ����1������ԭ���ñ���λ�͵���1�����ʾ

    // �����豸��ԭ����ҳ���û�б�ռ�ã�����λͼ������������ʾ������Ϣ�����ء�

    // ����ָ������ҳ��š�

 58 void swap_free(int swap_nr)

 59 {

 60         if (!swap_nr)

 61                 return;

 62         if (swap_bitmap && swap_nr < SWAP_BITS)

 63                 if (!setbit(swap_bitmap,swap_nr))

 64                         return;

 65         printk("Swap-space bad (swap_free())\n\r");

 66         return;

 67 }

 68

    // ��ָ��ҳ�潻�����ڴ��С�

    // ��ָ��ҳ����Ķ�Ӧҳ��ӽ����豸�ж��뵽��������ڴ�ҳ���С��޸Ľ���λͼ�ж�Ӧ

    // ����λ����λ����ͬʱ�޸�ҳ�������ݣ�����ָ����ڴ�ҳ�棬��������Ӧ��־��

 69 void swap_in(unsigned long *table_ptr)

 70 {

 71         int swap_nr;

 72         unsigned long page;

 73

    // ���ȼ�齻��λͼ�Ͳ�����Ч�ԡ��������λͼ�����ڣ�����ָ��ҳ�����Ӧ��ҳ���Ѵ���

    // ���ڴ��У����߽���ҳ���Ϊ 0������ʾ������Ϣ���˳��������ѷŵ������豸��ȥ���ڴ�

    // ҳ�棬��Ӧҳ�����д�ŵ�Ӧ�ǽ���ҳ���*2����(swap_nr << 1)���μ�����Գ��Խ�����

    // ��try_to_swap_out()�е�111�е�˵����

 74         if (!swap_bitmap) {

 75                 printk("Trying to swap in without swap bit-map");

 76                 return;

 77         }

 78         if (1 & *table_ptr) {

 79                 printk("trying to swap in present page\n\r");

 80                 return;

 81         }

 82         swap_nr = *table_ptr >> 1;

 83         if (!swap_nr) {

 84                 printk("No swap page in swap_in\n\r");

 85                 return;

 86         }

    // Ȼ������һҳ�����ڴ沢�ӽ����豸�ж���ҳ���Ϊswap_nr��ҳ�档�ڰ�ҳ�潻������

    // �󣬾Ͱѽ���λͼ�ж�Ӧ����λ��λ�������ԭ��������λ�ģ�˵���˴����ٴδӽ�����

    // ���ж�����ͬ��ҳ�棬������ʾһ�¾�����Ϣ�������ҳ����ָ�������ҳ�棬������ҳ

    // �����޸ġ��û��ɶ�д�ʹ��ڱ�־��Dirty��U/S��R/W��P����

 87         if (!(page = get_free_page()))

 88                 oom();

 89         read_swap_page(swap_nr, (char *) page);  // ��include/linux/mm.h�ж��塣

 90         if (setbit(swap_bitmap,swap_nr))

 91                 printk("swapping in multiply from same page\n\r");

 92         *table_ptr = page | (PAGE_DIRTY | 7);

 93 }

 94

    // ���԰�ҳ�潻����ȥ��

    // ��ҳ��û�б��޸Ĺ����ñ����ڽ����豸�У���Ϊ��Ӧҳ�滹������ֱ�Ӵ���Ӧӳ���ļ�

    // �ж��롣���ǿ���ֱ���ͷŵ���Ӧ����ҳ�����¡����������һ������ҳ��ţ�Ȼ���ҳ��

    // ������ȥ����ʱ����ҳ���Ҫ�����ڶ�Ӧҳ�����У���������Ҫ����ҳ�������λP = 0��

    // ������ҳ����ָ�롣ҳ�潻�����ͷųɹ�����1�����򷵻�0��

 95 int try_to_swap_out(unsigned long * table_ptr)

 96 {

 97         unsigned long page;

 98         unsigned long swap_nr;

 99

    // �����жϲ�������Ч�ԡ�����Ҫ������ȥ���ڴ�ҳ�沢�����ڣ������Ч�����򼴿��˳���

    // ��ҳ����ָ��������ҳ���ַ���ڷ�ҳ�������ڴ�߶�PAGING_MEMORY��15MB����Ҳ�˳���

100         page = *table_ptr;

101         if (!(PAGE_PRESENT & page))

102                 return 0;

103         if (page - LOW_MEM > PAGING_MEMORY)

104                 return 0;

    // ���ڴ�ҳ���ѱ��޸Ĺ������Ǹ�ҳ���DZ������ģ���ôΪ���������Ч�ʣ�����ҳ�治��

    // ��������ȥ������ֱ���˳�����������0�����������һ����ҳ��ţ�������������ҳ��

    // ���У�Ȼ���ҳ�潻����ȥ���ͷŶ�Ӧ�����ڴ�ҳ�档

105         if (PAGE_DIRTY & page) {

106                 page &= 0xfffff000;                    // ȡ����ҳ���ַ��

107                 if (mem_map[MAP_NR(page)] != 1)

108                         return 0;

109                 if (!(swap_nr = get_swap_page()))      // ���뽻��ҳ��š�

110                         return 0;

    // ����Ҫ�������豸�е�ҳ�棬��Ӧҳ�����н���ŵ���(swap_nr << 1)�� ��2������1λ��

    // ��Ϊ�˿ճ�ԭ��ҳ����Ĵ���λ��P����ֻ�д���λP=0����ҳ�������ݲ�Ϊ0��ҳ��Ż�

    // �ڽ����豸�С� Intel�ֲ�����ȷָ������һ������Ĵ���λ P = 0ʱ����Чҳ�����

    // ��������λ��λ31��1���ɹ�����ʹ�á�����д����ҳ����write_swap_page(nr, buffer)

    // ������Ϊll_rw_page(WRITE,SWAP_DEV,(nr),(buffer))���μ�linux/mm.h �ļ���12�С�

111                 *table_ptr = swap_nr<<1;

112                 invalidate();                        // ˢ��CPUҳ�任���ٻ��塣

113                 write_swap_page(swap_nr, (char *) page);

114                 free_page(page);

115                 return 1;

116         }

    // �������ҳ��û���޸Ĺ�����ô�Ͳ��ý�����ȥ����ֱ���ͷż��ɡ�

117         *table_ptr = 0;

118         invalidate();

119         free_page(page);

120         return 1;

121 }

122

123 /*

124  * Ok, this has a rather intricate logic - the idea is to make good

125  * and fast machine code. If we didn't worry about that, things would

126  * be easier.

127  */

    /*

     * OK�������������һ���dz����ӵ��߼� �C ���ڲ����߼��Ժò����ٶȿ��

     * �����롣������Dz��Դ˲��ĵĻ�����ô������ܸ�����Щ��

     */

    // ���ڴ�ҳ��ŵ������豸�С�

    // �����Ե�ַ64MB��Ӧ��Ŀ¼�FIRST_VM_PAGE>>10����ʼ����������4GB���Կռ䣬����

    // ЧҳĿ¼����ҳ����ҳ����ָ���������ڴ�ҳ��ִ�н����������豸��ȥ�ij��ԡ�һ���ɹ�

    // �ػ���һ��ҳ�棬�ͷ���1�����򷵻�0���ú�������get_free_page()�б����á�

128 int swap_out(void)

129 {

130         static int dir_entry = FIRST_VM_PAGE>>10;   // ������1�ĵ�1��Ŀ¼��������

131         static int page_entry = -1;

132         int counter = VM_PAGES;

133         int pg_table;

134

    // ��������ҳĿ¼�������Ҷ���ҳ�����ڵ�ҳĿ¼��pg_table���ҵ����˳�ѭ�����������

    // ҳĿ¼������Ӧʣ�����ҳ������counter��Ȼ����������һҳĿ¼� ��ȫ��������

    // ��û���ҵ��ʺϵģ����ڵģ�ҳĿ¼������¼���������

135         while (counter>0) {

136                 pg_table = pg_dir[dir_entry];        // ҳĿ¼�����ݡ�

137                 if (pg_table & 1)

138                         break;

139                 counter -= 1024;                     // 1��ҳ����Ӧ1024��ҳ֡��

140                 dir_entry++;                         // ��һĿ¼�

141                 if (dir_entry >= 1024)

142                         dir_entry = FIRST_VM_PAGE>>10;

143         }

    // ��ȡ�õ�ǰĿ¼���ҳ��ָ�����Ը�ҳ���е����� 1024 ��ҳ�棬��һ���ý�������

    // try_to_swap_out()���Խ�����ȥ��һ��ij��ҳ��ɹ������������豸�оͷ���1��������

    // ��Ŀ¼�������ҳ�����ѳ���ʧ�ܣ�����ʾ�������ڴ����ꡱ�ľ��棬������0��

144         pg_table &= 0xfffff000;                      // ҳ��ָ�루��ַ����

145         while (counter-- > 0) {

146                 page_entry++;                        // ҳ������������ʼΪ-1����

    // ����Ѿ����Դ����굱ǰҳ�������û���ܹ��ɹ��ؽ�����һ��ҳ�棬����ʱҳ��������

    // ���ڵ���1024������ͬǰ���135 �C 143��ִ����ͬ�Ĵ�����ѡ��һ������ҳ�����ڵ�ҳ

    // Ŀ¼���ȡ����Ӧ����ҳ��ָ�롣

147                 if (page_entry >= 1024) {

148                         page_entry = 0;

149                 repeat:

150                         dir_entry++;

151                         if (dir_entry >= 1024)

152                                 dir_entry = FIRST_VM_PAGE>>10;

153                         pg_table = pg_dir[dir_entry];  // ҳĿ¼�����ݡ�

154                         if (!(pg_table&1))

155                                 if ((counter -= 1024) > 0)

156                                         goto repeat;

157                                 else

158                                         break;

159                         pg_table &= 0xfffff000;        // ҳ��ָ�롣

160                 }

161                 if (try_to_swap_out(page_entry + (unsigned long *) pg_table))

162                         return 1;

163         }

164         printk("Out of swap-memory\n\r");

165         return 0;

166 }

167

168 /*

169  * Get physical address of first (actually last :-) free page, and mark it

170  * used. If no free pages left, return 0.

171  */

    /*

     * ��ȡ�׸�(ʵ���������1��:-)����ҳ�棬�����Ϊ��ʹ�á����û�п���ҳ�棬

     * �ͷ���0��

     */

    //// �����ڴ���������1ҳ��������ҳ�档

    // ����Ѿ�û�п��������ڴ�ҳ�棬�����ִ�н���������Ȼ���ٴ�����ҳ�档

    // ���룺%1(ax=0) - 0��%2(LOW_MEM)�ڴ��ֽ�λͼ��������ʼλ�ã�%3(cx= PAGING_PAGES)��

    // %4(edi=mem_map+PAGING_PAGES-1)��

    // ���������%0��ax = ����ҳ����ʼ��ַ��������������ҳ���������ַ��

    // ����%4�Ĵ���ʵ��ָ��mem_map[]�ڴ��ֽ�λͼ�����һ���ֽڡ���������λͼĩ�˿�ʼ��

    // ǰɨ������ҳ���־��ҳ������ΪPAGING_PAGES��������ҳ����У��ڴ�λͼ�ֽ�Ϊ0����

    // ����ҳ���ַ��ע�⣡������ֻ��ָ�������ڴ�����һҳ��������ҳ�棬����û��ӳ�䵽ij

    // �����̵ĵ�ַ�ռ���ȥ������� put_page() ���������ڰ�ָ��ҳ��ӳ�䵽ij�����̵ĵ�ַ

    // �ռ��С���Ȼ�����ں�ʹ�ñ�����������Ҫ��ʹ�� put_page() ����ӳ�䣬��Ϊ�ں˴����

    // ���ݿռ䣨16MB���Ѿ��Եȵ�ӳ�䵽������ַ�ռ䡣

    // ��65�ж�����һ���ֲ��Ĵ����������ñ������������� eax�Ĵ����У��Ա��ڸ�Ч���ʺ�

    // ���������ֶ�������ķ�����Ҫ������Ƕ�������С���ϸ˵���μ�gcc�ֲᡰ��ָ���Ĵ�

    // ���еı�������

172 unsigned long get_free_page(void)

173 {

174 register unsigned long __res asm("ax");

175

    // �������ڴ�ӳ���ֽ�λͼ�в���ֵΪ0���ֽ��Ȼ��Ѷ�Ӧ�����ڴ�ҳ�����㡣����õ�

    // ��ҳ���ַ����ʵ�������ڴ�����������Ѱ�ҡ����û���ҵ�����ҳ����ȥ����ִ�н�����

    // ���������²��ҡ���󷵻ؿ�������ҳ���ַ��

176 repeat:

177 __asm__("std ; repne ; scasb\n\t"     // �÷���λ��al(0)���Ӧÿ��ҳ���(di)���ݱȽϣ�

178         "jne 1f\n\t"                  // ���û�е���0���ֽڣ�����ת����������0����

179         "movb $1,1(%%edi)\n\t"         // 1 =>[1+edi], ����Ӧҳ���ڴ�ӳ�����λ��1��

180         "sall $12,%%ecx\n\t"          // ҳ����*4K = ���ҳ����ʼ��ַ��

181         "addl %2,%%ecx\n\t"           // �ټ��ϵͶ��ڴ��ַ����ҳ��ʵ��������ʼ��ַ��

182         "movl %%ecx,%%edx\n\t"        // ��ҳ��ʵ����ʼ��ַ��edx�Ĵ�����

183         "movl $1024,%%ecx\n\t"        // �Ĵ���ecx�ü���ֵ1024��

184         "leal 4092(%%edx),%%edi\n\t"  // ��4092+edx��λ����edi����ҳ���ĩ�ˣ���

185         "rep ; stosl\n\t"             // ��edi��ָ�ڴ����㣨�����򣬼�����ҳ�����㣩��

186         "movl %%edx,%%eax\n"          // ��ҳ����ʼ��ַ��eax������ֵ����

187         "1:"

188         :"=a" (__res)

189         :"0" (0),"i" (LOW_MEM),"c" (PAGING_PAGES),

190         "D" (mem_map+PAGING_PAGES-1)

191         :"di","cx","dx");

192         if (__res >= HIGH_MEMORY)     // ҳ���ַ����ʵ���ڴ�����������Ѱ�ҡ�

193                 goto repeat;

194         if (!__res && swap_out())     // ��û�õ�����ҳ����ִ�н��������������²��ҡ�

195                 goto repeat;

196         return __res;                 // ���ؿ�������ҳ���ַ��

197 }

198

    // �ڴ潻����ʼ����

199 void init_swapping(void)

200 {

    // blk_size[]ָ��ָ�����豸�ŵĿ��豸�������顣�ÿ�������ÿһ���Ӧһ�����豸����

    // ӵ�е����ݿ�������1���С=1KB����

201         extern int *blk_size[];              // blk_drv/ll_rw_blk.c��49�С�

202         int swap_size,i,j;

203

    // ���û�ж��彻���豸�򷵻ء���������豸û�����ÿ������飬����ʾ��Ϣ�����ء�

204         if (!SWAP_DEV)

205                 return;

206         if (!blk_size[MAJOR(SWAP_DEV)]) {

207                 printk("Unable to get size of swap device\n\r");

208                 return;

209         }

    // ȡָ�������豸�ŵĽ��������ݿ�����swap_size����Ϊ0�򷵻أ����ܿ���С��100��

    // ����ʾ��Ϣ�������豸��̫С����Ȼ���˳���

210         swap_size = blk_size[MAJOR(SWAP_DEV)][MINOR(SWAP_DEV)];

211         if (!swap_size)

212                 return;

213         if (swap_size < 100) {

214                 printk("Swap device too small (%d blocks)\n\r",swap_size);

215                 return;

216         }

    // �������ݿ�����ת���ɶ�Ӧ�ɽ���ҳ����������ֵ���ܴ���SWAP_BITS���ܱ�ʾ��ҳ������

    // ������ҳ���������ô��� 32768��  Ȼ������һҳ�����ڴ�������Ž���ҳ��λӳ������

    // swap_bitmap������ÿ1���ش���1ҳ����ҳ�档

217         swap_size >>= 2;

218         if (swap_size > SWAP_BITS)

219                 swap_size = SWAP_BITS;

220         swap_bitmap = (char *) get_free_page();

221         if (!swap_bitmap) {

222                 printk("Unable to start swapping: out of memory :-)\n\r");

223                 return;

224         }

    // read_swap_page(nr, buffer)������Ϊll_rw_page(READ,SWAP_DEV,(nr),(buffer))��

    // �μ�linux/mm.h�ļ���11�С�����ѽ����豸�ϵ�ҳ��0����swap_bitmapҳ���С�

    // ��ҳ���ǽ���������ҳ�档���е�4086�ֽڿ�ʼ������10���ַ��Ľ����豸������

    // ������SWAP-SPACE������û���ҵ��������ַ�������˵������һ����Ч�Ľ����豸��

    // ������ʾ��Ϣ���ͷŸ����������ҳ�沢�˳����������������ַ����ֽ����㡣

225         read_swap_page(0,swap_bitmap);

226         if (strncmp("SWAP-SPACE",swap_bitmap+4086,10)) {

227                 printk("Unable to find swap-space signature\n\r");

228                 free_page((long) swap_bitmap);

229                 swap_bitmap = NULL;

230                 return;

231         }

232         memset(swap_bitmap+4086,0,10);

    // Ȼ�������Ľ���λӳ��ͼ��Ӧ��32768������λȫΪ0����λͼ������λ�ı���λ0��

    // ���ʾλͼ�����⣬������ʾ������Ϣ���ͷ�λͼռ�õ�ҳ�沢�˳�������Ϊ�˼ӿ���

    // �ٶȣ��������Ƚ���ѡ�鿴λͼ��λ0�����һ������ҳ���Ӧ�ı���λ����swap_size

    // ����ҳ���Ӧ�ı���λ���Լ����SWAP_BITS��32768������λ��

233         for (i = 0 ; i < SWAP_BITS ; i++) {

234                 if (i == 1)

235                         i = swap_size;

236                 if (bit(swap_bitmap,i)) {

237                         printk("Bad swap-space bit-map\n\r");

238                         free_page((long) swap_bitmap);

239                         swap_bitmap = NULL;

240                         return;

241                 }

242         }

    // Ȼ������ϸ�ؼ��λ1��λswap_size���б���λ�Ƿ�Ϊ0�����в���0�ı���λ���ڣ�

    // ���ʾλͼ�����⣬�����ͷ�λͼռ�õ�ҳ�沢�˳�������������ʾ�����豸��������

    // �Լ�����ҳ�����ͽ����ռ����ֽ�����

243         j = 0;

244         for (i = 1 ; i < swap_size ; i++)

245                 if (bit(swap_bitmap,i))

246                         j++;

247         if (!j) {

248                 free_page((long) swap_bitmap);

249                 swap_bitmap = NULL;

250                 return;

251         }

252         printk("Swap device ok: %d pages (%d bytes) swap-space\n\r",j,j*4096);

253 }

254


 


 

��14�� �ں˰�������

14.1 ����14-1 linux/include/a.out.h


  1 #ifndef _A_OUT_H

  2 #define _A_OUT_H

  3

  4 #define __GNU_EXEC_MACROS__

  5

    // ��6--108���Ǹ��ļ���1���֡�����Ŀ���ļ�ִ�нṹ�Լ���ز����ĺ궨�塣

    // Ŀ���ļ�ͷ�ṹ���μ���������ϸ˵����

    // =============================

    // unsigned long a_magic        // ִ���ļ�ħ����ʹ��N_MAGIC�Ⱥ���ʡ�

    // unsigned a_text              // ���볤�ȣ��ֽ�����

    // unsigned a_data              // ���ݳ��ȣ��ֽ�����

    // unsigned a_bss               // �ļ��е�δ��ʼ�����������ȣ��ֽ�����

    // unsigned a_syms              // �ļ��еķ��ű����ȣ��ֽ�����

    // unsigned a_entry             // ִ�п�ʼ��ַ��

    // unsigned a_trsize            // �����ض�λ��Ϣ���ȣ��ֽ�����

    // unsigned a_drsize            // �����ض�λ��Ϣ���ȣ��ֽ�����

    // -----------------------------

  6 struct exec {

  7   unsigned long a_magic;        /* Use macros N_MAGIC, etc for access */

  8   unsigned a_text;              /* length of text, in bytes */

  9   unsigned a_data;              /* length of data, in bytes */

 10   unsigned a_bss;               /* length of uninitialized data area for file, in bytes */

 11   unsigned a_syms;              /* length of symbol table data in file, in bytes */

 12   unsigned a_entry;             /* start address */

 13   unsigned a_trsize;            /* length of relocation info for text, in bytes */

 14   unsigned a_drsize;            /* length of relocation info for data, in bytes */

 15 };

 16

    // ����ȡ����exec�ṹ�е�ħ����

 17 #ifndef N_MAGIC

 18 #define N_MAGIC(exec) ((exec).a_magic)

 19 #endif

 20

 21 #ifndef OMAGIC

 22 /* Code indicating object file or impure executable.  */

    /* ָ��ΪĿ���ļ����߲����Ŀ�ִ���ļ��Ĵ��� */

    // ��ʷ��������PDP-11������ϣ�ħ�����������ǰ˽�����0407��0x107������λ��ִ�г���

    // ͷ�ṹ�Ŀ�ʼ����ԭ����PDP-11��һ����תָ���ʾ��ת�����7���ֺ�Ĵ��뿪ʼ����

    // �������س���loader���Ϳ����ڰ�ִ���ļ������ڴ��ֱ����ת��ָ�ʼ�����С� ����

    // ��û�г���ʹ�����ַ�����������˽�����ȴ��Ϊʶ���ļ����͵ı�־��ħ����������������

    // OMAGIC������Ϊ��Old Magic ����˼��

 23 #define OMAGIC 0407

 24 /* Code indicating pure executable.  */

    /* ָ��Ϊ����ִ���ļ��Ĵ��� */       // New Magic��1975���Ժ�ʼʹ�á��漰�����ơ�

 25 #define NMAGIC 0410                  // 0410 == 0x108

 26 /* Code indicating demand-paged executable.  */

    /* ָ��Ϊ�����ҳ�����Ŀ�ִ���ļ� */ // ��ͷ�ṹռ���ļ���ʼ��1K�ռ䡣

 27 #define ZMAGIC 0413                  // 0413 == 0x10b

 28 #endif /* not OMAGIC */

 29 // ���⻹��һ��QMAGIC����Ϊ�˽�Լ����������������ִ���ļ���ͷ�ṹ�������մ�š�

    // ����������ж�ħ���ֶε���ȷ�ԡ����ħ�����ܱ�ʶ���򷵻��档

 30 #ifndef N_BADMAG

 31 #define N_BADMAG(x)                                     \

 32  (N_MAGIC(x) != OMAGIC && N_MAGIC(x) != NMAGIC          \

 33   && N_MAGIC(x) != ZMAGIC)

 34 #endif

 35

 36 #define _N_BADMAG(x)                                    \

 37  (N_MAGIC(x) != OMAGIC && N_MAGIC(x) != NMAGIC          \

 38   && N_MAGIC(x) != ZMAGIC)

 39

    // Ŀ���ļ�ͷ�ṹĩ�˵�1024�ֽ�֮��ij��ȡ�

 40 #define _N_HDROFF(x) (SEGMENT_SIZE - sizeof (struct exec))

 41

    // ��������ڲ���Ŀ���ļ������ݣ�����.oģ���ļ��Ϳ�ִ���ļ���

 

    // ���벿����ʼƫ��ֵ��

    // ����ļ��� ZMAGIC���͵ģ�����ִ���ļ�����ô���벿���Ǵ�ִ���ļ���1024�ֽ�ƫ�ƴ�

    // ��ʼ������ִ�д��벿�ֽ���ִ��ͷ�ṹĩ�ˣ�32�ֽڣ���ʼ�����ļ���ģ���ļ���OMAGIC

    // ���ͣ���

 42 #ifndef N_TXTOFF

 43 #define N_TXTOFF(x) \

 44  (N_MAGIC(x) == ZMAGIC ? _N_HDROFF((x)) + sizeof (struct exec) : sizeof (struct exec))

 45 #endif

 46

    // ���ݲ�����ʼƫ��ֵ���Ӵ��벿��ĩ�˿�ʼ��

 47 #ifndef N_DATOFF

 48 #define N_DATOFF(x) (N_TXTOFF(x) + (x).a_text)

 49 #endif

 50

    // �����ض�λ��Ϣƫ��ֵ�������ݲ���ĩ�˿�ʼ��

 51 #ifndef N_TRELOFF

 52 #define N_TRELOFF(x) (N_DATOFF(x) + (x).a_data)

 53 #endif

 54

    // �����ض�λ��Ϣƫ��ֵ���Ӵ����ض�λ��Ϣĩ�˿�ʼ��

 55 #ifndef N_DRELOFF

 56 #define N_DRELOFF(x) (N_TRELOFF(x) + (x).a_trsize)

 57 #endif

 58

    // ���ű�ƫ��ֵ�����������ݶ��ض�λ��ĩ�˿�ʼ��

 59 #ifndef N_SYMOFF

 60 #define N_SYMOFF(x) (N_DRELOFF(x) + (x).a_drsize)

 61 #endif

 62

    // �ַ�����Ϣƫ��ֵ���ڷ��ű�֮��

 63 #ifndef N_STROFF

 64 #define N_STROFF(x) (N_SYMOFF(x) + (x).a_syms)

 65 #endif

 66

    // ����Կ�ִ���ļ������ص��ڴ棨�߼��ռ䣩�е�λ��������в�����

 67 /* Address of text segment in memory after it is loaded.  */

    /* ����μ��غ����ڴ��еĵ�ַ */

 68 #ifndef N_TXTADDR

 69 #define N_TXTADDR(x) 0                            // �ɼ�������δӵ�ַ0��ʼִ�С�

 70 #endif

 71

 72 /* Address of data segment in memory after it is loaded.

 73    Note that it is up to you to define SEGMENT_SIZE

 74    on machines not listed here.  */

    /* ���ݶμ��غ����ڴ��еĵ�ַ��

       ע�⣬��������û���г����ƵĻ�������Ҫ���Լ�������

       ��Ӧ��SEGMENT_SIZE */

 75 #if defined(vax) || defined(hp300) || defined(pyr)

 76 #define SEGMENT_SIZE PAGE_SIZE

 77 #endif

 78 #ifdef  hp300

 79 #define PAGE_SIZE       4096

 80 #endif

 81 #ifdef  sony

 82 #define SEGMENT_SIZE    0x2000

 83 #endif  /* Sony.  */

 84 #ifdef is68k

 85 #define SEGMENT_SIZE 0x20000

 86 #endif

 87 #if defined(m68k) && defined(PORTAR)

 88 #define PAGE_SIZE 0x400

 89 #define SEGMENT_SIZE PAGE_SIZE

 90 #endif

 91

    // ���Linux 0.12�ں˰��ڴ�ҳ����Ϊ4KB���δ�С����Ϊ1KB�����û��ʹ������Ķ��塣

 92 #define PAGE_SIZE 4096

 93 #define SEGMENT_SIZE 1024

 94

    // �Զ�Ϊ��Ĵ�С����λ��ʽ����

 95 #define _N_SEGMENT_ROUND(x) (((x) + SEGMENT_SIZE - 1) & ~(SEGMENT_SIZE - 1))

 96

    // �����β��ַ��

 97 #define _N_TXTENDADDR(x) (N_TXTADDR(x)+(x).a_text)

 98

    // ���ݶο�ʼ��ַ��

    // ����ļ���OMAGIC���͵ģ���ô���ݶξ�ֱ�ӽ������κ��档����Ļ����ݶε�ַ�Ӵ���

    // �κ���α߽翪ʼ��1KB�߽���룩������ZMAGIC���͵��ļ���

 99 #ifndef N_DATADDR

100 #define N_DATADDR(x) \

101     (N_MAGIC(x)==OMAGIC? (_N_TXTENDADDR(x)) \

102      : (_N_SEGMENT_ROUND (_N_TXTENDADDR(x))))

103 #endif

104

105 /* Address of bss segment in memory after it is loaded.  */

    /* bss�μ��ص��ڴ��Ժ�ĵ�ַ */

    // δ��ʼ�����ݶ�bbsλ�����ݶκ��棬�������ݶΡ�

106 #ifndef N_BSSADDR

107 #define N_BSSADDR(x) (N_DATADDR(x) + (x).a_data)

108 #endif

109

    // ��110��185���ǵ�2���֡���Ŀ���ļ��еķ��ű������ز�������ж����˵����

    // a.outĿ���ļ��з��ű���ṹ�����ű���¼�ṹ�����μ���������ϸ˵����

110 #ifndef N_NLIST_DECLARED

111 struct nlist {

112   union {

113     char *n_name;

114     struct nlist *n_next;

115     long n_strx;

116   } n_un;

117   unsigned char n_type;        // ���ֽڷֳ�3���ֶΣ�146--154������Ӧ�ֶε������롣

118   char n_other;

119   short n_desc;

120   unsigned long n_value;

121 };

122 #endif

123

    // ���涨��nlist�ṹ��n_type�ֶ�ֵ�ij������š�

124 #ifndef N_UNDF

125 #define N_UNDF 0

126 #endif

127 #ifndef N_ABS

128 #define N_ABS 2

129 #endif

130 #ifndef N_TEXT

131 #define N_TEXT 4

132 #endif

133 #ifndef N_DATA

134 #define N_DATA 6

135 #endif

136 #ifndef N_BSS

137 #define N_BSS 8

138 #endif

139 #ifndef N_COMM

140 #define N_COMM 18

141 #endif

142 #ifndef N_FN

143 #define N_FN 15

144 #endif

145

    // ����3������������nlist�ṹ��n_type�ֶε������루�˽��̱�ʾ����

146 #ifndef N_EXT

147 #define N_EXT 1                  // 0x01��0b0000,0001�������Ƿ����ⲿ�ģ�ȫ�ֵģ���

148 #endif

149 #ifndef N_TYPE

150 #define N_TYPE 036               // 0x1e��0b0001,1110�����ŵ�����λ��

151 #endif

152 #ifndef N_STAB                   // STAB -- ���ű����ͣ�Symbol table types����

153 #define N_STAB 0340              // 0xe0��0b1110,0000���⼸���������ڷ��ŵ�������

154 #endif

155

156 /* The following type indicates the definition of a symbol as being

157    an indirect reference to another symbol.  The other symbol

158    appears as an undefined reference, immediately following this symbol.

159

160    Indirection is asymmetrical.  The other symbol's value will be used

161    to satisfy requests for the indirect symbol, but not vice versa.

162    If the other symbol does not have a definition, libraries will

163    be searched to find a definition.  */

    /* ���������ָ����һ�����ŵĶ�������Ϊ����һ�����ŵļ�����á����Ӹ�

     * ���ŵ������ķ��ų���Ϊδ��������á�

     *

     * ���ּ�������Dz��ԳƵġ���һ�����ŵ�ֵ�������������ӷ��ŵ�Ҫ��

     * ����֮��Ȼ�������һ������û�ж��壬����������Ѱ��һ������ */

164 #define N_INDR 0xa

165

166 /* The following symbols refer to set elements.

167    All the N_SET[ATDB] symbols with the same name form one set.

168    Space is allocated for the set in the text section, and each set

169    element's value is stored into one word of the space.

170    The first word of the space is the length of the set (number of elements).

171

172    The address of the set is made into an N_SETV symbol

173    whose name is the same as the name of the set.

174    This symbol acts like a N_DATA global symbol

175    in that it can satisfy undefined external references.  */

    /* ����ķ����뼯��Ԫ���йء����о�����ͬ����N_SET[ATDB]�ķ���

       �γ�һ�����ϡ��ڴ��벿������Ϊ���Ϸ����˿ռ䣬����ÿ������Ԫ��

       ��ֵ�����һ���֣�word���Ŀռ��С��ռ�ĵ�һ���ִ��м��ϵij��ȣ�����Ԫ����Ŀ����

     

       ���ϵĵ�ַ������һ��N_SETV�����У����������뼯��ͬ����

       ������δ������ⲿ���÷��棬�÷��ŵ���Ϊ��һ��N_DATAȫ�ַ��š�*/

176

177 /* These appear as input to LD, in a .o file.  */

    /* ������Щ������ .o �ļ�������Ϊ���ӳ���LD�����롣*/

178 #define N_SETA  0x14        /* Absolute set element symbol */  /* ���Լ���Ԫ�ط��� */

179 #define N_SETT  0x16        /* Text set element symbol */      /* ���뼯��Ԫ�ط��� */

180 #define N_SETD  0x18        /* Data set element symbol */      /* ���ݼ���Ԫ�ط��� */

181 #define N_SETB  0x1A        /* Bss set element symbol */       /* Bss����Ԫ�ط��� */

182

183 /* This is output from LD.  */

    /* ������LD�������*/

184 #define N_SETV  0x1C        /* Pointer to set vector in data area.  */

                                /* ָ���������м���������*/

185

186 #ifndef N_RELOCATION_INFO_DECLARED

187

188 /* This structure describes a single relocation to be performed.

189    The text-relocation section of the file is a vector of these structures,

190    all of which apply to the text section.

191    Likewise, the data-relocation section applies to the data section.  */

    /* ����ṹ���������ض�λ������ִ�С�

       �ļ��Ĵ����ض�λ��������Щ�ṹ��һ�����飬������Щ�����ڴ��벿�֡�

       ���Ƶأ������ض�λ�����������ݲ��֡�*/

192

    // a.outĿ���ļ��д���������ض�λ��Ϣ�ṹ��

193 struct relocation_info

194 {

195   /* Address (within segment) to be relocated.  */

      /* ������Ҫ�ض�λ�ĵ�ַ��*/

196   int r_address;

197   /* The meaning of r_symbolnum depends on r_extern.  */

      /* r_symbolnum�ĺ�����r_extern�йء�*/

198   unsigned int r_symbolnum:24;

199   /* Nonzero means value is a pc-relative offset

200      and it should be relocated for changes in its own address

201      as well as for changes in the symbol or section specified.  */

      /* ������ζ��ֵ��һ��pc��ص�ƫ��ֵ����������Լ���ַ�ռ�

         �Լ����Ż�ָ���Ľڸı�ʱ����Ҫ���ض�λ */

202   unsigned int r_pcrel:1;

203   /* Length (as exponent of 2) of the field to be relocated.

204      Thus, a value of 2 indicates 1<<2 bytes.  */

      /* ��Ҫ���ض�λ���ֶγ��ȣ���2�Ĵη�����

         ��ˣ���ֵ��2���ʾ1<<2�ֽ�����*/

205   unsigned int r_length:2;

206   /* 1 => relocate with value of symbol.

207           r_symbolnum is the index of the symbol

208           in file's the symbol table.

209      0 => relocate with the address of a segment.

210           r_symbolnum is N_TEXT, N_DATA, N_BSS or N_ABS

211           (the N_EXT bit may be set also, but signifies nothing).  */

      /* 1 => �Է��ŵ�ֵ�ض�λ��

              r_symbolnum���ļ����ű��з��ŵ�������

         0 => �Զεĵ�ַ�����ض�λ��

              r_symbolnum��N_TEXT��N_DATA��N_BSS��N_ABS

              (N_EXT����λҲ���Ա����ã����Ǻ�������)��*/

212   unsigned int r_extern:1;

213   /* Four bits that aren't used, but when writing an object file

214      it is desirable to clear them.  */

      /* û��ʹ�õ�4������λ�����ǵ�����дһ��Ŀ���ļ�ʱ

         ��ý����Ǹ�λ����*/

215   unsigned int r_pad:4;

216 };

217 #endif /* no N_RELOCATION_INFO_DECLARED.  */

218

219

220 #endif /* __A_OUT_GNU_H__ */

221


 


 

14.2 ����14-2 linux/include/const.h


  1 #ifndef _CONST_H

  2 #define _CONST_H

  3

  4 #define BUFFER_END 0x200000          // ���建��ʹ���ڴ��ĩ�ˣ�������û��ʹ�øó�������

  5

    // i�ڵ����ݽṹ��i_mode�ֶεĸ���־λ��

  6 #define I_TYPE          0170000      // ָ��i�ڵ����ͣ����������룩��

  7 #define I_DIRECTORY     0040000      // ��Ŀ¼�ļ���

  8 #define I_REGULAR       0100000      // �dz����ļ�������Ŀ¼�ļ��������ļ���

  9 #define I_BLOCK_SPECIAL 0060000      // �ǿ��豸�����ļ���

 10 #define I_CHAR_SPECIAL  0020000      // ���ַ��豸�����ļ���

 11 #define I_NAMED_PIPE    0010000      // �������ܵ��ڵ㡣

 12 #define I_SET_UID_BIT   0004000      // ��ִ��ʱ������Ч�û�ID���͡�

 13 #define I_SET_GID_BIT   0002000      // ��ִ��ʱ������Ч��ID���͡�

 14

 15 #endif

 16


 

 


 

14.3 ����14-3 linux/include/ctype.h


  1 #ifndef _CTYPE_H

  2 #define _CTYPE_H

  3

  4 #define _U      0x01    /* upper */          // �ñ���λ���ڴ�д�ַ�[A-Z]��

  5 #define _L      0x02    /* lower */          // �ñ���λ����Сд�ַ�[a-z]��

  6 #define _D      0x04    /* digit */          // �ñ���λ��������[0-9]��

  7 #define _C      0x08    /* cntrl */          // �ñ���λ���ڿ����ַ���

  8 #define _P      0x10    /* punct */          // �ñ���λ���ڱ���ַ���

  9 #define _S      0x20    /* white space (space/lf/tab) */ // �հ��ַ�����ո�\t��\n�ȡ�

 10 #define _X      0x40    /* hex digit */           // �ñ���λ����ʮ���������֡�

 11 #define _SP     0x80    /* hard space (0x20) */   // �ñ���λ���ڿո��ַ���0x20����

 12

 13 extern unsigned char _ctype[];     // �ַ��������飨��������������ַ���Ӧ��������ԡ�

 14 extern char _ctmp;                 // һ����ʱ�ַ��������ڶ���lib/ctype.c�У���

 15

    // ������һЩȷ���ַ����͵ĺꡣ

 16 #define isalnum(c) ((_ctype+1)[c]&(_U|_L|_D))     // ���ַ�������[A-Z]��[a-z]��[0-9]��

 17 #define isalpha(c) ((_ctype+1)[c]&(_U|_L))        // ���ַ���

 18 #define iscntrl(c) ((_ctype+1)[c]&(_C))           // �ǿ����ַ���

 19 #define isdigit(c) ((_ctype+1)[c]&(_D))           // �����֡�

 20 #define isgraph(c) ((_ctype+1)[c]&(_P|_U|_L|_D))  // ��ͼ���ַ���

 21 #define islower(c) ((_ctype+1)[c]&(_L))           // ��Сд�ַ���

 22 #define isprint(c) ((_ctype+1)[c]&(_P|_U|_L|_D|_SP))  // �ǿɴ�ӡ�ַ���

 23 #define ispunct(c) ((_ctype+1)[c]&(_P))           // �DZ����š�

 24 #define isspace(c) ((_ctype+1)[c]&(_S))           // �ǿհ��ַ���ո�,\f,\n,\r,\t,\v��

 25 #define isupper(c) ((_ctype+1)[c]&(_U))           // �Ǵ�д�ַ���

 26 #define isxdigit(c) ((_ctype+1)[c]&(_D|_X))       // ��ʮ���������֡�

 27

    // ���������������У������ǰʹ����ǰ׺��unsigned�������c Ӧ�ü����ţ�����ʾ�� (c)��

    // ��Ϊ�ڳ�����c������һ�����ӵı���ʽ�����磬���������a + b�����������ţ����ں궨

    // ���б���ˣ�(unsigned) a + b������Ȼ���ԡ��������ž�����ȷ��ʾ��(unsigned)(a + b)��

 28 #define isascii(c) (((unsigned) c)<=0x7f)            // ��ASCII�ַ���

 29 #define toascii(c) (((unsigned) c)&0x7f)             // ת����ASCII�ַ���

 30

    // ���������궨����ʹ��һ����ʱ����_ctmp��ԭ���ǣ��ں궨���У���IJ���ֻ�ܱ�ʹ��һ�Ρ�

    // �����ڶ��߳���˵���Dz���ȫ�ģ���Ϊ���������߳̿�����ͬһʱ��ʹ�����������ʱ������

    // ��˴�Linux 2.2.x�汾��ʼ����Ϊʹ������������ȡ���������궨�塣

 31 #define tolower(c) (_ctmp=c,isupper(_ctmp)?_ctmp-('A'-'a'):_ctmp)  // ת����Сд�ַ���

 32 #define toupper(c) (_ctmp=c,islower(_ctmp)?_ctmp-('a'-'A'):_ctmp)  // ת���ɴ�д�ַ���

 33

 34 #endif

 35


 


 

14.4 ����14-4  linux/include/errno.h


  1 #ifndef _ERRNO_H

  2 #define _ERRNO_H

  3

  4 /*

  5  * ok, as I hadn't got any other source of information about

  6  * possible error numbers, I was forced to use the same numbers

  7  * as minix.

  8  * Hopefully these are posix or something. I wouldn't know (and posix

  9  * isn't telling me - they want $$$ for their f***ing standard).

 10  *

 11  * We don't use the _SIGN cludge of minix, so kernel returns must

 12  * see to the sign by themselves.

 13  *

 14  * NOTE! Remember to change strerror() if you change this file!

 15  */

    /*

     * ok��������û�еõ��κ������йس����ŵ����ϣ���ֻ��ʹ����minixϵͳ

     * ��ͬ�ij������ˡ�

     * ϣ����Щ��POSIX���ݵĻ�����һ���̶����������ģ��Ҳ�֪��������POSIX

     * û�и����� - Ҫ������ǵĻ쵰��׼��Ҫ��Ǯ����

     *

     * ����û��ʹ��minix������_SIGN�أ������ں˵ķ���ֵ�����Լ���������š�

     *

     * ע�⣡�����ı���ļ��Ļ�������ҲҪ�޸�strerror()������

     */

 16

    // ϵͳ�����Լ��ܶ�⺯������һ�������ֵ�Ա�ʾ����ʧ�ܻ���������ֵͨ��ѡ��-1����

    // ����һЩ�ض���ֵ����ʾ�������������ֵ��˵���������ˡ� �����Ҫ֪�����������ͣ�

    // ����Ҫ�鿴��ʾϵͳ�����ŵı���errno���ñ������� errno.h �ļ����������ڳ���ʼִ

    // ��ʱ�ñ���ֵ����ʼ��Ϊ0��

 17 extern int errno;

 18

    // �ڳ���ʱ��ϵͳ���û�ѳ����ŷ��ڱ���errno�У���ֵ����Ȼ�󷵻�-1����˳�������Ҫ֪

    // ���������ţ�����Ҫ�鿴errno��ֵ��

 19 #define ERROR           99                 // һ�����

 20 #define EPERM            1                 // ����û�����ɡ�

 21 #define ENOENT           2                 // �ļ���Ŀ¼�����ڡ�

 22 #define ESRCH            3                 // ָ���Ľ��̲����ڡ�

 23 #define EINTR            4                 // �жϵ�ϵͳ���á�

 24 #define EIO              5                 // ����/�������

 25 #define ENXIO            6                 // ָ���豸���ַ�����ڡ�

 26 #define E2BIG            7                 // �����б�̫����

 27 #define ENOEXEC          8                 // ִ�г����ʽ����

 28 #define EBADF            9                 // �ļ����(������)����

 29 #define ECHILD          10                 // �ӽ��̲����ڡ�

 30 #define EAGAIN          11                 // ��Դ��ʱ�����á�

 31 #define ENOMEM          12                 // �ڴ治�㡣

 32 #define EACCES          13                 // û������Ȩ�ޡ�

 33 #define EFAULT          14                 // ��ַ����

 34 #define ENOTBLK         15                 // ���ǿ��豸�ļ���

 35 #define EBUSY           16                 // ��Դ��æ��

 36 #define EEXIST          17                 // �ļ��Ѵ��ڡ�

 37 #define EXDEV           18                 // �Ƿ����ӡ�

 38 #define ENODEV          19                 // �豸�����ڡ�

 39 #define ENOTDIR         20                 // ����Ŀ¼�ļ���

 40 #define EISDIR          21                 // ��Ŀ¼�ļ���

 41 #define EINVAL          22                 // ������Ч��

 42 #define ENFILE          23                 // ϵͳ���ļ���̫�ࡣ

 43 #define EMFILE          24                 // ���ļ���̫�ࡣ

 44 #define ENOTTY          25                 // ��ǡ����IO���Ʋ���(û��tty�ն�)��

 45 #define ETXTBSY         26                 // ����ʹ�á�

 46 #define EFBIG           27                 // �ļ�̫��

 47 #define ENOSPC          28                 // �豸�������豸�Ѿ�û�пռ䣩��

 48 #define ESPIPE          29                 // ��Ч���ļ�ָ���ض�λ��

 49 #define EROFS           30                 // �ļ�ϵͳֻ����

 50 #define EMLINK          31                 // ����̫�ࡣ

 51 #define EPIPE           32                 // �ܵ�����

 52 #define EDOM            33                 // ��(domain)������

 53 #define ERANGE          34                 // ���̫��

 54 #define EDEADLK         35                 // ������Դ������

 55 #define ENAMETOOLONG    36                 // �ļ���̫����

 56 #define ENOLCK          37                 // û���������á�

 57 #define ENOSYS          38                 // ���ܻ�û��ʵ�֡�

 58 #define ENOTEMPTY       39                 // Ŀ¼���ա�

 59

 60 /* Should never be seen by user programs */

    /* �û�����Ӧ�ü������������д���� */

 61 #define ERESTARTSYS     512                // ����ִ��ϵͳ���á�

 62 #define ERESTARTNOINTR  513                // ����ִ��ϵͳ���ã����жϡ�

 63

 64 #endif

 65


 


 

14.5 ����14-5  linux/include/fcntl.h


  1 #ifndef _FCNTL_H

  2 #define _FCNTL_H

  3

  4 #include <sys/types.h>    // ����ͷ�ļ��������˻�����ϵͳ�������͡�

  5

  6 /* open/fcntl - NOCTTY, NDELAY isn't implemented yet */

    /* open/fcntl - NOCTTY��NDELAY���ڻ�û��ʵ�� */

  7 #define O_ACCMODE       00003                    // �ļ�����ģʽ�����롣

    // ���ļ�open()���ļ����ƺ���fcntl()ʹ�õ��ļ�����ģʽ��ͬʱֻ��ʹ������֮һ��

  8 #define O_RDONLY           00                    // ��ֻ����ʽ���ļ���

  9 #define O_WRONLY           01                    // ��ֻд��ʽ���ļ���

 10 #define O_RDWR             02                    // �Զ�д��ʽ���ļ���

    // �������ļ������Ͳ�����־������open()�������������ģʽ��'λ��'�ķ�ʽһ��ʹ�á�

 11 #define O_CREAT         00100   /* not fcntl */  // ����ļ������ھʹ�����fcntl�������á�

 12 #define O_EXCL          00200   /* not fcntl */  // ��ռʹ���ļ���־��

 13 #define O_NOCTTY        00400   /* not fcntl */  // ����������նˡ�

 14 #define O_TRUNC         01000   /* not fcntl */  // ���ļ��Ѵ�������д�������򳤶Ƚ�Ϊ0��

 15 #define O_APPEND        02000                    // �����ӷ�ʽ�򿪣��ļ�ָ����Ϊ�ļ�β��

 16 #define O_NONBLOCK      04000   /* not fcntl */  // ��������ʽ�򿪺Ͳ����ļ���

 17 #define O_NDELAY        O_NONBLOCK               // ��������ʽ�򿪺Ͳ����ļ���

 18

 19 /* Defines for fcntl-commands. Note that currently

 20  * locking isn't supported, and other things aren't really

 21  * tested.

 22  */

    /* ���涨����fcntl�����ע��Ŀǰ�������û��֧�֣�������

     * ����ʵ���ϻ�û�в��Թ���

     */

    // �ļ����(������)��������fcntl()�����cmd����

 23 #define F_DUPFD         0       /* dup */          // �����ļ����Ϊ��С��ֵ�ľ����

 24 #define F_GETFD         1      /* get f_flags */   // ȡ�����־����1����־FD_CLOEXEC��

 25 #define F_SETFD         2       /* set f_flags */  // �����ļ������־��

 26 #define F_GETFL         3       /* more flags (cloexec) */  // ȡ�ļ�״̬��־�ͷ���ģʽ��

 27 #define F_SETFL         4                                   // �����ļ�״̬��־�ͷ���ģʽ��

    // �������ļ��������fcntl()�ĵ���������lock��ָ��flock�ṹ��ָ�롣

 28 #define F_GETLK         5       /* not implemented */  // ������ֹ������flock�ṹ��

 29 #define F_SETLK         6       // ����(F_RDLCK��F_WRLCK)�����(F_UNLCK)������

 30 #define F_SETLKW        7       // �ȴ����û����������

 31

 32 /* for F_[GET|SET]FL */

    /* ���� F_GETFL��F_SETFL */

    // ��ִ��exec()�غ���ʱ��Ҫ�رյ��ļ������(ִ��ʱ�ر� - Close On EXECution)

 33 #define FD_CLOEXEC      1       /* actually anything with low bit set goes */

                                    /* ʵ����ֻҪ��λΪ1���� */

 34

 35 /* Ok, these are locking features, and aren't implemented at any

 36  * level. POSIX wants them.

 37  */

    /* OK���������������ͣ��κκ����ж���û��ʵ�֡�POSIX��׼Ҫ����Щ���͡�

     */

 38 #define F_RDLCK         0       // ��������ļ�������

 39 #define F_WRLCK         1       // ��ռ��д�ļ�������

 40 #define F_UNLCK         2       // �ļ�������

 41

 42 /* Once again - not implemented, but ... */

    /* ͬ�� - Ҳ��û��ʵ�֣�����... */

    // �ļ������������ݽṹ����������Ӱ���ļ��ε�����(l_type)����ʼƫ��(l_whence)��

    // ���ƫ��(l_start)����������(l_len)��ʵʩ�����Ľ���id��

 43 struct flock {

 44         short l_type;           // �������ͣ�F_RDLCK��F_WRLCK��F_UNLCK����

 45         short l_whence;         // ��ʼƫ��(SEEK_SET��SEEK_CUR��SEEK_END)��

 46         off_t l_start;          // ���������Ŀ�ʼ�������ƫ�ƣ��ֽ�������

 47         off_t l_len;            // ���������Ĵ�С�������0��Ϊ���ļ�ĩβ��

 48         pid_t l_pid;            // �����Ľ���id��

 49 };

 50

    // ������ʹ��������־������ĺ���ԭ�͡�

    // �������ļ�����дһ���Ѵ����ļ���

    // ����filename���������ļ����ļ�����mode�Ǵ����ļ������ԣ���include/sys/stat.h����

 51 extern int creat(const char * filename,mode_t mode);

    // �ļ������������Ӱ���ļ��Ĵ򿪡�

    // ����fildes���ļ������cmd�Dz������������23--30�С��ú����������¼�����ʽ��

    // int fcntl(int fildes, int cmd);

    // int fcntl(int fildes, int cmd, long arg);

    // int fcntl(int fildes, int cmd, struct flock *lock);

 52 extern int fcntl(int fildes,int cmd, ...);

    // ���ļ������ļ����ļ����֮�佨����ϵ��

    // ����filename�������ļ����ļ�����flags������7-17���ϵı�־����ϡ�

 53 extern int open(const char * filename, int flags, ...);

 54

 55 #endif

 56


 


 

14.6 ����14-6  linux/include/signal.h


  1 #ifndef _SIGNAL_H

  2 #define _SIGNAL_H

  3

  4 #include <sys/types.h>                  // ����ͷ�ļ��������˻�����ϵͳ�������͡�

  5

  6 typedef int sig_atomic_t;               // �����ź�ԭ�Ӳ������͡�

  7 typedef unsigned int sigset_t;          /* 32 bits */  // �����źż����͡�

  8

  9 #define _NSIG             32            // �����ź����� -- 32 �֡�

 10 #define NSIG            _NSIG           // NSIG = _NSIG

 11

    // ������Щ��Linux 0.12�ں��ж�����źš����а�����POSIX.1Ҫ�������20���źš�

 12 #define SIGHUP           1              // Hang Up     -- �ҶϿ����ն˻���̡�

 13 #define SIGINT           2              // Interrupt   -- ���Լ��̵��жϡ�

 14 #define SIGQUIT          3              // Quit        -- ���Լ��̵��˳���

 15 #define SIGILL           4              // Illeagle    -- �Ƿ�ָ�

 16 #define SIGTRAP          5              // Trap        -- ���ٶϵ㡣

 17 #define SIGABRT          6              // Abort       -- �쳣������

 18 #define SIGIOT           6              // IO Trap     -- ͬ�ϡ�

 19 #define SIGUNUSED        7              // Unused      -- û��ʹ�á�

 20 #define SIGFPE           8              // FPE         -- Э������������

 21 #define SIGKILL          9              // Kill        -- ǿ�Ƚ�����ֹ��

 22 #define SIGUSR1         10              // User1       -- �û��ź�1�����̿�ʹ�á�

 23 #define SIGSEGV         11              // Segment Violation -- ��Ч�ڴ����á�

 24 #define SIGUSR2         12              // User2       -- �û��ź�2�����̿�ʹ�á�

 25 #define SIGPIPE         13              // Pipe        -- �ܵ�д�������޶��ߡ�

 26 #define SIGALRM         14              // Alarm       -- ʵʱ��ʱ��������

 27 #define SIGTERM         15              // Terminate   -- ������ֹ��

 28 #define SIGSTKFLT       16              // Stack Fault -- ջ������Э����������

 29 #define SIGCHLD         17              // Child       -- �ӽ���ֹͣ����ֹ��

 30 #define SIGCONT         18              // Continue    -- �ָ����̼���ִ�С�

 31 #define SIGSTOP         19              // Stop        -- ֹͣ���̵�ִ�С�

 32 #define SIGTSTP         20              // TTY Stop    -- tty����ֹͣ���̣��ɺ��ԡ�

 33 #define SIGTTIN         21              // TTY In      -- ��̨�����������롣

 34 #define SIGTTOU         22              // TTY Out     -- ��̨�������������

 35

 36 /* Ok, I haven't implemented sigactions, but trying to keep headers POSIX */

    /* OK���һ�û��ʵ��sigactions�ı��ƣ�����ͷ�ļ�����ϣ������POSIX��׼ */

    // ����ԭע���Ѿ���ʱ����Ϊ��0.12�ں����Ѿ�ʵ����sigaction()��������sigaction�ṹ

    // sa_flags��־�ֶο�ȡ�ķ��ų���ֵ��

 37 #define SA_NOCLDSTOP    1               // ���ӽ��̴���ֹͣ״̬���Ͳ���SIGCHLD������

 38 #define SA_INTERRUPT    0x20000000      // ϵͳ���ñ��ź��жϺ���������ϵͳ���á�

 39 #define SA_NOMASK       0x40000000      // ����ֹ��ָ�����źŴ������������յ����źš�

 40 #define SA_ONESHOT      0x80000000      // �źž��һ�������ù��ͻָ���Ĭ�ϴ��������

 41

    // ���³�������sigprocmask(how, )-- �ı������źż�(������)�����ڸı�ú�������Ϊ��

 42 #define SIG_BLOCK       0  /* for blocking signals */   // �������źż��м��ϸ����źš�

 43 #define SIG_UNBLOCK     1  /* for unblocking signals */ // �������źż���ɾ��ָ���źš�

 44 #define SIG_SETMASK     2  /* for setting the signal mask */   // ���������źż���

 45

    // ���������������Ŷ���ʾָ���޷���ֵ�ĺ���ָ�룬�Ҷ���һ��int���Ͳ�����������ָ��

    // ֵ���߼��Ͻ�ʵ���ϲ����ܳ��ֵĺ�����ֵַ������Ϊ����signal�����ĵڶ�����������

    // �ڸ�֪�ںˣ����ں˴����źŻ���Զ��źŵĴ�����ʹ�÷����μ� kernel/signal.c����

    // ��94--96�С�

 46 #define SIG_DFL         ((void (*)(int))0)      /* default signal handling */

                                                    // Ĭ���źŴ��������źž������

 47 #define SIG_IGN         ((void (*)(int))1)      /* ignore signal */

                                                    // �����źŵĴ�������

 48 #define SIG_ERR         ((void (*)(int))-1)     /* error return from signal */

                                                    // �źŴ������ش���

 49

    // ���涨���ʼ��������sigaction�ṹ�ź�������ĺꡣ

 50 #ifdef notdef

 51 #define sigemptyset(mask) ((*(mask) = 0), 1)    // ��mask���㡣

 52 #define sigfillset(mask) ((*(mask) = ~0), 1)    // ��mask���б���λ��λ��

 53 #endif

 54

    // ������sigaction�����ݽṹ��

    // sa_handler�Ƕ�Ӧij�ź�ָ��Ҫ��ȡ���ж��������������SIG_DFL����SIG_IGN�����Ը�

    // �źţ�Ҳ������ָ�������źź�����һ��ָ�롣

    // sa_mask�����˶��źŵ������룬���źų���ִ��ʱ����������Щ�źŵĴ�����

// sa_flagsָ���ı��źŴ������̵��źż���������37-40�е�λ��־����ġ�

// sa_restorer�ǻָ�����ָ�룬�ɺ�����Libc�ṩ�����������û�̬��ջ���μ�signal.c��

    // ���⣬���𴥷��źŴ������ź�Ҳ��������������ʹ����SA_NOMASK��־��

 55 struct sigaction {

 56         void (*sa_handler)(int);

 57         sigset_t sa_mask;

 58         int sa_flags;

 59         void (*sa_restorer)(void);

 60 };

 61

    // ����signal����������Ϊ�ź�_sig��װһ�µ��źŴ��������źž��������sigaction()

    // ���ơ��ú�����������������ָ����Ҫ������ź�_sig������һ���������޷���ֵ�ĺ���ָ��

    // _func���ú�������ֵҲ�Ǿ���һ��int���������һ��(int)�����޷���ֵ�ĺ���ָ�룬����

    // �������źŵ�ԭ���������

 62 void (*signal(int _sig, void (*_func)(int)))(int);

    // �������������ڷ����źš�kill() �������κν��̻�����鷢���źš�raise()������ǰ��

    // �����������źš������õȼ���kill(getpid(),sig)���μ�kernel/exit.c��60�С�

 63 int raise(int sig);

 64 int kill(pid_t pid, int sig);

    // �ڽ��̵�����ṹ�У�����һ���Ա���λ��ʾ��ǰ���̴�������32λ�ź��ֶ�signal���⣬

    // ����һ��ͬ���Ա���λ��ʾ���������ν��̵�ǰ�����źż��������źż������ֶ�blocked��

    // Ҳ��32λ��ÿ�����ش���һ����Ӧ�������źš��޸Ľ��̵������źż�����������������

    // ��ָ�����źš� ������������������ڲ������������źż�����Ȼ��ʵ�������ܼ򵥣���

    // ���汾�ں��л�δʵ�֡�

    // ����sigaddset() �� sigdelset() ���ڶ��źż��е��źŽ�������ɾ�޸ġ� sigaddset()��

    // ����maskָ����źż�������ָ�����ź�signo��sigdelset��֮������sigemptyset()��

    // sigfillset() ���ڳ�ʼ�����������źż��� ÿ��������ʹ���źż�ǰ������Ҫʹ����������

    // ��֮һ�������źż����г�ʼ���� sigemptyset()����������ε������źţ�Ҳ����Ӧ���е�

    // �źš�sigfillset()���źż������������źţ�Ҳ�����������źš���Ȼ SIGINT�� SIGSTOP

    // �Dz��ܱ����εġ�

    // sigismember()���ڲ���һ��ָ���ź��Ƿ����źż��У�1 - �ǣ�0 - ���ǣ�-1 - ��������

 65 int sigaddset(sigset_t *mask, int signo);

 66 int sigdelset(sigset_t *mask, int signo);

 67 int sigemptyset(sigset_t *mask);

 68 int sigfillset(sigset_t *mask);

 69 int sigismember(sigset_t *mask, int signo); /* 1 - is, 0 - not, -1 error */

    // ��set�е��źŽ��м�⣬���Ƿ��й�����źš���set�з��ؽ����е�ǰ���������źż���

 70 int sigpending(sigset_t *set);

    // ���溯�����ڸı����Ŀǰ���������źż����ź������룩����oldset����NULL����ͨ����

    // ���ؽ��̵�ǰ�����źż�����setָ�벻��NULL�������how��41-43�У�ָʾ�޸Ľ�������

    // �źż���

 71 int sigprocmask(int how, sigset_t *set, sigset_t *oldset);

    // ���溯���� sigmask ��ʱ�滻���̵��ź�������,Ȼ����ͣ�ý���ֱ���յ�һ���źš�����׽

    // ��ijһ�źŲ��Ӹ��źŴ��������з��أ���ú���Ҳ���أ������ź��������ָ������õ���

    // ǰ��ֵ��

 72 int sigsuspend(sigset_t *sigmask);

    // sigaction() �������ڸı�������յ�ָ���ź�ʱ����ȡ���ж������ı��źŵĴ�������ܡ�

    // �μ���kernel/signal.c�����˵����

 73 int sigaction(int sig, struct sigaction *act, struct sigaction *oldact);

 74

 75 #endif /* _SIGNAL_H */

 76


 


 

14.7 ����14-7 linux/include/stdarg.h


  1 #ifndef _STDARG_H

  2 #define _STDARG_H

  3

  4 typedef char *va_list;  // ����va_list��һ���ַ�ָ�����͡�

  5

  6 /* Amount of space required in an argument list for an arg of type TYPE.

  7    TYPE may alternatively be an expression whose type is used.  */

    /* �������������ΪTYPE��arg�����б���Ҫ��Ŀռ�������

       TYPEҲ������ʹ�ø����͵�һ������ʽ */

  8

    // ������䶨����ȡ�����TYPE���͵��ֽڳ���ֵ����int����(4)�ı�����

  9 #define __va_rounded_size(TYPE)  \

 10   (((sizeof (TYPE) + sizeof (int) - 1) / sizeof (int)) * sizeof (int))

 11

    // ����������ʼ��ָ��AP��ʹ��ָ�򴫸������Ŀɱ�������ĵ�һ��������

    // �ڵ�һ�ε���va_arg��va_end֮ǰ���������ȵ���va_start�ꡣ����LASTARG�Ǻ�������

    // �����ұ߲����ı�ʶ������'...'��ߵ�һ����ʶ����AP�ǿɱ����������ָ�룬LASTARG��

    // ���һ��ָ��������&(LASTARG) ����ȡ���ַ������ָ�룩�����Ҹ�ָ�����ַ����͡�����

    // LASTARG�Ŀ���ֵ��AP���ǿɱ�������е�һ��������ָ�롣�ú�û�з���ֵ��

    // ��17���ϵĺ��� __builtin_saveregs() ����gcc�Ŀ����libgcc2.c�ж���ģ����ڱ���

    // �Ĵ����� ���˵���μ� gcc�ֲᡰTarget Description Macros�����С�Implementing the

    // Varargs Macros��С�ڡ�

 12 #ifndef __sparc__

 13 #define va_start(AP, LASTARG)                                           \

 14  (AP = ((char *) &(LASTARG) + __va_rounded_size (LASTARG)))

 15 #else

 16 #define va_start(AP, LASTARG)                                           \

 17  (__builtin_saveregs (),                                                \

 18   AP = ((char *) &(LASTARG) + __va_rounded_size (LASTARG)))

 19 #endif

 20

    // ����ú����ڱ����ú������һ���������ء�va_end�����޸�APʹ�������µ���

    // va_start֮ǰ���ܱ�ʹ�á�va_end������va_arg�������еIJ������ٱ����á�

 21 void va_end (va_list);          /* Defined in gnulib */  /* ��gnulib�ж��� */

 22 #define va_end(AP)

 23

    // �����������չ����ʽʹ������һ�������ݲ���������ͬ�����ͺ�ֵ��

    // ����ȱʡֵ��va_arg �������ַ����޷����ַ��͸������͡��ڵ�һ��ʹ�� va_argʱ������

    // �ر��еĵ�һ��������������ÿ�ε��ö������ر��е���һ������������ͨ���ȷ���AP��Ȼ

    // ��������ֵ��ָ����һ����ʵ�ֵġ�va_arg ʹ��TYPE ����ɷ��ʺͶ�λ��һ�ÿ����һ

    // ��va_arg�������޸�AP��ָʾ���е���һ������

 24 #define va_arg(AP, TYPE)                           \

 25  (AP += __va_rounded_size (TYPE),                  \

 26   *((TYPE *) (AP - __va_rounded_size (TYPE))))

 27

 28 #endif /* _STDARG_H */

 29


 


 

14.8 ����14-8 linux/include/stddef.h


  1 #ifndef _STDDEF_H

  2 #define _STDDEF_H

  3

  4 #ifndef _PTRDIFF_T

  5 #define _PTRDIFF_T

  6 typedef long ptrdiff_t;              // ����ָ�������������͡�

  7 #endif

  8

  9 #ifndef _SIZE_T

 10 #define _SIZE_T

 11 typedef unsigned long size_t;        // sizeof���ص����͡�

 12 #endif

 13

 14 #undef NULL

 15 #define NULL ((void *)0)             // ��ָ�롣

 16

    // ���涨����һ������ij��Ա��������ƫ��λ�õĺꡣʹ�øú����ȷ��һ����Ա���ֶΣ���

    // �������Ľṹ�����дӽṹ��ʼ��������ֽ�ƫ��������Ľ��������Ϊ size_t ��������

    // ������ʽ��������һ�������÷���((TYPE *)0)�ǽ�һ������0����Ͷ�䣨type cast������

    // �ݶ���ָ�����ͣ�Ȼ���ڸý���Ͻ������㡣

 17 #define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER)

 18

 19 #endif

 20


 


 

14.9 ����14-9 linux/include/string.h


  1 #ifndef _STRING_H_

  2 #define _STRING_H_

  3

  4 #ifndef NULL

  5 #define NULL ((void *) 0)

  6 #endif

  7

  8 #ifndef _SIZE_T

  9 #define _SIZE_T

 10 typedef unsigned int size_t;

 11 #endif

 12

 13 extern char * strerror(int errno);

 14

 15 /*

 16  * This string-include defines all string functions as inline

 17  * functions. Use gcc. It also assumes ds=es=data space, this should be

 18  * normal. Most of the string-functions are rather heavily hand-optimized,

 19  * see especially strtok,strstr,str[c]spn. They should work, but are not

 20  * very easy to understand. Everything is done entirely within the register

 21  * set, making the functions fast and clean. String instructions have been

 22  * used through-out, making for "slightly" unclear code :-)

 23  *

 24  *              (C) 1991 Linus Torvalds

 25  */

    /*

     * ����ַ���ͷ�ļ�����Ƕ��������ʽ�����������ַ�������������ʹ��gccʱ��ͬʱ

     * �ٶ���ds=es=���ݿռ䣬��Ӧ���dz���ġ���������ַ����������Ǿ��ֹ����д���

     * �Ż��ģ������Ǻ���strtok��strstr��str[c]spn������Ӧ����������������ȴ������

     * ô�������⡣���еIJ��������϶���ʹ�üĴ���������ɵģ���ʹ�ú������������ࡣ

     * ���еط���ʹ�����ַ���ָ�����ʹ�ô��롰��΢����������J

     *

     *              (C) 1991 Linus Torvalds

     */

 26 

    //// ��һ���ַ���(src)��������һ���ַ���(dest)��ֱ������NULL�ַ���ֹͣ��

    // ������dest - Ŀ���ַ���ָ�룬src - Դ�ַ���ָ�롣

    // %0 - esi(src)��%1 - edi(dest)��

 27 extern inline char * strcpy(char * dest,const char *src)

 28 {

 29 __asm__("cld\n"                      // �巽��λ��

 30         "1:\tlodsb\n\t"              // ����DS:[esi]��1�ֽ���al��������esi��

 31         "stosb\n\t"                  // �洢�ֽ�al��ES:[edi]��������edi��

 32         "testb %%al,%%al\n\t"        // �մ洢���ֽ���0��

 33         "jne 1b"                     // �����������ת�����1�������������

 34         ::"S" (src),"D" (dest):"si","di","ax");

 35 return dest;                         // ����Ŀ���ַ���ָ�롣

 36 }

 37

    //// ����Դ�ַ���count���ֽڵ�Ŀ���ַ�����

    // ���Դ������С��count���ֽڣ��͸��ӿ��ַ�(NULL)��Ŀ���ַ�����

    // ������dest - Ŀ���ַ���ָ�룬src - Դ�ַ���ָ�룬count - �����ֽ�����

    // %0 - esi(src)��%1 - edi(dest)��%2 - ecx(count)��

 38 extern inline char * strncpy(char * dest,const char *src,int count)

 39 {

 40 __asm__("cld\n"                      // �巽��λ��

 41         "1:\tdecl %2\n\t"            // �Ĵ���ecx--��count--����

 42         "js 2f\n\t"                  // ���count<0����ǰ��ת�����2��������

 43         "lodsb\n\t"                  // ȡds:[esi]��1�ֽ���al������esi++��

 44         "stosb\n\t"                  // �洢���ֽ���es:[edi]������edi++��

 45         "testb %%al,%%al\n\t"        // ���ֽ���0��

 46         "jne 1b\n\t"                 // ���ǣ�����ǰ��ת�����1������������

 47         "rep\n\t"                    // ������Ŀ�Ĵ��д��ʣ������Ŀ��ַ���

 48         "stosb\n"

 49         "2:"

 50         ::"S" (src),"D" (dest),"c" (count):"si","di","ax","cx");

 51 return dest;                         // ����Ŀ���ַ���ָ�롣

 52 }

 53

    //// ��Դ�ַ���������Ŀ���ַ�����ĩβ����

    // ������dest - Ŀ���ַ���ָ�룬src - Դ�ַ���ָ�롣

    // %0 - esi(src)��%1 - edi(dest)��%2 - eax(0)��%3 - ecx(-1)��

 54 extern inline char * strcat(char * dest,const char * src)

 55 {

 56 __asm__("cld\n\t"                    // �巽��λ��

 57         "repne\n\t"                  // �Ƚ�al��es:[edi]�ֽڣ�������edi++��

 58         "scasb\n\t"                  // ֱ���ҵ�Ŀ�Ĵ�����0���ֽڣ���ʱedi��ָ���1�ֽڡ�

 59         "decl %1\n"                  // ��es:[edi]ָ��0ֵ�ֽڡ�

 60         "1:\tlodsb\n\t"              // ȡԴ�ַ����ֽ�ds:[esi]��al����esi++��

 61         "stosb\n\t"                  // �����ֽڴ浽es:[edi]����edi++��

 62         "testb %%al,%%al\n\t"        // ���ֽ���0��

 63         "jne 1b"                     // ���ǣ��������ת�����1���������������������

 64         ::"S" (src),"D" (dest),"a" (0),"c" (0xffffffff):"si","di","ax","cx");

 65 return dest;                         // ����Ŀ���ַ���ָ�롣

 66 }

 67

    //// ��Դ�ַ�����count���ֽڸ��Ƶ�Ŀ���ַ�����ĩβ���������һ���ַ���

    // ������dest - Ŀ���ַ�����src - Դ�ַ�����count - �����Ƶ��ֽ�����

    // %0 - esi(src)��%1 - edi(dest)��%2 - eax(0)��%3 - ecx(-1)��%4 - (count)��

 68 extern inline char * strncat(char * dest,const char * src,int count)

 69 {

 70 __asm__("cld\n\t"                    // �巽��λ��

 71         "repne\n\t"                  // �Ƚ�al��es:[edi]�ֽڣ�edi++��

 72         "scasb\n\t"                  // ֱ���ҵ�Ŀ�Ĵ���ĩ��0ֵ�ֽڡ�

 73         "decl %1\n\t"                // ediָ���0ֵ�ֽڡ�

 74         "movl %4,%3\n"               // �������ֽ�����ecx��

 75         "1:\tdecl %3\n\t"            // ecx--����0��ʼ��������

 76         "js 2f\n\t"                  // ecx <0 ?��������ǰ��ת�����2����

 77         "lodsb\n\t"                  // ����ȡds:[esi]�����ֽ���al��esi++��

 78         "stosb\n\t"                  // �洢��es:[edi]����edi++��

 79         "testb %%al,%%al\n\t"        // ���ֽ�ֵΪ0��

 80         "jne 1b\n"                   // �����������ת�����1�����������ơ�

 81         "2:\txorl %2,%2\n\t"         // ��al���㡣

 82         "stosb"                      // �浽es:[edi]����

 83         ::"S" (src),"D" (dest),"a" (0),"c" (0xffffffff),"g" (count)

 84         :"si","di","ax","cx");

 85 return dest;                         // ����Ŀ���ַ���ָ�롣

 86 }

 87

    //// ��һ���ַ�������һ���ַ������бȽϡ�

    // ������cs - �ַ���1��ct - �ַ���2��

    // %0 - eax(__res)����ֵ��%1 - edi(cs)�ַ���1ָ�룬%2 - esi(ct)�ַ���2ָ�롣

    // ���أ������1 > ��2���򷵻�1����1 = ��2���򷵻�0����1 < ��2���򷵻�-1��

    // ��90�ж�����һ���ֲ��Ĵ����������ñ�������������eax�Ĵ����У��Ա��ڸ�Ч���ʺͲ�����

    // ���ֶ�������ķ�����Ҫ������Ƕ�������С���ϸ˵���μ�gcc�ֲ���ָ���Ĵ����еı�������

 88 extern inline int strcmp(const char * cs,const char * ct)

 89 {

 90 register int __res __asm__("ax");    // __res�ǼĴ�������(eax)��

 91 __asm__("cld\n"                      // �巽��λ��

 92         "1:\tlodsb\n\t"              // ȡ�ַ���2���ֽ�ds:[esi]��al������esi++��

 93         "scasb\n\t"                  // al���ַ���1���ֽ�es:[edi]���Ƚϣ�����edi++��

 94         "jne 2f\n\t"                 // �������ȣ�����ǰ��ת�����2��

 95         "testb %%al,%%al\n\t"        // ���ֽ���0ֵ�ֽ����ַ�����β����

 96         "jne 1b\n\t"                 // ���ǣ��������ת�����1�������Ƚϡ�

 97         "xorl %%eax,%%eax\n\t"       // �ǣ��򷵻�ֵeax���㣬

 98         "jmp 3f\n"                   // ��ǰ��ת�����3��������

 99         "2:\tmovl $1,%%eax\n\t"      // eax����1��

100         "jl 3f\n\t"                  // ��ǰ��Ƚ��д�2�ַ�<��1�ַ����򷵻���ֵ������

101         "negl %%eax\n"               // ����eax = -eax�����ظ�ֵ��������

102         "3:"

103         :"=a" (__res):"D" (cs),"S" (ct):"si","di");

104 return __res;                        // ���رȽϽ����

105 }

106

    //// �ַ���1���ַ���2��ǰcount���ַ����бȽϡ�

    // ������cs - �ַ���1��ct - �ַ���2��count - �Ƚϵ��ַ�����

    // %0 - eax(__res)����ֵ��%1 - edi(cs)��1ָ�룬%2 - esi(ct)��2ָ�룬%3 - ecx(count)��

    // ���أ������1 > ��2���򷵻�1����1 = ��2���򷵻�0����1 < ��2���򷵻�-1��

107 extern inline int strncmp(const char * cs,const char * ct,int count)

108 {

109 register int __res __asm__("ax");    // __res�ǼĴ�������(eax)��

110 __asm__("cld\n"                      // �巽��λ��

111         "1:\tdecl %3\n\t"            // count--��

112         "js 2f\n\t"                  // ���count<0������ǰ��ת�����2��

113         "lodsb\n\t"                  // ȡ��2���ַ�ds:[esi]��al������esi++��

114         "scasb\n\t"                  // �Ƚ�al�봮1���ַ�es:[edi]������edi++��

115         "jne 3f\n\t"                 // �������ȣ�����ǰ��ת�����3��

116         "testb %%al,%%al\n\t"        // ���ַ���NULL�ַ���

117         "jne 1b\n"                   // ���ǣ��������ת�����1�������Ƚϡ�

118         "2:\txorl %%eax,%%eax\n\t"   // ��NULL�ַ�����eax���㣨����ֵ����

119         "jmp 4f\n"                   // ��ǰ��ת�����4��������

120         "3:\tmovl $1,%%eax\n\t"      // eax����1��

121         "jl 4f\n\t"                  // ���ǰ��Ƚ��д�2�ַ�<��1�ַ����򷵻�1������

122         "negl %%eax\n"               // ����eax = -eax�����ظ�ֵ��������

123         "4:"

124         :"=a" (__res):"D" (cs),"S" (ct),"c" (count):"si","di","cx");

125 return __res;                        // ���رȽϽ����

126 }

127

    //// ���ַ�����Ѱ�ҵ�һ��ƥ����ַ���

    // ������s - �ַ�����c - ��Ѱ�ҵ��ַ���

    // %0 - eax(__res)��%1 - esi(�ַ���ָ��s)��%2 - eax(�ַ�c)��

    // ���أ������ַ����е�һ�γ���ƥ���ַ���ָ�롣��û���ҵ�ƥ����ַ����򷵻ؿ�ָ�롣

128 extern inline char * strchr(const char * s,char c)

129 {

130 register char * __res __asm__("ax"); // __res�ǼĴ�������(eax)��

131 __asm__("cld\n\t"                    // �巽��λ��

132         "movb %%al,%%ah\n"           // �����Ƚ��ַ��Ƶ�ah��

133         "1:\tlodsb\n\t"              // ȡ�ַ������ַ�ds:[esi]��al������esi++��

134         "cmpb %%ah,%%al\n\t"         // �ַ������ַ�al��ָ���ַ�ah��Ƚϡ�

135         "je 2f\n\t"                  // ����ȣ�����ǰ��ת�����2����

136         "testb %%al,%%al\n\t"        // al���ַ���NULL�ַ��𣿣��ַ�����β����

137         "jne 1b\n\t"                 // �����ǣ��������ת�����1�������Ƚϡ�

138         "movl $1,%1\n"               // �ǣ���˵��û���ҵ�ƥ���ַ���esi��1��

139         "2:\tmovl %1,%0\n\t"         // ��ָ��ƥ���ַ���һ���ֽڴ���ָ��ֵ����eax

140         "decl %0"                    // ��ָ�����Ϊָ��ƥ����ַ���

141         :"=a" (__res):"S" (s),"0" (c):"si");

142 return __res;                        // ����ָ�롣

143 }

144

    //// Ѱ���ַ�����ָ���ַ����һ�γ��ֵĵط��������������ַ�����

    // ������s - �ַ�����c - ��Ѱ�ҵ��ַ���

    // %0 - edx(__res)��%1 - edx(0)��%2 - esi(�ַ���ָ��s)��%3 - eax(�ַ�c)��

    // ���أ������ַ��������һ�γ���ƥ���ַ���ָ�롣��û���ҵ�ƥ����ַ����򷵻ؿ�ָ�롣

145 extern inline char * strrchr(const char * s,char c)

146 {

147 register char * __res __asm__("dx"); // __res�ǼĴ�������(edx)��

148 __asm__("cld\n\t"                    // �巽��λ��

149         "movb %%al,%%ah\n"           // ����Ѱ�ҵ��ַ��Ƶ�ah��

150         "1:\tlodsb\n\t"              // ȡ�ַ������ַ�ds:[esi]��al������esi++��

151         "cmpb %%ah,%%al\n\t"         // �ַ������ַ�al��ָ���ַ�ah���Ƚϡ�

152         "jne 2f\n\t"                 // ������ȣ�����ǰ��ת�����2����

153         "movl %%esi,%0\n\t"          // ���ַ�ָ�뱣�浽edx�С�

154         "decl %0\n"                  // ָ�����һλ��ָ���ַ�����ƥ���ַ�����

155         "2:\ttestb %%al,%%al\n\t"    // �Ƚϵ��ַ���0�𣨵��ַ���β����

156         "jne 1b"                     // �����������ת�����1���������Ƚϡ�

157         :"=d" (__res):"0" (0),"S" (s),"a" (c):"ax","si");

158 return __res;                        // ����ָ�롣

159 }

160

    //// ���ַ���1��Ѱ�ҵ�1���ַ����У����ַ������е��κ��ַ����������ַ���2�С�

    // ������cs - �ַ���1ָ�룬ct - �ַ���2ָ�롣

    // %0 - esi(__res)��%1 - eax(0)��%2 - ecx(-1)��%3 - esi(��1ָ��cs)��%4 - (��2ָ��ct)��

    // �����ַ���1�а����ַ���2���κ��ַ����׸��ַ����еij���ֵ��

161 extern inline int strspn(const char * cs, const char * ct)

162 {

163 register char * __res __asm__("si"); // __res�ǼĴ�������(esi)��

164 __asm__("cld\n\t"                    // �巽��λ��

165         "movl %4,%%edi\n\t"          // ���ȼ��㴮2�ij��ȡ���2ָ�����edi�С�

166         "repne\n\t"                  // �Ƚ�al(0)�봮2�е��ַ���es:[edi]������edi++��

167         "scasb\n\t"                  // �������Ⱦͼ����Ƚ�(ecx�𲽵ݼ�)��

168         "notl %%ecx\n\t"             // ecx��ÿλȡ����

169         "decl %%ecx\n\t"             // ecx--���ô�2�ij���ֵ��

170         "movl %%ecx,%%edx\n"         // ����2�ij���ֵ�ݷ���edx�С�

171         "1:\tlodsb\n\t"              // ȡ��1�ַ�ds:[esi]��al������esi++��

172         "testb %%al,%%al\n\t"        // ���ַ�����0ֵ�𣨴�1��β����

173         "je 2f\n\t"                  // ����ǣ�����ǰ��ת�����2����

174         "movl %4,%%edi\n\t"          // ȡ��2ͷָ�����edi�С�

175         "movl %%edx,%%ecx\n\t"       // �ٽ���2�ij���ֵ����ecx�С�

176         "repne\n\t"                  // �Ƚ�al�봮2���ַ�es:[edi]������edi++��

177         "scasb\n\t"                  // �������Ⱦͼ����Ƚϡ�

178         "je 1b\n"                    // �����ȣ��������ת�����1����

179         "2:\tdecl %0"                // esi--��ָ�����һ�������ڴ�2�е��ַ���

180         :"=S" (__res):"a" (0),"c" (0xffffffff),"0" (cs),"g" (ct)

181         :"ax","cx","dx","di");

182 return __res-cs;                     // �����ַ����еij���ֵ��

183 }

184

    //// Ѱ���ַ���1�в������ַ���2���κ��ַ����׸��ַ����С�

    // ������cs - �ַ���1ָ�룬ct - �ַ���2ָ�롣

    // %0 - esi(__res)��%1 - eax(0)��%2 - ecx(-1)��%3 - esi(��1ָ��cs)��%4 - (��2ָ��ct)��

    // �����ַ���1�в������ַ���2���κ��ַ����׸��ַ����еij���ֵ��

185 extern inline int strcspn(const char * cs, const char * ct)

186 {

187 register char * __res __asm__("si"); // __res�ǼĴ�������(esi)��

188 __asm__("cld\n\t"                    // �巽��λ��

189         "movl %4,%%edi\n\t"          // ���ȼ��㴮2�ij��ȡ���2ָ�����edi�С�

190         "repne\n\t"                  // �Ƚ�al(0)�봮2�е��ַ���es:[edi]������edi++��

191         "scasb\n\t"                  // �������Ⱦͼ����Ƚ�(ecx�𲽵ݼ�)��

192         "notl %%ecx\n\t"             // ecx��ÿλȡ����

193         "decl %%ecx\n\t"             // ecx--���ô�2�ij���ֵ��

194         "movl %%ecx,%%edx\n"         // ����2�ij���ֵ�ݷ���edx�С�

195         "1:\tlodsb\n\t"              // ȡ��1�ַ�ds:[esi]��al������esi++��

196         "testb %%al,%%al\n\t"        // ���ַ�����0ֵ�𣨴�1��β����

197         "je 2f\n\t"                  // ����ǣ�����ǰ��ת�����2����

198         "movl %4,%%edi\n\t"          // ȡ��2ͷָ�����edi�С�

199         "movl %%edx,%%ecx\n\t"       // �ٽ���2�ij���ֵ����ecx�С�

200         "repne\n\t"                  // �Ƚ�al�봮2���ַ�es:[edi]������edi++��

201         "scasb\n\t"                  // �������Ⱦͼ����Ƚϡ�

202         "jne 1b\n"                   // �������ȣ��������ת�����1����

203         "2:\tdecl %0"                // esi--��ָ�����һ�������ڴ�2�е��ַ���

204         :"=S" (__res):"a" (0),"c" (0xffffffff),"0" (cs),"g" (ct)

205         :"ax","cx","dx","di");

206 return __res-cs;                     // �����ַ����еij���ֵ��

207 }

208

    //// ���ַ���1��Ѱ���׸��������ַ���2�е��κ��ַ���

    // ������cs - �ַ���1��ָ�룬ct - �ַ���2��ָ�롣

    // %0 -esi(__res)��%1 -eax(0)��%2 -ecx(0xffffffff)��%3 -esi(��1ָ��cs)��%4 -(��2ָ��ct)��

    // �����ַ���1���׸������ַ���2���ַ���ָ�롣

209 extern inline char * strpbrk(const char * cs,const char * ct)

210 {

211 register char * __res __asm__("si"); // __res�ǼĴ�������(esi)��

212 __asm__("cld\n\t"                    // �巽��λ��

213         "movl %4,%%edi\n\t"          // ���ȼ��㴮2�ij��ȡ���2ָ�����edi�С�

214         "repne\n\t"                  // �Ƚ�al(0)�봮2�е��ַ���es:[edi]������edi++��

215         "scasb\n\t"                  // �������Ⱦͼ����Ƚ�(ecx�𲽵ݼ�)��

216         "notl %%ecx\n\t"             // ecx��ÿλȡ����

217         "decl %%ecx\n\t"             // ecx--���ô�2�ij���ֵ��

218         "movl %%ecx,%%edx\n"         // ����2�ij���ֵ�ݷ���edx�С�

219         "1:\tlodsb\n\t"              // ȡ��1�ַ�ds:[esi]��al������esi++��

220         "testb %%al,%%al\n\t"        // ���ַ�����0ֵ�𣨴�1��β����

221         "je 2f\n\t"                  // ����ǣ�����ǰ��ת�����2����

222         "movl %4,%%edi\n\t"          // ȡ��2ͷָ�����edi�С�

223         "movl %%edx,%%ecx\n\t"       // �ٽ���2�ij���ֵ����ecx�С�

224         "repne\n\t"                  // �Ƚ�al�봮2���ַ�es:[edi]������edi++��

225         "scasb\n\t"                  // �������Ⱦͼ����Ƚϡ�

226         "jne 1b\n\t"                 // �������ȣ��������ת�����1����

227         "decl %0\n\t"                // esi--��ָ��һ�������ڴ�2�е��ַ���

228         "jmp 3f\n"                   // ��ǰ��ת�����3����

229         "2:\txorl %0,%0\n"           // û���ҵ����������ģ�������ֵΪNULL��

230         "3:"

231         :"=S" (__res):"a" (0),"c" (0xffffffff),"0" (cs),"g" (ct)

232         :"ax","cx","dx","di");

233 return __res;                        // ����ָ��ֵ��

234 }

235

    //// ���ַ���1��Ѱ���׸�ƥ�������ַ���2���ַ�����

    // ������cs - �ַ���1��ָ�룬ct - �ַ���2��ָ�롣

    // %0 -eax(__res)��%1 -eax(0)��%2 -ecx(0xffffffff)��%3 -esi(��1ָ��cs)��%4 -(��2ָ��ct)��

    // ���أ������ַ���1���׸�ƥ���ַ���2���ַ���ָ�롣

236 extern inline char * strstr(const char * cs,const char * ct)

237 {

238 register char * __res __asm__("ax"); // __res�ǼĴ�������(eax)��

239 __asm__("cld\n\t" \                  // �巽��λ��

240         "movl %4,%%edi\n\t"          // ���ȼ��㴮2�ij��ȡ���2ָ�����edi�С�

241         "repne\n\t"                  // �Ƚ�al(0)�봮2�е��ַ���es:[edi]������edi++��

242         "scasb\n\t"                  // �������Ⱦͼ����Ƚ�(ecx�𲽵ݼ�)��

243         "notl %%ecx\n\t"             // ecx��ÿλȡ����

244         "decl %%ecx\n\t"    /* NOTE! This also sets Z if searchstring='' */

                                /* ע�⣡���������Ϊ�գ�������Z��־ */ // �ô�2�ij���ֵ��

245         "movl %%ecx,%%edx\n"         // ����2�ij���ֵ�ݷ���edx�С�

246         "1:\tmovl %4,%%edi\n\t"      // ȡ��2ͷָ�����edi�С�

247         "movl %%esi,%%eax\n\t"       // ����1��ָ�븴�Ƶ�eax�С�

248         "movl %%edx,%%ecx\n\t"       // �ٽ���2�ij���ֵ����ecx�С�

249         "repe\n\t"                   // �Ƚϴ�1�ʹ�2�ַ�(ds:[esi],es:[edi])��esi++,edi++��

250         "cmpsb\n\t"                  // ����Ӧ�ַ���Ⱦ�һֱ�Ƚ���ȥ��

251         "je 2f\n\t"         /* also works for empty string, see above */

                                /* �Կմ�ͬ����Ч�������� */ // ��ȫ��ȣ���ת�����2��

252         "xchgl %%eax,%%esi\n\t"      // ��1ͷָ����esi���ȽϽ���Ĵ�1ָ����eax��

253         "incl %%esi\n\t"             // ��1ͷָ��ָ����һ���ַ���

254         "cmpb $0,-1(%%eax)\n\t"      // ��1ָ��(eax-1)��ָ�ֽ���0��

255         "jne 1b\n\t"                 // ������ת�����1�������Ӵ�1�ĵ�2���ַ���ʼ�Ƚϡ�

256         "xorl %%eax,%%eax\n\t"       // ��eax����ʾû���ҵ�ƥ�䡣

257         "2:"

258         :"=a" (__res):"0" (0),"c" (0xffffffff),"S" (cs),"g" (ct)

259         :"cx","dx","di","si");

260 return __res;                        // ���رȽϽ����

261 }

262

    //// �����ַ������ȡ�

    // ������s - �ַ�����

    // %0 - ecx(__res)��%1 - edi(�ַ���ָ��s)��%2 - eax(0)��%3 - ecx(0xffffffff)��

    // ���أ������ַ����ij��ȡ�

263 extern inline int strlen(const char * s)

264 {

265 register int __res __asm__("cx");    // __res�ǼĴ�������(ecx)��

266 __asm__("cld\n\t"                    // �巽��λ��

267         "repne\n\t"                  // al(0)���ַ������ַ�es:[edi]�Ƚϣ�

268         "scasb\n\t"                  // ������Ⱦ�һֱ�Ƚϡ�

269         "notl %0\n\t"                // ecxȡ����

270         "decl %0"                    // ecx--�����ַ����ó���ֵ��

271         :"=c" (__res):"D" (s),"a" (0),"0" (0xffffffff):"di");

272 return __res;                        // �����ַ�������ֵ��

273 }

274

275 extern char * ___strtok;     // ������ʱ���ָ�����汻�����ַ���1(s)��ָ�롣

276

    //// �����ַ���2�е��ַ����ַ���1�ָ�ɱ��(tokern)���С�

    // ����1�����ǰ��������������(token)�����У����ɷָ���ַ���2�е�һ�������ַ�

    // �ֿ�����һ�ε��� strtok()ʱ��������ָ���ַ���1�е�1��token���ַ���ָ�룬���ڷ�

    // ��tokenʱ��һ null�ַ�д���ָ����������ʹ�� null ��Ϊ�ַ���1�ĵ��ã��������ַ�

    // ������ɨ���ַ���1��ֱ��û��token Ϊֹ���ڲ�ͬ�ĵ��ù����У��ָ����2���Բ�ͬ��

    // ������s - ���������ַ���1��ct - ���������ָ�����ַ���2��

    // ��������%0 - ebx(__res)��%1 - esi(__strtok)��

    // ������룺%2 - ebx(__strtok)��%3 - esi(�ַ���1ָ��s)��%4 - (�ַ���2ָ��ct)��

    // ���أ������ַ���s�е�1��token�����û���ҵ�token���򷵻�һ��nullָ�롣

    // ����ʹ���ַ���sָ��Ϊnull�ĵ��ã�����ԭ�ַ���s��������һ��token��

277 extern inline char * strtok(char * s,const char * ct)

278 {

279 register char * __res __asm__("si");

280 __asm__("testl %1,%1\n\t"            // ���Ȳ���esi(�ַ���1ָ��s)�Ƿ���NULL��

281         "jne 1f\n\t"                 // ������ǣ���������״ε��ñ���������ת���1��

282         "testl %0,%0\n\t"            // ����NULL����ʾ�˴��Ǻ������ã���ebx(__strtok)��

283         "je 8f\n\t"                  // ���ebxָ����NULL�����ܴ�������ת������

284         "movl %0,%1\n"               // ��ebxָ�븴�Ƶ�esi��

285         "1:\txorl %0,%0\n\t"         // ��ebxָ�롣

286         "movl $-1,%%ecx\n\t"         // ��ecx = 0xffffffff��

287         "xorl %%eax,%%eax\n\t"       // ����eax��

288         "cld\n\t"                    // �巽��λ��

289         "movl %4,%%edi\n\t"          // �������ַ���2�ij��ȡ�ediָ���ַ���2��

290         "repne\n\t"                  // ��al(0)��es:[edi]�Ƚϣ�����edi++��

291         "scasb\n\t"                  // ֱ���ҵ��ַ���2�Ľ���null�ַ��������ecx==0��

292         "notl %%ecx\n\t"             // ��ecxȡ����

293         "decl %%ecx\n\t"             // ecx--���õ��ַ���2�ij���ֵ��

294         "je 7f\n\t"                  /* empty delimeter-string */

                                         /* �ָ���ַ����� */ // ����2����Ϊ0����ת���7��

295         "movl %%ecx,%%edx\n"         // ����2�����ݴ���edx��

296         "2:\tlodsb\n\t"              // ȡ��1���ַ�ds:[esi]��al������esi++��

297         "testb %%al,%%al\n\t"        // ���ַ�Ϊ0ֵ��(��1����)��

298         "je 7f\n\t"                  // ����ǣ�����ת���7��

299         "movl %4,%%edi\n\t"          // edi�ٴ�ָ��2�ס�

300         "movl %%edx,%%ecx\n\t"       // ȡ��2�ij���ֵ���������ecx��

301         "repne\n\t"                  // ��al�д�1���ַ��봮2�������ַ��Ƚϣ�

302         "scasb\n\t"                  // �жϸ��ַ��Ƿ�Ϊ�ָ����

303         "je 2b\n\t"                  // �����ڴ�2���ҵ���ͬ�ַ����ָ����������ת���2��

304         "decl %1\n\t"                // �����Ƿָ������1ָ��esiָ���ʱ�ĸ��ַ���

305         "cmpb $0,(%1)\n\t"           // ���ַ���NULL�ַ���

306         "je 7f\n\t"                  // ���ǣ�����ת���7����

307         "movl %1,%0\n"               // �����ַ���ָ��esi�����ebx��

308         "3:\tlodsb\n\t"              // ȡ��1��һ���ַ�ds:[esi]��al������esi++��

309         "testb %%al,%%al\n\t"        // ���ַ���NULL�ַ���

310         "je 5f\n\t"                  // ���ǣ���ʾ��1��������ת�����5��

311         "movl %4,%%edi\n\t"          // edi�ٴ�ָ��2�ס�

312         "movl %%edx,%%ecx\n\t"       // ��2����ֵ���������ecx��

313         "repne\n\t"                  // ��al�д�1���ַ��봮2��ÿ���ַ��Ƚϣ�

314         "scasb\n\t"                  // ����al�ַ��Ƿ��Ƿָ����

315         "jne 3b\n\t"                 // �����Ƿָ������ת���3����⴮1����һ���ַ���

316         "decl %1\n\t"                // ���Ƿָ������esi--��ָ��÷ָ���ַ���

317         "cmpb $0,(%1)\n\t"           // �÷ָ����NULL�ַ���

318         "je 5f\n\t"                  // ���ǣ�����ת�����5��

319         "movb $0,(%1)\n\t"           // �����ǣ��򽫸÷ָ����NULL�ַ��滻����

320         "incl %1\n\t"                // esiָ��1����һ���ַ���Ҳ��ʣ�മ�ס�

321         "jmp 6f\n"                   // ��ת���6����

322         "5:\txorl %1,%1\n"           // esi���㡣

323         "6:\tcmpb $0,(%0)\n\t"       // ebxָ��ָ��NULL�ַ���

324         "jne 7f\n\t"                 // �����ǣ�����ת���7��

325         "xorl %0,%0\n"               // ���ǣ�����ebx=NULL��

326         "7:\ttestl %0,%0\n\t"        // ebxָ��ΪNULL��

327         "jne 8f\n\t"                 // ����������ת8�����������롣

328         "movl %0,%1\n"               // ��esi��ΪNULL��

329         "8:"

330         :"=b" (__res),"=S" (___strtok)

331         :"0" (___strtok),"1" (s),"g" (ct)

332         :"ax","cx","dx","di");

333 return __res;                        // ����ָ����token��ָ�롣

334 }

335

    //// �ڴ�鸴�ơ���Դ��ַsrc����ʼ����n���ֽڵ�Ŀ�ĵ�ַdest����

    // ������dest - ���Ƶ�Ŀ�ĵ�ַ��src - ���Ƶ�Դ��ַ��n - �����ֽ�����

    // %0 - ecx(n)��%1 - esi(src)��%2 - edi(dest)��

336 extern inline void * memcpy(void * dest,const void * src, int n)

337 {

338 __asm__("cld\n\t"                    // �巽��λ��

339         "rep\n\t"                    // �ظ�ִ�и���ecx���ֽڣ�

340         "movsb"                      // ��ds:[esi]��es:[edi]��esi++��edi++��

341         ::"c" (n),"S" (src),"D" (dest)

342         :"cx","si","di");

343 return dest;                         // ����Ŀ�ĵ�ַ��

344 }

345

    //// �ڴ���ƶ���ͬ�ڴ�鸴�ƣ��������ƶ��ķ���

    // ������dest - ���Ƶ�Ŀ�ĵ�ַ��src - ���Ƶ�Դ��ַ��n - �����ֽ�����

    // ��dest<src��%0 - ecx(n)��%1 - esi(src)��%2 - edi(dest)��

    // ����%0 - ecx(n)��%1 - esi(src+n-1)��%2 - edi(dest+n-1)��

    // ����������Ϊ�˷�ֹ�ڸ���ʱ������ص����ǡ�

346 extern inline void * memmove(void * dest,const void * src, int n)

347 {

348 if (dest<src)

349 __asm__("cld\n\t"                    // �巽��λ��

350         "rep\n\t"                    // ��ds:[esi]��es:[edi]������esi++��edi++��

351         "movsb"                      // �ظ�ִ�и���ecx�ֽڡ�

352         ::"c" (n),"S" (src),"D" (dest)

353         :"cx","si","di");

354 else

355 __asm__("std\n\t"                    // �÷���λ����ĩ�˿�ʼ���ơ�

356         "rep\n\t"                    // ��ds:[esi]��es:[edi]������esi--��edi--��

357         "movsb"                      // ����ecx���ֽڡ�

358         ::"c" (n),"S" (src+n-1),"D" (dest+n-1)

359         :"cx","si","di");

360 return dest;

361 }

362

    //// �Ƚ�n���ֽڵ������ڴ棨�����ַ���������ʹ����NULL�ֽ�Ҳ��ֹͣ�Ƚϡ�

    // ������cs - �ڴ��1��ַ��ct - �ڴ��2��ַ��count - �Ƚϵ��ֽ�����

    // %0 - eax(__res)��%1 - eax(0)��%2 - edi(�ڴ��1)��%3 - esi(�ڴ��2)��%4 - ecx(count)��

    // ���أ�����1>��2 ����1����1<��2������-1����1==��2���򷵻�0��

363 extern inline int memcmp(const void * cs,const void * ct,int count)

364 {

365 register int __res __asm__("ax");    // __res�ǼĴ���������

366 __asm__("cld\n\t"                    // �巽��λ��

367         "repe\n\t"                   // ���������ظ���

368         "cmpsb\n\t"                  // �Ƚ�ds:[esi]��es:[edi]�����ݣ�����esi++��edi++��

369         "je 1f\n\t"                  // �������ͬ������ת�����1������0(eax)ֵ

370         "movl $1,%%eax\n\t"          // ����eax��1��

371         "jl 1f\n\t"                  // ���ڴ��2���ݵ�ֵ<�ڴ��1������ת���1��

372         "negl %%eax\n"               // ����eax = -eax��

373         "1:"

374         :"=a" (__res):"0" (0),"D" (cs),"S" (ct),"c" (count)

375         :"si","di","cx");

376 return __res;                        // ���رȽϽ����

377 }

378

    //// ��n�ֽڴ�С���ڴ��(�ַ���)��Ѱ��ָ���ַ���

    // ������cs - ָ���ڴ���ַ��c - ָ�����ַ���count - �ڴ�鳤�ȡ�

    // %0 - edi(__res)��%1 - eax(�ַ�c)��%2 - edi(�ڴ���ַcs)��%3 - ecx(�ֽ���count)��

    // ���ص�һ��ƥ���ַ���ָ�룬���û���ҵ����򷵻�NULL�ַ���

379 extern inline void * memchr(const void * cs,char c,int count)

380 {

381 register void * __res __asm__("di"); // __res�ǼĴ���������

382 if (!count)                          // ����ڴ�鳤��==0���򷵻�NULL��û���ҵ���

383         return NULL;

384 __asm__("cld\n\t"                    // �巽��λ��

385         "repne\n\t"                  // �����������ظ�ִ��������䣬

386         "scasb\n\t"                  // al���ַ���es:[edi]�ַ����Ƚϣ�����edi++��

387         "je 1f\n\t"                  // ����������ǰ��ת�����1����

388         "movl $1,%0\n"               // ����edi����1��

389         "1:\tdecl %0"                // ��ediָ���ҵ����ַ�������NULL����

390         :"=D" (__res):"a" (c),"D" (cs),"c" (count)

391         :"cx");

392 return __res;                        // �����ַ�ָ�롣

393 }

394

    //// ���ַ���дָ�������ڴ�顣

    // ���ַ�c��дsָ����ڴ����򣬹���count�ֽڡ�

    // %0 - eax(�ַ�c)��%1 - edi(�ڴ��ַ)��%2 - ecx(�ֽ���count)��

395 extern inline void * memset(void * s,char c,int count)

396 {

397 __asm__("cld\n\t"                    // �巽��λ��

398         "rep\n\t"                    // �ظ�ecxָ���Ĵ�����ִ��

399         "stosb"                      // ��al���ַ�����es:[edi]�У�����edi++��

400         ::"a" (c),"D" (s),"c" (count)

401         :"cx","di");

402 return s;

403 }

404

405 #endif

406


 


 

14.10 ����14-10 linux/include/termios.h


  1 #ifndef _TERMIOS_H

  2 #define _TERMIOS_H

  3

  4 #include <sys/types.h>

  5

  6 #define TTY_BUF_SIZE 1024            // tty�еĻ��������ȡ�

  7

  8 /* 0x54 is just a magic number to make these relatively uniqe ('T') */

    /* 0x54ֻ��һ��ħ����Ŀ����Ϊ��ʹ��Щ����Ψһ('T') */

  9

    // tty�豸��ioctl���������ioctl����������ڵ�λ���С�

    // ��������TC[*]�ĺ�����tty�������

    // ȡ��Ӧ�ն�termios�ṹ�е���Ϣ(�μ�tcgetattr())��

 10 #define TCGETS          0x5401

    // ������Ӧ�ն�termios�ṹ�е���Ϣ(�μ�tcsetattr()��TCSANOW)��

 11 #define TCSETS          0x5402

    // �������ն�termios����Ϣ֮ǰ����Ҫ�ȵȴ�����������������ݴ�����(�ľ�)�������޸IJ���

    // ��Ӱ����������������Ҫʹ��������ʽ(�μ�tcsetattr()��TCSADRAINѡ��)��

 12 #define TCSETSW         0x5403

    // ������termios����Ϣ֮ǰ����Ҫ�ȵȴ�����������������ݴ����꣬����ˢ��(���)������С�

    // �����ã��μ�tcsetattr()��TCSAFLUSHѡ���

 13 #define TCSETSF         0x5404

    // ȡ��Ӧ�ն�termio�ṹ�е���Ϣ(�μ�tcgetattr())��

 14 #define TCGETA          0x5405

    // ������Ӧ�ն�termio�ṹ�е���Ϣ(�μ�tcsetattr()��TCSANOWѡ��)��

 15 #define TCSETA          0x5406

    // �������ն�termio����Ϣ֮ǰ����Ҫ�ȵȴ�����������������ݴ�����(�ľ�)�������޸IJ���

    // ��Ӱ����������������Ҫʹ��������ʽ(�μ�tcsetattr()��TCSADRAINѡ��)��

 16 #define TCSETAW         0x5407

    // ������termio����Ϣ֮ǰ����Ҫ�ȵȴ�����������������ݴ����꣬����ˢ��(���)������С�

    // �����ã��μ�tcsetattr()��TCSAFLUSHѡ���

 17 #define TCSETAF         0x5408

    // �ȴ�������д������(��)��������ֵ��0������һ��break���μ�tcsendbreak()��tcdrain()����

 18 #define TCSBRK          0x5409

    // ��ʼ/ֹͣ���ơ��������ֵ��0�����������������1�������¿������������������2��

    // ��������룻�����3�������¿�����������루�μ�tcflow()����

 19 #define TCXONC          0x540A

    // ˢ����д�������û���ͻ����յ���û�ж����ݡ����������0����ˢ��(���)������У����

    // ��1����ˢ��������У������2����ˢ�������������У��μ�tcflush()����

 20 #define TCFLSH          0x540B

    // ��������TIOC[*]�ĺ�����tty ��������������

    // �����ն˴�����·ר��ģʽ��

 21 #define TIOCEXCL        0x540C

    // ��λ�ն˴�����·ר��ģʽ��

 22 #define TIOCNXCL        0x540D

    // ����ttyΪ�����նˡ�(TIOCNOTTY - ��ֹttyΪ�����ն�)��

 23 #define TIOCSCTTY       0x540E

    // ��ȡָ���ն��豸���̵���id���μ�tcgetpgrp()���ó�������������"Terminal IO Control

    // Get PGRP "����д����ȡǰ̨������ID��

 24 #define TIOCGPGRP       0x540F

    // ����ָ���ն��豸���̵���id(�μ�tcsetpgrp())��

 25 #define TIOCSPGRP       0x5410

    // ������������л�δ�ͳ����ַ�����

 26 #define TIOCOUTQ        0x5411

    // ģ���ն����롣��������һ��ָ���ַ���ָ����Ϊ����������װ���ַ������ն��ϼ���ġ��û�

    // �����ڸÿ����ն��Ͼ��г����û�Ȩ�޻���ж�����Ȩ�ޡ�

 27 #define TIOCSTI         0x5412

    // ��ȡ�ն��豸���ڴ�С��Ϣ���μ�winsize�ṹ����

 28 #define TIOCGWINSZ      0x5413

    // �����ն��豸���ڴ�С��Ϣ���μ�winsize�ṹ����

 29 #define TIOCSWINSZ      0x5414

    // ����modem״̬�������ߵĵ�ǰ״̬����λ��־�����μ�����185-196�У���

 30 #define TIOCMGET        0x5415

    // ���õ���modem״̬�������ߵ�״̬(true��false)(Individual control line Set)��

 31 #define TIOCMBIS        0x5416

    // ��λ����modem״̬�������ߵ�״̬(Individual control line clear)��

 32 #define TIOCMBIC        0x5417

    // ����modem״̬���ߵ�״̬�����ijһ����λ��λ����modem��Ӧ��״̬���߽���Ϊ��Ч��

 33 #define TIOCMSET        0x5418

    // ��ȡ�����ز�����־(1 - ������0 - �ر�)��

    // ���ڱ������ӵ��ն˻������豸�������ز���־�ǿ����ģ�����ʹ��modem��·���ն˻��豸

    // ���ǹرյġ�Ϊ����ʹ�������� ioctl���ã�tty��·Ӧ������ O_NDELAY ��ʽ�򿪵ģ�����

    // open()�Ͳ���ȴ��ز���

 34 #define TIOCGSOFTCAR    0x5419

    // ���������ز�����־(1 - ������0 - �ر�)��

 35 #define TIOCSSOFTCAR    0x541A

    // ������������л�δȡ���ַ�����Ŀ��

 36 #define FIONREAD        0x541B

 37 #define TIOCINQ         FIONREAD

 38

    // ���ڴ�С(Window size)���Խṹ���ڴ��ڻ����п����ڻ�����Ļ��Ӧ�ó���

    // ioctls�е�TIOCGWINSZ��TIOCSWINSZ��������ȡ��������Щ��Ϣ��

 39 struct winsize {

 40         unsigned short ws_row;       // �����ַ�������

 41         unsigned short ws_col;       // �����ַ�������

 42         unsigned short ws_xpixel;    // ���ڿ��ȣ�����ֵ��

 43         unsigned short ws_ypixel;    // ���ڸ߶ȣ�����ֵ��

 44 };

 45

    // AT&TϵͳV��termio�ṹ��

 46 #define NCC 8                        // termio�ṹ�п����ַ�����ij��ȡ�

 47 struct termio {

 48         unsigned short c_iflag;      /* input mode flags */     // ����ģʽ��־��

 49         unsigned short c_oflag;      /* output mode flags */    // ���ģʽ��־��

 50         unsigned short c_cflag;      /* control mode flags */   // ����ģʽ��־��

 51         unsigned short c_lflag;      /* local mode flags */     // ����ģʽ��־��

 52         unsigned char c_line;        /* line discipline */      // ��·��̣����ʣ���

 53         unsigned char c_cc[NCC];     /* control characters */   // �����ַ����顣

 54 };

 55

    // POSIX��termios�ṹ��

 56 #define NCCS 17                      // termios�ṹ�п����ַ����鳤�ȡ�

 57 struct termios {

 58         tcflag_t c_iflag;            /* input mode flags */     // ����ģʽ��־��

 59         tcflag_t c_oflag;            /* output mode flags */    // ���ģʽ��־��

 60         tcflag_t c_cflag;            /* control mode flags */   // ����ģʽ��־��

 61         tcflag_t c_lflag;            /* local mode flags */     // ����ģʽ��־��

 62         cc_t c_line;                 /* line discipline */      // ��·��̣����ʣ���

 63         cc_t c_cc[NCCS];             /* control characters */   // �����ַ����顣

 64 };

 65

    // �����ǿ����ַ�����c_cc[]���������ֵ���������ʼֵ������include/linux/tty.h�С�

    // ������Ը�����������е�ֵ�����������_POSIX_VDISABLE��\0������ô������ijһ��ֵ

    // ���� _POSIX_VDISABLE ��ֵʱ����ʾ��ֹʹ����������Ӧ�������ַ���

 66 /* c_cc characters */    /* c_cc�����е��ַ� */

 67 #define VINTR 0          // c_cc[VINTR]    = INTR    (^C)��\003���ж��ַ���

 68 #define VQUIT 1          // c_cc[VQUIT]    = QUIT    (^\)��\034���˳��ַ���

 69 #define VERASE 2         // c_cc[VERASE]   = ERASE   (^H)��\177�������ַ���

 70 #define VKILL 3          // c_cc[VKILL]    = KILL    (^U)��\025����ֹ�ַ���ɾ���У���

 71 #define VEOF 4           // c_cc[VEOF]     = EOF     (^D)��\004���ļ������ַ���

 72 #define VTIME 5          // c_cc[VTIME]    = TIME    (\0)��\0��  ��ʱ��ֵ(�μ�����˵��)��

 73 #define VMIN 6           // c_cc[VMIN]     = MIN     (\1)��\1��  ��ʱ��ֵ��

 74 #define VSWTC 7          // c_cc[VSWTC]    = SWTC    (\0)��\0��  �����ַ���

 75 #define VSTART 8         // c_cc[VSTART]   = START   (^Q)��\021����ʼ�ַ���

 76 #define VSTOP 9          // c_cc[VSTOP]    = STOP    (^S)��\023��ֹͣ�ַ���

 77 #define VSUSP 10         // c_cc[VSUSP]    = SUSP    (^Z)��\032�������ַ���

 78 #define VEOL 11          // c_cc[VEOL]     = EOL     (\0)��\0��  �н����ַ���

 79 #define VREPRINT 12      // c_cc[VREPRINT] = REPRINT (^R)��\022������ʾ�ַ���

 80 #define VDISCARD 13      // c_cc[VDISCARD] = DISCARD (^O)��\017�������ַ���

 81 #define VWERASE 14       // c_cc[VWERASE]  = WERASE  (^W)��\027�����ʲ����ַ���

 82 #define VLNEXT 15        // c_cc[VLNEXT]   = LNEXT   (^V)��\026����һ���ַ���

 83 #define VEOL2 16         // c_cc[VEOL2]    = EOL2    (\0)��\0��  �н����ַ�2��

 84

    // termios�ṹ����ģʽ�ֶ�c_iflag���ֱ�־�ķ��ų�����

 85 /* c_iflag bits */       /* c_iflag����λ */

 86 #define IGNBRK  0000001            // ����ʱ����BREAK������

 87 #define BRKINT  0000002            // ��BREAKʱ����SIGINT�źš�

 88 #define IGNPAR  0000004            // ������żУ��������ַ���

 89 #define PARMRK  0000010            // �����żУ�����

 90 #define INPCK   0000020            // ����������żУ�顣

 91 #define ISTRIP  0000040            // �����ַ���8λ��

 92 #define INLCR   0000100            // ����ʱ�����з�NLӳ��ɻس���CR��

 93 #define IGNCR   0000200            // ���Իس���CR��

 94 #define ICRNL   0000400            // ������ʱ���س���CRӳ��ɻ��з�NL��

 95 #define IUCLC   0001000            // ������ʱ����д�ַ�ת����Сд�ַ���

 96 #define IXON    0002000            // ������ʼ/ֹͣ��XON/XOFF��������ơ�

 97 #define IXANY   0004000            // �����κ��ַ����������

 98 #define IXOFF   0010000            // ������ʼ/ֹͣ��XON/XOFF��������ơ�

 99 #define IMAXBEL 0020000            // ���������ʱ���塣

100

    // termios�ṹ�����ģʽ�ֶ�c_oflag���ֱ�־�ķ��ų�����

101 /* c_oflag bits */       /* c_oflag����λ */

102 #define OPOST   0000001            // ִ�����������

103 #define OLCUC   0000002            // �����ʱ��Сд�ַ�ת���ɴ�д�ַ���

104 #define ONLCR   0000004            // �����ʱ�����з�NLӳ��ɻس�-���з�CR-NL��

105 #define OCRNL   0000010            // �����ʱ���س���CRӳ��ɻ��з�NL��

106 #define ONOCR   0000020            // ��0�в�����س���CR��

107 #define ONLRET  0000040            // ���з�NLִ�лس����Ĺ��ܡ�

108 #define OFILL   0000100            // �ӳ�ʱʹ������ַ�����ʹ��ʱ���ӳ١�

109 #define OFDEL   0000200            // ����ַ���ASCII��DEL�����δ���ã���ʹ��ASCII NULL��

110 #define NLDLY   0000400            // ѡ�����ӳ١�

111 #define   NL0   0000000            // �����ӳ�����0��

112 #define   NL1   0000400            // �����ӳ�����1��

113 #define CRDLY   0003000            // ѡ��س��ӳ١�

114 #define   CR0   0000000            // �س��ӳ�����0��

115 #define   CR1   0001000            // �س��ӳ�����1��

116 #define   CR2   0002000            // �س��ӳ�����2��

117 #define   CR3   0003000            // �س��ӳ�����3��

118 #define TABDLY  0014000            // ѡ��ˮƽ�Ʊ��ӳ١�

119 #define   TAB0  0000000            // ˮƽ�Ʊ��ӳ�����0��

120 #define   TAB1  0004000            // ˮƽ�Ʊ��ӳ�����1��

121 #define   TAB2  0010000            // ˮƽ�Ʊ��ӳ�����2��

122 #define   TAB3  0014000            // ˮƽ�Ʊ��ӳ�����3��

123 #define   XTABS 0014000            // ���Ʊ���TAB���ɿո񣬸�ֵ��ʾ�ո�����

124 #define BSDLY   0020000            // ѡ���˸��ӳ١�

125 #define   BS0   0000000            // �˸��ӳ�����0��

126 #define   BS1   0020000            // �˸��ӳ�����1��

127 #define VTDLY   0040000            // �����Ʊ��ӳ١�

128 #define   VT0   0000000            // �����Ʊ��ӳ�����0��

129 #define   VT1   0040000            // �����Ʊ��ӳ�����1��

130 #define FFDLY   0040000            // ѡ��ҳ�ӳ١�

131 #define   FF0   0000000            // ��ҳ�ӳ�����0��

132 #define   FF1   0040000            // ��ҳ�ӳ�����1��

133

    // termios�ṹ�п���ģʽ��־�ֶ�c_cflag��־�ķ��ų�����8����������

134 /* c_cflag bit meaning */     /* c_cflag ����λ�ĺ��� */

135 #define CBAUD   0000017         // ��������λ�����롣

136 #define  B0     0000000         /* hang up */  /* �Ҷ���· */

137 #define  B50    0000001         // ������ 50��

138 #define  B75    0000002         // ������ 75��

139 #define  B110   0000003         // ������ 110��

140 #define  B134   0000004         // ������ 134��

141 #define  B150   0000005         // ������ 150��

142 #define  B200   0000006         // ������ 200��

143 #define  B300   0000007         // ������ 300��

144 #define  B600   0000010         // ������ 600��

145 #define  B1200  0000011         // ������ 1200��

146 #define  B1800  0000012         // ������ 1800��

147 #define  B2400  0000013         // ������ 2400��

148 #define  B4800  0000014         // ������ 4800��

149 #define  B9600  0000015         // ������ 9600��

150 #define  B19200 0000016         // ������ 19200��

151 #define  B38400 0000017         // ������ 38400��

152 #define EXTA B19200             // ��չ������A��

153 #define EXTB B38400             // ��չ������B��

 

154 #define CSIZE   0000060         // �ַ�λ���������롣

155 #define   CS5   0000000         // ÿ�ַ�5����λ��

156 #define   CS6   0000020         // ÿ�ַ�6����λ��

157 #define   CS7   0000040         // ÿ�ַ�7����λ��

158 #define   CS8   0000060         // ÿ�ַ�8����λ��

159 #define CSTOPB  0000100         // ��������ֹͣλ��������1����

160 #define CREAD   0000200         // �������ա�

161 #define PARENB  0000400         // �������ʱ������żλ������ʱ������żУ�顣

162 #define PARODD  0001000         // ����/����У������У�顣

163 #define HUPCL   0002000         // �����̹رպ�Ҷϡ�

164 #define CLOCAL  0004000         // ���Ե��ƽ����(modem)������·��

165 #define CIBAUD  03600000        /* input baud rate (not used) */  /* ���벨����(δʹ��) */

166 #define CRTSCTS 020000000000    /* flow control */  /* ������ */

167

    // termios�ṹ�б���ģʽ��־�ֶ�c_lflag�ķ��ų�����

168 /* c_lflag bits */       /* c_lflag����λ */

169 #define ISIG    0000001         // ���յ��ַ�INTR��QUIT��SUSP��DSUSP��������Ӧ���źš�

170 #define ICANON  0000002         // �����淶ģʽ����ģʽ����

171 #define XCASE   0000004         // ��������ICANON�����ն��Ǵ�д�ַ��ġ�

172 #define ECHO    0000010         // ���������ַ���

173 #define ECHOE   0000020         // ��������ICANON����ERASE/WERASE������ǰһ�ַ�/���ʡ�

174 #define ECHOK   0000040         // ��������ICANON����KILL�ַ���������ǰ�С�

175 #define ECHONL  0000100         // ��������ICANON����ʹECHOû�п���Ҳ����NL�ַ���

176 #define NOFLSH  0000200         // ������SIGINT��SIGQUIT�ź�ʱ��ˢ������������У���

                                    // ����SIGSUSP�ź�ʱ��ˢ��������С�

177 #define TOSTOP  0000400         // ����SIGTTOU�źŵ���̨���̵Ľ����飬�ú�̨������ͼд

                                    // �Լ��Ŀ����նˡ�

178 #define ECHOCTL 0001000         // ��������ECHO�����TAB��NL��START��STOP�����ASCII

                                    // �����źŽ������Գ���^Xʽ����Xֵ�ǿ��Ʒ�+0x40��

179 #define ECHOPRT 0002000         // ��������ICANON��IECHO�����ַ��ڲ���ʱ����ʾ��

180 #define ECHOKE  0004000         // ��������ICANON����KILLͨ���������ϵ������ַ������ԡ�

181 #define FLUSHO  0010000         // �����ˢ�¡�ͨ������DISCARD�ַ����ñ�־����ת��

182 #define PENDIN  0040000         // ����һ���ַ��Ƕ�ʱ����������е������ַ��������ԡ�

183 #define IEXTEN  0100000         // ����ʵ��ʱ��������봦����

184

185 /* modem lines */    /* modem��·�źŷ��ų��� */

186 #define TIOCM_LE        0x001       // ��·����(Line Enable)��

187 #define TIOCM_DTR       0x002       // �����ն˾���(Data Terminal Ready)��

188 #define TIOCM_RTS       0x004       // ������(Request to Send)��

189 #define TIOCM_ST        0x008       // �������ݷ���(Serial Transfer)��[??]

190 #define TIOCM_SR        0x010       // �������ݽ���(Serial Receive)��[??]

191 #define TIOCM_CTS       0x020       // �������(Clear To Send)��

192 #define TIOCM_CAR       0x040       // �ز����(Carrier Detect)��

193 #define TIOCM_RNG       0x080       // ����ָʾ(Ring indicate)��

194 #define TIOCM_DSR       0x100       // �����豸����(Data Set Ready)��

195 #define TIOCM_CD        TIOCM_CAR

196 #define TIOCM_RI        TIOCM_RNG

197

198 /* tcflow() and TCXONC use these */   /* tcflow()��TCXONCʹ����Щ���ų��� */

199 #define TCOOFF          0          // �����������"Terminal Control Output OFF"����д����

200 #define TCOON           1          // ����������������

201 #define TCIOFF          2          // ϵͳ����һ��STOP�ַ���ʹ�豸ֹͣ��ϵͳ�������ݡ�

202 #define TCION           3          // ϵͳ����һ��START�ַ���ʹ�豸��ʼ��ϵͳ�������ݡ�

203

204 /* tcflush() and TCFLSH use these */  /* tcflush()��TCFLSHʹ����Щ���ų��� */

205 #define TCIFLUSH        0          // ����յ������ݵ�������

206 #define TCOFLUSH        1          // ����д�����ݵ������͡�

207 #define TCIOFLUSH       2          // ����յ������ݵ�����������д�����ݵ������͡�

208

209 /* tcsetattr uses these */            /* tcsetattr()ʹ����Щ���ų��� */

210 #define TCSANOW         0          // �ı�����������

211 #define TCSADRAIN       1          // �ı���������д�����������֮������

212 #define TCSAFLUSH       2          // �ı���������д�����������֮���������н��յ���

                                       // ��û�ж�ȡ�����ݱ�����֮������

213

    // ������Щ�����ڱ��뻷���ĺ�����libc.a��ʵ�֣��ں���û�С��ں�����ʵ���У���Щ����ͨ��

    // ����ϵͳ����ioctl()��ʵ�֡��й�ioctl()ϵͳ���ã���μ�fs/ioctl.c����

    // ����termios_p��ָtermios�ṹ�еĽ��ղ����ʡ�

214 extern speed_t cfgetispeed(struct termios *termios_p);

    // ����termios_p��ָtermios�ṹ�еķ��Ͳ����ʡ�

215 extern speed_t cfgetospeed(struct termios *termios_p);

    // ��termios_p��ָtermios�ṹ�еĽ��ղ���������Ϊspeed��

216 extern int cfsetispeed(struct termios *termios_p, speed_t speed);

    // ��termios_p��ָtermios�ṹ�еķ��Ͳ���������Ϊspeed��

217 extern int cfsetospeed(struct termios *termios_p, speed_t speed);

    // �ȴ�fildes��ָ������д������ݱ����ͳ�ȥ��

218 extern int tcdrain(int fildes);

    // ����/����fildes��ָ�������ݵĽ��պͷ��͡�

219 extern int tcflow(int fildes, int action);

    // ����fildesָ������������д����û�����Լ��������յ�����û�ж�ȡ�����ݡ�

220 extern int tcflush(int fildes, int queue_selector);

    // ��ȡ����fildes��Ӧ����IJ����������䱣����termios_p��ָ�ĵط���

221 extern int tcgetattr(int fildes, struct termios *termios_p);

    // ����ն�ʹ���첽�������ݴ��䣬����һ��ʱ������������һϵ��0ֵ����λ��

222 extern int tcsendbreak(int fildes, int duration);

    // ʹ��termios�ṹָ��termios_p��ָ�����ݣ��������ն���صIJ�����

223 extern int tcsetattr(int fildes, int optional_actions,

224         struct termios *termios_p);

225

226 #endif

227


 


 

14.11 ����14-11 linux/include/time.h


  1 #ifndef _TIME_H

  2 #define _TIME_H

  3

  4 #ifndef _TIME_T

  5 #define _TIME_T

  6 typedef long time_t;               // ��GMT 1970��1��1����ҹ0ʱ��ʼ�Ƶ�ʱ�䣨�룩��

  7 #endif

  8

  9 #ifndef _SIZE_T

 10 #define _SIZE_T

 11 typedef unsigned int size_t;

 12 #endif

 13

 14 #ifndef NULL

 15 #define NULL ((void *) 0)

 16 #endif

 17

 18 #define CLOCKS_PER_SEC 100         // ϵͳʱ�ӵδ�Ƶ�ʣ�100HZ��

 19

 20 typedef long clock_t;              // �ӽ��̿�ʼִ�м����ϵͳ������ʱ�ӵδ�����

 21

 22 struct tm {

 23         int tm_sec;                // ���� [0��59]��

 24         int tm_min;                // ������ [ 0��59]��

 25         int tm_hour;               // Сʱ�� [0��59]��

 26         int tm_mday;               // 1���µ����� [0��31]��

 27         int tm_mon;                // 1�����·� [0��11]��

 28         int tm_year;               // ��1900�꿪ʼ��������

 29         int tm_wday;               // 1�����е�ij�� [0��6]�������� =0����

 30         int tm_yday;               // 1���е�ij�� [0��365]��

 31         int tm_isdst;              // ����ʱ��־������ - ʹ�ã�0 - û��ʹ�ã����� - ��Ч��

 32 };

 33

    // �ж��Ƿ�Ϊ����ĺꡣ

 34 #define __isleap(year)  \

 35   ((year) % 4 == 0 && ((year) % 100 != 0 || (year) % 1000 == 0))

 36  

    // �������й�ʱ������ĺ���ԭ�͡�

    // ȷ��������ʹ��ʱ�䡣���س������ô�����ʱ�䣨�δ������Ľ���ֵ��

 37 clock_t clock(void);

    // ȡʱ�䣨�����������ش�1970.1.1:0:0:0��ʼ����������Ϊ����ʱ�䣩��

 38 time_t time(time_t * tp);

    // ����ʱ������ʱ��time2��time1֮�侭����������

 39 double difftime(time_t time2, time_t time1);

    // ��tm�ṹ��ʾ��ʱ��ת��������ʱ�䡣

 40 time_t mktime(struct tm * tp);

 41

    // ��tm�ṹ��ʾ��ʱ��ת����һ���ַ���������ָ��ô���ָ�롣

 42 char * asctime(const struct tm * tp);

    // ������ʱ��ת����һ���ַ�����ʽ���硰Wed Jun 30 21:49:08:1993\n����

 43 char * ctime(const time_t * tp);

    // ������ʱ��ת����tm�ṹ��ʾ��UTCʱ�䣨UTC - ����ʱ�����Universal Time Code����

 44 struct tm * gmtime(const time_t *tp);

    // ������ʱ��ת����tm�ṹ��ʾ��ָ��ʱ��(Time Zone)��ʱ�䡣

 45 struct tm *localtime(const time_t * tp);

    // ��tm�ṹ��ʾ��ʱ�����ø�ʽ�ַ���fmtת������󳤶�Ϊsmax���ַ�����������洢��s�С�

 46 size_t strftime(char * s, size_t smax, const char * fmt, const struct tm * tp);

    // ��ʼ��ʱ��ת����Ϣ��ʹ�û�������TZ����zname�������г�ʼ����

    // ����ʱ����ص�ʱ��ת�������н��Զ����øú�����

 47 void tzset(void);

 48

 49 #endif

 50


 

 


 

14.12 ����14-12 linux/include/unistd.h


  1 #ifndef _UNISTD_H

  2 #define _UNISTD_H

  3

  4 /* ok, this may be a joke, but I'm working on it */

    /* ok, ��Ҳ���Ǹ���Ц�������������ִ��� */

    // ������ų���ָ������IEEE��׼1003.1ʵ�ֵİ汾�ţ���һ������ֵ��

  5 #define _POSIX_VERSION 198808L

  6

    // chown()��fchown()��ʹ�������ڽ��̵�Ȩ�ޡ�/* ֻ�г����û�����ִ��chown������..��*/

  7 #define _POSIX_CHOWN_RESTRICTED /* only root can do a chown (I think..) */

    // ����(NAME_MAX)��·�������������󣬶������Զ��ضϡ�/* ·�������ضϣ������뿴�ں˴��룩*/

  8 #define _POSIX_NO_TRUNC         /* no pathname truncation (but see in kernel) */

    // ����������Ž�������ַ�ֵ����ֵ����ֹ�ն˶���Ĵ�����/* ��ֹ��^C�������ַ� */

    // _POSIX_VDISABLE���ڿ����ն�ijЩ�����ַ��Ĺ��ܡ���һ���ն�termios�ṹ��c_cc[]

    // ����ij���ַ�����ֵ����_POSIX_VDISABLE��ֵʱ����ʾ��ֹʹ����Ӧ�������ַ���

  9 #define _POSIX_VDISABLE '\0'    /* character to disable things like ^C */

    // ϵͳʵ��֧����ҵ���ơ�

 10 #define _POSIX_JOB_CONTROL

    // ÿ�����̶���һ�����set-user-ID��һ�����set-group-ID�� /* �Ѿ�ʵ�֡� */

 11 #define _POSIX_SAVED_IDS        /* Implemented, for whatever good it is */

 12

 13 #define STDIN_FILENO    0            // ��׼�����ļ���������������š�

 14 #define STDOUT_FILENO   1            // ��׼����ļ�����š�

 15 #define STDERR_FILENO   2            // ��׼�����ļ�����š�

 16

 17 #ifndef NULL

 18 #define NULL    ((void *)0)          // �����ָ�롣

 19 #endif

 20

 21 /* access */   /* �ļ����� */

    // ���¶���ķ��ų�������access()������

 22 #define F_OK    0                    // ����ļ��Ƿ���ڡ�

 23 #define X_OK    1                    // ����Ƿ��ִ�У���������

 24 #define W_OK    2                    // ����Ƿ��д��

 25 #define R_OK    4                    // ����Ƿ�ɶ���

 26

 27 /* lseek */   /* �ļ�ָ���ض�λ */

    // ���·��ų�������lseek()��fcntl()������

 28 #define SEEK_SET        0            // ���ļ���дָ������Ϊƫ��ֵ��

 29 #define SEEK_CUR        1            // ���ļ���дָ������Ϊ��ǰֵ����ƫ��ֵ��

 30 #define SEEK_END        2            // ���ļ���дָ������Ϊ�ļ����ȼ���ƫ��ֵ��

 31

 32 /* _SC stands for System Configuration. We don't use them much */

    /* _SC��ʾϵͳ���á����Ǻ���ʹ�� */

    // ����ķ��ų�������sysconf()������

 33 #define _SC_ARG_MAX             1    // ����������

 34 #define _SC_CHILD_MAX           2    // �ӽ����������

 35 #define _SC_CLOCKS_PER_SEC      3    // ÿ��δ�����

 36 #define _SC_NGROUPS_MAX         4    // ���������

 37 #define _SC_OPEN_MAX            5    // �����ļ�����

 38 #define _SC_JOB_CONTROL         6    // ��ҵ���ơ�

 39 #define _SC_SAVED_IDS           7    // ����ı�ʶ����

 40 #define _SC_VERSION             8    // �汾��

 41

 42 /* more (possibly) configurable things - now pathnames */

    /* ����ģ����ܵģ������ò��� - ��������·���� */

    // ����ķ��ų�������pathconf()������

 43 #define _PC_LINK_MAX            1    // �����������

 44 #define _PC_MAX_CANON           2    // ��󳣹��ļ�����

 45 #define _PC_MAX_INPUT           3    // ������볤�ȡ�

 46 #define _PC_NAME_MAX            4    // ������󳤶ȡ�

 47 #define _PC_PATH_MAX            5    // ·����󳤶ȡ�

 48 #define _PC_PIPE_BUF            6    // �ܵ������С��

 49 #define _PC_NO_TRUNC            7    // �ļ������ضϡ�

 50 #define _PC_VDISABLE            8    //

 51 #define _PC_CHOWN_RESTRICTED    9    // �ı��������ޡ�

 52

 53 #include <sys/stat.h>     // �ļ�״̬ͷ�ļ��������ļ����ļ�ϵͳ״̬�ṹstat{}�ͳ�����

 54 #include <sys/time.h>

 55 #include <sys/times.h>    // �����˽���������ʱ��ṹtms�Լ�times()����ԭ�͡�

 56 #include <sys/utsname.h>  // ϵͳ���ƽṹͷ�ļ���

 57 #include <sys/resource.h>

 58 #include <utime.h>        // �û�ʱ��ͷ�ļ��������˷��ʺ��޸�ʱ��ṹ�Լ�utime()ԭ�͡�

 59

 60 #ifdef __LIBRARY__

 61

    // ������ʵ�ֵ�ϵͳ���÷��ų���������ϵͳ���ú�����������ֵ(�μ�include/linux/sys.h) ��

 62 #define __NR_setup      0       /* used only by init, to get system going */

 63 #define __NR_exit       1       /* __NR_setup�����ڳ�ʼ����������ϵͳ */

 64 #define __NR_fork       2

 65 #define __NR_read       3

 66 #define __NR_write      4

 67 #define __NR_open       5

 68 #define __NR_close      6

 69 #define __NR_waitpid    7

 70 #define __NR_creat      8

 71 #define __NR_link       9

 72 #define __NR_unlink     10

 73 #define __NR_execve     11

 74 #define __NR_chdir      12

 75 #define __NR_time       13

 76 #define __NR_mknod      14

 77 #define __NR_chmod      15

 78 #define __NR_chown      16

 79 #define __NR_break      17

 80 #define __NR_stat       18

 81 #define __NR_lseek      19

 82 #define __NR_getpid     20

 83 #define __NR_mount      21

 84 #define __NR_umount     22

 85 #define __NR_setuid     23

 86 #define __NR_getuid     24

 87 #define __NR_stime      25

 88 #define __NR_ptrace     26

 89 #define __NR_alarm      27

 90 #define __NR_fstat      28

 91 #define __NR_pause      29

 92 #define __NR_utime      30

 93 #define __NR_stty       31

 94 #define __NR_gtty       32

 95 #define __NR_access     33

 96 #define __NR_nice       34

 97 #define __NR_ftime      35

 98 #define __NR_sync       36

 99 #define __NR_kill       37

100 #define __NR_rename     38

101 #define __NR_mkdir      39

102 #define __NR_rmdir      40

103 #define __NR_dup        41

104 #define __NR_pipe       42

105 #define __NR_times      43

106 #define __NR_prof       44

107 #define __NR_brk        45

108 #define __NR_setgid     46

109 #define __NR_getgid     47

110 #define __NR_signal     48

111 #define __NR_geteuid    49

112 #define __NR_getegid    50

113 #define __NR_acct       51

114 #define __NR_phys       52

115 #define __NR_lock       53

116 #define __NR_ioctl      54

117 #define __NR_fcntl      55

118 #define __NR_mpx        56

119 #define __NR_setpgid    57

120 #define __NR_ulimit     58

121 #define __NR_uname      59

122 #define __NR_umask      60

123 #define __NR_chroot     61

124 #define __NR_ustat      62

125 #define __NR_dup2       63

126 #define __NR_getppid    64

127 #define __NR_getpgrp    65

128 #define __NR_setsid     66

129 #define __NR_sigaction  67

130 #define __NR_sgetmask   68

131 #define __NR_ssetmask   69

132 #define __NR_setreuid   70

133 #define __NR_setregid   71

134 #define __NR_sigsuspend 72

135 #define __NR_sigpending 73

136 #define __NR_sethostname 74

137 #define __NR_setrlimit  75

138 #define __NR_getrlimit  76

139 #define __NR_getrusage  77

140 #define __NR_gettimeofday 78

141 #define __NR_settimeofday 79

142 #define __NR_getgroups  80

143 #define __NR_setgroups  81

144 #define __NR_select     82

145 #define __NR_symlink    83

146 #define __NR_lstat      84

147 #define __NR_readlink   85

148 #define __NR_uselib     86

149

    // ���¶���ϵͳ����Ƕ��ʽ���꺯����

    // ����������ϵͳ���ú꺯����type name(void)��

    // %0 - eax(__res)��%1 - eax(__NR_##name)������name��ϵͳ���õ����ƣ��� __NR_ ����γ�����

    // ��ϵͳ���÷��ų������Ӷ�������ϵͳ���ñ��к���ָ��Ѱַ��

    // ���أ��������ֵ���ڵ���0���򷵻ظ�ֵ�������ó�����errno��������-1��

    // �ں궨���У�����������Ƿ���֮�������������ľ���'##'�����ʾ�ں��滻ʱ������������

    // ����������һ�����������139���ϵ�__NR_##name�����滻�˲���name��������fork��֮��

    // ����ڳ����г��ֵĽ����Ƿ���__NR_fork���μ���The C Programming Language����¼A.12.3��

150 #define _syscall0(type,name) \

151 type name(void) \

152 { \

153 long __res; \

154 __asm__ volatile ("int $0x80" \          // ����ϵͳ�ж�0x80��

155         : "=a" (__res) \                 // ����ֵ��eax(__res)��

156         : "0" (__NR_##name)); \          // ����Ϊϵͳ�жϵ��ú�__NR_name��

157 if (__res >= 0) \                        // �������ֵ>=0����ֱ�ӷ��ظ�ֵ��

158         return (type) __res; \

159 errno = -__res; \                        // �����ó����ţ�������-1��

160 return -1; \

161 }

162

    // ��1��������ϵͳ���ú꺯����type name(atype a)

    // %0 - eax(__res)��%1 - eax(__NR_name)��%2 - ebx(a)��

163 #define _syscall1(type,name,atype,a) \

164 type name(atype a) \

165 { \

166 long __res; \

167 __asm__ volatile ("int $0x80" \

168         : "=a" (__res) \

169         : "0" (__NR_##name),"b" ((long)(a))); \

170 if (__res >= 0) \

171         return (type) __res; \

172 errno = -__res; \

173 return -1; \

174 }

175

    // ��2��������ϵͳ���ú꺯����type name(atype a, btype b)

    // %0 - eax(__res)��%1 - eax(__NR_name)��%2 - ebx(a)��%3 - ecx(b)��

176 #define _syscall2(type,name,atype,a,btype,b) \

177 type name(atype a,btype b) \

178 { \

179 long __res; \

180 __asm__ volatile ("int $0x80" \

181         : "=a" (__res) \

182         : "0" (__NR_##name),"b" ((long)(a)),"c" ((long)(b))); \

183 if (__res >= 0) \

184         return (type) __res; \

185 errno = -__res; \

186 return -1; \

187 }

188

    // ��3��������ϵͳ���ú꺯����type name(atype a, btype b, ctype c)

    // %0 - eax(__res)��%1 - eax(__NR_name)��%2 - ebx(a)��%3 - ecx(b)��%4 - edx(c)��

189 #define _syscall3(type,name,atype,a,btype,b,ctype,c) \

190 type name(atype a,btype b,ctype c) \

191 { \

192 long __res; \

193 __asm__ volatile ("int $0x80" \

194         : "=a" (__res) \

195         : "0" (__NR_##name),"b" ((long)(a)),"c" ((long)(b)),"d" ((long)(c))); \

196 if (__res>=0) \

197         return (type) __res; \

198 errno=-__res; \

199 return -1; \

200 }

201

202 #endif /* __LIBRARY__ */

203

204 extern int errno;                      // �����ţ�ȫ�ֱ�����

205

    // ��Ӧ��ϵͳ���õĺ���ԭ�Ͷ��塣(��ϸ˵���μ�include/linux/sys.h )

206 int access(const char * filename, mode_t mode);

207 int acct(const char * filename);

208 int alarm(int sec);

209 int brk(void * end_data_segment);

210 void * sbrk(ptrdiff_t increment);

211 int chdir(const char * filename);

212 int chmod(const char * filename, mode_t mode);

213 int chown(const char * filename, uid_t owner, gid_t group);

214 int chroot(const char * filename);

215 int close(int fildes);

216 int creat(const char * filename, mode_t mode);

217 int dup(int fildes);

218 int execve(const char * filename, char ** argv, char ** envp);

219 int execv(const char * pathname, char ** argv);

220 int execvp(const char * file, char ** argv);

221 int execl(const char * pathname, char * arg0, ...);

222 int execlp(const char * file, char * arg0, ...);

223 int execle(const char * pathname, char * arg0, ...);

    // ������ǰ�Ĺؼ���volatile���ڸ��߱�����gcc�ú������᷵�ء���������gcc��������һ

    // Щ�Ĵ��룬����Ҫ����ʹ������ؼ��ֿ��Ա������ijЩ��δ��ʼ�������ģ��پ�����Ϣ��

    // ��ͬ��gcc�ĺ�������˵����void do_exit(int error_code) __attribute__ ((noreturn));

224 volatile void exit(int status);

225 volatile void _exit(int status);

226 int fcntl(int fildes, int cmd, ...);

227 int fork(void);

228 int getpid(void);

229 int getuid(void);

230 int geteuid(void);

231 int getgid(void);

232 int getegid(void);

233 int ioctl(int fildes, int cmd, ...);

234 int kill(pid_t pid, int signal);

235 int link(const char * filename1, const char * filename2);

236 int lseek(int fildes, off_t offset, int origin);

237 int mknod(const char * filename, mode_t mode, dev_t dev);

238 int mount(const char * specialfile, const char * dir, int rwflag);

239 int nice(int val);

240 int open(const char * filename, int flag, ...);

241 int pause(void);

242 int pipe(int * fildes);

243 int read(int fildes, char * buf, off_t count);

244 int setpgrp(void);

245 int setpgid(pid_t pid,pid_t pgid);

246 int setuid(uid_t uid);

247 int setgid(gid_t gid);

248 void (*signal(int sig, void (*fn)(int)))(int);

249 int stat(const char * filename, struct stat * stat_buf);

250 int fstat(int fildes, struct stat * stat_buf);

251 int stime(time_t * tptr);

252 int sync(void);

253 time_t time(time_t * tloc);

254 time_t times(struct tms * tbuf);

255 int ulimit(int cmd, long limit);

256 mode_t umask(mode_t mask);

257 int umount(const char * specialfile);

258 int uname(struct utsname * name);

259 int unlink(const char * filename);

260 int ustat(dev_t dev, struct ustat * ubuf);

261 int utime(const char * filename, struct utimbuf * times);

262 pid_t waitpid(pid_t pid,int * wait_stat,int options);

263 pid_t wait(int * wait_stat);

264 int write(int fildes, const char * buf, off_t count);

265 int dup2(int oldfd, int newfd);

266 int getppid(void);

267 pid_t getpgrp(void);

268 pid_t setsid(void);

269 int sethostname(char *name, int len);

270 int setrlimit(int resource, struct rlimit *rlp);

271 int getrlimit(int resource, struct rlimit *rlp);

272 int getrusage(int who, struct rusage *rusage);

273 int gettimeofday(struct timeval *tv, struct timezone *tz);

274 int settimeofday(struct timeval *tv, struct timezone *tz);

275 int getgroups(int gidsetlen, gid_t *gidset);

276 int setgroups(int gidsetlen, gid_t *gidset);

277 int select(int width, fd_set * readfds, fd_set * writefds,

278         fd_set * exceptfds, struct timeval * timeout);

279

280 #endif

281



 

14.13 ����14-13 linux/include/utime.h


  1 #ifndef _UTIME_H

  2 #define _UTIME_H

  3

  4 #include <sys/types.h>  /* I know - shouldn't do this, but .. */

  5                         /* ��֪�� - ��Ӧ��������������.. */

  6 struct utimbuf {

  7         time_t actime;          // �ļ�����ʱ�䡣��1970.1.1:0:0:0��ʼ��������

  8         time_t modtime;         // �ļ��޸�ʱ�䡣��1970.1.1:0:0:0��ʼ��������

  9 };

 10

    // �����ļ����ʺ��޸�ʱ�亯����

 11 extern int utime(const char *filename, struct utimbuf *times);

 12

 13 #endif

 14


 


 

14.14 ����14-14 linux/include/asm/io.h


    //// Ӳ���˿��ֽ����������

    // ������value - ������ֽڣ�port - �˿ڡ�

  1 #define outb(value,port) \

  2 __asm__ ("outb %%al,%%dx"::"a" (value),"d" (port))

  3

  4

    //// Ӳ���˿��ֽ����뺯����

    // ������port - �˿ڡ����ض�ȡ���ֽڡ�

  5 #define inb(port) ({ \

  6 unsigned char _v; \

  7 __asm__ volatile ("inb %%dx,%%al":"=a" (_v):"d" (port)); \

  8 _v; \

  9 })

 10

    //// ���ӳٵ�Ӳ���˿��ֽ����������ʹ��������ת������ӳ�һ�ᡣ

    // ������value - ������ֽڣ�port - �˿ڡ�

 11 #define outb_p(value,port) \

 12 __asm__ ("outb %%al,%%dx\n" \

 13                 "\tjmp 1f\n" \               // ��ǰ��ת�����1��������һ����䴦����

 14                 "1:\tjmp 1f\n" \             // ��ǰ��ת�����1����

 15                 "1:"::"a" (value),"d" (port))

 16

    //// ���ӳٵ�Ӳ���˿��ֽ����뺯����ʹ��������ת������ӳ�һ�ᡣ

    // ������port - �˿ڡ����ض�ȡ���ֽڡ�

 17 #define inb_p(port) ({ \

 18 unsigned char _v; \

 19 __asm__ volatile ("inb %%dx,%%al\n" \

 20         "\tjmp 1f\n" \                       // ��ǰ��ת�����1��������һ����䴦����

 21         "1:\tjmp 1f\n" \                     // ��ǰ��ת�����1����

 22         "1:":"=a" (_v):"d" (port)); \

 23 _v; \

 24 })

 25


 


 

14.15 ����14-15 linux/include/asm/memory.h


  1 /*

  2  *  NOTE!!! memcpy(dest,src,n) assumes ds=es=normal data segment. This

  3  *  goes for all kernel functions (ds=es=kernel space, fs=local data,

  4  *  gs=null), as well as for all well-behaving user programs (ds=es=

  5  *  user data space). This is NOT a bug, as any user program that changes

  6  *  es deserves to die if it isn't careful.

  7  */

    /*

     * ע��!!!memcpy(dest,src,n)����μĴ���ds=es=ͨ�����ݶΡ����ں���ʹ�õ�

     * ���к��������ڸü��裨ds=es=�ں˿ռ䣬fs=�ֲ����ݿռ䣬gs=null��,��������

     * ��Ϊ��Ӧ�ó���Ҳ��������ds=es=�û����ݿռ䣩������κ��û���������Ķ���

     * es�Ĵ������������򲢲�������ϵͳ���������ɵġ�

     */

    //// �ڴ�鸴�ơ���Դ��ַsrc����ʼ����n���ֽڵ�Ŀ�ĵ�ַdest����

    // ������dest - ���Ƶ�Ŀ�ĵ�ַ��src - ���Ƶ�Դ��ַ��n - �����ֽ�����

    // %0 - edi(Ŀ�ĵ�ַdest)��%1 - esi(Դ��ַsrc)��%2 - ecx(�ֽ���n)��

  8 #define memcpy(dest,src,n) ({ \

  9 void * _res = dest; \

 10 __asm__ ("cld;rep;movsb" \                // ��ds:[esi]���Ƶ�es:[edi]������esi++��edi++��

                                              // ������ecx(n)�ֽڡ�

 11         ::"D" ((long)(_res)),"S" ((long)(src)),"c" ((long) (n)) \

 12         :"di","si","cx"); \

 13 _res; \

 14 })

 15


 


 

14.16 ����14-16 linux/include/asm/segment.h


    //// ��ȡfs����ָ����ַ�����ֽڡ�

    // ������addr - ָ�����ڴ��ַ��

    // %0 - (���ص��ֽ�_v)��%1 - (�ڴ��ַaddr)��

    // ���أ������ڴ�fs:[addr]�����ֽڡ�

    // ��3�ж�����һ���Ĵ�������_v���ñ�������������һ���Ĵ����У��Ա��ڸ�Ч���ʺͲ�����

  1 extern inline unsigned char get_fs_byte(const char * addr)

  2 {

  3         unsigned register char _v;

  4

  5         __asm__ ("movb %%fs:%1,%0":"=r" (_v):"m" (*addr));

  6         return _v;

  7 }

  8

    //// ��ȡfs����ָ����ַ�����֡�

    // ������addr - ָ�����ڴ��ַ��

    // %0 - (���ص���_v)��%1 - (�ڴ��ַaddr)��

    // ���أ������ڴ�fs:[addr]�����֡�

  9 extern inline unsigned short get_fs_word(const unsigned short *addr)

 10 {

 11         unsigned short _v;

 12

 13         __asm__ ("movw %%fs:%1,%0":"=r" (_v):"m" (*addr));

 14         return _v;

 15 }

 16

    //// ��ȡfs����ָ����ַ���ij���(4�ֽ�)��

    // ������addr - ָ�����ڴ��ַ��

    // %0 - (���صij���_v)��%1 - (�ڴ��ַaddr)��

    // ���أ������ڴ�fs:[addr]���ij��֡�

 17 extern inline unsigned long get_fs_long(const unsigned long *addr)

 18 {

 19         unsigned long _v;

 20

 21         __asm__ ("movl %%fs:%1,%0":"=r" (_v):"m" (*addr)); \

 22         return _v;

 23 }

 24

    //// ��һ�ֽڴ����fs����ָ���ڴ��ַ����

    // ������val - �ֽ�ֵ��addr - �ڴ��ַ��

    // %0 - �Ĵ���(�ֽ�ֵval)��%1 - (�ڴ��ַaddr)��

 25 extern inline void put_fs_byte(char val,char *addr)

 26 {

 27 __asm__ ("movb %0,%%fs:%1"::"r" (val),"m" (*addr));

 28 }

 29

    //// ��һ�ִ����fs����ָ���ڴ��ַ����

    // ������val - ��ֵ��addr - �ڴ��ַ��

    // %0 - �Ĵ���(��ֵval)��%1 - (�ڴ��ַaddr)��

 30 extern inline void put_fs_word(short val,short * addr)

 31 {

 32 __asm__ ("movw %0,%%fs:%1"::"r" (val),"m" (*addr));

 33 }

 34

    //// ��һ���ִ����fs����ָ���ڴ��ַ����

    // ������val - ����ֵ��addr - �ڴ��ַ��

    // %0 - �Ĵ���(����ֵval)��%1 - (�ڴ��ַaddr)��

 35 extern inline void put_fs_long(unsigned long val,unsigned long * addr)

 36 {

 37 __asm__ ("movl %0,%%fs:%1"::"r" (val),"m" (*addr));

 38 }

 39

 40 /*

 41  * Someone who knows GNU asm better than I should double check the followig.

 42  * It seems to work, but I don't know if I'm doing something subtly wrong.

 43  * --- TYT, 11/24/91

 44  * [ nothing wrong here, Linus ]

 45  */

    /*

     * ���Ҹ���GNU������Ӧ����ϸ�������Ĵ��롣��Щ������ʹ�ã����Ҳ�֪���Ƿ�

     * ����һЩС����

     * --- TYT��1991��11��24��

     * [ ��Щ����û�д���Linus ]

     */

 46

    //// ȡfs�μĴ���ֵ(ѡ���)��

    // ���أ�fs�μĴ���ֵ��

 47 extern inline unsigned long get_fs()

 48 {

 49         unsigned short _v;

 50         __asm__("mov %%fs,%%ax":"=a" (_v):);

 51         return _v;

 52 }

 53

    //// ȡds�μĴ���ֵ��

    // ���أ�ds�μĴ���ֵ��

 54 extern inline unsigned long get_ds()

 55 {

 56         unsigned short _v;

 57         __asm__("mov %%ds,%%ax":"=a" (_v):);

 58         return _v;

 59 }

 60

    //// ����fs�μĴ�����

    // ������val - ��ֵ��ѡ�������

 61 extern inline void set_fs(unsigned long val)

 62 {

 63         __asm__("mov %0,%%fs"::"a" ((unsigned short) val));

 64 }

 65

 66


 


 

14.17 ����14-17 linux/include/asm/system.h


    //// �ƶ����û�ģʽ���С�

    // �ú�������iretָ��ʵ�ִ��ں�ģʽ�ƶ�����ʼ����0��ȥִ�С�

  1 #define move_to_user_mode() \

  2 __asm__ ("movl %%esp,%%eax\n\t" \      // �����ջָ��esp��eax�Ĵ����С�

  3         "pushl $0x17\n\t" \            // ���Ƚ���ջ��ѡ���(SS)��ջ��

  4         "pushl %%eax\n\t" \            // Ȼ�󽫱���Ķ�ջָ��ֵ(esp)��ջ��

  5         "pushfl\n\t" \                 // ����־�Ĵ���(eflags)������ջ��

  6         "pushl $0x0f\n\t" \            // ��Task0�����ѡ���(cs)��ջ��

  7         "pushl $1f\n\t" \              // ��������1��ƫ�Ƶ�ַ(eip)��ջ��

  8         "iret\n" \                     // ִ���жϷ���ָ������ת��������1����

  9         "1:\tmovl $0x17,%%eax\n\t" \   // ��ʱ��ʼִ������0��

 10         "movw %%ax,%%ds\n\t" \         // ��ʼ���μĴ���ָ�򱾾ֲ��������ݶΡ�

 11         "movw %%ax,%%es\n\t" \

 12         "movw %%ax,%%fs\n\t" \

 13         "movw %%ax,%%gs" \

 14         :::"ax")

 15

 16 #define sti() __asm__ ("sti"::)        // ���ж�Ƕ����꺯����

 17 #define cli() __asm__ ("cli"::)        // ���жϡ�

 18 #define nop() __asm__ ("nop"::)        // �ղ�����

 19

 20 #define iret() __asm__ ("iret"::)      // �жϷ��ء�

 21

    //// �������������ꡣ

    // ���ݲ����е��жϻ��쳣�������̵�ַaddr��������������type����Ȩ����Ϣdpl������λ��

    // ��ַgate_addr����������������ע�⣺���桰ƫ�ơ�ֵ��������ں˴�������ݶ���˵�ģ���

    // ������gate_addr -��������ַ��type -������������ֵ��dpl -��������Ȩ����addr -ƫ�Ƶ�ַ��

    // %0 - (��dpl,type��ϳɵ����ͱ�־��)��%1 - (��������4�ֽڵ�ַ)��

    // %2 - (��������4�ֽڵ�ַ)��%3 - edx(����ƫ�Ƶ�ַaddr)��%4 - eax(�����к��ж�ѡ���0x8)��

 22 #define _set_gate(gate_addr,type,dpl,addr) \

 23 __asm__ ("movw %%dx,%%ax\n\t" \        // ��ƫ�Ƶ�ַ������ѡ�����ϳ���������4�ֽ�(eax)��

 24         "movw %0,%%dx\n\t" \           // �����ͱ�־����ƫ�Ƹ�����ϳ���������4�ֽ�(edx)��

 25         "movl %%eax,%1\n\t" \          // �ֱ��������������ĵ�4�ֽں͸�4�ֽڡ�

 26         "movl %%edx,%2" \

 27         : \

 28         : "i" ((short) (0x8000+(dpl<<13)+(type<<8))), \

 29         "o" (*((char *) (gate_addr))), \

 30         "o" (*(4+(char *) (gate_addr))), \

 31         "d" ((char *) (addr)),"a" (0x00080000))

 32

    //// �����ж��ź������Զ����������жϣ���

    // ������n - �жϺţ�addr - �жϳ���ƫ�Ƶ�ַ��

    // &idt[n]���ж������������жϺ�n��Ӧ���ƫ��ֵ���ж���������������14����Ȩ����0��

 33 #define set_intr_gate(n,addr) \

 34         _set_gate(&idt[n],14,0,addr)

 35

    //// ���������ź�����

    // ������n - �жϺţ�addr - �жϳ���ƫ�Ƶ�ַ��

    // &idt[n]���ж������������жϺ�n��Ӧ���ƫ��ֵ���ж���������������15����Ȩ����0��

 36 #define set_trap_gate(n,addr) \

 37         _set_gate(&idt[n],15,0,addr)

 38

    //// ����ϵͳ�����ź�����

    // ����set_trap_gate()���õ�����������Ȩ��Ϊ0����������3�����set_system_gate()���õ�

    // �жϴ��������ܹ������г���ִ�С����絥�����ԡ���������ͱ߽糬������������

    // ������n - �жϺţ�addr - �жϳ���ƫ�Ƶ�ַ��

    // &idt[n]���ж������������жϺ�n��Ӧ���ƫ��ֵ���ж���������������15����Ȩ����3��

 39 #define set_system_gate(n,addr) \

 40         _set_gate(&idt[n],15,3,addr)

 41

    //// ���ö��������������ں���û���õ�����

    // ������gate_addr -��������ַ��type -��������������ֵ��dpl -��������Ȩ��ֵ��

    // base - �εĻ���ַ��limit - ���޳���

    // ��μ����������ĸ�ʽ��ע�⣬���︳ֵ����Ū���ˡ�43��Ӧ���� *((gate_addr)+1)����

    // 49�в��� *(gate_addr)�������ں˴�����û���õ�����꣬����Linusû�в�� :-)

 42 #define _set_seg_desc(gate_addr,type,dpl,base,limit) {\

 43         *(gate_addr) = ((base) & 0xff000000) | \             // ��������4�ֽڡ�

 44                 (((base) & 0x00ff0000)>>16) | \

 45                 ((limit) & 0xf0000) | \

 46                 ((dpl)<<13) | \

 47                 (0x00408000) | \

 48                 ((type)<<8); \

 49         *((gate_addr)+1) = (((base) & 0x0000ffff)<<16) | \   // ��������4�ֽڡ�

 50                 ((limit) & 0x0ffff); }

 51

    //// ��ȫ�ֱ�����������״̬��/�ֲ�����������״̬�κ;ֲ����εij��Ⱦ������ó�104�ֽڡ�

    // ������n - ��ȫ�ֱ�����������n����Ӧ�ĵ�ַ��addr - ״̬��/�ֲ��������ڴ�Ļ���ַ��

    //       type - �������еı�־�����ֽڡ�

    // %0 - eax(��ַaddr)��%1 - (��������n�ĵ�ַ)��%2 - (��������n�ĵ�ַƫ��2��)��

    // %3 - (��������n�ĵ�ַƫ��4��)��%4 - (��������n�ĵ�ַƫ��5��)��

    // %5 - (��������n�ĵ�ַƫ��6��)��%6 - (��������n�ĵ�ַƫ��7��)��

 52 #define _set_tssldt_desc(n,addr,type) \

 53 __asm__ ("movw $104,%1\n\t" \          // ��TSS����LDT�����ȷ���������������(��0-1�ֽ�)��

 54         "movw %%ax,%2\n\t" \           // ������ַ�ĵ��ַ�����������2-3�ֽڡ�

 55         "rorl $16,%%eax\n\t" \         // ������ַ������ѭ������ax�У������������ִ�����

 56         "movb %%al,%3\n\t" \           // ������ַ�����е��ֽ�������������4�ֽڡ�

 57         "movb $" type ",%4\n\t" \      // ����־�����ֽ������������ĵ�5�ֽڡ�

 58         "movb $0x00,%5\n\t" \          // �������ĵ�6�ֽ���0��

 59         "movb %%ah,%6\n\t" \           // ������ַ�����и��ֽ�������������7�ֽڡ�

 60         "rorl $16,%%eax" \             // ����ѭ��16���أ�eax�ָ�ԭֵ��

 61         ::"a" (addr), "m" (*(n)), "m" (*(n+2)), "m" (*(n+4)), \

 62          "m" (*(n+5)), "m" (*(n+6)), "m" (*(n+7)) \

 63         )

 64

    //// ��ȫ�ֱ�����������״̬����������

    // n - �Ǹ���������ָ�룻addr - �����������жεĻ���ֵַ������״̬����������������0x89��

 65 #define set_tss_desc(n,addr) _set_tssldt_desc(((char *) (n)),addr,"0x89")

    //// ��ȫ�ֱ������þֲ�����������

    // n - �Ǹ���������ָ�룻addr - �����������жεĻ���ֵַ���ֲ�������������������0x82��

 66 #define set_ldt_desc(n,addr) _set_tssldt_desc(((char *) (n)),addr,"0x82")

 67



 

14.18 ����14-18 linux/include/linux/config.h


  1 #ifndef _CONFIG_H

  2 #define _CONFIG_H

  3

  4 /*

  5  * Defines for what uname() should return

  6  */

    /*

     * ����uname()����Ӧ�÷��ص�ֵ��

     */

  7 #define UTS_SYSNAME "Linux"

  8 #define UTS_NODENAME "(none)"   /* set by sethostname() */

  9 #define UTS_RELEASE ""          /* patchlevel */

 10 #define UTS_VERSION "0.12"

 11 #define UTS_MACHINE "i386"      /* hardware type */

 12

 13 /* Don't touch these, unless you really know what your doing. */

    /* �벻Ҫ�����޸����涨��ֵ��������֪���Լ����ڸ�ʲô�� */

 14 #define DEF_INITSEG     0x9000        // �����������򽫱��ƶ����Ķ�ֵ��

 15 #define DEF_SYSSEG      0x1000        // �������������ϵͳģ����ص��ڴ�Ķ�ֵ��

 16 #define DEF_SETUPSEG    0x9020        // setup���������ڴ��λ�á�

 17 #define DEF_SYSSIZE     0x3000        // �ں�ϵͳģ��Ĭ����������16�ֽ�=1�ڣ���

 18

 19 /*

 20  * The root-device is no longer hard-coded. You can change the default

 21  * root-device by changing the line ROOT_DEV = XXX in boot/bootsect.s

 22  */

    /*

     * ���ļ�ϵͳ�豸�Ѳ�����Ӳ������ˡ�ͨ���޸�boot/bootsect.s�ļ�����

     * ROOT_DEV = XXX������Ըı���豸��Ĭ������ֵ��

     */

 23

 24 /*

 25  * The keyboard is now defined in kernel/chr_dev/keyboard.S

 26  */

    /*

     * ���ڼ������ͱ�����kernel/chr_dev/keyboard.S�����ж��塣

     */

 27

 28 /*

 29  * Normally, Linux can get the drive parameters from the BIOS at

 30  * startup, but if this for some unfathomable reason fails, you'd

 31  * be left stranded. For this case, you can define HD_TYPE, which

 32  * contains all necessary info on your harddisk.

 33  *

 34  * The HD_TYPE macro should look like this:

 35  *

 36  * #define HD_TYPE { head, sect, cyl, wpcom, lzone, ctl}

 37  *

 38  * In case of two harddisks, the info should be sepatated by

 39  * commas:

 40  *

 41  * #define HD_TYPE { h,s,c,wpcom,lz,ctl },{ h,s,c,wpcom,lz,ctl }

 42  */

    /*

     * ͨ����Linux�ܹ�������ʱ��BIOS�л�ȡ�������²���������������δ֪ԭ��

     * ��û�еõ���Щ����ʱ����ʹ���������޲ߡ������������������Զ���HD_TYPE��

     * ���а���Ӳ�̵�������Ϣ��

     *

     * HD_TYPE��Ӧ����������������ʽ��

     *

     * #define HD_TYPE { head, sect, cyl, wpcom, lzone, ctl}

     *

     * ����������Ӳ�̵������������Ϣ���ö��ŷֿ���

     *

     * #define HD_TYPE { h,s,c,wpcom,lz,ctl }, {h,s,c,wpcom,lz,ctl }

     */

 43 /*

 44  This is an example, two drives, first is type 2, second is type 3:

 45

 46 #define HD_TYPE { 4,17,615,300,615,8 }, { 6,17,615,300,615,0 }

 47

 48  NOTE: ctl is 0 for all drives with heads<=8, and ctl=8 for drives

 49  with more than 8 heads.

 50

 51  If you want the BIOS to tell what kind of drive you have, just

 52  leave HD_TYPE undefined. This is the normal thing to do.

 53 */

    /*

     * ������һ�����ӣ�����Ӳ�̣���1��������2����2��������3��

     *

     * #define HD_TYPE { 4,17,615,300,615,8 }, {6,17,615,300,615,0 }

     *

     * ע�⣺��Ӧ����Ӳ�̣������ͷ��<=8����ctl����0������ͷ������8����

     * ��ctl=8��

     *

     * ���������BIOS����Ӳ�̵����ͣ���ôֻ�費����HD_TYPE������Ĭ�ϲ�����

     */

 54

 55 #endif

 56


 


 

14.19 ����14-19 linux/include/linux/fdreg.h


  1 /*

  2  * This file contains some defines for the floppy disk controller.

  3  * Various sources. Mostly "IBM Microcomputers: A Programmers

  4  * Handbook", Sanches and Canton.

  5  */

    /*

     * ���ļ��к���һЩ���̿�������һЩ���塣��Щ��Ϣ�жദ��Դ�������ȡ��Sanches��Canton

     * ������"IBM΢�ͼ����������Ա�ֲ�"һ�顣

     */

  6 #ifndef _FDREG_H    // �ö��������ų��������ظ�������ͷ�ļ���

  7 #define _FDREG_H

  8

    // һЩ�������ͺ�����ԭ��˵����

  9 extern int ticks_to_floppy_on(unsigned int nr);

 10 extern void floppy_on(unsigned int nr);

 11 extern void floppy_off(unsigned int nr);

 12 extern void floppy_select(unsigned int nr);

 13 extern void floppy_deselect(unsigned int nr);

 14

    // �������й����̿�����һЩ�˿ںͷ��ŵĶ��塣

 15 /* Fd controller regs. S&C, about page 340 */

    /* ���̿�����(FDC)�Ĵ����˿ڡ�ժ��S&C����Լ340ҳ */

 16 #define FD_STATUS       0x3f4           // ��״̬�Ĵ����˿ڡ�

 17 #define FD_DATA         0x3f5           // ���ݶ˿ڡ�

 18 #define FD_DOR          0x3f2           /* Digital Output Register */

                                            // ��������Ĵ�����Ҳ��Ϊ���ֿ��ƼĴ�������

 19 #define FD_DIR          0x3f7           /* Digital Input Register (read) */

                                            // ��������Ĵ�����

 20 #define FD_DCR          0x3f7           /* Diskette Control Register (write)*/

                                            // ���ݴ����ʿ��ƼĴ�����

 21

 22 /* Bits of main status register */

    /* ��״̬�Ĵ���������λ�ĺ��� */

 23 #define STATUS_BUSYMASK 0x0F            /* drive busy mask */

                                            // ������æλ��ÿλ��Ӧһ������������

 24 #define STATUS_BUSY     0x10            /* FDC busy */

                                            // ���̿�����æ��

 25 #define STATUS_DMA      0x20            /* 0- DMA mode */

                                            // 0 - ΪDMA���ݴ���ģʽ��1 - Ϊ��DMAģʽ��

 26 #define STATUS_DIR      0x40            /* 0- cpu->fdc */

                                            // ���䷽��0 - CPU �� fdc��1 - �෴��

 27 #define STATUS_READY    0x80            /* Data reg ready */

                                            // ���ݼĴ�������λ��

 28

 29 /* Bits of FD_ST0 */

    /*״̬�ֽ�0��ST0��������λ�ĺ��� */

 30 #define ST0_DS          0x03            /* drive select mask */

                                            // ������ѡ��ţ������ж�ʱ�������ţ���

 31 #define ST0_HA          0x04            /* Head (Address) */

                                            // ��ͷ�š�

 32 #define ST0_NR          0x08            /* Not Ready */

                                            // ����������δ׼���á�

 33 #define ST0_ECE         0x10            /* Equipment chech error */

                                            // �豸����������ŵ�У׼��������

 34 #define ST0_SE          0x20            /* Seek end */

                                            // Ѱ��������У������ִ�н�����

 35 #define ST0_INTR        0xC0            /* Interrupt code mask */

                                            // �жϴ���λ���ж�ԭ�򣩣�00 - ��������������

                                    // 01 - �����쳣������10 - ������Ч��11 - FDD����״̬�ı䡣

 36

 37 /* Bits of FD_ST1 */

    /*״̬�ֽ�1��ST1��������λ�ĺ��� */

 38 #define ST1_MAM         0x01            /* Missing Address Mark */

                                            // δ�ҵ���ַ��־(ID AM)��

 39 #define ST1_WP          0x02            /* Write Protect */

                                            // д������

 40 #define ST1_ND          0x04            /* No Data - unreadable */

                                            // δ�ҵ�ָ����������

 41 #define ST1_OR          0x10            /* OverRun */

                                            // ���ݴ��䳬ʱ��DMA���������ϣ���

 42 #define ST1_CRC         0x20            /* CRC error in data or addr */

                                            // CRC���������

 43 #define ST1_EOC         0x80            /* End Of Cylinder */

                                            // ���ʳ���һ���ŵ��ϵ���������š�

 44

 45 /* Bits of FD_ST2 */

    /*״̬�ֽ�2��ST2��������λ�ĺ��� */

 46 #define ST2_MAM         0x01            /* Missing Addess Mark (again) */

                                            // δ�ҵ����ݵ�ַ��־��

 47 #define ST2_BC          0x02            /* Bad Cylinder */

                                            // �ŵ�����

 48 #define ST2_SNS         0x04            /* Scan Not Satisfied */

                                            // ������ɨ�裩���������㡣

 49 #define ST2_SEH         0x08            /* Scan Equal Hit */

                                            // �����������㡣

 50 #define ST2_WC          0x10            /* Wrong Cylinder */

                                            // �ŵ������棩�Ų�����

 51 #define ST2_CRC         0x20            /* CRC error in data field */

                                            // ���ݳ�CRCУ�����

 52 #define ST2_CM          0x40            /* Control Mark = deleted */

                                            // ����������ɾ����־��

 53

 54 /* Bits of FD_ST3 */

    /*״̬�ֽ�3��ST3��������λ�ĺ��� */

 55 #define ST3_HA          0x04            /* Head (Address) */

                                            // ��ͷ�š�

 56 #define ST3_TZ          0x10            /* Track Zero signal (1=track 0) */

                                            // ��ŵ��źš�

 57 #define ST3_WP          0x40            /* Write Protect */

                                            // д������

 58

 59 /* Values for FD_COMMAND */

    /* ���������� */

 60 #define FD_RECALIBRATE  0x07            /* move to track 0 */

                                            // ����У��(��ͷ�˵���ŵ�)��

 61 #define FD_SEEK         0x0F            /* seek track */

                                            // ��ͷѰ����

 62 #define FD_READ         0xE6            /* read with MT, MFM, SKip deleted */

                                            // �����ݣ�MT��ŵ�������MFM��ʽ������ɾ�����ݣ���

 63 #define FD_WRITE        0xC5            /* write with MT, MFM */

                                            // д���ݣ�MT��MFM����

 64 #define FD_SENSEI       0x08            /* Sense Interrupt Status */

                                            // ����ж�״̬��

 65 #define FD_SPECIFY      0x03            /* specify HUT etc */

                                            // �趨�������������������ʡ���ͷж��ʱ��ȣ���

 66

 67 /* DMA commands */

    /* DMA ���� */

 68 #define DMA_READ        0x46            // DMA���̣�DMA��ʽ�֣���DMA�˿�12��11����

 69 #define DMA_WRITE       0x4A            // DMAд�̣�DMA��ʽ�֡�

 70

 71 #endif

 72


 


 

14.20 ����14-20 linux/include/linux/fs.h


  1 /*

  2  * This file has definitions for some important file table

  3  * structures etc.

  4  */

    /*

     * ���ļ�����ijЩ��Ҫ�ļ����ṹ�Ķ���ȡ�

     */

  5

  6 #ifndef _FS_H

  7 #define _FS_H

  8

  9 #include <sys/types.h>    // ����ͷ�ļ��������˻�����ϵͳ�������͡�

 10

 11 /* devices are as follows: (same as minix, so we can use the minix

 12  * file system. These are major numbers.)

 13  *

 14  * 0 - unused (nodev)

 15  * 1 - /dev/mem

 16  * 2 - /dev/fd

 17  * 3 - /dev/hd

 18  * 4 - /dev/ttyx

 19  * 5 - /dev/tty

 20  * 6 - /dev/lp

 21  * 7 - unnamed pipes

 22  */

    /*

     * ϵͳ�������豸���£�����minixϵͳ��һ�����������ǿ���ʹ��minix��

     * �ļ�ϵͳ��������Щ�����豸�š���

     *

     * 0 - û���õ���nodev��

     * 1 - /dev/mem         �ڴ��豸��

     * 2 - /dev/fd          �����豸��

     * 3 - /dev/hd          Ӳ���豸��

     * 4 - /dev/ttyx        tty�����ն��豸��

     * 5 - /dev/tty         tty�ն��豸��

     * 6 - /dev/lp          ��ӡ�豸��

     * 7 - unnamed pipes    û�������Ĺܵ���

     */

 23

 24 #define IS_SEEKABLE(x) ((x)>=1 && (x)<=3)      // �ж��豸�Ƿ��ǿ���Ѱ�Ҷ�λ�ġ�

 25

 26 #define READ 0

 27 #define WRITE 1

 28 #define READA 2         /* read-ahead - don't pause */

 29 #define WRITEA 3        /* "write-ahead" - silly, but somewhat useful */

 30

 31 void buffer_init(long buffer_end);              // ���ٻ�������ʼ��������

 32

 33 #define MAJOR(a) (((unsigned)(a))>>8)           // ȡ���ֽڣ����豸�ţ���

 34 #define MINOR(a) ((a)&0xff)                     // ȡ���ֽڣ����豸�ţ���

 35

 36 #define NAME_LEN 14                             // ���ֳ���ֵ��

 37 #define ROOT_INO 1                              // ��i�ڵ㡣

 38

 39 #define I_MAP_SLOTS 8                           // i�ڵ�λͼ������

 40 #define Z_MAP_SLOTS 8                           // �߼��飨���ο飩λͼ������

 41 #define SUPER_MAGIC 0x137F                      // �ļ�ϵͳħ����

 42

 43 #define NR_OPEN 20                              // ���������ļ�����

 44 #define NR_INODE 32                             // ϵͳͬʱ���ʹ��I�ڵ������

 45 #define NR_FILE 64                              // ϵͳ����ļ��������ļ�������������

 46 #define NR_SUPER 8                              // ϵͳ���������������������������������

 47 #define NR_HASH 307                             // ������Hash����������ֵ��

 48 #define NR_BUFFERS nr_buffers                   // ϵͳ����������������ʼ�����ٸı䡣

 49 #define BLOCK_SIZE 1024                         // ���ݿ鳤�ȣ��ֽ�ֵ����

 50 #define BLOCK_SIZE_BITS 10                      // ���ݿ鳤����ռ����λ����

 51 #ifndef NULL

 52 #define NULL ((void *) 0)

 53 #endif

 54

    // ÿ���߼���ɴ�ŵ�i�ڵ�����

 55 #define INODES_PER_BLOCK ((BLOCK_SIZE)/(sizeof (struct d_inode)))

    // ÿ���߼���ɴ�ŵ�Ŀ¼������

 56 #define DIR_ENTRIES_PER_BLOCK ((BLOCK_SIZE)/(sizeof (struct dir_entry)))

 57

    // �ܵ�ͷ���ܵ�β���ܵ���С���ܵ��գ����ܵ��������ܵ�ͷָ�������

 58 #define PIPE_READ_WAIT(inode) ((inode).i_wait)

 59 #define PIPE_WRITE_WAIT(inode) ((inode).i_wait2)

 60 #define PIPE_HEAD(inode) ((inode).i_zone[0])

 61 #define PIPE_TAIL(inode) ((inode).i_zone[1])

 62 #define PIPE_SIZE(inode) ((PIPE_HEAD(inode)-PIPE_TAIL(inode))&(PAGE_SIZE-1))

 63 #define PIPE_EMPTY(inode) (PIPE_HEAD(inode)==PIPE_TAIL(inode))

 64 #define PIPE_FULL(inode) (PIPE_SIZE(inode)==(PAGE_SIZE-1))

 65

 66 #define NIL_FILP        ((struct file *)0)   // ���ļ��ṹָ�롣

 67 #define SEL_IN          1

 68 #define SEL_OUT         2

 69 #define SEL_EX          4

 70

 71 typedef char buffer_block[BLOCK_SIZE];       // �黺������

 72

    // �����ͷ���ݽṹ������Ϊ��Ҫ��������

    // �ڳ����г���bh����ʾbuffer_head���͵���д��

 73 struct buffer_head {

 74         char * b_data;                  /* pointer to data block (1024 bytes) */ //ָ�롣

 75         unsigned long b_blocknr;        /* block number */       // ��š�

 76         unsigned short b_dev;           /* device (0 = free) */  // ����Դ���豸�š�

 77         unsigned char b_uptodate;       // ���±�־����ʾ�����Ƿ��Ѹ��¡�

 78         unsigned char b_dirt;           /* 0-clean,1-dirty */ //�޸ı�־:0δ�޸�,1���޸�.

 79         unsigned char b_count;          /* users using this block */   // ʹ�õ��û�����

 80         unsigned char b_lock;           /* 0 - ok, 1 -locked */  // �������Ƿ�������

 81         struct task_struct * b_wait;    // ָ��ȴ��û���������������

 82         struct buffer_head * b_prev;    // hash������ǰһ�飨���ĸ�ָ�����ڻ������Ĺ�������

 83         struct buffer_head * b_next;    // hash��������һ�顣

 84         struct buffer_head * b_prev_free;   // ���б���ǰһ�顣

 85         struct buffer_head * b_next_free;   // ���б�����һ�顣

 86 };

 87

    // �����ϵ������ڵ�(i�ڵ�)���ݽṹ��

 88 struct d_inode {

 89         unsigned short i_mode;        // �ļ����ͺ�����(rwxλ)��

 90         unsigned short i_uid;         // �û�id���ļ�ӵ���߱�ʶ������

 91         unsigned long i_size;         // �ļ���С���ֽ�������

 92         unsigned long i_time;         // �޸�ʱ�䣨��1970.1.1:0�����룩��

 93         unsigned char i_gid;          // ��id(�ļ�ӵ�������ڵ���)��

 94         unsigned char i_nlinks;       // �����������ٸ��ļ�Ŀ¼��ָ���i�ڵ㣩��

 95         unsigned short i_zone[9];     // ֱ��(0-6)�����(7)��˫�ؼ��(8)�߼���š�

                                          // zone��������˼����������Σ����߼��顣

 96 };

 97

    // �������ڴ��е�i�ڵ�ṹ��ǰ7����d_inode��ȫһ����

 98 struct m_inode {

 99         unsigned short i_mode;        // �ļ����ͺ�����(rwxλ)��

100         unsigned short i_uid;         // �û�id���ļ�ӵ���߱�ʶ������

101         unsigned long i_size;         // �ļ���С���ֽ�������

102         unsigned long i_mtime;        // �޸�ʱ�䣨��1970.1.1:0�����룩��

103         unsigned char i_gid;          // ��id(�ļ�ӵ�������ڵ���)��

104         unsigned char i_nlinks;       // �ļ�Ŀ¼����������

105         unsigned short i_zone[9];     // ֱ��(0-6)�����(7)��˫�ؼ��(8)�߼���š�

106 /* these are in memory also */

107         struct task_struct * i_wait;  // �ȴ���i�ڵ�Ľ��̡�

108         struct task_struct * i_wait2;   /* for pipes */

109         unsigned long i_atime;        // ������ʱ�䡣

110         unsigned long i_ctime;        // i�ڵ������޸�ʱ�䡣

111         unsigned short i_dev;         // i�ڵ����ڵ��豸�š�

112         unsigned short i_num;         // i�ڵ�š�

113         unsigned short i_count;       // i�ڵ㱻ʹ�õĴ�����0��ʾ��i�ڵ���С�

114         unsigned char i_lock;         // ������־��

115         unsigned char i_dirt;         // ���޸�(��)��־��

116         unsigned char i_pipe;         // �ܵ���־��

117         unsigned char i_mount;        // ��װ��־��

118         unsigned char i_seek;         // ��Ѱ��־(lseekʱ)��

119         unsigned char i_update;       // ���±�־��

120 };

121

    // �ļ��ṹ���������ļ������i�ڵ�֮�佨����ϵ��

122 struct file {

123         unsigned short f_mode;        // �ļ�����ģʽ��RWλ��

124         unsigned short f_flags;       // �ļ��򿪺Ϳ��Ƶı�־��

125         unsigned short f_count;       // ��Ӧ�ļ����ü���ֵ��

126         struct m_inode * f_inode;     // ָ���Ӧi�ڵ㡣

127         off_t f_pos;                  // �ļ�λ�ã���дƫ��ֵ����

128 };

129

    // �ڴ��д��̳�����ṹ��

130 struct super_block {

131         unsigned short s_ninodes;       // �ڵ�����

132         unsigned short s_nzones;        // �߼�������

133         unsigned short s_imap_blocks;   // i�ڵ�λͼ��ռ�õ����ݿ�����

134         unsigned short s_zmap_blocks;   // �߼���λͼ��ռ�õ����ݿ�����

135         unsigned short s_firstdatazone; // ��һ�������߼���š�

136         unsigned short s_log_zone_size; // log(���ݿ���/�߼���)������2Ϊ�ף���

137         unsigned long s_max_size;       // �ļ���󳤶ȡ�

138         unsigned short s_magic;         // �ļ�ϵͳħ����

139 /* These are only in memory */

140         struct buffer_head * s_imap[8]; // i�ڵ�λͼ�����ָ������(ռ��8�飬�ɱ�ʾ64M)��

141         struct buffer_head * s_zmap[8]; // �߼���λͼ�����ָ�����飨ռ��8�飩��

142         unsigned short s_dev;           // ���������ڵ��豸�š�

143         struct m_inode * s_isup;        // ����װ���ļ�ϵͳ��Ŀ¼��i�ڵ㡣(isup-super i)

144         struct m_inode * s_imount;      // ����װ����i�ڵ㡣

145         unsigned long s_time;           // �޸�ʱ�䡣

146         struct task_struct * s_wait;    // �ȴ��ó�����Ľ��̡�

147         unsigned char s_lock;           // ��������־��

148         unsigned char s_rd_only;        // ֻ����־��

149         unsigned char s_dirt;           // ���޸�(��)��־��

150 };

151

    // �����ϳ�����ṹ������125-132����ȫһ����

152 struct d_super_block {

153         unsigned short s_ninodes;       // �ڵ�����

154         unsigned short s_nzones;        // �߼�������

155         unsigned short s_imap_blocks;   // i�ڵ�λͼ��ռ�õ����ݿ�����

156         unsigned short s_zmap_blocks;   // �߼���λͼ��ռ�õ����ݿ�����

157         unsigned short s_firstdatazone; // ��һ�������߼��顣

158         unsigned short s_log_zone_size; // log(���ݿ���/�߼���)������2Ϊ�ף���

159         unsigned long s_max_size;       // �ļ���󳤶ȡ�

160         unsigned short s_magic;         // �ļ�ϵͳħ����

161 };

162

    // �ļ�Ŀ¼��ṹ��

163 struct dir_entry {

164         unsigned short inode;           // i�ڵ�š�

165         char name[NAME_LEN];            // �ļ���������NAME_LEN=14��

166 };

167

168 extern struct m_inode inode_table[NR_INODE];     // ����i�ڵ�����飨32���

169 extern struct file file_table[NR_FILE];          // �ļ������飨64���

170 extern struct super_block super_block[NR_SUPER]; // ���������飨8���

171 extern struct buffer_head * start_buffer;        // ��������ʼ�ڴ�λ�á�

172 extern int nr_buffers;                           // ���������

173

    //// ���̲�������ԭ�͡�

    // ����������������Ƿ�ı䡣

174 extern void check_disk_change(int dev);

    // ���ָ�����������̸��������������̸������򷵻�1�����򷵻�0��

175 extern int floppy_change(unsigned int nr);

    // ��������ָ������������ȴ���ʱ�䣨���õȴ���ʱ������

176 extern int ticks_to_floppy_on(unsigned int dev);

    // ����ָ����������

177 extern void floppy_on(unsigned int dev);

    // �ر�ָ����������������

178 extern void floppy_off(unsigned int dev);

 

    //// �������ļ�ϵͳ���������õĺ���ԭ�͡�

    // ��i�ڵ�ָ�����ļ���Ϊ0��

179 extern void truncate(struct m_inode * inode);

    // ˢ��i�ڵ���Ϣ��

180 extern void sync_inodes(void);

    // �ȴ�ָ����i�ڵ㡣

181 extern void wait_on(struct m_inode * inode);

    // �߼���(���Σ����̿�)λͼ������ȡ���ݿ�block���豸�϶�Ӧ���߼���š�

182 extern int bmap(struct m_inode * inode,int block);

    // �������ݿ�block���豸�϶�Ӧ���߼��飬���������豸�ϵ��߼���š�

183 extern int create_block(struct m_inode * inode,int block);

    // ��ȡָ��·������i�ڵ�š�

184 extern struct m_inode * namei(const char * pathname);

    // ȡָ��·������i�ڵ㣬������������ӡ�

185 extern struct m_inode * lnamei(const char * pathname);

    // ����·����Ϊ���ļ�������׼����

186 extern int open_namei(const char * pathname, int flag, int mode,

187         struct m_inode ** res_inode);

    // �ͷ�һ��i�ڵ�(��д���豸)��

188 extern void iput(struct m_inode * inode);

    // ���豸��ȡָ���ڵ�ŵ�һ��i�ڵ㡣

189 extern struct m_inode * iget(int dev,int nr);

    // ��i�ڵ��(inode_table)�л�ȡһ������i�ڵ��

190 extern struct m_inode * get_empty_inode(void);

    // ��ȡ������һ���ܵ��ڵ㡣����Ϊi�ڵ�ָ�루�����NULL��ʧ�ܣ���

191 extern struct m_inode * get_pipe_inode(void);

    // �ڹ�ϣ���в���ָ�������ݿ顣�����ҵ���Ļ���ͷָ�롣

192 extern struct buffer_head * get_hash_table(int dev, int block);

    // ���豸��ȡָ���飨���Ȼ���hash���в��ң���

193 extern struct buffer_head * getblk(int dev, int block);

    // ��/д���ݿ顣

194 extern void ll_rw_block(int rw, struct buffer_head * bh);

    // ��/д����ҳ�棬��ÿ��4�����ݿ顣

195 extern void ll_rw_page(int rw, int dev, int nr, char * buffer);

    // �ͷ�ָ������顣

196 extern void brelse(struct buffer_head * buf);

    // ��ȡָ�������ݿ顣

197 extern struct buffer_head * bread(int dev,int block);

    // ��4�黺������ָ����ַ���ڴ��С�

198 extern void bread_page(unsigned long addr,int dev,int b[4]);

    // ��ȡͷһ��ָ�������ݿ飬����Ǻ�����Ҫ���Ŀ顣

199 extern struct buffer_head * breada(int dev,int block,...);

    // ���豸dev����һ�����̿飨���Σ��߼��飩�������߼����

200 extern int new_block(int dev);

    // �ͷ��豸�������е��߼���(���Σ����̿�)block����λָ���߼���block���߼���λͼ����λ��

201 extern void free_block(int dev, int block);

    // Ϊ�豸dev����һ����i�ڵ㣬����i�ڵ�š�

202 extern struct m_inode * new_inode(int dev);

    // �ͷ�һ��i�ڵ㣨ɾ���ļ�ʱ����

203 extern void free_inode(struct m_inode * inode);

    // ˢ��ָ���豸��������

204 extern int sync_dev(int dev);

    // ��ȡָ���豸�ij����顣

205 extern struct super_block * get_super(int dev);

206 extern int ROOT_DEV;

207

    // ��װ���ļ�ϵͳ��

208 extern void mount_root(void);

209

210 #endif

211


 


 

14.21 ����14-21 linux/include/linux/hdreg.h


  1 /*

  2  * This file contains some defines for the AT-hd-controller.

  3  * Various sources. Check out some definitions (see comments with

  4  * a ques).

  5  */

    /*

     * ���ļ�����һЩATӲ�̿������Ķ��塣���Ը������ϡ����֤ijЩ

     * ���壨�����ʺŵ�ע�ͣ���

     */

  6 #ifndef _HDREG_H

  7 #define _HDREG_H

  8

  9 /* Hd controller regs. Ref: IBM AT Bios-listing */

    /* Ӳ�̿������Ĵ����˿ڡ��μ���IBM AT Bios���� */

 10 #define HD_DATA         0x1f0   /* _CTL when writing */

 11 #define HD_ERROR        0x1f1   /* see err-bits */

 12 #define HD_NSECTOR      0x1f2   /* nr of sectors to read/write */

 13 #define HD_SECTOR       0x1f3   /* starting sector */

 14 #define HD_LCYL         0x1f4   /* starting cylinder */

 15 #define HD_HCYL         0x1f5   /* high byte of starting cyl */

 16 #define HD_CURRENT      0x1f6   /* 101dhhhh , d=drive, hhhh=head */

 17 #define HD_STATUS       0x1f7   /* see status-bits */

 18 #define HD_PRECOMP HD_ERROR     /* same io address, read=error, write=precomp */

 19 #define HD_COMMAND HD_STATUS    /* same io address, read=status, write=cmd */

 20

 21 #define HD_CMD          0x3f6   // ���ƼĴ����˿ڡ�

 22

 23 /* Bits of HD_STATUS */

    /* Ӳ��״̬�Ĵ�����λ�Ķ���(HD_STATUS) */

 24 #define ERR_STAT        0x01    // ����ִ�д���

 25 #define INDEX_STAT      0x02    // �յ�������

 26 #define ECC_STAT        0x04    /* Corrected error */  // ECCУ�����

 27 #define DRQ_STAT        0x08    // �������

 28 #define SEEK_STAT       0x10    // Ѱ��������

 29 #define WRERR_STAT      0x20    // ���������ϡ�

 30 #define READY_STAT      0x40    // ������׼���ã���������

 31 #define BUSY_STAT       0x80    // ������æµ��

 32

 33 /* Values for HD_COMMAND */

    /* Ӳ������ֵ��HD_CMD�� */

 34 #define WIN_RESTORE             0x10   // ����������У������������λ����

 35 #define WIN_READ                0x20   // ��������

 36 #define WIN_WRITE               0x30   // д������

 37 #define WIN_VERIFY              0x40   // �������顣

 38 #define WIN_FORMAT              0x50   // ��ʽ���ŵ���

 39 #define WIN_INIT                0x60   // ��������ʼ����

 40 #define WIN_SEEK                0x70   // Ѱ����

 41 #define WIN_DIAGNOSE            0x90   // ��������ϡ�

 42 #define WIN_SPECIFY             0x91   // ����������������

 43

 44 /* Bits for HD_ERROR */

    /* ����Ĵ���������λ�ĺ��壨HD_ERROR�� */

    // ִ�п������������ʱ��������������ʱ�IJ�ͬ������ֱ��г���

    // ==================================================

    //           �������ʱ            ��������ʱ

    // --------------------------------------------------

    // 0x01      �޴���               ���ݱ�־��ʧ

    // 0x02      ����������           �ŵ�0��

    // 0x03      ������������        

    // 0x04      ECC������            �������

    // 0x05      ���ƴ�������         

    // 0x10                            IDδ�ҵ�

    // 0x40                            ECC����

    // 0x80                            ������

    //---------------------------------------------------

 45 #define MARK_ERR        0x01    /* Bad address mark ? */

 46 #define TRK0_ERR        0x02    /* couldn't find track 0 */

 47 #define ABRT_ERR        0x04    /* ? */

 48 #define ID_ERR          0x10    /* ? */

 49 #define ECC_ERR         0x40    /* ? */

 50 #define BBD_ERR         0x80    /* ? */

 51

    // Ӳ�̷������ṹ���μ������б�����Ϣ��

 52 struct partition {

 53         unsigned char boot_ind;         /* 0x80 - active (unused) */

 54         unsigned char head;             /* ? */

 55         unsigned char sector;           /* ? */

 56         unsigned char cyl;              /* ? */

 57         unsigned char sys_ind;          /* ? */

 58         unsigned char end_head;         /* ? */

 59         unsigned char end_sector;       /* ? */

 60         unsigned char end_cyl;          /* ? */

 61         unsigned int start_sect;        /* starting sector counting from 0 */

 62         unsigned int nr_sects;          /* nr of sectors in partition */

 63 };

 64

 65 #endif

 66


 


 

14.22 ����14-22 linux/include/linux/head.h


  1 #ifndef _HEAD_H

  2 #define _HEAD_H

  3

  4 typedef struct desc_struct {        // �����˶������������ݽṹ���ýṹ��˵��ÿ������

  5         unsigned long a,b;          // ������8���ֽڹ��ɣ�ÿ��������������256�

  6 } desc_table[256];

  7

  8 extern unsigned long pg_dir[1024];  // �ڴ�ҳĿ¼���顣ÿ��Ŀ¼��Ϊ4�ֽڡ���������ַ0��ʼ��

  9 extern desc_table idt,gdt;          // �ж�����������ȫ������������

 10

 11 #define GDT_NUL 0                   // ȫ�����������ĵ�0����á�

 12 #define GDT_CODE 1                  // ��1����ں˴�����������

 13 #define GDT_DATA 2                  // ��2����ں����ݶ��������

 14 #define GDT_TMP 3                   // ��3�ϵͳ����������Linuxû��ʹ�á�

 15

 16 #define LDT_NUL 0                   // ÿ���ֲ����������ĵ�0����á�

 17 #define LDT_CODE 1                  // ��1����û����������������

 18 #define LDT_DATA 2                  // ��2����û��������ݶ��������

 19

 20 #endif

 21


 


 

14.23 ����14-23 linux/include/linux/kernel.h


  1 /*

  2  * 'kernel.h' contains some often-used function prototypes etc

  3  */

    /*

     * 'kernel.h'������һЩ���ú�����ԭ�͵ȡ�

     */

    // ��֤������ַ��ʼ���ڴ���Ƿ��ޡ���������׷���ڴ档( kernel/fork.c, 24 )��

  4 void verify_area(void * addr,int count);

    // ��ʾ�ں˳�����Ϣ��Ȼ�������ѭ����( kernel/panic.c, 16 )��

    // ������ǰ�Ĺؼ���volatile���ڸ��߱�����gcc�ú������᷵�ء���������gcc��������

    // һЩ�Ĵ��룬����Ҫ����ʹ������ؼ��ֿ��Ա������ijδ��ʼ�������ļپ�����Ϣ��

  5 volatile void panic(const char * str);

    // �����˳��������� kernel/exit.c��262 ����

  6 volatile void do_exit(long error_code);

    // ��׼��ӡ����ʾ��������( init/main.c, 151)��

  7 int printf(const char * fmt, ...);

    // �ں�ר�õĴ�ӡ��Ϣ������������printf()��ͬ��( kernel/printk.c, 21 )��

  8 int printk(const char * fmt, ...);

    // ����̨��ʾ�������� kernel/chr_drv/console.c��995����

  9 void console_print(const char * str);

    // ��tty��дָ�����ȵ��ַ�����( kernel/chr_drv/tty_io.c, 290 )��

 10 int tty_write(unsigned ch,char * buf,int count);

    // ͨ���ں��ڴ���亯����( lib/malloc.c, 117)��

 11 void * malloc(unsigned int size);

    // �ͷ�ָ������ռ�õ��ڴ档( lib/malloc.c, 182)��

 12 void free_s(void * obj, int size);

    // Ӳ�̴�����ʱ����kernel/blk_drv/hd.c��318����

 13 extern void hd_times_out(void);

    // ֹͣ��������kernel/chr_drv/console.c��944����

 14 extern void sysbeepstop(void);

    // ������������kernel/chr_drv/console.c��981����

 15 extern void blank_screen(void);

    // �ָ�����������Ļ����kernel/chr_drv/console.c��988����

 16 extern void unblank_screen(void);

 17

 18 extern int beepcount;              // ����ʱ����઼�����kernel/chr_drv/console.c��988����

 19 extern int hd_timeout;             // Ӳ�̳�ʱ�δ�ֵ��kernel/blk_drv/blk.h����

 20 extern int blankinterval;          // �趨����Ļ�������ʱ�䡣

 21 extern int blankcount;             // ����ʱ�������kernel/chr_drv/console.c��138��139����

 22

 23 #define free(x) free_s((x), 0)

 24

 25 /*

 26  * This is defined as a macro, but at some point this might become a

 27  * real subroutine that sets a flag if it returns true (to do

 28  * BSD-style accounting where the process is flagged if it uses root

 29  * privs).  The implication of this is that you should do normal

 30  * permissions checks first, and check suser() last.

 31  */

    /*

     * ���溯�����Ժ����ʽ����ģ�������ij�������������Գ�Ϊһ���������ӳ���

     * ���������trueʱ�������ñ�־�����ʹ��root�û�Ȩ�޵Ľ��������˱�־������

     * ��ִ��BSD��ʽ�ļ��ʴ�����������ζ����Ӧ������ִ�г���Ȩ�޼�飬�����

     * ���suser()��

     */

 32 #define suser() (current->euid == 0)             // ����Ƿ��dz����û���

 33


 


 

 

14.24 ����14-24 linux/include/linux/math_emu.h


  1 /*

  2  * linux/include/linux/math_emu.h

  3  *

  4  * (C) 1991 Linus Torvalds

  5  */

  6 #ifndef _LINUX_MATH_EMU_H

  7 #define _LINUX_MATH_EMU_H

  8

  9 #include <linux/sched.h>  // ���ȳ���ͷ�ļ�������������ṹtask_struct������0 �����ݣ�

                              // ����һЩ�й��������������úͻ�ȡ��Ƕ��ʽ��ຯ������䡣

 10

    // CPU�����쳣�ж�int 7ʱ��ջ�зֲ������ݹ��ɵĽṹ����ϵͳ����ʱ�ں�ջ�����ݷֲ����ơ�

 11 struct info {

 12         long ___math_ret;     // math_emulate()�����ߣ�int7�����ص�ַ��

 13         long ___orig_eip;     // ��ʱ����ԭEIP �ĵط���

 14         long ___edi;          // �쳣�ж�int7 ����������ջ�ļĴ�����

 15         long ___esi;

 16         long ___ebp;

 17         long ___sys_call_ret; // �ж�7 ����ʱ��ȥִ��ϵͳ���õķ��ش������롣

 18         long ___eax;          // ���²��֣�18--30 �У���ϵͳ����ʱջ�нṹ��ͬ��

 19         long ___ebx;

 20         long ___ecx;

 21         long ___edx;

 22         long ___orig_eax;     // �粻��ϵͳ���ö��������ж�ʱ����ֵΪ-1��

 23         long ___fs;

 24         long ___es;

 25         long ___ds;

 26         long ___eip;          // 26 -- 30 �� ��CPU �Զ���ջ��

 27         long ___cs;

 28         long ___eflags;

 29         long ___esp;

 30         long ___ss;

 31 };

 32

    // Ϊ��������info�ṹ�и��ֶΣ�ջ�����ݣ��������һЩ������

 33 #define EAX (info->___eax)

 34 #define EBX (info->___ebx)

 35 #define ECX (info->___ecx)

 36 #define EDX (info->___edx)

 37 #define ESI (info->___esi)

 38 #define EDI (info->___edi)

 39 #define EBP (info->___ebp)

 40 #define ESP (info->___esp)

 41 #define EIP (info->___eip)

 42 #define ORIG_EIP (info->___orig_eip)

 43 #define EFLAGS (info->___eflags)

 44 #define DS (*(unsigned short *) &(info->___ds))

 45 #define ES (*(unsigned short *) &(info->___es))

 46 #define FS (*(unsigned short *) &(info->___fs))

 47 #define CS (*(unsigned short *) &(info->___cs))

 48 #define SS (*(unsigned short *) &(info->___ss))

 49

    // ��ֹ��ѧЭ�����������������math_emulation.c������ʵ��(L488�У���

    // ����52-53���Ϻ궨���ʵ�������ǰ�__math_abort���¶���Ϊһ�����᷵�صĺ���

    // ������ǰ�������volatile�����ú��ǰ���֣�

    // (volatile void (*)(struct info *,unsigned int))

    // �Ǻ������Ͷ��壬��������ָ�� __math_abort�����Ķ��塣����������Ӧ�IJ�����

    // �ؼ���volatile ���ں�����ǰ�����κ�����������֪ͨgcc �������ú������᷵��,

    // ����gcc ��������һЩ�Ĵ��롣��ϸ˵����μ���3�� $3.3.2�����ݡ�

    // �������ĺ궨�壬����ҪĿ�ľ�������__math_abort����������������ͨ�з��غ�����

    // �ֿ�����ʹ�ú궨��math_abort() ʱ���������صĺ�����

 50 void __math_abort(struct info *, unsigned int);

 51

 52 #define math_abort(x,y) \

 53 (((volatile void (*)(struct info *,unsigned int)) __math_abort)((x),(y)))

 54 

 55 /*

 56  * Gcc forces this stupid alignment problem: I want to use only two longs

 57  * for the temporary real 64-bit mantissa, but then gcc aligns out the

 58  * structure to 12 bytes which breaks things in math_emulate.c. Shit. I

 59  * want some kind of "no-alignt" pragma or something.

 60  */

    /*

     * Gcc��ǿ�������޴��Ķ������⣺��ֻ��ʹ������long������������ʾ64���ص�

     * ��ʱʵ��β��������gccȴ�Ὣ�ýṹ��12�ֽ������룬�⽫����math_emulate.c

     * �г�������⡣����������Ҫij�ַǶ��롰no-align������ָ�

     */

 61

    // ��ʱʵ����Ӧ�Ľṹ��

 62 typedef struct {

 63 long a,b;          // ��64����β��������aΪ��32λ��bΪ��32λ������1λ�̶�λ����

 64 short exponent;    // ָ��ֵ��

 65 } temp_real;

 66

    // Ϊ�˽������Ӣ��ע�������ἰ�Ķ����������ƵĽṹ������ͬ����temp_real�ṹ��

 67 typedef struct {

 68 short m0,m1,m2,m3;

 69 short exponent;

 70 } temp_real_unaligned;

 71

    // ��temp_real����ֵa��ֵ��80387ջ�Ĵ���b (ST(i))��

 72 #define real_to_real(a,b) \

 73 ((*(long long *) (b) = *(long long *) (a)),((b)->exponent = (a)->exponent))

 74

    // ��ʵ����˫���ȣ��ṹ��

 75 typedef struct {

 76 long a,b;          // a Ϊ��ʵ���ĵ�32λ��bΪ��32λ��

 77 } long_real;

 78

 79 typedef long short_real;  // �����ʵ�����͡�

 80

    // ��ʱ�����ṹ��

 81 typedef struct {

 82 long a,b;         // a Ϊ��32λ��bΪ��32λ��

 83 short sign;       // ���ű�־��

 84 } temp_int;

 85

    // 80387Э�������ڲ���״̬�ּĴ������ݶ�Ӧ�Ľṹ�����μ�ͼ11-6��

 86 struct swd {

 87 int ie:1;         // ��Ч�����쳣��

 88 int de:1;         // �ǹ���쳣��

 89 int ze:1;         // �����쳣��

 90 int oe:1;         // ������쳣��

 91 int ue:1;         // ������쳣��

 92 int pe:1;         // �����쳣��

 93 int sf:1;         // ջ������־����ʾ�ۼ��������ɵ��쳣��

 94 int ir:1;         // ir, b: ������6λ�κ�δ�����쳣����������λ��

 95 int c0:1;         // c0--c3: ���������λ��

 96 int c1:1;

 97 int c2:1;

 98 int top:3;        // ָʾ80387�е�ǰλ��ջ����80λ�Ĵ�����

 99 int c3:1;

100 int b:1;

101 };

102

    // 80387�ڲ��Ĵ������Ʒ�ʽ������

103 #define I387 (current->tss.i387)          // ���̵�80387״̬��Ϣ���μ�sched.h�ļ���

104 #define SWD (*(struct swd *) &I387.swd)   // 80387��״̬�����֡�

105 #define ROUNDING ((I387.cwd >> 10) & 3)   // ȡ��������������Ʒ�ʽ��

106 #define PRECISION ((I387.cwd >> 8) & 3)   // ȡ�������о��ȿ��Ʒ�ʽ��

107

    // ���徫����Чλ������

108 #define BITS24 0              // ������Ч����24λ�����μ�ͼ11-6��

109 #define BITS53 2              // ������Ч����53λ��

110 #define BITS64 3              // ������Ч����64λ��

111

    // �������뷽ʽ������

112 #define ROUND_NEAREST     0      // ���뷽ʽ�����뵽�����ż����

113 #define ROUND_DOWN  1          // ���뷽ʽ���������ޡ�

114 #define ROUND_UP 2          // ���뷽ʽ�����������ޡ�

115 #define ROUND_0            3          // ���뷽ʽ�������0��

116

    // �������塣

117 #define CONSTZ   (temp_real_unaligned) {0x0000,0x0000,0x0000,0x0000,0x0000}  // 0

118 #define CONST1   (temp_real_unaligned) {0x0000,0x0000,0x0000,0x8000,0x3FFF}  // 1.0

119 #define CONSTPI  (temp_real_unaligned) {0xC235,0x2168,0xDAA2,0xC90F,0x4000}  // Pi

120 #define CONSTLN2 (temp_real_unaligned) {0x79AC,0xD1CF,0x17F7,0xB172,0x3FFE}  // Loge(2)

121 #define CONSTLG2 (temp_real_unaligned) {0xF799,0xFBCF,0x9A84,0x9A20,0x3FFD}  // Log10(2)

122 #define CONSTL2E (temp_real_unaligned) {0xF0BC,0x5C17,0x3B29,0xB8AA,0x3FFF}  // Log2(e)

123 #define CONSTL2T (temp_real_unaligned) {0x8AFE,0xCD1B,0x784B,0xD49A,0x4000}  // Log2(10)

124

    // ����80387��״̬

125 #define set_IE() (I387.swd |= 1)   

126 #define set_DE() (I387.swd |= 2)

127 #define set_ZE() (I387.swd |= 4)

128 #define set_OE() (I387.swd |= 8)

129 #define set_UE() (I387.swd |= 16)

130 #define set_PE() (I387.swd |= 32)

131

    // ����80387����������

132 #define set_C0() (I387.swd |= 0x0100)

133 #define set_C1() (I387.swd |= 0x0200)

134 #define set_C2() (I387.swd |= 0x0400)

135 #define set_C3() (I387.swd |= 0x4000)

136

137 /* ea.c */

138

    // �������ָ���в�����ʹ�õ�����Ч��ֵַ��������ָ����Ѱַģʽ�ֽڼ�����Ч��ֵַ��

    // ������__info - �ж�ʱջ�����ݶ�Ӧ�ṹ��__code - ָ����롣

    // ���أ���Ч��ֵַ��

139 char * ea(struct info * __info, unsigned short __code);

140

141 /* convert.c */

142

    // ������������ת����������convert.c�ļ���ʵ�֡�

143 void short_to_temp(const short_real * __a, temp_real * __b);

144 void long_to_temp(const long_real * __a, temp_real * __b);

145 void temp_to_short(const temp_real * __a, short_real * __b);

146 void temp_to_long(const temp_real * __a, long_real * __b);

147 void real_to_int(const temp_real * __a, temp_int * __b);

148 void int_to_real(const temp_int * __a, temp_real * __b);

149

150 /* get_put.c */

151

    // ��ȡ�����������ĺ�����

152 void get_short_real(temp_real *, struct info *, unsigned short);

153 void get_long_real(temp_real *, struct info *, unsigned short);

154 void get_temp_real(temp_real *, struct info *, unsigned short);

155 void get_short_int(temp_real *, struct info *, unsigned short);

156 void get_long_int(temp_real *, struct info *, unsigned short);

157 void get_longlong_int(temp_real *, struct info *, unsigned short);

158 void get_BCD(temp_real *, struct info *, unsigned short);

159 void put_short_real(const temp_real *, struct info *, unsigned short);

160 void put_long_real(const temp_real *, struct info *, unsigned short);

161 void put_temp_real(const temp_real *, struct info *, unsigned short);

162 void put_short_int(const temp_real *, struct info *, unsigned short);

163 void put_long_int(const temp_real *, struct info *, unsigned short);

164 void put_longlong_int(const temp_real *, struct info *, unsigned short);

165 void put_BCD(const temp_real *, struct info *, unsigned short);

166

167 /* add.c */

168

    // ���渡��ӷ�ָ��ĺ�����

169 void fadd(const temp_real *, const temp_real *, temp_real *);

170

171 /* mul.c */

172

    // ���渡��˷�ָ�

173 void fmul(const temp_real *, const temp_real *, temp_real *);

174

175 /* div.c */

176

    // ���渡�����ָ�

177 void fdiv(const temp_real *, const temp_real *, temp_real *);

178

179 /* compare.c */

180

    // �ȽϺ�����

181 void fcom(const temp_real *, const temp_real *);    // ���渡��ָ��FCOM���Ƚ���������

182 void fucom(const temp_real *, const temp_real *);   // ���渡��ָ��FUCOM���޴���Ƚϡ�

183 void ftst(const temp_real *);                // ���渡��ָ��FTST��ջ���ۼ�����0�Ƚϡ�

184

185 #endif

186


 

 


 

14.25 ����14-25 linux/include/linux/mm.h


  1 #ifndef _MM_H

  2 #define _MM_H

  3

  4 #define PAGE_SIZE 4096    // ����1ҳ�ڴ�ҳ���ֽ�����ע����ٻ���鳤����1024�ֽڡ�

  5

  6 #include <linux/kernel.h> // �ں�ͷ�ļ�������һЩ�ں˳��ú�����ԭ�Ͷ��塣

  7 #include <signal.h>       // �ź�ͷ�ļ��������źŷ��ų������źŽṹ�Լ��źŲ�������ԭ�͡�

  8

  9 extern int SWAP_DEV;      // �ڴ�ҳ�潻���豸�š�������mm/memory.c�ļ��У���36�С�

 10

    // �ӽ����豸�����д���������ڴ�ҳ�档ll_rw_page()������blk_drv/ll_rw_block.c�ļ��С�

    // ����nr�����ڴ�����ҳ��ţ�buffer�Ƕ�/д��������

 11 #define read_swap_page(nr,buffer) ll_rw_page(READ,SWAP_DEV,(nr),(buffer));

 12 #define write_swap_page(nr,buffer) ll_rw_page(WRITE,SWAP_DEV,(nr),(buffer));

 13

    // �����ڴ�����ȡ��������ҳ�档����Ѿ�û�п����ڴ��ˣ��򷵻�0��

 14 extern unsigned long get_free_page(void);

    // ��һ�������޸Ĺ��������ڴ�ҳ��ӳ�䵽���Ե�ַ�ռ�ָ��������put_page()������ȫһ����

 15 extern unsigned long put_dirty_page(unsigned long page,unsigned long address);

    //�ͷ�������ַaddr��ʼ��1ҳ���ڴ档

 16 extern void free_page(unsigned long addr);

 17 void swap_free(int page_nr);

 18 void swap_in(unsigned long *table_ptr);

 19

    //// ��ʾ�ڴ������������Ϣ�����˳���

    // ���溯����ǰ�Ĺؼ���volatile���ڸ��߱�����gcc�ú������᷵�ء���������gcc��������

    // һЩ�Ĵ��룬����Ҫ����ʹ������ؼ��ֿ��Ա������ijЩ��δ��ʼ�������ģ��پ�����Ϣ��

 20 extern inline volatile void oom(void)

 21 {

    // do_exit()Ӧ��ʹ���˳����룬���������ź�ֵSIGSEGV(11) ��ֵͬ�ij����뺬���ǡ���Դ

    // ��ʱ�����á�������ͬ�塣

 22         printk("out of memory\n\r");

 23         do_exit(SIGSEGV);

 24 }

 25

    // ˢ��ҳ�任���ٻ���꺯����

    // Ϊ����ߵ�ַת����Ч�ʣ�CPU�����ʹ�õ�ҳ�����ݴ����оƬ�и��ٻ����С����޸Ĺ�

    // ҳ����Ϣ֮�󣬾���Ҫˢ�¸û������� ����ʹ�����¼���ҳĿ¼��ַ�Ĵ���cr3 �ķ�����

    // ����ˢ�¡�����eax = 0����ҳĿ¼�Ļ�ַ��

 26 #define invalidate() \

 27 __asm__("movl %%eax,%%cr3"::"a" (0))

 28

 29 /* these are not to be changed without changing head.s etc */

    /* ���涨������Ҫ�Ķ�������Ҫ��head.s���ļ��е������Ϣһ��ı� */

    // Linux 0.12�ں�Ĭ��֧�ֵ�����ڴ�������16MB�������޸���Щ�������ʺϸ�����ڴ档

 30 #define LOW_MEM 0x100000                     // ���������ڴ�Ͷˣ�1MB����

 31 extern unsigned long HIGH_MEMORY;            // ���ʵ�������ڴ���߶˵�ַ��

 32 #define PAGING_MEMORY (15*1024*1024)         // ��ҳ�ڴ�15MB�����ڴ������15M��

 33 #define PAGING_PAGES (PAGING_MEMORY>>12)     // ��ҳ��������ڴ�ҳ������3840����

 34 #define MAP_NR(addr) (((addr)-LOW_MEM)>>12)  // ָ���ڴ��ַӳ��Ϊҳ��š�

 35 #define USED 100                             // ҳ�汻ռ�ñ�־���μ�449�С�

 36

    // �ڴ�ӳ���ֽ�ͼ��1�ֽڴ���1ҳ�ڴ棩��ÿ��ҳ���Ӧ���ֽ����ڱ�־ҳ�浱ǰ������

    // ��ռ�ã���������������ӳ��15Mb���ڴ�ռ䡣�ڳ�ʼ������mem_init()�У����ڲ�

    // ���������ڴ���ҳ���λ�þ���Ԥ�ȱ����ó�USED��100����

 37 extern unsigned char mem_map [ PAGING_PAGES ];

 38

    // ���涨��ķ��ų�����ӦҳĿ¼�����ҳ��������ҳ�������е�һЩ��־λ��

 39 #define PAGE_DIRTY      0x40              // λ6��ҳ���ࣨ���޸ģ���

 40 #define PAGE_ACCESSED   0x20              // λ5��ҳ�汻���ʹ���

 41 #define PAGE_USER       0x04              // λ2��ҳ�����ڣ�1-�û���0-�����û���

 42 #define PAGE_RW         0x02              // λ1����дȨ��1�Cд��0�C����

 43 #define PAGE_PRESENT    0x01              // λ0��ҳ����ڣ�1-���ڣ�0-�����ڡ�

 44

 45 #endif

 46


 


 

14.26 ����14-26 linux/include/linux/sched.h


  1 #ifndef _SCHED_H

  2 #define _SCHED_H

  3

  4 #define HZ 100                           // ����ϵͳʱ�ӵδ�Ƶ��(1�ٺ��ȣ�ÿ���δ�10ms)

  5

  6 #define NR_TASKS        64               // ϵͳ��ͬʱ������񣨽��̣�����

  7 #define TASK_SIZE       0x04000000       // ÿ������ij��ȣ�64MB����

  8 #define LIBRARY_SIZE    0x00400000       // ��̬���ؿⳤ�ȣ�4MB����

  9

 10 #if (TASK_SIZE & 0x3fffff)

 11 #error "TASK_SIZE must be multiple of 4M"       // ���񳤶ȱ�����4MB�ı�����

 12 #endif

 13

 14 #if (LIBRARY_SIZE & 0x3fffff)

 15 #error "LIBRARY_SIZE must be a multiple of 4M"  // �ⳤ��Ҳ������4MB�ı�����

 16 #endif

 17

 18 #if (LIBRARY_SIZE >= (TASK_SIZE/2))

 19 #error "LIBRARY_SIZE too damn big!"             // ���ؿ�ij��Ȳ��ô������񳤶ȵ�һ�롣

 20 #endif

 21

 22 #if (((TASK_SIZE>>16)*NR_TASKS) != 0x10000)

 23 #error "TASK_SIZE*NR_TASKS must be 4GB"         // ���񳤶�*�����ܸ�������Ϊ4GB��

 24 #endif

 25

    // �ڽ����߼���ַ�ռ��ж�̬�ⱻ���ص�λ�ã�60MB������

 26 #define LIBRARY_OFFSET (TASK_SIZE - LIBRARY_SIZE)

 27

    // �����CT_TO_SECS ��CT_TO_USECS���ڰ�ϵͳ��ǰ�����ת��������ֵ��΢��ֵ��ʾ��

 28 #define CT_TO_SECS(x)   ((x) / HZ)

 29 #define CT_TO_USECS(x)  (((x) % HZ) * 1000000/HZ)

 30

 31 #define FIRST_TASK task[0]             // ����0�Ƚ����⣬�������������������һ�����š�

 32 #define LAST_TASK task[NR_TASKS-1]     // ���������е����һ������

 33

 34 #include <linux/head.h>

 35 #include <linux/fs.h>

 36 #include <linux/mm.h>

 37 #include <sys/param.h>

 38 #include <sys/time.h>

 39 #include <sys/resource.h>

 40 #include <signal.h>

 41

 42 #if (NR_OPEN > 32)

 43 #error "Currently the close-on-exec-flags and select masks are in one long, max 32 files/proc"

 44 #endif

 45

    // ���ﶨ���˽�������ʱ���ܴ���״̬��

 46 #define TASK_RUNNING            0   // �����������л���׼��������

 47 #define TASK_INTERRUPTIBLE      1   // ���̴��ڿ��жϵȴ�״̬��

 48 #define TASK_UNINTERRUPTIBLE    2   // ���̴��ڲ����жϵȴ�״̬����Ҫ����I/O�����ȴ���

 49 #define TASK_ZOMBIE             3   // ���̴��ڽ���״̬���Ѿ�ֹͣ���У��������̻�û���źš�

 50 #define TASK_STOPPED            4   // ������ֹͣ��

 51

 52 #ifndef NULL

 53 #define NULL ((void *) 0)           // ����NULLΪ��ָ�롣

 54 #endif

 55

    // ���ƽ��̵�ҳĿ¼ҳ����Linus��Ϊ�����ں�����ӵĺ���֮һ��( mm/memory.c, 105 )

 56 extern int copy_page_tables(unsigned long from, unsigned long to, long size);

    // �ͷ�ҳ����ָ�����ڴ�鼰ҳ��������( mm/memory.c, 150 )

 57 extern int free_page_tables(unsigned long from, unsigned long size);

 58

    // ���ȳ���ij�ʼ��������( kernel/sched.c, 385 )

 59 extern void sched_init(void);

    // ���̵��Ⱥ�����( kernel/sched.c, 104 )

 60 extern void schedule(void);

    // �쳣(����)�жϴ�����ʼ�������������жϵ����Ų������ж������źš�( kernel/traps.c, 181 )

 61 extern void trap_init(void);

    // ��ʾ�ں˳�����Ϣ��Ȼ�������ѭ����( kernel/panic.c, 16 )��

 62 extern void panic(const char * str);

    // ��tty��дָ�����ȵ��ַ�����( kernel/chr_drv/tty_io.c, 290 )��

 63 extern int tty_write(unsigned minor,char * buf,int count);

 64

 65 typedef int (*fn_ptr)();                   // ���庯��ָ�����͡�

 66

    // ��������ѧЭ������ʹ�õĽṹ����Ҫ���ڱ�������л�ʱi387��ִ��״̬��Ϣ��

 67 struct i387_struct {

 68         long    cwd;            // ������(Control word)��

 69         long    swd;            // ״̬��(Status word)��

 70         long    twd;            // �����(Tag word)��

 71         long    fip;            // Э����������ָ�롣

 72         long    fcs;            // Э����������μĴ�����

 73         long    foo;            // �ڴ��������ƫ��λ�á�

 74         long    fos;            // �ڴ�������Ķ�ֵ��

 75         long    st_space[20];   /* 8*10 bytes for each FP-reg = 80 bytes */

 76 };                              /* 8��10�ֽڵ�Э�������ۼ�����*/

 77

    // ����״̬�����ݽṹ��

 78 struct tss_struct {

 79         long    back_link;      /* 16 high bits zero */

 80         long    esp0;

 81         long    ss0;            /* 16 high bits zero */

 82         long    esp1;

 83         long    ss1;            /* 16 high bits zero */

 84         long    esp2;

 85         long    ss2;            /* 16 high bits zero */

 86         long    cr3;

 87         long    eip;

 88         long    eflags;

 89         long    eax,ecx,edx,ebx;

 90         long    esp;

 91         long    ebp;

 92         long    esi;

 93         long    edi;

 94         long    es;             /* 16 high bits zero */

 95         long    cs;             /* 16 high bits zero */

 96         long    ss;             /* 16 high bits zero */

 97         long    ds;             /* 16 high bits zero */

 98         long    fs;             /* 16 high bits zero */

 99         long    gs;             /* 16 high bits zero */

100         long    ldt;            /* 16 high bits zero */

101         long    trace_bitmap;   /* bits: trace 0, bitmap 16-31 */

102         struct i387_struct i387;

103 };

104

    // ���������񣨽��̣����ݽṹ�����Ϊ������������

    // long state                    ���������״̬��-1�������У�0������(����)��>0��ֹͣ����

    // long counter                  ��������ʱ�����(�ݼ�)���δ�����������ʱ��Ƭ��

    // long priority                 ������������ʼ����ʱcounter=priority��Խ������Խ����

    // long signal                   �ź�λͼ��ÿ������λ����һ���źţ��ź�ֵ=λƫ��ֵ+1��

    // struct sigaction sigaction[32]   �ź�ִ�����Խṹ����Ӧ�źŽ�Ҫִ�еIJ����ͱ�־��Ϣ��

    // long blocked                  �����ź������루��Ӧ�ź�λͼ����

    // -------------------

    // int exit_code                 ����ִ��ֹͣ���˳��룬�丸���̻�ȡ��

    // unsigned long start_code      ����ε�ַ��

    // unsigned long end_code        ���볤�ȣ��ֽ�������

    // unsigned long end_data        ���볤�� + ���ݳ��ȣ��ֽ�������

    // unsigned long brk             �ܳ��ȣ��ֽ�������

    // unsigned long start_stack     ��ջ�ε�ַ��

    // long pid                      ���̱�ʶ��(���̺�)��

    // long pgrp                     ������š�

    // long session                  �Ự�š�

    // long leader                   �Ự���졣

    // int groups[NGROUPS]           ����������š�һ�����̿����ڶ���顣

    // task_struct *p_pptr           ָ�򸸽��̵�ָ�롣

    // task_struct *p_cptr           ָ�������ӽ��̵�ָ�롣

    // task_struct *p_ysptr          ָ����Լ��󴴽������ڽ��̵�ָ�롣

    // task_struct *p_osptr          ָ����Լ��紴�������ڽ��̵�ָ�롣

    // unsigned short uid            �û���ʶ�ţ��û�id����

    // unsigned short euid           ��Ч�û�id��

    // unsigned short suid           ������û�id��

    // unsigned short gid            ���ʶ�ţ���id����

    // unsigned short egid           ��Ч��id��

    // unsigned short sgid           �������id��

    // long timeout                  �ں˶�ʱ��ʱֵ��

    // long alarm                    ������ʱֵ���δ�������

    // long utime                    �û�̬����ʱ�䣨�δ�������

    // long stime                    ϵͳ̬����ʱ�䣨�δ�������

    // long cutime                   �ӽ����û�̬����ʱ�䡣

    // long cstime                   �ӽ���ϵͳ̬����ʱ�䡣

    // long start_time               ���̿�ʼ����ʱ�̡�

    // struct rlimit rlim[RLIM_NLIMITS]  ������Դʹ��ͳ�����顣

    // unsigned int flags;           �����̵ı�־���������149�п�ʼ���壨��δʹ�ã���

    // unsigned short used_math      ��־���Ƿ�ʹ����Э��������

    // ------------------------

    // int tty                       ����ʹ��tty�ն˵����豸�š�-1��ʾû��ʹ�á�

    // unsigned short umask          �ļ�������������λ��

    // struct m_inode * pwd          ��ǰ����Ŀ¼i�ڵ�ṹָ�롣

    // struct m_inode * root         ��Ŀ¼i�ڵ�ṹָ�롣

    // struct m_inode * executable   ִ���ļ�i�ڵ�ṹָ�롣

    // struct m_inode * library      �����ؿ��ļ�i�ڵ�ṹָ�롣

    // unsigned long close_on_exec   ִ��ʱ�ر��ļ����λͼ��־�����μ�include/fcntl.h��

    // struct file * filp[NR_OPEN]   �ļ��ṹָ��������32�����ż����ļ���������ֵ��

    // struct desc_struct ldt[3]     �ֲ�����������0-�գ�1-�����cs��2-���ݺͶ�ջ��ds&ss��

    // struct tss_struct tss         ���̵�����״̬����Ϣ�ṹ��

    // ======================================

105 struct task_struct {

106 /* these are hardcoded - don't touch */

107         long state;     /* -1 unrunnable, 0 runnable, >0 stopped */

108         long counter;

109         long priority;

110         long signal;

111         struct sigaction sigaction[32];

112         long blocked;   /* bitmap of masked signals */

113 /* various fields */

114         int exit_code;

115         unsigned long start_code,end_code,end_data,brk,start_stack;

116         long pid,pgrp,session,leader;

117         int     groups[NGROUPS];

118         /*

119          * pointers to parent process, youngest child, younger sibling,

120          * older sibling, respectively.  (p->father can be replaced with

121          * p->p_pptr->pid)

122          */

123         struct task_struct      *p_pptr, *p_cptr, *p_ysptr, *p_osptr;

124         unsigned short uid,euid,suid;

125         unsigned short gid,egid,sgid;

126         unsigned long timeout,alarm;

127         long utime,stime,cutime,cstime,start_time;

128         struct rlimit rlim[RLIM_NLIMITS];

129         unsigned int flags;     /* per process flags, defined below */

130         unsigned short used_math;

131 /* file system info */

132         int tty;                /* -1 if no tty, so it must be signed */

133         unsigned short umask;

134         struct m_inode * pwd;

135         struct m_inode * root;

136         struct m_inode * executable;

137         struct m_inode * library;

138         unsigned long close_on_exec;

139         struct file * filp[NR_OPEN];

140 /* ldt for this task 0 - zero 1 - cs 2 - ds&ss */

141         struct desc_struct ldt[3];

142 /* tss for this task */

143         struct tss_struct tss;

144 };

145

146 /*

147  * Per process flags

148  */

    /* ÿ�����̵ı�־ */  /* ��ӡ���뾯����Ϣ����δʵ�֣�������486 */

149 #define PF_ALIGNWARN    0x00000001      /* Print alignment warning msgs */

150                                         /* Not implemented yet, only for 486*/

151

152 /*

153  *  INIT_TASK is used to set up the first task table, touch at

154  * your own risk!. Base=0, limit=0x9ffff (=640kB)

155  */

    /*

     * INIT_TASK�������õ�1��������������޸ģ������Ը�J��

     * ��ַBase = 0���γ�limit = 0x9ffff��=640kB����

     */

    // ��Ӧ��������ṹ�ĵ�1���������Ϣ��

156 #define INIT_TASK \

157 /* state etc */ { 0,15,15, \      // state, counter, priority

158 /* signals */   0,{{},},0, \      // signal, sigaction[32], blocked

159 /* ec,brk... */ 0,0,0,0,0,0, \  // exit_code,start_code,end_code,end_data,brk,start_stack

160 /* pid etc.. */ 0,0,0,0, \        // pid, pgrp, session, leader

161 /* suppl grps*/ {NOGROUP,}, \     // groups[]

162 /* proc links*/ &init_task.task,0,0,0, \    // p_pptr, p_cptr, p_ysptr, p_osptr

163 /* uid etc */   0,0,0,0,0,0, \    // uid, euid, suid, gid, egid, sgid

164 /* timeout */   0,0,0,0,0,0,0, \  // alarm,utime,stime,cutime,cstime,start_time,used_math

165 /* rlimits */   { {0x7fffffff, 0x7fffffff}, {0x7fffffff, 0x7fffffff},  \

166                   {0x7fffffff, 0x7fffffff}, {0x7fffffff, 0x7fffffff}, \

167                   {0x7fffffff, 0x7fffffff}, {0x7fffffff, 0x7fffffff}}, \

168 /* flags */     0, \            // flags

169 /* math */      0, \            // used_math, tty,umask,pwd,root,executable,close_on_exec

170 /* fs info */   -1,0022,NULL,NULL,NULL,NULL,0, \

171 /* filp */      {NULL,}, \      // filp[20]

172         { \                     // ldt[3]

173                 {0,0}, \

174 /* ldt */       {0x9f,0xc0fa00}, \  // ���볤640K����ַ0x0��G=1��D=1��DPL=3��P=1 TYPE=0xa

175                 {0x9f,0xc0f200}, \  // ���ݳ�640K����ַ0x0��G=1��D=1��DPL=3��P=1 TYPE=0x2

176         }, \

177 /*tss*/ {0,PAGE_SIZE+(long)&init_task,0x10,0,0,0,0,(long)&pg_dir,\       // tss

178          0,0,0,0,0,0,0,0, \

179          0,0,0x17,0x17,0x17,0x17,0x17,0x17, \

180          _LDT(0),0x80000000, \

181                 {} \

182         }, \

183 }

184

185 extern struct task_struct *task[NR_TASKS];      // ����ָ�����顣

186 extern struct task_struct *last_task_used_math; // ��һ��ʹ�ù�Э�������Ľ��̡�

187 extern struct task_struct *current;             // ��ǰ���н��̽ṹָ�������

188 extern unsigned long volatile jiffies;          // �ӿ�����ʼ����ĵδ�����10ms/�δ𣩡�

189 extern unsigned long startup_time;              // ����ʱ�䡣��1970:0:0:0��ʼ��ʱ��������

190 extern int jiffies_offset;                      // �����ۼ���Ҫ������ʱ���������

191

192 #define CURRENT_TIME (startup_time+(jiffies+jiffies_offset)/HZ)  // ��ǰʱ�䣨��������

193

    // ���Ӷ�ʱ����������ʱʱ��jiffies�δ�������ʱ��ʱ���ú���*fn()����( kernel/sched.c )

194 extern void add_timer(long jiffies, void (*fn)(void));

    // �����жϵĵȴ�˯�ߡ�( kernel/sched.c )

195 extern void sleep_on(struct task_struct ** p);

    // ���жϵĵȴ�˯�ߡ�( kernel/sched.c )

196 extern void interruptible_sleep_on(struct task_struct ** p);

    // ��ȷ����˯�ߵĽ��̡�( kernel/sched.c )

197 extern void wake_up(struct task_struct ** p);

    // ��鵱ǰ�����Ƿ���ָ�����û���grp�С�

198 extern int in_group_p(gid_t grp);

199

200 /*

201  * Entry into gdt where to find first TSS. 0-nul, 1-cs, 2-ds, 3-syscall

202  * 4-TSS0, 5-LDT0, 6-TSS1 etc ...

203  */

    /*

     * Ѱ�ҵ�1��TSS��ȫ�ֱ��е���ڡ�0-û����nul��1-�����cs��2-���ݶ�ds��3-ϵͳ��syscall

     * 4-����״̬��TSS0��5-�ֲ���LTD0��6-����״̬��TSS1���ȡ�

     */

    // �Ӹ�Ӣ��ע�Ϳ��Բ��뵽��Linus��ʱ�����ϵͳ���õĴ���ר�ŷ���GDT���е�4�������Ķ��С�

    // ��������û�������������Ǿ�һֱ��GDT���е�4�������������syscall�������һ�ԡ�

    // ���涨��꣺ȫ�ֱ��е�1������״̬��(TSS)��������ѡ��������š�

204 #define FIRST_TSS_ENTRY 4

    // ȫ�ֱ��е�1���ֲ���������(LDT)��������ѡ��������š�

205 #define FIRST_LDT_ENTRY (FIRST_TSS_ENTRY+1)

    // �궨�壬������ȫ�ֱ��е�n�������TSS����������ѡ���ֵ��ƫ��������

    // ��ÿ��������ռ8�ֽڣ����FIRST_TSS_ENTRY<<3 ��ʾ����������GDT���е���ʼƫ��λ�á�

    // ��Ϊÿ������ʹ��1��TSS��1��LDT����������ռ��16�ֽڣ������Ҫ n<<4 ����ʾ��Ӧ

    // TSS��ʼλ�á��ú�õ���ֵ����Ҳ�Ǹ�TSS��ѡ���ֵ��

206 #define _TSS(n) ((((unsigned long) n)<<4)+(FIRST_TSS_ENTRY<<3))

    // �궨�壬������ȫ�ֱ��е�n�������LDT����������ѡ���ֵ��ƫ��������

207 #define _LDT(n) ((((unsigned long) n)<<4)+(FIRST_LDT_ENTRY<<3))

    // �궨�壬�ѵ�n�������TSS��ѡ������ص�����Ĵ���TR�С�

208 #define ltr(n) __asm__("ltr %%ax"::"a" (_TSS(n)))

    // �궨�壬�ѵ�n�������LDT��ѡ������ص��ֲ����������Ĵ���LDTR�С�

209 #define lldt(n) __asm__("lldt %%ax"::"a" (_LDT(n)))

    // ȡ��ǰ�������������ţ������������е�����ֵ������̺�pid��ͬ����

    // ���أ�n - ��ǰ����š�����( kernel/traps.c )��

210 #define str(n) \

211 __asm__("str %%ax\n\t" \            // ������Ĵ�����TSS�ε�ѡ������Ƶ�ax�С�

212         "subl %2,%%eax\n\t" \       // (eax - FIRST_TSS_ENTRY*8)��eax

213         "shrl $4,%%eax" \           // (eax/16)��eax = ��ǰ����š�

214         :"=a" (n) \

215         :"a" (0),"i" (FIRST_TSS_ENTRY<<3))

216 /*

217  *      switch_to(n) should switch tasks to task nr n, first

218  * checking that n isn't the current task, in which case it does nothing.

219  * This also clears the TS-flag if the task we switched to has used

220  * tha math co-processor latest.

221  */

    /*

     * switch_to(n)���л���ǰ��������nr����n�����ȼ������n���ǵ�ǰ����

     * �������ʲôҲ�����˳�����������л���������������ϴ����У�ʹ�ù���ѧ

     * Э�������Ļ������踴λ���ƼĴ���cr0�е�TS��־��

     */

    // ��ת��һ�������TSS��ѡ�����ɵĵ�ַ�������CPU���������л�������

    // ���룺%0 - ָ��__tmp��               %1 - ָ��__tmp.b�������ڴ����TSS��ѡ�����

    //       dx - ������n��TSS��ѡ�����  ecx - ������n������ṹָ��task[n]��

    // ������ʱ���ݽṹ__tmp�����齨177��Զ��ת��far jump��ָ��IJ��������ò�������4�ֽ�

    // ƫ�Ƶ�ַ��2�ֽڵĶ�ѡ�����ɡ����__tmp��a��ֵ��32λƫ��ֵ����b�ĵ�2�ֽ�����

    // TSS�ε�ѡ�������2�ֽڲ��ã�����ת��TSS��ѡ�������������л�����TSS��Ӧ�Ľ��̡�

    // ������������л��ij���ת��aֵ���á�177���ϵ��ڴ�����תָ��ʹ��6�ֽڲ�������Ϊ��

    // תĿ�ĵصij�ָ�룬���ʽΪ��jmp 16λ��ѡ�����32λƫ��ֵ�������ڴ��в������ı�ʾ˳

    // �������������෴�������л�����֮�����ж�ԭ�����ϴ�ִ���Ƿ�ʹ�ù�Э������ʱ����ͨ��

    // ��ԭ����ָ���뱣����last_task_used_math�����е��ϴ�ʹ�ù�Э����������ָ����бȽ϶�

    // �����ģ��μ��ļ�kernel/sched.c���й�math_state_restore()������˵����

222 #define switch_to(n) {\

223 struct {long a,b;} __tmp; \

224 __asm__("cmpl %%ecx,_current\n\t" \     // ����n�ǵ�ǰ������?(current ==task[n]?)

225         "je 1f\n\t" \                   // �ǣ���ʲô���������˳���

226         "movw %%dx,%1\n\t" \            // ��������TSS��16λѡ�������__tmp.b�С�

227         "xchgl %%ecx,_current\n\t" \    // current = task[n]��ecx = ���л���������

228         "ljmp %0\n\t" \                 // ִ�г���ת��*&__tmp����������л���

                                            // �������л�������Ż����ִ���������䡣

229         "cmpl %%ecx,_last_task_used_math\n\t" \     // ԭ�����ϴ�ʹ�ù�Э��������

230         "jne 1f\n\t" \                  // û������ת���˳���

231         "clts\n" \                      // ԭ�����ϴ�ʹ�ù�Э������������cr0�е�����

232         "1:" \                          // �л���־TS��

233         ::"m" (*&__tmp.a),"m" (*&__tmp.b), \

234         "d" (_TSS(n)),"c" ((long) task[n])); \

235 }

236

    // ҳ���ַ��׼�������ں˴�����û���κεط�����!!��

237 #define PAGE_ALIGN(n) (((n)+0xfff)&0xfffff000)

238

    // ����λ�ڵ�ַaddr���������еĸ�����ַ�ֶ�(����ַ��base)��

    // %0 - ��ַaddrƫ��2��%1 - ��ַaddrƫ��4��%2 - ��ַaddrƫ��7��edx - ����ַbase��

239 #define _set_base(addr,base) \

240 __asm__("movw %%dx,%0\n\t" \           // ��ַbase��16λ(λ15-0)��[addr+2]��

241         "rorl $16,%%edx\n\t" \         // edx�л�ַ��16λ(λ31-16)��dx��

242         "movb %%dl,%1\n\t" \           // ��ַ��16λ�еĵ�8λ(λ23-16)��[addr+4]��

243         "movb %%dh,%2" \               // ��ַ��16λ�еĸ�8λ(λ31-24)��[addr+7]��

244         ::"m" (*((addr)+2)), \

245           "m" (*((addr)+4)), \

246           "m" (*((addr)+7)), \

247           "d" (base) \

248         :"dx")                 // ����gcc������edx�Ĵ����е�ֵ�ѱ�Ƕ�������ı��ˡ�

249

    // ����λ�ڵ�ַaddr���������еĶ��޳��ֶ�(�γ���limit)��

    // %0 - ��ַaddr��%1 - ��ַaddrƫ��6����edx - �γ�ֵlimit��

250 #define _set_limit(addr,limit) \

251 __asm__("movw %%dx,%0\n\t" \           // �γ�limit��16λ(λ15-0)��[addr]��

252         "rorl $16,%%edx\n\t" \         // edx�еĶγ���4λ(λ19-16)��dl��

253         "movb %1,%%dh\n\t" \           // ȡԭ[addr+6]�ֽ���dh�����и�4λ��Щ��־��

254         "andb $0xf0,%%dh\n\t" \        // ��dh�ĵ�4λ(����Ŷγ���λ19-16)��

255         "orb %%dh,%%dl\n\t" \          // ��ԭ��4λ��־�Ͷγ��ĸ�4λ(λ19-16)�ϳ�1�ֽڣ�

256         "movb %%dl,%1" \               // ���Ż�[addr+6]����

257         ::"m" (*(addr)), \

258           "m" (*((addr)+6)), \

259           "d" (limit) \

260         :"dx")

261

    // ���þֲ�����������ldt�������Ļ���ַ�ֶΡ�

262 #define set_base(ldt,base) _set_base( ((char *)&(ldt)) , base )

    // ���þֲ�����������ldt�������Ķγ��ֶΡ�

263 #define set_limit(ldt,limit) _set_limit( ((char *)&(ldt)) , (limit-1)>>12 )

264

    // �ӵ�ַaddr����������ȡ�λ���ַ��������_set_base()�����෴��

    // edx - ��Ż���ַ(__base)��%1 - ��ַaddrƫ��2��%2 - ��ַaddrƫ��4��%3 - addrƫ��7��

265 #define _get_base(addr) ({\

266 unsigned long __base; \

267 __asm__("movb %3,%%dh\n\t" \           // ȡ[addr+7]����ַ��16λ�ĸ�8λ(λ31-24)��dh��

268         "movb %2,%%dl\n\t" \           // ȡ[addr+4]����ַ��16λ�ĵ�8λ(λ23-16)��dl��

269         "shll $16,%%edx\n\t" \         // ����ַ��16λ�Ƶ�edx�и�16λ����

270         "movw %1,%%dx" \               // ȡ[addr+2]����ַ��16λ(λ15-0)��dx��

271         :"=d" (__base) \               // �Ӷ�edx�к���32λ�Ķλ���ַ��

272         :"m" (*((addr)+2)), \

273          "m" (*((addr)+4)), \

274          "m" (*((addr)+7))); \

275 __base;})

276

    // ȡ�ֲ�����������ldt��ָ���������еĻ���ַ��

277 #define get_base(ldt) _get_base( ((char *)&(ldt)) )

278

    // ȡ��ѡ���segmentָ�����������еĶ��޳�ֵ��

    // ָ��lsl��Load Segment Limit��д������ָ������������ȡ����ɢ���޳�����λƴ��������

    // ���޳�ֵ����ָ���Ĵ����С����õĶ��޳���ʵ���ֽ�����1��������ﻹ��Ҫ��1��ŷ��ء�

    // %0 - ��Ŷγ�ֵ(�ֽ���)��%1 - ��ѡ���segment��

279 #define get_limit(segment) ({ \

280 unsigned long __limit; \

281 __asm__("lsll %1,%0\n\tincl %0":"=r" (__limit):"r" (segment)); \

282 __limit;})

283

284 #endif

285


 


 

14.27 ����14-27 linux/include/linux/sys.h


  1 /*

  2  * Why isn't this a .c file?  Enquiring minds....

  3  */

    /*

     * Ϊʲô�ⲻ��һ��.c�ļ��������Խ��Լ�����....

     */

  4

  5 extern int sys_setup();        // 0 - ϵͳ������ʼ�����ú�����   (kernel/blk_drv/hd.c)

  6 extern int sys_exit();         // 1 - �����˳���                 (kernel/exit.c )

  7 extern int sys_fork();         // 2 - �������̡�                 (kernel/system_call.s)

  8 extern int sys_read();         // 3 - ���ļ���                   (fs/read_write.c)

  9 extern int sys_write();        // 4 - д�ļ���                   (fs/read_write.c)

 10 extern int sys_open();         // 5 - ���ļ���                 (fs/open.c)

 11 extern int sys_close();        // 6 - �ر��ļ���                 (fs/open.c)

 12 extern int sys_waitpid();      // 7 - �ȴ�������ֹ��             (kernel/exit.c)

 13 extern int sys_creat();        // 8 - �����ļ���                 (fs/open.c)

 14 extern int sys_link();         // 9 - ����һ���ļ���Ӳ���ӡ�     (fs/namei.c)

 15 extern int sys_unlink();       // 10 - ɾ��һ���ļ���(��ɾ���ļ�)�� (fs/namei.c)

 16 extern int sys_execve();       // 11 - ִ�г���                (kernel/system_call.s)

 17 extern int sys_chdir();        // 12 - ���ĵ�ǰĿ¼��            (fs/open.c)

 18 extern int sys_time();         // 13 - ȡ��ǰʱ�䡣              (kernel/sys.c)

 19 extern int sys_mknod();        // 14 - ������/�ַ������ļ���     (fs/namei.c)

 20 extern int sys_chmod();        // 15 - �޸��ļ����ԡ�            (fs/open.c)

 21 extern int sys_chown();        // 16 - �޸��ļ������������顣    (fs/open.c)

 22 extern int sys_break();        // 17 -                           (kernel/sys.c)*

 23 extern int sys_stat();         // 18 - ʹ��·����ȡ�ļ�״̬��Ϣ��(fs/stat.c)

 24 extern int sys_lseek();        // 19 - ���¶�λ��/д�ļ�ƫ�ơ�   (fs/read_write.c)

 25 extern int sys_getpid();       // 20 - ȡ����id��               (kernel/sched.c)

 26 extern int sys_mount();        // 21 - ��װ�ļ�ϵͳ��            (fs/super.c)

 27 extern int sys_umount();       // 22 - ж���ļ�ϵͳ��            (fs/super.c)

 28 extern int sys_setuid();       // 23 - ���ý����û�id��         (kernel/sys.c)

 29 extern int sys_getuid();       // 24 - ȡ�����û�id��           (kernel/sched.c)

 30 extern int sys_stime();        // 25 - ����ϵͳʱ�����ڡ�        (kernel/sys.c)*

 31 extern int sys_ptrace();       // 26 - ������ԡ�                (kernel/sys.c)*

 32 extern int sys_alarm();        // 27 - ���ñ�����                (kernel/sched.c)

 33 extern int sys_fstat();        // 28 - ʹ���ļ����ȡ�ļ���״̬��Ϣ��(fs/stat.c)

 34 extern int sys_pause();        // 29 - ��ͣ�������С�            (kernel/sched.c)

 35 extern int sys_utime();        // 30 - �ı��ļ��ķ��ʺ��޸�ʱ�䡣(fs/open.c)

 36 extern int sys_stty();         // 31 - �޸��ն������á�          (kernel/sys.c)*

 37 extern int sys_gtty();         // 32 - ȡ�ն���������Ϣ��        (kernel/sys.c)*

 38 extern int sys_access();       // 33 - ����û���һ���ļ��ķ���Ȩ�ޡ�(fs/open.c)

 39 extern int sys_nice();         // 34 - ���ý���ִ������Ȩ��      (kernel/sched.c)

 40 extern int sys_ftime();        // 35 - ȡ���ں�ʱ�䡣            (kernel/sys.c)*

 41 extern int sys_sync();         // 36 - ͬ�����ٻ������豸�����ݡ�(fs/buffer.c)

 42 extern int sys_kill();         // 37 - ��ֹһ�����̡�            (kernel/exit.c)

 43 extern int sys_rename();       // 38 - �����ļ�����              (kernel/sys.c)*

 44 extern int sys_mkdir();        // 39 - ����Ŀ¼��                (fs/namei.c)

 45 extern int sys_rmdir();        // 40 - ɾ��Ŀ¼��                (fs/namei.c)

 46 extern int sys_dup();          // 41 - �����ļ������            (fs/fcntl.c)

 47 extern int sys_pipe();         // 42 - �����ܵ���                (fs/pipe.c)

 48 extern int sys_times();        // 43 - ȡ����ʱ�䡣              (kernel/sys.c)

 49 extern int sys_prof();         // 44 - ����ִ��ʱ������        (kernel/sys.c)*

 50 extern int sys_brk();          // 45 - �޸����ݶγ��ȡ�          (kernel/sys.c)

 51 extern int sys_setgid();       // 46 - ���ý�����id��            (kernel/sys.c)

 52 extern int sys_getgid();       // 47 - ȡ������id��              (kernel/sched.c)

 53 extern int sys_signal();       // 48 - �źŴ�����                (kernel/signal.c)

 54 extern int sys_geteuid();      // 49 - ȡ������Ч�û�id��        (kenrl/sched.c)

 55 extern int sys_getegid();      // 50 - ȡ������Ч��id��          (kenrl/sched.c)

 56 extern int sys_acct();         // 51 - ���̼��ʡ�                (kernel/sys.c)*

 57 extern int sys_phys();         // 52 -                           (kernel/sys.c)*

 58 extern int sys_lock();         // 53 -                           (kernel/sys.c)*

 59 extern int sys_ioctl();        // 54 - �豸����������ơ�        (fs/ioctl.c)

 60 extern int sys_fcntl();        // 55 - �ļ�������Ʋ�����        (fs/fcntl.c)

 61 extern int sys_mpx();          // 56 -                           (kernel/sys.c)*

 62 extern int sys_setpgid();      // 57 - ���ý�����id��            (kernel/sys.c)

 63 extern int sys_ulimit();       // 58 - ͳ�ƽ���ʹ����Դ�����     (kernel/sys.c)

 64 extern int sys_uname();        // 59 - ��ʾϵͳ��Ϣ��             (kernel/sys.c)

 65 extern int sys_umask();        // 60 - ȡĬ���ļ����������롣     (kernel/sys.c)

 66 extern int sys_chroot();       // 61 - �ı��Ŀ¼��               (fs/open.c)

 67 extern int sys_ustat();        // 62 - ȡ�ļ�ϵͳ��Ϣ��           (fs/open.c)

 68 extern int sys_dup2();         // 63 - �����ļ������             (fs/fcntl.c)

 69 extern int sys_getppid();      // 64 - ȡ������id��              (kernel/sched.c)

 70 extern int sys_getpgrp();      // 65 - ȡ������id������getpgid(0)��(kernel/sys.c)

 71 extern int sys_setsid();       // 66 - ���»Ự�����г���       (kernel/sys.c)

 72 extern int sys_sigaction();    // 67 - �ı��źŴ������̡�         (kernel/signal.c)

 73 extern int sys_sgetmask();     // 68 - ȡ�ź������롣             (kernel/signal.c)

 74 extern int sys_ssetmask();     // 69 - �����ź������롣           (kernel/signal.c)

 75 extern int sys_setreuid();     // 70 - ������ʵ��/����Ч�û�id��  (kernel/sys.c)

 76 extern int sys_setregid();     // 71 - ������ʵ��/����Ч��id��    (kernel/sys.c)

 77 extern int sys_sigpending();   // 73 - �����δ�������źš�       (kernel/signal.c)

 78 extern int sys_sigsuspend();   // 72 - ʹ���������������̡�     (kernel/signal.c)

 79 extern int sys_sethostname();  // 74 - ������������               (kernel/sys.c)

 80 extern int sys_setrlimit();    // 75 - ������Դʹ�����ơ�         (kernel/sys.c)

 81 extern int sys_getrlimit();    // 76 - ȡ�ý���ʹ����Դ�����ơ�   (kernel/sys.c)

 82 extern int sys_getrusage();    // 77 -

 83 extern int sys_gettimeofday(); // 78 - ��ȡ����ʱ�䡣             (kernel/sys.c)

 84 extern int sys_settimeofday(); // 79 - ���õ���ʱ�䡣             (kernel/sys.c)

 85 extern int sys_getgroups();    // 80 - ȡ�ý����������ʶ�š�     (kernel/sys.c)

 86 extern int sys_setgroups();    // 81 - ���ý������ʶ�����顣     (kernel/sys.c)

 87 extern int sys_select();       // 82 - �ȴ��ļ�������״̬�ı䡣   (fs/select.c)

 88 extern int sys_symlink();      // 83 - �����������ӡ�             (fs/namei.c��767)

 89 extern int sys_lstat();        // 84 - ȡ���������ļ�״̬��       (fs/stat.c��47)

 90 extern int sys_readlink();     // 85 - ��ȡ���������ļ���Ϣ��     (fs/stat.c��69)

 91 extern int sys_uselib();       // 86 - ѡ�����⡣               (fs/exec.c, 42)

 92

    // ϵͳ���ú���ָ���������ϵͳ�����жϴ�������(int 0x80)����Ϊ��ת����

 93 fn_ptr sys_call_table[] = { sys_setup, sys_exit, sys_fork, sys_read,

 94 sys_write, sys_open, sys_close, sys_waitpid, sys_creat, sys_link,

 95 sys_unlink, sys_execve, sys_chdir, sys_time, sys_mknod, sys_chmod,

 96 sys_chown, sys_break, sys_stat, sys_lseek, sys_getpid, sys_mount,

 97 sys_umount, sys_setuid, sys_getuid, sys_stime, sys_ptrace, sys_alarm,

 98 sys_fstat, sys_pause, sys_utime, sys_stty, sys_gtty, sys_access,

 99 sys_nice, sys_ftime, sys_sync, sys_kill, sys_rename, sys_mkdir,

100 sys_rmdir, sys_dup, sys_pipe, sys_times, sys_prof, sys_brk, sys_setgid,

101 sys_getgid, sys_signal, sys_geteuid, sys_getegid, sys_acct, sys_phys,

102 sys_lock, sys_ioctl, sys_fcntl, sys_mpx, sys_setpgid, sys_ulimit,

103 sys_uname, sys_umask, sys_chroot, sys_ustat, sys_dup2, sys_getppid,

104 sys_getpgrp, sys_setsid, sys_sigaction, sys_sgetmask, sys_ssetmask,

105 sys_setreuid,sys_setregid, sys_sigsuspend, sys_sigpending, sys_sethostname,

106 sys_setrlimit, sys_getrlimit, sys_getrusage, sys_gettimeofday,

107 sys_settimeofday, sys_getgroups, sys_setgroups, sys_select, sys_symlink,

108 sys_lstat, sys_readlink, sys_uselib };

109

110 /* So we don't have to do any more manual updating.... */

    /* ����������������Ǿ������ֹ�����ϵͳ������Ŀ�� */

111 int NR_syscalls = sizeof(sys_call_table)/sizeof(fn_ptr);

112


 


 

14.28 ����14-28 linux/include/linux/tty.h


  1 /*

  2  * 'tty.h' defines some structures used by tty_io.c and some defines.

  3  *

  4  * NOTE! Don't touch this without checking that nothing in rs_io.s or

  5  * con_io.s breaks. Some constants are hardwired into the system (mainly

  6  * offsets into 'tty_queue'

  7  */

    /*

     * 'tty.h'�ж�����tty_io.c����ʹ�õ�ijЩ�ṹ������һЩ���塣

     *

     * ע�⣡���޸�����Ķ���ʱ��һ��Ҫ���rs_io.s��con_io.s�����в���������⡣

     * ��ϵͳ����Щ������ֱ��д�ڳ����еģ���Ҫ��һЩtty_queue�е�ƫ��ֵ����

     */

  8

  9 #ifndef _TTY_H

 10 #define _TTY_H

 11

 12 #define MAX_CONSOLES    8         // ����������̨������

 13 #define NR_SERIALS      2         // �����ն�������

 14 #define NR_PTYS         4         // α�ն�������

 15

 16 extern int NR_CONSOLES;           // �������̨������

 17

 18 #include <termios.h>       // �ն������������ͷ�ļ�����Ҫ��������첽ͨ�ſڵ��ն˽ӿڡ�

 19

 20 #define TTY_BUF_SIZE 1024        // tty��������������У���С��

 21

    // tty�ַ�����������ݽṹ������tty_struc�ṹ�еĶ���д�͸������淶��������С�

 22 struct tty_queue {

 23         unsigned long data;              // ���л������к����ַ�����ֵ�����ǵ�ǰ�ַ�������

                                             // ���ڴ����նˣ����Ŵ��ж˿ڵ�ַ��

 24         unsigned long head;              // ������������ͷָ�롣

 25         unsigned long tail;              // ������������βָ�롣

 26         struct task_struct * proc_list;  // �ȴ������еĽ����б���

 27         char buf[TTY_BUF_SIZE];          // ���еĻ�������

 28 };

 29

 30 #define IS_A_CONSOLE(min)       (((min) & 0xC0) == 0x00)        // ��һ�������նˡ�

 31 #define IS_A_SERIAL(min)        (((min) & 0xC0) == 0x40)        // ��һ�������նˡ�

 32 #define IS_A_PTY(min)           ((min) & 0x80)                  // ��һ��α�նˡ�

 33 #define IS_A_PTY_MASTER(min)    (((min) & 0xC0) == 0x80)        // ��һ����α�նˡ�

 34 #define IS_A_PTY_SLAVE(min)     (((min) & 0xC0) == 0xC0)        // ��һ����α�նˡ�

 35 #define PTY_OTHER(min)          ((min) ^ 0x40)                  // ����α�նˡ�

 36

    // ���¶�����tty�ȴ������л����������꺯������tail��ǰ��head�ں󣬲μ�tty_io.c��ͼ����

    // a������ָ��ǰ��1�ֽڣ����ѳ����������Ҳ࣬��ָ��ѭ����

 37 #define INC(a) ((a) = ((a)+1) & (TTY_BUF_SIZE-1))

    // a������ָ�����1�ֽڣ���ѭ����

 38 #define DEC(a) ((a) = ((a)-1) & (TTY_BUF_SIZE-1))

    // ���ָ�����еĻ�������

 39 #define EMPTY(a) ((a)->head == (a)->tail)

    // ���������ɴ���ַ��ij��ȣ����������ȣ���

 40 #define LEFT(a) (((a)->tail-(a)->head-1)&(TTY_BUF_SIZE-1))

    // �����������һ��λ�á�

 41 #define LAST(a) ((a)->buf[(TTY_BUF_SIZE-1)&((a)->head-1)])

    // �������������Ϊ1�Ļ�����

 42 #define FULL(a) (!LEFT(a))

    // ���������Ѵ���ַ��ij��ȣ��ַ�������

 43 #define CHARS(a) (((a)->head-(a)->tail)&(TTY_BUF_SIZE-1))

    // ��queue�����������ȡһ�ַ�(��tail��������tail+=1)��

 44 #define GETCH(queue,c) \

 45 (void)({c=(queue)->buf[(queue)->tail];INC((queue)->tail);})

    // ��queue����������з���һ�ַ�����head��������head+=1����

 46 #define PUTCH(c,queue) \

 47 (void)({(queue)->buf[(queue)->head]=(c);INC((queue)->head);})

 48

    // �ж��ն˼����ַ����͡�

 49 #define INTR_CHAR(tty) ((tty)->termios.c_cc[VINTR])     // �жϷ������ж��ź�SIGINT��

 50 #define QUIT_CHAR(tty) ((tty)->termios.c_cc[VQUIT])     // �˳��������˳��ź�SIGQUIT��

 51 #define ERASE_CHAR(tty) ((tty)->termios.c_cc[VERASE])   // ������������һ���ַ���

 52 #define KILL_CHAR(tty) ((tty)->termios.c_cc[VKILL])     // ɾ���С�ɾ��һ���ַ���

 53 #define EOF_CHAR(tty) ((tty)->termios.c_cc[VEOF])       // �ļ���������

 54 #define START_CHAR(tty) ((tty)->termios.c_cc[VSTART])   // ��ʼ�����ָ������

 55 #define STOP_CHAR(tty) ((tty)->termios.c_cc[VSTOP])     // ֹͣ����ֹͣ�����

 56 #define SUSPEND_CHAR(tty) ((tty)->termios.c_cc[VSUSP])  // ��������������ź�SIGTSTP��

 57

    // tty���ݽṹ��

 58 struct tty_struct {

 59         struct termios termios;                   // �ն�io���ԺͿ����ַ����ݽṹ��

 60         int pgrp;                                 // ���������顣

 61         int session;                              // �Ự�š�

 62         int stopped;                              // ֹͣ��־��

 63         void (*write)(struct tty_struct * tty);   // ttyд����ָ�롣

 64         struct tty_queue *read_q;                 // tty�����С�

 65         struct tty_queue *write_q;                // ttyд���С�

 66         struct tty_queue *secondary;              // tty��������(��Ź淶ģʽ�ַ�����)��

 67         };                                        // �ɳ�Ϊ�淶(��)ģʽ���С�

 68

 69 extern struct tty_struct tty_table[];             // tty�ṹ���顣

 70 extern int fg_console;                            // ǰ̨����̨�š�

 71

    // �����ն�������tty_table[] ��ȡ��Ӧ�ն˺�nr��tty �ṹָ�롣��73�к�벿������

    // �������豸��dev��tty_table[]����ѡ���Ӧ��tty�ṹ�����dev = 0����ʾ����ʹ��

    // ǰ̨�նˣ����ֱ��ʹ���ն˺�fg_console ��Ϊ tty_table[] ������ȡ tty�ṹ�����

    // dev����0����ô��Ҫ������������ǣ��� dev �������ն˺ţ��� dev �Ǵ����ն˺Ż���

    // α�ն˺š����������ն���tty�ṹ�� tty_table[]���������� dev-1��0 -- 63��������

    // ���������նˣ������ǵ� tty�ṹ��������� dev�����磬���dev = 64����ʾ��һ����

    // ���ն�1������tty �ṹ���� ttb_table[dev]�� ���dev = 1�����Ӧ�ն˵�tty�ṹ��

    // tty_table[0]���μ�tty_io.c�����70 -- 73�С�

 72 #define TTY_TABLE(nr) \

 73 (tty_table + ((nr) ? (((nr) < 64)? (nr)-1:(nr)) : fg_console))

 74

    // ����������ն�termios�ṹ�пɸ��ĵ������ַ�����c_cc[]�ij�ʼֵ����termios�ṹ

    // ������include/termios.h�С�POSIX.1������11�������ַ�������Linuxϵͳ�����ⶨ

    // ����SVR4ʹ�õ�6�������ַ������������_POSIX_VDISABLE��\0������ô��ijһ��ֵ��

    // ��_POSIX_VDISABLE��ֵʱ����ʾ��ֹʹ����Ӧ�������ַ���[8����ֵ]

 75 /*      intr=^C         quit=^|         erase=del       kill=^U

 76         eof=^D          vtime=\0        vmin=\1         sxtc=\0

 77         start=^Q        stop=^S         susp=^Z         eol=\0

 78         reprint=^R      discard=^U      werase=^W       lnext=^V

 79         eol2=\0

 80 */

    /* �ж�intr=^C     �˳�quit=^|     ɾ��erase=del     ��ֹkill=^U

     * �ļ�����eof=^D  vtime=\0         vmin=\1           sxtc=\0

     * ��ʼstart=^Q    ֹͣstop=^S     ����susp=^Z       �н���eol=\0

     * ����reprint=^R  ����discard=^U  werase=^W          lnext=^V

     * �н���eol2=\0

     */

 81 #define INIT_C_CC "\003\034\177\025\004\0\1\0\021\023\032\0\022\017\027\026\0"

 82

 83 void rs_init(void);       // �첽����ͨ�ų�ʼ����(kernel/chr_drv/serial.c)

 84 void con_init(void);      // �����ն˳�ʼ����    (kernel/chr_drv/console.c)

 85 void tty_init(void);      // tty��ʼ����         (kernel/chr_drv/tty_io.c)

 86

 87 int tty_read(unsigned c, char * buf, int n);   // (kernel/chr_drv/tty_io.c)

 88 int tty_write(unsigned c, char * buf, int n);  // (kernel/chr_drv/tty_io.c)

 89

 90 void con_write(struct tty_struct * tty);       // (kernel/chr_drv/console.c)

 91 void rs_write(struct tty_struct * tty);        // (kernel/chr_drv/serial.c)

 92 void mpty_write(struct tty_struct * tty);      // (kernel/chr_drv/pty.c)

 93 void spty_write(struct tty_struct * tty);      // (kernel/chr_drv/pty.c)

 94

 95 void copy_to_cooked(struct tty_struct * tty);  // (kernel/chr_drv/tty_io.c)

 96

 97 void update_screen(void);                      // (kernel/chr_drv/console.c)

 98

 99 #endif

100


 


 

14.29 ����14-29 linux/include/sys/param.h


  1 #ifndef _SYS_PARAM_H

  2 #define _SYS_PARAM_H

  3

  4 #define HZ 100                  // ϵͳʱ��Ƶ�ʣ�ÿ���ж�100�Ρ�

  5 #define EXEC_PAGESIZE 4096      // ҳ���С��

  6

  7 #define NGROUPS         32      /* Max number of groups per user */ /* ÿ������������*/

  8 #define NOGROUP         -1

  9

 10 #define MAXHOSTNAMELEN 8        // ��������󳤶ȣ�8�ֽڡ�

 11

 12 #endif

 13


 

 


 

14.30 ����14-30 linux/include/sys/resource.h


  1 /*

  2  * Resource control/accounting header file for linux

  3  */

    /*

     * Linux��Դ����/���ͷ�ļ���

  4

  5 #ifndef _SYS_RESOURCE_H

  6 #define _SYS_RESOURCE_H

  7

    // ���·��ų����ͽṹ����getrusage()���μ�kernel/sys.c�ļ���412�п�ʼ��

  8 /*

  9  * Definition of struct rusage taken from BSD 4.3 Reno

 10  *

 11  * We don't support all of these yet, but we might as well have them....

 12  * Otherwise, each time we add new items, programs which depend on this

 13  * structure will lose.  This reduces the chances of that happening.

 14  */

    /*

     * rusage�ṹ�Ķ���ȡ��BSD 4.3 Renoϵͳ��

     *

     * �������ڻ�û��֧�ָýṹ�е�������Щ�ֶΣ������ǿ��ܻ�֧�����ǵ�....

     * ����Ļ���ÿ�����������µ��ֶΣ���Щ����������ṹ�ij���ͻ�����⡣

     * ���ڰ������ֶζ����������Ϳ��Ա����������鷢����

     */

    // ������getrusage()�IJ���who��ʹ�õķ��ų�����

 15 #define RUSAGE_SELF     0     // ���ص�ǰ���̵���Դ������Ϣ��

 16 #define RUSAGE_CHILDREN -1    // ���ص�ǰ��������ֹ�͵ȴ��ŵ��ӽ��̵���Դ������Ϣ��

 17

    // rusage�ǽ��̵���Դ����ͳ�ƽṹ������getrusage()����ָ�����̶���Դ���õ�ͳ��ֵ��

    // Linux 0.12�ں˽�ʹ����ǰ�����ֶΣ����Ƕ���timeval�ṹ��include/sys/time.h����

    // ru_utime �C �������û�̬����ʱ��ͳ��ֵ��ru_stime �C �������ں�̬����ʱ��ͳ��ֵ��

 18 struct  rusage {

 19         struct timeval ru_utime;        /* user time used */

 20         struct timeval ru_stime;        /* system time used */

 21         long    ru_maxrss;              /* maximum resident set size */

 22         long    ru_ixrss;               /* integral shared memory size */

 23         long    ru_idrss;               /* integral unshared data size */

 24         long    ru_isrss;               /* integral unshared stack size */

 25         long    ru_minflt;              /* page reclaims */

 26         long    ru_majflt;              /* page faults */

 27         long    ru_nswap;               /* swaps */

 28         long    ru_inblock;             /* block input operations */

 29         long    ru_oublock;             /* block output operations */

 30         long    ru_msgsnd;              /* messages sent */

 31         long    ru_msgrcv;              /* messages received */

 32         long    ru_nsignals;            /* signals received */

 33         long    ru_nvcsw;               /* voluntary context switches */

 34         long    ru_nivcsw;              /* involuntary " */

 35 };

 36

    // ������getrlimit()��setrlimit()ʹ�õķ��ų����ͽṹ��

 37 /*

 38  * Resource limits

 39  */

    /*

     * ��Դ���ơ�

     */

    // ������Linux 0.12�ں������������Դ���࣬��getrlimit()��setrlimit()�е�1������

    // resource ��ȡֵ��Χ�� ��ʵ��Щ���ų������ǽ�������ṹ�� rlim[] �����������ֵ��

    // rlim[]�����ÿһ���һ��rlimit�ṹ���ýṹ�������58�С�

 40

 41 #define RLIMIT_CPU      0          /* CPU time in ms */        /* ʹ�õ�CPUʱ�� */

 42 #define RLIMIT_FSIZE    1          /* Maximum filesize */      /* ����ļ����� */

 43 #define RLIMIT_DATA     2          /* max data size */         /* ������ݳ��� */

 44 #define RLIMIT_STACK    3          /* max stack size */        /* ���ջ���� */

 45 #define RLIMIT_CORE     4          /* max core file size */    /* ���core�ļ����� */

 46 #define RLIMIT_RSS      5          /* max resident set size */ /* ���פ������С */

 47

    // ��������˷���notdef����Ҳ�������·��ų������塣

 48 #ifdef notdef

 49 #define RLIMIT_MEMLOCK  6          /* max locked-in-memory address space*/ /* ������ */

 50 #define RLIMIT_NPROC    7          /* max number of processes */   /* ����ӽ����� */

 51 #define RLIMIT_OFILE    8          /* max number of open files */  /* �����ļ��� */

 52 #endif

 53

    // ������ų���������Linux�����Ƶ���Դ���ࡣRLIM_NLIMITS=6����˽�ǰ��6����Ч��

 54 #define RLIM_NLIMITS    6

 55

    // ��ʾ��Դ���ޣ������޸ġ�

 56 #define RLIM_INFINITY   0x7fffffff

 57

    // ��Դ���޽ṹ��

 58 struct rlimit {

 59         int     rlim_cur;          // ��ǰ��Դ���ƣ���������ƣ�soft limit����

 60         int     rlim_max;          // Ӳ���ƣ�hard limit����

 61 };

 62

 63 #endif /* _SYS_RESOURCE_H */

 64


 


 

14.31 ����14-31 linux/include/sys/stat.h


  1 #ifndef _SYS_STAT_H

  2 #define _SYS_STAT_H

  3

  4 #include <sys/types.h>

  5

  6 struct stat {

  7         dev_t   st_dev;       // �����ļ����豸�š�

  8         ino_t   st_ino;       // �ļ�i�ڵ�š�

  9         umode_t st_mode;      // �ļ����ͺ����ԣ������棩��

 10         nlink_t st_nlink;     // ָ���ļ�����������

 11         uid_t   st_uid;       // �ļ����û�(��ʶ)�š�

 12         gid_t   st_gid;       // �ļ�����š�

 13         dev_t   st_rdev;      // �豸��(����ļ���������ַ��ļ�����ļ�)��

 14         off_t   st_size;      // �ļ���С���ֽ�����������ļ��dz����ļ�����

 15         time_t  st_atime;     // �ϴΣ���󣩷���ʱ�䡣

 16         time_t  st_mtime;     // ����޸�ʱ�䡣

 17         time_t  st_ctime;     // ���ڵ��޸�ʱ�䡣

 18 };

 19

    //

    // ������Ϊst_mode�ֶ����õ�ֵ����ķ������ơ���Щֵ���ð˽��Ʊ�ʾ���μ���12���ļ�

    // ϵͳ��ͼ12-5��i�ڵ������ֶ����ݣ��� Ϊ���ڼ��䣬��Щ�������ƾ�ΪһЩӢ�ĵ��ʵ���

    // ��ĸ����д��϶��ɡ� �������� S_IFMT ��ÿ����ĸ�ֱ�������� State��Inode��File��

    // Mask��Type�������� S_IFREG ����State��Inode��File��REGular������д��ĸ����ϣ�

    // ����S_IRWXU��State��Inode��Read��Write��eXecute��User����ϡ��������ƿ��Դ����ơ�

    // �ļ����ͣ�

 20 #define S_IFMT  00170000      // �ļ����ͱ���λ�����루8���Ʊ�ʾ����

 21 #define S_IFLNK  0120000      // �������ӡ�

 22 #define S_IFREG  0100000      // �����ļ���

 23 #define S_IFBLK  0060000      // �����⣨�豸���ļ��������dev/fd0��

 24 #define S_IFDIR  0040000      // Ŀ¼��

 25 #define S_IFCHR  0020000      // �ַ��豸�ļ���

 26 #define S_IFIFO  0010000      // FIFO�����ļ���

    // �ļ�����λ��

    // S_ISUID���ڲ����ļ���set-user-ID��־�Ƿ���λ�����ñ�־��λ����ִ�и��ļ�ʱ�����̵�

    // ��Ч�û�ID��������Ϊ���ļ��������û�ID��S_ISGID���������ID������ͬ������

 27 #define S_ISUID  0004000    // ִ��ʱ�����û�ID��set-user-ID����

 28 #define S_ISGID  0002000    // ִ��ʱ������ID��set-group-ID����

 29 #define S_ISVTX  0001000    // ����Ŀ¼������ɾ����־��

 30

 31 #define S_ISLNK(m)      (((m) & S_IFMT) == S_IFLNK)   // �����Ƿ���������ļ���

 32 #define S_ISREG(m)      (((m) & S_IFMT) == S_IFREG)   // �����Ƿ񳣹��ļ���

 33 #define S_ISDIR(m)      (((m) & S_IFMT) == S_IFDIR)   // �Ƿ�Ŀ¼�ļ���

 34 #define S_ISCHR(m)      (((m) & S_IFMT) == S_IFCHR)   // �Ƿ��ַ��豸�ļ���

 35 #define S_ISBLK(m)      (((m) & S_IFMT) == S_IFBLK)   // �Ƿ���豸�ļ���

 36 #define S_ISFIFO(m)     (((m) & S_IFMT) == S_IFIFO)   // �Ƿ�FIFO�����ļ���

 37

    // �ļ�����Ȩ�ޣ�

 38 #define S_IRWXU 00700      // �������Զ���д��ִ��/���������������ĸ����User����

 39 #define S_IRUSR 00400      // ���������ɡ�

 40 #define S_IWUSR 00200      // ����д���ɡ�

 41 #define S_IXUSR 00100      // ����ִ��/�������ɡ�

 42

 43 #define S_IRWXG 00070      // ���Ա���Զ���д��ִ��/���������������ĸ����Group����

 44 #define S_IRGRP 00040      // ���Ա�����ɡ�

 45 #define S_IWGRP 00020      // ���Աд���ɡ�

 46 #define S_IXGRP 00010      // ���Աִ��/�������ɡ�

 47

 48 #define S_IRWXO 00007      // �����˶���д��ִ��/�������ɣ����������ĸO����Other����

 49 #define S_IROTH 00004      // �����˶����ɣ����3����ĸ����Other����

 50 #define S_IWOTH 00002      // ������д���ɡ�

 51 #define S_IXOTH 00001      // ������ִ��/�������ɡ�

 52

 53 extern int chmod(const char *_path, mode_t mode);     // �޸��ļ����ԡ�

 54 extern int fstat(int fildes, struct stat *stat_buf);  // ȡָ���ļ�������ļ�״̬��Ϣ��

 55 extern int mkdir(const char *_path, mode_t mode);     // ����Ŀ¼��

 56 extern int mkfifo(const char *_path, mode_t mode);    // �����ܵ��ļ���

 57 extern int stat(const char *filename, struct stat *stat_buf); // ȡָ���ļ������ļ�״̬��Ϣ��

 58 extern mode_t umask(mode_t mask);  // �������������롣

 59

 60 #endif

 61


 


 

14.32 ����14-32 linux/include/sys/time.h


  1 #ifndef _SYS_TIME_H

  2 #define _SYS_TIME_H

  3

  4 /* gettimofday returns this */                      // gettimeofday()�������ظ�ʱ��ṹ��

  5 struct timeval {

  6         long    tv_sec;         /* seconds */       // �롣

  7         long    tv_usec;        /* microseconds */  // ΢�롣

  8 };

  9

    // ʱ�����ṹ��tzΪʱ����Time Zone������д��DST��Daylight Saving Time��������ʱ����д��

 10 struct timezone {

 11         int     tz_minuteswest; /* minutes west of Greenwich */   // ����������������ʱ�䡣

 12         int     tz_dsttime;     /* type of dst correction */      // ����ʱ������ʱ�䡣

 13 };

 14

 15 #define DST_NONE        0       /* not on dst */                  // ������ʱ��

 16 #define DST_USA         1       /* USA style dst */               // USA��ʽ������ʱ��

 17 #define DST_AUST        2       /* Australian style dst */        // ������ʽ������ʱ��

 18 #define DST_WET         3       /* Western European dst */

 19 #define DST_MET         4       /* Middle European dst */

 20 #define DST_EET         5       /* Eastern European dst */

 21 #define DST_CAN         6       /* Canada */

 22 #define DST_GB          7       /* Great Britain and Eire */

 23 #define DST_RUM         8       /* Rumania */

 24 #define DST_TUR         9       /* Turkey */

 25 #define DST_AUSTALT     10      /* Australian style with shift in 1986 */

 26

    // �ļ��������������ú꣬����select()������

 27 #define FD_SET(fd,fdsetp)       (*(fdsetp) |= (1 << (fd)))

 28 #define FD_CLR(fd,fdsetp)       (*(fdsetp) &= ~(1 << (fd)))

 29 #define FD_ISSET(fd,fdsetp)     ((*(fdsetp) >> fd) & 1)

 30 #define FD_ZERO(fdsetp)         (*(fdsetp) = 0)

 31

 32 /*

 33  * Operations on timevals.

 34  *

 35  * NB: timercmp does not work for >= or <=.

 36  */

    // timevalʱ��ṹ�IJ���������

 37 #define timerisset(tvp)         ((tvp)->tv_sec || (tvp)->tv_usec)

 38 #define timercmp(tvp, uvp, cmp) \

 39         ((tvp)->tv_sec cmp (uvp)->tv_sec || \

 40          (tvp)->tv_sec == (uvp)->tv_sec && (tvp)->tv_usec cmp (uvp)->tv_usec)

 41 #define timerclear(tvp)         ((tvp)->tv_sec = (tvp)->tv_usec = 0)

 42

 43 /*

 44  * Names of the interval timers, and structure

 45  * defining a timer setting.

 46  */

    /* �ڲ���ʱ�����ƺͽṹ�����ڶ��嶨ʱ�����á� */

 47 #define ITIMER_REAL     0              // ��ʵ��ʱ��ݼ���

 48 #define ITIMER_VIRTUAL  1              // �Խ�������ʱ��ݼ���

 49 #define ITIMER_PROF     2              // �Խ�������ʱ����ߵ�ϵͳ����ʱ�Խ���ʱ��ݼ���

 50

    // �ڲ�ʱ��ṹ������it��Internal Timer�����ڲ���ʱ������д��

 51 struct  itimerval {

 52         struct  timeval it_interval;    /* timer interval */

 53         struct  timeval it_value;       /* current value */

 54 };

 55

 56 #include <time.h>

 57 #include <sys/types.h>

 58

 59 int gettimeofday(struct timeval * tp, struct timezone * tz);

 60 int select(int width, fd_set * readfds, fd_set * writefds,

 61         fd_set * exceptfds, struct timeval * timeout);

 62

 63 #endif /*_SYS_TIME_H*/

 64


 


 

14.33 ����14-33 linux/include/sys/times.h


  1 #ifndef _TIMES_H

  2 #define _TIMES_H

  3

  4 #include <sys/types.h>     // ����ͷ�ļ��������˻�����ϵͳ�������͡�

  5

  6 struct tms {

  7         time_t tms_utime;  // �û�ʹ�õ�CPUʱ�䡣

  8         time_t tms_stime;  // ϵͳ���ںˣ�CPUʱ�䡣

  9         time_t tms_cutime; // ����ֹ���ӽ���ʹ�õ��û�CPUʱ�䡣

 10         time_t tms_cstime; // ����ֹ���ӽ���ʹ�õ�ϵͳCPUʱ�䡣

 11 };

 12

 13 extern time_t times(struct tms * tp);

 14

 15 #endif

 16


 

 


 

14.34 ����14-34 linux/include/sys/types.h


  1 #ifndef _SYS_TYPES_H

  2 #define _SYS_TYPES_H

  3

  4 #ifndef _SIZE_T

  5 #define _SIZE_T

  6 typedef unsigned int size_t;        // ���ڶ���Ĵ�С�����ȣ���

  7 #endif

  8

  9 #ifndef _TIME_T

 10 #define _TIME_T

 11 typedef long time_t;               // ����ʱ�䣨����ƣ���

 12 #endif

 13

 14 #ifndef _PTRDIFF_T

 15 #define _PTRDIFF_T

 16 typedef long ptrdiff_t;

 17 #endif

 18

 19 #ifndef NULL

 20 #define NULL ((void *) 0)

 21 #endif

 22

 23 typedef int pid_t;                // ���ڽ��̺źͽ�����š�

 24 typedef unsigned short uid_t;     // �����û��ţ��û���ʶ�ţ���

 25 typedef unsigned char gid_t;      // ������š�

 26 typedef unsigned short dev_t;     // �����豸�š�

 27 typedef unsigned short ino_t;     // �����ļ����кš�

 28 typedef unsigned short mode_t;    // ����ijЩ�ļ����ԡ�

 29 typedef unsigned short umode_t;   //

 30 typedef unsigned char nlink_t;    // �������Ӽ�����

 31 typedef int daddr_t;

 32 typedef long off_t;               // �����ļ����ȣ���С����

 33 typedef unsigned char u_char;     // �޷����ַ����͡�

 34 typedef unsigned short ushort;    // �޷��Ŷ��������͡�

 35

 36 typedef unsigned char cc_t;

 37 typedef unsigned int speed_t;

 38 typedef unsigned long tcflag_t;

 39

 40 typedef unsigned long fd_set;     // �ļ�����������ÿ���ش���1����������

 41

 42 typedef struct { int quot,rem; } div_t;    // ����DIV������

 43 typedef struct { long quot,rem; } ldiv_t;  // ���ڳ�DIV������

 44

    // �ļ�ϵͳ�����ṹ������ustat()��������������ֶ�δʹ�ã����Ƿ���NULLָ�롣

 45 struct ustat {

 46         daddr_t f_tfree;              // ϵͳ�ܿ��п�����

 47         ino_t f_tinode;               // �ܿ���i�ڵ�����

 48         char f_fname[6];              // �ļ�ϵͳ���ơ�

 49         char f_fpack[6];              // �ļ�ϵͳѹ�����ơ�

 50 };

 51

 52 #endif

 53


 

 


 

14.35 ����14-35 linux/include/sys/utsname.h


  1 #ifndef _SYS_UTSNAME_H

  2 #define _SYS_UTSNAME_H

  3

  4 #include <sys/types.h>     // ����ͷ�ļ��������˻�����ϵͳ�������͡�

  5 #include <sys/param.h>     // �ں˲����ļ���

  5

  6 struct utsname {

  7         char sysname[9];   // ��ǰ����ϵͳ�����ơ�

  8         char nodename[MAXHOSTNAMELEN+1];  // ��ʵ����ص������нڵ����ƣ��������ƣ���

  9         char release[9];   // ������ϵͳʵ�ֵĵ�ǰ���м���

 10         char version[9];   // ���η��еIJ���ϵͳ�汾����

 11         char machine[9];   // ϵͳ���е�Ӳ���������ơ�

 12 };

 13

 14 extern int uname(struct utsname * utsbuf);

 15

 16 #endif

 17


 


 

14.36 ����14-36 linux/include/sys/wait.h


  1 #ifndef _SYS_WAIT_H

  2 #define _SYS_WAIT_H

  3

  4 #include <sys/types.h>

  5

  6 #define _LOW(v)         ( (v) & 0377)          // ȡ���ֽڣ�8���Ʊ�ʾ����

  7 #define _HIGH(v)        ( ((v) >> 8) & 0377)   // ȡ���ֽڡ�

  8

  9 /* options for waitpid, WUNTRACED not supported */

    /* waitpid��ѡ�����WUNTRACEDδ��֧�� */

    // [ ע����ʵ0.12�ں��Ѿ�֧��WUNTRACEDѡ���������ע��Ӧ������ǰ�ں˰汾���������ġ� ]

    // ���³��������Ǻ���waitpid(pid_t pid, long *stat_addr, int options)��optionsʹ�õ�ѡ�

 10 #define WNOHANG         1      // ���û��״̬Ҳ��Ҫ���𣬲����̷��ء�

 11 #define WUNTRACED       2      // ����ִֹͣ�е��ӽ���״̬��

 12

    // ���º궨�������ж�waitpid()�������ص�״̬�֣���20��21�еIJ���*stat_loc���ĺ��塣

 13 #define WIFEXITED(s)    (!((s)&0xFF)       // ����ӽ��������˳�����Ϊ�档

 14 #define WIFSTOPPED(s)   (((s)&0xFF)==0x7F) // ����ӽ�����ֹͣ�ţ���Ϊtrue��

 15 #define WEXITSTATUS(s)  (((s)>>8)&0xFF)    // �����˳�״̬��

 16 #define WTERMSIG(s)     ((s)&0x7F)         // ���ص��½�����ֹ���ź�ֵ���ź�������

 17 #define WCOREDUMP(s)    ((s)&0x80)         // �жϽ����Ƿ�ִ�����ڴ�ӳ��ת����dumpcore����

 18 #define WSTOPSIG(s)     (((s)>>8)&0xFF)    // ���ص��½���ֹͣ���ź�ֵ��

 19 #define WIFSIGNALED(s)  (((unsigned int)(s)-1 & 0xFFFF) < 0xFF) // �������δ��׽�źŶ�

                                                                    // �����ӽ����˳���Ϊ�档

 20

    // wait()��waitpit()�����������̻�ȡ�����ӽ���֮һ��״̬��Ϣ������ѡ��������ȡ�Ѿ���ֹ��

    // ֹͣ���ӽ���״̬��Ϣ������������������������ӽ��̵�״̬��Ϣ���򱨸��˳���Dz�ָ���ġ�

    // wait()������ǰ���̣�ֱ�����ӽ���֮һ�˳�����ֹ���������յ�Ҫ����ֹ�ý��̵��źţ�

    // ��������Ҫ����һ���źž�����źŴ������򣩡�

    // waitpid()����ǰ���̣�ֱ��pidָ�����ӽ����˳�����ֹ�������յ�Ҫ����ֹ�ý��̵��źţ�

    // ��������Ҫ����һ���źž�����źŴ������򣩡�

    // ���pid= -1��options=0����waitpid()��������wait()����һ������������Ϊ����pid��options

    // �����IJ�ͬ����ͬ�����μ�kernel/exit.c,142��

    // ����pid�ǽ��̺ţ�*stat_loc�DZ���״̬��Ϣλ�õ�ָ�룻options�ǵȴ�ѡ�����10��11�С�

 21 pid_t wait(int *stat_loc);

 22 pid_t waitpid(pid_t pid, int *stat_loc, int options);

 23

 24 #endif

 25


 


 

��15�� �ں˿⺯������

15.1 ����15-1 linux/lib/_exit.c


  1 /*

  2  *  linux/lib/_exit.c

  3  *

  4  *  (C) 1991  Linus Torvalds

  5  */

  6

  7 #define __LIBRARY__       // ����һ�����ų�����������˵����

  8 #include <unistd.h>       // Linux��׼ͷ�ļ��������˸��ַ��ų��������ͣ��������˸��ֺ�����

                              // ��������__LIBRARY__���򻹺�ϵͳ���úź���Ƕ���syscall0()�ȡ�

  9

    //// �ں�ʹ�õij���(�˳�)��ֹ������

    // ֱ�ӵ���ϵͳ�ж�int 0x80�����ܺ�__NR_exit��

    // ������exit_code - �˳��롣

    // ������ǰ�Ĺؼ���volatile���ڸ��߱�����gcc�ú������᷵�ء���������gcc��������һ

    // Щ�Ĵ��룬����Ҫ����ʹ������ؼ��ֿ��Ա������ijЩ��δ��ʼ�������ģ��پ�����Ϣ��

    // ��ͬ��gcc�ĺ�������˵����void do_exit(int error_code) __attribute__ ((noreturn));

 10 volatile void _exit(int exit_code)

 11 {

    // %0 - eax(ϵͳ���ú�__NR_exit)��%1 - ebx(�˳���exit_code)��

 12         __asm__("int $0x80"::"a" (__NR_exit),"b" (exit_code));

 13 }

 14


 


 

15.2 ����15-2 linux/lib/close.c


  1 /*

  2  *  linux/lib/close.c

  3  *

  4  *  (C) 1991  Linus Torvalds

  5  */

  6

  7 #define __LIBRARY__

  8 #include <unistd.h>       // Linux��׼ͷ�ļ��������˸��ַ��ų��������ͣ��������˸��ֺ�����

                              // �綨����__LIBRARY__���򻹺�ϵͳ���úź���Ƕ���syscall0()�ȡ�

  9

    // �ر��ļ�������

    // ����õ��ú꺯����Ӧ��int close(int fd)��ֱ�ӵ�����ϵͳ�ж�int 0x80��������__NR_close��

    // ����fd���ļ���������

 10 _syscall1(int,close,int,fd)

 11


 

 


 

15.3 ����15-3 linux/lib/ctype.c


  1 /*

  2  *  linux/lib/ctype.c

  3  *

  4  *  (C) 1991  Linus Torvalds

  5  */

  6

  7 #include <ctype.h>        // �ַ�����ͷ�ļ���������һЩ�й��ַ������жϺ�ת���ĺꡣ

  8

  9 char _ctmp;               // һ����ʱ�ַ���������ctype.h�ļ���ת���ַ��꺯��ʹ�á�

    // �ַ���������(��)�������˸����ַ���Ӧ�����ԣ���Щ��������(��_C��)��ctype.h�ж��塣

    // �����ж��ַ��ǿ����ַ�(_C)����д�ַ�(_U)��Сд�ַ�(_L)���������͡�

 10 unsigned char _ctype[] = {0x00,                 /* EOF */

 11 _C,_C,_C,_C,_C,_C,_C,_C,                        /* 0-7 */

 12 _C,_C|_S,_C|_S,_C|_S,_C|_S,_C|_S,_C,_C,         /* 8-15 */

 13 _C,_C,_C,_C,_C,_C,_C,_C,                        /* 16-23 */

 14 _C,_C,_C,_C,_C,_C,_C,_C,                        /* 24-31 */

 15 _S|_SP,_P,_P,_P,_P,_P,_P,_P,                    /* 32-39 */

 16 _P,_P,_P,_P,_P,_P,_P,_P,                        /* 40-47 */

 17 _D,_D,_D,_D,_D,_D,_D,_D,                        /* 48-55 */

 18 _D,_D,_P,_P,_P,_P,_P,_P,                        /* 56-63 */

 19 _P,_U|_X,_U|_X,_U|_X,_U|_X,_U|_X,_U|_X,_U,      /* 64-71 */

 20 _U,_U,_U,_U,_U,_U,_U,_U,                        /* 72-79 */

 21 _U,_U,_U,_U,_U,_U,_U,_U,                        /* 80-87 */

 22 _U,_U,_U,_P,_P,_P,_P,_P,                        /* 88-95 */

 23 _P,_L|_X,_L|_X,_L|_X,_L|_X,_L|_X,_L|_X,_L,      /* 96-103 */

 24 _L,_L,_L,_L,_L,_L,_L,_L,                        /* 104-111 */

 25 _L,_L,_L,_L,_L,_L,_L,_L,                        /* 112-119 */

 26 _L,_L,_L,_P,_P,_P,_P,_C,                        /* 120-127 */

 27 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,                /* 128-143 */

 28 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,                /* 144-159 */

 29 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,                /* 160-175 */

 30 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,                /* 176-191 */

 31 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,                /* 192-207 */

 32 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,                /* 208-223 */

 33 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,                /* 224-239 */

 34 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};               /* 240-255 */

 35

 36


 

 


 

15.4 ����15-4 linux/lib/dup.c


  1 /*

  2  *  linux/lib/dup.c

  3  *

  4  *  (C) 1991  Linus Torvalds

  5  */

  6

  7 #define __LIBRARY__

  8 #include <unistd.h>       // Linux��׼ͷ�ļ��������˸��ַ��ų��������ͣ��������˸��ֺ�����

                              // �綨����__LIBRARY__���򻹺�ϵͳ���úź���Ƕ���_syscall0()�ȡ�

  9

    //// �����ļ�������������

    // ����õ��ú꺯����Ӧ��int dup(int fd)��ֱ�ӵ�����ϵͳ�ж�int 0x80��������__NR_dup��

    // ����fd���ļ���������

 10 _syscall1(int,dup,int,fd)

 11


 


 

15.5 ����15-5 linux/lib/errno.c


  1 /*

  2  *  linux/lib/errno.c

  3  *

  4  *  (C) 1991  Linus Torvalds

  5  */

  6

  7 int errno;

  8


 


 

15.6 ����15-6 linux/lib/execve.c


  1 /*

  2  *  linux/lib/execve.c

  3  *

  4  *  (C) 1991  Linus Torvalds

  5  */

  6

  7 #define __LIBRARY__

  8 #include <unistd.h>       // Linux��׼ͷ�ļ��������˸��ַ��ų��������ͣ��������˸��ֺ�����

                              // �綨����__LIBRARY__���򻹺�ϵͳ���úź���Ƕ���_syscall0()�ȡ�

  9

    //// ���ز�ִ���ӽ���(��������)������

    // ����õ��ú꺯����Ӧ��int execve(const char * file, char ** argv, char ** envp)��

    // ������file - ��ִ�г����ļ�����argv - �����в���ָ�����飻envp - ��������ָ�����顣

    // ֱ�ӵ�����ϵͳ�ж�int 0x80��������__NR_execve���μ�include/unistd.h��fs/exec.c����

 10 _syscall3(int,execve,const char *,file,char **,argv,char **,envp)

 11


 

 


 

15.7 ����15-7 linux/lib/malloc.c


  1 /*

  2  * malloc.c --- a general purpose kernel memory allocator for Linux.

  3  *

  4  * Written by Theodore Ts'o (tytso@mit.edu), 11/29/91

  5  *

  6  * This routine is written to be as fast as possible, so that it

  7  * can be called from the interrupt level.

  8  *

  9  * Limitations: maximum size of memory we can allocate using this routine

 10  *      is 4k, the size of a page in Linux.

 11  *

 12  * The general game plan is that each page (called a bucket) will only hold

 13  * objects of a given size.  When all of the object on a page are released,

 14  * the page can be returned to the general free pool.  When malloc() is

 15  * called, it looks for the smallest bucket size which will fulfill its

 16  * request, and allocate a piece of memory from that bucket pool.

 17  *

 18  * Each bucket has as its control block a bucket descriptor which keeps

 19  * track of how many objects are in use on that page, and the free list

 20  * for that page.  Like the buckets themselves, bucket descriptors are

 21  * stored on pages requested from get_free_page().  However, unlike buckets,

 22  * pages devoted to bucket descriptor pages are never released back to the

 23  * system.  Fortunately, a system should probably only need 1 or 2 bucket

 24  * descriptor pages, since a page can hold 256 bucket descriptors (which

 25  * corresponds to 1 megabyte worth of bucket pages.)  If the kernel is using

 26  * that much allocated memory, it's probably doing something wrong.  :-)

 27  *

 28  * Note: malloc() and free() both call get_free_page() and free_page()

 29  *      in sections of code where interrupts are turned off, to allow

 30  *      malloc() and free() to be safely called from an interrupt routine.

 31  *      (We will probably need this functionality when networking code,

 32  *      particularily things like NFS, is added to Linux.)  However, this

 33  *      presumes that get_free_page() and free_page() are interrupt-level

 34  *      safe, which they may not be once paging is added.  If this is the

 35  *      case, we will need to modify malloc() to keep a few unused pages

 36  *      "pre-allocated" so that it can safely draw upon those pages if

 37  *      it is called from an interrupt routine.

 38  *

 39  *      Another concern is that get_free_page() should not sleep; if it

 40  *      does, the code is carefully ordered so as to avoid any race

 41  *      conditions.  The catch is that if malloc() is called re-entrantly,

 42  *      there is a chance that unecessary pages will be grabbed from the

 43  *      system.  Except for the pages for the bucket descriptor page, the

 44  *      extra pages will eventually get released back to the system, though,

 45  *      so it isn't all that bad.

 46  */

 47

    /*

     *     malloc.c - Linux��ͨ���ں��ڴ���亯����

     *

     * ��Theodore Ts'o���� (tytso@mit.edu), 11/29/91

     *

     * �ú�������д�ɾ����ܵؿ죬�Ӷ����Դ��жϲ���ô˺�����

     *

     * ���ƣ�ʹ�øú���һ�����ܷ��������ڴ���4k��Ҳ��Linux���ڴ�ҳ��Ĵ�С��

     *

     * ��д�ú�������ѭ��һ�������ÿҳ(����Ϊһ���洢Ͱ)��������Ҫ���ɶ���Ĵ�С��

     * ��һҳ�ϵ����ж����ͷź󣬸�ҳ�Ϳ��Է���ͨ�ÿ����ڴ�ء���malloc()������

     * ʱ������Ѱ������Ҫ�����С�Ĵ洢Ͱ�����Ӹô洢Ͱ�з���һ���ڴ档

     *

     * ÿ���洢Ͱ����һ����Ϊ������õĴ洢Ͱ�����������м�¼��ҳ�����ж��ٶ�������

     * ʹ���Լ���ҳ�Ͽ����ڴ���б�������洢Ͱ����һ�����洢Ͱ������Ҳ�Ǵ洢��ʹ��

     * get_free_page()���뵽��ҳ���ϵģ�������洢Ͱ��ͬ���ǣ�Ͱ��������ռ�õ�ҳ��

     * �����ٻ��ͷŸ�ϵͳ�����˵���һ��ϵͳ��Լֻ��Ҫ1��2ҳ��Ͱ������ҳ�棬��Ϊһ

     * ��ҳ����Դ��256��Ͱ������(��Ӧ1MB�ڴ�Ĵ洢Ͱҳ��)�����ϵͳΪͰ��������

     * ���������ڴ棬��ô�϶�ϵͳʲô�ط���������J��

     *

     * ע�⣡malloc()��free()���߹ر����жϵĴ��벿�ֶ�������get_free_page()��

     *       free_page()��������ʹmalloc()��free()���԰�ȫ�ر����жϳ����е���

     *       (��������룬������NFS�ȱ����뵽Linux��ʱ�Ϳ�����Ҫ���ֹ���)����ǰ

     *       ���Ǽ���get_free_page()��free_page()�ǿ��԰�ȫ�����жϼ�������ʹ�õģ�

     *       ����һ�������˷�ҳ����֮��Ϳ��ܲ��ǰ�ȫ�ġ�������������������ô����

     *       ����Ҫ�޸�malloc()����Ԥ�ȷ��䡱��ҳ���õ��ڴ棬���malloc()��free()

     *       �����жϳ����е���ʱ�Ϳ��԰�ȫ��ʹ����Щҳ�档

     *

     *       ������Ҫ���ǵ�����get_free_page()��Ӧ��˯�ߣ������˯�ߵĻ�����Ϊ�˷�ֹ

     *       �κξ���������������Ҫ��ϸ�ذ���˳�� �ؼ��������malloc()�ǿ��������

     *       �����õĻ�����ô�ͻ���ڲ���Ҫ��ҳ�汻��ϵͳ��ȡ�ߵĻ��ᡣ��������Ͱ����

     *       ����ҳ�棬��Щ�����ҳ�����ջ��ͷŸ�ϵͳ�����Բ�������������������á�

     */

 

 48 #include <linux/kernel.h> // �ں�ͷ�ļ�������һЩ�ں˳��ú�����ԭ�ζ��塣

 49 #include <linux/mm.h>     // �ڴ����ͷ�ļ�������ҳ���С�����һЩҳ���ͷź���ԭ�͡�

 50 #include <asm/system.h>   // ϵͳͷ�ļ������������û��޸�������/�ж��ŵȵ�Ƕ��ʽ���ꡣ

 51

    // �洢Ͱ�������ṹ��

 52 struct bucket_desc {    /* 16 bytes */

 53         void                    *page;          // ��Ͱ��������Ӧ���ڴ�ҳ��ָ�롣

 54         struct bucket_desc      *next;          // ��һ��������ָ�롣

 55         void                    *freeptr;       // ָ��Ͱ�п����ڴ�λ�õ�ָ�롣

 56         unsigned short          refcnt;         // ���ü�����

 57         unsigned short          bucket_size;    // ����������Ӧ�洢Ͱ�Ĵ�С��

 58 };

 59

    // �洢Ͱ������Ŀ¼�ṹ��

 60 struct _bucket_dir {    /* 8 bytes */

 61         int                     size;      // �ô洢Ͱ�Ĵ�С(�ֽ���)��

 62         struct bucket_desc      *chain;    // �ô洢ͰĿ¼���Ͱ����������ָ�롣

 63 };

 64

 65 /*

 66  * The following is the where we store a pointer to the first bucket

 67  * descriptor for a given size. 

 68  *

 69  * If it turns out that the Linux kernel allocates a lot of objects of a

 70  * specific size, then we may want to add that specific size to this list,

 71  * since that will allow the memory to be allocated more efficiently.

 72  * However, since an entire page must be dedicated to each specific size

 73  * on this list, some amount of temperance must be exercised here.

 74  *

 75  * Note that this list *must* be kept in order.

 76  */

    /*

     * ���������Ǵ�ŵ�һ��������С�洢Ͱ������ָ��ĵط���

     *

     * ���Linux�ں˷���������ָ����С�Ķ�����ô���Ǿ�ϣ������ָ���Ĵ�С�ӵ�

     * ���б�(����)�У���Ϊ��������ʹ�ڴ�ķ������Ч�����ǣ���Ϊһҳ�����ڴ�ҳ��

     * ���������б���ָ����С�����ж���������Ҫ����������IJ��Բ�����

     */

    // �洢ͰĿ¼�б�(����)��

 77 struct _bucket_dir bucket_dir[] = {

 78         { 16,   (struct bucket_desc *) 0},    // 16�ֽڳ��ȵ��ڴ�顣

 79         { 32,   (struct bucket_desc *) 0},    // 32�ֽڳ��ȵ��ڴ�顣

 80         { 64,   (struct bucket_desc *) 0},    // 64�ֽڳ��ȵ��ڴ�顣

 81         { 128,  (struct bucket_desc *) 0},    // 128�ֽڳ��ȵ��ڴ�顣

 82         { 256,  (struct bucket_desc *) 0},    // 256�ֽڳ��ȵ��ڴ�顣

 83         { 512,  (struct bucket_desc *) 0},    // 512�ֽڳ��ȵ��ڴ�顣

 84         { 1024, (struct bucket_desc *) 0},    // 1024�ֽڳ��ȵ��ڴ�顣

 85         { 2048, (struct bucket_desc *) 0},    // 2048�ֽڳ��ȵ��ڴ�顣

 86         { 4096, (struct bucket_desc *) 0},    // 4096�ֽ�(1ҳ)�ڴ档

 87         { 0,    (struct bucket_desc *) 0}};   /* End of list marker */

 88

 89 /*

 90  * This contains a linked list of free bucket descriptor blocks

 91  */

    /*

     * �����Ǻ��п���Ͱ�������ڴ���������

     */

 92 struct bucket_desc *free_bucket_desc = (struct bucket_desc *) 0;

 93

 94 /*

 95  * This routine initializes a bucket description page.

 96  */

    /*

     * ������ӳ������ڳ�ʼ��һҳͰ������ҳ�档

     */

    //// ��ʼ��Ͱ��������

    // ��������Ͱ����������������free_bucket_descָ���һ������Ͱ��������

 97 static inline void init_bucket_desc()

 98 {

 99         struct bucket_desc *bdesc, *first;

100         int     i;

101        

    // ����һҳ�ڴ棬���ڴ��Ͱ�����������ʧ�ܣ�����ʾ��ʼ��Ͱ������ʱ�ڴ治��������Ϣ��������

102         first = bdesc = (struct bucket_desc *) get_free_page();

103         if (!bdesc)

104                 panic("Out of memory in init_bucket_desc()");

    // ���ȼ���һҳ�ڴ��пɴ�ŵ�Ͱ������������Ȼ����佨����������ָ�롣

105         for (i = PAGE_SIZE/sizeof(struct bucket_desc); i > 1; i--) {

106                 bdesc->next = bdesc+1;

107                 bdesc++;

108         }

109         /*

110          * This is done last, to avoid race conditions in case

111          * get_free_page() sleeps and this routine gets called again....

112          */

            /*

             * ������������ģ�Ŀ����Ϊ�˱�����get_free_page()˯��ʱ���ӳ����ֱ�

             * ���ö�����ľ���������

             */

    // ������Ͱ������ָ��free_bucket_desc���������С�

113         bdesc->next = free_bucket_desc;

114         free_bucket_desc = first;

115 }

116

    //// ���䶯̬�ڴ溯����

    // ������len - ������ڴ�鳤�ȡ�

    // ���أ�ָ�򱻷����ڴ��ָ�롣���ʧ���򷵻�NULL��

117 void *malloc(unsigned int len)

118 {

119         struct _bucket_dir      *bdir;

120         struct bucket_desc      *bdesc;

121         void                    *retval;

122

123         /*

124          * First we search the bucket_dir to find the right bucket change

125          * for this request.

126          */

            /*

             * �������������洢ͰĿ¼bucket_dir��Ѱ���ʺ������Ͱ��С��

             */

    // �����洢ͰĿ¼��Ѱ���ʺ������ڴ���С��Ͱ���������������Ŀ¼���Ͱ�ֽ�������������ֽ�

    // �������ҵ��˶�Ӧ��ͰĿ¼�

127         for (bdir = bucket_dir; bdir->size; bdir++)

128                 if (bdir->size >= len)

129                         break;

    // �������������Ŀ¼��û���ҵ����ʴ�С��Ŀ¼��������������ڴ���С̫�󣬳����˸�

    // ����ķ�������(�Ϊ1��ҳ��)��������ʾ������Ϣ��������

130         if (!bdir->size) {

131                 printk("malloc called with impossibly large argument (%d)\n",

132                         len);

133                 panic("malloc: bad arg");

134         }

135         /*

136          * Now we search for a bucket descriptor which has free space

137          */

            /*

             * �����������������п��пռ��Ͱ��������

             */

138         cli();  /* Avoid race conditions */   /* Ϊ�˱�����־������������ȹ��ж� */

    // ������ӦͰĿ¼�������������������Ҿ��п��пռ��Ͱ�����������Ͱ�������Ŀ����ڴ�ָ��

    // freeptr��Ϊ�գ����ʾ�ҵ�����Ӧ��Ͱ��������

139         for (bdesc = bdir->chain; bdesc; bdesc = bdesc->next)

140                 if (bdesc->freeptr)

141                         break;

142         /*

143          * If we didn't find a bucket with free space, then we'll

144          * allocate a new one.

145          */

            /*

             * ���û���ҵ����п��пռ��Ͱ����������ô���Ǿ�Ҫ�½���һ����Ŀ¼�����������

             */

146         if (!bdesc) {

147                 char            *cp;

148                 int             i;

149

    // ��free_bucket_desc��Ϊ��ʱ����ʾ��һ�ε��øó��򣬻������������п�Ͱ�������������ꡣ

    // ��ʱ����Ҫ����һ��ҳ�沢�����Ͻ�������ʼ������������������free_bucket_desc��ָ���һ

    // ������Ͱ��������

150                 if (!free_bucket_desc

151                         init_bucket_desc();

    // ȡfree_bucket_descָ��Ŀ���Ͱ������������free_bucket_descָ����һ������Ͱ��������

152                 bdesc = free_bucket_desc;

153                 free_bucket_desc = bdesc->next;

    // ��ʼ�����µ�Ͱ������������������������0��Ͱ�Ĵ�С���ڶ�ӦͰĿ¼�Ĵ�С������һ�ڴ�ҳ�棬

    // ����������ҳ��ָ��pageָ���ҳ�棻�����ڴ�ָ��Ҳָ���ҳ��ͷ����Ϊ��ʱȫΪ���С�

154                 bdesc->refcnt = 0;

155                 bdesc->bucket_size = bdir->size;

156                 bdesc->page = bdesc->freeptr = (void *) cp = get_free_page();

    // ��������ڴ�ҳ�����ʧ�ܣ�����ʾ������Ϣ��������

157                 if (!cp)

158                         panic("Out of memory in kernel malloc()");

159                 /* Set up the chain of free objects */

                    /* �ڸ�ҳ�����ڴ��н������ж������� */

    // �Ը�ͰĿ¼��ָ����Ͱ��СΪ���󳤶ȣ��Ը�ҳ�ڴ���л��֣���ʹÿ������Ŀ�ʼ4�ֽ�����

    // ��ָ����һ�����ָ�롣

160                 for (i=PAGE_SIZE/bdir->size; i > 1; i--) {

161                         *((char **) cp) = cp + bdir->size;

162                         cp += bdir->size;

163                 }

    // ���һ������ʼ����ָ������Ϊ0(NULL)��

    // Ȼ���ø�Ͱ����������һ������ָ���ֶ�ָ���ӦͰĿ¼��ָ��chain��ָ������������ͰĿ¼��

    // chainָ���Ͱ��������Ҳ���������������뵽����������ͷ����

164                 *((char **) cp) = 0;

165                 bdesc->next = bdir->chain; /* OK, link it in! */   /* OK���������룡*/

166                 bdir->chain = bdesc;

167         }

    // ����ָ�뼴���ڸ���������Ӧҳ��ĵ�ǰ����ָ�롣Ȼ������ÿ��пռ�ָ��ָ����һ�����ж���

    // ��ʹ�������ж�Ӧҳ���ж������ü�����1��

168         retval = (void *) bdesc->freeptr;

169         bdesc->freeptr = *((void **) retval);

170         bdesc->refcnt++;

    // ��󿪷��жϣ�������ָ������ڴ�����ָ�롣

171         sti();  /* OK, we're safe again */   /* OK�����������ְ�ȫ��*/

172         return(retval);

173 }

174

175 /*

176  * Here is the free routine.  If you know the size of the object that you

177  * are freeing, then free_s() will use that information to speed up the

178  * search for the bucket descriptor.

179  *

180  * We will #define a macro so that "free(x)" is becomes "free_s(x, 0)"

181  */

    /*

     * �������ͷ��ӳ��������֪���ͷŶ���Ĵ�С����free_s()��ʹ�ø���Ϣ����

     * ��Ѱ��ӦͰ���������ٶȡ�

     *

     * ���ǽ�����һ���꣬ʹ��"free(x)"��Ϊ"free_s(x, 0)"��

     */

    //// �ͷŴ洢Ͱ����

    // ������obj - ��Ӧ����ָ�룻size - ��С��

182 void free_s(void *obj, int size)

183 {

184         void            *page;

185         struct _bucket_dir      *bdir;

186         struct bucket_desc      *bdesc, *prev;

187

188         /* Calculate what page this object lives in */

            /* ����ö������ڵ�ҳ�� */

189         page = (void *)  ((unsigned long) obj & 0xfffff000);

190         /* Now search the buckets looking for that page */

            /* ���������洢ͰĿ¼�������ӵ�Ͱ��������Ѱ�Ҹ�ҳ�� */

    //

191         for (bdir = bucket_dir; bdir->size; bdir++) {

192                 prev = 0;

193                 /* If size is zero then this conditional is always false */

                    /* �������size��0�������������϶���false */

194                 if (bdir->size < size)

195                         continue;

    // ������ӦĿ¼�������ӵ����������������Ҷ�Ӧҳ�档���ij������ҳ��ָ�����page���ʾ�ҵ�

    // ����Ӧ������������ת��found����������������ж�Ӧpage������������ָ��prevָ�����������

196                 for (bdesc = bdir->chain; bdesc; bdesc = bdesc->next) {

197                         if (bdesc->page == page)

198                                 goto found;

199                         prev = bdesc;

200                 }

201         }

    // �������˶�ӦĿ¼���������������û���ҵ�ָ����ҳ�棬����ʾ������Ϣ��������

202         panic("Bad address passed to kernel free_s()");

203 found:

    // �ҵ���Ӧ��Ͱ�����������ȹ��жϡ�Ȼ�󽫸ö����ڴ��������п���������У���ʹ��������

    // �Ķ������ü�����1��

204         cli(); /* To avoid race conditions */   /* Ϊ�˱��⾺������ */

205         *((void **)obj) = bdesc->freeptr;

206         bdesc->freeptr = obj;

207         bdesc->refcnt--;

    // ������ü����ѵ���0�������ǾͿ����ͷŶ�Ӧ���ڴ�ҳ��͸�Ͱ��������

208         if (bdesc->refcnt == 0) {

209                 /*

210                  * We need to make sure that prev is still accurate.  It

211                  * may not be, if someone rudely interrupted us....

212                  */

                    /*

                     * ������Ҫȷ��prev��Ȼ����ȷ�ģ���ij�����³���ж�������

                     * ���п��ܲ����ˡ�

                     */

    // ���prev�Ѿ���������������������ǰһ����������������������ǰ��������ǰһ����������

213                 if ((prev && (prev->next != bdesc)) ||

214                     (!prev && (bdir->chain != bdesc)))

215                         for (prev = bdir->chain; prev; prev = prev->next)

216                                 if (prev->next == bdesc)

217                                         break;

    // ����ҵ���ǰһ�����������������������ɾ����ǰ��������

218                 if (prev)

219                         prev->next = bdesc->next;

    // ���prev==NULL����˵����ǰһ���������Ǹ�Ŀ¼���׸���������Ҳ��Ŀ¼����chainӦ��ֱ��

    // ָ��ǰ������bdesc�������ʾ���������⣬����ʾ������Ϣ����������ˣ�Ϊ�˽���ǰ������

    // ��������ɾ����Ӧ����chainָ����һ����������

220                 else {

221                         if (bdir->chain != bdesc)

222                                 panic("malloc bucket chains corrupted");

223                         bdir->chain = bdesc->next;

224                 }

    // �ͷŵ�ǰ���������������ڴ�ҳ�棬�������������������������������ʼ����

225                 free_page((unsigned long) bdesc->page);

226                 bdesc->next = free_bucket_desc;

227                 free_bucket_desc = bdesc;

228         }

    // ���жϣ����ء�

229         sti();

230         return;

231 }

232

233


 


 

15.8 ����15-8 linux/lib/open.c


  1 /*

  2  *  linux/lib/open.c

  3  *

  4  *  (C) 1991  Linus Torvalds

  5  */

  6

  7 #define __LIBRARY__

  8 #include <unistd.h>       // Linux��׼ͷ�ļ��������˸��ַ��ų��������ͣ��������˸��ֺ�����

                              // �綨����__LIBRARY__���򻹺�ϵͳ���úź���Ƕ���_syscall0()�ȡ�

  9 #include <stdarg.h>       // ��׼����ͷ�ļ����Ժ����ʽ������������б�����Ҫ˵����-��

                              // ����(va_list)��������(va_start, va_arg��va_end)������

                              // vsprintf��vprintf��vfprintf������

 10

    //// ���ļ�������

    // �򿪲��п��ܴ���һ���ļ���

    // ������filename - �ļ�����flag - �ļ��򿪱�־��...

    // ���أ��ļ������������������ó����룬������-1��

    // ��13�ж�����һ���Ĵ�������res���ñ�������������һ���Ĵ����У��Ա��ڸ�Ч���ʺͲ�����

    // ����ָ����ŵļĴ���������eax������ô���԰Ѹþ�д����register int res asm("ax");����

 11 int open(const char * filename, int flag, ...)

 12 {

 13         register int res;

 14         va_list arg;

 15

    // ����va_start()�꺯����ȡ��flag���������ָ�룬Ȼ�����ϵͳ�ж�int 0x80������open����

    // �ļ��򿪲�����

    // %0 - eax(���ص��������������)��%1 - eax(ϵͳ�жϵ��ù��ܺ�__NR_open)��

    // %2 - ebx(�ļ���filename)��%3 - ecx(���ļ���־flag)��%4 - edx(��������ļ�����mode)��

 16         va_start(arg,flag);

 17         __asm__("int $0x80"

 18                 :"=a" (res)

 19                 :"" (__NR_open),"b" (filename),"c" (flag),

 20                 "d" (va_arg(arg,int)));

    // ϵͳ�жϵ��÷���ֵ���ڻ����0����ʾ��һ���ļ�����������ֱ�ӷ���֮��

 21         if (res>=0)

 22                 return res;

    // ����˵������ֵС��0�������һ�������롣���øó����벢����-1��

 23         errno = -res;

 24         return -1;

 25 }

 26


 


 

15.9 ����15-9 linux/lib/setsid.c


  1 /*

  2  *  linux/lib/setsid.c

  3  *

  4  *  (C) 1991  Linus Torvalds

  5  */

  6

  7 #define __LIBRARY__

  8 #include <unistd.h>       // Linux��׼ͷ�ļ��������˸��ַ��ų��������ͣ��������˸��ֺ�����

                              // �綨����__LIBRARY__���򻹺�ϵͳ���úź���Ƕ���_syscall0()�ȡ�

  9

    //// ����һ���Ự�����ý�����š�

    // ����ϵͳ���ú��Ӧ�ں�����pid_t setsid()��

    // ���أ����ý��̵ĻỰ��ʶ��(session ID)��

 10 _syscall0(pid_t,setsid)

 11


 


 

15.10 ����15-10 linux/lib/string.c


  1 /*

  2  *  linux/lib/string.c

  3  *

  4  *  (C) 1991  Linus Torvalds

  5  */

  6

  7 #ifndef __GNUC__              // ��ҪGNU��C���������롣

  8 #error I want gcc!

  9 #endif

 10

 11 #define extern

 12 #define inline

 13 #define __LIBRARY__

 14 #include <string.h>

 15


 


 

15.11 ����15-11 linux/lib/wait.c


  1 /*

  2  *  linux/lib/wait.c

  3  *

  4  *  (C) 1991  Linus Torvalds

  5  */

  6

  7 #define __LIBRARY__

  8 #include <unistd.h>       // Linux��׼ͷ�ļ��������˸��ַ��ų��������ͣ��������˸��ֺ�����

                              // �綨����__LIBRARY__���򻹺�ϵͳ���úź���Ƕ���_syscall0()�ȡ�

  9 #include <sys/wait.h>     // �ȴ�����ͷ�ļ�������ϵͳ����wait()��waitpid()����س������š�

 10

    //// �ȴ�������ֹϵͳ���ú�����

    // �������ṹ��Ӧ�ں�����pid_t waitpid(pid_t pid, int * wait_stat, int options)

    //

    // ������pid - �ȴ�����ֹ���̵Ľ���id������������ָ����������������ض���ֵ��

    //       wait_stat - ���ڴ��״̬��Ϣ��options - WNOHANG��WUNTRACED����0��

 11 _syscall3(pid_t,waitpid,pid_t,pid,int *,wait_stat,int,options)

 12

    //// wait()ϵͳ���á�ֱ�ӵ���waitpid()������

 13 pid_t wait(int * wait_stat)

 14 {

 15         return waitpid(-1,wait_stat,0);

 16 }

 17


 


 

15.12 ����15-12 linux/lib/write.c


  1 /*

  2  *  linux/lib/write.c

  3  *

  4  *  (C) 1991  Linus Torvalds

  5  */

  6

  7 #define __LIBRARY__

  8 #include <unistd.h>       // Linux��׼ͷ�ļ��������˸��ַ��ų��������ͣ��������˸��ֺ�����

                              // �綨����__LIBRARY__���򻹺�ϵͳ���úź���Ƕ���_syscall0()�ȡ�

  9

    //// д�ļ�ϵͳ���ú�����

    // �ú�ṹ��Ӧ�ں�����int write(int fd, const char * buf, off_t count)

    // ������fd - �ļ���������buf - д������ָ�룻count - д�ֽ�����

    // ���أ��ɹ�ʱ����д����ֽ���(0��ʾд��0�ֽ�)������ʱ������-1�����������˳����š�

 10 _syscall3(int,write,int,fd,const char *,buf,off_t,count)

 11


 


 

��16�� �ں˴�����ϳ���

16.1 ����16-1 linux/tools/build.c


  1 /*

  2  *  linux/tools/build.c

  3  *

  4  *  (C) 1991  Linus Torvalds

  5  */

  6

  7 /*

  8  * This file builds a disk-image from three different files:

  9  *

 10  * - bootsect: max 510 bytes of 8086 machine code, loads the rest

 11  * - setup: max 4 sectors of 8086 machine code, sets up system parm

 12  * - system: 80386 code for actual system

 13  *

 14  * It does some checking that all files are of the correct type, and

 15  * just writes the result to stdout, removing headers and padding to

 16  * the right amount. It also writes some system data to stderr.

 17  */

    /*

     * �ó����������ͬ�ij����д�������ӳ���ļ���

     *

     * - bootsect�����ļ���8086�������Ϊ510�ֽڣ����ڼ�����������

     * - setup�����ļ���8086�������Ϊ4��������������������ϵͳ������

     * - system��ʵ��ϵͳ��80386���롣

     *

     * �ó������ȼ�����г���ģ��������Ƿ���ȷ��������������ն�����ʾ������

     * Ȼ��ɾ��ģ��ͷ�����������ȷ�ij��ȡ��ó���Ҳ�ὫһЩϵͳ����д��stderr��

     */

 18

 19 /*

 20  * Changes by tytso to allow root device specification

 21  *

 22  * Added swap-device specification: Linux 20.12.91

 23  */

    /*

     * tytso�Ըó��������޸ģ�������ָ�����ļ��豸��

     *

     * ������ָ�������豸���ܣ�Linus 20.12.91

     */

 24

 25 #include <stdio.h>      /* fprintf */              // ʹ�����е�fprintf()������

 26 #include <string.h>                                // �ַ�������������

 27 #include <stdlib.h>     /* contains exit */        // ��exit����ԭ��˵����

 28 #include <sys/types.h>  /* unistd.h needs this */  // ��ͷ�ļ���unistd.h�ļ�ʹ�á�

 29 #include <sys/stat.h>                              // ���ļ�״̬��Ϣ�ṹ���塣

 30 #include <linux/fs.h>                              // �ļ�ϵͳͷ�ļ���

 31 #include <unistd.h>     /* contains read/write */  // ��read/write����ԭ��˵����

 32 #include <fcntl.h>                                 // �����ļ�����ģʽ���ų�����

 33

 34 #define MINIX_HEADER 32              // minix������Ŀ���ļ�ģ��ͷ������Ϊ32�ֽڡ�

 35 #define GCC_HEADER 1024              // GCCͷ����Ϣ����Ϊ1024�ֽڡ�

 36

 37 #define SYS_SIZE 0x3000              // system�ļ������(�ֽ���ΪSYS_SIZE*16=128KB)��

 38

    // Ĭ�ϵذ�Linux���ļ�ϵͳ�����豸����Ϊ�ڵ�2��Ӳ�̵ĵ�1�������ϣ����豸��Ϊ0x0306����

    // ����ΪLinus��ʱ����Linuxʱ���ѵ�1��Ӳ������MINIXϵͳ�̣�����2��Ӳ������ΪLinux

    // �ĸ��ļ�ϵͳ�̡�

 39 #define DEFAULT_MAJOR_ROOT 3         // Ĭ�ϸ��豸���豸�� - 3��Ӳ�̣���

 40 #define DEFAULT_MINOR_ROOT 6         // Ĭ�ϸ��豸���豸�� - 6����2��Ӳ�̵ĵ�1��������

 41

 42 #define DEFAULT_MAJOR_SWAP 0         // Ĭ�Ͻ����豸���豸�š�

 43 #define DEFAULT_MINOR_SWAP 0         // Ĭ�Ͻ����豸���豸�š�

 44

 45 /* max nr of sectors of setup: don't change unless you also change

 46  * bootsect etc */

    /* ����ָ��setupģ��ռ���������������Ҫ�ı��ֵ������Ҳ�ı�bootsect����Ӧ�ļ���

 47 #define SETUP_SECTS 4                // setup��󳤶�Ϊ4��������2KB����

 48

 49 #define STRINGIFY(x) #x              // ��xת�����ַ������ͣ����ڳ�����ʾ����С�

 50

    //// ��ʾ������Ϣ������ֹ����

 51 void die(char * str)

 52 {

 53         fprintf(stderr,"%s\n",str);

 54         exit(1);

 55 }

 56

    // ��ʾ����ʹ�÷��������˳���

 57 void usage(void)

 58 {

 59         die("Usage: build bootsect setup system [rootdev] [> image]");

 60 }

 61

    // ������ʼ��

 62 int main(int argc, char ** argv)

 63 {

 64         int i,c,id;

 65         char buf[1024];

 66         char major_root, minor_root;

 67         char major_swap, minor_swap;

 68         struct stat sb;

 69

    // ���ȼ��build����ִ��ʱʵ�������в��������������ݲ�����������Ӧ���á����build����

    // �����в�����������4��6��������������1����������ʾ�����÷����˳���

 70         if ((argc < 4) || (argc > 6))

 71                 usage();

    // ���������������ж���4����������ô������豸���������̣�"FLOPPY"������ȡ���豸�ļ���

    // ״̬��Ϣ����ȡ״̬��������ʾ��Ϣ���˳�������ȡ���豸��״̬�ṹ�е����豸�źʹ��豸��

    // ��Ϊ���豸�š�������豸����FLOPPY�豸���������豸�źʹ��豸��ȡ0����ʾ���豸�ǵ�ǰ

    // ���������豸��

 72         if (argc > 4) {

 73                 if (strcmp(argv[4], "FLOPPY")) {

 74                         if (stat(argv[4], &sb)) {

 75                                 perror(argv[4]);

 76                                 die("Couldn't stat root device.");

 77                         }

 78                         major_root = MAJOR(sb.st_rdev);   // ȡ�豸��״̬�ṹ���豸�š�

 79                         minor_root = MINOR(sb.st_rdev);

 80                 } else {

 81                         major_root = 0;

 82                         minor_root = 0;

 83                 }

    // ������ֻ��4�����������豸�źʹ��豸�ŵ���ϵͳĬ�ϵĸ��豸�š�

 84         } else {

 85                 major_root = DEFAULT_MAJOR_ROOT;

 86                 minor_root = DEFAULT_MINOR_ROOT;

 87         }

    // ����������������6����������ô������һ����ʾ�����豸�IJ��������ޣ�"NONE"������ȡ��

    // �豸�ļ���״̬��Ϣ����ȡ״̬��������ʾ��Ϣ���˳�������ȡ���豸��״̬�ṹ�е����豸��

    // �ʹ��豸����Ϊ�����豸�š�������һ����������"NONE"�����ý����豸�����豸�źʹ��豸

    // ��ȡΪ0����ʾ�����豸���ǵ�ǰ���������豸��

 88         if (argc == 6) {

 89                 if (strcmp(argv[5], "NONE")) {

 90                         if (stat(argv[5], &sb)) {

 91                                 perror(argv[5]);

 92                                 die("Couldn't stat root device.");

 93                         }

 94                         major_swap = MAJOR(sb.st_rdev);   // ȡ�豸��״̬�ṹ���豸�š�

 95                         minor_swap = MINOR(sb.st_rdev);

 96                 } else {

 97                         major_swap = 0;

 98                         minor_swap = 0;

 99                 }

    // ������û��6������5������ʾ��������û�д������豸�������Ǿ��ý����豸���豸�źʹ��豸

    // �ŵ���ϵͳĬ�ϵĽ����豸�š�

100         } else {

101                 major_swap = DEFAULT_MAJOR_SWAP;

102                 minor_swap = DEFAULT_MINOR_SWAP;

103         }

 

    // �������ڱ�׼�����ն�����ʾ������ѡ��ĸ��豸�������豸�źͽ����豸�������豸�š����

    // ���豸�Ų�����2�����̣���3��Ӳ�̣���Ҳ��Ϊ0��ȡϵͳĬ���豸��������ʾ������Ϣ���˳���

    // �ն˵ı�׼����������ļ�Image����˱�������������ں˴������ݣ������ں�ӳ���ļ���

104         fprintf(stderr, "Root device is (%d, %d)\n", major_root, minor_root);

105         fprintf(stderr, "Swap device is (%d, %d)\n", major_swap, minor_swap);

106         if ((major_root != 2) && (major_root != 3) &&

107             (major_root != 0)) {

108                 fprintf(stderr, "Illegal root device (major = %d)\n",

109                         major_root);

110                 die("Bad root device --- major #");

111         }

112         if (major_swap && major_swap != 3) {

113                 fprintf(stderr, "Illegal swap device (major = %d)\n",

114                         major_swap);

115                 die("Bad root device --- major #");

116         }

    // ���濪ʼִ�ж�ȡ�����ļ����ݲ�������Ӧ�ĸ��ƴ��������ȳ�ʼ��1KB�ĸ��ƻ���������ȫ0��

    // Ȼ����ֻ����ʽ�򿪲���1ָ�����ļ���bootsect�������ж�ȡ32�ֽڵ�MINIXִ���ļ�ͷ�ṹ

    // ���ݣ��μ��б���˵������������buf�С�

117         for (i=0;i<sizeof buf; i++) buf[i]=0;

118         if ((id=open(argv[1],O_RDONLY,0))<0)

119                 die("Unable to open 'boot'");

120         if (read(id,buf,MINIX_HEADER) != MINIX_HEADER)

121                 die("Unable to read header of 'boot'");

    // ����������MINIXͷ���ṹ�ж�bootsect�Ƿ�Ϊһ����Ч��MINIXִ���ļ������ǣ�����ļ���

    // ��ȡ512�ֽڵ�����������������ݡ�

    // 0x0301 - MINIXͷ��a_magicħ����0x10 - a_flag��ִ�У�0x04 - a_cpu, Intel 8086�����롣

122         if (((long *) buf)[0]!=0x04100301)

123                 die("Non-Minix header of 'boot'");

    // �ж�ͷ�������ֶ�a_hdrlen���ֽڣ��Ƿ���ȷ��32�ֽڣ����������ֽ�����û���ã���0��

124         if (((long *) buf)[1]!=MINIX_HEADER)

125                 die("Non-Minix header of 'boot'");

    // �ж����ݶγ�a_data�ֶ�(long)�����Ƿ�Ϊ0��

126         if (((long *) buf)[3]!=0)

127                 die("Illegal data segment in 'boot'");

    // �ж϶�a_bss�ֶ�(long)�����Ƿ�Ϊ0��

128         if (((long *) buf)[4]!=0)

129                 die("Illegal bss in 'boot'");

    // �ж�ִ�е�a_entry�ֶ�(long)�����Ƿ�Ϊ0��

130         if (((long *) buf)[5] != 0)

131                 die("Non-Minix header of 'boot'");

    // �жϷ��ű����ֶ�a_sym�������Ƿ�Ϊ0��

132         if (((long *) buf)[7] != 0)

133                 die("Illegal symbol table in 'boot'");

    // �������ж϶���ȷ�������¶�ȡ�ļ�������ʵ�ʴ������ݣ�Ӧ�÷��ض�ȡ�ֽ���Ϊ512�ֽڡ�

    // ��Ϊbootsect�ļ��а�������1������������������������ݣ��������2�ֽ�Ӧ���ǿ�����

    // ��־0xAA55��

134         i=read(id,buf,sizeof buf);

135         fprintf(stderr,"Boot sector %d bytes.\n",i);

136         if (i != 512)

137                 die("Boot block must be exactly 512 bytes");

138         if ((*(unsigned short *)(buf+510)) != 0xAA55)

139                 die("Boot block hasn't got boot flag (0xAA55)");

    // ����������506��507ƫ�ƴ����Ž����豸�ţ�508��509ƫ�ƴ����Ÿ��豸�š�

140         buf[506] = (char) minor_swap;

141         buf[507] = (char) major_swap;

142         buf[508] = (char) minor_root;

143         buf[509] = (char) major_root;  

    // Ȼ�󽫸�512�ֽڵ�����д����׼���stdout����д���ֽ������ԣ�����ʾ������Ϣ���˳���

    // ��linux/Makefile�У�build�����׼������ض����ں�ӳ���ļ���Image�ϣ��������

    // ������������ݻᱻд��Image��ʼ��512�ֽڴ������ر�bootsectģ���ļ���

144         i=write(1,buf,512);

145         if (i!=512)

146                 die("Write call failed");

147         close (id);

148        

    // ������ֻ����ʽ�򿪲���2ָ�����ļ���setup�������ж�ȡ32�ֽڵ�MINIXִ���ļ�ͷ�ṹ

    // ���ݵ�������buf�С�������ʽ��������ͬ��������ֻ����ʽ��ָ�����ļ�setup�����ж�

    // ȡ32�ֽڵ�MINIXִ���ļ�ͷ�ṹ���ݵ�������buf�С�

149         if ((id=open(argv[2],O_RDONLY,0))<0)

150                 die("Unable to open 'setup'");

151         if (read(id,buf,MINIX_HEADER) != MINIX_HEADER)

152                 die("Unable to read header of 'setup'");

    // ����������MINIXͷ���ṹ�ж�setup�Ƿ�Ϊһ����Ч��MINIXִ���ļ������ǣ�����ļ���

    // ��ȡ512�ֽڵ�����������������ݡ�

    // 0x0301- MINIXͷ��a_magicħ����0x10- a_flag��ִ�У�0x04- a_cpu, Intel 8086�����롣

153         if (((long *) buf)[0]!=0x04100301)

154                 die("Non-Minix header of 'setup'");

    // �ж�ͷ�������ֶ�a_hdrlen���ֽڣ��Ƿ���ȷ��32�ֽڣ����������ֽ�����û���ã���0��

155         if (((long *) buf)[1]!=MINIX_HEADER)

156                 die("Non-Minix header of 'setup'");

    // �ж����ݶγ��ֶ�a_data�����ֶ�a_bss����ʼִ�е��ֶ�a_entry�ͷ��ű��ֶ�a_sym������

    // �Ƿ�Ϊ0�����붼Ϊ0��

157         if (((long *) buf)[3]!=0)                      // ���ݶγ�a_data�ֶΡ�

158                 die("Illegal data segment in 'setup'");

159         if (((long *) buf)[4]!=0)                      // ��a_bss�ֶΡ�

160                 die("Illegal bss in 'setup'");

161         if (((long *) buf)[5] != 0)                    // ִ����ʼ��a_entry�ֶΡ�

162                 die("Non-Minix header of 'setup'");

163         if (((long *) buf)[7] != 0)

164                 die("Illegal symbol table in 'setup'");

    // �������ж϶���ȷ�������¶�ȡ�ļ�������ʵ�ʴ������ݣ�����д���ն˱�׼�����ͬʱͳ��

    // д�ij��ȣ�i�������ڲ���������ر�setup�ļ���֮���ж�һ������setupִ��д�����Ĵ���

    // �����ݳ���ֵ����ֵ���ܴ���(SETUP_SECTS * 512)�ֽڣ�����͵������޸�build��bootsect

    // ��setup�������趨��setup��ռ�����������±����ںˡ���һ����������ʾsetupʵ�ʳ���ֵ��

165         for (i=0 ; (c=read(id,buf,sizeof buf))>0 ; i+=c )

166                 if (write(1,buf,c)!=c)

167                         die("Write call failed");

168         close (id);                                   //�ر�setupģ���ļ���

169         if (i > SETUP_SECTS*512)

170                 die("Setup exceeds " STRINGIFY(SETUP_SECTS)

171                         " sectors - rewrite build/boot/setup");

172         fprintf(stderr,"Setup is %d bytes.\n",i);

    // �ڽ�������buf����֮���ж�ʵ��д��setup������(SETUP_SECTS4*512)����ֵ���setup

    // ����С�ڸó��ȣ�4*512�ֽڣ�������NULL�ַ���setup����Ϊ4*512�ֽڡ�

173         for (c=0 ; c<sizeof(buf) ; c++)

174                 buf[c] = '\0';

175         while (i<SETUP_SECTS*512) {

176                 c = SETUP_SECTS*512-i;

177                 if (c > sizeof(buf))

178                         c = sizeof(buf);

179                 if (write(1,buf,c) != c)

180                         die("Write call failed");

181                 i += c;

182         }

183        

    // ���濪ʼ����systemģ���ļ������ļ�ʹ��gas���룬��˾���GNU a.outĿ���ļ���ʽ��

    // ������ֻ����ʽ���ļ�������ȡ����a.out��ʽͷ���ṹ��Ϣ��1KB���ȣ������ж�system

    // ��һ����Ч��a.out��ʽ�ļ�֮�󣬾ͰѸ��ļ������������ݶ�д����׼�����Image�ļ���

    // �У����رո��ļ���Ȼ����ʾsystemģ��ij��ȡ���system��������ݳ��ȳ���SYS_SIZE��

    // ����128KB�ֽڣ�������ʾ������Ϣ���˳������޴����򷵻�0����ʾ�����˳���

184         if ((id=open(argv[3],O_RDONLY,0))<0)

185                 die("Unable to open 'system'");

186         if (read(id,buf,GCC_HEADER) != GCC_HEADER)

187                 die("Unable to read header of 'system'");

188         if (((long *) buf)[5] != 0)               // ִ����ڵ��ֶ�a_entryֵӦΪ0��

189                 die("Non-GCC header of 'system'");

190         for (i=0 ; (c=read(id,buf,sizeof buf))>0 ; i+=c )

191                 if (write(1,buf,c)!=c)

192                         die("Write call failed");

193         close(id);

194         fprintf(stderr,"System is %d bytes.\n",i);

195         if (i > SYS_SIZE*16)

196                 die("System is too big");

197         return(0);

198 }

199