a heavily commented linux kernel source...

652

Click here to load reader

Upload: nguyenque

Post on 13-Jul-2018

271 views

Category:

Documents


5 download

TRANSCRIPT

  • Linux0.11(0.95)

    www.oldlinux.org

    V1.9.5

    [email protected]

  • Linux 0.11 A Heavily Commented Linux Kernel Source Code

    Linux Version 0.11

    1.9.5

    Revision 1.9.5

    Zhao Jiong

    [email protected]

    www.plinux.org

    www.oldlinux.org

    2004-05-21

  • Linux (v0.11)

    Linux Linux LINUX Linux Linux 0.11(0.95)

    Linux

    .,.,,.:[email protected], : ( 1239 ,:200092).

    2002,2003,2004 by Zhao Jiong 2002,2003,2004 .

  • RTFSC Read The F**king Source Code !

    Linus Benedict Torvalds

  • - I -

    ................................................................................ 1

    ........................................................ 1 .................................................... 1 ........................................ 2 ........................ 2 ............................ 3 .................................... 3 ........................................ 4 EXT2 MINIX ......................... 4

    1 .................................................................. 5

    1.1 LINUX ........................................... 5 1.2 ........................................................... 10 1.3 ........................................................... 14

    2 LINUX .................................. 15

    2.1 LINUX ................................................. 15 2.2 LINUX ................................. 16 2.3 ........................................................... 18 2.4 ........................................................... 19 2.5 LINUX ................................................. 20 2.6 LINUX ......................... 26 2.7 LINUX ......................... 29 2.8 LINUX ......................... 32 2.9 ............................ 38 2.10 LINUX/MAKEFILE ...................................... 39 2.11 .......................................................... 47

    3 BOOT............................. 49

    3.1 ................................................................... 49 3.2 ........................................................... 49 3.3 BOOTSECT.S ................................................ 50 3.4 SETUP.S ....................................................... 58 3.5 HEAD.S ........................................................ 71 3.6 ........................................................... 80

    4 (INIT)......................................... 81

    4.1 ................................................................... 81 4.2 MAIN.C ........................................................ 81 4.3 ............................................... 91 4.4 ........................................................... 92

    5 (KERNEL)..................................... 95

    5.1 ................................................................... 95 5.2 ................................................... 95

    5.3 MAKEFILE ................................................... 98 5.4 ASM.S ........................................................ 100 5.5 TRAPS.C ..................................................... 106 5.6 SYSTEM_CALL.S ........................................ 113 5.7 MKTIME.C ................................................. 123 5.8 SCHED.C .................................................... 125 5.9 SIGNAL.C ................................................... 138 5.10 EXIT.C ..................................................... 147 5.11 FORK.C .................................................... 153 5.12 SYS.C ....................................................... 160 5.13 VSPRINTF.C .............................................. 166 5.14 PRINTK.C ................................................. 174 5.15 PANIC.C ................................................... 175 5.16 ........................................................ 176

    6 (BLOCK DRIVER)......... 177

    6.1 ................................................................. 177 6.2 .......................................................... 177 6.3 MAKEFILE ................................................. 180 6.4 BLK.H ........................................................ 182 6.5 HD.C .......................................................... 186 6.6 LL_RW_BLK.C ........................................... 202 6.7 RAMDISK.C ................................................ 207 6.8 FLOPPY.C ................................................... 212

    7 (CHAR DRIVER) ....... 239

    7.1 ................................................................. 239 7.2 .................................................. 239 7.3 MAKEFILE ................................................. 247 7.4 KEYBOARD.S ............................................. 249 7.5 CONSOLE.C ................................................ 267 7.6 SERIAL.C ................................................... 290 7.7 RS_IO.S ..................................................... 293 7.8 TTY_IO.C ................................................... 297 7.9 TTY_IOCTL.C ............................................. 308

    8 (MATH)................................ 317

    8.1 ................................................................. 317 8.2 MAKEFILE ................................................. 317 8.3 MATH-EMULATION.C .................................. 319

    9 (FS) ............................................... 321

    9.1 ................................................................. 321 9.2 .................................................. 321 9.3 MAKEFILE ................................................. 327

  • - II -

    9.4 BUFFER.C .................................................. 330 9.5 BITMAP.C ................................................... 345 9.6 INODE.C .................................................... 349 9.7 SUPER.C .................................................... 360 9.8 NAMEI.C .................................................... 369 9.9 FILE_TABLE.C ............................................ 390 9.10 BLOCK_DEV.C ......................................... 390 9.11 FILE_DEV.C .............................................. 394 9.12 PIPE.C ...................................................... 397 9.13 CHAR_DEV.C ........................................... 400 9.14 READ_WRITE.C ........................................ 403 9.15 TRUNCATE.C ............................................ 407 9.16 OPEN.C .................................................... 409 9.17 EXEC.C .................................................... 415 9.18 STAT.C ..................................................... 430 9.19 FCNTL.C .................................................. 431 9.20 IOCTL.C ................................................... 434

    10 (MM).......................................... 437

    10.1 ............................................................... 437 10.2 ............................................... 437 10.3 MAKEFILE ............................................... 442 10.4 MEMORY.C ............................................... 443 10.5 PAGE.S ..................................................... 457

    11 (INCLUDE) ................................... 459

    11.1 ............................................................... 459 11.2 INCLUDE/ ................................. 459 11.3 A.OUT.H ................................................... 460 11.4 CONST.H .................................................. 470 11.5 CTYPE.H .................................................. 471 11.6 ERRNO.H ................................................. 472 11.7 FCNTL.H .................................................. 474 11.8 SIGNAL.H ................................................. 476 11.9 STDARG.H ................................................ 478 11.10 STDDEF.H .............................................. 479 11.11 STRING.H ............................................... 480 11.12 TERMIOS.H ............................................ 490 11.13 TIME.H ................................................... 497 11.14 UNISTD.H ............................................... 498 11.15 UTIME.H ................................................ 504 11.16 INCLUDE/ASM/ ....................... 505 11.17 IO.H ....................................................... 505 11.18 MEMORY.H ............................................. 506 11.19 SEGMENT.H ........................................... 507 11.20 SYSTEM.H .............................................. 509 11.21 INCLUDE/LINUX/ .................... 512 11.22 CONFIG.H ............................................... 512 11.23 FDREG.H ............................................ 514 11.24 FS.H ....................................................... 517 11.25 HDREG.H ................................................ 523 11.26 HEAD.H ................................................. 525

    11.27 KERNEL.H .............................................. 526 11.28 MM.H ..................................................... 527 11.29 SCHED.H ................................................ 527 11.30 SYS.H ..................................................... 535 11.31 TTY.H ..................................................... 537 11.32 INCLUDE/SYS/......................... 540 11.33 STAT.H ................................................... 540 11.34 TIMES.H ................................................. 541 11.35 TYPES.H ................................................. 542 11.36 UTSNAME.H ........................................... 543 11.37 WAIT.H ................................................... 544

    12 (LIB)............................................... 547

    12.1 ............................................................... 547 12.2 MAKEFILE ............................................... 548 12.3 _EXIT.C ................................................... 550 12.4 CLOSE.C .................................................. 550 12.5 CTYPE.C .................................................. 551 12.6 DUP.C ...................................................... 552 12.7 ERRNO.C .................................................. 553 12.8 EXECVE.C ................................................ 553 12.9 MALLOC.C ............................................... 554 12.10 OPEN.C .................................................. 562 12.11 SETSID.C ................................................ 563 12.12 STRING.C ............................................... 564 12.13 WAIT.C ................................................... 564 12.14 WRITE.C ................................................ 565

    13 (TOOLS) .................................... 567

    13.1 ............................................................... 567 13.2 BUILD.C ................................................... 567

    14 ........................ 574

    14.1 ............................................................... 574 14.2 BOCHS ............................................ 574 14.3 ........................................ 578 14.4 ........................ 581 14.5 ............................................ 584 14.6 LINUX 0.11 0.11 ........... 590 14.7 REDHAT 9 LINUX 0.11 .. 591 14.8 BOCHS ................................... 594

    .................................................................... 595

    ............................................................................ 596

    1 ............................................ 596 2 ............................................ 599 3 80X86 ................................. 607 4 ASCII ................................................. 617

    ............................................................................ 618

  • - 1 -

    Linux

    Linux linux linux Linux UNIX Linux

    Linux Linux Redhat 7.0 2.2.16 Linux 2.2.20 268 Linux Linux Scott Maxwell Linux Linux Linux (*.h) make Linux Linux

    John Lions UNIX UNIX UNIX V6 PDP-11 A.S.Tanenbaum MINIX Linux Linux Linux Linux Linux

  • - 2 -

    Linux 1991 10 Linux Linus Toravlds Linux 0.03 LINUX--a free unix-386 kernel Linux ... GNU Hurd Linux GNU Hurd Linux Linux Linux

    Linux DJJ x86Uclinux www.linux.org Linux Linux Linux Linux

    Leland L. Beck (SIC) Linux Leland Linux Linux

    Linux VFS a.out Linux

    Linux RTFSC Read The Fucking Source Code

    M.J.Bach UNIX UNIX

    AST I/O

  • - 3 -

    Linux Linux 0.11 Linux

    1000

    10000

    100000

    1000000

    10000000

    V0.01

    V0.11

    V0.12

    V0.95

    V0.96a

    V0.97

    V1.0

    V1.1.52

    V1.2.13

    V1.3.95

    V2.0.38

    V2.2.20

    V2.4.17

    Linux 0.11 2 VFSext2 ext3

    80x86 80x86 INTEL 80386 Programmer's Reference Manual 80x86 Linux Linux M.J.Bach UNIX

  • - 4 -

    Linus Linux MINIX Linux MINIX 1.0 A.S.Tanenbaum Tanenbaum Linux

    Linux Linux Tanenbaum Linux is obsolete Linux

    Ext2 MINIX

    Linux Ext2 Ext3 1.x Linux Linux

    Linux 0.11 MINIX 1.0 Linux Linux Linux 2002.12

  • 1.1 Linux

    - 5 -

    1

    Linux Linux Linux

    1.1 Linux

    Linux UNIX 1991 10 5 Internet UNIX Linux UNIX MINIX GNU POSIX Internet Linux Linux Linus Toravlds Linux 0.01 hacker 1.0 Linux Linux 2.5.52 Linux 2.4.20 2 Linux

    1.1.1 UNIX Linux UNIX UNIX Ken.Thompson Dennis Ritchie 1969 DEC PDP-7 Ken Thompson PDP-7 Space travel 1969 UNIX BCPL Dennis Ritchie 1972 C UNIX

    1.1.2 MINIX MINIX Andrew S. TanenbaumASTAST Amsterdam Vrije ACM IEEE () 100 5 AST (1914 )M.I.T Berkeley Vrije Amsterdam AST MINIX 1987 1991 1.51.5 2.0

  • 1.1 Linux

    - 6 -

    MINIX FTP Linux Linus Linux MINIX MINIX Linus Linux Linus MINIX C hacker

    1.1.3 GNU GNU FSF(the Free Software Foundation) Richard M. Stallman 1984 UNIX GNU GNU "GNU's Not Unix""guh-NEW" Linux GNU "Linux" Stallman GNU/Linux 90 GNU emacs bash shell gcc gdb Linux Linux Linux GNU/Linux

    1.1.4 POSIX POSIXPortable Operating System Interface for Computing Systems IEEE ISO/IEC UNIX 1980 UNIX (usr/group)UNIX AT&T System V Berkeley CSRG BSD 1984 /usr/group 1985 IEEE TCOS-SS ANSI IEEE 1986 4 IEEE 1988 9 IEEE 1003.1-1988POSIX.1 1989 POSIX ISO/IEC 15 ISO 1990POSIX.1 C IEEE 1003.1-1990 ANSI ISO/IEC 9945-1:1990 POSIX.1 API IEEE POSIX 300 (POSIX.2)POSIX.3 APIPOSIX.4 1990 25 16 X/OpenAT&TOSF 90 POSIX 1991-1993 Linux UNIX Linux Linux UNIX Linux 0.01 0.11 Linux POSIX Linux 0.01 /include/unistd.h POSXI Linus OK

  • 1.1 Linux

    - 7 -

    1991 7 3 comp.os.minix post POSIX POSIX

    1.1.5 Linux 1981 IBM IBM PC 1981-1991 MS-DOS

    Apple MACs UNIX UNIX UNIX PC Bell Labs UNIX PC MINIX AST

    Linux Linus Benedict Torvalds (1991 )Linus Benedict Torvalds hacker 21 GNU GNU C GNU MINIX GNU HURD Linus 386 MINIX MINIX Linus Intel 80386 Modem 80386 CPU MINIX MINIX Linus GNU GNU CGNUHURD Linus 1991 4 Intel 386 Linux Linus comp.os.minix MINIX Linux Linus 1 comp.os.minix 1991 3 29 gcc on minix-386 doesn't optimize, gcc MINIX-386 MINIX-386 Bruce Evans Intel 386 32 MINIX Linus 1991 MINIX MINIX MINIX Intel 80386 MINIX RTFSC (Read the F**ing Source Code :-)

  • 1.1 Linux

    - 8 -

    1991 4 Linus MINIX-386 (Hacking the kernel) GNU (GNU gccbashgdb ) 4 13 comp.os.minix bash MINIX shell Linux 1991 7 3 comp.os.minix Linux Linus FREAX FREAX Linux POSIX Linus (1991 8 25 comp.os.minix) MINIX What would you like to see in minix?( MINIX )()386(486) GNU MINIX MINIX MINIX bash(1.08) gcc(1.40 ) Linus MINIX 386 AT Linux Linus Linux 1991 10 5 Linus comp.os.minix Linux Free minix-like kernel sources for 386-AT Linux 10 5 Linux Linux RedHat

    1.1.6 Linux Linux 1.0 11

    11

    0.00 (1991.2-4) AAABBB

    0.01 (1991.8) Linux

    0.02 (1991.10.5) 0.03

    0.10 (1991.10) Ted Tso Linux

    0.11 (1991.12.8)

    0.12 (1992.1.15)

    0.95(0.13) (1992.3.8)

    CDROM

    0.96 (1992.5.12)

    X-Windows

    0.97 (1992.8.1) SCSI

    0.98 (1992.9.29) TCP/IP0.8.1 extfs

    0.99 (1992.12.13) 4G

    1.0 (1994.3.14)

  • 1.1 Linux

    - 9 -

    Linux 0.13 0.95 Linus 1.0 0.95 () Linus 2003 12 18 2.6.2 15000 gz 40MB 12

    12

    ( gz )

    2.4.22 2004.2.4 35MB

    2.6.5 2004.4.4 41MB

    1.1.7 Linux Linux LinuxLinus FREAX ftp.funet.fi Ari Lemke Linus Linux Linux Linus Just for FunLinus 1 Linux Freax Makefile - - Freax Ari Lemke ftp Freax (Linux)

    1.1.8 Linux Linux Linux Linus Theodore Ts'o (Ted Ts'o) 1990 MIT Hacking on Linux IBM IETF Linux Linux linux Maillist Linux Linux Linux Linux 0.10 ramdisk.c kmalloc.c) Linux Linux ftp tsx-11.mit.edu Linux Linux ext2 Linux ext3 97 2002 5 Linux Journal IBM Linux

    1 Linus TorvaldsJust for fun 84-88

  • 1.2

    - 10 -

    Linux LSB(Linux Standard Base) Linux Alan Cox(Swansea University College) MUDMulti-User Dungeon or Dimension 90 games.mud posts MUD (rec.games.mud 1992 3 9 A history of MUD) MUD

    MINIX Linux 0.11 386BSD 386SX 386BSD Intel 386SX CPU Linux Linux Linux Linux Linux (beautifully) Linux 0.95 Linux Linus Linux TCP/IP Linux Linux Linux Linus Microsoft 2001 Linux 2.4.x Linus ( 2.5.x) The Linux Kernel Hackers' Guide Michael K. Johnson Linux ( 0.97 ) Linux Linux Document Project - LDP Linux Journel RedHat Linux Linux Linux CREDITS Linux 400 email Linux UNIX -- UNIX 1969 Bell Linux UNIX UNIX MINIX -- MINIX UNIX 1987 Andrew S. Tanenbaum MINIX () UNIX Linux MINIX 1991 GNU -- Linux Linux GNU Linux GNU ( bash shell) Linux POSIX -- Linux Linux INTERNET -- Intenet Linux 0.13(0.95)

    1.2

    Linux 0.11 Linux-0.11 1991 12 8

  • 1.2

    - 11 -

    bootimage.Z -

    rootimage.Z - 1200kB

    linux-0.11.tar.Z - 94KB 325KB

    as86.tar.Z - Bruce Evans' 16

    INSTALL-0.11 -

    rootimage.Z Internet Linux 0.11 rootimage-0.11 0.11 gcc 1.40 oldlinux.org linux-0.11 Makefile shell C GNU C / Intel 8259A

    Linux 0.11 Linux Linux-0.11 325K Linux 2.5.XX 188 Linux 0.01 240K 0.01

    0.11 0.11 (bootimage)(rootimage) Linux 0.11 TCP/IP Linux Linux Linux

    Linux 1.1 linux

  • 1.2

    - 12 -

    1-1 Linux/

    (GMT)

    boot/ 1991-12-05 22:48:49

    fs/ 1991-12-08 14:08:27

    include/ 1991-09-22 19:58:04

    init/ 1991-12-05 19:59:04

    kernel/ 1991-12-08 14:08:00

    lib/ 1991-12-08 14:10:00

    mm/ 1991-12-08 14:08:21

    tools/ 1991-12-04 13:11:56

    Makefile 2887 bytes 1991-12-06 03:12:46

    1 4 32 5 10 5 11 13 2 Linux Linux Linux/Makefile make 3 boot/ bootsect.s BIOS setup.s 32 head.s 32 4 init/ main.c shell

    main.c Linux 5 kenel/ schedule()sleep_on() 6 kernel/dev_blk/

    7 kernel/dev_chr/ 0.11 8 kernel/math/ 9 fs/Andrew S. Tanenbaum MINIX Linux MINIX Linux 0.11

  • 1.2

    - 13 -

    10 mm/ Intel 80X86 80X86 Intel 80386 (Intel 80386 Programmer's Reference Manual) Linux 11 include/

    12 Linux 0.11 lib/

    0.11 13 tools/ build.c(image)kernel image 14 Bochs Linux Linux 0.11 RedHat 9 Linux PC

    Linux LDPLinux Document Project HOWTO LDP Linus Linux 3 M. J. Bach UNIX UNIX System V Linus Linux John H. Crawford Programming the 8038680x86 Andrew S.Tanenbaum MINIX 1 Linus MINIX 1.0 Linux

    Tanenbaum

    C

    Linux

  • 1.3

    - 14 -

    Linux Linux GURU 1.0 Linux 2.5.44 patch

    1.3

    Linux UNIX Linux Rechard Stallman GNU Linux POSIX Linux A.S.T MINIX LinuxInternet Linux

  • 2.1 Linux

    - 15 -

    2 Linux Linux Linux

    Linux/ Makefile 4 2-1 Internet Linux X shell

    2-1

    Linux Linux 0.11 Linux Linux 0.11

    2.1 Linux

    Linux 0.11 (int x80) CPU User ModeKernel Model

  • 2.2 Linux

    - 16 -

    2-2

    2-2

    2.2 Linux

    Linux 5 CPU CPU Linux

    2-3 Linux 0.11 Linux 0.95 0.96

  • 2.2 Linux

    - 17 -

    2-3Linux

    3

    NFSramdisk Linux 0.11 2-4

  • 2.3

    - 18 -

    2-4

    2.3

    80X86 PC 8259A 8 64 PC/AT 8259A 15 2-5 INT IR2 8259A 0x20 0xA0

  • 2.4

    - 19 -

    2-5 PC/AT 8259

    8259A CPU IN OUT 8259A IRQ0 IRQ15 CPU INT CPU CPU D7-D0 CPU Linux () 0-255 int0--int31(0x00--0x1f) Intel , Intel CPU (Fault)(traps) int32--int255 (0x20--0xff) Linux int32--int47(0x20--0x2f) 8259A IRQ0-IRQ15(system_call) int128(0x80)

    2.4

    Linux 0.11 PC Intel 8253 10 IRQ0 1 1 timer_interrupt jiffies 1 CPL do_timer() do_timer() CPL=0 stime 1 1 0 1

    IR0IR1 INTIR2 IR3 8259A IR4 IR5 IR6 IR7 A0 CS CAS2-0

    IRQ0 IRQ1 int IRQ2 2 IRQ3 1 IRQ4 2 IRQ5 IRQ6 1 IRQ7 0x20-0x3f

    IR0 CAS2-0IR1 INTIR2 IR3 8259A IR4 IR5 IR6 IR7 A0 CS

    IRQ8 INT0AH IRQ9 IRQ10 IRQ11 PS2 IRQ12 IRQ13 IRQ14 IRQ15 0xA0-0xbf

    INTR CPU

    D7-D0

  • 2.5 Linux

    - 20 -

    0 do_timer() 0 CPU 0 do_timer() schedule() do_timer() Linux

    2.5 Linux

    process Linux CPU

    CPU 15 =150 Linux 0.11 64 fork child processparent processprocess IDpid

    CPU Linux kernel modeuser modeLinux

    2.5.1 Linux task_struct include/linux/sched.h PCBProcess Control Block PDProcessor Descriptor

    struct task_struct {

    long state //-1 0 ()>0

    long counter // ()

    long priority // counter=priority

    long signal // =+1

    struct sigaction sigaction[32] //

    long blocked //

    int exit_code //

    unsigned long start_code //

    unsigned long end_code //

    unsigned long end_data // +

    unsigned long brk //

    unsigned long start_stack //

  • 2.5 Linux

    - 21 -

    long pid // ()

    long father //

    long pgrp //

    long session //

    long leader //

    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 alarm //

    long utime //

    long stime //

    long cutime //

    long cstime //

    long start_time //

    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

    unsigned long close_on_exec // include/fcntl.h

    struct file * filp[NR_OPEN] // 32

    struct desc_struct ldt[3] // 0-1- cs2- ds&ss

    struct tss_struct tss //

    };

    CPU switch Linux

    2.5.2 2-6 state Linux

  • 2.5 Linux

    - 22 -

    2-6

    TASK_RUNNING

    CPU running

    TASK_RUNNING TASK_INTERRUPTIBLE

    TASK_UNINTERRUPTIBLE

    wake_up()

    TASK_STOPPED SIGSTOPSIGTSTPSIGTTIN SIGTTOU SIGCONT Linux 0.11

    TASK_ZOMBIE

    sleep_on() sleep_on_interruptible() CPU TASK_UNINTERRUPTIBLE TASK_INTERRUPTIBLE

    running

    ,

    running

    zombie

    stopped

    interruptible

    uninterruptible

    1

    2

    3

    40

    0

    0

    running

  • 2.5 Linux

    - 23 -

    2.5.3 boot/ init/main.c

    0 0 fork() 1 1 shell 0 0 pause() 0 move_to_user_modeinclude/asm/system.h main.c 0 3 0 sched_init() 0 0 include/linux/sched.h 0 TSSLDT tr ldtr 0 0 0 0 640KB 0 16MB 0 main.c 0 0 0 main.c move_to_user_mode 0 3 0 move_to_user_mode 0 3 iret CPU 0 3 2-7

    2-7

    move_to_user_mode 0 0 iret iret CPU CS:EIP CPU 3 0 CPU SS:ESP DSESFS GS CPU iret

    031 SS

    CS

    ESP

    EFLAGS

    EIP

    SP0 - (TSS SS:ESP)

    SP1 - iret SS:ESP

  • 2.5 Linux

    - 24 -

    3 0 PAGE_SIZE + (long)&init_task 0 0 1 1

    2.5.4 Linux fork() 0 0 64 fork()

    TASK_UNINTERRUPTIBLE 15 150 TSS 0 tss.eax = 0 tss.esp0 tss.ss0 tss.ldt GDT tss.i387 1 GDT TSS LDT tss ldt

    2.5.5 Linux TASK_RUNNING CPU Linux 0.11 schedule()TASK_RUNNING counter TASK_RUNNING priority counter

    prioritycountercounter +=2

    schdeule() TASK_RUNNING switch_to() 0Linux 0.11 0 pause() schedule()schedule() 0

  • 2.5 Linux

    - 25 -

    0 switch_to()switch_to()

    current TSS CPU CPU TR TSS tss tss CPU 2-8

    2-8

    2.5.6 exit() do_exit()

    i init SIGHUP TASK_ZOMBIE SIGCHLD do_exit()

    80386 CPU tss

    GDT

    tss

    CR3

    TSS

    TSS

    EAX

    EBX

    ECX

    EDX

    ESI

    EDI

    EBP

    ESP

    EIP

    EFLAGS

    CS

    DS

    ES

    FS

    GS

    SS

    LDTR

    32 ljmp

    TR

    # TSS CPU

  • 2.6 Linux

    - 26 -

    wait() waitpid()

    2.6 Linux

    Linux 0.11 2-9

    2-9

    Linux

    RAM CPU Intel CPU Segmentation SystemPaging SystemLinux Intel CPU Linux 0.11 3 a. b. CPU c. Logical Address Intel

    Linear Address

    Intel 80386 4G

    0 1M 640K

    BIOS ROM

  • 2.6 Linux

    - 27 -

    Physical Address CPU

    Virtual Memory

    3

    Linux 0.11 64MB 0x0000000 0x4000000

    CPU

    ,

    CPU

    CPU 80386 CPU CR2

    Swapper Linux 0.11 mm/memory.c Intel CPU Segment

    Linux 0.11 CPU GDT LDT LDT LDT 2-10

  • 2.6 Linux

    - 28 -

    2-10 Linux

    idtLinux 0.11 Linux 0.11 4096 Intel 80386 CPU 4G Linux 0.11 GDT 256 2 2 (256-4)/2 + 1=127 ((256-4)/2)* 64MB 8G 0.11 NR_TASKS = 64 64M(-1)*64MB 64MB*64 =4G 2-11 4G CPU 0.11

    0 64M

    ()0 2 1

    128M 192M 4G

    - - -

    ldtN

    tssN

    0

    Data

    Code

    0

    0

    1

    Data

    Code

    1

    1

    ldt1

    tss1

    ldt0

    tss0

    sys

    Data

    Code

    NULL

    GDT LDT

    LDT

  • 2.7 Linux

    - 29 -

    2-11 Linux 0.11

    CPU PDT PT 64MB*64M 10 Linux 0.99 4G

    2.7 Linux

    Linux Linux 0.11 0

    2.7.1 (bootsect.ssetup.s) bootsect ROM BIOS 0x7c00 bootsect 0x9000:0 SS 0x9000esp 0xff00 0x9000:0xff00 boot/bootsect.s 6162 setup.s bootsect (head.s) head.s 0x10 esp user_stack head.s 31 1 4Kuser_stack sched.c 67--72 1024 2-12

  • 2.7 Linux

    - 30 -

    2-12

    (main.c) main.c move_to_user_mode()move_to_user_mode()main.c 0 fork()main.c init() 1 1 main() 0 0 0

    2.7.2 4096 3K 64MB 0 64MB 64MB CPU Linux Copy on Write task_structfork() tss (tss.esp0 tss.ss0)kernel/fork.c93 p->tss.esp0 = PAGE_SIZE + (long)p;

    p->tss.ss0 = 0x10;

    p tss task_struct tss task_struct tss.ss0

    kernel

    0x0000

    ss

    esp

    system

    kernel

    user_stack[1k],1

    *task[]

    main

    gdt(2k)

    idt(2k)

    (4k X 4)

    (4k)

    head

    sched

  • 2.7 Linux

    - 31 -

    0x10 tss.esp0 task_struct 2-13

    2-13

    tss.ss0 0x10 head.s 16MB Linux 0.11 head.s110 Linux 0.98 1GB CPU TSS (esp0) CPU 0 0 0 0 640KB move_to_user_mode() sched.c user_stack 0 movie_to_user_mode() iret esp user_stack ss 0x17 0 640KB 2-7

    2.7.3

    eflags iret eflags 2-14

    (current)

    (esp0)

    1 (4096 )

  • 2.8 Linux

    - 32 -

    2-14

    2.8 Linux

    Linux

    Linux

    tar linux-0.11.tar.gz linux/ 2-15

    2-15 Linux

    14 102

    2.8.1 linux linux 14 Makefile make make

    SS

    ESP

    EFLAGS

    CS

    EIP

    IRET

    INT

    linux

    boot

    fs

    include (*.h)

    asm CPU

    linux Linux

    sys

    init

    kernel

    blk_drv

    chr_drv

    math

    lib

    mm

    tools Image

  • 2.8 Linux

    - 33 -

    make linux Makefile Makefile linuxmake linux make

    2.8.2 boot boot 3 3 32 bootsect.s setup.s as86 as86 head.s GNU as AT&T bootsect.s 0 0 1 PC ROM BIOS BIOS 0x7C00 setup.s system head.s system

    2.8.3 fs Linux 0.11 1.0 MINIX Linux MINIX MINIX MINIX Linux MINIX Linux MINIX MINIX Linux Linux Linux MINIX Linux sleep() fs/ 17 C 2-16 .c

  • 2.8 Linux

    - 34 -

    2-16 fs

    buffer.c file_table.c ioctl.c

    kernel/chr_drv/tty.c io exec.c do_execve() exec()fcntl.c i/o read_write.c /stat.c open.c

    char_dev.c rw_char()pipe.c file_dev.c i namei.c block_dev.c inode.c i truncate.c bitmap.c i super.c buffer.c ll_rw_block fs kernel/blk_drv/ll_rw_block.c

    ll_rw_block()

    read_write

    block dev char dev

    bitmap

    buffer

    file devpipe

    inode

    super

    exec

    truncate

    namei

    open

    ll_rw_block

    ioctlfile_table

    stat

    fcntl

  • 2.8 Linux

    - 35 -

    2.8.4 include 32 .h 13 asm 4 linux 10 sys 5 a.out a.out i i_mode (Linus minix ) -va_listva_start, va_arg va_end vsprintfvprintfvfprintf NULL, offsetof(TYPE, MEMBER) tm Linux __LIBRARY___syscall0() utime() include/asm CPU 4 io io memcpy() / Linux include/linux HD_TYPE file,buffer_head,m_inode head task_struct 0 72 C ,'sys_' tty tty_io include/sys stat{} tms times() wait() waitpid()

  • 2.8 Linux

    - 36 -

    2.8.5 init main.c shell task 0 fork() init() shell

    2.8.6 kernel linux/kernel 12 Makefile 3 kernel/ forkexit get_hd_block tty_write

    2-17

    2-17

    asm.s traps.c traps.c C exit.c fork.c sys_fork() C find_empty_process()copy_process() mktime.c mktime() 1970 1 1 0 init/main.c panic. panic() printk.c printk() sched.c (sleep_onwakeupschedule ) signal.c4 do_signal() sys.c system_call.s Linux int 0x80 C Linux

    mktime

    schedule.c

    panic.c

    pintk,vsprintf

    asm.s

    traps.c

    system_call.s

    fork.c,sys.c,exit.c,signal.c

  • 2.8 Linux

    - 37 -

    vsprintf.c kernel/blk_drv

    blk_drv 4 c 1 blk.h C 2-18

    2-18 blk_drv

    blk.h 3 C hd.c / do_hd__request()floppy.c / do_fd_request() ll_rw_blk.c /ll_rw_block() fs/buffer.c kernel/chr_drv 4 C 2 rs-232 2-19

    2-19

    tty_io.c tty tty_read() tty_write() C do_tty_interrupt()

    console.c con_write() tty con_init() rs_io.s 0x3fa 0x2fa 4 do_tty_interrupt() serial.c UART

    ll_rw_blk.c

    hd.c floppy.c

    blk.h

    ramdisk.c

    tty_io.c

    serial.c rs_io.s

    tty_ioctl.c

    console.c keyboard.S

  • 2.9

    - 38 -

    tty rs_write() tty_ioctl.c tty io tty_ioctl() termio(s) io sys_ioctl() fs/ioctl.c keyboard.S keyboard_interrupt kernel/math C math_emulate.c math_emulate() int7 C CPU

    SIGFPE

    2.8.7 lib init/main.c 01 libc lib/ 12 C tytso malloc.c _exit() close(fd) dup() open() write() execve() malloc() wait() setsid() include/string.h

    2.8.8 mm 2

    Linux 386 4G 64 64MB fork page.s int 14 memory.c mem_init() page.s do_no_page() do_wp_page()

    2.8.9 tools build.c Linux image

    2.9

    Linux 5 int 0x80 12 C libc C

  • 2.10 linux/Makefile

    - 39 -

    libc ID include/linux/unistd.h Linux LSBLinux Standard Base Linux 2 C / I/O fopen fclose open close

    3

    2.10 linux/Makefile

    linux Makefile

    2.10.1 Makefile make

    Makefile make Makefile make make Makefile

    Makefile make make Makefile (last-modification time) Makefile Makefile '#''=' Makefile make tools/ build image boot/bootsect.ssetup.s 8086 GNU gcc/gas system build image. / 2-20

  • 2.10 linux/Makefile

    - 40 -

    2-20 /

    2.10.2 2-1 linux/Makefile

    1 #

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

    3 # size in blocks. #

    4 #

    5 RAMDISK = #-DRAMDISK=512

    6

    7 AS86 =as86 -0 -a # 8086

    8 LD86 =ld86 -0 # -0 8086 -a gas gld

    9

    10 AS =gas # GNU

    11 LD =gld

    12 LDFLAGS =-s -x -M # GNU gld -s

    # -x -M

    # ()(link map)

    #

    #

    #

    #

    #

    13 CC =gcc $(RAMDISK) # gcc GNU C UNIX (script)

    # $

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

    15 -fcombine-regs -mstring-insns # gcc '\'

    # -Wall -O

    # -fstrength-reduce -mstring-insns

    # Linus gcc gcc gcc-1.40

    # 386 CPU

    16 CPP =cpp -nostdinc -Iinclude # cpp gcc ()-nostdinc -Iinclude

    # -I

    #

    head main kernel mm fs lib

    bootsect setup system

    Build

    Image

  • 2.10 linux/Makefile

    - 41 -

    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 #

    23 ROOT_DEV=/dev/hd6 # ROOT_DEV (image)

    # (FLOPPY)/dev/xxxx

    # build tools//dev/hd6

    24

    25 ARCHIVES=kernel/kernel.o mm/mm.o fs/fs.o # kernel mm fs

    #

    # ARCHIVES

    26 DRIVERS =kernel/blk_drv/blk_drv.a kernel/chr_drv/chr_drv.a # .a

    #

    # GNU ar ar GNU

    #

    27 MATH =kernel/math/math.a #

    28 LIBS =lib/lib.a # lib/

    29

    30 .c.s: # make make

    # .c .s ':'

    31 $(CC) $(CFLAGS) \

    32 -nostdinc -Iinclude -S -o $*.s $< # gcc CFLAGS

    # include/

    # -S C

    # C .c

    # .s -o $*.s$@

    # $ Image

    43 sync # tools build

    # bootsectsetup system

    # $(ROOT_DEV) Image

    # sync

    44

    45 disk: Image # disk Image

    46 dd bs=8192 if=Image of=/dev/PS0 # dd UNIX

    # bs=/

    # if=of=

  • 2.10 linux/Makefile

    - 42 -

    # /dev/PS0 ()

    47

    48 tools/build: tools/build.c # tools build.c build

    49 $(CC) $(CFLAGS) \

    50 -o tools/build tools/build.c # build

    51

    52 boot/head.o: boot/head.s # .s.o head.o

    53

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

    55 $(ARCHIVES) $(DRIVERS) $(MATH) $(LIBS) # tools system

    #

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

    57 $(ARCHIVES) \

    58 $(DRIVERS) \

    59 $(MATH) \

    60 $(LIBS) \

    61 -o tools/system > System.map # system > System.map

    # gld System.map

    # System.map

    62

    63 kernel/math/math.a: # math.a

    64 (cd kernel/math; make) # kernel/math/ make

    # 66--82

    65

    66 kernel/blk_drv/blk_drv.a: # blk_drv.a

    67 (cd kernel/blk_drv; make)

    68

    69 kernel/chr_drv/chr_drv.a: # chr_drv.a

    70 (cd kernel/chr_drv; make)

    71

    72 kernel/kernel.o: # kernel.o

    73 (cd kernel; make)

    74

    75 mm/mm.o: # mm.o

    76 (cd mm; make)

    77

    78 fs/fs.o: # fs.o

    79 (cd fs; make)

    80

    81 lib/lib.a: # lib.a

    82 (cd lib; make)

    83

    84 boot/setup: boot/setup.s # 8086

    85 $(AS86) -o boot/setup.o boot/setup.s # setup.s setup

    86 $(LD86) -s -o boot/setup boot/setup.o # -s

    87

    88 boot/bootsect: boot/bootsect.s # bootsect.o

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

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

    91

    92 tmp.s: boot/bootsect.s tools/system # 92--95 bootsect.s

    # system SYSSIZE = system

    # tmp.s bootsect.s system

  • 2.10 linux/Makefile

    - 43 -

    # ls system grep

    # tmp.s cut tr

    # ( + 15)/16 1 = 16

    93 (echo -n "SYSSIZE = (";ls -l tools/system | grep system \

    94 | cut -c25-31 | tr '\012' ' '; echo "+ 15 ) / 16") > tmp.s

    95 cat boot/bootsect.s >> tmp.s

    96 a

    97 clean: # 'make clean' 98--103

    # 'rm'-f

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

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

    100 (cd mm;make clean) # mm/ Makefile clean

    101 (cd fs;make clean)

    102 (cd kernel;make clean)

    103 (cd lib;make clean)

    104 a

    105 backup: clean # clean linux/

    # backup.Z 'cd .. ' linux/

    # 'tar cf - linux' linux/ tar -cf

    # '| compress -' tar ('|')

    # compress backup.Z

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

    107 sync #

    108

    109 dep:

    # make

    # make

    # *.c

    # sed Makefile Makefile

    # '### Dependencies' 118 tmp_make

    # 110 init/ C

    # main.c gcc -M

    # make make

    # --

    # 111 $$i $($i)$i shell

    # tmp_make Makefile

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

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

    112 cp tmp_make Makefile

    113 (cd fs; make dep) # fs/ Makefile

    114 (cd kernel; make dep)

    115 (cd mm; make dep)

    116

    117 ### Dependencies:

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

    119 include/sys/types.h include/sys/times.h include/sys/utsname.h \

    120 include/utime.h include/time.h include/linux/tty.h include/termios.h \

    121 include/linux/sched.h include/linux/head.h include/linux/fs.h \

    122 include/linux/mm.h include/signal.h include/asm/system.h include/asm/io.h \

    123 include/stddef.h include/stdarg.h include/fcntl.h

  • 2.10 linux/Makefile

    - 44 -

    2.10.3 Makefile makefile make Make makefile makefile GNU make make makefile make makefile make makefile make

    make makefile makefile make make C C (object file) makefile

    (target)... : (prerequisites)... (command) ... ... ''''('clean')'''' make make

    $^$

  • 2.10 linux/Makefile

    - 45 -

    $

  • 2.10 linux/Makefile

    - 46 -

    -m

    -n

    -o

    -s

    -u

    -w

    ld

    Minix a.out

    ld [-03Mims[-]] [-T textaddr] [-llib_extension] [-o outfile] infile...

    GNU-Minix a.out

    ld [-03Mimrs[-]] [-T textaddr] [-llib_extension] [-o outfile] infile...

    ():

    -03 32

    outfile a.out

    -0 16 -lx i86

    -3 32 -lx i386

    -M

    -T ( strtoul )

    -i I&D

    -lx /local/lib/subdir/libx.a

    -m

    -o

    -r

    -s

    System.map System.map System.map System.map System.map c03441a0 B dmi_broken

    c03441a4 B is_sony_vaio_laptop

    c03441c0 b dmi_ident

    c0344200 b pci_bios_present

    c0344204 b pirq_table

    dmi_broken c03441a0

    System.map ( klogd) klogd System.map klogd System.map /boot/System.map

    /System.map

    /usr/src/linux/System.map

  • 2.11

    - 47 -

    System.map klogdlsofps dosemu System.map

    2.11

    Linux Linux 0.11 RedHat 9 Linux 0.11 Linux makefile

  • 3.1

    - 49 -

    3 boot

    3.1

    boot/ 3-1 bootsect.s setup.s Intel Intel 8086 as86 ld86 head.s GNU GNU as AT&T Intel x86 GNU i386 CPU

    3-1 linux/boot/

    () (GMT)

    bootsect.s 5052 bytes 1991-12-05 22:47:58

    head.s 5938 bytes 1991-11-18 15:05:09

    setup.s 5364 bytes 1991-12-05 22:48:10

    8086 Intel 80X86 PC 80386 32 PC 80386 32

    3.2

    Linux PC 80x86 CPU 0xFFFF0 ROM-BIOS PC BIOS 0 512 0x7C00 Linux 8086 (boot/bootsect.s) BIOS 0x7C00(31KB) 0x90000(576KB) 2kB(boot/setup.s) 0x90200 system 0x10000 system 0x80000 512KB 0x90000 bootsect setup setup system system 3-1 Linux

  • 3.3 bootsect.s

    - 50 -

    "Loading..." boot/setup.s

    3-1

    vga 0x10000 0x0000 0x0000 32 : IDTGDT LDT init/main.c main() boot/head.S

    0x0000 setup setup ROM BIOS BIOS 0x400 (1Kb) BIOS

    3.3 bootsect.s

    3.3.1 bootsect.s 0 0 1 PC ROM BIOS BIOS 0x7C00 0x90000 setup setup.s bootsect 0x90200, BIOS 0x13

    1 2 3 4 5 6

    0x7c00

    0x0000

    0x90000

    0x10000

    0xA0000

    bootsect.s

    setup.s

    system

    system head.s

    0x90200

  • 3.3 bootsect.s

    - 51 -

    Loading system... system 0x10000

    1.44M A root_dev( 0x508 ) setup 0x90200 setup

    3.3.2 3-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 1 0x3000

    ! 0x30000 =196 kB 1024 1KB 192KB

    5 !

    6 SYSSIZE = 0x3000 ! system 2.1 92

    !

    7 !

    8 ! bootsect.s (C) 1991 Linus Torvalds

    9 !

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

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

    12 !

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

    14 ! at 0x10000, using BIOS interrupts.

    15 !

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

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

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

    19 ! buffer cache as in minix

    20 !

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

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

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

    !

    !

    ! bootsect.s (C) 1991 Linus Torvalds

    !

    ! bootsect.s bios- 0x7c00 (31k)

    ! 0x90000 (576k)

    !

    ! BIOS 'setup'(0x90200)(576.5k)

    ! system 0x10000

    !

    ! ! (8*65536)(512k)

    ! 512k

    ! minix

    !

    !

    !

    24

  • 3.3 bootsect.s

    - 52 -

    25 .globl begtext, begdata, begbss, endtext, enddata, endbss ! 6

    26 .text !

    27 begtext:

    28 .data !

    29 begdata:

    30 .bss ! (Block Started by Symbol)

    31 begbss:

    32 .text !

    33

    34 SETUPLEN = 4 ! nr of setup-sectors

    ! setup (setup-sectors)

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

    ! bootsect

    36 INITSEG = 0x9000 ! we move boot here - out of the way

    ! bootsect --

    37 SETUPSEG = 0x9020 ! setup starts here

    ! setup

    38 SYSSEG = 0x1000 ! system loaded at 0x10000 (65536).

    ! system 0x1000064 kB

    39 ENDSEG = SYSSEG + SYSSIZE ! where to stop loading

    !

    40

    41 ! ROOT_DEV: 0x000 - same type of floppy as boot.

    !

    42 ! 0x301 - first partition on first drive etc

    !

    43 ROOT_DEV = 0x306 ! 2 1 Linux

    ! ,

    ! =*256 + dev_no = (major

  • 3.3 bootsect.s

    - 53 -

    56 jmpi go,INITSEG ! INITSEG

    ! CPU 0x9000

    57 go: mov ax,cs ! dses ss (0x9000)

    58 mov ds,ax (push,pop,call)

    59 mov es,ax

    60 ! put stack at 0x9ff00. ! sp 0x9ff00( 0x9000:0xff00)

    61 mov ss,ax

    62 mov sp,#0xFF00 ! arbitrary value >>512

    !

    ! sp 512 0x90200

    ! 0x90200 setup

    ! setup 4 sp

    ! 0x200 + 0x200 * 4 +

    63

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

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

    ! bootsect setup

    ! es es 0x9000

    66

    67 load_setup:

    ! 68--77 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

    68 mov dx,#0x0000 ! drive 0, head 0

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

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

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

    72 int 0x13 ! read it

    73 jnc ok_load_setup ! ok - continue

    74 mov dx,#0x0000

    75 mov ax,#0x0000 ! reset the diskette

    76 int 0x13

    77 j load_setup

    78

    79 ok_load_setup:

    80

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

    !

    ! 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 -

    82

    83 mov dl,#0x00

  • 3.3 bootsect.s

    - 54 -

    84 mov ax,#0x0800 ! AH=8 is get drive parameters

    85 int 0x13

    86 mov ch,#0x00

    87 seg cs ! cs

    88 mov sectors,cx !

    89 mov ax,#INITSEG

    90 mov es,ax ! es

    91

    92 ! Print some inane message ! ('Loading system ...' 24 )

    93

    94 mov ah,#0x03 ! read cursor pos

    95 xor bh,bh !

    96 int 0x10

    97

    98 mov cx,#24 ! 24

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

    100 mov bp,#msg1 !

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

    102 int 0x10 !

    103

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

    105 ! we want to load the system (at 0x10000) ! system 0x10000(64k)

    106

    107 mov ax,#SYSSEG

    108 mov es,ax ! segment of 0x010000 ! es = system

    109 call read_it ! system es

    110 call kill_motor !

    111

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

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

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

    115 ! 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 ABC Dtype 2 1.2M 7 1.44M

    ! 7*4 + 0 = 28 /dev/PS0 (2,28) 1.44M A , 0x021c

    ! /dev/at0 (2,8) 1.2M A 0x0208

    116

    117 seg cs

    118 mov ax,root_dev !

    119 cmp ax,#0

    120 jne root_defined

    121 seg cs

    122 mov bx,sectors ! 88 sectors=15

    ! 1.2Mb sectors=18

    ! 1.44Mb A

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

    124 cmp bx,#15 ! =15

    125 je root_defined ! ax

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

  • 3.3 bootsect.s

    - 55 -

    127 cmp bx,#18

    128 je root_defined

    129 undef_root: !

    130 jmp undef_root

    131 root_defined:

    132 seg cs

    133 mov root_dev,ax !

    134

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

    136 ! the setup-routine loaded directly after

    137 ! the bootblock:

    !

    ! bootsect setup

    138

    139 jmpi 0,SETUPSEG ! 0x9020:0000(setup.s )

    !!!! !!!!

    !

    140

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

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

    143 ! possible, loading whole tracks whenever we can.

    144 !

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

    146 !

    ! 0x10000 64KB

    !

    ! es 0x1000

    147 sread: .word 1+SETUPLEN ! sectors read of current track

    ! 1

    ! bootsect setup SETUPLEN

    148 head: .word 0 ! current head !

    149 track: .word 0 ! current track !

    150

    151 read_it:

    ! 64KB

    ! bx

    152 mov ax,es

    153 test ax,#0x0fff

    154 die: jne die ! es must be at 64kB boundary ! es 64KB !

    155 xor bx,bx ! bx is starting address within segment ! bx

    156 rp_read:

    ! (#ENDSEG)

    ! ok1_read

    157 mov ax,es

    158 cmp ax,#ENDSEG ! have we loaded all yet? !

    159 jb ok1_read

    160 ret

    161 ok1_read:

    ! ax

    !

    ! 64KB (64KB

  • 3.3 bootsect.s

    - 56 -

    ! )

    162 seg cs

    163 mov ax,sectors !

    164 sub ax,sread !

    165 mov cx,ax ! cx = ax =

    166 shl cx,#9 ! cx = cx * 512

    167 add cx,bx ! cx = cx + (bx)

    ! =

    168 jnc ok2_read ! 64KB ok2_read

    169 je ok2_read

    170 xor ax,ax ! 64KB

    171 sub ax,bx ! (64KB )

    172 shr ax,#9 !

    173 ok2_read:

    174 call read_track

    175 mov cx,ax ! cx =

    176 add ax,sread !

    177 seg cs

    178 cmp ax,sectors ! ok3_read

    179 jne ok3_read

    ! (1 )

    180 mov ax,#1

    181 sub ax,head !

    182 jne ok4_read ! 0 1

    183 inc track !

    184 ok4_read:

    185 mov head,ax !

    186 xor ax,ax !

    187 ok3_read:

    188 mov sread,ax !

    189 shl cx,#9 ! *512

    190 add bx,cx !

    191 jnc rp_read ! 64KB rp_read(156 )

    !

    192 mov ax,es

    193 add ax,#0x1000 ! 64KB

    194 mov es,ax

    195 xor bx,bx !

    196 jmp rp_read ! rp_read(156 )

    197

    ! es:bx 67 BIOS

    ! int 0x13ah=2

    ! al es:bx

    198 read_track:

    199 push ax

    200 push bx

    201 push cx

    202 push dx

    203 mov dx,track !

    204 mov cx,sread !

    205 inc cx ! cl =

    206 mov ch,dl ! ch =

    207 mov dx,head !

  • 3.3 bootsect.s

    - 57 -

    208 mov dh,dl ! dh =

    209 mov dl,#0 ! dl = ( 0 A )

    210 and dx,#0x0100 ! 1

    211 mov ah,#2 ! ah = 2

    212 int 0x13

    213 jc bad_rt ! bad_rt

    214 pop dx

    215 pop cx

    216 pop bx

    217 pop ax

    218 ret

    ! 0 read_track

    219 bad_rt: mov ax,#0

    220 mov dx,#0

    221 int 0x13

    222 pop dx

    223 pop cx

    224 pop bx

    225 pop ax

    226 jmp read_track

    227

    228 /*

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

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

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

    232 */

    !

    233 kill_motor:

    234 push dx

    235 mov dx,#0x3f2 !

    236 mov al,#0 ! A FDC DMA

    237 outb ! al dx

    238 pop dx

    239 ret

    240

    241 sectors:

    242 .word 0 !

    243

    244 msg1:

    245 .byte 13,10 ! ASCII

    246 .ascii "Loading system ..."

    247 .byte 13,10,13,10 ! 24 ASCII

    248

    249 .org 508 ! 508(0x1FC) root_dev

    ! 508 2

    250 root_dev:

    251 .word ROOT_DEV ! (init/main.c

    )

    252 boot_flag:

    253 .word 0xAA55 !

    254

    255 .text

    256 endtext:

  • 3.4 setup.s

    - 58 -

    257 .data

    258 enddata:

    259 .bss

    260 endbss:

    3.3.3 bootsect.s Alessandro RubiniLinux (http://oldlinux.org/Linux.old/docs/) 386 80x86 [1][16] Linux 0.11

    3.4 setup.s

    3.4.1 setup ROM BIOS 0x90000 bootsect 31 ttyio.c

    31 setup

    ()

    0x90000 2 0x00-0x00-

    0x90002 2 1M KB

    0x90004 2

    0x90006 1

    0x90007 1

    0x90008 2 ??

    0x9000A 1 (0x00-64k,0x01-128k,0x02-192k,0x03=256k)

    0x9000B 1 0x00-,I/O=0x3dX0x11-,I/O=0x3bX

    0x9000C 2

    ...

    0x90080 16 1

    0x90090 16 2

    0x901FC 2 bootsec.s

    setup system 0x10000-0x8ffff system 512KB 0x00000 (idtr)(gdtr) A20 8259A0x20 - 0x2f CPU CR0 32 system head.s head.s 32 idt

  • 3.4 setup.s

    - 59 -

    gdt gdt head.s CPU 32 ds 64KB si 3-2 (a)

    16 3-2 (b)

    3-2

    gdt lgdt CPUgdt gdtr 32

    3.4.2 3-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 !

    ds

    si

    ds

    esi

    gdtr

    64kb

    (a) (b)

  • 3.4 setup.s

    - 60 -

    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.

    !

    ! setup.s BIOS

    ! setup.s system bootsect

    !

    ! bios //

    ! 0x90000-0x901FF bootsect

    ! system

    13 !

    14

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

    ! bootsect.s

    16

    17 INITSEG = 0x9000 ! we move boot here - out of the way ! bootsect

    18 SYSSEG = 0x1000 ! system loaded at 0x10000 (65536). ! system 0x10000(64k)

    19 SETUPSEG = 0x9020 ! this is the current segment !

    20

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

    22 .text

    23 begtext:

    24 .data

    25 begdata:

    26 .bss

    27 begbss:

    28 .text

    29

    30 entry start

    31 start:

    32

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

    34 ! posterity.

    ! ok

    35

    36 mov ax,#INITSEG ! this is done in bootsect already, but...

    ! ds #INITSEG(0x9000) bootsect

    ! setup Linus

    !

    37 mov ds,ax

    38 mov ah,#0x03 ! read cursor pos

    ! BIOS 0x10 ah = 0x03

    ! bh =

    ! ch = cl =

    ! dh = (0x00 )dl = (0x00 )

    39 xor bh,bh

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

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

    ! 0x90000

    !

    42

  • 3.4 setup.s

    - 61 -

    43 ! Get memory size (extended mem, kB) ! 3 KB

    ! 0x15 ah = 0x88

    ! ax = 0x1000001M(KB)

    ! CF ax =

    44

    45 mov ah,#0x88

    46 int 0x15

    47 mov [2],ax ! 0x90002 1

    48

    49 ! Get video-card data: !

    ! BIOS 0x10 ah = 0x0f

    ! ah = al = bh =

    ! 0x90004(1 )0x90006 0x90007

    50

    51 mov ah,#0x0f

    52 int 0x10

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

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

    55

    56 ! check for EGA/VGA and some config parameters ! EGA/VGA

    ! BIOS 0x10 -

    ! ah = 0x12bl = 0x10

    ! bh =

    ! (0x00 - I/O =0x3dX)

    ! (0x01 - I/O =0x3bX)

    ! bl =

    ! (0x00 - 64k, 0x01 - 128k, 0x02 - 192k, 0x03 = 256k)

    ! cx = ()

    57

    58 mov ah,#0x12

    59 mov bl,#0x10

    60 int 0x10

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

    62 mov [10],bx ! 0x9000A = 0x9000B = (/)

    63 mov [12],cx ! 0x9000C =

    64

    65 ! Get hd0 data !

    ! 1 0x41 2

    ! 1 0x46 2

    ! 16 (0x10)

    ! BIOS 0x90080 1

    ! 0x90090 2

    66

    67 mov ax,#0x0000

    68 mov ds,ax

    69 lds si,[4*0x41] ! 0x41 hd0 ds:si

    70 mov ax,#INITSEG

    71 mov es,ax

    72 mov di,#0x0080 ! : 0x9000:0x0080 es:di

    73 mov cx,#0x10 ! 0x10

    74 rep

    75 movsb

    76

  • 3.4 setup.s

    - 62 -

    77 ! Get hd1 data

    78

    79 mov ax,#0x0000

    80 mov ds,ax

    81 lds si,[4*0x46] ! 0x46 hd1 ds:si

    82 mov ax,#INITSEG

    83 mov es,ax

    84 mov di,#0x0090 ! : 0x9000:0x0090 es:di

    85 mov cx,#0x10

    86 rep

    87 movsb

    88

    89 ! 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 --

    90

    91 mov ax,#0x01500

    92 mov dl,#0x81

    93 int 0x13

    94 jc no_disk1

    95 cmp ah,#3 ! ( = 3 )

    96 je is_disk1

    97 no_disk1:

    98 mov ax,#INITSEG ! 2 2

    99 mov es,ax

    100 mov di,#0x0090

    101 mov cx,#0x10

    102 mov ax,#0x00

    103 rep

    104 stosb

    105 is_disk1:

    106

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

    108

    109 cli ! no interrupts allowed ! !

    110

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

    ! system

    ! bootsect system 0x1000064k

    ! system 0x80000512k 0x90000

    ! bootsect 0x90000 setup

    ! system 0x00000 0x10000 0x8ffff

    ! (512k) 0x1000064k

    112

    113 mov ax,#0x0000

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

    115 do_move:

    116 mov es,ax ! destination segment ! es:di ( 0x0000:0x0)

    117 add ax,#0x1000

    118 cmp ax,#0x9000 ! 0x8000 64k

  • 3.4 setup.s

    - 63 -

    119 jz end_move

    120 mov ds,ax ! source segment ! ds:si ( 0x1000:0x0)

    121 sub di,di

    122 sub si,si

    123 mov cx,#0x8000 ! 0x8000 64k

    124 rep

    125 movsw

    126 jmp do_move

    127

    128 ! then we load the segment descriptors

    !

    ! 32 Intel 32 ,

    !

    !

    !

    !

    ! lidt (idt) 6 0-1

    ! ()2-5 32

    ! 219-220 223-224 8

    !

    !

    ! lgdt (gdt) lidt

    ! (8 )

    ! (16 )32

    ! 205-216

    !

    129

    130 end_move:

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

    132 mov ds,ax ! ds (setup)

    133 lidt idt_48 ! load idt with 0,0

    ! (idt)idt_48 6

    ! ( 218 ) 2 idt 4 idt

    !

    134 lgdt gdt_48 ! load gdt with whatever appropriate

    ! (gdt)gdt_48 6

    ! ( 222 )

    135

    136 ! that was painless, now we enable A20

    ! A20 A20

    ! kernel/chr_drv/keyboard.S

    137

    138 call empty_8042 !

    !

    139 mov al,#0xD1 ! command write ! 0xD1 -

    140 out #0x64,al ! 8042 P2 P2 1 A20

    ! 0x60

    141 call empty_8042 !

    142 mov al,#0xDF ! A20 on ! A20

    143 out #0x60,al

    144 call empty_8042 ! A20

    145

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

  • 3.4 setup.s

    - 64 -

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

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

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

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

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

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

    !!

    !! intel int 0x20-0x2F

    !! IBM PC

    !! PC bios 0x08-0x0f

    !! 8259

    153

    154 mov al,#0x11 ! initialization sequence

    ! 0x11 ICW1

    ! 8259 ICW4

    155 out #0x20,al ! send it to 8259A-1 ! 8259A

    !

    ! 0xeb 1 -127 127CPU

    ! EIP EIP

    ! CPU 7 10 0x00eb 0

    ! 14-20 CPU as86

    ! Linus setup.s

    ! NOP 3 6 7 NOP

    156 .word 0x00eb,0x00eb ! jmp $+2, jmp $+2 ! '$'

    157 out #0xA0,al ! and to 8259A-2 ! 8259A

    158 .word 0x00eb,0x00eb

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

    160 out #0x21,al ! ICW2

    161 .word 0x00eb,0x00eb

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

    163 out #0xA1,al ! ICW2

    164 .word 0x00eb,0x00eb

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

    166 out #0x21,al ! ICW3 IR2 INT

    167 .word 0x00eb,0x00eb

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

    169 out #0xA1,al ! ICW3 INT

    ! IR2

    170 .word 0x00eb,0x00eb

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

    172 out #0x21,al ! ICW4 8086 EOI

    !

    173 .word 0x00eb,0x00eb

    174 out #0xA1,al ICW4

    175 .word 0x00eb,0x00eb

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

    177 out #0x21,al !

    178 .word 0x00eb,0x00eb

    179 out #0xA1,al

    180

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

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

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

  • 3.4 setup.s

    - 65 -

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

    185 !

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

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

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

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

    !! BIOS

    !! BIOS !!

    190

    ! 32 (lmsw-Load Machine Status Word)

    ! CR0 0 1 CPU

    191 mov ax,#0x0001 ! protected mode (PE) bit ! (PE)

    192 lmsw ax ! This is it! ! !

    193 jmpi 0,8 ! jmp offset 0 of segment 8 (cs) ! cs 8 0

    ! system 0x00000 0

    ! 8

    ! 16 2 0-1 0-3linux

    ! 0 3 2 (0)

    ! (1) 3-15

    ! 8(0b0000,0000,0000,1000) 0 1

    ! 0 209 system

    194

    195 ! This routine checks that the keyboard command queue is empty

    196 ! No timeout is used - if this hangs there is something wrong with

    197 ! the machine, and we probably couldn't proceed anyway.

    ! -

    ! PC

    ! 2 = 0

    198 empty_8042:

    199 .word 0x00eb,0x00eb ! ()

    200 in al,#0x64 ! 8042 status port ! AT

    201 test al,#2 ! is input buffer full? ! 2

    202 jnz empty_8042 ! yes - loop

    203 ret

    204

    205 gdt: ! 8

    ! 3 1 206 2

    ! 208-211 3 (213-216 )

    !

    206 .word 0,0,0,0 ! dummy ! 1

    207 ! gdt 0x08()

    208 .word 0x07FF ! 8Mb - limit=2047 (2048*4096=8Mb)

    209 .word 0x0000 ! base address=0

    210 .word 0x9A00 ! code read/exec

    211 .word 0x00C0 ! granularity=4096, 386

    212 ! gdt 0x10( ds )

    213 .word 0x07FF ! 8Mb - limit=2047 (2048*4096=8Mb)

    214 .word 0x0000 ! base address=0

    215 .word 0x9200 ! data read/write

    216 .word 0x00C0 ! granularity=4096, 386

    217

    218 idt_48:

  • 3.4 setup.s

    - 66 -

    219 .word 0 ! idt limit=0

    220 .word 0,0 ! idt base=0L

    221

    222 gdt_48:

    223 .word 0x800 ! gdt limit=2048, 256 GDT entries

    ! 2k 8

    ! 256

    224 .word 512+gdt,0x9 ! gdt base = 0X9xxxx

    ! 4 0x0009

  • 3.4 setup.s

    - 67 -

    NULL 0x0000 setup.s 'jmp 0,8 ' 193 head.s '8' gdt '0' 3.4.3.2 BIOS 0x10 ROM BIOS A.

    32 ah = 0x12bh = 0x10

    /

    ah =0x12

    bh =0x10

    bh

    0x00 I/O 0x3DX

    0x01 I/O 0x3BX

    X 0 f

    bl

    00 = 64K, 01 = 128K, 02 = 192K, 03 = 256K

    ch

    0 1 2

    1 0 2

    2 1 1

    3 0 1

    4-7 ( 0)

    cl

    0 1

    1 2

    2 3

    3 4

    4-7

    EGA/VGA :

    0x00 MDA/HGC

    0x01-0x03 MDA/HGC

    0x04 CGA 40x25

    0x05 CGA 80x25

    0x06 EGA+ 40x25

    0x07-0x09 EGA+ 80x25

    0x0A EGA+ 80x25

    0x0B EGA+ 80x25

  • 3.4 setup.s

    - 68 -

    3.4.3.3 INT 0x41 int 0x41 4 * 0x41 =0x0000:0x0104 100% BIOS F000h:E401h int 0x46

    33

    0x00 cyl

    0x02 head

    0x03 ( PC XT 0)

    0x05 wpcom 4

    0x07 ECC XT 0

    0x08 ctl

    0

    1 (0) ( IRQ)

    2

    3 8 1

    4 (0)

    5 +1 1

    6 ECC

    7

    0x09 XT 0

    0x0A XT 0

    0x0B XT 0

    0x0C lzone ()

    0x0E sect

    0x0F

    3.4.3.4 A20 1981 8 IBM IBM PC CPU Intel 8088 20 (A0 A19) RAM KB 1MB 20 0xffff:0xffff 0x10ffef 0x100000(1MB) 0x0ffef IBM 1985 AT Intel 80286 CPU 24 16MB 8088 1MB 8088 IBM 0x100000 8042 P2 P21 A20 20 A20

    A20 setup.s 138-144 A20

  • 3.4 setup.s

    - 69 -

    A20 A20 A20 (Fast Gate A20) I/O 0x92 A20 0x92 0xee A20 A20 3.4.3.5 8259 8259A 8 64 PC/AT 8259A 15 3-4 INT IR2 8259A 0x20 0xA0

    3-4 PC/AT 8259

    CPU IN OUT 8259A IRQ0 IRQ15 CPU INT CPU CPU D7-D0 CPU Linux int 320x20int 0 - int 31 CPU int32 -- int 47 3.4.3.6 Intel CPU 32 Intel CPU Intel CPU8088/8086 Intel 80386 32 4G

    IR0IR1 INTIR2 IR3 8259A IR4 IR5 IR6 IR7 A0 CS CAS2-0

    IRQ0 IRQ1 int IRQ2 2 IRQ3 1 IRQ4 2 IRQ5 IRQ6 1 IRQ7 0x20-0x3f

    IR0 CAS2-0IR1 INTIR2 IR3 8259A IR4 IR5 IR6 IR7 A0 CS

    IRQ8 INT0AH IRQ9 IRQ10 IRQ11 PS2 IRQ12 IRQ13 IRQ14 IRQ15 0xA0-0xbf

    INTR CPU

    D7-D0

  • 3.4 setup.s

    - 70 -

    Linux

    setup.s head.s 80x86 3.4.3.7 Intel 80386 CPU 4 GDTR Global Descriptor Table Register LDTR Local Descriptor Table Register GDT LDT IDTR Interrupt Descriptor Table Register IDT TR Task Register task{} 3.4.3.8 Intel 80386 4 CR0CR1CR2CR3 MOV 3-5 31 23 15 7 0

    Page Directory Base Register (PDBR)

    Reserved CR3

    Page Fault Linear Address CR2

    Reserved CR1

    P

    G

    Reserved

    E

    T

    T

    S

    E

    M

    M

    P

    P

    ECR0

    3-5

    CR0

    PE Protection Enable 0 MP Math Present 1 WAIT EM Emulation 2 TS Task Switch 3 ET Extention Type 4 80287 80387 PG Paging 31 10

    CR2 PG CPU CR3 PG CPU

  • 3.5 head.s

    - 71 -

    3.5 head.s

    3.5.1 head.s system(head)heads.s AT&T GNU gas gld2 0 idt 256 gdt 0 1M A20 1Mb CPU IP MOD 1Mb PC 8028780387 CR0 0 16MB 4 /init/main.c main()

    3.5.2 3-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: #

    17 startup_32: # 18-22

    18 movl $0x10,%eax # GNU '$'

    2 Linux gas gld as ld

  • 3.5 head.s

    - 72 -

    # '%'eax 32 ax

    # !!! 32 $0x10 0x10

    #

    # setup.s 193 $0x10

    # 0( 0-1=0)( 2=0) 2 ( 3-15=2)

    # setup.s 212213

    # ds,es,fs,gs setup.s

    # 2 =0x10 stack_start user_stack

    # setup.s

    # 8MB 16MBstack_start kernel/sched.c69

    # user_stack

    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.c69

    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 16MB setup.s 208-216

    # 235-236

    # bochs CS 26 CS

    # 8MB CS CS

    31 lss _stack_start,%esp

    # 32-36 A20 0x000000

    # 0x100000(1M)

    # A20 1M

    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)

    * int 16

    */

    # 43-65 CR0

    #

    # CR0 EM 2 MP 1

  • 3.5 head.s

    - 73 -

    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

    */

    54 check_x87:

    55 fninit

    56 fstsw %ax

    57 cmpb $0,%al

    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

    63 .align 2 # ".align 2""2" 2

    # 4

    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

    # (Gate Descriptor) 0-1,6-7 2-3 4-5

    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

  • 3.5 head.s

    - 74 -

    # 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)

    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

    * *

    */

    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)

    # (U/S 2)()(D 6) 12-31

    #

    114 .org 0x1000 # 0x1000 1 0

    115 pg0:

    116

    117 .org 0x2000

    118 pg1:

    119

  • 3.5 head.s

    - 75 -

    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

    # (pushl)/init/main.c

    # 3 0 envpargv argc main()

    # 139 main.c

    # main.c L6

    # 140 main.c setup_paging

    # 'ret' main.c main.c

    135 after_page_tables:

    136 pushl $0 # These are the parameters to main :-)

    137 pushl $0 # main init/main.c

    138 pushl $0 # '$'

    139 pushl $L6 # return address for main, if it decides to.

    140 pushl $_main # '_main' 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.

    145

    146 /* This is the default interrupt "handler" :-) */

    /* */ 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

    # 32 4

    155 push %es

    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

  • 3.5 head.s

    - 76 -

    162 call _printk # /kernel/printk.c

    # '_printk' printk

    163 popl %eax

    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 identi