From d8647f9771b97df23466ececf921fd4195937808 Mon Sep 17 00:00:00 2001 From: zhaoyimin <26086733040@qq.com> Date: Fri, 9 Jul 2021 17:34:33 +0800 Subject: [PATCH] zhaoyimin --- 110_master/110/.gitignore | 53 + 110_master/110/LICENSE | 35 + 110_master/110/README.md | 19 + .../110/os/os/linux/.vscode/settings.json | 9 + 110_master/110/os/os/linux/Image | Bin 0 -> 138404 bytes 110_master/110/os/os/linux/Image.bkp | Bin 0 -> 131556 bytes 110_master/110/os/os/linux/Makefile | 125 ++ 110_master/110/os/os/linux/System.map | 598 +++++++++ 110_master/110/os/os/linux/System.map.2 | 1082 +++++++++++++++++ 110_master/110/os/os/linux/boot/bootsect | Bin 0 -> 544 bytes 110_master/110/os/os/linux/boot/bootsect.o | Bin 0 -> 923 bytes 110_master/110/os/os/linux/boot/bootsect.s | 260 ++++ 110_master/110/os/os/linux/boot/head.o | Bin 0 -> 27012 bytes 110_master/110/os/os/linux/boot/head.s | 240 ++++ 110_master/110/os/os/linux/boot/setup | Bin 0 -> 344 bytes 110_master/110/os/os/linux/boot/setup.o | Bin 0 -> 596 bytes 110_master/110/os/os/linux/boot/setup.s | 231 ++++ 110_master/110/os/os/linux/execve2.patch | 41 + 110_master/110/os/os/linux/fs/Makefile | 101 ++ 110_master/110/os/os/linux/fs/bitmap.c | 168 +++ 110_master/110/os/os/linux/fs/bitmap.o | Bin 0 -> 10280 bytes 110_master/110/os/os/linux/fs/block_dev.c | 73 ++ 110_master/110/os/os/linux/fs/block_dev.o | Bin 0 -> 7296 bytes 110_master/110/os/os/linux/fs/buffer.c | 384 ++++++ 110_master/110/os/os/linux/fs/buffer.o | Bin 0 -> 13348 bytes 110_master/110/os/os/linux/fs/char_dev.c | 104 ++ 110_master/110/os/os/linux/fs/char_dev.o | Bin 0 -> 8288 bytes 110_master/110/os/os/linux/fs/exec.c | 359 ++++++ 110_master/110/os/os/linux/fs/exec.o | Bin 0 -> 14932 bytes 110_master/110/os/os/linux/fs/fcntl.c | 75 ++ 110_master/110/os/os/linux/fs/fcntl.o | Bin 0 -> 6748 bytes 110_master/110/os/os/linux/fs/file_dev.c | 90 ++ 110_master/110/os/os/linux/fs/file_dev.o | Bin 0 -> 7828 bytes 110_master/110/os/os/linux/fs/file_table.c | 9 + 110_master/110/os/os/linux/fs/file_table.o | Bin 0 -> 2644 bytes 110_master/110/os/os/linux/fs/fs.o | Bin 0 -> 142933 bytes 110_master/110/os/os/linux/fs/inode.c | 340 ++++++ 110_master/110/os/os/linux/fs/inode.o | Bin 0 -> 14072 bytes 110_master/110/os/os/linux/fs/ioctl.c | 46 + 110_master/110/os/os/linux/fs/ioctl.o | Bin 0 -> 5828 bytes 110_master/110/os/os/linux/fs/namei.c | 783 ++++++++++++ 110_master/110/os/os/linux/fs/namei.o | Bin 0 -> 20756 bytes 110_master/110/os/os/linux/fs/open.c | 208 ++++ 110_master/110/os/os/linux/fs/open.o | Bin 0 -> 11184 bytes 110_master/110/os/os/linux/fs/pipe.c | 111 ++ 110_master/110/os/os/linux/fs/pipe.o | Bin 0 -> 8104 bytes 110_master/110/os/os/linux/fs/read_write.c | 103 ++ 110_master/110/os/os/linux/fs/read_write.o | Bin 0 -> 7520 bytes 110_master/110/os/os/linux/fs/select.c | 10 + 110_master/110/os/os/linux/fs/select.o | Bin 0 -> 1776 bytes 110_master/110/os/os/linux/fs/stat.c | 66 + 110_master/110/os/os/linux/fs/stat.o | Bin 0 -> 7212 bytes 110_master/110/os/os/linux/fs/super.c | 282 +++++ 110_master/110/os/os/linux/fs/super.o | Bin 0 -> 12284 bytes 110_master/110/os/os/linux/fs/truncate.c | 65 + 110_master/110/os/os/linux/fs/truncate.o | Bin 0 -> 6848 bytes 110_master/110/os/os/linux/include/a.out.h | 220 ++++ 110_master/110/os/os/linux/include/asm/io.h | 24 + .../110/os/os/linux/include/asm/memory.h | 15 + .../110/os/os/linux/include/asm/segment.h | 65 + .../110/os/os/linux/include/asm/system.h | 66 + 110_master/110/os/os/linux/include/const.h | 15 + 110_master/110/os/os/linux/include/ctype.h | 34 + 110_master/110/os/os/linux/include/errno.h | 60 + 110_master/110/os/os/linux/include/fcntl.h | 55 + .../110/os/os/linux/include/linux/config.h | 48 + .../110/os/os/linux/include/linux/fdreg.h | 71 ++ 110_master/110/os/os/linux/include/linux/fs.h | 202 +++ .../110/os/os/linux/include/linux/hdreg.h | 65 + .../110/os/os/linux/include/linux/head.h | 20 + .../110/os/os/linux/include/linux/kernel.h | 22 + 110_master/110/os/os/linux/include/linux/mm.h | 10 + .../110/os/os/linux/include/linux/sched.h | 239 ++++ .../110/os/os/linux/include/linux/sys.h | 116 ++ .../110/os/os/linux/include/linux/tty.h | 77 ++ 110_master/110/os/os/linux/include/new0.h | 30 + 110_master/110/os/os/linux/include/signal.h | 68 ++ 110_master/110/os/os/linux/include/stdarg.h | 28 + 110_master/110/os/os/linux/include/stddef.h | 19 + 110_master/110/os/os/linux/include/string.h | 405 ++++++ 110_master/110/os/os/linux/include/sys/stat.h | 60 + .../110/os/os/linux/include/sys/times.h | 15 + .../110/os/os/linux/include/sys/types.h | 46 + .../110/os/os/linux/include/sys/utsname.h | 16 + 110_master/110/os/os/linux/include/sys/wait.h | 23 + 110_master/110/os/os/linux/include/termios.h | 228 ++++ 110_master/110/os/os/linux/include/time.h | 42 + 110_master/110/os/os/linux/include/unistd.h | 276 +++++ 110_master/110/os/os/linux/include/utime.h | 13 + 110_master/110/os/os/linux/init/main.c | 216 ++++ 110_master/110/os/os/linux/init/main.o | Bin 0 -> 12208 bytes 110_master/110/os/os/linux/kernel/Makefile | 83 ++ 110_master/110/os/os/linux/kernel/asm.o | Bin 0 -> 1740 bytes 110_master/110/os/os/linux/kernel/asm.s | 146 +++ .../110/os/os/linux/kernel/blk_drv/Makefile | 58 + .../110/os/os/linux/kernel/blk_drv/blk.h | 140 +++ .../110/os/os/linux/kernel/blk_drv/blk_drv.a | Bin 0 -> 52212 bytes .../110/os/os/linux/kernel/blk_drv/floppy.c | 463 +++++++ .../110/os/os/linux/kernel/blk_drv/floppy.o | Bin 0 -> 16612 bytes .../110/os/os/linux/kernel/blk_drv/hd.c | 351 ++++++ .../110/os/os/linux/kernel/blk_drv/hd.o | Bin 0 -> 15520 bytes .../os/os/linux/kernel/blk_drv/ll_rw_blk.c | 165 +++ .../os/os/linux/kernel/blk_drv/ll_rw_blk.o | Bin 0 -> 8740 bytes .../110/os/os/linux/kernel/blk_drv/ramdisk.c | 126 ++ .../110/os/os/linux/kernel/blk_drv/ramdisk.o | Bin 0 -> 10664 bytes .../110/os/os/linux/kernel/chr_drv/Makefile | 68 ++ .../110/os/os/linux/kernel/chr_drv/chr_drv.a | Bin 0 -> 68902 bytes .../110/os/os/linux/kernel/chr_drv/console.c | 710 +++++++++++ .../110/os/os/linux/kernel/chr_drv/console.o | Bin 0 -> 20896 bytes .../os/os/linux/kernel/chr_drv/keyboard.2.o | Bin 0 -> 6024 bytes .../os/os/linux/kernel/chr_drv/keyboard.2.s | 466 +++++++ .../110/os/os/linux/kernel/chr_drv/keyboard.S | 588 +++++++++ .../110/os/os/linux/kernel/chr_drv/rs_io.o | Bin 0 -> 1320 bytes .../110/os/os/linux/kernel/chr_drv/rs_io.s | 147 +++ .../110/os/os/linux/kernel/chr_drv/serial.c | 59 + .../110/os/os/linux/kernel/chr_drv/serial.o | Bin 0 -> 6752 bytes .../110/os/os/linux/kernel/chr_drv/tty_io.c | 349 ++++++ .../110/os/os/linux/kernel/chr_drv/tty_io.o | Bin 0 -> 22504 bytes .../os/os/linux/kernel/chr_drv/tty_ioctl.c | 204 ++++ .../os/os/linux/kernel/chr_drv/tty_ioctl.o | Bin 0 -> 10648 bytes 110_master/110/os/os/linux/kernel/exec2.o | Bin 0 -> 15272 bytes 110_master/110/os/os/linux/kernel/execve2.c | 359 ++++++ 110_master/110/os/os/linux/kernel/execve2.o | Bin 0 -> 15064 bytes 110_master/110/os/os/linux/kernel/exit.c | 197 +++ 110_master/110/os/os/linux/kernel/exit.o | Bin 0 -> 11164 bytes 110_master/110/os/os/linux/kernel/fork.c | 148 +++ 110_master/110/os/os/linux/kernel/fork.o | Bin 0 -> 9640 bytes 110_master/110/os/os/linux/kernel/getdents.c | 96 ++ 110_master/110/os/os/linux/kernel/getdents.o | Bin 0 -> 7672 bytes 110_master/110/os/os/linux/kernel/kernel.o | Bin 0 -> 109562 bytes .../110/os/os/linux/kernel/math/Makefile | 43 + 110_master/110/os/os/linux/kernel/math/math.a | Bin 0 -> 6628 bytes .../os/os/linux/kernel/math/math_emulate.c | 42 + .../os/os/linux/kernel/math/math_emulate.o | Bin 0 -> 6464 bytes 110_master/110/os/os/linux/kernel/mktime.c | 58 + 110_master/110/os/os/linux/kernel/mktime.o | Bin 0 -> 2872 bytes 110_master/110/os/os/linux/kernel/panic.c | 24 + 110_master/110/os/os/linux/kernel/panic.o | Bin 0 -> 5424 bytes 110_master/110/os/os/linux/kernel/pipe2.c | 55 + 110_master/110/os/os/linux/kernel/pipe2.o | Bin 0 -> 6280 bytes 110_master/110/os/os/linux/kernel/printk.c | 41 + 110_master/110/os/os/linux/kernel/printk.o | Bin 0 -> 2424 bytes 110_master/110/os/os/linux/kernel/sched.c | 412 +++++++ 110_master/110/os/os/linux/kernel/sched.o | Bin 0 -> 22936 bytes 110_master/110/os/os/linux/kernel/signal.c | 129 ++ 110_master/110/os/os/linux/kernel/signal.o | Bin 0 -> 8960 bytes 110_master/110/os/os/linux/kernel/sys.c | 299 +++++ 110_master/110/os/os/linux/kernel/sys.o | Bin 0 -> 13576 bytes .../110/os/os/linux/kernel/system_call.o | Bin 0 -> 2640 bytes .../110/os/os/linux/kernel/system_call.s | 298 +++++ 110_master/110/os/os/linux/kernel/traps.c | 208 ++++ 110_master/110/os/os/linux/kernel/traps.o | Bin 0 -> 12972 bytes 110_master/110/os/os/linux/kernel/vsprintf.c | 233 ++++ 110_master/110/os/os/linux/kernel/vsprintf.o | Bin 0 -> 6156 bytes 110_master/110/os/os/linux/lib/Makefile | 73 ++ 110_master/110/os/os/linux/lib/_exit.c | 13 + 110_master/110/os/os/linux/lib/_exit.o | Bin 0 -> 1988 bytes 110_master/110/os/os/linux/lib/close.c | 10 + 110_master/110/os/os/linux/lib/close.o | Bin 0 -> 2220 bytes 110_master/110/os/os/linux/lib/ctype.c | 35 + 110_master/110/os/os/linux/lib/ctype.o | Bin 0 -> 1908 bytes 110_master/110/os/os/linux/lib/dup.c | 10 + 110_master/110/os/os/linux/lib/dup.o | Bin 0 -> 2196 bytes 110_master/110/os/os/linux/lib/errno.c | 7 + 110_master/110/os/os/linux/lib/errno.o | Bin 0 -> 1472 bytes 110_master/110/os/os/linux/lib/execve.c | 10 + 110_master/110/os/os/linux/lib/execve.o | Bin 0 -> 2336 bytes 110_master/110/os/os/linux/lib/lib.a | Bin 0 -> 34138 bytes 110_master/110/os/os/linux/lib/malloc.c | 232 ++++ 110_master/110/os/os/linux/lib/malloc.o | Bin 0 -> 4880 bytes 110_master/110/os/os/linux/lib/open.c | 25 + 110_master/110/os/os/linux/lib/open.o | Bin 0 -> 2364 bytes 110_master/110/os/os/linux/lib/setsid.c | 10 + 110_master/110/os/os/linux/lib/setsid.o | Bin 0 -> 2240 bytes 110_master/110/os/os/linux/lib/string.c | 14 + 110_master/110/os/os/linux/lib/string.o | Bin 0 -> 6380 bytes 110_master/110/os/os/linux/lib/wait.c | 16 + 110_master/110/os/os/linux/lib/wait.o | Bin 0 -> 2580 bytes 110_master/110/os/os/linux/lib/write.c | 10 + 110_master/110/os/os/linux/lib/write.o | Bin 0 -> 2372 bytes 110_master/110/os/os/linux/mm/Makefile | 38 + 110_master/110/os/os/linux/mm/memory.c | 468 +++++++ 110_master/110/os/os/linux/mm/memory.o | Bin 0 -> 13816 bytes 110_master/110/os/os/linux/mm/mm.o | Bin 0 -> 13936 bytes 110_master/110/os/os/linux/mm/page.o | Bin 0 -> 640 bytes 110_master/110/os/os/linux/mm/page.s | 40 + 110_master/110/os/os/linux/myls.c | 24 + 110_master/110/os/os/linux/tools/build | Bin 0 -> 15144 bytes 110_master/110/os/os/linux/tools/build.c | 171 +++ 110_master/110/os/os/linux/tools/system | Bin 0 -> 306090 bytes 190 files changed, 16950 insertions(+) create mode 100644 110_master/110/.gitignore create mode 100644 110_master/110/LICENSE create mode 100644 110_master/110/README.md create mode 100644 110_master/110/os/os/linux/.vscode/settings.json create mode 100644 110_master/110/os/os/linux/Image create mode 100644 110_master/110/os/os/linux/Image.bkp create mode 100644 110_master/110/os/os/linux/Makefile create mode 100644 110_master/110/os/os/linux/System.map create mode 100644 110_master/110/os/os/linux/System.map.2 create mode 100644 110_master/110/os/os/linux/boot/bootsect create mode 100644 110_master/110/os/os/linux/boot/bootsect.o create mode 100644 110_master/110/os/os/linux/boot/bootsect.s create mode 100644 110_master/110/os/os/linux/boot/head.o create mode 100644 110_master/110/os/os/linux/boot/head.s create mode 100644 110_master/110/os/os/linux/boot/setup create mode 100644 110_master/110/os/os/linux/boot/setup.o create mode 100644 110_master/110/os/os/linux/boot/setup.s create mode 100644 110_master/110/os/os/linux/execve2.patch create mode 100644 110_master/110/os/os/linux/fs/Makefile create mode 100644 110_master/110/os/os/linux/fs/bitmap.c create mode 100644 110_master/110/os/os/linux/fs/bitmap.o create mode 100644 110_master/110/os/os/linux/fs/block_dev.c create mode 100644 110_master/110/os/os/linux/fs/block_dev.o create mode 100644 110_master/110/os/os/linux/fs/buffer.c create mode 100644 110_master/110/os/os/linux/fs/buffer.o create mode 100644 110_master/110/os/os/linux/fs/char_dev.c create mode 100644 110_master/110/os/os/linux/fs/char_dev.o create mode 100644 110_master/110/os/os/linux/fs/exec.c create mode 100644 110_master/110/os/os/linux/fs/exec.o create mode 100644 110_master/110/os/os/linux/fs/fcntl.c create mode 100644 110_master/110/os/os/linux/fs/fcntl.o create mode 100644 110_master/110/os/os/linux/fs/file_dev.c create mode 100644 110_master/110/os/os/linux/fs/file_dev.o create mode 100644 110_master/110/os/os/linux/fs/file_table.c create mode 100644 110_master/110/os/os/linux/fs/file_table.o create mode 100644 110_master/110/os/os/linux/fs/fs.o create mode 100644 110_master/110/os/os/linux/fs/inode.c create mode 100644 110_master/110/os/os/linux/fs/inode.o create mode 100644 110_master/110/os/os/linux/fs/ioctl.c create mode 100644 110_master/110/os/os/linux/fs/ioctl.o create mode 100644 110_master/110/os/os/linux/fs/namei.c create mode 100644 110_master/110/os/os/linux/fs/namei.o create mode 100644 110_master/110/os/os/linux/fs/open.c create mode 100644 110_master/110/os/os/linux/fs/open.o create mode 100644 110_master/110/os/os/linux/fs/pipe.c create mode 100644 110_master/110/os/os/linux/fs/pipe.o create mode 100644 110_master/110/os/os/linux/fs/read_write.c create mode 100644 110_master/110/os/os/linux/fs/read_write.o create mode 100644 110_master/110/os/os/linux/fs/select.c create mode 100644 110_master/110/os/os/linux/fs/select.o create mode 100644 110_master/110/os/os/linux/fs/stat.c create mode 100644 110_master/110/os/os/linux/fs/stat.o create mode 100644 110_master/110/os/os/linux/fs/super.c create mode 100644 110_master/110/os/os/linux/fs/super.o create mode 100644 110_master/110/os/os/linux/fs/truncate.c create mode 100644 110_master/110/os/os/linux/fs/truncate.o create mode 100644 110_master/110/os/os/linux/include/a.out.h create mode 100644 110_master/110/os/os/linux/include/asm/io.h create mode 100644 110_master/110/os/os/linux/include/asm/memory.h create mode 100644 110_master/110/os/os/linux/include/asm/segment.h create mode 100644 110_master/110/os/os/linux/include/asm/system.h create mode 100644 110_master/110/os/os/linux/include/const.h create mode 100644 110_master/110/os/os/linux/include/ctype.h create mode 100644 110_master/110/os/os/linux/include/errno.h create mode 100644 110_master/110/os/os/linux/include/fcntl.h create mode 100644 110_master/110/os/os/linux/include/linux/config.h create mode 100644 110_master/110/os/os/linux/include/linux/fdreg.h create mode 100644 110_master/110/os/os/linux/include/linux/fs.h create mode 100644 110_master/110/os/os/linux/include/linux/hdreg.h create mode 100644 110_master/110/os/os/linux/include/linux/head.h create mode 100644 110_master/110/os/os/linux/include/linux/kernel.h create mode 100644 110_master/110/os/os/linux/include/linux/mm.h create mode 100644 110_master/110/os/os/linux/include/linux/sched.h create mode 100644 110_master/110/os/os/linux/include/linux/sys.h create mode 100644 110_master/110/os/os/linux/include/linux/tty.h create mode 100644 110_master/110/os/os/linux/include/new0.h create mode 100644 110_master/110/os/os/linux/include/signal.h create mode 100644 110_master/110/os/os/linux/include/stdarg.h create mode 100644 110_master/110/os/os/linux/include/stddef.h create mode 100644 110_master/110/os/os/linux/include/string.h create mode 100644 110_master/110/os/os/linux/include/sys/stat.h create mode 100644 110_master/110/os/os/linux/include/sys/times.h create mode 100644 110_master/110/os/os/linux/include/sys/types.h create mode 100644 110_master/110/os/os/linux/include/sys/utsname.h create mode 100644 110_master/110/os/os/linux/include/sys/wait.h create mode 100644 110_master/110/os/os/linux/include/termios.h create mode 100644 110_master/110/os/os/linux/include/time.h create mode 100644 110_master/110/os/os/linux/include/unistd.h create mode 100644 110_master/110/os/os/linux/include/utime.h create mode 100644 110_master/110/os/os/linux/init/main.c create mode 100644 110_master/110/os/os/linux/init/main.o create mode 100644 110_master/110/os/os/linux/kernel/Makefile create mode 100644 110_master/110/os/os/linux/kernel/asm.o create mode 100644 110_master/110/os/os/linux/kernel/asm.s create mode 100644 110_master/110/os/os/linux/kernel/blk_drv/Makefile create mode 100644 110_master/110/os/os/linux/kernel/blk_drv/blk.h create mode 100644 110_master/110/os/os/linux/kernel/blk_drv/blk_drv.a create mode 100644 110_master/110/os/os/linux/kernel/blk_drv/floppy.c create mode 100644 110_master/110/os/os/linux/kernel/blk_drv/floppy.o create mode 100644 110_master/110/os/os/linux/kernel/blk_drv/hd.c create mode 100644 110_master/110/os/os/linux/kernel/blk_drv/hd.o create mode 100644 110_master/110/os/os/linux/kernel/blk_drv/ll_rw_blk.c create mode 100644 110_master/110/os/os/linux/kernel/blk_drv/ll_rw_blk.o create mode 100644 110_master/110/os/os/linux/kernel/blk_drv/ramdisk.c create mode 100644 110_master/110/os/os/linux/kernel/blk_drv/ramdisk.o create mode 100644 110_master/110/os/os/linux/kernel/chr_drv/Makefile create mode 100644 110_master/110/os/os/linux/kernel/chr_drv/chr_drv.a create mode 100644 110_master/110/os/os/linux/kernel/chr_drv/console.c create mode 100644 110_master/110/os/os/linux/kernel/chr_drv/console.o create mode 100644 110_master/110/os/os/linux/kernel/chr_drv/keyboard.2.o create mode 100644 110_master/110/os/os/linux/kernel/chr_drv/keyboard.2.s create mode 100644 110_master/110/os/os/linux/kernel/chr_drv/keyboard.S create mode 100644 110_master/110/os/os/linux/kernel/chr_drv/rs_io.o create mode 100644 110_master/110/os/os/linux/kernel/chr_drv/rs_io.s create mode 100644 110_master/110/os/os/linux/kernel/chr_drv/serial.c create mode 100644 110_master/110/os/os/linux/kernel/chr_drv/serial.o create mode 100644 110_master/110/os/os/linux/kernel/chr_drv/tty_io.c create mode 100644 110_master/110/os/os/linux/kernel/chr_drv/tty_io.o create mode 100644 110_master/110/os/os/linux/kernel/chr_drv/tty_ioctl.c create mode 100644 110_master/110/os/os/linux/kernel/chr_drv/tty_ioctl.o create mode 100644 110_master/110/os/os/linux/kernel/exec2.o create mode 100644 110_master/110/os/os/linux/kernel/execve2.c create mode 100644 110_master/110/os/os/linux/kernel/execve2.o create mode 100644 110_master/110/os/os/linux/kernel/exit.c create mode 100644 110_master/110/os/os/linux/kernel/exit.o create mode 100644 110_master/110/os/os/linux/kernel/fork.c create mode 100644 110_master/110/os/os/linux/kernel/fork.o create mode 100644 110_master/110/os/os/linux/kernel/getdents.c create mode 100644 110_master/110/os/os/linux/kernel/getdents.o create mode 100644 110_master/110/os/os/linux/kernel/kernel.o create mode 100644 110_master/110/os/os/linux/kernel/math/Makefile create mode 100644 110_master/110/os/os/linux/kernel/math/math.a create mode 100644 110_master/110/os/os/linux/kernel/math/math_emulate.c create mode 100644 110_master/110/os/os/linux/kernel/math/math_emulate.o create mode 100644 110_master/110/os/os/linux/kernel/mktime.c create mode 100644 110_master/110/os/os/linux/kernel/mktime.o create mode 100644 110_master/110/os/os/linux/kernel/panic.c create mode 100644 110_master/110/os/os/linux/kernel/panic.o create mode 100644 110_master/110/os/os/linux/kernel/pipe2.c create mode 100644 110_master/110/os/os/linux/kernel/pipe2.o create mode 100644 110_master/110/os/os/linux/kernel/printk.c create mode 100644 110_master/110/os/os/linux/kernel/printk.o create mode 100644 110_master/110/os/os/linux/kernel/sched.c create mode 100644 110_master/110/os/os/linux/kernel/sched.o create mode 100644 110_master/110/os/os/linux/kernel/signal.c create mode 100644 110_master/110/os/os/linux/kernel/signal.o create mode 100644 110_master/110/os/os/linux/kernel/sys.c create mode 100644 110_master/110/os/os/linux/kernel/sys.o create mode 100644 110_master/110/os/os/linux/kernel/system_call.o create mode 100644 110_master/110/os/os/linux/kernel/system_call.s create mode 100644 110_master/110/os/os/linux/kernel/traps.c create mode 100644 110_master/110/os/os/linux/kernel/traps.o create mode 100644 110_master/110/os/os/linux/kernel/vsprintf.c create mode 100644 110_master/110/os/os/linux/kernel/vsprintf.o create mode 100644 110_master/110/os/os/linux/lib/Makefile create mode 100644 110_master/110/os/os/linux/lib/_exit.c create mode 100644 110_master/110/os/os/linux/lib/_exit.o create mode 100644 110_master/110/os/os/linux/lib/close.c create mode 100644 110_master/110/os/os/linux/lib/close.o create mode 100644 110_master/110/os/os/linux/lib/ctype.c create mode 100644 110_master/110/os/os/linux/lib/ctype.o create mode 100644 110_master/110/os/os/linux/lib/dup.c create mode 100644 110_master/110/os/os/linux/lib/dup.o create mode 100644 110_master/110/os/os/linux/lib/errno.c create mode 100644 110_master/110/os/os/linux/lib/errno.o create mode 100644 110_master/110/os/os/linux/lib/execve.c create mode 100644 110_master/110/os/os/linux/lib/execve.o create mode 100644 110_master/110/os/os/linux/lib/lib.a create mode 100644 110_master/110/os/os/linux/lib/malloc.c create mode 100644 110_master/110/os/os/linux/lib/malloc.o create mode 100644 110_master/110/os/os/linux/lib/open.c create mode 100644 110_master/110/os/os/linux/lib/open.o create mode 100644 110_master/110/os/os/linux/lib/setsid.c create mode 100644 110_master/110/os/os/linux/lib/setsid.o create mode 100644 110_master/110/os/os/linux/lib/string.c create mode 100644 110_master/110/os/os/linux/lib/string.o create mode 100644 110_master/110/os/os/linux/lib/wait.c create mode 100644 110_master/110/os/os/linux/lib/wait.o create mode 100644 110_master/110/os/os/linux/lib/write.c create mode 100644 110_master/110/os/os/linux/lib/write.o create mode 100644 110_master/110/os/os/linux/mm/Makefile create mode 100644 110_master/110/os/os/linux/mm/memory.c create mode 100644 110_master/110/os/os/linux/mm/memory.o create mode 100644 110_master/110/os/os/linux/mm/mm.o create mode 100644 110_master/110/os/os/linux/mm/page.o create mode 100644 110_master/110/os/os/linux/mm/page.s create mode 100644 110_master/110/os/os/linux/myls.c create mode 100644 110_master/110/os/os/linux/tools/build create mode 100644 110_master/110/os/os/linux/tools/build.c create mode 100644 110_master/110/os/os/linux/tools/system diff --git a/110_master/110/.gitignore b/110_master/110/.gitignore new file mode 100644 index 0000000..0b8c959 --- /dev/null +++ b/110_master/110/.gitignore @@ -0,0 +1,53 @@ +# ---> Eagle +# Ignore list for Eagle, a PCB layout tool + +# Backup files +*.s#? +*.b#? +*.l#? +*.b$? +*.s$? +*.l$? + +# Eagle project file +# It contains a serial number and references to the file structure +# on your computer. +# comment the following line if you want to have your project file included. +eagle.epf + +# Autorouter files +*.pro +*.job + +# CAM files +*.$$$ +*.cmp +*.ly2 +*.l15 +*.sol +*.plc +*.stc +*.sts +*.crc +*.crs + +*.dri +*.drl +*.gpi +*.pls +*.ger +*.xln + +*.drd +*.drd.* + +*.s#* +*.b#* + +*.info + +*.eps + +# file locks introduced since 7.x +*.lck + diff --git a/110_master/110/LICENSE b/110_master/110/LICENSE new file mode 100644 index 0000000..2172f86 --- /dev/null +++ b/110_master/110/LICENSE @@ -0,0 +1,35 @@ +GCC RUNTIME LIBRARY EXCEPTION + +Version 3.1, 31 March 2009 + +General information: http://www.gnu.org/licenses/gcc-exception.html + +Copyright (C) 2009 Free Software Foundation, Inc. + +Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. + +This GCC Runtime Library Exception ("Exception") is an additional permission under section 7 of the GNU General Public License, version 3 ("GPLv3"). It applies to a given file (the "Runtime Library") that bears a notice placed by the copyright holder of the file stating that the file is governed by GPLv3 along with this Exception. + +When you use GCC to compile a program, GCC may combine portions of certain GCC header files and runtime libraries with the compiled program. The purpose of this Exception is to allow compilation of non-GPL (including proprietary) programs to use, in this way, the header files and runtime libraries covered by this Exception. + + 0. Definitions. + + A file is an "Independent Module" if it either requires the Runtime Library for execution after a Compilation Process, or makes use of an interface provided by the Runtime Library, but is not otherwise based on the Runtime Library. + + "GCC" means a version of the GNU Compiler Collection, with or without modifications, governed by version 3 (or a specified later version) of the GNU General Public License (GPL) with the option of using any subsequent versions published by the FSF. + + "GPL-compatible Software" is software whose conditions of propagation, modification and use would permit combination with GCC in accord with the license of GCC. + + "Target Code" refers to output from any compiler for a real or virtual target processor architecture, in executable form or suitable for input to an assembler, loader, linker and/or execution phase. Notwithstanding that, Target Code does not include data in any format that is used as a compiler intermediate representation, or used for producing a compiler intermediate representation. + + The "Compilation Process" transforms code entirely represented in non-intermediate languages designed for human-written code, and/or in Java Virtual Machine byte code, into Target Code. Thus, for example, use of source code generators and preprocessors need not be considered part of the Compilation Process, since the Compilation Process can be understood as starting with the output of the generators or preprocessors. + + A Compilation Process is "Eligible" if it is done using GCC, alone or with other GPL-compatible software, or if it is done without using any work based on GCC. For example, using non-GPL-compatible Software to optimize any GCC intermediate representations would not qualify as an Eligible Compilation Process. + + 1. Grant of Additional Permission. + + You have permission to propagate a work of Target Code formed by combining the Runtime Library with Independent Modules, even if such propagation would otherwise violate the terms of GPLv3, provided that all Target Code was generated by Eligible Compilation Processes. You may then convey such a combination under terms of your choice, consistent with the licensing of the Independent Modules. + + 2. No Weakening of GCC Copyleft. + +The availability of this Exception does not imply any general presumption that third-party software is unaffected by the copyleft requirements of the license of GCC. diff --git a/110_master/110/README.md b/110_master/110/README.md new file mode 100644 index 0000000..161a42e --- /dev/null +++ b/110_master/110/README.md @@ -0,0 +1,19 @@ +#### 从命令行创建一个新的仓库 + +```bash +touch README.md +git init +git add README.md +git commit -m "first commit" +git remote add origin https://bdgit.educoder.net/pngwt4f59/110.git +git push -u origin master + +``` + +#### 从命令行推送已经创建的仓库 + +```bash +git remote add origin https://bdgit.educoder.net/pngwt4f59/110.git +git push -u origin master + +``` diff --git a/110_master/110/os/os/linux/.vscode/settings.json b/110_master/110/os/os/linux/.vscode/settings.json new file mode 100644 index 0000000..be9f164 --- /dev/null +++ b/110_master/110/os/os/linux/.vscode/settings.json @@ -0,0 +1,9 @@ +{ + "files.associations": { + "*.json": "c", + "*.o": "plaintext", + "new.h": "c", + "new0.h": "c", + "errno.h": "c" + } +} \ No newline at end of file diff --git a/110_master/110/os/os/linux/Image b/110_master/110/os/os/linux/Image new file mode 100644 index 0000000000000000000000000000000000000000..62185d12845e99a4b3199211bbf903536613322b GIT binary patch literal 138404 zcmeEv3w%`7wfC7YApr(wlu<`J%AkV|b;PK#4K>K9X&Y_YMn$Dc6|cypma5f^XsaPO zq2@4#=6bQ$T3ey?VITHdr8VFy0ZOQk8tp@T)f6qAaj3Ow6)knX|9`E0&YTJ1Veh@) z@B4mtqRcsa@3q%nd+oK?-h1tJ_U`SgS+=>?>RHye#_~;hYfABr@4gbTte%@TE!(`T zZ`t4jR&lLmt*Nr^x2k&mRgX`&YAnLNmi73A!q$86Qv3LXpIKAweWv>a%j!{e#m7Ty zBG&yi)`K&Ay}k*LhkC8hvcBALR_+(p)RjAY(=97~;MDA)$WdFB`FpT!Y;P3L{o1Mu z?@e8`!}p41#d@kO{@v8~gJLlK-m%Z!)HmHqUFlmtb>(#5QKN6Q?Ed~gjPX5l)tI)L zWBaCT?$3?M)gy8glBS+Gdb%&YU$4(PYV>VZ+Fu-fyS3^z>)5_kw_42f=vDXJ)K^WC zj(x81{noS2I5T^|?N)Z5TdkA3ew#huHmmD*_gIU!SiaS$?UmK%edhdG>rr3S`tb=2 z6dpTs?dzlNwq8ANy=9Fb+j99ub3b?4zs9b*_Nul^z7U%_b?W%BBgA#qW+~Y>VkuPuuuqo2L|~ zytT∾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 Cri=yv literal 0 HcmV?d00001 diff --git a/110_master/110/os/os/linux/Makefile b/110_master/110/os/os/linux/Makefile new file mode 100644 index 0000000..ecbcf30 --- /dev/null +++ b/110_master/110/os/os/linux/Makefile @@ -0,0 +1,125 @@ +# +# if you want the ram-disk device, define this to be the +# size in blocks. +# +RAMDISK = #-DRAMDISK=512 + +AS86 =as86 -0 -a +LD86 =ld86 -0 + +AS =as +LD =ld +LDFLAGS =-m elf_i386 -Ttext 0 -e startup_32 -Map=System.map.2 -N +CC =gcc -march=i386 $(RAMDISK) +CFLAGS =-w -g -fstrength-reduce -fomit-frame-pointer -fno-stack-protector -mcld +CPP =cpp -nostdinc -Iinclude + +# +# ROOT_DEV specifies the default root-device when making the image. +# This can be either FLOPPY, /dev/xxxx or empty, in which case the +# default of /dev/hd6 is used by 'build'. +# +ROOT_DEV= + +ARCHIVES=kernel/kernel.o mm/mm.o fs/fs.o +DRIVERS =kernel/blk_drv/blk_drv.a kernel/chr_drv/chr_drv.a +MATH =kernel/math/math.a +LIBS =lib/lib.a + +.c.s: + $(CC) $(CFLAGS) \ + -nostdinc -Iinclude -S -o $*.s $< +.s.o: + $(AS) -o $*.o $< +.c.o: + $(CC) $(CFLAGS) \ + -nostdinc -Iinclude -c -o $*.o $< + +all: Image + +Image: boot/bootsect boot/setup tools/system tools/build + cp -f tools/system system.tmp + strip system.tmp + tools/build boot/bootsect boot/setup system.tmp $(ROOT_DEV) > Image + rm -f system.tmp + sync + +disk: Image + dd bs=8192 if=Image of=/dev/PS0 + +tools/build: tools/build.c + $(CC) $(CFLAGS) \ + -o tools/build tools/build.c + +boot/head.o: boot/head.s + +tools/system: boot/head.o init/main.o \ + $(ARCHIVES) $(DRIVERS) $(MATH) $(LIBS) + $(LD) $(LDFLAGS) boot/head.o init/main.o \ + $(ARCHIVES) \ + $(DRIVERS) \ + $(MATH) \ + $(LIBS) \ + -o tools/system + nm tools/system | grep -v '\(compiled\)\|\(\.o$$\)\|\( [aUw]\)\|\(\.\.ng$$\)\|\(LASH[RL]DI\)' | sort >System.map + +kernel/math/math.a: FORCE + (cd kernel/math; make) + +kernel/blk_drv/blk_drv.a: FORCE + (cd kernel/blk_drv; make) + +kernel/chr_drv/chr_drv.a: FORCE + (cd kernel/chr_drv; make) + +kernel/kernel.o: FORCE + (cd kernel; make) + +mm/mm.o: FORCE + (cd mm; make) + +fs/fs.o: FORCE + (cd fs; make) + +lib/lib.a: FORCE + (cd lib; make) + +FORCE: + +boot/setup: boot/setup.s + $(AS86) -o boot/setup.o boot/setup.s + $(LD86) -s -o boot/setup boot/setup.o + +boot/bootsect: boot/bootsect.s + $(AS86) -o boot/bootsect.o boot/bootsect.s + $(LD86) -s -o boot/bootsect boot/bootsect.o + +tmp.s: boot/bootsect.s tools/system + (echo -n "SYSSIZE = (";ls -l tools/system | grep system \ + | cut -c25-31 | tr '\012' ' '; echo "+ 15 ) / 16") > tmp.s + cat boot/bootsect.s >> tmp.s + +clean: + rm -f Image System.map tmp_make core System.map.2 + rm -f boot/bootsect boot/setup + rm -f init/*.o tools/system tools/build boot/*.o + (cd mm;make clean) + (cd fs;make clean) + (cd kernel;make clean) + (cd lib;make clean) + +dep: + sed '/\#\#\# Dependencies/q' < Makefile > tmp_make + (for i in init/*.c;do echo -n "init/";$(CPP) -M $$i;done) >> tmp_make + cp tmp_make Makefile + (cd fs; make dep) + (cd kernel; make dep) + (cd mm; make dep) + +### Dependencies: +init/main.o : init/main.c include/unistd.h include/sys/stat.h \ + include/sys/types.h include/sys/times.h include/sys/utsname.h \ + include/utime.h include/time.h include/linux/tty.h include/termios.h \ + include/linux/sched.h include/linux/head.h include/linux/fs.h \ + include/linux/mm.h include/signal.h include/asm/system.h include/asm/io.h \ + include/stddef.h include/stdarg.h include/fcntl.h diff --git a/110_master/110/os/os/linux/System.map b/110_master/110/os/os/linux/System.map new file mode 100644 index 0000000..a25824e --- /dev/null +++ b/110_master/110/os/os/linux/System.map @@ -0,0 +1,598 @@ +00000000 T pg_dir +00000000 T startup_32 +0000005a t check_x87 +00000073 t setup_idt +00000090 t rp_sidt +000000a3 t setup_gdt +00001000 t pg0 +00002000 t pg1 +00003000 t pg2 +00004000 t pg3 +00005000 T tmp_floppy_area +00005412 t L6 +00005414 t int_msg +00005428 t ignore_int +00005450 t setup_paging +000054ae t idt_descr +000054b6 t gdt_descr +000054c0 T idt +00005cc0 T gdt +000064c0 T fork +000064ef T pause +0000651e T setup +00006555 T sync +00006584 t time_init +00006799 T main +0000690c t printf +0000695b T init +00006bd3 T print_nr +00006c04 T show_task +00006c89 T show_stat +00006ccf T math_state_restore +00006d2d T schedule +00006edf T sys_pause +00006ef5 T sleep_on +00006f54 T interruptible_sleep_on +0000700f T ticks_to_floppy_on +000070da T floppy_on +00007109 T floppy_off +00007119 T do_floppy_timer +00007311 T do_timer +00007400 T sys_alarm +0000747f T sys_getpid +0000748b T sys_getppid +00007497 T sys_getuid +000074a6 T sys_geteuid +000074b6 T sys_getgid +000074c6 T sys_getegid +000074d5 T sys_nice +00007500 T sched_init +00007690 t bad_sys_call +00007698 t reschedule +000076a4 T system_call +000076df t ret_from_sys_call +00007728 T coprocessor_error +0000774a T device_not_available +00007784 T timer_interrupt +000077bc T sys_execve +000077cc T sys_execve2 +000077dc T sys_fork +000077f4 T hd_interrupt +00007830 T floppy_interrupt +00007866 T parallel_interrupt +0000786d t _get_base +0000789f t die +00007a81 T do_double_fault +00007aa4 T do_general_protection +00007ac7 T do_divide_error +00007aea T do_int3 +00007bb2 T do_nmi +00007bd5 T do_debug +00007bf8 T do_overflow +00007c1b T do_bounds +00007c3e T do_invalid_op +00007c61 T do_device_not_available +00007c84 T do_coprocessor_segment_overrun +00007ca7 T do_invalid_TSS +00007cca T do_segment_not_present +00007ced T do_stack_segment +00007d10 T do_coprocessor_error +00007d44 T do_reserved +00007d67 T trap_init +0000804b T divide_error +00008050 t no_error_code +00008080 T debug +00008087 T nmi +0000808e T int3 +00008095 T overflow +0000809c T bounds +000080a3 T invalid_op +000080aa T coprocessor_segment_overrun +000080b1 T reserved +000080b8 T irq13 +000080cd T double_fault +000080d2 t error_code +00008104 T invalid_TSS +0000810b T segment_not_present +00008112 T stack_segment +00008119 T general_protection +00008120 t _get_base +00008152 T verify_area +000081b9 T copy_mem +00008313 T copy_process +000087c0 T find_empty_process +00008854 T panic +0000888f t put_fs_long +0000889b T sys_pipe2 +00008aa8 T printk +00008af9 t skip_atoi +00008b54 t number +00008dc5 T vsprintf +00009251 t get_fs_long +00009267 t put_fs_byte +0000927f t put_fs_long +0000928b T sys_ftime +00009291 T sys_break +00009297 T sys_ptrace +0000929d T sys_stty +000092a3 T sys_gtty +000092a9 T sys_rename +000092af T sys_prof +000092b5 T sys_setregid +0000936e T sys_setgid +00009405 T sys_acct +0000940b T sys_phys +00009411 T sys_lock +00009417 T sys_mpx +0000941d T sys_ulimit +00009423 T sys_time +0000947f T sys_setreuid +00009561 T sys_setuid +000095f6 T sys_stime +0000964c T sys_times +000096ec T sys_brk +0000972e T sys_setpgid +00009807 T sys_getpgrp +00009813 T sys_setsid +0000988d T sys_getgroups +00009893 T sys_setgroups +00009899 T sys_uname +00009902 T sys_sethostname +00009908 T sys_getrlimit +0000990e T sys_setrlimit +00009914 T sys_getrusage +0000991a T sys_gettimeofday +00009920 T sys_settimeofday +00009926 T sys_umask +00009959 T sys_sleep +00009992 t _get_base +000099c4 t get_fs_byte +000099d2 t get_fs_long +000099e8 t put_fs_byte +00009a00 t put_fs_long +00009a0c t get_fs +00009a20 t get_ds +00009a34 t set_fs +00009a3b t create_tables +00009b86 t count +00009bc5 t copy_strings +00009d81 t change_ldt +00009f04 T do_execve2 +0000a9d6 t _get_base +0000aa08 t put_fs_long +0000aa14 T release +0000aa78 t send_sig +0000aaf7 t kill_session +0000ab51 T sys_kill +0000ad01 t tell_father +0000ad8b T do_exit +0000afbf T sys_exit +0000afd8 T sys_waitpid +0000b1fe t get_fs_byte +0000b20c t put_fs_byte +0000b224 t put_fs_long +0000b230 T sys_sgetmask +0000b23c T sys_ssetmask +0000b268 T sys_sigpending +0000b26e T sys_sigsuspend +0000b274 t save_old +0000b2c7 t get_new +0000b307 T sys_signal +0000b38b T sys_sigaction +0000b495 T do_signal +0000b681 T kernel_mktime +0000b7c6 t put_fs_byte +0000b7de T sys_getdents +0000b921 T sys_getcwd +0000baf0 t oom +0000bb0f T get_free_page +0000bb4b T free_page +0000bbba T free_page_tables +0000bcb9 T copy_page_tables +0000be3a T put_page +0000bf26 T un_wp_page +0000bfde T do_wp_page +0000c069 T get_empty_page +0000c0a9 t try_to_share +0000c23b t share_page +0000c2ef T do_no_page +0000c484 T do_no_pagex +0000c5e6 T mem_init +0000c65a T calc_mem +0000c74f T page_fault +0000c786 t get_fs_long +0000c79c T sys_ustat +0000c7a2 T sys_utime +0000c84f T sys_access +0000c92b T sys_chdir +0000c99f T sys_chroot +0000ca13 T sys_chmod +0000caad T sys_chown +0000cb28 T sys_open +0000cdcb T sys_creat +0000cdee T sys_close +0000cebd T sys_lseek +0000cfd4 T sys_read +0000d1c7 T sys_write +0000d375 t lock_inode +0000d3a2 t unlock_inode +0000d3c0 T invalidate_inodes +0000d42f T sync_inodes +0000d486 t _bmap +0000d872 T bmap +0000d895 T create_block +0000d8b8 T iput +0000da27 T get_empty_inode +0000db7c T get_pipe_inode +0000dbf1 T iget +0000ddb6 t read_inode +0000dfec T sys_sync +0000e04f T sync_dev +0000e148 T invalidate_buffers +0000e1ba T check_disk_change +0000e264 t remove_from_queues +0000e35b t insert_into_queues +0000e420 t find_buffer +0000e488 T get_hash_table +0000e50a T getblk +0000e6a8 T brelse +0000e6f1 T bread +0000e776 T bread_page +0000e898 T breada +0000e98d T buffer_init +0000eabc t lock_super +0000eae9 t free_super +0000eb2e T get_super +0000eb9d T put_super +0000ec70 t read_super +0000efb3 T sys_umount +0000f114 T sys_mount +0000f285 T mount_root +0000f493 t get_fs_byte +0000f4a1 t put_fs_byte +0000f4b9 T block_write +0000f60b T block_read +0000f736 t get_fs_byte +0000f744 t put_fs_byte +0000f75c t rw_ttyx +0000f7a4 t rw_tty +0000f7f4 t rw_ram +0000f7fa t rw_mem +0000f800 t rw_kmem +0000f806 t rw_port +0000f8a0 t rw_memory +0000f976 T rw_char +0000f9e0 t get_fs_byte +0000f9ee t put_fs_byte +0000fa06 T file_read +0000fbb1 T file_write +0000fdab t put_fs_byte +0000fdc3 t cp_stat +0000fe9a T sys_stat +0000fee4 T sys_lstat +0000feff T sys_fstat +0000ff5c T sys_readlink +0000ff62 t _get_base +0000ff94 t get_fs_byte +0000ffa2 t get_fs_long +0000ffb8 t put_fs_byte +0000ffd0 t put_fs_long +0000ffdc t get_fs +0000fff0 t get_ds +00010004 t set_fs +0001000b T sys_uselib +00010011 t create_tables +0001015c t count +0001019b t copy_strings +00010357 t change_ldt +000104da T do_execve +00010f5c t get_fs_byte +00010f6a t put_fs_byte +00010f82 t put_fs_long +00010f8e T read_pipe +00011263 T sys_pipe +00011465 t get_fs_byte +00011473 t permission +00011514 t match +0001157c t find_entry +000119d6 t get_dir +00011bc3 t dir_namei +00011c42 T namei +00011d58 T open_namei +000120ab T sys_mknod +000122db T sys_mkdir +0001268c t empty_dir +0001286a T sys_rmdir +00012bc2 T sys_unlink +00012e63 T sys_symlink +00012e69 T sys_link +000130c3 T free_block +00013235 T new_block +000133d9 T free_inode +00013540 T new_inode +0001371a t dupfd +000137f4 T sys_dup2 +0001381b T sys_dup +00013836 T sys_fcntl +00013975 T sys_ioctl +00013a46 t free_ind +00013ae5 t free_dind +00013b84 T truncate +00013cb9 T sys_select +00013cbf t lock_buffer +00013cec t unlock_buffer +00013ede t make_request +00014082 T ll_rw_block +000140db T blk_dev_init +00014129 t unlock_buffer +0001415e t end_request +0001420f T floppy_deselect +00014246 T floppy_change +000142cc t setup_DMA +00014382 t output_byte +000143f8 t result +000144b5 t bad_flp_intr +00014514 t rw_interrupt +00014603 T setup_rw_floppy +000146c4 t seek_interrupt +0001471d t transfer +00014852 t recal_interrupt +0001489c T unexpected_floppy_interrupt +000148e1 t recalibrate_floppy +00014943 t reset_interrupt +00014988 t reset_floppy +00014a05 t floppy_on_interrupt +00014a70 t do_fd_request +00014c74 T floppy_init +00014cc6 t unlock_buffer +00014cfb t end_request +00014d9a T sys_setup +0001514d t controller_ready +000151e1 t hd_out +000152ce t drive_busy +00015334 t reset_controller +000153b1 t reset_hd +00015449 T unexpected_hd_interrupt +0001545c t bad_rw_intr +0001549a t read_intr +000155c0 t recal_intr +000155da t do_hd_request +000158db T hd_init +00015955 t unlock_buffer +0001598a t end_request +00015a29 t do_rd_request +00015b5f T rd_init +00015bb5 T rd_load +00015e61 t get_fs_byte +00015e6f t put_fs_byte +00015e87 T tty_init +00015e98 T tty_intr +00015f0c t sleep_if_empty +00015f44 t sleep_if_full +00015fb8 T copy_to_cooked +00016573 T tty_read +000168e1 T tty_write +00016af3 T do_tty_interrupt +00016b1b T chr_dev_init +00016b1c t gotoxy +00016b6a t set_origin +00016bd0 t scrup +00016dc0 t scrdown +00016eb7 t lf +00016eed t ri +00016f23 t cr +00016f44 t del +00016f76 t csi_J +00017007 t csi_K +000170b9 T csi_m +00017120 t set_cursor +00017186 t respond +000171de t insert_char +00017241 t insert_line +00017285 t delete_char +000172e3 t delete_line +00017327 t csi_at +00017365 t csi_L +000173a3 t csi_P +000173e1 t csi_M +0001741f t save_cur +00017434 t restore_cur +00017453 T con_write +00017ae1 T con_init +00017d18 T sysbeepstop +00017d41 t sysbeep +00017d9f t mode +00017da0 t leds +00017da1 t e0 +00017da2 T keyboard_interrupt +00017dcb t e0_e1 +00017df6 t set_e0 +00017dff t set_e1 +00017e08 t put_queue +00017e41 t ctrl +00017e59 t unctrl +00017e5d t unalt +00017e73 t lshift +00017e7b t unlshift +00017e83 t rshift +00017e8b t unrshift +00017e93 t caps +00017eb5 t set_leds +00017ecb t uncaps +00017ed3 t scroll +00017edc t num +00017ee5 t cursor +00017f05 t cur2 +00017f2e t cur +00017f3a t ok_cur +00017f48 t num_table +00017f55 t cur_table +00017f62 t func +00017f7f t ok_func +00017f92 t end_func +00017f93 t func_table +00017fc3 t key_map +00018024 t shift_map +000180e6 t do_self +0001814e t none +0001814f t minus +00018164 t key_table +00018564 t kb_wait +0001856d t reboot +0001857f t die +00018581 t init +000185f6 T rs_init +00018679 T rs_write +000186c8 T rs1_interrupt +000186d0 T rs2_interrupt +000186d5 t rs_int +000186ec t rep_int +00018709 t end +00018717 t jmp_table +00018728 t modem_status +00018730 t line_status +00018738 t read_char +000187bf t get_fs_byte +000187cd t get_fs_long +000187e3 t put_fs_byte +000187fb t put_fs_long +00018807 t change_speed +00018885 t flush +00018897 t send_break +00018898 t get_termios +000188f4 t set_termios +00018944 t get_termio +00018a0c t set_termio +00018ad0 T tty_ioctl +00018dce t get_fs_byte +00018ddc T math_emulate +00018ebf T math_error +00018edf T _exit +00018eef T open +00018f38 T close +00018fac T dup +00018fe3 T setsid +00019012 T execve +000190af T strcpy +000190cb T strncpy +000190f0 T strcat +0001911b T strncat +00019150 T strcmp +00019177 T strncmp +000191a5 T strchr +000191d2 T strrchr +00019201 T strspn +0001923e T strcspn +0001927b T strpbrk +000192b2 T strstr +000192eb T strlen +0001930e T strtok +00019391 T memcpy +000193b1 T memmove +00019405 T memcmp +0001942f T memchr +00019467 T memset +0001d5e8 d envp_rc +0001d5fc d envp +0001d620 D sys_call_table +0001d790 D NR_syscalls +0001d7a0 d init_task +0001e7a0 D current +0001e7c0 D task +0001e8c0 D stack_start +0001e8c8 D current_DOR +0001e8e0 d thisname.1955 +0001e920 d month +0001e960 d last_inode.1935 +0001e964 D start_buffer +0001e980 d crw_table +0001e9a0 d ioctl_table +0001e9c0 d floppy_type +0001ea80 d cur_spec1 +0001ea84 d cur_rate +0001ea88 d floppy +0001ea8c d current_track +0001ea90 d callable.1844 +0001eaa0 D tty_table +00020fc0 D table_list +00020fe0 d quotient +00021000 D _ctype +00021101 B __bss_start +00021101 D _edata +00021120 b printbuf +00021520 b memory_end +00021524 b buffer_memory_end +00021528 b main_memory_start +00021540 B jiffies +00021544 B startup_time +00021548 B last_task_used_math +0002155c b mon_timer +0002156c b moff_timer +00021580 b timer_list +00021880 b next_timer +00021884 B last_pid +000218a0 b buf +00021ca0 b HIGH_MEMORY +00021cc0 b mem_map +00022bc0 B inode_table +000232c0 B nr_buffers +000232c4 b free_list +000232c8 b buffer_wait +000232cc B ROOT_DEV +00023300 B blk_dev +00023338 B do_floppy +0002333c B selected +00023344 b recalibrate +00023348 b reset +0002334c b seek +00023350 b reply_buffer +00023357 b current_drive +00023358 b sector +00023359 b head +0002335a b track +0002335b b seek_track +0002335c b command +00023360 B do_hd +00023380 B hd_info +000233b0 b recalibrate +000233b4 b reset +000233b8 b NR_HD +000233c0 b hd +00023410 B rd_length +00023414 b cr_flag.1923 +00023420 B beepcount +00023424 b video_type +00023428 b video_num_columns +0002342c b video_size_row +00023430 b video_num_lines +00023434 b video_page +00023438 b video_mem_start +0002343c b video_mem_end +00023440 b video_port_reg +00023442 b video_port_val +00023444 b video_erase_char +00023448 b origin +0002344c b scr_end +00023450 b pos +00023454 b x +00023458 b y +0002345c b top +00023460 b bottom +00023464 b state +00023468 b npar +00023480 b par +000234c0 b ques +000234c4 b saved_x +000234c8 b saved_y +000234e0 B drive_info +00023500 B user_stack +00024500 B hash_table +000249e0 B super_block +00024d40 B file_table +00025140 B request +000255c0 B rd_start +000255c4 B _ctmp +000255c8 B errno +000255cc B ___strtok +000255d0 B end +000255d0 B _end diff --git a/110_master/110/os/os/linux/System.map.2 b/110_master/110/os/os/linux/System.map.2 new file mode 100644 index 0000000..f550302 --- /dev/null +++ b/110_master/110/os/os/linux/System.map.2 @@ -0,0 +1,1082 @@ +Archive member included to satisfy reference by file (symbol) + +kernel/blk_drv/blk_drv.a(ll_rw_blk.o) + fs/fs.o (ll_rw_block) +kernel/blk_drv/blk_drv.a(floppy.o) + kernel/kernel.o (do_floppy) +kernel/blk_drv/blk_drv.a(hd.o) + kernel/kernel.o (do_hd) +kernel/blk_drv/blk_drv.a(ramdisk.o) + kernel/blk_drv/blk_drv.a(hd.o) (rd_load) +kernel/chr_drv/chr_drv.a(tty_io.o) + kernel/kernel.o (tty_table) +kernel/chr_drv/chr_drv.a(console.o) + kernel/chr_drv/chr_drv.a(tty_io.o) (con_write) +kernel/chr_drv/chr_drv.a(keyboard.2.o) + kernel/chr_drv/chr_drv.a(console.o) (keyboard_interrupt) +kernel/chr_drv/chr_drv.a(serial.o) + kernel/chr_drv/chr_drv.a(tty_io.o) (rs_init) +kernel/chr_drv/chr_drv.a(rs_io.o) + kernel/chr_drv/chr_drv.a(serial.o) (rs1_interrupt) +kernel/chr_drv/chr_drv.a(tty_ioctl.o) + fs/fs.o (tty_ioctl) +kernel/math/math.a(math_emulate.o) + kernel/kernel.o (math_emulate) +lib/lib.a(ctype.o) kernel/chr_drv/chr_drv.a(tty_io.o) (_ctmp) +lib/lib.a(_exit.o) init/main.o (_exit) +lib/lib.a(open.o) init/main.o (open) +lib/lib.a(close.o) init/main.o (close) +lib/lib.a(errno.o) init/main.o (errno) +lib/lib.a(write.o) init/main.o (write) +lib/lib.a(dup.o) init/main.o (dup) +lib/lib.a(setsid.o) init/main.o (setsid) +lib/lib.a(execve.o) init/main.o (execve) +lib/lib.a(wait.o) init/main.o (wait) +lib/lib.a(string.o) kernel/kernel.o (strncpy) + +分配公共符号 +公共符号 大小 文件 + +errno 0x4 lib/lib.a(errno.o) +hash_table 0x4cc fs/fs.o +___strtok 0x4 lib/lib.a(string.o) +rd_start 0x4 kernel/blk_drv/blk_drv.a(ramdisk.o) +request 0x480 kernel/blk_drv/blk_drv.a(ll_rw_blk.o) +user_stack 0x1000 kernel/kernel.o +_ctmp 0x1 lib/lib.a(ctype.o) +super_block 0x360 fs/fs.o +drive_info 0x20 init/main.o +file_table 0x400 fs/fs.o + +Discarded input sections + + .note.GNU-stack + 0x0000000000000000 0x0 init/main.o + .note.GNU-stack + 0x0000000000000000 0x0 kernel/kernel.o + .note.GNU-stack + 0x0000000000000000 0x0 mm/mm.o + .note.GNU-stack + 0x0000000000000000 0x0 fs/fs.o + .note.GNU-stack + 0x0000000000000000 0x0 kernel/blk_drv/blk_drv.a(ll_rw_blk.o) + .note.GNU-stack + 0x0000000000000000 0x0 kernel/blk_drv/blk_drv.a(floppy.o) + .note.GNU-stack + 0x0000000000000000 0x0 kernel/blk_drv/blk_drv.a(hd.o) + .note.GNU-stack + 0x0000000000000000 0x0 kernel/blk_drv/blk_drv.a(ramdisk.o) + .note.GNU-stack + 0x0000000000000000 0x0 kernel/chr_drv/chr_drv.a(tty_io.o) + .note.GNU-stack + 0x0000000000000000 0x0 kernel/chr_drv/chr_drv.a(console.o) + .note.GNU-stack + 0x0000000000000000 0x0 kernel/chr_drv/chr_drv.a(serial.o) + .note.GNU-stack + 0x0000000000000000 0x0 kernel/chr_drv/chr_drv.a(tty_ioctl.o) + .note.GNU-stack + 0x0000000000000000 0x0 kernel/math/math.a(math_emulate.o) + .note.GNU-stack + 0x0000000000000000 0x0 lib/lib.a(ctype.o) + .note.GNU-stack + 0x0000000000000000 0x0 lib/lib.a(_exit.o) + .note.GNU-stack + 0x0000000000000000 0x0 lib/lib.a(open.o) + .note.GNU-stack + 0x0000000000000000 0x0 lib/lib.a(close.o) + .note.GNU-stack + 0x0000000000000000 0x0 lib/lib.a(errno.o) + .note.GNU-stack + 0x0000000000000000 0x0 lib/lib.a(write.o) + .note.GNU-stack + 0x0000000000000000 0x0 lib/lib.a(dup.o) + .note.GNU-stack + 0x0000000000000000 0x0 lib/lib.a(setsid.o) + .note.GNU-stack + 0x0000000000000000 0x0 lib/lib.a(execve.o) + .note.GNU-stack + 0x0000000000000000 0x0 lib/lib.a(wait.o) + .note.GNU-stack + 0x0000000000000000 0x0 lib/lib.a(string.o) + +内存配置 + +名称 来源 长度 属性 +*default* 0x0000000000000000 0xffffffffffffffff + +Linker script and memory map + +段 .text 的地址设置为 0x0 +LOAD boot/head.o +LOAD init/main.o +LOAD kernel/kernel.o +LOAD mm/mm.o +LOAD fs/fs.o +LOAD kernel/blk_drv/blk_drv.a +LOAD kernel/chr_drv/chr_drv.a +LOAD kernel/math/math.a +LOAD lib/lib.a + 0x0000000008048000 PROVIDE (__executable_start, 0x8048000) + 0x0000000008048074 . = (0x8048000 + SIZEOF_HEADERS) + +.interp + *(.interp) + +.note.gnu.build-id + *(.note.gnu.build-id) + +.hash + *(.hash) + +.gnu.hash + *(.gnu.hash) + +.dynsym + *(.dynsym) + +.dynstr + *(.dynstr) + +.gnu.version + *(.gnu.version) + +.gnu.version_d + *(.gnu.version_d) + +.gnu.version_r + *(.gnu.version_r) + +.rel.init + *(.rel.init) + +.rel.text 0x0000000008048074 0x0 + *(.rel.text .rel.text.* .rel.gnu.linkonce.t.*) + .rel.text 0x0000000000000000 0x0 boot/head.o + +.rel.fini + *(.rel.fini) + +.rel.rodata + *(.rel.rodata .rel.rodata.* .rel.gnu.linkonce.r.*) + +.rel.data.rel.ro + *(.rel.data.rel.ro .rel.data.rel.ro.* .rel.gnu.linkonce.d.rel.ro.*) + +.rel.data 0x0000000008048074 0x0 + *(.rel.data .rel.data.* .rel.gnu.linkonce.d.*) + .rel.data 0x0000000000000000 0x0 boot/head.o + +.rel.tdata + *(.rel.tdata .rel.tdata.* .rel.gnu.linkonce.td.*) + +.rel.tbss + *(.rel.tbss .rel.tbss.* .rel.gnu.linkonce.tb.*) + +.rel.ctors + *(.rel.ctors) + +.rel.dtors + *(.rel.dtors) + +.rel.got + *(.rel.got) + +.rel.bss + *(.rel.bss .rel.bss.* .rel.gnu.linkonce.b.*) + +.rel.ifunc + *(.rel.ifunc) + +.rel.plt 0x0000000008048074 0x0 + *(.rel.plt) + 0x0000000008048074 PROVIDE (__rel_iplt_start, .) + *(.rel.iplt) + .rel.iplt 0x0000000000000000 0x0 boot/head.o + 0x0000000008048074 PROVIDE (__rel_iplt_end, .) + +.init + *(SORT(.init)) + +.plt 0x0000000008048080 0x0 + *(.plt) + *(.iplt) + .iplt 0x0000000000000000 0x0 boot/head.o + +.text 0x0000000000000000 0x1948b + *(.text.unlikely .text.*_unlikely .text.unlikely.*) + *(.text.exit .text.exit.*) + *(.text.startup .text.startup.*) + *(.text.hot .text.hot.*) + *(.text .stub .text.* .gnu.linkonce.t.*) + .text 0x0000000000000000 0x64c0 boot/head.o + 0x0000000000000000 startup_32 + 0x0000000000000000 pg_dir + 0x0000000000005000 tmp_floppy_area + 0x00000000000054c0 idt + 0x0000000000005cc0 gdt + .text 0x00000000000064c0 0x744 init/main.o + 0x00000000000064c0 fork + 0x00000000000064ef pause + 0x000000000000651e setup + 0x0000000000006555 sync + 0x0000000000006799 main + 0x000000000000695b init + 0x0000000000006bd3 print_nr + .text 0x0000000000006c04 0x4eec kernel/kernel.o + 0x0000000000006c04 show_task + 0x0000000000006c89 show_stat + 0x0000000000006ccf math_state_restore + 0x0000000000006d2d schedule + 0x0000000000006edf sys_pause + 0x0000000000006ef5 sleep_on + 0x0000000000006f54 interruptible_sleep_on + 0x0000000000006fe7 wake_up + 0x000000000000700f ticks_to_floppy_on + 0x00000000000070da floppy_on + 0x0000000000007109 floppy_off + 0x0000000000007119 do_floppy_timer + 0x00000000000071ed add_timer + 0x0000000000007311 do_timer + 0x0000000000007400 sys_alarm + 0x000000000000747f sys_getpid + 0x000000000000748b sys_getppid + 0x0000000000007497 sys_getuid + 0x00000000000074a6 sys_geteuid + 0x00000000000074b6 sys_getgid + 0x00000000000074c6 sys_getegid + 0x00000000000074d5 sys_nice + 0x0000000000007500 sched_init + 0x00000000000076a4 system_call + 0x0000000000007728 coprocessor_error + 0x000000000000774a device_not_available + 0x0000000000007784 timer_interrupt + 0x00000000000077bc sys_execve + 0x00000000000077cc sys_execve2 + 0x00000000000077dc sys_fork + 0x00000000000077f4 hd_interrupt + 0x0000000000007830 floppy_interrupt + 0x0000000000007866 parallel_interrupt + 0x0000000000007a81 do_double_fault + 0x0000000000007aa4 do_general_protection + 0x0000000000007ac7 do_divide_error + 0x0000000000007aea do_int3 + 0x0000000000007bb2 do_nmi + 0x0000000000007bd5 do_debug + 0x0000000000007bf8 do_overflow + 0x0000000000007c1b do_bounds + 0x0000000000007c3e do_invalid_op + 0x0000000000007c61 do_device_not_available + 0x0000000000007c84 do_coprocessor_segment_overrun + 0x0000000000007ca7 do_invalid_TSS + 0x0000000000007cca do_segment_not_present + 0x0000000000007ced do_stack_segment + 0x0000000000007d10 do_coprocessor_error + 0x0000000000007d44 do_reserved + 0x0000000000007d67 trap_init + 0x000000000000804b divide_error + 0x0000000000008080 debug + 0x0000000000008087 nmi + 0x000000000000808e int3 + 0x0000000000008095 overflow + 0x000000000000809c bounds + 0x00000000000080a3 invalid_op + 0x00000000000080aa coprocessor_segment_overrun + 0x00000000000080b1 reserved + 0x00000000000080b8 irq13 + 0x00000000000080cd double_fault + 0x0000000000008104 invalid_TSS + 0x000000000000810b segment_not_present + 0x0000000000008112 stack_segment + 0x0000000000008119 general_protection + 0x0000000000008152 verify_area + 0x00000000000081b9 copy_mem + 0x0000000000008313 copy_process + 0x00000000000087c0 find_empty_process + 0x0000000000008854 panic + 0x000000000000889b sys_pipe2 + 0x0000000000008aa8 printk + 0x0000000000008dc5 vsprintf + 0x000000000000928b sys_ftime + 0x0000000000009291 sys_break + 0x0000000000009297 sys_ptrace + 0x000000000000929d sys_stty + 0x00000000000092a3 sys_gtty + 0x00000000000092a9 sys_rename + 0x00000000000092af sys_prof + 0x00000000000092b5 sys_setregid + 0x000000000000936e sys_setgid + 0x0000000000009405 sys_acct + 0x000000000000940b sys_phys + 0x0000000000009411 sys_lock + 0x0000000000009417 sys_mpx + 0x000000000000941d sys_ulimit + 0x0000000000009423 sys_time + 0x000000000000947f sys_setreuid + 0x0000000000009561 sys_setuid + 0x00000000000095f6 sys_stime + 0x000000000000964c sys_times + 0x00000000000096ec sys_brk + 0x000000000000972e sys_setpgid + 0x0000000000009807 sys_getpgrp + 0x0000000000009813 sys_setsid + 0x000000000000988d sys_getgroups + 0x0000000000009893 sys_setgroups + 0x0000000000009899 sys_uname + 0x0000000000009902 sys_sethostname + 0x0000000000009908 sys_getrlimit + 0x000000000000990e sys_setrlimit + 0x0000000000009914 sys_getrusage + 0x000000000000991a sys_gettimeofday + 0x0000000000009920 sys_settimeofday + 0x0000000000009926 sys_umask + 0x0000000000009959 sys_sleep + 0x0000000000009f04 do_execve2 + 0x000000000000aa14 release + 0x000000000000ab51 sys_kill + 0x000000000000ad8b do_exit + 0x000000000000afbf sys_exit + 0x000000000000afd8 sys_waitpid + 0x000000000000b230 sys_sgetmask + 0x000000000000b23c sys_ssetmask + 0x000000000000b268 sys_sigpending + 0x000000000000b26e sys_sigsuspend + 0x000000000000b307 sys_signal + 0x000000000000b38b sys_sigaction + 0x000000000000b495 do_signal + 0x000000000000b681 kernel_mktime + 0x000000000000b7de sys_getdents + 0x000000000000b921 sys_getcwd + .text 0x000000000000baf0 0xc96 mm/mm.o + 0x000000000000bb0f get_free_page + 0x000000000000bb4b free_page + 0x000000000000bbba free_page_tables + 0x000000000000bcb9 copy_page_tables + 0x000000000000be3a put_page + 0x000000000000bf26 un_wp_page + 0x000000000000bfde do_wp_page + 0x000000000000c010 write_verify + 0x000000000000c069 get_empty_page + 0x000000000000c2ef do_no_page + 0x000000000000c484 do_no_pagex + 0x000000000000c5e6 mem_init + 0x000000000000c65a calc_mem + 0x000000000000c74f page_fault + .text 0x000000000000c786 0x7539 fs/fs.o + 0x000000000000c79c sys_ustat + 0x000000000000c7a2 sys_utime + 0x000000000000c84f sys_access + 0x000000000000c92b sys_chdir + 0x000000000000c99f sys_chroot + 0x000000000000ca13 sys_chmod + 0x000000000000caad sys_chown + 0x000000000000cb28 sys_open + 0x000000000000cdcb sys_creat + 0x000000000000cdee sys_close + 0x000000000000cebd sys_lseek + 0x000000000000cfd4 sys_read + 0x000000000000d1c7 sys_write + 0x000000000000d3c0 invalidate_inodes + 0x000000000000d42f sync_inodes + 0x000000000000d872 bmap + 0x000000000000d895 create_block + 0x000000000000d8b8 iput + 0x000000000000da27 get_empty_inode + 0x000000000000db7c get_pipe_inode + 0x000000000000dbf1 iget + 0x000000000000dfec sys_sync + 0x000000000000e04f sync_dev + 0x000000000000e148 invalidate_buffers + 0x000000000000e1ba check_disk_change + 0x000000000000e488 get_hash_table + 0x000000000000e50a getblk + 0x000000000000e6a8 brelse + 0x000000000000e6f1 bread + 0x000000000000e776 bread_page + 0x000000000000e898 breada + 0x000000000000e98d buffer_init + 0x000000000000eb2e get_super + 0x000000000000eb9d put_super + 0x000000000000efb3 sys_umount + 0x000000000000f114 sys_mount + 0x000000000000f285 mount_root + 0x000000000000f4b9 block_write + 0x000000000000f60b block_read + 0x000000000000f976 rw_char + 0x000000000000fa06 file_read + 0x000000000000fbb1 file_write + 0x000000000000fe9a sys_stat + 0x000000000000fee4 sys_lstat + 0x000000000000feff sys_fstat + 0x000000000000ff5c sys_readlink + 0x000000000001000b sys_uselib + 0x00000000000104da do_execve + 0x0000000000010f8e read_pipe + 0x00000000000110e4 write_pipe + 0x0000000000011263 sys_pipe + 0x0000000000011c42 namei + 0x0000000000011d58 open_namei + 0x00000000000120ab sys_mknod + 0x00000000000122db sys_mkdir + 0x000000000001286a sys_rmdir + 0x0000000000012bc2 sys_unlink + 0x0000000000012e63 sys_symlink + 0x0000000000012e69 sys_link + 0x00000000000130c3 free_block + 0x0000000000013235 new_block + 0x00000000000133d9 free_inode + 0x0000000000013540 new_inode + 0x00000000000137f4 sys_dup2 + 0x000000000001381b sys_dup + 0x0000000000013836 sys_fcntl + 0x0000000000013975 sys_ioctl + 0x0000000000013b84 truncate + 0x0000000000013cb9 sys_select + .text 0x0000000000013cbf 0x46a kernel/blk_drv/blk_drv.a(ll_rw_blk.o) + 0x0000000000014082 ll_rw_block + 0x00000000000140db blk_dev_init + .text 0x0000000000014129 0xb9d kernel/blk_drv/blk_drv.a(floppy.o) + 0x000000000001420f floppy_deselect + 0x0000000000014246 floppy_change + 0x0000000000014603 setup_rw_floppy + 0x000000000001489c unexpected_floppy_interrupt + 0x0000000000014c74 floppy_init + .text 0x0000000000014cc6 0xc8f kernel/blk_drv/blk_drv.a(hd.o) + 0x0000000000014d9a sys_setup + 0x0000000000015449 unexpected_hd_interrupt + 0x00000000000158db hd_init + .text 0x0000000000015955 0x50c kernel/blk_drv/blk_drv.a(ramdisk.o) + 0x0000000000015b5f rd_init + 0x0000000000015bb5 rd_load + .text 0x0000000000015e61 0xcbb kernel/chr_drv/chr_drv.a(tty_io.o) + 0x0000000000015e87 tty_init + 0x0000000000015e98 tty_intr + 0x0000000000015fa5 wait_for_keypress + 0x0000000000015fb8 copy_to_cooked + 0x0000000000016573 tty_read + 0x00000000000168e1 tty_write + 0x0000000000016af3 do_tty_interrupt + 0x0000000000016b1b chr_dev_init + .text 0x0000000000016b1c 0x1283 kernel/chr_drv/chr_drv.a(console.o) + 0x00000000000170b9 csi_m + 0x0000000000017453 con_write + 0x0000000000017ae1 con_init + 0x0000000000017d18 sysbeepstop + .text 0x0000000000017d9f 0x7e2 kernel/chr_drv/chr_drv.a(keyboard.2.o) + 0x0000000000017da2 keyboard_interrupt + .text 0x0000000000018581 0x145 kernel/chr_drv/chr_drv.a(serial.o) + 0x00000000000185f6 rs_init + 0x0000000000018679 rs_write + *fill* 0x00000000000186c6 0x2 + .text 0x00000000000186c8 0xf7 kernel/chr_drv/chr_drv.a(rs_io.o) + 0x00000000000186c8 rs1_interrupt + 0x00000000000186d0 rs2_interrupt + .text 0x00000000000187bf 0x60f kernel/chr_drv/chr_drv.a(tty_ioctl.o) + 0x0000000000018ad0 tty_ioctl + .text 0x0000000000018dce 0x111 kernel/math/math.a(math_emulate.o) + 0x0000000000018ddc math_emulate + 0x0000000000018ebf math_error + .text 0x0000000000018edf 0x0 lib/lib.a(ctype.o) + .text 0x0000000000018edf 0x10 lib/lib.a(_exit.o) + 0x0000000000018edf _exit + .text 0x0000000000018eef 0x49 lib/lib.a(open.o) + 0x0000000000018eef open + .text 0x0000000000018f38 0x37 lib/lib.a(close.o) + 0x0000000000018f38 close + .text 0x0000000000018f6f 0x0 lib/lib.a(errno.o) + .text 0x0000000000018f6f 0x3d lib/lib.a(write.o) + 0x0000000000018f6f write + .text 0x0000000000018fac 0x37 lib/lib.a(dup.o) + 0x0000000000018fac dup + .text 0x0000000000018fe3 0x2f lib/lib.a(setsid.o) + 0x0000000000018fe3 setsid + .text 0x0000000000019012 0x3d lib/lib.a(execve.o) + 0x0000000000019012 execve + .text 0x000000000001904f 0x60 lib/lib.a(wait.o) + 0x000000000001904f waitpid + 0x000000000001908c wait + .text 0x00000000000190af 0x3dc lib/lib.a(string.o) + 0x00000000000190af strcpy + 0x00000000000190cb strncpy + 0x00000000000190f0 strcat + 0x000000000001911b strncat + 0x0000000000019150 strcmp + 0x0000000000019177 strncmp + 0x00000000000191a5 strchr + 0x00000000000191d2 strrchr + 0x0000000000019201 strspn + 0x000000000001923e strcspn + 0x000000000001927b strpbrk + 0x00000000000192b2 strstr + 0x00000000000192eb strlen + 0x000000000001930e strtok + 0x0000000000019391 memcpy + 0x00000000000193b1 memmove + 0x0000000000019405 memcmp + 0x000000000001942f memchr + 0x0000000000019467 memset + *(.gnu.warning) + +.fini + *(SORT(.fini)) + 0x000000000001948b PROVIDE (__etext, .) + 0x000000000001948b PROVIDE (_etext, .) + 0x000000000001948b PROVIDE (etext, .) + +.rodata 0x000000000001948c 0x146e + *(.rodata .rodata.* .gnu.linkonce.r.*) + .rodata 0x000000000001948c 0xc9 init/main.o + *fill* 0x0000000000019555 0x3 + .rodata 0x0000000000019558 0x498 kernel/kernel.o + .rodata 0x00000000000199f0 0x1b5 mm/mm.o + *fill* 0x0000000000019ba5 0x3 + .rodata 0x0000000000019ba8 0x62c fs/fs.o + .rodata 0x000000000001a1d4 0x7a kernel/blk_drv/blk_drv.a(ll_rw_blk.o) + *fill* 0x000000000001a24e 0x2 + .rodata 0x000000000001a250 0x133 kernel/blk_drv/blk_drv.a(floppy.o) + *fill* 0x000000000001a383 0x1 + .rodata 0x000000000001a384 0x19b kernel/blk_drv/blk_drv.a(hd.o) + *fill* 0x000000000001a51f 0x1 + .rodata 0x000000000001a520 0x188 kernel/blk_drv/blk_drv.a(ramdisk.o) + .rodata 0x000000000001a6a8 0x17d kernel/chr_drv/chr_drv.a(console.o) + *fill* 0x000000000001a825 0x3 + .rodata 0x000000000001a828 0x80 kernel/chr_drv/chr_drv.a(tty_ioctl.o) + .rodata 0x000000000001a8a8 0x52 kernel/math/math.a(math_emulate.o) + +.rodata1 + *(.rodata1) + +.eh_frame_hdr + *(.eh_frame_hdr) + +.eh_frame 0x000000000001a8fc 0x2cc8 + *(.eh_frame) + .eh_frame 0x000000000001a8fc 0x108 init/main.o + .eh_frame 0x000000000001aa04 0xd2c kernel/kernel.o + 0xe64 (size before relaxing) + .eh_frame 0x000000000001b730 0x1b0 mm/mm.o + 0x1c8 (size before relaxing) + .eh_frame 0x000000000001b8e0 0xdd8 fs/fs.o + 0xf70 (size before relaxing) + .eh_frame 0x000000000001c6b8 0x98 kernel/blk_drv/blk_drv.a(ll_rw_blk.o) + 0xb0 (size before relaxing) + .eh_frame 0x000000000001c750 0x23c kernel/blk_drv/blk_drv.a(floppy.o) + 0x254 (size before relaxing) + .eh_frame 0x000000000001c98c 0x1e8 kernel/blk_drv/blk_drv.a(hd.o) + 0x200 (size before relaxing) + .eh_frame 0x000000000001cb74 0xac kernel/blk_drv/blk_drv.a(ramdisk.o) + 0xc4 (size before relaxing) + .eh_frame 0x000000000001cc20 0x12c kernel/chr_drv/chr_drv.a(tty_io.o) + 0x144 (size before relaxing) + .eh_frame 0x000000000001cd4c 0x2c0 kernel/chr_drv/chr_drv.a(console.o) + 0x2d8 (size before relaxing) + .eh_frame 0x000000000001d00c 0x54 kernel/chr_drv/chr_drv.a(serial.o) + 0x6c (size before relaxing) + .eh_frame 0x000000000001d060 0x148 kernel/chr_drv/chr_drv.a(tty_ioctl.o) + 0x160 (size before relaxing) + .eh_frame 0x000000000001d1a8 0x5c kernel/math/math.a(math_emulate.o) + 0x74 (size before relaxing) + .eh_frame 0x000000000001d204 0x1c lib/lib.a(_exit.o) + 0x34 (size before relaxing) + .eh_frame 0x000000000001d220 0x24 lib/lib.a(open.o) + 0x3c (size before relaxing) + .eh_frame 0x000000000001d244 0x20 lib/lib.a(close.o) + 0x38 (size before relaxing) + .eh_frame 0x000000000001d264 0x20 lib/lib.a(write.o) + 0x38 (size before relaxing) + .eh_frame 0x000000000001d284 0x20 lib/lib.a(dup.o) + 0x38 (size before relaxing) + .eh_frame 0x000000000001d2a4 0x18 lib/lib.a(setsid.o) + 0x30 (size before relaxing) + .eh_frame 0x000000000001d2bc 0x20 lib/lib.a(execve.o) + 0x38 (size before relaxing) + .eh_frame 0x000000000001d2dc 0x38 lib/lib.a(wait.o) + 0x50 (size before relaxing) + .eh_frame 0x000000000001d314 0x2b0 lib/lib.a(string.o) + 0x2c8 (size before relaxing) + +.gcc_except_table + *(.gcc_except_table .gcc_except_table.*) + +.exception_ranges + *(.exception_ranges .exception_ranges*) + 0x000000000001d5c4 . = . + +.eh_frame + *(.eh_frame) + +.gcc_except_table + *(.gcc_except_table .gcc_except_table.*) + +.exception_ranges + *(.exception_ranges .exception_ranges*) + +.tdata + *(.tdata .tdata.* .gnu.linkonce.td.*) + +.tbss + *(.tbss .tbss.* .gnu.linkonce.tb.*) + *(.tcommon) + +.preinit_array 0x000000000001d5c4 0x0 + 0x000000000001d5c4 PROVIDE (__preinit_array_start, .) + *(.preinit_array) + 0x000000000001d5c4 PROVIDE (__preinit_array_end, .) + +.init_array 0x000000000001d5c4 0x0 + 0x000000000001d5c4 PROVIDE (__init_array_start, .) + *(SORT(.init_array.*) SORT(.ctors.*)) + *(.init_array EXCLUDE_FILE(*crtend?.o *crtend.o *crtbegin?.o *crtbegin.o) .ctors) + 0x000000000001d5c4 PROVIDE (__init_array_end, .) + +.fini_array 0x000000000001d5c4 0x0 + 0x000000000001d5c4 PROVIDE (__fini_array_start, .) + *(SORT(.fini_array.*) SORT(.dtors.*)) + *(.fini_array EXCLUDE_FILE(*crtend?.o *crtend.o *crtbegin?.o *crtbegin.o) .dtors) + 0x000000000001d5c4 PROVIDE (__fini_array_end, .) + +.ctors + *crtbegin.o(.ctors) + *crtbegin?.o(.ctors) + *(EXCLUDE_FILE(*crtend?.o *crtend.o) .ctors) + *(SORT(.ctors.*)) + *(.ctors) + +.dtors + *crtbegin.o(.dtors) + *crtbegin?.o(.dtors) + *(EXCLUDE_FILE(*crtend?.o *crtend.o) .dtors) + *(SORT(.dtors.*)) + *(.dtors) + +.jcr + *(.jcr) + +.data.rel.ro + *(.data.rel.ro.local* .gnu.linkonce.d.rel.ro.local.*) + *(.data.rel.ro .data.rel.ro.* .gnu.linkonce.d.rel.ro.*) + +.dynamic + *(.dynamic) + +.got + *(.got) + *(.igot) + +.got.plt 0x000000000001d5c4 0x0 + *(.got.plt) + *(.igot.plt) + .igot.plt 0x0000000000000000 0x0 boot/head.o + +.data 0x000000000001d5e0 0x3b21 + *(.data .data.* .gnu.linkonce.d.*) + .data 0x000000000001d5e0 0x0 boot/head.o + .data 0x000000000001d5e0 0x28 init/main.o + *fill* 0x000000000001d608 0x18 + .data 0x000000000001d620 0x1330 kernel/kernel.o + 0x000000000001d620 sys_call_table + 0x000000000001d790 NR_syscalls + 0x000000000001e7a0 current + 0x000000000001e7c0 task + 0x000000000001e8c0 stack_start + 0x000000000001e8c8 current_DOR + .data 0x000000000001e950 0x0 mm/mm.o + *fill* 0x000000000001e950 0x10 + .data 0x000000000001e960 0x60 fs/fs.o + 0x000000000001e964 start_buffer + .data 0x000000000001e9c0 0x0 kernel/blk_drv/blk_drv.a(ll_rw_blk.o) + .data 0x000000000001e9c0 0xcd kernel/blk_drv/blk_drv.a(floppy.o) + *fill* 0x000000000001ea8d 0x3 + .data 0x000000000001ea90 0x4 kernel/blk_drv/blk_drv.a(hd.o) + .data 0x000000000001ea94 0x0 kernel/blk_drv/blk_drv.a(ramdisk.o) + *fill* 0x000000000001ea94 0xc + .data 0x000000000001eaa0 0x2538 kernel/chr_drv/chr_drv.a(tty_io.o) + 0x000000000001eaa0 tty_table + 0x0000000000020fc0 table_list + .data 0x0000000000020fd8 0x1 kernel/chr_drv/chr_drv.a(console.o) + .data 0x0000000000020fd9 0x0 kernel/chr_drv/chr_drv.a(keyboard.2.o) + .data 0x0000000000020fd9 0x0 kernel/chr_drv/chr_drv.a(serial.o) + .data 0x0000000000020fd9 0x0 kernel/chr_drv/chr_drv.a(rs_io.o) + *fill* 0x0000000000020fd9 0x7 + .data 0x0000000000020fe0 0x20 kernel/chr_drv/chr_drv.a(tty_ioctl.o) + .data 0x0000000000021000 0x0 kernel/math/math.a(math_emulate.o) + .data 0x0000000000021000 0x101 lib/lib.a(ctype.o) + 0x0000000000021000 _ctype + .data 0x0000000000021101 0x0 lib/lib.a(_exit.o) + .data 0x0000000000021101 0x0 lib/lib.a(open.o) + .data 0x0000000000021101 0x0 lib/lib.a(close.o) + .data 0x0000000000021101 0x0 lib/lib.a(errno.o) + .data 0x0000000000021101 0x0 lib/lib.a(write.o) + .data 0x0000000000021101 0x0 lib/lib.a(dup.o) + .data 0x0000000000021101 0x0 lib/lib.a(setsid.o) + .data 0x0000000000021101 0x0 lib/lib.a(execve.o) + .data 0x0000000000021101 0x0 lib/lib.a(wait.o) + .data 0x0000000000021101 0x0 lib/lib.a(string.o) + +.data1 + *(.data1) + 0x0000000000021101 _edata = . + 0x0000000000021101 PROVIDE (edata, .) + 0x0000000000021101 . = . + 0x0000000000021101 __bss_start = . + +.bss 0x0000000000021120 0x44b0 + *(.dynbss) + *(.bss .bss.* .gnu.linkonce.b.*) + .bss 0x0000000000021120 0x0 boot/head.o + .bss 0x0000000000021120 0x40c init/main.o + *fill* 0x000000000002152c 0x14 + .bss 0x0000000000021540 0x760 kernel/kernel.o + 0x0000000000021540 jiffies + 0x0000000000021544 startup_time + 0x0000000000021548 last_task_used_math + 0x0000000000021884 last_pid + .bss 0x0000000000021ca0 0xf20 mm/mm.o + .bss 0x0000000000022bc0 0x710 fs/fs.o + 0x0000000000022bc0 inode_table + 0x00000000000232c0 nr_buffers + 0x00000000000232cc ROOT_DEV + *fill* 0x00000000000232d0 0x10 + .bss 0x00000000000232e0 0x58 kernel/blk_drv/blk_drv.a(ll_rw_blk.o) + 0x00000000000232e0 wait_for_request + 0x0000000000023300 blk_dev + .bss 0x0000000000023338 0x25 kernel/blk_drv/blk_drv.a(floppy.o) + 0x0000000000023338 do_floppy + 0x000000000002333c selected + 0x0000000000023340 wait_on_floppy_select + *fill* 0x000000000002335d 0x3 + .bss 0x0000000000023360 0xb0 kernel/blk_drv/blk_drv.a(hd.o) + 0x0000000000023360 do_hd + 0x0000000000023380 hd_info + .bss 0x0000000000023410 0x4 kernel/blk_drv/blk_drv.a(ramdisk.o) + 0x0000000000023410 rd_length + .bss 0x0000000000023414 0x4 kernel/chr_drv/chr_drv.a(tty_io.o) + *fill* 0x0000000000023418 0x8 + .bss 0x0000000000023420 0xac kernel/chr_drv/chr_drv.a(console.o) + 0x0000000000023420 beepcount + .bss 0x00000000000234cc 0x0 kernel/chr_drv/chr_drv.a(keyboard.2.o) + .bss 0x00000000000234cc 0x0 kernel/chr_drv/chr_drv.a(serial.o) + .bss 0x00000000000234cc 0x0 kernel/chr_drv/chr_drv.a(rs_io.o) + .bss 0x00000000000234cc 0x0 kernel/chr_drv/chr_drv.a(tty_ioctl.o) + .bss 0x00000000000234cc 0x0 kernel/math/math.a(math_emulate.o) + .bss 0x00000000000234cc 0x0 lib/lib.a(ctype.o) + .bss 0x00000000000234cc 0x0 lib/lib.a(_exit.o) + .bss 0x00000000000234cc 0x0 lib/lib.a(open.o) + .bss 0x00000000000234cc 0x0 lib/lib.a(close.o) + .bss 0x00000000000234cc 0x0 lib/lib.a(errno.o) + .bss 0x00000000000234cc 0x0 lib/lib.a(write.o) + .bss 0x00000000000234cc 0x0 lib/lib.a(dup.o) + .bss 0x00000000000234cc 0x0 lib/lib.a(setsid.o) + .bss 0x00000000000234cc 0x0 lib/lib.a(execve.o) + .bss 0x00000000000234cc 0x0 lib/lib.a(wait.o) + .bss 0x00000000000234cc 0x0 lib/lib.a(string.o) + *(COMMON) + *fill* 0x00000000000234cc 0x14 + COMMON 0x00000000000234e0 0x20 init/main.o + 0x00000000000234e0 drive_info + COMMON 0x0000000000023500 0x1000 kernel/kernel.o + 0x0000000000023500 user_stack + COMMON 0x0000000000024500 0xc40 fs/fs.o + 0x0000000000024500 hash_table + 0x00000000000249e0 super_block + 0x0000000000024d40 file_table + COMMON 0x0000000000025140 0x480 kernel/blk_drv/blk_drv.a(ll_rw_blk.o) + 0x0000000000025140 request + COMMON 0x00000000000255c0 0x4 kernel/blk_drv/blk_drv.a(ramdisk.o) + 0x00000000000255c0 rd_start + COMMON 0x00000000000255c4 0x1 lib/lib.a(ctype.o) + 0x00000000000255c4 _ctmp + *fill* 0x00000000000255c5 0x3 + COMMON 0x00000000000255c8 0x4 lib/lib.a(errno.o) + 0x00000000000255c8 errno + COMMON 0x00000000000255cc 0x4 lib/lib.a(string.o) + 0x00000000000255cc ___strtok + 0x00000000000255d0 . = ALIGN ((. != 0x0)?0x4:0x1) + 0x00000000000255d0 . = ALIGN (0x4) + 0x00000000000255d0 . = SEGMENT_START ("ldata-segment", .) + 0x00000000000255d0 . = ALIGN (0x4) + 0x00000000000255d0 _end = . + 0x00000000000255d0 PROVIDE (end, .) + +.stab + *(.stab) + +.stabstr + *(.stabstr) + +.stab.excl + *(.stab.excl) + +.stab.exclstr + *(.stab.exclstr) + +.stab.index + *(.stab.index) + +.stab.indexstr + *(.stab.indexstr) + +.comment 0x0000000000000000 0x29 + *(.comment) + .comment 0x0000000000000000 0x29 init/main.o + 0x2a (size before relaxing) + .comment 0x0000000000000000 0x222 kernel/kernel.o + .comment 0x0000000000000000 0x2a mm/mm.o + .comment 0x0000000000000000 0x2f4 fs/fs.o + .comment 0x0000000000000000 0x2a kernel/blk_drv/blk_drv.a(ll_rw_blk.o) + .comment 0x0000000000000000 0x2a kernel/blk_drv/blk_drv.a(floppy.o) + .comment 0x0000000000000000 0x2a kernel/blk_drv/blk_drv.a(hd.o) + .comment 0x0000000000000000 0x2a kernel/blk_drv/blk_drv.a(ramdisk.o) + .comment 0x0000000000000000 0x2a kernel/chr_drv/chr_drv.a(tty_io.o) + .comment 0x0000000000000000 0x2a kernel/chr_drv/chr_drv.a(console.o) + .comment 0x0000000000000000 0x2a kernel/chr_drv/chr_drv.a(serial.o) + .comment 0x0000000000000000 0x2a kernel/chr_drv/chr_drv.a(tty_ioctl.o) + .comment 0x0000000000000000 0x2a kernel/math/math.a(math_emulate.o) + .comment 0x0000000000000000 0x2a lib/lib.a(ctype.o) + .comment 0x0000000000000000 0x2a lib/lib.a(_exit.o) + .comment 0x0000000000000000 0x2a lib/lib.a(open.o) + .comment 0x0000000000000000 0x2a lib/lib.a(close.o) + .comment 0x0000000000000000 0x2a lib/lib.a(errno.o) + .comment 0x0000000000000000 0x2a lib/lib.a(write.o) + .comment 0x0000000000000000 0x2a lib/lib.a(dup.o) + .comment 0x0000000000000000 0x2a lib/lib.a(setsid.o) + .comment 0x0000000000000000 0x2a lib/lib.a(execve.o) + .comment 0x0000000000000000 0x2a lib/lib.a(wait.o) + .comment 0x0000000000000000 0x2a lib/lib.a(string.o) + +.debug + *(.debug) + +.line + *(.line) + +.debug_srcinfo + *(.debug_srcinfo) + +.debug_sfnames + *(.debug_sfnames) + +.debug_aranges 0x0000000000000000 0x688 + *(.debug_aranges) + .debug_aranges + 0x0000000000000000 0x20 init/main.o + .debug_aranges + 0x0000000000000020 0x1a0 kernel/kernel.o + .debug_aranges + 0x00000000000001c0 0x20 mm/mm.o + .debug_aranges + 0x00000000000001e0 0x238 fs/fs.o + .debug_aranges + 0x0000000000000418 0x20 kernel/blk_drv/blk_drv.a(ll_rw_blk.o) + .debug_aranges + 0x0000000000000438 0x20 kernel/blk_drv/blk_drv.a(floppy.o) + .debug_aranges + 0x0000000000000458 0x20 kernel/blk_drv/blk_drv.a(hd.o) + .debug_aranges + 0x0000000000000478 0x20 kernel/blk_drv/blk_drv.a(ramdisk.o) + .debug_aranges + 0x0000000000000498 0x20 kernel/chr_drv/chr_drv.a(tty_io.o) + .debug_aranges + 0x00000000000004b8 0x20 kernel/chr_drv/chr_drv.a(console.o) + .debug_aranges + 0x00000000000004d8 0x20 kernel/chr_drv/chr_drv.a(serial.o) + .debug_aranges + 0x00000000000004f8 0x20 kernel/chr_drv/chr_drv.a(tty_ioctl.o) + .debug_aranges + 0x0000000000000518 0x20 kernel/math/math.a(math_emulate.o) + .debug_aranges + 0x0000000000000538 0x18 lib/lib.a(ctype.o) + .debug_aranges + 0x0000000000000550 0x20 lib/lib.a(_exit.o) + .debug_aranges + 0x0000000000000570 0x20 lib/lib.a(open.o) + .debug_aranges + 0x0000000000000590 0x20 lib/lib.a(close.o) + .debug_aranges + 0x00000000000005b0 0x18 lib/lib.a(errno.o) + .debug_aranges + 0x00000000000005c8 0x20 lib/lib.a(write.o) + .debug_aranges + 0x00000000000005e8 0x20 lib/lib.a(dup.o) + .debug_aranges + 0x0000000000000608 0x20 lib/lib.a(setsid.o) + .debug_aranges + 0x0000000000000628 0x20 lib/lib.a(execve.o) + .debug_aranges + 0x0000000000000648 0x20 lib/lib.a(wait.o) + .debug_aranges + 0x0000000000000668 0x20 lib/lib.a(string.o) + +.debug_pubnames + *(.debug_pubnames) + +.debug_info 0x0000000000000000 0x19187 + *(.debug_info .gnu.linkonce.wi.*) + .debug_info 0x0000000000000000 0xb73 init/main.o + .debug_info 0x0000000000000b73 0x6a7d kernel/kernel.o + .debug_info 0x00000000000075f0 0xba8 mm/mm.o + .debug_info 0x0000000000008198 0xa290 fs/fs.o + .debug_info 0x0000000000012428 0x932 kernel/blk_drv/blk_drv.a(ll_rw_blk.o) + .debug_info 0x0000000000012d5a 0xc9f kernel/blk_drv/blk_drv.a(floppy.o) + .debug_info 0x00000000000139f9 0xd5f kernel/blk_drv/blk_drv.a(hd.o) + .debug_info 0x0000000000014758 0xad5 kernel/blk_drv/blk_drv.a(ramdisk.o) + .debug_info 0x000000000001522d 0xacd kernel/chr_drv/chr_drv.a(tty_io.o) + .debug_info 0x0000000000015cfa 0xdb0 kernel/chr_drv/chr_drv.a(console.o) + .debug_info 0x0000000000016aaa 0x85c kernel/chr_drv/chr_drv.a(serial.o) + .debug_info 0x0000000000017306 0xb47 kernel/chr_drv/chr_drv.a(tty_ioctl.o) + .debug_info 0x0000000000017e4d 0x7b5 kernel/math/math.a(math_emulate.o) + .debug_info 0x0000000000018602 0x66 lib/lib.a(ctype.o) + .debug_info 0x0000000000018668 0x77 lib/lib.a(_exit.o) + .debug_info 0x00000000000186df 0xd0 lib/lib.a(open.o) + .debug_info 0x00000000000187af 0x97 lib/lib.a(close.o) + .debug_info 0x0000000000018846 0x36 lib/lib.a(errno.o) + .debug_info 0x000000000001887c 0xc9 lib/lib.a(write.o) + .debug_info 0x0000000000018945 0x97 lib/lib.a(dup.o) + .debug_info 0x00000000000189dc 0x95 lib/lib.a(setsid.o) + .debug_info 0x0000000000018a71 0xcb lib/lib.a(execve.o) + .debug_info 0x0000000000018b3c 0xed lib/lib.a(wait.o) + .debug_info 0x0000000000018c29 0x55e lib/lib.a(string.o) + +.debug_abbrev 0x0000000000000000 0x4901 + *(.debug_abbrev) + .debug_abbrev 0x0000000000000000 0x237 init/main.o + .debug_abbrev 0x0000000000000237 0x1447 kernel/kernel.o + .debug_abbrev 0x000000000000167e 0x20b mm/mm.o + .debug_abbrev 0x0000000000001889 0x19f1 fs/fs.o + .debug_abbrev 0x000000000000327a 0x169 kernel/blk_drv/blk_drv.a(ll_rw_blk.o) + .debug_abbrev 0x00000000000033e3 0x27d kernel/blk_drv/blk_drv.a(floppy.o) + .debug_abbrev 0x0000000000003660 0x23c kernel/blk_drv/blk_drv.a(hd.o) + .debug_abbrev 0x000000000000389c 0x1a8 kernel/blk_drv/blk_drv.a(ramdisk.o) + .debug_abbrev 0x0000000000003a44 0x279 kernel/chr_drv/chr_drv.a(tty_io.o) + .debug_abbrev 0x0000000000003cbd 0x26b kernel/chr_drv/chr_drv.a(console.o) + .debug_abbrev 0x0000000000003f28 0x175 kernel/chr_drv/chr_drv.a(serial.o) + .debug_abbrev 0x000000000000409d 0x18d kernel/chr_drv/chr_drv.a(tty_ioctl.o) + .debug_abbrev 0x000000000000422a 0x163 kernel/math/math.a(math_emulate.o) + .debug_abbrev 0x000000000000438d 0x3e lib/lib.a(ctype.o) + .debug_abbrev 0x00000000000043cb 0x51 lib/lib.a(_exit.o) + .debug_abbrev 0x000000000000441c 0x97 lib/lib.a(open.o) + .debug_abbrev 0x00000000000044b3 0x75 lib/lib.a(close.o) + .debug_abbrev 0x0000000000004528 0x2c lib/lib.a(errno.o) + .debug_abbrev 0x0000000000004554 0xa1 lib/lib.a(write.o) + .debug_abbrev 0x00000000000045f5 0x75 lib/lib.a(dup.o) + .debug_abbrev 0x000000000000466a 0x73 lib/lib.a(setsid.o) + .debug_abbrev 0x00000000000046dd 0x85 lib/lib.a(execve.o) + .debug_abbrev 0x0000000000004762 0xb6 lib/lib.a(wait.o) + .debug_abbrev 0x0000000000004818 0xe9 lib/lib.a(string.o) + +.debug_line 0x0000000000000000 0x4bde + *(.debug_line .debug_line.* .debug_line_end) + .debug_line 0x0000000000000000 0x1e5 init/main.o + .debug_line 0x00000000000001e5 0x144d kernel/kernel.o + .debug_line 0x0000000000001632 0x2b4 mm/mm.o + .debug_line 0x00000000000018e6 0x1c50 fs/fs.o + .debug_line 0x0000000000003536 0x197 kernel/blk_drv/blk_drv.a(ll_rw_blk.o) + .debug_line 0x00000000000036cd 0x24c kernel/blk_drv/blk_drv.a(floppy.o) + .debug_line 0x0000000000003919 0x2bf kernel/blk_drv/blk_drv.a(hd.o) + .debug_line 0x0000000000003bd8 0x160 kernel/blk_drv/blk_drv.a(ramdisk.o) + .debug_line 0x0000000000003d38 0x33b kernel/chr_drv/chr_drv.a(tty_io.o) + .debug_line 0x0000000000004073 0x3ab kernel/chr_drv/chr_drv.a(console.o) + .debug_line 0x000000000000441e 0xd9 kernel/chr_drv/chr_drv.a(serial.o) + .debug_line 0x00000000000044f7 0x1db kernel/chr_drv/chr_drv.a(tty_ioctl.o) + .debug_line 0x00000000000046d2 0xe1 kernel/math/math.a(math_emulate.o) + .debug_line 0x00000000000047b3 0x28 lib/lib.a(ctype.o) + .debug_line 0x00000000000047db 0x39 lib/lib.a(_exit.o) + .debug_line 0x0000000000004814 0x62 lib/lib.a(open.o) + .debug_line 0x0000000000004876 0x5c lib/lib.a(close.o) + .debug_line 0x00000000000048d2 0x28 lib/lib.a(errno.o) + .debug_line 0x00000000000048fa 0x76 lib/lib.a(write.o) + .debug_line 0x0000000000004970 0x5a lib/lib.a(dup.o) + .debug_line 0x00000000000049ca 0x77 lib/lib.a(setsid.o) + .debug_line 0x0000000000004a41 0x5d lib/lib.a(execve.o) + .debug_line 0x0000000000004a9e 0x7a lib/lib.a(wait.o) + .debug_line 0x0000000000004b18 0xc6 lib/lib.a(string.o) + +.debug_frame + *(.debug_frame) + +.debug_str 0x0000000000000000 0x21bc + *(.debug_str) + .debug_str 0x0000000000000000 0x3bd init/main.o + 0x460 (size before relaxing) + .debug_str 0x00000000000003bd 0xb28 kernel/kernel.o + 0x30bd (size before relaxing) + .debug_str 0x0000000000000ee5 0x181 mm/mm.o + 0x4e8 (size before relaxing) + .debug_str 0x0000000000001066 0x7a3 fs/fs.o + 0x49a7 (size before relaxing) + .debug_str 0x0000000000001809 0xf0 kernel/blk_drv/blk_drv.a(ll_rw_blk.o) + 0x491 (size before relaxing) + .debug_str 0x00000000000018f9 0x1cf kernel/blk_drv/blk_drv.a(floppy.o) + 0x673 (size before relaxing) + .debug_str 0x0000000000001ac8 0x15e kernel/blk_drv/blk_drv.a(hd.o) + 0x5e8 (size before relaxing) + .debug_str 0x0000000000001c26 0x43 kernel/blk_drv/blk_drv.a(ramdisk.o) + 0x58a (size before relaxing) + .debug_str 0x0000000000001c69 0xfb kernel/chr_drv/chr_drv.a(tty_io.o) + 0x4e3 (size before relaxing) + .debug_str 0x0000000000001d64 0x1b9 kernel/chr_drv/chr_drv.a(console.o) + 0x5b7 (size before relaxing) + .debug_str 0x0000000000001f1d 0x1a kernel/chr_drv/chr_drv.a(serial.o) + 0x3fc (size before relaxing) + .debug_str 0x0000000000001f37 0x8b kernel/chr_drv/chr_drv.a(tty_ioctl.o) + 0x4a7 (size before relaxing) + .debug_str 0x0000000000001fc2 0x70 kernel/math/math.a(math_emulate.o) + 0x392 (size before relaxing) + .debug_str 0x0000000000002032 0x8d lib/lib.a(ctype.o) + 0xb6 (size before relaxing) + .debug_str 0x00000000000020bf 0x31 lib/lib.a(_exit.o) + 0xde (size before relaxing) + .debug_str 0x0000000000000000 0x31 lib/lib.a(open.o) + 0xee (size before relaxing) + .debug_str 0x00000000000020f0 0x8 lib/lib.a(close.o) + 0xe0 (size before relaxing) + .debug_str 0x00000000000020f8 0x8 lib/lib.a(errno.o) + 0x93 (size before relaxing) + .debug_str 0x0000000000000000 0x8 lib/lib.a(write.o) + 0xec (size before relaxing) + .debug_str 0x0000000000002100 0x6 lib/lib.a(dup.o) + 0xd8 (size before relaxing) + .debug_str 0x0000000000002106 0x9 lib/lib.a(setsid.o) + 0xe8 (size before relaxing) + .debug_str 0x000000000000210f 0x9 lib/lib.a(execve.o) + 0xf1 (size before relaxing) + .debug_str 0x0000000000002118 0x11 lib/lib.a(wait.o) + 0xfe (size before relaxing) + .debug_str 0x0000000000002129 0x93 lib/lib.a(string.o) + 0x147 (size before relaxing) + +.debug_loc + *(.debug_loc) + +.debug_macinfo + *(.debug_macinfo) + +.debug_weaknames + *(.debug_weaknames) + +.debug_funcnames + *(.debug_funcnames) + +.debug_typenames + *(.debug_typenames) + +.debug_varnames + *(.debug_varnames) + +.debug_pubtypes + *(.debug_pubtypes) + +.debug_ranges 0x0000000000000000 0x18 + *(.debug_ranges) + .debug_ranges 0x0000000000000000 0x18 init/main.o + +.debug_macro + *(.debug_macro) + +.gnu.attributes + *(.gnu.attributes) + +/DISCARD/ + *(.note.GNU-stack) + *(.gnu_debuglink) + *(.gnu.lto_*) +OUTPUT(tools/system elf32-i386) diff --git a/110_master/110/os/os/linux/boot/bootsect b/110_master/110/os/os/linux/boot/bootsect new file mode 100644 index 0000000000000000000000000000000000000000..4fbb8f823afe23687f1887d48deeb19fdcf83049 GIT binary patch literal 544 zcmZQ%7GP0e00JfufdrZ$>>UT#`)=%Dn9z4%Cj+DAH_iW_m%fre~uHUSwNXN9*i=ymehGJ;Ln!ff#WtiVnQ zhTZH8d+ix_Fbba)*ufysci@E)!;7N~dJF$B+A=VditBaD0d;UNHUH)>;o2bsq=ibD zUjNfu{D<)s1B1c@RhzFW-(_8 zyWs)N8wX!-zAym_G6SXbtl4ZCONDkYGHA2SVkl+#&o+l)@hk?z1B+)cfHa*h-qdq| z733tt+pm`g1P2Cni_Kx^=9|Ib*m1R6Y!*YuwM`6-j~E!Y0DW7;8WkBGaTw@dps&vg zgE+6x1nv67yn*3e)L{k&UM`>f#FWgubcN!|;*!){1wB1IUM^lPq<|j0Og84wRRH+h BgWdoD literal 0 HcmV?d00001 diff --git a/110_master/110/os/os/linux/boot/bootsect.o b/110_master/110/os/os/linux/boot/bootsect.o new file mode 100644 index 0000000000000000000000000000000000000000..e35422ec017a165928bfcbec5f9f0363b4a9e75c GIT binary patch literal 923 zcmYjPe@GKy7=FH+PB$=@gOrLGSb;@HGl?KZQ#V8qHK&qRjLn^EOg*`~_2a*bAQEj2 z`bR7R8DjO1Ax5YD;D!W64T2~X>5mFT9P~#*1c~eYW`BB3fn$y+MeVjqc)FB7D{5ZwQc zlnx;W9UDX^enV$llvLXoyfYO9Z}$=84ic;$V`O7tS=LmkPeZ`p+0`EKHzCjy2sHQl zw}lpeD-uHysXwTY5sDOw1Y=|-4_TXAn>%^rd%=iw84Yc11;O9ydW>fq~$ltjP-a7_y>584mLI>~!sq4M`D5Ly@qm@(>AWA%vwU zr%{<_+X|nde;^cvTBwf1Bxp*gFV1T;>8i$^g?NcKSG5q0@!xcE+`au;IbOSyoY+a~ z{!PR`f4ixx+SO^8CCMcNsiZj%R`aVSzcIBg=v7dW8hevmN}95U=#^i zr)no|09j{lb(WIStn(?vkzMq|I|{AlEXVU%$9xr@m*6E`j|&EKW*r6`Npr0hYp)?r zZZZ#$s1!#JP?cts3OD|gYj$Hl#R^TxZHehkwhp*b#dJ@BG4oNrJhA0o88bcbDr`}l zq`HQqR(%{jBbm%s8(UUwT8Z1NS<0;0*6J{lvGC1C@wAnkO^FJFf$S6TC5rM^{XXi` zL>k>@nq232gLmrem|4t+bg$&5+XH7iM)#1fVRRQc{Pnj!5uJed*5_GV{{}WkC!rMg z_MAVrNM}JOl67*Dd*89})A9sAdKZB*dkfv2*ih7^UQ;z`&?SnZugqR%-#z8CTDl%r F<1c(7E-?TA literal 0 HcmV?d00001 diff --git a/110_master/110/os/os/linux/boot/bootsect.s b/110_master/110/os/os/linux/boot/bootsect.s new file mode 100644 index 0000000..711f103 --- /dev/null +++ b/110_master/110/os/os/linux/boot/bootsect.s @@ -0,0 +1,260 @@ +! +! SYS_SIZE is the number of clicks (16 bytes) to be loaded. +! 0x3000 is 0x30000 bytes = 196kB, more than enough for current +! versions of linux +! +SYSSIZE = 0x3000 +! +! bootsect.s (C) 1991 Linus Torvalds +! +! bootsect.s is loaded at 0x7c00 by the bios-startup routines, and moves +! iself out of the way to address 0x90000, and jumps there. +! +! It then loads 'setup' directly after itself (0x90200), and the system +! at 0x10000, using BIOS interrupts. +! +! NOTE! currently system is at most 8*65536 bytes long. This should be no +! problem, even in the future. I want to keep it simple. This 512 kB +! kernel size should be enough, especially as this doesn't contain the +! buffer cache as in minix +! +! The loader has been made as simple as possible, and continuos +! read errors will result in a unbreakable loop. Reboot by hand. It +! loads pretty fast by getting whole sectors at a time whenever possible. + +.globl begtext, begdata, begbss, endtext, enddata, endbss +.text +begtext: +.data +begdata: +.bss +begbss: +.text + +SETUPLEN = 4 ! nr of setup-sectors +BOOTSEG = 0x07c0 ! original address of boot-sector +INITSEG = 0x9000 ! we move boot here - out of the way +SETUPSEG = 0x9020 ! setup starts here +SYSSEG = 0x1000 ! system loaded at 0x10000 (65536). +ENDSEG = SYSSEG + SYSSIZE ! where to stop loading + +! ROOT_DEV: 0x000 - same type of floppy as boot. +! 0x301 - first partition on first drive etc +ROOT_DEV = 0x306 + +entry start +start: + mov ax,#BOOTSEG + mov ds,ax + mov ax,#INITSEG + mov es,ax + mov cx,#256 + sub si,si + sub di,di + rep + movw + jmpi go,INITSEG +go: mov ax,cs + mov ds,ax + mov es,ax +! put stack at 0x9ff00. + mov ss,ax + mov sp,#0xFF00 ! arbitrary value >>512 + +! load the setup-sectors directly after the bootblock. +! Note that 'es' is already set up. + +load_setup: + mov dx,#0x0000 ! drive 0, head 0 + mov cx,#0x0002 ! sector 2, track 0 + mov bx,#0x0200 ! address = 512, in INITSEG + mov ax,#0x0200+SETUPLEN ! service 2, nr of sectors + int 0x13 ! read it + jnc ok_load_setup ! ok - continue + mov dx,#0x0000 + mov ax,#0x0000 ! reset the diskette + int 0x13 + j load_setup + +ok_load_setup: + +! Get disk drive parameters, specifically nr of sectors/track + + mov dl,#0x00 + mov ax,#0x0800 ! AH=8 is get drive parameters + int 0x13 + mov ch,#0x00 + seg cs + mov sectors,cx + mov ax,#INITSEG + mov es,ax + +! Print some inane message + + mov ah,#0x03 ! read cursor pos + xor bh,bh + int 0x10 + + mov cx,#24 + mov bx,#0x0007 ! page 0, attribute 7 (normal) + mov bp,#msg1 + mov ax,#0x1301 ! write string, move cursor + int 0x10 + +! ok, we've written the message, now +! we want to load the system (at 0x10000) + + mov ax,#SYSSEG + mov es,ax ! segment of 0x010000 + call read_it + call kill_motor + +! After that we check which root-device to use. If the device is +! defined (!= 0), nothing is done and the given device is used. +! Otherwise, either /dev/PS0 (2,28) or /dev/at0 (2,8), depending +! on the number of sectors that the BIOS reports currently. + + seg cs + mov ax,root_dev + cmp ax,#0 + jne root_defined + seg cs + mov bx,sectors + mov ax,#0x0208 ! /dev/ps0 - 1.2Mb + cmp bx,#15 + je root_defined + mov ax,#0x021c ! /dev/PS0 - 1.44Mb + cmp bx,#18 + je root_defined +undef_root: + jmp undef_root +root_defined: + seg cs + mov root_dev,ax + +! after that (everyting loaded), we jump to +! the setup-routine loaded directly after +! the bootblock: + + jmpi 0,SETUPSEG + +! This routine loads the system at address 0x10000, making sure +! no 64kB boundaries are crossed. We try to load it as fast as +! possible, loading whole tracks whenever we can. +! +! in: es - starting address segment (normally 0x1000) +! +sread: .word 1+SETUPLEN ! sectors read of current track +head: .word 0 ! current head +track: .word 0 ! current track + +read_it: + mov ax,es + test ax,#0x0fff +die: jne die ! es must be at 64kB boundary + xor bx,bx ! bx is starting address within segment +rp_read: + mov ax,es + cmp ax,#ENDSEG ! have we loaded all yet? + jb ok1_read + ret +ok1_read: + seg cs + mov ax,sectors + sub ax,sread + mov cx,ax + shl cx,#9 + add cx,bx + jnc ok2_read + je ok2_read + xor ax,ax + sub ax,bx + shr ax,#9 +ok2_read: + call read_track + mov cx,ax + add ax,sread + seg cs + cmp ax,sectors + jne ok3_read + mov ax,#1 + sub ax,head + jne ok4_read + inc track +ok4_read: + mov head,ax + xor ax,ax +ok3_read: + mov sread,ax + shl cx,#9 + add bx,cx + jnc rp_read + mov ax,es + add ax,#0x1000 + mov es,ax + xor bx,bx + jmp rp_read + +read_track: + push ax + push bx + push cx + push dx + mov dx,track + mov cx,sread + inc cx + mov ch,dl + mov dx,head + mov dh,dl + mov dl,#0 + and dx,#0x0100 + mov ah,#2 + int 0x13 + jc bad_rt + pop dx + pop cx + pop bx + pop ax + ret +bad_rt: mov ax,#0 + mov dx,#0 + int 0x13 + pop dx + pop cx + pop bx + pop ax + jmp read_track + +/* + * This procedure turns off the floppy drive motor, so + * that we enter the kernel in a known state, and + * don't have to worry about it later. + */ +kill_motor: + push dx + mov dx,#0x3f2 + mov al,#0 + outb + pop dx + ret + +sectors: + .word 0 + +msg1: + .byte 13,10 + .ascii "Loading system ..." + .byte 13,10,13,10 + +.org 508 +root_dev: + .word ROOT_DEV +boot_flag: + .word 0xAA55 + +.text +endtext: +.data +enddata: +.bss +endbss: diff --git a/110_master/110/os/os/linux/boot/head.o b/110_master/110/os/os/linux/boot/head.o new file mode 100644 index 0000000000000000000000000000000000000000..a4c55649c84336692e2f017e7d3b9dc5fd3082ba GIT binary patch literal 27012 zcmeI5O=ule7>2)-rn#v$OwS%uL!8 z6a%qn7P*Sc3jRisn&iB4& z&iUrdGdG*FIOn4m54>cIk-Qk$Ah(^!ke}VzorWRlmW`=8*Nf1++Dw|)n=8(lL2X<) zq}4H0_qtn3hEHg(eMrzN@gL4WGWd|l-26`+&h}(Q)Bb+)4UucVe)-Gw{Sx<}!~D%I z+*?{aEZ2TpTI?Ts6R8Drs4QHmT#)ACbDHqHPI#fPaIkZJx%=grzZ~<#59qk$nEtaG zwGRskkN^pg011!)36KB@kN^pg011!)36KB@kN^pg011!)36KB@kN^pg011!)36KB@ zkN^pg011!)36KB@kN^pg011!)36KB@kN^pg011!)36KB@kN^pg011!)36KB@kN^pg z011!)36KB@kN^pg011!)36KB@{I3YSFZx$|7#nQXbmBLjzwysojfuwek;Xv15&K~{ z6T}bn$jEE2Z|!ovS+gN%tq)^XR$HyssPk=M+o88dFJpht^U^0$N=mKOKTj>|UZ7II z4x`H(J5>#+>Q=Qw)n--0B9~TQ#eSfLn=SeK)YI5gR6e{_N}TOiv2kb*y3Aqg&{f?# zRHRiv)sBntlbK~r0wh2JBtQZrur3L-9K81NMAG<0vMw3$rAdGUNPq-LVBHWXMn|V& zZ%m3&9A>eWtI(e;#{O(9#j+QBQXGq-`^K^jJ@x#QE<0i`Vp6sSL02)fJdSHqsHM(blD3iP(3Pv78q7&_8 zM*5-k_?fI2(eEHwXv&I_5`-Qfll%P;pXV0YUx3zAW3po86$m{&CikN%^o7%6cM$*qTtc_Ysx=5yrWmz#Y0Wq@1&%*1%SXPY8K_u4qV*JPI(}(IbjC`7P zOl$R@sT#=|)qkDIv{wK99Ukv?m%n(Im&lK20=Hg{t*Sze*ZlDbcXsa{@hVv2a|5sH zyZGms^dqTP8`GihV(m}Dz>RbuF1PGQ!HL`fm@lJ4uYeu7y6z=u@~z6cI{M&Nu>=k<<%P!gh--%^>djmB1Ic# zG~x&OiAMa0zq0GKeRF1UbBAE`q28r)_-9Aob|_S NJgpJWKc}%z4Mb on a 4Mb machine). + * + * NOTE! Although all physical memory should be identity + * mapped by this routine, only the kernel page functions + * use the >1Mb addresses directly. All "normal" functions + * use just the lower 1Mb, or the local data space, which + * will be mapped to some other place - mm keeps track of + * that. + * + * For those with more memory than 16 Mb - tough luck. I've + * not got it, why should you :-) The source is here. Change + * it. (Seriously - it shouldn't be too difficult. Mostly + * change some constants etc. I left it at 16Mb, as my machine + * even cannot be extended past that (ok, but it was cheap :-) + * I've tried to show which constants to change by having + * some kind of marker at them (search for "16Mb"), but I + * won't guarantee that's all :-( ) + */ +.align 4 +setup_paging: + movl $1024*5,%ecx /* 5 pages - pg_dir+4 page tables */ + xorl %eax,%eax + xorl %edi,%edi /* pg_dir is at 0x000 */ + cld;rep;stosl + movl $pg0+7,pg_dir /* set present bit/user r/w */ + movl $pg1+7,pg_dir+4 /* --------- " " --------- */ + movl $pg2+7,pg_dir+8 /* --------- " " --------- */ + movl $pg3+7,pg_dir+12 /* --------- " " --------- */ + movl $pg3+4092,%edi + movl $0xfff007,%eax /* 16Mb - 4096 + 7 (r/w user,p) */ + std +1: stosl /* fill pages backwards - more efficient :-) */ + subl $0x1000,%eax + jge 1b + xorl %eax,%eax /* pg_dir is at 0x0000 */ + movl %eax,%cr3 /* cr3 - page directory start */ + movl %cr0,%eax + orl $0x80000000,%eax + movl %eax,%cr0 /* set paging (PG) bit */ + cld /* by wyj */ + ret /* this also flushes prefetch-queue */ + +.align 4 +.word 0 +idt_descr: + .word 256*8-1 # idt contains 256 entries + .long idt +.align 4 +.word 0 +gdt_descr: + .word 256*8-1 # so does gdt (not that that's any + .long gdt # magic number, but it works for me :^) + + .align 8 +idt: .fill 256,8,0 # idt is uninitialized + +gdt: .quad 0x0000000000000000 /* NULL descriptor */ + .quad 0x00c09a0000000fff /* 16Mb */ + .quad 0x00c0920000000fff /* 16Mb */ + .quad 0x0000000000000000 /* TEMPORARY - don't use */ + .fill 252,8,0 /* space for LDT's and TSS's etc */ diff --git a/110_master/110/os/os/linux/boot/setup b/110_master/110/os/os/linux/boot/setup new file mode 100644 index 0000000000000000000000000000000000000000..0e70f4846819f560fb2e22a8eb1e7186c7956ab0 GIT binary patch literal 344 zcmZQ%7GP0eU|_Id1QJNVq7lN`!7!ok#ujFS|7Qg{#TXd2bet7k%*3#TAIOzsVOY$@ zutjLIz*&LC91NXuTnwFjJPbP+82WA;HDh4}X+5yNfnlcr!{;SXQ3*l_<@!izwL4T8@UUNgLAc(wpUZcuop2&OfjEda<7{%Xg;=gL$t<~Tutazx3hbYqSrLZVca%ibUp9b?$HkVw;4TnF?Rz@46w`UObliF2LrIX1l zD$%Xa$Sgt^u2&7@|GQ@O1M(N{a&->*XRca94ek$5^Qt@KbHx4WGu-r2)9WkibQgy407%ZoGynhq literal 0 HcmV?d00001 diff --git a/110_master/110/os/os/linux/boot/setup.s b/110_master/110/os/os/linux/boot/setup.s new file mode 100644 index 0000000..2329d00 --- /dev/null +++ b/110_master/110/os/os/linux/boot/setup.s @@ -0,0 +1,231 @@ +! +! setup.s (C) 1991 Linus Torvalds +! +! setup.s is responsible for getting the system data from the BIOS, +! and putting them into the appropriate places in system memory. +! both setup.s and system has been loaded by the bootblock. +! +! This code asks the bios for memory/disk/other parameters, and +! puts them in a "safe" place: 0x90000-0x901FF, ie where the +! boot-block used to be. It is then up to the protected mode +! system to read them from there before the area is overwritten +! for buffer-blocks. +! + +! NOTE! These had better be the same as in bootsect.s! + +INITSEG = 0x9000 ! we move boot here - out of the way +SYSSEG = 0x1000 ! system loaded at 0x10000 (65536). +SETUPSEG = 0x9020 ! this is the current segment + +.globl begtext, begdata, begbss, endtext, enddata, endbss +.text +begtext: +.data +begdata: +.bss +begbss: +.text + +entry start +start: + +! ok, the read went well so we get current cursor position and save it for +! posterity. + + mov ax,#INITSEG ! this is done in bootsect already, but... + mov ds,ax + mov ah,#0x03 ! read cursor pos + xor bh,bh + int 0x10 ! save it in known place, con_init fetches + mov [0],dx ! it from 0x90000. + +! Get memory size (extended mem, kB) + + mov ah,#0x88 + int 0x15 + mov [2],ax + +! Get video-card data: + + mov ah,#0x0f + int 0x10 + mov [4],bx ! bh = display page + mov [6],ax ! al = video mode, ah = window width + +! check for EGA/VGA and some config parameters + + mov ah,#0x12 + mov bl,#0x10 + int 0x10 + mov [8],ax + mov [10],bx + mov [12],cx + +! Get hd0 data + + mov ax,#0x0000 + mov ds,ax + lds si,[4*0x41] + mov ax,#INITSEG + mov es,ax + mov di,#0x0080 + mov cx,#0x10 + rep + movsb + +! Get hd1 data + + mov ax,#0x0000 + mov ds,ax + lds si,[4*0x46] + mov ax,#INITSEG + mov es,ax + mov di,#0x0090 + mov cx,#0x10 + rep + movsb + +! Check that there IS a hd1 :-) + + mov ax,#0x01500 + mov dl,#0x81 + int 0x13 + jc no_disk1 + cmp ah,#3 + je is_disk1 +no_disk1: + mov ax,#INITSEG + mov es,ax + mov di,#0x0090 + mov cx,#0x10 + mov ax,#0x00 + rep + stosb +is_disk1: + +! now we want to move to protected mode ... + + cli ! no interrupts allowed ! + +! first we move the system to it's rightful place + + mov ax,#0x0000 + cld ! 'direction'=0, movs moves forward +do_move: + mov es,ax ! destination segment + add ax,#0x1000 + cmp ax,#0x9000 + jz end_move + mov ds,ax ! source segment + sub di,di + sub si,si + mov cx,#0x8000 + rep + movsw + jmp do_move + +! then we load the segment descriptors + +end_move: + mov ax,#SETUPSEG ! right, forgot this at first. didn't work :-) + mov ds,ax + lidt idt_48 ! load idt with 0,0 + lgdt gdt_48 ! load gdt with whatever appropriate + +! that was painless, now we enable A20 + + call empty_8042 + mov al,#0xD1 ! command write + out #0x64,al + call empty_8042 + mov al,#0xDF ! A20 on + out #0x60,al + call empty_8042 + +! well, that went ok, I hope. Now we have to reprogram the interrupts :-( +! we put them right after the intel-reserved hardware interrupts, at +! int 0x20-0x2F. There they won't mess up anything. Sadly IBM really +! messed this up with the original PC, and they haven't been able to +! rectify it afterwards. Thus the bios puts interrupts at 0x08-0x0f, +! which is used for the internal hardware interrupts as well. We just +! have to reprogram the 8259's, and it isn't fun. + + mov al,#0x11 ! initialization sequence + out #0x20,al ! send it to 8259A-1 + .word 0x00eb,0x00eb ! jmp $+2, jmp $+2 + out #0xA0,al ! and to 8259A-2 + .word 0x00eb,0x00eb + mov al,#0x20 ! start of hardware int's (0x20) + out #0x21,al + .word 0x00eb,0x00eb + mov al,#0x28 ! start of hardware int's 2 (0x28) + out #0xA1,al + .word 0x00eb,0x00eb + mov al,#0x04 ! 8259-1 is master + out #0x21,al + .word 0x00eb,0x00eb + mov al,#0x02 ! 8259-2 is slave + out #0xA1,al + .word 0x00eb,0x00eb + mov al,#0x01 ! 8086 mode for both + out #0x21,al + .word 0x00eb,0x00eb + out #0xA1,al + .word 0x00eb,0x00eb + mov al,#0xFF ! mask off all interrupts for now + out #0x21,al + .word 0x00eb,0x00eb + out #0xA1,al + +! well, that certainly wasn't fun :-(. Hopefully it works, and we don't +! need no steenking BIOS anyway (except for the initial loading :-). +! The BIOS-routine wants lots of unnecessary data, and it's less +! "interesting" anyway. This is how REAL programmers do it. +! +! Well, now's the time to actually move into protected mode. To make +! things as simple as possible, we do no register set-up or anything, +! we let the gnu-compiled 32-bit programs do that. We just jump to +! absolute address 0x00000, in 32-bit protected mode. + + mov ax,#0x0001 ! protected mode (PE) bit + lmsw ax ! This is it! + jmpi 0,8 ! jmp offset 0 of segment 8 (cs) + +! This routine checks that the keyboard command queue is empty +! No timeout is used - if this hangs there is something wrong with +! the machine, and we probably couldn't proceed anyway. +empty_8042: + .word 0x00eb,0x00eb + in al,#0x64 ! 8042 status port + test al,#2 ! is input buffer full? + jnz empty_8042 ! yes - loop + ret + +gdt: + .word 0,0,0,0 ! dummy + + .word 0x07FF ! 8Mb - limit=2047 (2048*4096=8Mb) + .word 0x0000 ! base address=0 + .word 0x9A00 ! code read/exec + .word 0x00C0 ! granularity=4096, 386 + + .word 0x07FF ! 8Mb - limit=2047 (2048*4096=8Mb) + .word 0x0000 ! base address=0 + .word 0x9200 ! data read/write + .word 0x00C0 ! granularity=4096, 386 + +idt_48: + .word 0 ! idt limit=0 + .word 0,0 ! idt base=0L + +gdt_48: + .word 0x800 ! gdt limit=2048, 256 GDT entries + .word 512+gdt,0x9 ! gdt base = 0X9xxxx + +.text +endtext: +.data +enddata: +.bss +endbss: diff --git a/110_master/110/os/os/linux/execve2.patch b/110_master/110/os/os/linux/execve2.patch new file mode 100644 index 0000000..7d99d4f --- /dev/null +++ b/110_master/110/os/os/linux/execve2.patch @@ -0,0 +1,41 @@ +diff -Naur 0/linux/init/main.c 4/linux/init/main.c +--- 0/linux/init/main.c 2016-08-08 09:40:13.000000000 +0800 ++++ 4/linux/init/main.c 2021-07-06 14:16:56.000000000 +0800 +@@ -208,3 +208,9 @@ + } + _exit(0); /* NOTE! _exit, not exit() */ + } ++ ++void print_nr(int sid) ++{ ++ if (sid > 86) ++ printk(" --syscall: sid=%d, pid=%d\n", sid, current->pid); ++} +diff -Naur 0/linux/kernel/system_call.s 4/linux/kernel/system_call.s +--- 0/linux/kernel/system_call.s 2015-09-03 20:21:09.000000000 +0800 ++++ 4/linux/kernel/system_call.s 2021-07-06 14:18:56.000000000 +0800 +@@ -91,6 +91,11 @@ + mov %dx,%es + movl $0x17,%edx # fs points to local data space + mov %dx,%fs ++ ++ pushl %eax #by wyj ++ call print_nr ++ popl %eax ++ + call sys_call_table(,%eax,4) + pushl %eax + movl current,%eax +diff -Naur 0/linux/mm/memory.c 4/linux/mm/memory.c +--- 0/linux/mm/memory.c 2015-09-04 15:24:20.000000000 +0800 ++++ 4/linux/mm/memory.c 2021-07-06 14:21:45.000000000 +0800 +@@ -370,6 +370,9 @@ + unsigned long page; + int block,i; + ++ if (current->pid > 5) ++ printk(" --do_no_page: address=%x, pid=%d\n", address, current->pid); ++ + address &= 0xfffff000; + tmp = address - current->start_code; + if (!current->executable || tmp >= current->end_data) { diff --git a/110_master/110/os/os/linux/fs/Makefile b/110_master/110/os/os/linux/fs/Makefile new file mode 100644 index 0000000..970acd4 --- /dev/null +++ b/110_master/110/os/os/linux/fs/Makefile @@ -0,0 +1,101 @@ +AR =ar +AS =as +LD =ld +LDFLAGS =-s -x +CC =gcc -march=i386 +CFLAGS =-w -g -fstrength-reduce -fomit-frame-pointer -mcld \ + -finline-functions -nostdinc -fno-stack-protector -I../include +CPP =gcc -E -nostdinc -I../include + +.c.s: + $(CC) $(CFLAGS) \ + -S -o $*.s $< +.c.o: + $(CC) $(CFLAGS) \ + -c -o $*.o $< +.s.o: + $(AS) -o $*.o $< + +OBJS= open.o read_write.o inode.o file_table.o buffer.o super.o \ + block_dev.o char_dev.o file_dev.o stat.o exec.o pipe.o namei.o \ + bitmap.o fcntl.o ioctl.o truncate.o select.o + +fs.o: $(OBJS) + $(LD) -r -o fs.o $(OBJS) + +clean: + rm -f core *.o *.a tmp_make + for i in *.c;do rm -f `basename $$i .c`.s;done + +dep: + sed '/\#\#\# Dependencies/q' < Makefile > tmp_make + (for i in *.c;do $(CPP) -M $$i;done) >> tmp_make + cp tmp_make Makefile + +### Dependencies: +bitmap.o : bitmap.c ../include/string.h ../include/linux/sched.h \ + ../include/linux/head.h ../include/linux/fs.h ../include/sys/types.h \ + ../include/linux/mm.h ../include/signal.h ../include/linux/kernel.h +block_dev.o : block_dev.c ../include/errno.h ../include/linux/sched.h \ + ../include/linux/head.h ../include/linux/fs.h ../include/sys/types.h \ + ../include/linux/mm.h ../include/signal.h ../include/linux/kernel.h \ + ../include/asm/segment.h ../include/asm/system.h +buffer.o : buffer.c ../include/stdarg.h ../include/linux/config.h \ + ../include/linux/sched.h ../include/linux/head.h ../include/linux/fs.h \ + ../include/sys/types.h ../include/linux/mm.h ../include/signal.h \ + ../include/linux/kernel.h ../include/asm/system.h ../include/asm/io.h +char_dev.o : char_dev.c ../include/errno.h ../include/sys/types.h \ + ../include/linux/sched.h ../include/linux/head.h ../include/linux/fs.h \ + ../include/linux/mm.h ../include/signal.h ../include/linux/kernel.h \ + ../include/asm/segment.h ../include/asm/io.h +exec.o : exec.c ../include/errno.h ../include/string.h \ + ../include/sys/stat.h ../include/sys/types.h ../include/a.out.h \ + ../include/linux/fs.h ../include/linux/sched.h ../include/linux/head.h \ + ../include/linux/mm.h ../include/signal.h ../include/linux/kernel.h \ + ../include/asm/segment.h +fcntl.o : fcntl.c ../include/string.h ../include/errno.h \ + ../include/linux/sched.h ../include/linux/head.h ../include/linux/fs.h \ + ../include/sys/types.h ../include/linux/mm.h ../include/signal.h \ + ../include/linux/kernel.h ../include/asm/segment.h ../include/fcntl.h \ + ../include/sys/stat.h +file_dev.o : file_dev.c ../include/errno.h ../include/fcntl.h \ + ../include/sys/types.h ../include/linux/sched.h ../include/linux/head.h \ + ../include/linux/fs.h ../include/linux/mm.h ../include/signal.h \ + ../include/linux/kernel.h ../include/asm/segment.h +file_table.o : file_table.c ../include/linux/fs.h ../include/sys/types.h +inode.o : inode.c ../include/string.h ../include/sys/stat.h \ + ../include/sys/types.h ../include/linux/sched.h ../include/linux/head.h \ + ../include/linux/fs.h ../include/linux/mm.h ../include/signal.h \ + ../include/linux/kernel.h ../include/asm/system.h +ioctl.o : ioctl.c ../include/string.h ../include/errno.h \ + ../include/sys/stat.h ../include/sys/types.h ../include/linux/sched.h \ + ../include/linux/head.h ../include/linux/fs.h ../include/linux/mm.h \ + ../include/signal.h +namei.o : namei.c ../include/linux/sched.h ../include/linux/head.h \ + ../include/linux/fs.h ../include/sys/types.h ../include/linux/mm.h \ + ../include/signal.h ../include/linux/kernel.h ../include/asm/segment.h \ + ../include/string.h ../include/fcntl.h ../include/errno.h \ + ../include/const.h ../include/sys/stat.h +open.o : open.c ../include/string.h ../include/errno.h ../include/fcntl.h \ + ../include/sys/types.h ../include/utime.h ../include/sys/stat.h \ + ../include/linux/sched.h ../include/linux/head.h ../include/linux/fs.h \ + ../include/linux/mm.h ../include/signal.h ../include/linux/tty.h \ + ../include/termios.h ../include/linux/kernel.h ../include/asm/segment.h +pipe.o : pipe.c ../include/signal.h ../include/sys/types.h \ + ../include/linux/sched.h ../include/linux/head.h ../include/linux/fs.h \ + ../include/linux/mm.h ../include/asm/segment.h +read_write.o : read_write.c ../include/sys/stat.h ../include/sys/types.h \ + ../include/errno.h ../include/linux/kernel.h ../include/linux/sched.h \ + ../include/linux/head.h ../include/linux/fs.h ../include/linux/mm.h \ + ../include/signal.h ../include/asm/segment.h +stat.o : stat.c ../include/errno.h ../include/sys/stat.h \ + ../include/sys/types.h ../include/linux/fs.h ../include/linux/sched.h \ + ../include/linux/head.h ../include/linux/mm.h ../include/signal.h \ + ../include/linux/kernel.h ../include/asm/segment.h +super.o : super.c ../include/linux/config.h ../include/linux/sched.h \ + ../include/linux/head.h ../include/linux/fs.h ../include/sys/types.h \ + ../include/linux/mm.h ../include/signal.h ../include/linux/kernel.h \ + ../include/asm/system.h ../include/errno.h ../include/sys/stat.h +truncate.o : truncate.c ../include/linux/sched.h ../include/linux/head.h \ + ../include/linux/fs.h ../include/sys/types.h ../include/linux/mm.h \ + ../include/signal.h ../include/sys/stat.h diff --git a/110_master/110/os/os/linux/fs/bitmap.c b/110_master/110/os/os/linux/fs/bitmap.c new file mode 100644 index 0000000..73951a8 --- /dev/null +++ b/110_master/110/os/os/linux/fs/bitmap.c @@ -0,0 +1,168 @@ +/* + * linux/fs/bitmap.c + * + * (C) 1991 Linus Torvalds + */ + +/* bitmap.c contains the code that handles the inode and block bitmaps */ +#include + +#include +#include + +#define clear_block(addr) \ +__asm__ __volatile__ ("cld\n\t" \ + "rep\n\t" \ + "stosl" \ + ::"a" (0),"c" (BLOCK_SIZE/4),"D" ((long) (addr))) + +#define set_bit(nr,addr) ({\ +register int res __asm__("ax"); \ +__asm__ __volatile__("btsl %2,%3\n\tsetb %%al": \ +"=a" (res):"0" (0),"r" (nr),"m" (*(addr))); \ +res;}) + +#define clear_bit(nr,addr) ({\ +register int res __asm__("ax"); \ +__asm__ __volatile__("btrl %2,%3\n\tsetnb %%al": \ +"=a" (res):"0" (0),"r" (nr),"m" (*(addr))); \ +res;}) + +#define find_first_zero(addr) ({ \ +int __res; \ +__asm__ __volatile__ ("cld\n" \ + "1:\tlodsl\n\t" \ + "notl %%eax\n\t" \ + "bsfl %%eax,%%edx\n\t" \ + "je 2f\n\t" \ + "addl %%edx,%%ecx\n\t" \ + "jmp 3f\n" \ + "2:\taddl $32,%%ecx\n\t" \ + "cmpl $8192,%%ecx\n\t" \ + "jl 1b\n" \ + "3:" \ + :"=c" (__res):"c" (0),"S" (addr)); \ +__res;}) + +void free_block(int dev, int block) +{ + struct super_block * sb; + struct buffer_head * bh; + + if (!(sb = get_super(dev))) + panic("trying to free block on nonexistent device"); + if (block < sb->s_firstdatazone || block >= sb->s_nzones) + panic("trying to free block not in datazone"); + bh = get_hash_table(dev,block); + if (bh) { + if (bh->b_count != 1) { + printk("trying to free block (%04x:%d), count=%d\n", + dev,block,bh->b_count); + return; + } + bh->b_dirt=0; + bh->b_uptodate=0; + brelse(bh); + } + block -= sb->s_firstdatazone - 1 ; + if (clear_bit(block&8191,sb->s_zmap[block/8192]->b_data)) { + printk("block (%04x:%d) ",dev,block+sb->s_firstdatazone-1); + panic("free_block: bit already cleared"); + } + sb->s_zmap[block/8192]->b_dirt = 1; +} + +int new_block(int dev) +{ + struct buffer_head * bh; + struct super_block * sb; + int i,j; + + if (!(sb = get_super(dev))) + panic("trying to get new block from nonexistant device"); + j = 8192; + for (i=0 ; i<8 ; i++) + if (bh=sb->s_zmap[i]) + if ((j=find_first_zero(bh->b_data))<8192) + break; + if (i>=8 || !bh || j>=8192) + return 0; + if (set_bit(j,bh->b_data)) + panic("new_block: bit already set"); + bh->b_dirt = 1; + j += i*8192 + sb->s_firstdatazone-1; + if (j >= sb->s_nzones) + return 0; + if (!(bh=getblk(dev,j))) + panic("new_block: cannot get block"); + if (bh->b_count != 1) + panic("new block: count is != 1"); + clear_block(bh->b_data); + bh->b_uptodate = 1; + bh->b_dirt = 1; + brelse(bh); + return j; +} + +void free_inode(struct m_inode * inode) +{ + struct super_block * sb; + struct buffer_head * bh; + + if (!inode) + return; + if (!inode->i_dev) { + memset(inode,0,sizeof(*inode)); + return; + } + if (inode->i_count>1) { + printk("trying to free inode with count=%d\n",inode->i_count); + panic("free_inode"); + } + if (inode->i_nlinks) + panic("trying to free inode with links"); + if (!(sb = get_super(inode->i_dev))) + panic("trying to free inode on nonexistent device"); + if (inode->i_num < 1 || inode->i_num > sb->s_ninodes) + panic("trying to free inode 0 or nonexistant inode"); + if (!(bh=sb->s_imap[inode->i_num>>13])) + panic("nonexistent imap in superblock"); + if (clear_bit(inode->i_num&8191,bh->b_data)) + printk("free_inode: bit already cleared.\n\r"); + bh->b_dirt = 1; + memset(inode,0,sizeof(*inode)); +} + +struct m_inode * new_inode(int dev) +{ + struct m_inode * inode; + struct super_block * sb; + struct buffer_head * bh; + int i,j; + + if (!(inode=get_empty_inode())) + return NULL; + if (!(sb = get_super(dev))) + panic("new_inode with unknown device"); + j = 8192; + for (i=0 ; i<8 ; i++) + if (bh=sb->s_imap[i]) + if ((j=find_first_zero(bh->b_data))<8192) + break; + if (!bh || j >= 8192 || j+i*8192 > sb->s_ninodes) { + iput(inode); + return NULL; + } + if (set_bit(j,bh->b_data)) + panic("new_inode: bit already set"); + bh->b_dirt = 1; + inode->i_count=1; + inode->i_nlinks=1; + inode->i_dev=dev; + inode->i_uid=current->euid; + inode->i_gid=current->egid; + inode->i_dirt=1; + inode->i_num = j + i*8192; + inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME; + return inode; +} diff --git a/110_master/110/os/os/linux/fs/bitmap.o b/110_master/110/os/os/linux/fs/bitmap.o new file mode 100644 index 0000000000000000000000000000000000000000..501d3c5e3fb1a044792589a0bdde55cbb41cfaa2 GIT binary patch literal 10280 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 J@|j5fe*vQQ&y@fG literal 0 HcmV?d00001 diff --git a/110_master/110/os/os/linux/fs/block_dev.c b/110_master/110/os/os/linux/fs/block_dev.c new file mode 100644 index 0000000..a50ae3f --- /dev/null +++ b/110_master/110/os/os/linux/fs/block_dev.c @@ -0,0 +1,73 @@ +/* + * linux/fs/block_dev.c + * + * (C) 1991 Linus Torvalds + */ + +#include + +#include +#include +#include +#include + +int block_write(int dev, long * pos, char * buf, int count) +{ + int block = *pos >> BLOCK_SIZE_BITS; + int offset = *pos & (BLOCK_SIZE-1); + int chars; + int written = 0; + struct buffer_head * bh; + register char * p; + + while (count>0) { + chars = BLOCK_SIZE - offset; + if (chars > count) + chars=count; + if (chars == BLOCK_SIZE) + bh = getblk(dev,block); + else + bh = breada(dev,block,block+1,block+2,-1); + block++; + if (!bh) + return written?written:-EIO; + p = offset + bh->b_data; + offset = 0; + *pos += chars; + written += chars; + count -= chars; + while (chars-->0) + *(p++) = get_fs_byte(buf++); + bh->b_dirt = 1; + brelse(bh); + } + return written; +} + +int block_read(int dev, unsigned long * pos, char * buf, int count) +{ + int block = *pos >> BLOCK_SIZE_BITS; + int offset = *pos & (BLOCK_SIZE-1); + int chars; + int read = 0; + struct buffer_head * bh; + register char * p; + + while (count>0) { + chars = BLOCK_SIZE-offset; + if (chars > count) + chars = count; + if (!(bh = breada(dev,block,block+1,block+2,-1))) + return read?read:-EIO; + block++; + p = offset + bh->b_data; + offset = 0; + *pos += chars; + read += chars; + count -= chars; + while (chars-->0) + put_fs_byte(*(p++),buf++); + brelse(bh); + } + return read; +} diff --git a/110_master/110/os/os/linux/fs/block_dev.o b/110_master/110/os/os/linux/fs/block_dev.o new file mode 100644 index 0000000000000000000000000000000000000000..e5e9334ce9a4697061730271c4c9d92fcf4aa105 GIT binary patch literal 7296 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 + +#include +#include +#include +#include +#include + +extern void put_super(int dev); +extern void invalidate_inodes(int dev); + +extern int end; +struct buffer_head * start_buffer = (struct buffer_head *) &end; +struct buffer_head * hash_table[NR_HASH]; +static struct buffer_head * free_list; +static struct task_struct * buffer_wait = NULL; +int NR_BUFFERS = 0; + +static inline void wait_on_buffer(struct buffer_head * bh) +{ + cli(); + while (bh->b_lock) + sleep_on(&bh->b_wait); + sti(); +} + +int sys_sync(void) +{ + int i; + struct buffer_head * bh; + + sync_inodes(); /* write out inodes into buffers */ + bh = start_buffer; + for (i=0 ; ib_dirt) + ll_rw_block(WRITE,bh); + } + return 0; +} + +int sync_dev(int dev) +{ + int i; + struct buffer_head * bh; + + bh = start_buffer; + for (i=0 ; ib_dev != dev) + continue; + wait_on_buffer(bh); + if (bh->b_dev == dev && bh->b_dirt) + ll_rw_block(WRITE,bh); + } + sync_inodes(); + bh = start_buffer; + for (i=0 ; ib_dev != dev) + continue; + wait_on_buffer(bh); + if (bh->b_dev == dev && bh->b_dirt) + ll_rw_block(WRITE,bh); + } + return 0; +} + +void inline invalidate_buffers(int dev) +{ + int i; + struct buffer_head * bh; + + bh = start_buffer; + for (i=0 ; ib_dev != dev) + continue; + wait_on_buffer(bh); + if (bh->b_dev == dev) + bh->b_uptodate = bh->b_dirt = 0; + } +} + +/* + * This routine checks whether a floppy has been changed, and + * invalidates all buffer-cache-entries in that case. This + * is a relatively slow routine, so we have to try to minimize using + * it. Thus it is called only upon a 'mount' or 'open'. This + * is the best way of combining speed and utility, I think. + * People changing diskettes in the middle of an operation deserve + * to loose :-) + * + * NOTE! Although currently this is only for floppies, the idea is + * that any additional removable block-device will use this routine, + * and that mount/open needn't know that floppies/whatever are + * special. + */ +void check_disk_change(int dev) +{ + int i; + + if (MAJOR(dev) != 2) + return; + if (!floppy_change(dev & 0x03)) + return; + for (i=0 ; ib_next) + bh->b_next->b_prev = bh->b_prev; + if (bh->b_prev) + bh->b_prev->b_next = bh->b_next; + if (hash(bh->b_dev,bh->b_blocknr) == bh) + hash(bh->b_dev,bh->b_blocknr) = bh->b_next; +/* remove from free list */ + if (!(bh->b_prev_free) || !(bh->b_next_free)) + panic("Free block list corrupted"); + bh->b_prev_free->b_next_free = bh->b_next_free; + bh->b_next_free->b_prev_free = bh->b_prev_free; + if (free_list == bh) + free_list = bh->b_next_free; +} + +static inline void insert_into_queues(struct buffer_head * bh) +{ +/* put at end of free list */ + bh->b_next_free = free_list; + bh->b_prev_free = free_list->b_prev_free; + free_list->b_prev_free->b_next_free = bh; + free_list->b_prev_free = bh; +/* put the buffer in new hash-queue if it has a device */ + bh->b_prev = NULL; + bh->b_next = NULL; + if (!bh->b_dev) + return; + bh->b_next = hash(bh->b_dev,bh->b_blocknr); + hash(bh->b_dev,bh->b_blocknr) = bh; + bh->b_next->b_prev = bh; +} + +static struct buffer_head * find_buffer(int dev, int block) +{ + struct buffer_head * tmp; + + for (tmp = hash(dev,block) ; tmp != NULL ; tmp = tmp->b_next) + if (tmp->b_dev==dev && tmp->b_blocknr==block) + return tmp; + return NULL; +} + +/* + * Why like this, I hear you say... The reason is race-conditions. + * As we don't lock buffers (unless we are readint them, that is), + * something might happen to it while we sleep (ie a read-error + * will force it bad). This shouldn't really happen currently, but + * the code is ready. + */ +struct buffer_head * get_hash_table(int dev, int block) +{ + struct buffer_head * bh; + + for (;;) { + if (!(bh=find_buffer(dev,block))) + return NULL; + bh->b_count++; + wait_on_buffer(bh); + if (bh->b_dev == dev && bh->b_blocknr == block) + return bh; + bh->b_count--; + } +} + +/* + * Ok, this is getblk, and it isn't very clear, again to hinder + * race-conditions. Most of the code is seldom used, (ie repeating), + * so it should be much more efficient than it looks. + * + * The algoritm is changed: hopefully better, and an elusive bug removed. + */ +#define BADNESS(bh) (((bh)->b_dirt<<1)+(bh)->b_lock) +struct buffer_head * getblk(int dev,int block) +{ + struct buffer_head * tmp, * bh; + +repeat: + if (bh = get_hash_table(dev,block)) + return bh; + tmp = free_list; + do { + if (tmp->b_count) + continue; + if (!bh || BADNESS(tmp)b_next_free) != free_list); + if (!bh) { + sleep_on(&buffer_wait); + goto repeat; + } + wait_on_buffer(bh); + if (bh->b_count) + goto repeat; + while (bh->b_dirt) { + sync_dev(bh->b_dev); + wait_on_buffer(bh); + if (bh->b_count) + goto repeat; + } +/* NOTE!! While we slept waiting for this block, somebody else might */ +/* already have added "this" block to the cache. check it */ + if (find_buffer(dev,block)) + goto repeat; +/* OK, FINALLY we know that this buffer is the only one of it's kind, */ +/* and that it's unused (b_count=0), unlocked (b_lock=0), and clean */ + bh->b_count=1; + bh->b_dirt=0; + bh->b_uptodate=0; + remove_from_queues(bh); + bh->b_dev=dev; + bh->b_blocknr=block; + insert_into_queues(bh); + return bh; +} + +void brelse(struct buffer_head * buf) +{ + if (!buf) + return; + wait_on_buffer(buf); + if (!(buf->b_count--)) + panic("Trying to free free buffer"); + wake_up(&buffer_wait); +} + +/* + * bread() reads a specified block and returns the buffer that contains + * it. It returns NULL if the block was unreadable. + */ +struct buffer_head * bread(int dev,int block) +{ + struct buffer_head * bh; + + if (!(bh=getblk(dev,block))) + panic("bread: getblk returned NULL\n"); + if (bh->b_uptodate) + return bh; + ll_rw_block(READ,bh); + wait_on_buffer(bh); + if (bh->b_uptodate) + return bh; + brelse(bh); + return NULL; +} + +#define COPYBLK(from,to) \ +__asm__("cld\n\t" \ + "rep\n\t" \ + "movsl\n\t" \ + ::"c" (BLOCK_SIZE/4),"S" (from),"D" (to) \ + ) + +/* + * bread_page reads four buffers into memory at the desired address. It's + * a function of its own, as there is some speed to be got by reading them + * all at the same time, not waiting for one to be read, and then another + * etc. + */ +void bread_page(unsigned long address,int dev,int b[4]) +{ + struct buffer_head * bh[4]; + int i; + + for (i=0 ; i<4 ; i++) + if (b[i]) { + if (bh[i] = getblk(dev,b[i])) + if (!bh[i]->b_uptodate) + ll_rw_block(READ,bh[i]); + } else + bh[i] = NULL; + for (i=0 ; i<4 ; i++,address += BLOCK_SIZE) + if (bh[i]) { + wait_on_buffer(bh[i]); + if (bh[i]->b_uptodate) + COPYBLK((unsigned long) bh[i]->b_data,address); + brelse(bh[i]); + } +} + +/* + * Ok, breada can be used as bread, but additionally to mark other + * blocks for reading as well. End the argument list with a negative + * number. + */ +struct buffer_head * breada(int dev,int first, ...) +{ + va_list args; + struct buffer_head * bh, *tmp; + + va_start(args,first); + if (!(bh=getblk(dev,first))) + panic("bread: getblk returned NULL\n"); + if (!bh->b_uptodate) + ll_rw_block(READ,bh); + while ((first=va_arg(args,int))>=0) { + tmp=getblk(dev,first); + if (tmp) { + if (!tmp->b_uptodate) + ll_rw_block(READA,bh); + tmp->b_count--; + } + } + va_end(args); + wait_on_buffer(bh); + if (bh->b_uptodate) + return bh; + brelse(bh); + return (NULL); +} + +void buffer_init(long buffer_end) +{ + struct buffer_head * h = start_buffer; + void * b; + int i; + + if (buffer_end == 1<<20) + b = (void *) (640*1024); + else + b = (void *) buffer_end; + while ( (b -= BLOCK_SIZE) >= ((void *) (h+1)) ) { + h->b_dev = 0; + h->b_dirt = 0; + h->b_count = 0; + h->b_lock = 0; + h->b_uptodate = 0; + h->b_wait = NULL; + h->b_next = NULL; + h->b_prev = NULL; + h->b_data = (char *) b; + h->b_prev_free = h-1; + h->b_next_free = h+1; + h++; + NR_BUFFERS++; + if (b == (void *) 0x100000) + b = (void *) 0xA0000; + } + h--; + free_list = start_buffer; + free_list->b_prev_free = h; + h->b_next_free = free_list; + for (i=0;iQ6+~nZ1VPZCP{pdlWadpWGMO3Y4-glv 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 +#include + +#include +#include + +#include +#include + +extern int tty_read(unsigned minor,char * buf,int count); +extern int tty_write(unsigned minor,char * buf,int count); + +typedef (*crw_ptr)(int rw,unsigned minor,char * buf,int count,off_t * pos); + +static int rw_ttyx(int rw,unsigned minor,char * buf,int count,off_t * pos) +{ + return ((rw==READ)?tty_read(minor,buf,count): + tty_write(minor,buf,count)); +} + +static int rw_tty(int rw,unsigned minor,char * buf,int count, off_t * pos) +{ + if (current->tty<0) + return -EPERM; + return rw_ttyx(rw,current->tty,buf,count,pos); +} + +static int rw_ram(int rw,char * buf, int count, off_t *pos) +{ + return -EIO; +} + +static int rw_mem(int rw,char * buf, int count, off_t * pos) +{ + return -EIO; +} + +static int rw_kmem(int rw,char * buf, int count, off_t * pos) +{ + return -EIO; +} + +static int rw_port(int rw,char * buf, int count, off_t * pos) +{ + int i=*pos; + + while (count-->0 && i<65536) { + if (rw==READ) + put_fs_byte(inb(i),buf++); + else + outb(get_fs_byte(buf++),i); + i++; + } + i -= *pos; + *pos += i; + return i; +} + +static int rw_memory(int rw, unsigned minor, char * buf, int count, off_t * pos) +{ + switch(minor) { + case 0: + return rw_ram(rw,buf,count,pos); + case 1: + return rw_mem(rw,buf,count,pos); + case 2: + return rw_kmem(rw,buf,count,pos); + case 3: + return (rw==READ)?0:count; /* rw_null */ + case 4: + return rw_port(rw,buf,count,pos); + default: + return -EIO; + } +} + +#define NRDEVS ((sizeof (crw_table))/(sizeof (crw_ptr))) + +static crw_ptr crw_table[]={ + NULL, /* nodev */ + rw_memory, /* /dev/mem etc */ + NULL, /* /dev/fd */ + NULL, /* /dev/hd */ + rw_ttyx, /* /dev/ttyx */ + rw_tty, /* /dev/tty */ + NULL, /* /dev/lp */ + NULL}; /* unnamed pipes */ + +int rw_char(int rw,int dev, char * buf, int count, off_t * pos) +{ + crw_ptr call_addr; + + if (MAJOR(dev)>=NRDEVS) + return -ENODEV; + if (!(call_addr=crw_table[MAJOR(dev)])) + return -ENODEV; + return call_addr(rw,MINOR(dev),buf,count,pos); +} diff --git a/110_master/110/os/os/linux/fs/char_dev.o b/110_master/110/os/os/linux/fs/char_dev.o new file mode 100644 index 0000000000000000000000000000000000000000..2977060a7c0b215e10aa16a8395ed973d52837cd GIT binary patch literal 8288 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 O%Ys)0UlIH-!T$wZ8WjQn literal 0 HcmV?d00001 diff --git a/110_master/110/os/os/linux/fs/exec.c b/110_master/110/os/os/linux/fs/exec.c new file mode 100644 index 0000000..2ff220e --- /dev/null +++ b/110_master/110/os/os/linux/fs/exec.c @@ -0,0 +1,359 @@ +/* + * linux/fs/exec.c + * + * (C) 1991 Linus Torvalds + */ + +/* + * #!-checking implemented by tytso. + */ + +/* + * Demand-loading implemented 01.12.91 - no need to read anything but + * the header into memory. The inode of the executable is put into + * "current->executable", and page faults do the actual loading. Clean. + * + * Once more I can proudly say that linux stood up to being changed: it + * was less than 2 hours work to get demand-loading completely implemented. + */ + +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +extern int sys_exit(int exit_code); +extern int sys_close(int fd); + +/* + * MAX_ARG_PAGES defines the number of pages allocated for arguments + * and envelope for the new program. 32 should suffice, this gives + * a maximum env+arg of 128kB ! + */ +#define MAX_ARG_PAGES 32 + + +int sys_uselib() +{ + return -ENOSYS; +} + +/* + * create_tables() parses the env- and arg-strings in new user + * memory and creates the pointer tables from them, and puts their + * addresses on the "stack", returning the new stack pointer value. + */ +static unsigned long * create_tables(char * p,int argc,int envc) +{ + unsigned long *argv,*envp; + unsigned long * sp; + + sp = (unsigned long *) (0xfffffffc & (unsigned long) p); + sp -= envc+1; + envp = sp; + sp -= argc+1; + argv = sp; + put_fs_long((unsigned long)envp,--sp); + put_fs_long((unsigned long)argv,--sp); + put_fs_long((unsigned long)argc,--sp); + while (argc-->0) { + put_fs_long((unsigned long) p,argv++); + while (get_fs_byte(p++)) /* nothing */ ; + } + put_fs_long(0,argv); + while (envc-->0) { + put_fs_long((unsigned long) p,envp++); + while (get_fs_byte(p++)) /* nothing */ ; + } + put_fs_long(0,envp); + return sp; +} + +/* + * count() counts the number of arguments/envelopes + */ +static int count(char ** argv) +{ + int i=0; + char ** tmp; + + if (tmp = argv) + while (get_fs_long((unsigned long *) (tmp++))) + i++; + + return i; +} + +/* + * 'copy_string()' copies argument/envelope strings from user + * memory to free pages in kernel mem. These are in a format ready + * to be put directly into the top of new user memory. + * + * Modified by TYT, 11/24/91 to add the from_kmem argument, which specifies + * whether the string and the string array are from user or kernel segments: + * + * from_kmem argv * argv ** + * 0 user space user space + * 1 kernel space user space + * 2 kernel space kernel space + * + * We do this by playing games with the fs segment register. Since it + * it is expensive to load a segment register, we try to avoid calling + * set_fs() unless we absolutely have to. + */ +static unsigned long copy_strings(int argc,char ** argv,unsigned long *page, + unsigned long p, int from_kmem) +{ + char *tmp, *pag; + int len, offset = 0; + unsigned long old_fs, new_fs; + + if (!p) + return 0; /* bullet-proofing */ + new_fs = get_ds(); + old_fs = get_fs(); + if (from_kmem==2) + set_fs(new_fs); + while (argc-- > 0) { + if (from_kmem == 1) + set_fs(new_fs); + if (!(tmp = (char *)get_fs_long(((unsigned long *)argv)+argc))) + panic("argc is wrong"); + if (from_kmem == 1) + set_fs(old_fs); + len=0; /* remember zero-padding */ + do { + len++; + } while (get_fs_byte(tmp++)); + if (p-len < 0) { /* this shouldn't happen - 128kB */ + set_fs(old_fs); + return 0; + } + while (len) { + --p; --tmp; --len; + if (--offset < 0) { + offset = p % PAGE_SIZE; + if (from_kmem==2) + set_fs(old_fs); + if (!(pag = (char *) page[p/PAGE_SIZE]) && + !(pag = (char *) (page[p/PAGE_SIZE] = + (unsigned long *) get_free_page()))) + return 0; + if (from_kmem==2) + set_fs(new_fs); + + } + *(pag + offset) = get_fs_byte(tmp); + } + } + if (from_kmem==2) + set_fs(old_fs); + return p; +} + +static unsigned long change_ldt(unsigned long text_size,unsigned long * page) +{ + unsigned long code_limit,data_limit,code_base,data_base; + int i; + + code_limit = text_size+PAGE_SIZE -1; + code_limit &= 0xFFFFF000; + data_limit = 0x4000000; + code_base = get_base(current->ldt[1]); + data_base = code_base; + set_base(current->ldt[1],code_base); + set_limit(current->ldt[1],code_limit); + set_base(current->ldt[2],data_base); + set_limit(current->ldt[2],data_limit); +/* make sure fs points to the NEW data segment */ + __asm__("pushl $0x17\n\tpop %%fs"::); + data_base += data_limit; + for (i=MAX_ARG_PAGES-1 ; i>=0 ; i--) { + data_base -= PAGE_SIZE; + if (page[i]) + put_page(page[i],data_base); + } + return data_limit; +} + +/* + * 'do_execve()' executes a new program. + */ +int do_execve(unsigned long * eip,long tmp,char * filename, + char ** argv, char ** envp) +{ + struct m_inode * inode; + struct buffer_head * bh; + struct exec ex; + unsigned long page[MAX_ARG_PAGES]; + int i,argc,envc; + int e_uid, e_gid; + int retval; + int sh_bang = 0; + unsigned long p=PAGE_SIZE*MAX_ARG_PAGES-4; + + if ((0xffff & eip[1]) != 0x000f) + panic("execve called from supervisor mode"); + for (i=0 ; ii_mode)) { /* must be regular file */ + retval = -EACCES; + goto exec_error2; + } + i = inode->i_mode; + e_uid = (i & S_ISUID) ? inode->i_uid : current->euid; + e_gid = (i & S_ISGID) ? inode->i_gid : current->egid; + if (current->euid == inode->i_uid) + i >>= 6; + else if (current->egid == inode->i_gid) + i >>= 3; + if (!(i & 1) && + !((inode->i_mode & 0111) && suser())) { + retval = -ENOEXEC; + goto exec_error2; + } + if (!(bh = bread(inode->i_dev,inode->i_zone[0]))) { + retval = -EACCES; + goto exec_error2; + } + ex = *((struct exec *) bh->b_data); /* read exec-header */ + if ((bh->b_data[0] == '#') && (bh->b_data[1] == '!') && (!sh_bang)) { + /* + * This section does the #! interpretation. + * Sorta complicated, but hopefully it will work. -TYT + */ + + char buf[1023], *cp, *interp, *i_name, *i_arg; + unsigned long old_fs; + + strncpy(buf, bh->b_data+2, 1022); + brelse(bh); + iput(inode); + buf[1022] = '\0'; + if (cp = strchr(buf, '\n')) { + *cp = '\0'; + for (cp = buf; (*cp == ' ') || (*cp == '\t'); cp++); + } + if (!cp || *cp == '\0') { + retval = -ENOEXEC; /* No interpreter name found */ + goto exec_error1; + } + interp = i_name = cp; + i_arg = 0; + for ( ; *cp && (*cp != ' ') && (*cp != '\t'); cp++) { + if (*cp == '/') + i_name = cp+1; + } + if (*cp) { + *cp++ = '\0'; + i_arg = cp; + } + /* + * OK, we've parsed out the interpreter name and + * (optional) argument. + */ + if (sh_bang++ == 0) { + p = copy_strings(envc, envp, page, p, 0); + p = copy_strings(--argc, argv+1, page, p, 0); + } + /* + * Splice in (1) the interpreter's name for argv[0] + * (2) (optional) argument to interpreter + * (3) filename of shell script + * + * This is done in reverse order, because of how the + * user environment and arguments are stored. + */ + p = copy_strings(1, &filename, page, p, 1); + argc++; + if (i_arg) { + p = copy_strings(1, &i_arg, page, p, 2); + argc++; + } + p = copy_strings(1, &i_name, page, p, 2); + argc++; + if (!p) { + retval = -ENOMEM; + goto exec_error1; + } + /* + * OK, now restart the process with the interpreter's inode. + */ + old_fs = get_fs(); + set_fs(get_ds()); + if (!(inode=namei(interp))) { /* get executables inode */ + set_fs(old_fs); + retval = -ENOENT; + goto exec_error1; + } + set_fs(old_fs); + goto restart_interp; + } + brelse(bh); + if (N_MAGIC(ex) != ZMAGIC || ex.a_trsize || ex.a_drsize || + ex.a_text+ex.a_data+ex.a_bss>0x3000000 || + inode->i_size < ex.a_text+ex.a_data+ex.a_syms+N_TXTOFF(ex)) { + retval = -ENOEXEC; + goto exec_error2; + } + if (N_TXTOFF(ex) != BLOCK_SIZE) { + printk("%s: N_TXTOFF != BLOCK_SIZE. See a.out.h.", filename); + retval = -ENOEXEC; + goto exec_error2; + } + if (!sh_bang) { + p = copy_strings(envc,envp,page,p,0); + p = copy_strings(argc,argv,page,p,0); + if (!p) { + retval = -ENOMEM; + goto exec_error2; + } + } +/* OK, This is the point of no return */ + if (current->executable) + iput(current->executable); + current->executable = inode; + for (i=0 ; i<32 ; i++) + current->sigaction[i].sa_handler = NULL; + for (i=0 ; iclose_on_exec>>i)&1) + sys_close(i); + current->close_on_exec = 0; + free_page_tables(get_base(current->ldt[1]),get_limit(0x0f)); + free_page_tables(get_base(current->ldt[2]),get_limit(0x17)); + if (last_task_used_math == current) + last_task_used_math = NULL; + current->used_math = 0; + p += change_ldt(ex.a_text,page)-MAX_ARG_PAGES*PAGE_SIZE; + p = (unsigned long) create_tables((char *)p,argc,envc); + current->brk = ex.a_bss + + (current->end_data = ex.a_data + + (current->end_code = ex.a_text)); + current->start_stack = p & 0xfffff000; + current->euid = e_uid; + current->egid = e_gid; + i = ex.a_text+ex.a_data; + while (i&0xfff) + put_fs_byte(0,(char *) (i++)); + eip[0] = ex.a_entry; /* eip, magic happens :-) */ + eip[3] = p; /* stack pointer */ + return 0; +exec_error2: + iput(inode); +exec_error1: + for (i=0 ; ifLjn&WLJ0DU0bbdE!WBx#8#{JUaxh_{r%qa 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 C=E>Ip literal 0 HcmV?d00001 diff --git a/110_master/110/os/os/linux/fs/fcntl.c b/110_master/110/os/os/linux/fs/fcntl.c new file mode 100644 index 0000000..c201aa8 --- /dev/null +++ b/110_master/110/os/os/linux/fs/fcntl.c @@ -0,0 +1,75 @@ +/* + * linux/fs/fcntl.c + * + * (C) 1991 Linus Torvalds + */ + +#include +#include +#include +#include +#include + +#include +#include + +extern int sys_close(int fd); + +static int dupfd(unsigned int fd, unsigned int arg) +{ + if (fd >= NR_OPEN || !current->filp[fd]) + return -EBADF; + if (arg >= NR_OPEN) + return -EINVAL; + while (arg < NR_OPEN) + if (current->filp[arg]) + arg++; + else + break; + if (arg >= NR_OPEN) + return -EMFILE; + current->close_on_exec &= ~(1<filp[arg] = current->filp[fd])->f_count++; + return arg; +} + +int sys_dup2(unsigned int oldfd, unsigned int newfd) +{ + sys_close(newfd); + return dupfd(oldfd,newfd); +} + +int sys_dup(unsigned int fildes) +{ + return dupfd(fildes,0); +} + +int sys_fcntl(unsigned int fd, unsigned int cmd, unsigned long arg) +{ + struct file * filp; + + if (fd >= NR_OPEN || !(filp = current->filp[fd])) + return -EBADF; + switch (cmd) { + case F_DUPFD: + return dupfd(fd,arg); + case F_GETFD: + return (current->close_on_exec>>fd)&1; + case F_SETFD: + if (arg&1) + current->close_on_exec |= (1<close_on_exec &= ~(1<f_flags; + case F_SETFL: + filp->f_flags &= ~(O_APPEND | O_NONBLOCK); + filp->f_flags |= arg & (O_APPEND | O_NONBLOCK); + return 0; + case F_GETLK: case F_SETLK: case F_SETLKW: + return -1; + default: + return -1; + } +} diff --git a/110_master/110/os/os/linux/fs/fcntl.o b/110_master/110/os/os/linux/fs/fcntl.o new file mode 100644 index 0000000000000000000000000000000000000000..17a6ecacd50cb07b4337da65f94d880d02b367a8 GIT binary patch literal 6748 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 literal 0 HcmV?d00001 diff --git a/110_master/110/os/os/linux/fs/file_dev.c b/110_master/110/os/os/linux/fs/file_dev.c new file mode 100644 index 0000000..0c50eaa --- /dev/null +++ b/110_master/110/os/os/linux/fs/file_dev.c @@ -0,0 +1,90 @@ +/* + * linux/fs/file_dev.c + * + * (C) 1991 Linus Torvalds + */ + +#include +#include + +#include +#include +#include + +#define MIN(a,b) (((a)<(b))?(a):(b)) +#define MAX(a,b) (((a)>(b))?(a):(b)) + +int file_read(struct m_inode * inode, struct file * filp, char * buf, int count) +{ + int left,chars,nr; + struct buffer_head * bh; + + if ((left=count)<=0) + return 0; + while (left) { + if (nr = bmap(inode,(filp->f_pos)/BLOCK_SIZE)) { + if (!(bh=bread(inode->i_dev,nr))) + break; + } else + bh = NULL; + nr = filp->f_pos % BLOCK_SIZE; + chars = MIN( BLOCK_SIZE-nr , left ); + filp->f_pos += chars; + left -= chars; + if (bh) { + char * p = nr + bh->b_data; + while (chars-->0) + put_fs_byte(*(p++),buf++); + brelse(bh); + } else { + while (chars-->0) + put_fs_byte(0,buf++); + } + } + inode->i_atime = CURRENT_TIME; + return (count-left)?(count-left):-ERROR; +} + +int file_write(struct m_inode * inode, struct file * filp, char * buf, int count) +{ + off_t pos; + int block,c; + struct buffer_head * bh; + char * p; + int i=0; + +/* + * ok, append may not work when many processes are writing at the same time + * but so what. That way leads to madness anyway. + */ + if (filp->f_flags & O_APPEND) + pos = inode->i_size; + else + pos = filp->f_pos; + while (ii_dev,block))) + break; + c = pos % BLOCK_SIZE; + p = c + bh->b_data; + bh->b_dirt = 1; + c = BLOCK_SIZE-c; + if (c > count-i) c = count-i; + pos += c; + if (pos > inode->i_size) { + inode->i_size = pos; + inode->i_dirt = 1; + } + i += c; + while (c-->0) + *(p++) = get_fs_byte(buf++); + brelse(bh); + } + inode->i_mtime = CURRENT_TIME; + if (!(filp->f_flags & O_APPEND)) { + filp->f_pos = pos; + inode->i_ctime = CURRENT_TIME; + } + return (i?i:-1); +} diff --git a/110_master/110/os/os/linux/fs/file_dev.o b/110_master/110/os/os/linux/fs/file_dev.o new file mode 100644 index 0000000000000000000000000000000000000000..e1ba8a5aa9f848cbe07cc40a116357db631d2c89 GIT binary patch literal 7828 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 SclH@D3RwcTDjZc + +struct file file_table[NR_FILE]; diff --git a/110_master/110/os/os/linux/fs/file_table.o b/110_master/110/os/os/linux/fs/file_table.o new file mode 100644 index 0000000000000000000000000000000000000000..422bcb331f1423abef699440aa5b0f0ff3a8b671 GIT binary patch literal 2644 zcma)8ONbmr7_OR`-P!Hgo!w=9BnF`a8xkecvzttkb&W;|x+aF`!4(DLY)?=3Ogq!v zV?VOl_&SK&K#0s-B=xPW^?j%FhrbeTlMCJwT9?XVawWCSbyVX|l2jSv>;r0{YaW6k_^T zz^c43M3{C3LO#m~p?wD-+vFv!O1}9tWJUXp+$5jUK4*OA9`G6MD!D~It9?Y?9e~%h zNpi;q*R@lSvd7#dtx0>I{E+r8?Jnm!to=&<9J!$#WXynkS-U~|kmDcG>f|2zQB7xz zPu|k*q&*-%ra=ffB0sKOX3X>CC&cs`U|z-_!=_!MBjE%>dy4!bc}e?}e2cuIh2)nQ zKBe73zWo5~GpHxaSY_e9qLcMJC2H@1m#062oG8PB_yu{OzE~^Q_tocb$KXq%R=Xc6 z!W5mtG`ERzeXVwH?aU$)7onWoi!GZ&EG<G-(`FDL5GCjLkzBG)c>s!O5Yd43kpIj0J zL$ni?^gGLma)}S#8gV?s>Amp;_i=x>NJiF;9-MAS< z4d33%KD)7OtgJMKW~aHF8JbRnjKu9i4g+f-0>^2`Q2fM$^wI?~uoxN5N}`rr)!X zkOgp0bB?ivVFjLNqo#(BEj4ghvMo+e;Qti+cm>cWRebh7?!!!*IMC1w&2`!#>Rb)&9ZYkHg8gkiQ-5obM!ho&zcta4TOYQ7!kK zhn{n~t|E>PMc#7XSs04*p2N$^c{neB7xH;8faf`&;yT9LBvCE*xzNe^-E4CxbDRBJaN~jlSq|VjswDS1$X0~#=Lq&ga zCz+rAOpXJ}=@*Vw_-pAt>oj4i1@Xtt-Oowk-9QNMj)Y*HB&K4`iTsa2WPK#+q${0w zg!W?!)3XcxL8Yf>6#9nJ`D4X+Q{jsW-%$9r!fOgYRQQR)FBEb=InIv?e^L0SLLMmk uXB6&HxTJ7d;Yo#$D11WUrb18Qw!+sGzNPRTh3_l;TH*IZ6fvzQ&gs8hV_9GT literal 0 HcmV?d00001 diff --git a/110_master/110/os/os/linux/fs/fs.o b/110_master/110/os/os/linux/fs/fs.o new file mode 100644 index 0000000000000000000000000000000000000000..2349695695bbbdfedaff566aca9df867504e492d GIT binary patch literal 142933 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 z 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 RcGJMzRp~C5qy&x9`#(X^mgfKf literal 0 HcmV?d00001 diff --git a/110_master/110/os/os/linux/fs/inode.c b/110_master/110/os/os/linux/fs/inode.c new file mode 100644 index 0000000..9bb10b3 --- /dev/null +++ b/110_master/110/os/os/linux/fs/inode.c @@ -0,0 +1,340 @@ +/* + * linux/fs/inode.c + * + * (C) 1991 Linus Torvalds + */ + +#include +#include + +#include +#include +#include +#include + +struct m_inode inode_table[NR_INODE]={{0,},}; + +static void read_inode(struct m_inode * inode); +static void write_inode(struct m_inode * inode); + +static inline void wait_on_inode(struct m_inode * inode) +{ + cli(); + while (inode->i_lock) + sleep_on(&inode->i_wait); + sti(); +} + +static inline void lock_inode(struct m_inode * inode) +{ + cli(); + while (inode->i_lock) + sleep_on(&inode->i_wait); + inode->i_lock=1; + sti(); +} + +static inline void unlock_inode(struct m_inode * inode) +{ + inode->i_lock=0; + wake_up(&inode->i_wait); +} + +void invalidate_inodes(int dev) +{ + int i; + struct m_inode * inode; + + inode = 0+inode_table; + for(i=0 ; ii_dev == dev) { + if (inode->i_count) + printk("inode in use on removed disk\n\r"); + inode->i_dev = inode->i_dirt = 0; + } + } +} + +void sync_inodes(void) +{ + int i; + struct m_inode * inode; + + inode = 0+inode_table; + for(i=0 ; ii_dirt && !inode->i_pipe) + write_inode(inode); + } +} + +static int _bmap(struct m_inode * inode,int block,int create) +{ + struct buffer_head * bh; + int i; + + if (block<0) + panic("_bmap: block<0"); + if (block >= 7+512+512*512) + panic("_bmap: block>big"); + if (block<7) { + if (create && !inode->i_zone[block]) + if (inode->i_zone[block]=new_block(inode->i_dev)) { + inode->i_ctime=CURRENT_TIME; + inode->i_dirt=1; + } + return inode->i_zone[block]; + } + block -= 7; + if (block<512) { + if (create && !inode->i_zone[7]) + if (inode->i_zone[7]=new_block(inode->i_dev)) { + inode->i_dirt=1; + inode->i_ctime=CURRENT_TIME; + } + if (!inode->i_zone[7]) + return 0; + if (!(bh = bread(inode->i_dev,inode->i_zone[7]))) + return 0; + i = ((unsigned short *) (bh->b_data))[block]; + if (create && !i) + if (i=new_block(inode->i_dev)) { + ((unsigned short *) (bh->b_data))[block]=i; + bh->b_dirt=1; + } + brelse(bh); + return i; + } + block -= 512; + if (create && !inode->i_zone[8]) + if (inode->i_zone[8]=new_block(inode->i_dev)) { + inode->i_dirt=1; + inode->i_ctime=CURRENT_TIME; + } + if (!inode->i_zone[8]) + return 0; + if (!(bh=bread(inode->i_dev,inode->i_zone[8]))) + return 0; + i = ((unsigned short *)bh->b_data)[block>>9]; + if (create && !i) + if (i=new_block(inode->i_dev)) { + ((unsigned short *) (bh->b_data))[block>>9]=i; + bh->b_dirt=1; + } + brelse(bh); + if (!i) + return 0; + if (!(bh=bread(inode->i_dev,i))) + return 0; + i = ((unsigned short *)bh->b_data)[block&511]; + if (create && !i) + if (i=new_block(inode->i_dev)) { + ((unsigned short *) (bh->b_data))[block&511]=i; + bh->b_dirt=1; + } + brelse(bh); + return i; +} + +int bmap(struct m_inode * inode,int block) +{ + return _bmap(inode,block,0); +} + +int create_block(struct m_inode * inode, int block) +{ + return _bmap(inode,block,1); +} + +void iput(struct m_inode * inode) +{ + if (!inode) + return; + wait_on_inode(inode); + if (!inode->i_count) + panic("iput: trying to free free inode"); + if (inode->i_pipe) { + wake_up(&inode->i_wait); + if (--inode->i_count) + return; + free_page(inode->i_size); + inode->i_count=0; + inode->i_dirt=0; + inode->i_pipe=0; + return; + } + if (!inode->i_dev) { + inode->i_count--; + return; + } + if (S_ISBLK(inode->i_mode)) { + sync_dev(inode->i_zone[0]); + wait_on_inode(inode); + } +repeat: + if (inode->i_count>1) { + inode->i_count--; + return; + } + if (!inode->i_nlinks) { + truncate(inode); + free_inode(inode); + return; + } + if (inode->i_dirt) { + write_inode(inode); /* we can sleep - so do again */ + wait_on_inode(inode); + goto repeat; + } + inode->i_count--; + return; +} + +struct m_inode * get_empty_inode(void) +{ + struct m_inode * inode; + static struct m_inode * last_inode = inode_table; + int i; + + do { + inode = NULL; + for (i = NR_INODE; i ; i--) { + if (++last_inode >= inode_table + NR_INODE) + last_inode = inode_table; + if (!last_inode->i_count) { + inode = last_inode; + if (!inode->i_dirt && !inode->i_lock) + break; + } + } + if (!inode) { + for (i=0 ; ii_dirt) { + write_inode(inode); + wait_on_inode(inode); + } + } while (inode->i_count); + memset(inode,0,sizeof(*inode)); + inode->i_count = 1; + return inode; +} + +struct m_inode * get_pipe_inode(void) +{ + struct m_inode * inode; + + if (!(inode = get_empty_inode())) + return NULL; + if (!(inode->i_size=get_free_page())) { + inode->i_count = 0; + return NULL; + } + inode->i_count = 2; /* sum of readers/writers */ + PIPE_HEAD(*inode) = PIPE_TAIL(*inode) = 0; + inode->i_pipe = 1; + return inode; +} + +struct m_inode * iget(int dev,int nr) +{ + struct m_inode * inode, * empty; + + if (!dev) + panic("iget with dev==0"); + empty = get_empty_inode(); + inode = inode_table; + while (inode < NR_INODE+inode_table) { + if (inode->i_dev != dev || inode->i_num != nr) { + inode++; + continue; + } + wait_on_inode(inode); + if (inode->i_dev != dev || inode->i_num != nr) { + inode = inode_table; + continue; + } + inode->i_count++; + if (inode->i_mount) { + int i; + + for (i = 0 ; i= NR_SUPER) { + printk("Mounted inode hasn't got sb\n"); + if (empty) + iput(empty); + return inode; + } + iput(inode); + dev = super_block[i].s_dev; + nr = ROOT_INO; + inode = inode_table; + continue; + } + if (empty) + iput(empty); + return inode; + } + if (!empty) + return (NULL); + inode=empty; + inode->i_dev = dev; + inode->i_num = nr; + read_inode(inode); + return inode; +} + +static void read_inode(struct m_inode * inode) +{ + struct super_block * sb; + struct buffer_head * bh; + int block; + + lock_inode(inode); + if (!(sb=get_super(inode->i_dev))) + panic("trying to read inode without dev"); + block = 2 + sb->s_imap_blocks + sb->s_zmap_blocks + + (inode->i_num-1)/INODES_PER_BLOCK; + if (!(bh=bread(inode->i_dev,block))) + panic("unable to read i-node block"); + __asm__ volatile ("cld"); /* by wyj */ + *(struct d_inode *)inode = + ((struct d_inode *)bh->b_data) + [(inode->i_num-1)%INODES_PER_BLOCK]; + brelse(bh); + unlock_inode(inode); +} + +static void write_inode(struct m_inode * inode) +{ + struct super_block * sb; + struct buffer_head * bh; + int block; + + lock_inode(inode); + if (!inode->i_dirt || !inode->i_dev) { + unlock_inode(inode); + return; + } + if (!(sb=get_super(inode->i_dev))) + panic("trying to write inode without device"); + block = 2 + sb->s_imap_blocks + sb->s_zmap_blocks + + (inode->i_num-1)/INODES_PER_BLOCK; + if (!(bh=bread(inode->i_dev,block))) + panic("unable to read i-node block"); + __asm__ volatile ("cld"); /* by wyj */ + ((struct d_inode *)bh->b_data) + [(inode->i_num-1)%INODES_PER_BLOCK] = + *(struct d_inode *)inode; + bh->b_dirt=1; + inode->i_dirt=0; + brelse(bh); + unlock_inode(inode); +} diff --git a/110_master/110/os/os/linux/fs/inode.o b/110_master/110/os/os/linux/fs/inode.o new file mode 100644 index 0000000000000000000000000000000000000000..dd67bfa4d43e1073c47e0226043fc43f5f0e9153 GIT binary patch literal 14072 zcmc&)Ym`*gl|FUrcHOeNXd1e~21+QfTS5B;wAcZW1`$EPpn?jbMRoP9?vn1RvL3uf z5iN`q?F&~%Gc#&O^KueUv&M|Z&ddNB)S1kZxF#`KlQ_mlv?VbyMB@-A%=ewUZ*_I! zI9c;&?pjsf-uvvc_dfgVbMCpf>XwUFE%SIh%Dp_wtA;tH+Rt)Y+BD2m6IG2W{3>+f z*x3H1_2I(7aM7%P_mh(+Pm-swy$3A^``1Z zlYk_7Mi@Y9htBjOn%??0i!q->k&L}(Ccd2jqguTq#L(6`H0PsO7FxWxBs8prcw9$+ zeq8;IgTOP4dFVbvaVlFO9sBfAhtf{h)|*9fT*L$+!a9|gPS-h|>iVnEq0Mv9b2Q$s z7%3}3=Xx<9r1JC23=SKkPDtg>K;y6prY;mO8WbMssATGNZOXa`4ZVvz-HOyHICq@H zpwk-f@0iMjT}8$z;Nr-HO)XRVKV{5yA)}8V5ZC0NpR-v`FB$Nmk5Buwv@Lbgw(!)k zNNSO`Fd9c#`K-)2_9XDHW5S0mV z?R-|q&<;6kJ%pXg&nkte9tkjk;UesR_{Wnc3(o#X6~uOm$}7Vv2r;bk6+;`H8PFDP zKH==P&JLI7#?b*Q?hc1t82eG~dO9rINXeqda-=SdmDnmg_sEK&|8k;$LTTZ!9eZS} z4i7uE-Zg=3YUt&Xb|b5I!f4Y&kGl$7SPkm8N-b2Il*&)jM*BOe%6A6I%QyaWcvOXt zJzK_)wtDPZO7?b)!Dc&|WYJwJW%RLmjuJQLlG2w=XAtbr0XN4Upi+4+-+Dh?BE zxd4s_q4uGvqFQ9pedHwQv$~BbIeANRgdBDtVB9D4;zN4R+kJ5C?)_+nu2TWCh9~*1 z+V7(UH|9gH8x(@(H=A0Rb8i1m z4jLhAlYBJ0adF2a&C0p@sw)e>3V#B&wTPte|4=7=)NPVR;R?5FZi7#vyHi&5r3Z1> z8s3#TqdpADJ?6*+FF*8d1w=?Ey*SgUXJF*5rPdh?J^ax1z_@Dl8G?6lR?G6j>(dUs zUU65D4qJR5RXi$0eRPIrFEa=#As06k!;rUWsI? z%MK@!;e6H(r;_1}-Iv;8cZItW+0B75D$>~(P0tT^_NHQ+FK8XXUf7xFRw|Ls=jMlV zneB;WcQ}^{$1}F=d}+(7p|x$>{BXm(uG7?I(yAM>^x0?ksYJJ(3vW&2dcs}ymW2yj z)#_9}nL`9lWIfSr^6Xr=JCzG(JMm;N>?vbMT_tu;<#V*4^2umtugy>#g(f{fJphh= zxc}BnBFB+){AC6bFA?qgESwlLk{N@JOIPIrU{hrsn zj7BVO^X3{3SXn=Vz`UHaX*~cN<`ty<)>-IaUP(G=HBx7701Lf3aDqDPD6cjGFO#`? zE|^*)a3`5-ZUa+i1VZehnUE1!0GY#tjmplvjuz@-5Faj5GkeXRy1eW6*<1kB&%5JJ%OSNT2 zU=9svX1Ng<;t(`*sSzmB&qju`$_VgeVO~dOjS=_;`)FpZ5%}j4bBz&*vX5@rXapWC zwQMp11sb@XPP>fCTyDEEH!*KLMqmqDqHO6!4z?n;&Uer=Z3M1m)G;zSBk%yn(?w>R z5jey^ZRYwWBXE*VV-t-Eztc7g8*)azl<=yF+JD>61;+Xq7 zW7$R8XU(SRTS@z^U(n@kqyyG+(go%wX#IgUcT-+%orZ7k7wD?i;x6L7gLIpPGpX|K zq0U-sF>MwZ?ll&lx4nBwZ?t|&zx}ki$?9R>J2@v^)@thCwHWdqYZi6xCY`XxQhpEV z8&r_a-heSZ!Q2-q+!3;ocRQ3UyLhn7FW3PWl5hy+Vtf}pG(^Bizm{` zY$P4@#ba1oO{A-R@l;Bg&7^BVL*7EV&iXd&o2@h-QbCHi6!qY0RK-;o(Z8811*9~$x z$&Eg}pRFLh$y$wX^HS1XR*)H6xdi#_QNdqhvbq21)J{{ub3pSWsrH-Pc7joK>~N)q z8h0jod1@h44fuE->_Xf4t;mk2mbGl`Q)=8XwuIQ;q;>X`bV4Pam)WJ^3baqvI{QmH z4X#d2H73t#b^i8_jAr+1I4=|wo61^)rXt99?m zSfSKkI70tISO4^v7}0Vz&O@4hMef0^=;MrTxkNQSOtV_e*k_LC>k*gpPw4DXo=dqN zjeR|IwNhNEx~WXton&W#I#UO9pk(~c5yrI|jH|k*n1Frkb#bZJo26d+M)cBZ>{at9 z!uQC!v#Vyb)Un@FGP_`e*@Yv_ zUO3Y1qLSHZUw~Ds29aW^@s{;1*pmerK8?=C{tYBf#)Ayu2d;vprt|jZ{p$B1nLY$v zv;Pf{Gq}{Jd%5r3Nm6;nc^ax}D!o-xs>XT7`>IdJaO+iN<%JNTzmS*>bE5KA&97Wg zxuOOxYdqen%1W{xu)Zv!6iFAJ=wlJ$>;J@z_H_o{Gv;W4YEhH|VdGXgf~@vNw! z@iEiYikcSKshZ$9dlDtM!O>jx1aU@jjt$~H}ICErrEP- z(x)ocLQ$fp;)J#l>_o6K7`C21>}^HO2!D0u4o0<23WyQb=j2KxeLPmv6!BECqK2kJ zV!C3~K+ceXh}u*MNZ4t^?4n5*ARpo3fEP`o-Rb25YRouK=MQ&KOg4)^p>*VOpYq6d zq0vx9P#(`8tH$74|KP{cZfX^PoaYEUf)exqM7}^15b-|`|6JT;K1Mk&E|am>Bj6De%d+@%3@Gqeo)m|Df8lg5&rk3A5m>)12YS5)j zx^MU3%GC?~2b@oS{ovr>fw%n!*1tVaC~O!!zQMoJ-|`PH9dA7_IH*6zr>|a881NSc zUfQRvU=-dR&6>Q_=RGaQz>F{R%YP5Qjk)8baqIU6TeRnAo;>b9FtBp;$V}F zB=Fh=z}t8>7tQ1%_>OH>omztLXfCR{>}(A3Og@%VcCyP6W}}gKZxpATTqYW`Bb|vH zEhQpJl;`Fwh-fa+XREya#+hr5%J)UHn^ioT>#;KmZ-KfZeW2APm#qt56mDy7Z*B`W z^+hwWo`s3I?ejp#db`3+-QlKqsxOgiif5vIc2hcqw;y%}!UR3pP4Rp(mP@3PS%{LU zCLMlLI+M!Tv0N&n_&zD37X(7e+V*A@!|R%y4X%&xe-wP3uk5}w9%rGD*kLmdXzxwo zJrm!w#G%+l{d6L2BQY`E&E|u879-duo$_fr6LH@DFsoWAE-9i9H-Vjzq`fT{;p;1v zipL{4uDz_C17UBoWBDB4D(SafsuMF2VLA~~B%4N>@zRMaRll@iWKJxJ2r__NcRK!Y zx6Vd-Q{55Hu@jvh%!s~vvh(SP?wCk!iS{Ni*S3?YEayLwL1>XoS0t6}Wp1=4Uv-tz z$(In>o>V3m9$~sOlFry$oDpK;TNS=$!y=~wcJgUDDs56a5DWwWtewrG02SU;xRV^q>TG4jOQcWI%u(vs zfs(^$Z#2`VT6$7_c1tqfm1{|5o09fcXNzxYZJs^5sW;l$(&`9W@OV+mbgU2|uRF}7eC1tGd2`b&4 zNh@2=wcah<3F(cZDxH;;vC~*nN{2*KdO1m3c6&1BkgO`!zUswHAi_w5>B^;86uR2@ zhE{eVCwXE6HXcRiFK?ORz6mMUT`@mx^v*xDK@H}XtJvp9y?Kdxs)zH zNHca8I|Rho{#fjBvB@{lisiuqa|W1=#1olpj=Lcj6?!DHd6a^)2}oh^S!Q`E-t!YkPbF+8OZfkCBo8?Gxht>~oyyNewnK-|w zFXH1qby4np*9%KdtWN^nhbH=nh>sT`cOQ#fIc>d;kNfaLxp%Wi+hW@%__$9w+Rx=q z8)K`(nZ?~0NuE)inzP&cuw$rZ7O%!0m&(|^%{f+hGbvV! zYVO3Fg60g14vZGto%wFmRXnAdyEGl`?Br4`YmH{2$!@IMG7)cfZU^{N&9PKppN;!d za}xKuX52-cd!N(C?!o?x`y~eWXI}iH6H=l05Xy@+R(>{R8?Pz&;3=RDQ|~a%+Ag=Z3zNeBw8y@#J^e$5$N=gf?D1Dj_X-QaxEY5& zwgRa)!3`cf?eXfsr%bGVG)Af8c<6C2x9tK5%H!LE_}<0i662$LH$JXCw+~45BF_Dv zlnGq&`cZn%BcWk-kjvHE0KVLBdLACYAfsQDc*!qcowIxYr&O+7m7VbWIaopKN|?mQufkU;=1< z=$Cn?&vJWTYE?ciAtd`CGRBkCX3&c9!{ z_dK>gJgWVxqj>&B%Dw3C?_CB+{<%^7OQZOs;NANr{rw2Md!Ho#26*@WNdBEs{XZDR zpBTk^%ch+1RDpNzskFx*O5Ka?4dC7TD%yG4e>V~GpNpKo8B%^9knui1 z9`Sygh;jacSg+Iy988P`{OgE#7W9Z`EA?xj2fjWOJRx|Ji2PXCH`rcD1Ya%u8G@Td zzDMvOBI0-y$b3E}{CCMCu8C+faF5{6)5c63^@-;y^*E6I{*FBK_y-!cKM$neS-61^ zGem6Oe@R5!UjylfKR*~}Ds@=!=WK`GABgA|#7&>=lY!*#Am5C9lZTy$$;0mu5&8Y2 z$Q8~slrJPA&kqsN?+GCLJtgfYiRd>DTQ=nrf$X=5h3c;%cuM_MPyj^gw;QfM+3UYs@-Dd@l2)-itn&5ka z9|;<)cl6_aNt`Um-?_=p7hEQIg&@}t+iwuuB3KZ-SMVXhZwfvy_?qA`!H)&`o|Sf| z2{sBY6TDJzlVG3V4#7JFzbN>K;NyZX3cexu8^KQm_0Jpd&mZO)#|pu9g8W+u<$Z$N z1#cJJC-}JFvw}wiUlDvw@IAqg1P$y5w9kh_;$%VoiHAJ@8!+u12__af${wWdsIl|8qTq1ax;0D3CU`BAK z;9kM|1s@fBT<}@JBZ6-VzAtz}(8qm`@d-{9yh!jXf(HeEAovr(-wOJ<@4-&H;O_+g zB)AxR1lzg)alKz9ye+s{iCxY(^q70O0jC01NJ-zP&!;l-mcEL4*J%YOgza;pS;12}f62#F`+X)Hs97?-u I1a}MmH>)TywEzGB literal 0 HcmV?d00001 diff --git a/110_master/110/os/os/linux/fs/ioctl.c b/110_master/110/os/os/linux/fs/ioctl.c new file mode 100644 index 0000000..36fc976 --- /dev/null +++ b/110_master/110/os/os/linux/fs/ioctl.c @@ -0,0 +1,46 @@ +/* + * linux/fs/ioctl.c + * + * (C) 1991 Linus Torvalds + */ + +#include +#include +#include + +#include + +extern int tty_ioctl(int dev, int cmd, int arg); + +typedef int (*ioctl_ptr)(int dev,int cmd,int arg); + +#define NRDEVS ((sizeof (ioctl_table))/(sizeof (ioctl_ptr))) + +static ioctl_ptr ioctl_table[]={ + NULL, /* nodev */ + NULL, /* /dev/mem */ + NULL, /* /dev/fd */ + NULL, /* /dev/hd */ + tty_ioctl, /* /dev/ttyx */ + tty_ioctl, /* /dev/tty */ + NULL, /* /dev/lp */ + NULL}; /* named pipes */ + + +int sys_ioctl(unsigned int fd, unsigned int cmd, unsigned long arg) +{ + struct file * filp; + int dev,mode; + + if (fd >= NR_OPEN || !(filp = current->filp[fd])) + return -EBADF; + mode=filp->f_inode->i_mode; + if (!S_ISCHR(mode) && !S_ISBLK(mode)) + return -EINVAL; + dev = filp->f_inode->i_zone[0]; + if (MAJOR(dev) >= NRDEVS) + return -ENODEV; + if (!ioctl_table[MAJOR(dev)]) + return -ENOTTY; + return ioctl_table[MAJOR(dev)](dev,cmd,arg); +} diff --git a/110_master/110/os/os/linux/fs/ioctl.o b/110_master/110/os/os/linux/fs/ioctl.o new file mode 100644 index 0000000000000000000000000000000000000000..1f1f33c5568ad7f154251149e1ecc40766da48c1 GIT binary patch literal 5828 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 +#include +#include + +#include +#include +#include +#include +#include + +#define ACC_MODE(x) ("\004\002\006\377"[(x)&O_ACCMODE]) + +/* + * comment out this line if you want names > NAME_LEN chars to be + * truncated. Else they will be disallowed. + */ +/* #define NO_TRUNCATE */ + +#define MAY_EXEC 1 +#define MAY_WRITE 2 +#define MAY_READ 4 + +/* + * permission() + * + * is used to check for read/write/execute permissions on a file. + * I don't know if we should look at just the euid or both euid and + * uid, but that should be easily changed. + */ +static int permission(struct m_inode * inode,int mask) +{ + int mode = inode->i_mode; + +/* special case: not even root can read/write a deleted file */ + if (inode->i_dev && !inode->i_nlinks) + return 0; + else if (current->euid==inode->i_uid) + mode >>= 6; + else if (current->egid==inode->i_gid) + mode >>= 3; + if (((mode & mask & 0007) == mask) || suser()) + return 1; + return 0; +} + +/* + * ok, we cannot use strncmp, as the name is not in our data space. + * Thus we'll have to use match. No big problem. Match also makes + * some sanity tests. + * + * NOTE! unlike strncmp, match returns 1 for success, 0 for failure. + */ +static int match(int len,const char * name,struct dir_entry * de) +{ + register int same __asm__("ax"); + + if (!de || !de->inode || len > NAME_LEN) + return 0; + if (len < NAME_LEN && de->name[len]) + return 0; + __asm__("cld\n\t" + "fs ; repe ; cmpsb\n\t" + "setz %%al" + :"=a" (same) + :"0" (0),"S" ((long) name),"D" ((long) de->name),"c" (len) + ); + return same; +} + +/* + * find_entry() + * + * finds an entry in the specified directory with the wanted name. It + * returns the cache buffer in which the entry was found, and the entry + * itself (as a parameter - res_dir). It does NOT read the inode of the + * entry - you'll have to do that yourself if you want to. + * + * This also takes care of the few special cases due to '..'-traversal + * over a pseudo-root and a mount point. + */ +static struct buffer_head * find_entry(struct m_inode ** dir, + const char * name, int namelen, struct dir_entry ** res_dir) +{ + int entries; + int block,i; + struct buffer_head * bh; + struct dir_entry * de; + struct super_block * sb; + +#ifdef NO_TRUNCATE + if (namelen > NAME_LEN) + return NULL; +#else + if (namelen > NAME_LEN) + namelen = NAME_LEN; +#endif + entries = (*dir)->i_size / (sizeof (struct dir_entry)); + *res_dir = NULL; + if (!namelen) + return NULL; +/* check for '..', as we might have to do some "magic" for it */ + if (namelen==2 && get_fs_byte(name)=='.' && get_fs_byte(name+1)=='.') { +/* '..' in a pseudo-root results in a faked '.' (just change namelen) */ + if ((*dir) == current->root) + namelen=1; + else if ((*dir)->i_num == ROOT_INO) { +/* '..' over a mount-point results in 'dir' being exchanged for the mounted + directory-inode. NOTE! We set mounted, so that we can iput the new dir */ + sb=get_super((*dir)->i_dev); + if (sb->s_imount) { + iput(*dir); + (*dir)=sb->s_imount; + (*dir)->i_count++; + } + } + } + if (!(block = (*dir)->i_zone[0])) + return NULL; + if (!(bh = bread((*dir)->i_dev,block))) + return NULL; + i = 0; + de = (struct dir_entry *) bh->b_data; + while (i < entries) { + if ((char *)de >= BLOCK_SIZE+bh->b_data) { + brelse(bh); + bh = NULL; + if (!(block = bmap(*dir,i/DIR_ENTRIES_PER_BLOCK)) || + !(bh = bread((*dir)->i_dev,block))) { + i += DIR_ENTRIES_PER_BLOCK; + continue; + } + de = (struct dir_entry *) bh->b_data; + } + if (match(namelen,name,de)) { + *res_dir = de; + return bh; + } + de++; + i++; + } + brelse(bh); + return NULL; +} + +/* + * add_entry() + * + * adds a file entry to the specified directory, using the same + * semantics as find_entry(). It returns NULL if it failed. + * + * NOTE!! The inode part of 'de' is left at 0 - which means you + * may not sleep between calling this and putting something into + * the entry, as someone else might have used it while you slept. + */ +static struct buffer_head * add_entry(struct m_inode * dir, + const char * name, int namelen, struct dir_entry ** res_dir) +{ + int block,i; + struct buffer_head * bh; + struct dir_entry * de; + + *res_dir = NULL; +#ifdef NO_TRUNCATE + if (namelen > NAME_LEN) + return NULL; +#else + if (namelen > NAME_LEN) + namelen = NAME_LEN; +#endif + if (!namelen) + return NULL; + if (!(block = dir->i_zone[0])) + return NULL; + if (!(bh = bread(dir->i_dev,block))) + return NULL; + i = 0; + de = (struct dir_entry *) bh->b_data; + while (1) { + if ((char *)de >= BLOCK_SIZE+bh->b_data) { + brelse(bh); + bh = NULL; + block = create_block(dir,i/DIR_ENTRIES_PER_BLOCK); + if (!block) + return NULL; + if (!(bh = bread(dir->i_dev,block))) { + i += DIR_ENTRIES_PER_BLOCK; + continue; + } + de = (struct dir_entry *) bh->b_data; + } + if (i*sizeof(struct dir_entry) >= dir->i_size) { + de->inode=0; + dir->i_size = (i+1)*sizeof(struct dir_entry); + dir->i_dirt = 1; + dir->i_ctime = CURRENT_TIME; + } + if (!de->inode) { + dir->i_mtime = CURRENT_TIME; + for (i=0; i < NAME_LEN ; i++) + de->name[i]=(ib_dirt = 1; + *res_dir = de; + return bh; + } + de++; + i++; + } + brelse(bh); + return NULL; +} + +/* + * get_dir() + * + * Getdir traverses the pathname until it hits the topmost directory. + * It returns NULL on failure. + */ +static struct m_inode * get_dir(const char * pathname) +{ + char c; + const char * thisname; + struct m_inode * inode; + struct buffer_head * bh; + int namelen,inr,idev; + struct dir_entry * de; + + if (!current->root || !current->root->i_count) + panic("No root inode"); + if (!current->pwd || !current->pwd->i_count) + panic("No cwd inode"); + if ((c=get_fs_byte(pathname))=='/') { + inode = current->root; + pathname++; + } else if (c) + inode = current->pwd; + else + return NULL; /* empty name is bad */ + inode->i_count++; + while (1) { + thisname = pathname; + if (!S_ISDIR(inode->i_mode) || !permission(inode,MAY_EXEC)) { + iput(inode); + return NULL; + } + for(namelen=0;(c=get_fs_byte(pathname++))&&(c!='/');namelen++) + /* nothing */ ; + if (!c) + return inode; + if (!(bh = find_entry(&inode,thisname,namelen,&de))) { + iput(inode); + return NULL; + } + inr = de->inode; + idev = inode->i_dev; + brelse(bh); + iput(inode); + if (!(inode = iget(idev,inr))) + return NULL; + } +} + +/* + * dir_namei() + * + * dir_namei() returns the inode of the directory of the + * specified name, and the name within that directory. + */ +static struct m_inode * dir_namei(const char * pathname, + int * namelen, const char ** name) +{ + char c; + const char * basename; + struct m_inode * dir; + + if (!(dir = get_dir(pathname))) + return NULL; + basename = pathname; + while (c=get_fs_byte(pathname++)) + if (c=='/') + basename=pathname; + *namelen = pathname-basename-1; + *name = basename; + return dir; +} + +/* + * namei() + * + * is used by most simple commands to get the inode of a specified name. + * Open, link etc use their own routines, but this is enough for things + * like 'chmod' etc. + */ +struct m_inode * namei(const char * pathname) +{ + const char * basename; + int inr,dev,namelen; + struct m_inode * dir; + struct buffer_head * bh; + struct dir_entry * de; + + if (!(dir = dir_namei(pathname,&namelen,&basename))) + return NULL; + if (!namelen) /* special case: '/usr/' etc */ + return dir; + bh = find_entry(&dir,basename,namelen,&de); + if (!bh) { + iput(dir); + return NULL; + } + inr = de->inode; + dev = dir->i_dev; + brelse(bh); + iput(dir); + dir=iget(dev,inr); + if (dir) { + dir->i_atime=CURRENT_TIME; + dir->i_dirt=1; + } + return dir; +} + +/* + * open_namei() + * + * namei for open - this is in fact almost the whole open-routine. + */ +int open_namei(const char * pathname, int flag, int mode, + struct m_inode ** res_inode) +{ + const char * basename; + int inr,dev,namelen; + struct m_inode * dir, *inode; + struct buffer_head * bh; + struct dir_entry * de; + + if ((flag & O_TRUNC) && !(flag & O_ACCMODE)) + flag |= O_WRONLY; + mode &= 0777 & ~current->umask; + mode |= I_REGULAR; + if (!(dir = dir_namei(pathname,&namelen,&basename))) + return -ENOENT; + if (!namelen) { /* special case: '/usr/' etc */ + if (!(flag & (O_ACCMODE|O_CREAT|O_TRUNC))) { + *res_inode=dir; + return 0; + } + iput(dir); + return -EISDIR; + } + bh = find_entry(&dir,basename,namelen,&de); + if (!bh) { + if (!(flag & O_CREAT)) { + iput(dir); + return -ENOENT; + } + if (!permission(dir,MAY_WRITE)) { + iput(dir); + return -EACCES; + } + inode = new_inode(dir->i_dev); + if (!inode) { + iput(dir); + return -ENOSPC; + } + inode->i_uid = current->euid; + inode->i_mode = mode; + inode->i_dirt = 1; + bh = add_entry(dir,basename,namelen,&de); + if (!bh) { + inode->i_nlinks--; + iput(inode); + iput(dir); + return -ENOSPC; + } + de->inode = inode->i_num; + bh->b_dirt = 1; + brelse(bh); + iput(dir); + *res_inode = inode; + return 0; + } + inr = de->inode; + dev = dir->i_dev; + brelse(bh); + iput(dir); + if (flag & O_EXCL) + return -EEXIST; + if (!(inode=iget(dev,inr))) + return -EACCES; + if ((S_ISDIR(inode->i_mode) && (flag & O_ACCMODE)) || + !permission(inode,ACC_MODE(flag))) { + iput(inode); + return -EPERM; + } + inode->i_atime = CURRENT_TIME; + if (flag & O_TRUNC) + truncate(inode); + *res_inode = inode; + return 0; +} + +int sys_mknod(const char * filename, int mode, int dev) +{ + const char * basename; + int namelen; + struct m_inode * dir, * inode; + struct buffer_head * bh; + struct dir_entry * de; + + if (!suser()) + return -EPERM; + if (!(dir = dir_namei(filename,&namelen,&basename))) + return -ENOENT; + if (!namelen) { + iput(dir); + return -ENOENT; + } + if (!permission(dir,MAY_WRITE)) { + iput(dir); + return -EPERM; + } + bh = find_entry(&dir,basename,namelen,&de); + if (bh) { + brelse(bh); + iput(dir); + return -EEXIST; + } + inode = new_inode(dir->i_dev); + if (!inode) { + iput(dir); + return -ENOSPC; + } + inode->i_mode = mode; + if (S_ISBLK(mode) || S_ISCHR(mode)) + inode->i_zone[0] = dev; + inode->i_mtime = inode->i_atime = CURRENT_TIME; + inode->i_dirt = 1; + bh = add_entry(dir,basename,namelen,&de); + if (!bh) { + iput(dir); + inode->i_nlinks=0; + iput(inode); + return -ENOSPC; + } + de->inode = inode->i_num; + bh->b_dirt = 1; + iput(dir); + iput(inode); + brelse(bh); + return 0; +} + +int sys_mkdir(const char * pathname, int mode) +{ + const char * basename; + int namelen; + struct m_inode * dir, * inode; + struct buffer_head * bh, *dir_block; + struct dir_entry * de; + + if (!suser()) + return -EPERM; + if (!(dir = dir_namei(pathname,&namelen,&basename))) + return -ENOENT; + if (!namelen) { + iput(dir); + return -ENOENT; + } + if (!permission(dir,MAY_WRITE)) { + iput(dir); + return -EPERM; + } + bh = find_entry(&dir,basename,namelen,&de); + if (bh) { + brelse(bh); + iput(dir); + return -EEXIST; + } + inode = new_inode(dir->i_dev); + if (!inode) { + iput(dir); + return -ENOSPC; + } + inode->i_size = 32; + inode->i_dirt = 1; + inode->i_mtime = inode->i_atime = CURRENT_TIME; + if (!(inode->i_zone[0]=new_block(inode->i_dev))) { + iput(dir); + inode->i_nlinks--; + iput(inode); + return -ENOSPC; + } + inode->i_dirt = 1; + if (!(dir_block=bread(inode->i_dev,inode->i_zone[0]))) { + iput(dir); + free_block(inode->i_dev,inode->i_zone[0]); + inode->i_nlinks--; + iput(inode); + return -ERROR; + } + de = (struct dir_entry *) dir_block->b_data; + de->inode=inode->i_num; + strcpy(de->name,"."); + de++; + de->inode = dir->i_num; + strcpy(de->name,".."); + inode->i_nlinks = 2; + dir_block->b_dirt = 1; + brelse(dir_block); + inode->i_mode = I_DIRECTORY | (mode & 0777 & ~current->umask); + inode->i_dirt = 1; + bh = add_entry(dir,basename,namelen,&de); + if (!bh) { + iput(dir); + free_block(inode->i_dev,inode->i_zone[0]); + inode->i_nlinks=0; + iput(inode); + return -ENOSPC; + } + de->inode = inode->i_num; + bh->b_dirt = 1; + dir->i_nlinks++; + dir->i_dirt = 1; + iput(dir); + iput(inode); + brelse(bh); + return 0; +} + +/* + * routine to check that the specified directory is empty (for rmdir) + */ +static int empty_dir(struct m_inode * inode) +{ + int nr,block; + int len; + struct buffer_head * bh; + struct dir_entry * de; + + len = inode->i_size / sizeof (struct dir_entry); + if (len<2 || !inode->i_zone[0] || + !(bh=bread(inode->i_dev,inode->i_zone[0]))) { + printk("warning - bad directory on dev %04x\n",inode->i_dev); + return 0; + } + de = (struct dir_entry *) bh->b_data; + if (de[0].inode != inode->i_num || !de[1].inode || + strcmp(".",de[0].name) || strcmp("..",de[1].name)) { + printk("warning - bad directory on dev %04x\n",inode->i_dev); + return 0; + } + nr = 2; + de += 2; + while (nr= (void *) (bh->b_data+BLOCK_SIZE)) { + brelse(bh); + block=bmap(inode,nr/DIR_ENTRIES_PER_BLOCK); + if (!block) { + nr += DIR_ENTRIES_PER_BLOCK; + continue; + } + if (!(bh=bread(inode->i_dev,block))) + return 0; + de = (struct dir_entry *) bh->b_data; + } + if (de->inode) { + brelse(bh); + return 0; + } + de++; + nr++; + } + brelse(bh); + return 1; +} + +int sys_rmdir(const char * name) +{ + const char * basename; + int namelen; + struct m_inode * dir, * inode; + struct buffer_head * bh; + struct dir_entry * de; + + if (!suser()) + return -EPERM; + if (!(dir = dir_namei(name,&namelen,&basename))) + return -ENOENT; + if (!namelen) { + iput(dir); + return -ENOENT; + } + if (!permission(dir,MAY_WRITE)) { + iput(dir); + return -EPERM; + } + bh = find_entry(&dir,basename,namelen,&de); + if (!bh) { + iput(dir); + return -ENOENT; + } + if (!(inode = iget(dir->i_dev, de->inode))) { + iput(dir); + brelse(bh); + return -EPERM; + } + if ((dir->i_mode & S_ISVTX) && current->euid && + inode->i_uid != current->euid) { + iput(dir); + iput(inode); + brelse(bh); + return -EPERM; + } + if (inode->i_dev != dir->i_dev || inode->i_count>1) { + iput(dir); + iput(inode); + brelse(bh); + return -EPERM; + } + if (inode == dir) { /* we may not delete ".", but "../dir" is ok */ + iput(inode); + iput(dir); + brelse(bh); + return -EPERM; + } + if (!S_ISDIR(inode->i_mode)) { + iput(inode); + iput(dir); + brelse(bh); + return -ENOTDIR; + } + if (!empty_dir(inode)) { + iput(inode); + iput(dir); + brelse(bh); + return -ENOTEMPTY; + } + if (inode->i_nlinks != 2) + printk("empty directory has nlink!=2 (%d)",inode->i_nlinks); + de->inode = 0; + bh->b_dirt = 1; + brelse(bh); + inode->i_nlinks=0; + inode->i_dirt=1; + dir->i_nlinks--; + dir->i_ctime = dir->i_mtime = CURRENT_TIME; + dir->i_dirt=1; + iput(dir); + iput(inode); + return 0; +} + +int sys_unlink(const char * name) +{ + const char * basename; + int namelen; + struct m_inode * dir, * inode; + struct buffer_head * bh; + struct dir_entry * de; + + if (!(dir = dir_namei(name,&namelen,&basename))) + return -ENOENT; + if (!namelen) { + iput(dir); + return -ENOENT; + } + if (!permission(dir,MAY_WRITE)) { + iput(dir); + return -EPERM; + } + bh = find_entry(&dir,basename,namelen,&de); + if (!bh) { + iput(dir); + return -ENOENT; + } + if (!(inode = iget(dir->i_dev, de->inode))) { + iput(dir); + brelse(bh); + return -ENOENT; + } + if ((dir->i_mode & S_ISVTX) && !suser() && + current->euid != inode->i_uid && + current->euid != dir->i_uid) { + iput(dir); + iput(inode); + brelse(bh); + return -EPERM; + } + if (S_ISDIR(inode->i_mode)) { + iput(inode); + iput(dir); + brelse(bh); + return -EPERM; + } + if (!inode->i_nlinks) { + printk("Deleting nonexistent file (%04x:%d), %d\n", + inode->i_dev,inode->i_num,inode->i_nlinks); + inode->i_nlinks=1; + } + de->inode = 0; + bh->b_dirt = 1; + brelse(bh); + inode->i_nlinks--; + inode->i_dirt = 1; + inode->i_ctime = CURRENT_TIME; + iput(inode); + iput(dir); + return 0; +} + +int sys_symlink() +{ + return -ENOSYS; +} + +int sys_link(const char * oldname, const char * newname) +{ + struct dir_entry * de; + struct m_inode * oldinode, * dir; + struct buffer_head * bh; + const char * basename; + int namelen; + + oldinode=namei(oldname); + if (!oldinode) + return -ENOENT; + if (S_ISDIR(oldinode->i_mode)) { + iput(oldinode); + return -EPERM; + } + dir = dir_namei(newname,&namelen,&basename); + if (!dir) { + iput(oldinode); + return -EACCES; + } + if (!namelen) { + iput(oldinode); + iput(dir); + return -EPERM; + } + if (dir->i_dev != oldinode->i_dev) { + iput(dir); + iput(oldinode); + return -EXDEV; + } + if (!permission(dir,MAY_WRITE)) { + iput(dir); + iput(oldinode); + return -EACCES; + } + bh = find_entry(&dir,basename,namelen,&de); + if (bh) { + brelse(bh); + iput(dir); + iput(oldinode); + return -EEXIST; + } + bh = add_entry(dir,basename,namelen,&de); + if (!bh) { + iput(dir); + iput(oldinode); + return -ENOSPC; + } + de->inode = oldinode->i_num; + bh->b_dirt = 1; + brelse(bh); + iput(dir); + oldinode->i_nlinks++; + oldinode->i_ctime = CURRENT_TIME; + oldinode->i_dirt = 1; + iput(oldinode); + return 0; +} diff --git a/110_master/110/os/os/linux/fs/namei.o b/110_master/110/os/os/linux/fs/namei.o new file mode 100644 index 0000000000000000000000000000000000000000..0514463113d5878e35d040844344865d47c7032e GIT binary patch literal 20756 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 a@7aEaV1r +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +int sys_ustat(int dev, struct ustat * ubuf) +{ + return -ENOSYS; +} + +int sys_utime(char * filename, struct utimbuf * times) +{ + struct m_inode * inode; + long actime,modtime; + + if (!(inode=namei(filename))) + return -ENOENT; + if (times) { + actime = get_fs_long((unsigned long *) ×->actime); + modtime = get_fs_long((unsigned long *) ×->modtime); + } else + actime = modtime = CURRENT_TIME; + inode->i_atime = actime; + inode->i_mtime = modtime; + inode->i_dirt = 1; + iput(inode); + return 0; +} + +/* + * XXX should we use the real or effective uid? BSD uses the real uid, + * so as to make this call useful to setuid programs. + */ +int sys_access(const char * filename,int mode) +{ + struct m_inode * inode; + int res, i_mode; + + mode &= 0007; + if (!(inode=namei(filename))) + return -EACCES; + i_mode = res = inode->i_mode & 0777; + iput(inode); + if (current->uid == inode->i_uid) + res >>= 6; + else if (current->gid == inode->i_gid) + res >>= 6; + if ((res & 0007 & mode) == mode) + return 0; + /* + * XXX we are doing this test last because we really should be + * swapping the effective with the real user id (temporarily), + * and then calling suser() routine. If we do call the + * suser() routine, it needs to be called last. + */ + if ((!current->uid) && + (!(mode & 1) || (i_mode & 0111))) + return 0; + return -EACCES; +} + +int sys_chdir(const char * filename) +{ + struct m_inode * inode; + + if (!(inode = namei(filename))) + return -ENOENT; + if (!S_ISDIR(inode->i_mode)) { + iput(inode); + return -ENOTDIR; + } + iput(current->pwd); + current->pwd = inode; + return (0); +} + +int sys_chroot(const char * filename) +{ + struct m_inode * inode; + + if (!(inode=namei(filename))) + return -ENOENT; + if (!S_ISDIR(inode->i_mode)) { + iput(inode); + return -ENOTDIR; + } + iput(current->root); + current->root = inode; + return (0); +} + +int sys_chmod(const char * filename,int mode) +{ + struct m_inode * inode; + + if (!(inode=namei(filename))) + return -ENOENT; + if ((current->euid != inode->i_uid) && !suser()) { + iput(inode); + return -EACCES; + } + inode->i_mode = (mode & 07777) | (inode->i_mode & ~07777); + inode->i_dirt = 1; + iput(inode); + return 0; +} + +int sys_chown(const char * filename,int uid,int gid) +{ + struct m_inode * inode; + + if (!(inode=namei(filename))) + return -ENOENT; + if (!suser()) { + iput(inode); + return -EACCES; + } + inode->i_uid=uid; + inode->i_gid=gid; + inode->i_dirt=1; + iput(inode); + return 0; +} + +int sys_open(const char * filename,int flag,int mode) +{ + struct m_inode * inode; + struct file * f; + int i,fd; + + mode &= 0777 & ~current->umask; + for(fd=0 ; fdfilp[fd]) + break; + if (fd>=NR_OPEN) + return -EINVAL; + current->close_on_exec &= ~(1<f_count) break; + if (i>=NR_FILE) + return -EINVAL; + (current->filp[fd]=f)->f_count++; + if ((i=open_namei(filename,flag,mode,&inode))<0) { + current->filp[fd]=NULL; + f->f_count=0; + return i; + } +/* ttys are somewhat special (ttyxx major==4, tty major==5) */ + if (S_ISCHR(inode->i_mode)) + if (MAJOR(inode->i_zone[0])==4) { + if (current->leader && current->tty<0) { + current->tty = MINOR(inode->i_zone[0]); + tty_table[current->tty].pgrp = current->pgrp; + } + } else if (MAJOR(inode->i_zone[0])==5) + if (current->tty<0) { + iput(inode); + current->filp[fd]=NULL; + f->f_count=0; + return -EPERM; + } +/* Likewise with block-devices: check for floppy_change */ + if (S_ISBLK(inode->i_mode)) + check_disk_change(inode->i_zone[0]); + f->f_mode = inode->i_mode; + f->f_flags = flag; + f->f_count = 1; + f->f_inode = inode; + f->f_pos = 0; + return (fd); +} + +int sys_creat(const char * pathname, int mode) +{ + return sys_open(pathname, O_CREAT | O_TRUNC, mode); +} + +int sys_close(unsigned int fd) +{ + struct file * filp; + + if (fd >= NR_OPEN) + return -EINVAL; + current->close_on_exec &= ~(1<filp[fd])) + return -EINVAL; + current->filp[fd] = NULL; + if (filp->f_count == 0) + panic("Close: file count is 0"); + if (--filp->f_count) + return (0); + iput(filp->f_inode); + return (0); +} diff --git a/110_master/110/os/os/linux/fs/open.o b/110_master/110/os/os/linux/fs/open.o new file mode 100644 index 0000000000000000000000000000000000000000..aceb4b8d44365ee59ea3c9bb01413542e9cf0177 GIT binary patch literal 11184 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 literal 0 HcmV?d00001 diff --git a/110_master/110/os/os/linux/fs/pipe.c b/110_master/110/os/os/linux/fs/pipe.c new file mode 100644 index 0000000..dfc4480 --- /dev/null +++ b/110_master/110/os/os/linux/fs/pipe.c @@ -0,0 +1,111 @@ +/* + * linux/fs/pipe.c + * + * (C) 1991 Linus Torvalds + */ + +#include + +#include +#include /* for get_free_page */ +#include + +int read_pipe(struct m_inode * inode, char * buf, int count) +{ + int chars, size, read = 0; + + while (count>0) { + while (!(size=PIPE_SIZE(*inode))) { + wake_up(&inode->i_wait); + if (inode->i_count != 2) /* are there any writers? */ + return read; + sleep_on(&inode->i_wait); + } + chars = PAGE_SIZE-PIPE_TAIL(*inode); + if (chars > count) + chars = count; + if (chars > size) + chars = size; + count -= chars; + read += chars; + size = PIPE_TAIL(*inode); + PIPE_TAIL(*inode) += chars; + PIPE_TAIL(*inode) &= (PAGE_SIZE-1); + while (chars-->0) + put_fs_byte(((char *)inode->i_size)[size++],buf++); + } + wake_up(&inode->i_wait); + return read; +} + +int write_pipe(struct m_inode * inode, char * buf, int count) +{ + int chars, size, written = 0; + + while (count>0) { + while (!(size=(PAGE_SIZE-1)-PIPE_SIZE(*inode))) { + wake_up(&inode->i_wait); + if (inode->i_count != 2) { /* no readers */ + current->signal |= (1<<(SIGPIPE-1)); + return written?written:-1; + } + sleep_on(&inode->i_wait); + } + chars = PAGE_SIZE-PIPE_HEAD(*inode); + if (chars > count) + chars = count; + if (chars > size) + chars = size; + count -= chars; + written += chars; + size = PIPE_HEAD(*inode); + PIPE_HEAD(*inode) += chars; + PIPE_HEAD(*inode) &= (PAGE_SIZE-1); + while (chars-->0) + ((char *)inode->i_size)[size++]=get_fs_byte(buf++); + } + wake_up(&inode->i_wait); + return written; +} + +int sys_pipe(unsigned long * fildes) +{ + struct m_inode * inode; + struct file * f[2]; + int fd[2]; + int i,j; + + j=0; + for(i=0;j<2 && if_count++; + if (j==1) + f[0]->f_count=0; + if (j<2) + return -1; + j=0; + for(i=0;j<2 && ifilp[i]) { + current->filp[ fd[j]=i ] = f[j]; + j++; + } + if (j==1) + current->filp[fd[0]]=NULL; + if (j<2) { + f[0]->f_count=f[1]->f_count=0; + return -1; + } + if (!(inode=get_pipe_inode())) { + current->filp[fd[0]] = + current->filp[fd[1]] = NULL; + f[0]->f_count = f[1]->f_count = 0; + return -1; + } + f[0]->f_inode = f[1]->f_inode = inode; + f[0]->f_pos = f[1]->f_pos = 0; + f[0]->f_mode = 1; /* read */ + f[1]->f_mode = 2; /* write */ + put_fs_long(fd[0],0+fildes); + put_fs_long(fd[1],1+fildes); + return 0; +} diff --git a/110_master/110/os/os/linux/fs/pipe.o b/110_master/110/os/os/linux/fs/pipe.o new file mode 100644 index 0000000000000000000000000000000000000000..d5b5db26c38f6881a408d3b6291aeb9d28c67659 GIT binary patch literal 8104 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 Jg} +#include +#include + +#include +#include +#include + +extern int rw_char(int rw,int dev, char * buf, int count, off_t * pos); +extern int read_pipe(struct m_inode * inode, char * buf, int count); +extern int write_pipe(struct m_inode * inode, char * buf, int count); +extern int block_read(int dev, off_t * pos, char * buf, int count); +extern int block_write(int dev, off_t * pos, char * buf, int count); +extern int file_read(struct m_inode * inode, struct file * filp, + char * buf, int count); +extern int file_write(struct m_inode * inode, struct file * filp, + char * buf, int count); + +int sys_lseek(unsigned int fd,off_t offset, int origin) +{ + struct file * file; + int tmp; + + if (fd >= NR_OPEN || !(file=current->filp[fd]) || !(file->f_inode) + || !IS_SEEKABLE(MAJOR(file->f_inode->i_dev))) + return -EBADF; + if (file->f_inode->i_pipe) + return -ESPIPE; + switch (origin) { + case 0: + if (offset<0) return -EINVAL; + file->f_pos=offset; + break; + case 1: + if (file->f_pos+offset<0) return -EINVAL; + file->f_pos += offset; + break; + case 2: + if ((tmp=file->f_inode->i_size+offset) < 0) + return -EINVAL; + file->f_pos = tmp; + break; + default: + return -EINVAL; + } + return file->f_pos; +} + +int sys_read(unsigned int fd,char * buf,int count) +{ + struct file * file; + struct m_inode * inode; + + if (fd>=NR_OPEN || count<0 || !(file=current->filp[fd])) + return -EINVAL; + if (!count) + return 0; + verify_area(buf,count); + inode = file->f_inode; + if (inode->i_pipe) + return (file->f_mode&1)?read_pipe(inode,buf,count):-EIO; + if (S_ISCHR(inode->i_mode)) + return rw_char(READ,inode->i_zone[0],buf,count,&file->f_pos); + if (S_ISBLK(inode->i_mode)) + return block_read(inode->i_zone[0],&file->f_pos,buf,count); + if (S_ISDIR(inode->i_mode) || S_ISREG(inode->i_mode)) { + if (count+file->f_pos > inode->i_size) + count = inode->i_size - file->f_pos; + if (count<=0) + return 0; + return file_read(inode,file,buf,count); + } + printk("(Read)inode->i_mode=%06o\n\r",inode->i_mode); + return -EINVAL; +} + +int sys_write(unsigned int fd,char * buf,int count) +{ + struct file * file; + struct m_inode * inode; + + if (fd>=NR_OPEN || count <0 || !(file=current->filp[fd])) + return -EINVAL; + if (!count) + return 0; + inode=file->f_inode; + if (inode->i_pipe) + return (file->f_mode&2)?write_pipe(inode,buf,count):-EIO; + if (S_ISCHR(inode->i_mode)) + return rw_char(WRITE,inode->i_zone[0],buf,count,&file->f_pos); + if (S_ISBLK(inode->i_mode)) + return block_write(inode->i_zone[0],&file->f_pos,buf,count); + if (S_ISREG(inode->i_mode)) + return file_write(inode,file,buf,count); + printk("(Write)inode->i_mode=%06o\n\r",inode->i_mode); + return -EINVAL; +} diff --git a/110_master/110/os/os/linux/fs/read_write.o b/110_master/110/os/os/linux/fs/read_write.o new file mode 100644 index 0000000000000000000000000000000000000000..998aad95c9e243e4bfcae9647b34d9235f717844 GIT binary patch literal 7520 zcmbVQYiu0Xb-wf1;mmSLQCvzEBRN?cD{Ezw%cVq1v`kvGMN5?Yh^&V#Id)e2nB}gu zukOx@q+v9+7!{=nR}lg_n!NhJNvN*AKtHNnh1&}46z~!@%^Y@GbSM+Hi&+) z_;%mobMb-b+=o9$?eekszzdgui_HAQ(sVq6%82lGEQ2mj+2<~K+Z0`%8Y+DCs$GC; zV2x_=J>yLH^>=UFxN+@EjO6>iI5qb1OJ4Z(A5i~kU%zGXJdej%Du+ZXEIWMdE6BC9h62MA z*FFygV$Ps-_G5ajP3=Mn;$%Hxqn(z}dF12FaS1v7nUqezq2$`NXa9Tx3EU5_B zL$CjYX`J?3NG#KDtN2$TCPhq$*1Zh&l1x{kusqd^+NERhKFsb6Fan$gvIpkZ%{V(N zJ9h0yU~pX(?-b(gl<{Vm{vh7}iuG{ZTvFY;_QjjTnG(X=ur~Pf2%cx~W!c#o?aC5o zF|j;l-gEiPMoHx)B4Ls3mzS=f%QG^`AM27yzCH~b=81h{o|vy84vfA_LB5zxe^jjM z9J8Fe#WyB?t|@!ilpGHtFFl zG?T&>J^VrFd?BWHXB(%L5ZA*9sf2{yT`%Q@agw2j^l+UuQb_6H?=qSc#`N%HTNp>8+rvEJx4)o5!!}`*qrI4X_Fzhoh5X`%-#!?RyM(FD@9{_~zL|4j2;x%w9$JMc&t58@?@;k{*%Ok&w+_nm(x-f>wBUT}Y`5z|l zvkJAEFp}g0;LwkdZ*m?(d?Us1TSSB^E*H5tq9XJNM)WtvPHuhY01d}zA)MbPznk2& zn$46jc9Gl8%hc~Ck3c^vjB)Zl=ZnmvPvfOOI$1JyrID2V74n6o3`2_SOVcbtX1z+$7$fuzf z#y-*+i|LvseHgtI#)G7Xtvu*{(qmQu^Z@AzYZi2d^eId3xr5}VoD`nMA@aP#H>UB> zLFBV2B0s`pbC1f@en><{!TD3E?lQRpBN@0H2(-Fb|3^riHYk?`YIr1RpZPrM`wMyK zx$5)_BKi)}r44df>KDxDH>E@${enHf<*sdJOZtWR4PK=#v@L#}CpJ#PNZU=3q2H0= zLwI$`@Viy`{%orNt0fg4pnTfl@A1Qz2WHvW9_|(WLQ!n|1Byo(J`5F43+*%cApFr) z;g7BgFMZnKkFN^H=1fZEM%|d~h12YwZX1EEo#gGu) z9YG*QH0@xN!Fz5K2csjf@7D7k2pa5;4Px7%5bKlL-a$Xmw!wo@j$&%lryh`& z{h@Zp^i4uUA*v2g92i?AZh)vp!P<>Ci~Fm7+*?*W_YO{=6F38qIQ)<(`Q#(Gu8<$X z9O~jMn5O-tw+B!8iN~2uCPzxuT)CBZN6MvYYhH9HnhVViQHTaERp~iipOQI-EkaHf z1;R9QMOV>6(^q*5b(a+VYL;fJnKC$*6Q)o0)ELyJaNE%=&(af7$?T+MPhR}?Mf-MD z(RwxISM*ygdopETgyKx=k+xqvda-rUo_zIHY4t-qb^9B58Yiri_Cxx;Q9O34*oQ3p zA^U=TvenY>7_b*lu8Hz9W26}9jwrlz6S>RPTDb8wy-dSP(njZDr>XG>lsQy0i-nt2qZbQK9d-2};arHU(B^0_LwP87g;d-OyxjC=aK!2L9dm2!Y<3!}$)RmrfIcCol zrke6DakVbaq-CWDdWXrC|B6De`0AbV3 zI&vghRW21bucG^jE~U|1-O>dyJwbU2k99UU%bvLh*9F@l#|I|sR9rXghZux<(^B%33bI~Q|P$2|hd zI=WPCRRjhAP>qn_(w-a3FZ#M!xarHmwlsj9X z9E{rcG6Zg*9mQzx!l0frx>Af)nPNQ7^hz-V7E4Dl1SY$q7&4 + +int sys_select() +{ + return -ENOSYS; +} + diff --git a/110_master/110/os/os/linux/fs/select.o b/110_master/110/os/os/linux/fs/select.o new file mode 100644 index 0000000000000000000000000000000000000000..d61f73a39bf58c107d845f3825c695fe69663502 GIT binary patch literal 1776 zcma)7&ubG=5T2J!Yc*|X8^x9irr?h%?k3TorD`oLDvI>~7iJXeveV zCY}@#J&1bs?8UqPfKX4Kdi3hqL;YsoPO~}bz`U9HX5P%3>16x#`kfm}DH2j-P~Rf@ zl+m7QEas>{P2kmV>r<>uh}!akeCds_eOT8?M2Wg)X97y zXXIz{6KZmJ{3ubzqHEJeej#@`cdNkQ($w4KX(HnU<#LNTV+09~f%U6&dCo2MSm&o^ z=r~TL{^ZAS#{HoyMWNGi>XB9FIHI9A%~auDMj@)y@?EFobsJI14^7W`RO+<7ZqF=R zm5SN1Yo)RVO3jdNuC5hVidAdgsuoSx4(hF|?F;i4q1QW&qPbBto4(tQ%w}M_j=AZh zUncKQJrYawEG&Ru~0ZwnU4Z zUPM;Ij%>1OVMtcsbgYI`>u#*Ky`~RWtlPC(;57dvg*F;I@kis zL)RAOsi&aRIIZ<~a{8_RbIu@$_g4DiB@mtO%TCWGy1^hwHd9;uxYGc5+5Qz*MvUa< z9Gq{Nm4w8{zmS6hLcYY~mLMmkQ0ApQ$Ac%gz;MoiD`Am=g*R7#1j7tNTI!1mRP(~3C{b&IOkWGJ +#include + +#include +#include +#include +#include + +static void cp_stat(struct m_inode * inode, struct stat * statbuf) +{ + struct stat tmp; + int i; + + verify_area(statbuf,sizeof (* statbuf)); + tmp.st_dev = inode->i_dev; + tmp.st_ino = inode->i_num; + tmp.st_mode = inode->i_mode; + tmp.st_nlink = inode->i_nlinks; + tmp.st_uid = inode->i_uid; + tmp.st_gid = inode->i_gid; + tmp.st_rdev = inode->i_zone[0]; + tmp.st_size = inode->i_size; + tmp.st_atime = inode->i_atime; + tmp.st_mtime = inode->i_mtime; + tmp.st_ctime = inode->i_ctime; + for (i=0 ; i= NR_OPEN || !(f=current->filp[fd]) || !(inode=f->f_inode)) + return -EBADF; + cp_stat(inode,statbuf); + return 0; +} + +int sys_readlink() +{ + return -ENOSYS; +} diff --git a/110_master/110/os/os/linux/fs/stat.o b/110_master/110/os/os/linux/fs/stat.o new file mode 100644 index 0000000000000000000000000000000000000000..fdb41d331a01a0b46c2a069b24d4be4631d5abd0 GIT binary patch literal 7212 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 +#include +#include +#include + +#include +#include + +int sync_dev(int dev); +void wait_for_keypress(void); + +/* set_bit uses setb, as gas doesn't recognize setc */ +#define set_bit(bitnr,addr) ({ \ +register int __res __asm__("ax"); \ +__asm__("bt %2,%3;setb %%al":"=a" (__res):"a" (0),"r" (bitnr),"m" (*(addr))); \ +__res; }) + +struct super_block super_block[NR_SUPER]; +/* this is initialized in init/main.c */ +int ROOT_DEV = 0; + +static void lock_super(struct super_block * sb) +{ + cli(); + while (sb->s_lock) + sleep_on(&(sb->s_wait)); + sb->s_lock = 1; + sti(); +} + +static void free_super(struct super_block * sb) +{ + cli(); + sb->s_lock = 0; + wake_up(&(sb->s_wait)); + sti(); +} + +static void wait_on_super(struct super_block * sb) +{ + cli(); + while (sb->s_lock) + sleep_on(&(sb->s_wait)); + sti(); +} + +struct super_block * get_super(int dev) +{ + struct super_block * s; + + if (!dev) + return NULL; + s = 0+super_block; + while (s < NR_SUPER+super_block) + if (s->s_dev == dev) { + wait_on_super(s); + if (s->s_dev == dev) + return s; + s = 0+super_block; + } else + s++; + return NULL; +} + +void put_super(int dev) +{ + struct super_block * sb; +/* struct m_inode * inode; */ + int i; + + if (dev == ROOT_DEV) { + printk("root diskette changed: prepare for armageddon\n\r"); + return; + } + if (!(sb = get_super(dev))) + return; + if (sb->s_imount) { + printk("Mounted disk changed - tssk, tssk\n\r"); + return; + } + lock_super(sb); + sb->s_dev = 0; + for(i=0;is_imap[i]); + for(i=0;is_zmap[i]); + free_super(sb); + return; +} + +static struct super_block * read_super(int dev) +{ + struct super_block * s; + struct buffer_head * bh; + int i,block; + + if (!dev) + return NULL; + check_disk_change(dev); + if (s = get_super(dev)) + return s; + for (s = 0+super_block ;; s++) { + if (s >= NR_SUPER+super_block) + return NULL; + if (!s->s_dev) + break; + } + s->s_dev = dev; + s->s_isup = NULL; + s->s_imount = NULL; + s->s_time = 0; + s->s_rd_only = 0; + s->s_dirt = 0; + lock_super(s); + if (!(bh = bread(dev,1))) { + s->s_dev=0; + free_super(s); + return NULL; + } + __asm__ volatile ("cld"); /* by wyj */ + *((struct d_super_block *) s) = + *((struct d_super_block *) bh->b_data); + brelse(bh); + if (s->s_magic != SUPER_MAGIC) { + s->s_dev = 0; + free_super(s); + return NULL; + } + for (i=0;is_imap[i] = NULL; + for (i=0;is_zmap[i] = NULL; + block=2; + for (i=0 ; i < s->s_imap_blocks ; i++) + if (s->s_imap[i]=bread(dev,block)) + block++; + else + break; + for (i=0 ; i < s->s_zmap_blocks ; i++) + if (s->s_zmap[i]=bread(dev,block)) + block++; + else + break; + if (block != 2+s->s_imap_blocks+s->s_zmap_blocks) { + for(i=0;is_imap[i]); + for(i=0;is_zmap[i]); + s->s_dev=0; + free_super(s); + return NULL; + } + s->s_imap[0]->b_data[0] |= 1; + s->s_zmap[0]->b_data[0] |= 1; + free_super(s); + return s; +} + +int sys_umount(char * dev_name) +{ + struct m_inode * inode; + struct super_block * sb; + int dev; + + if (!(inode=namei(dev_name))) + return -ENOENT; + dev = inode->i_zone[0]; + if (!S_ISBLK(inode->i_mode)) { + iput(inode); + return -ENOTBLK; + } + iput(inode); + if (dev==ROOT_DEV) + return -EBUSY; + if (!(sb=get_super(dev)) || !(sb->s_imount)) + return -ENOENT; + if (!sb->s_imount->i_mount) + printk("Mounted inode has i_mount=0\n"); + for (inode=inode_table+0 ; inodei_dev==dev && inode->i_count) + return -EBUSY; + sb->s_imount->i_mount=0; + iput(sb->s_imount); + sb->s_imount = NULL; + iput(sb->s_isup); + sb->s_isup = NULL; + put_super(dev); + sync_dev(dev); + return 0; +} + +int sys_mount(char * dev_name, char * dir_name, int rw_flag) +{ + struct m_inode * dev_i, * dir_i; + struct super_block * sb; + int dev; + + if (!(dev_i=namei(dev_name))) + return -ENOENT; + dev = dev_i->i_zone[0]; + if (!S_ISBLK(dev_i->i_mode)) { + iput(dev_i); + return -EPERM; + } + iput(dev_i); + if (!(dir_i=namei(dir_name))) + return -ENOENT; + if (dir_i->i_count != 1 || dir_i->i_num == ROOT_INO) { + iput(dir_i); + return -EBUSY; + } + if (!S_ISDIR(dir_i->i_mode)) { + iput(dir_i); + return -EPERM; + } + if (!(sb=read_super(dev))) { + iput(dir_i); + return -EBUSY; + } + if (sb->s_imount) { + iput(dir_i); + return -EBUSY; + } + if (dir_i->i_mount) { + iput(dir_i); + return -EPERM; + } + sb->s_imount=dir_i; + dir_i->i_mount=1; + dir_i->i_dirt=1; /* NOTE! we don't iput(dir_i) */ + return 0; /* we do that in umount */ +} + +void mount_root(void) +{ + int i,free; + struct super_block * p; + struct m_inode * mi; + + if (32 != sizeof (struct d_inode)) + panic("bad i-node size"); + for(i=0;is_dev = 0; + p->s_lock = 0; + p->s_wait = NULL; + } + if (!(p=read_super(ROOT_DEV))) + panic("Unable to mount root"); + if (!(mi=iget(ROOT_DEV,ROOT_INO))) + panic("Unable to read root i-node"); + mi->i_count += 3 ; /* NOTE! it is logically used 4 times, not 1 */ + p->s_isup = p->s_imount = mi; + current->pwd = mi; + current->root = mi; + free=0; + i=p->s_nzones; + while (-- i >= 0) + if (!set_bit(i&8191,p->s_zmap[i>>13]->b_data)) + free++; + printk("%d/%d free blocks\n\r",free,p->s_nzones); + free=0; + i=p->s_ninodes+1; + while (-- i >= 0) + if (!set_bit(i&8191,p->s_imap[i>>13]->b_data)) + free++; + printk("%d/%d free inodes\n\r",free,p->s_ninodes); +} diff --git a/110_master/110/os/os/linux/fs/super.o b/110_master/110/os/os/linux/fs/super.o new file mode 100644 index 0000000000000000000000000000000000000000..b551798da16bfa699c2dc2848c061720be0e1b2a GIT binary patch literal 12284 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 + +#include + +static void free_ind(int dev,int block) +{ + struct buffer_head * bh; + unsigned short * p; + int i; + + if (!block) + return; + if (bh=bread(dev,block)) { + p = (unsigned short *) bh->b_data; + for (i=0;i<512;i++,p++) + if (*p) + free_block(dev,*p); + brelse(bh); + } + free_block(dev,block); +} + +static void free_dind(int dev,int block) +{ + struct buffer_head * bh; + unsigned short * p; + int i; + + if (!block) + return; + if (bh=bread(dev,block)) { + p = (unsigned short *) bh->b_data; + for (i=0;i<512;i++,p++) + if (*p) + free_ind(dev,*p); + brelse(bh); + } + free_block(dev,block); +} + +void truncate(struct m_inode * inode) +{ + int i; + + if (!(S_ISREG(inode->i_mode) || S_ISDIR(inode->i_mode))) + return; + for (i=0;i<7;i++) + if (inode->i_zone[i]) { + free_block(inode->i_dev,inode->i_zone[i]); + inode->i_zone[i]=0; + } + free_ind(inode->i_dev,inode->i_zone[7]); + free_dind(inode->i_dev,inode->i_zone[8]); + inode->i_zone[7] = inode->i_zone[8] = 0; + inode->i_size = 0; + inode->i_dirt = 1; + inode->i_mtime = inode->i_ctime = CURRENT_TIME; +} + diff --git a/110_master/110/os/os/linux/fs/truncate.o b/110_master/110/os/os/linux/fs/truncate.o new file mode 100644 index 0000000000000000000000000000000000000000..8975b924958105c719b40601717933b390dce7b0 GIT binary patch literal 6848 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 T&knY~U11EUL+(?^{YLp;_3Udb literal 0 HcmV?d00001 diff --git a/110_master/110/os/os/linux/include/a.out.h b/110_master/110/os/os/linux/include/a.out.h new file mode 100644 index 0000000..3e67974 --- /dev/null +++ b/110_master/110/os/os/linux/include/a.out.h @@ -0,0 +1,220 @@ +#ifndef _A_OUT_H +#define _A_OUT_H + +#define __GNU_EXEC_MACROS__ + +struct exec { + unsigned long a_magic; /* Use macros N_MAGIC, etc for access */ + unsigned a_text; /* length of text, in bytes */ + unsigned a_data; /* length of data, in bytes */ + unsigned a_bss; /* length of uninitialized data area for file, in bytes */ + unsigned a_syms; /* length of symbol table data in file, in bytes */ + unsigned a_entry; /* start address */ + unsigned a_trsize; /* length of relocation info for text, in bytes */ + unsigned a_drsize; /* length of relocation info for data, in bytes */ +}; + +#ifndef N_MAGIC +#define N_MAGIC(exec) ((exec).a_magic) +#endif + +#ifndef OMAGIC +/* Code indicating object file or impure executable. */ +#define OMAGIC 0407 +/* Code indicating pure executable. */ +#define NMAGIC 0410 +/* Code indicating demand-paged executable. */ +#define ZMAGIC 0413 +#endif /* not OMAGIC */ + +#ifndef N_BADMAG +#define N_BADMAG(x) \ + (N_MAGIC(x) != OMAGIC && N_MAGIC(x) != NMAGIC \ + && N_MAGIC(x) != ZMAGIC) +#endif + +#define _N_BADMAG(x) \ + (N_MAGIC(x) != OMAGIC && N_MAGIC(x) != NMAGIC \ + && N_MAGIC(x) != ZMAGIC) + +#define _N_HDROFF(x) (SEGMENT_SIZE - sizeof (struct exec)) + +#ifndef N_TXTOFF +#define N_TXTOFF(x) \ + (N_MAGIC(x) == ZMAGIC ? _N_HDROFF((x)) + sizeof (struct exec) : sizeof (struct exec)) +#endif + +#ifndef N_DATOFF +#define N_DATOFF(x) (N_TXTOFF(x) + (x).a_text) +#endif + +#ifndef N_TRELOFF +#define N_TRELOFF(x) (N_DATOFF(x) + (x).a_data) +#endif + +#ifndef N_DRELOFF +#define N_DRELOFF(x) (N_TRELOFF(x) + (x).a_trsize) +#endif + +#ifndef N_SYMOFF +#define N_SYMOFF(x) (N_DRELOFF(x) + (x).a_drsize) +#endif + +#ifndef N_STROFF +#define N_STROFF(x) (N_SYMOFF(x) + (x).a_syms) +#endif + +/* Address of text segment in memory after it is loaded. */ +#ifndef N_TXTADDR +#define N_TXTADDR(x) 0 +#endif + +/* Address of data segment in memory after it is loaded. + Note that it is up to you to define SEGMENT_SIZE + on machines not listed here. */ +#if defined(vax) || defined(hp300) || defined(pyr) +#define SEGMENT_SIZE PAGE_SIZE +#endif +#ifdef hp300 +#define PAGE_SIZE 4096 +#endif +#ifdef sony +#define SEGMENT_SIZE 0x2000 +#endif /* Sony. */ +#ifdef is68k +#define SEGMENT_SIZE 0x20000 +#endif +#if defined(m68k) && defined(PORTAR) +#define PAGE_SIZE 0x400 +#define SEGMENT_SIZE PAGE_SIZE +#endif + +#define PAGE_SIZE 4096 +#define SEGMENT_SIZE 1024 + +#define _N_SEGMENT_ROUND(x) (((x) + SEGMENT_SIZE - 1) & ~(SEGMENT_SIZE - 1)) + +#define _N_TXTENDADDR(x) (N_TXTADDR(x)+(x).a_text) + +#ifndef N_DATADDR +#define N_DATADDR(x) \ + (N_MAGIC(x)==OMAGIC? (_N_TXTENDADDR(x)) \ + : (_N_SEGMENT_ROUND (_N_TXTENDADDR(x)))) +#endif + +/* Address of bss segment in memory after it is loaded. */ +#ifndef N_BSSADDR +#define N_BSSADDR(x) (N_DATADDR(x) + (x).a_data) +#endif + +#ifndef N_NLIST_DECLARED +struct nlist { + union { + char *n_name; + struct nlist *n_next; + long n_strx; + } n_un; + unsigned char n_type; + char n_other; + short n_desc; + unsigned long n_value; +}; +#endif + +#ifndef N_UNDF +#define N_UNDF 0 +#endif +#ifndef N_ABS +#define N_ABS 2 +#endif +#ifndef N_TEXT +#define N_TEXT 4 +#endif +#ifndef N_DATA +#define N_DATA 6 +#endif +#ifndef N_BSS +#define N_BSS 8 +#endif +#ifndef N_COMM +#define N_COMM 18 +#endif +#ifndef N_FN +#define N_FN 15 +#endif + +#ifndef N_EXT +#define N_EXT 1 +#endif +#ifndef N_TYPE +#define N_TYPE 036 +#endif +#ifndef N_STAB +#define N_STAB 0340 +#endif + +/* The following type indicates the definition of a symbol as being + an indirect reference to another symbol. The other symbol + appears as an undefined reference, immediately following this symbol. + + Indirection is asymmetrical. The other symbol's value will be used + to satisfy requests for the indirect symbol, but not vice versa. + If the other symbol does not have a definition, libraries will + be searched to find a definition. */ +#define N_INDR 0xa + +/* The following symbols refer to set elements. + All the N_SET[ATDB] symbols with the same name form one set. + Space is allocated for the set in the text section, and each set + element's value is stored into one word of the space. + The first word of the space is the length of the set (number of elements). + + The address of the set is made into an N_SETV symbol + whose name is the same as the name of the set. + This symbol acts like a N_DATA global symbol + in that it can satisfy undefined external references. */ + +/* These appear as input to LD, in a .o file. */ +#define N_SETA 0x14 /* Absolute set element symbol */ +#define N_SETT 0x16 /* Text set element symbol */ +#define N_SETD 0x18 /* Data set element symbol */ +#define N_SETB 0x1A /* Bss set element symbol */ + +/* This is output from LD. */ +#define N_SETV 0x1C /* Pointer to set vector in data area. */ + +#ifndef N_RELOCATION_INFO_DECLARED + +/* This structure describes a single relocation to be performed. + The text-relocation section of the file is a vector of these structures, + all of which apply to the text section. + Likewise, the data-relocation section applies to the data section. */ + +struct relocation_info +{ + /* Address (within segment) to be relocated. */ + int r_address; + /* The meaning of r_symbolnum depends on r_extern. */ + unsigned int r_symbolnum:24; + /* Nonzero means value is a pc-relative offset + and it should be relocated for changes in its own address + as well as for changes in the symbol or section specified. */ + unsigned int r_pcrel:1; + /* Length (as exponent of 2) of the field to be relocated. + Thus, a value of 2 indicates 1<<2 bytes. */ + unsigned int r_length:2; + /* 1 => relocate with value of symbol. + r_symbolnum is the index of the symbol + in file's the symbol table. + 0 => relocate with the address of a segment. + r_symbolnum is N_TEXT, N_DATA, N_BSS or N_ABS + (the N_EXT bit may be set also, but signifies nothing). */ + unsigned int r_extern:1; + /* Four bits that aren't used, but when writing an object file + it is desirable to clear them. */ + unsigned int r_pad:4; +}; +#endif /* no N_RELOCATION_INFO_DECLARED. */ + + +#endif /* __A_OUT_GNU_H__ */ diff --git a/110_master/110/os/os/linux/include/asm/io.h b/110_master/110/os/os/linux/include/asm/io.h new file mode 100644 index 0000000..d5cc42a --- /dev/null +++ b/110_master/110/os/os/linux/include/asm/io.h @@ -0,0 +1,24 @@ +#define outb(value,port) \ +__asm__ ("outb %%al,%%dx"::"a" (value),"d" (port)) + + +#define inb(port) ({ \ +unsigned char _v; \ +__asm__ volatile ("inb %%dx,%%al":"=a" (_v):"d" (port)); \ +_v; \ +}) + +#define outb_p(value,port) \ +__asm__ ("outb %%al,%%dx\n" \ + "\tjmp 1f\n" \ + "1:\tjmp 1f\n" \ + "1:"::"a" (value),"d" (port)) + +#define inb_p(port) ({ \ +unsigned char _v; \ +__asm__ volatile ("inb %%dx,%%al\n" \ + "\tjmp 1f\n" \ + "1:\tjmp 1f\n" \ + "1:":"=a" (_v):"d" (port)); \ +_v; \ +}) diff --git a/110_master/110/os/os/linux/include/asm/memory.h b/110_master/110/os/os/linux/include/asm/memory.h new file mode 100644 index 0000000..51b69e7 --- /dev/null +++ b/110_master/110/os/os/linux/include/asm/memory.h @@ -0,0 +1,15 @@ +/* + * NOTE!!! memcpy(dest,src,n) assumes ds=es=normal data segment. This + * goes for all kernel functions (ds=es=kernel space, fs=local data, + * gs=null), as well as for all well-behaving user programs (ds=es= + * user data space). This is NOT a bug, as any user program that changes + * es deserves to die if it isn't careful. + */ +#define memcpy(dest,src,n) ({ \ +void * _res = dest; \ +__asm__ ("cld;rep;movsb" \ + ::"D" ((long)(_res)),"S" ((long)(src)),"c" ((long) (n)) \ + ); \ +_res; \ +}) + diff --git a/110_master/110/os/os/linux/include/asm/segment.h b/110_master/110/os/os/linux/include/asm/segment.h new file mode 100644 index 0000000..94dd102 --- /dev/null +++ b/110_master/110/os/os/linux/include/asm/segment.h @@ -0,0 +1,65 @@ +static inline unsigned char get_fs_byte(const char * addr) +{ + unsigned register char _v; + + __asm__ ("movb %%fs:%1,%0":"=r" (_v):"m" (*addr)); + return _v; +} + +static inline unsigned short get_fs_word(const unsigned short *addr) +{ + unsigned short _v; + + __asm__ ("movw %%fs:%1,%0":"=r" (_v):"m" (*addr)); + return _v; +} + +static inline unsigned long get_fs_long(const unsigned long *addr) +{ + unsigned long _v; + + __asm__ ("movl %%fs:%1,%0":"=r" (_v):"m" (*addr)); \ + return _v; +} + +static inline void put_fs_byte(char val,char *addr) +{ +__asm__ ("movb %0,%%fs:%1"::"r" (val),"m" (*addr)); +} + +static inline void put_fs_word(short val,short * addr) +{ +__asm__ ("movw %0,%%fs:%1"::"r" (val),"m" (*addr)); +} + +static inline void put_fs_long(unsigned long val,unsigned long * addr) +{ +__asm__ ("movl %0,%%fs:%1"::"r" (val),"m" (*addr)); +} + +/* + * Someone who knows GNU asm better than I should double check the followig. + * It seems to work, but I don't know if I'm doing something subtly wrong. + * --- TYT, 11/24/91 + * [ nothing wrong here, Linus ] + */ + +static inline unsigned long get_fs() +{ + unsigned short _v; + __asm__("mov %%fs,%%ax":"=a" (_v):); + return _v; +} + +static inline unsigned long get_ds() +{ + unsigned short _v; + __asm__("mov %%ds,%%ax":"=a" (_v):); + return _v; +} + +static inline void set_fs(unsigned long val) +{ + __asm__("mov %0,%%fs"::"a" ((unsigned short) val)); +} + diff --git a/110_master/110/os/os/linux/include/asm/system.h b/110_master/110/os/os/linux/include/asm/system.h new file mode 100644 index 0000000..0b5a21d --- /dev/null +++ b/110_master/110/os/os/linux/include/asm/system.h @@ -0,0 +1,66 @@ +#define move_to_user_mode() \ +__asm__ ("movl %%esp,%%eax\n\t" \ + "pushl $0x17\n\t" \ + "pushl %%eax\n\t" \ + "pushfl\n\t" \ + "pushl $0x0f\n\t" \ + "pushl $1f\n\t" \ + "iret\n" \ + "1:\tmovl $0x17,%%eax\n\t" \ + "movw %%ax,%%ds\n\t" \ + "movw %%ax,%%es\n\t" \ + "movw %%ax,%%fs\n\t" \ + "movw %%ax,%%gs" \ + :::"ax") + +#define sti() __asm__ ("sti"::) +#define cli() __asm__ ("cli"::) +#define nop() __asm__ ("nop"::) + +#define iret() __asm__ ("iret"::) + +#define _set_gate(gate_addr,type,dpl,addr) \ +__asm__ ("movw %%dx,%%ax\n\t" \ + "movw %0,%%dx\n\t" \ + "movl %%eax,%1\n\t" \ + "movl %%edx,%2" \ + : \ + : "i" ((short) (0x8000+(dpl<<13)+(type<<8))), \ + "o" (*((char *) (gate_addr))), \ + "o" (*(4+(char *) (gate_addr))), \ + "d" ((char *) (addr)),"a" (0x00080000)) + +#define set_intr_gate(n,addr) \ + _set_gate(&idt[n],14,0,addr) + +#define set_trap_gate(n,addr) \ + _set_gate(&idt[n],15,0,addr) + +#define set_system_gate(n,addr) \ + _set_gate(&idt[n],15,3,addr) + +#define _set_seg_desc(gate_addr,type,dpl,base,limit) {\ + *(gate_addr) = ((base) & 0xff000000) | \ + (((base) & 0x00ff0000)>>16) | \ + ((limit) & 0xf0000) | \ + ((dpl)<<13) | \ + (0x00408000) | \ + ((type)<<8); \ + *((gate_addr)+1) = (((base) & 0x0000ffff)<<16) | \ + ((limit) & 0x0ffff); } + +#define _set_tssldt_desc(n,addr,type) \ +__asm__ ("movw $104,%1\n\t" \ + "movw %%ax,%2\n\t" \ + "rorl $16,%%eax\n\t" \ + "movb %%al,%3\n\t" \ + "movb $" type ",%4\n\t" \ + "movb $0x00,%5\n\t" \ + "movb %%ah,%6\n\t" \ + "rorl $16,%%eax" \ + ::"a" (addr), "m" (*(n)), "m" (*(n+2)), "m" (*(n+4)), \ + "m" (*(n+5)), "m" (*(n+6)), "m" (*(n+7)) \ + ) + +#define set_tss_desc(n,addr) _set_tssldt_desc(((char *) (n)),addr,"0x89") +#define set_ldt_desc(n,addr) _set_tssldt_desc(((char *) (n)),addr,"0x82") diff --git a/110_master/110/os/os/linux/include/const.h b/110_master/110/os/os/linux/include/const.h new file mode 100644 index 0000000..7828e61 --- /dev/null +++ b/110_master/110/os/os/linux/include/const.h @@ -0,0 +1,15 @@ +#ifndef _CONST_H +#define _CONST_H + +#define BUFFER_END 0x200000 + +#define I_TYPE 0170000 +#define I_DIRECTORY 0040000 +#define I_REGULAR 0100000 +#define I_BLOCK_SPECIAL 0060000 +#define I_CHAR_SPECIAL 0020000 +#define I_NAMED_PIPE 0010000 +#define I_SET_UID_BIT 0004000 +#define I_SET_GID_BIT 0002000 + +#endif diff --git a/110_master/110/os/os/linux/include/ctype.h b/110_master/110/os/os/linux/include/ctype.h new file mode 100644 index 0000000..7acf55d --- /dev/null +++ b/110_master/110/os/os/linux/include/ctype.h @@ -0,0 +1,34 @@ +#ifndef _CTYPE_H +#define _CTYPE_H + +#define _U 0x01 /* upper */ +#define _L 0x02 /* lower */ +#define _D 0x04 /* digit */ +#define _C 0x08 /* cntrl */ +#define _P 0x10 /* punct */ +#define _S 0x20 /* white space (space/lf/tab) */ +#define _X 0x40 /* hex digit */ +#define _SP 0x80 /* hard space (0x20) */ + +extern unsigned char _ctype[]; +extern char _ctmp; + +#define isalnum(c) ((_ctype+1)[c]&(_U|_L|_D)) +#define isalpha(c) ((_ctype+1)[c]&(_U|_L)) +#define iscntrl(c) ((_ctype+1)[c]&(_C)) +#define isdigit(c) ((_ctype+1)[c]&(_D)) +#define isgraph(c) ((_ctype+1)[c]&(_P|_U|_L|_D)) +#define islower(c) ((_ctype+1)[c]&(_L)) +#define isprint(c) ((_ctype+1)[c]&(_P|_U|_L|_D|_SP)) +#define ispunct(c) ((_ctype+1)[c]&(_P)) +#define isspace(c) ((_ctype+1)[c]&(_S)) +#define isupper(c) ((_ctype+1)[c]&(_U)) +#define isxdigit(c) ((_ctype+1)[c]&(_D|_X)) + +#define isascii(c) (((unsigned) c)<=0x7f) +#define toascii(c) (((unsigned) c)&0x7f) + +#define tolower(c) (_ctmp=c,isupper(_ctmp)?_ctmp-('A'-'a'):_ctmp) +#define toupper(c) (_ctmp=c,islower(_ctmp)?_ctmp-('a'-'A'):_ctmp) + +#endif diff --git a/110_master/110/os/os/linux/include/errno.h b/110_master/110/os/os/linux/include/errno.h new file mode 100644 index 0000000..c282f69 --- /dev/null +++ b/110_master/110/os/os/linux/include/errno.h @@ -0,0 +1,60 @@ +#ifndef _ERRNO_H +#define _ERRNO_H + +/* + * ok, as I hadn't got any other source of information about + * possible error numbers, I was forced to use the same numbers + * as minix. + * Hopefully these are posix or something. I wouldn't know (and posix + * isn't telling me - they want $$$ for their f***ing standard). + * + * We don't use the _SIGN cludge of minix, so kernel returns must + * see to the sign by themselves. + * + * NOTE! Remember to change strerror() if you change this file! + */ + +extern int errno; + +#define ERROR 99 +#define EPERM 1 +#define ENOENT 2 +#define ESRCH 3 +#define EINTR 4 +#define EIO 5 +#define ENXIO 6 +#define E2BIG 7 +#define ENOEXEC 8 +#define EBADF 9 +#define ECHILD 10 +#define EAGAIN 11 +#define ENOMEM 12 +#define EACCES 13 +#define EFAULT 14 +#define ENOTBLK 15 +#define EBUSY 16 +#define EEXIST 17 +#define EXDEV 18 +#define ENODEV 19 +#define ENOTDIR 20 +#define EISDIR 21 +#define EINVAL 22 +#define ENFILE 23 +#define EMFILE 24 +#define ENOTTY 25 +#define ETXTBSY 26 +#define EFBIG 27 +#define ENOSPC 28 +#define ESPIPE 29 +#define EROFS 30 +#define EMLINK 31 +#define EPIPE 32 +#define EDOM 33 +#define ERANGE 34 +#define EDEADLK 35 +#define ENAMETOOLONG 36 +#define ENOLCK 37 +#define ENOSYS 38 +#define ENOTEMPTY 39 + +#endif diff --git a/110_master/110/os/os/linux/include/fcntl.h b/110_master/110/os/os/linux/include/fcntl.h new file mode 100644 index 0000000..a5bf9af --- /dev/null +++ b/110_master/110/os/os/linux/include/fcntl.h @@ -0,0 +1,55 @@ +#ifndef _FCNTL_H +#define _FCNTL_H + +#include + +/* open/fcntl - NOCTTY, NDELAY isn't implemented yet */ +#define O_ACCMODE 00003 +#define O_RDONLY 00 +#define O_WRONLY 01 +#define O_RDWR 02 +#define O_CREAT 00100 /* not fcntl */ +#define O_EXCL 00200 /* not fcntl */ +#define O_NOCTTY 00400 /* not fcntl */ +#define O_TRUNC 01000 /* not fcntl */ +#define O_APPEND 02000 +#define O_NONBLOCK 04000 /* not fcntl */ +#define O_NDELAY O_NONBLOCK + +/* Defines for fcntl-commands. Note that currently + * locking isn't supported, and other things aren't really + * tested. + */ +#define F_DUPFD 0 /* dup */ +#define F_GETFD 1 /* get f_flags */ +#define F_SETFD 2 /* set f_flags */ +#define F_GETFL 3 /* more flags (cloexec) */ +#define F_SETFL 4 +#define F_GETLK 5 /* not implemented */ +#define F_SETLK 6 +#define F_SETLKW 7 + +/* for F_[GET|SET]FL */ +#define FD_CLOEXEC 1 /* actually anything with low bit set goes */ + +/* Ok, these are locking features, and aren't implemented at any + * level. POSIX wants them. + */ +#define F_RDLCK 0 +#define F_WRLCK 1 +#define F_UNLCK 2 + +/* Once again - not implemented, but ... */ +struct flock { + short l_type; + short l_whence; + off_t l_start; + off_t l_len; + pid_t l_pid; +}; + +extern int creat(const char * filename,mode_t mode); +extern int fcntl(int fildes,int cmd, ...); +extern int open(const char * filename, int flags, ...); + +#endif diff --git a/110_master/110/os/os/linux/include/linux/config.h b/110_master/110/os/os/linux/include/linux/config.h new file mode 100644 index 0000000..c979fb3 --- /dev/null +++ b/110_master/110/os/os/linux/include/linux/config.h @@ -0,0 +1,48 @@ +#ifndef _CONFIG_H +#define _CONFIG_H + +/* + * The root-device is no longer hard-coded. You can change the default + * root-device by changing the line ROOT_DEV = XXX in boot/bootsect.s + */ + +/* + * define your keyboard here - + * KBD_FINNISH for Finnish keyboards + * KBD_US for US-type + * KBD_GR for German keyboards + * KBD_FR for Frech keyboard + */ +#define KBD_US +/*#define KBD_GR */ +/*#define KBD_FR */ +/*#define KBD_FINNISH */ + +/* + * Normally, Linux can get the drive parameters from the BIOS at + * startup, but if this for some unfathomable reason fails, you'd + * be left stranded. For this case, you can define HD_TYPE, which + * contains all necessary info on your harddisk. + * + * The HD_TYPE macro should look like this: + * + * #define HD_TYPE { head, sect, cyl, wpcom, lzone, ctl} + * + * In case of two harddisks, the info should be sepatated by + * commas: + * + * #define HD_TYPE { h,s,c,wpcom,lz,ctl },{ h,s,c,wpcom,lz,ctl } + */ +/* + This is an example, two drives, first is type 2, second is type 3: + +#define HD_TYPE { 4,17,615,300,615,8 }, { 6,17,615,300,615,0 } + + NOTE: ctl is 0 for all drives with heads<=8, and ctl=8 for drives + with more than 8 heads. + + If you want the BIOS to tell what kind of drive you have, just + leave HD_TYPE undefined. This is the normal thing to do. +*/ + +#endif diff --git a/110_master/110/os/os/linux/include/linux/fdreg.h b/110_master/110/os/os/linux/include/linux/fdreg.h new file mode 100644 index 0000000..01355af --- /dev/null +++ b/110_master/110/os/os/linux/include/linux/fdreg.h @@ -0,0 +1,71 @@ +/* + * This file contains some defines for the floppy disk controller. + * Various sources. Mostly "IBM Microcomputers: A Programmers + * Handbook", Sanches and Canton. + */ +#ifndef _FDREG_H +#define _FDREG_H + +extern int ticks_to_floppy_on(unsigned int nr); +extern void floppy_on(unsigned int nr); +extern void floppy_off(unsigned int nr); +extern void floppy_select(unsigned int nr); +extern void floppy_deselect(unsigned int nr); + +/* Fd controller regs. S&C, about page 340 */ +#define FD_STATUS 0x3f4 +#define FD_DATA 0x3f5 +#define FD_DOR 0x3f2 /* Digital Output Register */ +#define FD_DIR 0x3f7 /* Digital Input Register (read) */ +#define FD_DCR 0x3f7 /* Diskette Control Register (write)*/ + +/* Bits of main status register */ +#define STATUS_BUSYMASK 0x0F /* drive busy mask */ +#define STATUS_BUSY 0x10 /* FDC busy */ +#define STATUS_DMA 0x20 /* 0- DMA mode */ +#define STATUS_DIR 0x40 /* 0- cpu->fdc */ +#define STATUS_READY 0x80 /* Data reg ready */ + +/* Bits of FD_ST0 */ +#define ST0_DS 0x03 /* drive select mask */ +#define ST0_HA 0x04 /* Head (Address) */ +#define ST0_NR 0x08 /* Not Ready */ +#define ST0_ECE 0x10 /* Equipment chech error */ +#define ST0_SE 0x20 /* Seek end */ +#define ST0_INTR 0xC0 /* Interrupt code mask */ + +/* Bits of FD_ST1 */ +#define ST1_MAM 0x01 /* Missing Address Mark */ +#define ST1_WP 0x02 /* Write Protect */ +#define ST1_ND 0x04 /* No Data - unreadable */ +#define ST1_OR 0x10 /* OverRun */ +#define ST1_CRC 0x20 /* CRC error in data or addr */ +#define ST1_EOC 0x80 /* End Of Cylinder */ + +/* Bits of FD_ST2 */ +#define ST2_MAM 0x01 /* Missing Addess Mark (again) */ +#define ST2_BC 0x02 /* Bad Cylinder */ +#define ST2_SNS 0x04 /* Scan Not Satisfied */ +#define ST2_SEH 0x08 /* Scan Equal Hit */ +#define ST2_WC 0x10 /* Wrong Cylinder */ +#define ST2_CRC 0x20 /* CRC error in data field */ +#define ST2_CM 0x40 /* Control Mark = deleted */ + +/* Bits of FD_ST3 */ +#define ST3_HA 0x04 /* Head (Address) */ +#define ST3_TZ 0x10 /* Track Zero signal (1=track 0) */ +#define ST3_WP 0x40 /* Write Protect */ + +/* Values for FD_COMMAND */ +#define FD_RECALIBRATE 0x07 /* move to track 0 */ +#define FD_SEEK 0x0F /* seek track */ +#define FD_READ 0xE6 /* read with MT, MFM, SKip deleted */ +#define FD_WRITE 0xC5 /* write with MT, MFM */ +#define FD_SENSEI 0x08 /* Sense Interrupt Status */ +#define FD_SPECIFY 0x03 /* specify HUT etc */ + +/* DMA commands */ +#define DMA_READ 0x46 +#define DMA_WRITE 0x4A + +#endif diff --git a/110_master/110/os/os/linux/include/linux/fs.h b/110_master/110/os/os/linux/include/linux/fs.h new file mode 100644 index 0000000..7a90b10 --- /dev/null +++ b/110_master/110/os/os/linux/include/linux/fs.h @@ -0,0 +1,202 @@ +/* + * This file has definitions for some important file table + * structures etc. + */ + +#ifndef _FS_H +#define _FS_H + +#include + +/* devices are as follows: (same as minix, so we can use the minix + * file system. These are major numbers.) + * + * 0 - unused (nodev) + * 1 - /dev/mem + * 2 - /dev/fd + * 3 - /dev/hd + * 4 - /dev/ttyx + * 5 - /dev/tty + * 6 - /dev/lp + * 7 - unnamed pipes + */ + +#define IS_SEEKABLE(x) ((x)>=1 && (x)<=3) + +#define READ 0 +#define WRITE 1 +#define READA 2 /* read-ahead - don't pause */ +#define WRITEA 3 /* "write-ahead" - silly, but somewhat useful */ + +void buffer_init(long buffer_end); + +#define MAJOR(a) (((unsigned)(a))>>8) +#define MINOR(a) ((a)&0xff) + +#define NAME_LEN 14 +#define ROOT_INO 1 + +#define I_MAP_SLOTS 8 +#define Z_MAP_SLOTS 8 +#define SUPER_MAGIC 0x137F + +#define NR_OPEN 20 +#define NR_INODE 32 +#define NR_FILE 64 +#define NR_SUPER 8 +#define NR_HASH 307 +#define NR_BUFFERS nr_buffers +#define BLOCK_SIZE 1024 +#define BLOCK_SIZE_BITS 10 +#ifndef NULL +#define NULL ((void *) 0) +#endif + +#define INODES_PER_BLOCK ((BLOCK_SIZE)/(sizeof (struct d_inode))) +#define DIR_ENTRIES_PER_BLOCK ((BLOCK_SIZE)/(sizeof (struct dir_entry))) + +#define PIPE_HEAD(inode) ((inode).i_zone[0]) +#define PIPE_TAIL(inode) ((inode).i_zone[1]) +#define PIPE_SIZE(inode) ((PIPE_HEAD(inode)-PIPE_TAIL(inode))&(PAGE_SIZE-1)) +#define PIPE_EMPTY(inode) (PIPE_HEAD(inode)==PIPE_TAIL(inode)) +#define PIPE_FULL(inode) (PIPE_SIZE(inode)==(PAGE_SIZE-1)) +#define INC_PIPE(head) \ +__asm__("incl %0\n\tandl $4095,%0"::"m" (head)) + +typedef char buffer_block[BLOCK_SIZE]; + +struct buffer_head { + char * b_data; /* pointer to data block (1024 bytes) */ + unsigned long b_blocknr; /* block number */ + unsigned short b_dev; /* device (0 = free) */ + unsigned char b_uptodate; + unsigned char b_dirt; /* 0-clean,1-dirty */ + unsigned char b_count; /* users using this block */ + unsigned char b_lock; /* 0 - ok, 1 -locked */ + struct task_struct * b_wait; + struct buffer_head * b_prev; + struct buffer_head * b_next; + struct buffer_head * b_prev_free; + struct buffer_head * b_next_free; +}; + +struct d_inode { + unsigned short i_mode; + unsigned short i_uid; + unsigned long i_size; + unsigned long i_time; + unsigned char i_gid; + unsigned char i_nlinks; + unsigned short i_zone[9]; +}; + +struct m_inode { + unsigned short i_mode; + unsigned short i_uid; + unsigned long i_size; + unsigned long i_mtime; + unsigned char i_gid; + unsigned char i_nlinks; + unsigned short i_zone[9]; +/* these are in memory also */ + struct task_struct * i_wait; + unsigned long i_atime; + unsigned long i_ctime; + unsigned short i_dev; + unsigned short i_num; + unsigned short i_count; + unsigned char i_lock; + unsigned char i_dirt; + unsigned char i_pipe; + unsigned char i_mount; + unsigned char i_seek; + unsigned char i_update; +}; + +struct file { + unsigned short f_mode; + unsigned short f_flags; + unsigned short f_count; + struct m_inode * f_inode; + off_t f_pos; +}; + +struct super_block { + unsigned short s_ninodes; + unsigned short s_nzones; + unsigned short s_imap_blocks; + unsigned short s_zmap_blocks; + unsigned short s_firstdatazone; + unsigned short s_log_zone_size; + unsigned long s_max_size; + unsigned short s_magic; +/* These are only in memory */ + struct buffer_head * s_imap[8]; + struct buffer_head * s_zmap[8]; + unsigned short s_dev; + struct m_inode * s_isup; + struct m_inode * s_imount; + unsigned long s_time; + struct task_struct * s_wait; + unsigned char s_lock; + unsigned char s_rd_only; + unsigned char s_dirt; +}; + +struct d_super_block { + unsigned short s_ninodes; + unsigned short s_nzones; + unsigned short s_imap_blocks; + unsigned short s_zmap_blocks; + unsigned short s_firstdatazone; + unsigned short s_log_zone_size; + unsigned long s_max_size; + unsigned short s_magic; +}; + +struct dir_entry { + unsigned short inode; + char name[NAME_LEN]; +}; + +extern struct m_inode inode_table[NR_INODE]; +extern struct file file_table[NR_FILE]; +extern struct super_block super_block[NR_SUPER]; +extern struct buffer_head * start_buffer; +extern int nr_buffers; + +extern void check_disk_change(int dev); +extern int floppy_change(unsigned int nr); +extern int ticks_to_floppy_on(unsigned int dev); +extern void floppy_on(unsigned int dev); +extern void floppy_off(unsigned int dev); +extern void truncate(struct m_inode * inode); +extern void sync_inodes(void); +extern void wait_on(struct m_inode * inode); +extern int bmap(struct m_inode * inode,int block); +extern int create_block(struct m_inode * inode,int block); +extern struct m_inode * namei(const char * pathname); +extern int open_namei(const char * pathname, int flag, int mode, + struct m_inode ** res_inode); +extern void iput(struct m_inode * inode); +extern struct m_inode * iget(int dev,int nr); +extern struct m_inode * get_empty_inode(void); +extern struct m_inode * get_pipe_inode(void); +extern struct buffer_head * get_hash_table(int dev, int block); +extern struct buffer_head * getblk(int dev, int block); +extern void ll_rw_block(int rw, struct buffer_head * bh); +extern void brelse(struct buffer_head * buf); +extern struct buffer_head * bread(int dev,int block); +extern void bread_page(unsigned long addr,int dev,int b[4]); +extern struct buffer_head * breada(int dev,int block,...); +extern int new_block(int dev); +extern void free_block(int dev, int block); +extern struct m_inode * new_inode(int dev); +extern void free_inode(struct m_inode * inode); +extern int sync_dev(int dev); +extern struct super_block * get_super(int dev); +extern int ROOT_DEV; + +extern void mount_root(void); + +#endif diff --git a/110_master/110/os/os/linux/include/linux/hdreg.h b/110_master/110/os/os/linux/include/linux/hdreg.h new file mode 100644 index 0000000..e6c593f --- /dev/null +++ b/110_master/110/os/os/linux/include/linux/hdreg.h @@ -0,0 +1,65 @@ +/* + * This file contains some defines for the AT-hd-controller. + * Various sources. Check out some definitions (see comments with + * a ques). + */ +#ifndef _HDREG_H +#define _HDREG_H + +/* Hd controller regs. Ref: IBM AT Bios-listing */ +#define HD_DATA 0x1f0 /* _CTL when writing */ +#define HD_ERROR 0x1f1 /* see err-bits */ +#define HD_NSECTOR 0x1f2 /* nr of sectors to read/write */ +#define HD_SECTOR 0x1f3 /* starting sector */ +#define HD_LCYL 0x1f4 /* starting cylinder */ +#define HD_HCYL 0x1f5 /* high byte of starting cyl */ +#define HD_CURRENT 0x1f6 /* 101dhhhh , d=drive, hhhh=head */ +#define HD_STATUS 0x1f7 /* see status-bits */ +#define HD_PRECOMP HD_ERROR /* same io address, read=error, write=precomp */ +#define HD_COMMAND HD_STATUS /* same io address, read=status, write=cmd */ + +#define HD_CMD 0x3f6 + +/* Bits of HD_STATUS */ +#define ERR_STAT 0x01 +#define INDEX_STAT 0x02 +#define ECC_STAT 0x04 /* Corrected error */ +#define DRQ_STAT 0x08 +#define SEEK_STAT 0x10 +#define WRERR_STAT 0x20 +#define READY_STAT 0x40 +#define BUSY_STAT 0x80 + +/* Values for HD_COMMAND */ +#define WIN_RESTORE 0x10 +#define WIN_READ 0x20 +#define WIN_WRITE 0x30 +#define WIN_VERIFY 0x40 +#define WIN_FORMAT 0x50 +#define WIN_INIT 0x60 +#define WIN_SEEK 0x70 +#define WIN_DIAGNOSE 0x90 +#define WIN_SPECIFY 0x91 + +/* Bits for HD_ERROR */ +#define MARK_ERR 0x01 /* Bad address mark ? */ +#define TRK0_ERR 0x02 /* couldn't find track 0 */ +#define ABRT_ERR 0x04 /* ? */ +#define ID_ERR 0x10 /* ? */ +#define ECC_ERR 0x40 /* ? */ +#define BBD_ERR 0x80 /* ? */ + +struct partition { + unsigned char boot_ind; /* 0x80 - active (unused) */ + unsigned char head; /* ? */ + unsigned char sector; /* ? */ + unsigned char cyl; /* ? */ + unsigned char sys_ind; /* ? */ + unsigned char end_head; /* ? */ + unsigned char end_sector; /* ? */ + unsigned char end_cyl; /* ? */ + unsigned int start_sect; /* starting sector counting from 0 */ + unsigned int nr_sects; /* nr of sectors in partition */ +}; + +#endif diff --git a/110_master/110/os/os/linux/include/linux/head.h b/110_master/110/os/os/linux/include/linux/head.h new file mode 100644 index 0000000..db3dda2 --- /dev/null +++ b/110_master/110/os/os/linux/include/linux/head.h @@ -0,0 +1,20 @@ +#ifndef _HEAD_H +#define _HEAD_H + +typedef struct desc_struct { + unsigned long a,b; +} desc_table[256]; + +extern unsigned long pg_dir[1024]; +extern desc_table idt,gdt; + +#define GDT_NUL 0 +#define GDT_CODE 1 +#define GDT_DATA 2 +#define GDT_TMP 3 + +#define LDT_NUL 0 +#define LDT_CODE 1 +#define LDT_DATA 2 + +#endif diff --git a/110_master/110/os/os/linux/include/linux/kernel.h b/110_master/110/os/os/linux/include/linux/kernel.h new file mode 100644 index 0000000..cb40dd5 --- /dev/null +++ b/110_master/110/os/os/linux/include/linux/kernel.h @@ -0,0 +1,22 @@ +/* + * 'kernel.h' contains some often-used function prototypes etc + */ +void verify_area(void * addr,int count); +volatile void panic(const char * str); +int printf(const char * fmt, ...); +int printk(const char * fmt, ...); +int tty_write(unsigned ch,char * buf,int count); +void * malloc(unsigned int size); +void free_s(void * obj, int size); + +#define free(x) free_s((x), 0) + +/* + * This is defined as a macro, but at some point this might become a + * real subroutine that sets a flag if it returns true (to do + * BSD-style accounting where the process is flagged if it uses root + * privs). The implication of this is that you should do normal + * permissions checks first, and check suser() last. + */ +#define suser() (current->euid == 0) + diff --git a/110_master/110/os/os/linux/include/linux/mm.h b/110_master/110/os/os/linux/include/linux/mm.h new file mode 100644 index 0000000..5a160f3 --- /dev/null +++ b/110_master/110/os/os/linux/include/linux/mm.h @@ -0,0 +1,10 @@ +#ifndef _MM_H +#define _MM_H + +#define PAGE_SIZE 4096 + +extern unsigned long get_free_page(void); +extern unsigned long put_page(unsigned long page,unsigned long address); +extern void free_page(unsigned long addr); + +#endif diff --git a/110_master/110/os/os/linux/include/linux/sched.h b/110_master/110/os/os/linux/include/linux/sched.h new file mode 100644 index 0000000..772646a --- /dev/null +++ b/110_master/110/os/os/linux/include/linux/sched.h @@ -0,0 +1,239 @@ +#ifndef _SCHED_H +#define _SCHED_H + +#define NR_TASKS 64 +#define HZ 100 + +#define FIRST_TASK task[0] +#define LAST_TASK task[NR_TASKS-1] + +#include +#include +#include +#include + +#if (NR_OPEN > 32) +#error "Currently the close-on-exec-flags are in one word, max 32 files/proc" +#endif + +#define TASK_RUNNING 0 +#define TASK_INTERRUPTIBLE 1 +#define TASK_UNINTERRUPTIBLE 2 +#define TASK_ZOMBIE 3 +#define TASK_STOPPED 4 + +#ifndef NULL +#define NULL ((void *) 0) +#endif + +extern int copy_page_tables(unsigned long from, unsigned long to, long size); +extern int free_page_tables(unsigned long from, unsigned long size); + +extern void sched_init(void); +extern void schedule(void); +extern void trap_init(void); +extern void panic(const char * str); +extern int tty_write(unsigned minor,char * buf,int count); + +typedef int (*fn_ptr)(); + +struct i387_struct { + long cwd; + long swd; + long twd; + long fip; + long fcs; + long foo; + long fos; + long st_space[20]; /* 8*10 bytes for each FP-reg = 80 bytes */ +}; + +struct tss_struct { + long back_link; /* 16 high bits zero */ + long esp0; + long ss0; /* 16 high bits zero */ + long esp1; + long ss1; /* 16 high bits zero */ + long esp2; + long ss2; /* 16 high bits zero */ + long cr3; + long eip; + long eflags; + long eax,ecx,edx,ebx; + long esp; + long ebp; + long esi; + long edi; + long es; /* 16 high bits zero */ + long cs; /* 16 high bits zero */ + long ss; /* 16 high bits zero */ + long ds; /* 16 high bits zero */ + long fs; /* 16 high bits zero */ + long gs; /* 16 high bits zero */ + long ldt; /* 16 high bits zero */ + long trace_bitmap; /* bits: trace 0, bitmap 16-31 */ + struct i387_struct i387; +}; + +struct task_struct { +/* these are hardcoded - don't touch */ + long state; /* -1 unrunnable, 0 runnable, >0 stopped */ + long counter; + long priority; + long signal; + struct sigaction sigaction[32]; + long blocked; /* bitmap of masked signals */ +/* various fields */ + int exit_code; + unsigned long start_code,end_code,end_data,brk,start_stack; + long pid,father,pgrp,session,leader; + unsigned short uid,euid,suid; + unsigned short gid,egid,sgid; + long alarm; + long utime,stime,cutime,cstime,start_time; + unsigned short used_math; +/* file system info */ + int tty; /* -1 if no tty, so it must be signed */ + unsigned short umask; + struct m_inode * pwd; + struct m_inode * root; + struct m_inode * executable; + unsigned long close_on_exec; + struct file * filp[NR_OPEN]; +/* ldt for this task 0 - zero 1 - cs 2 - ds&ss */ + struct desc_struct ldt[3]; +/* tss for this task */ + struct tss_struct tss; +}; + +/* + * INIT_TASK is used to set up the first task table, touch at + * your own risk!. Base=0, limit=0x9ffff (=640kB) + */ +#define INIT_TASK \ +/* state etc */ { 0,15,15, \ +/* signals */ 0,{{},},0, \ +/* ec,brk... */ 0,0,0,0,0,0, \ +/* pid etc.. */ 0,-1,0,0,0, \ +/* uid etc */ 0,0,0,0,0,0, \ +/* alarm */ 0,0,0,0,0,0, \ +/* math */ 0, \ +/* fs info */ -1,0022,NULL,NULL,NULL,0, \ +/* filp */ {NULL,}, \ + { \ + {0,0}, \ +/* ldt */ {0x9f,0xc0fa00}, \ + {0x9f,0xc0f200}, \ + }, \ +/*tss*/ {0,PAGE_SIZE+(long)&init_task,0x10,0,0,0,0,(long)&pg_dir,\ + 0,0,0,0,0,0,0,0, \ + 0,0,0x17,0x17,0x17,0x17,0x17,0x17, \ + _LDT(0),0x80000000, \ + {} \ + }, \ +} + +extern struct task_struct *task[NR_TASKS]; +extern struct task_struct *last_task_used_math; +extern struct task_struct *current; +extern long volatile jiffies; +extern long startup_time; + +#define CURRENT_TIME (startup_time+jiffies/HZ) + +extern void add_timer(long jiffies, void (*fn)(void)); +extern void sleep_on(struct task_struct ** p); +extern void interruptible_sleep_on(struct task_struct ** p); +extern void wake_up(struct task_struct ** p); + +/* + * Entry into gdt where to find first TSS. 0-nul, 1-cs, 2-ds, 3-syscall + * 4-TSS0, 5-LDT0, 6-TSS1 etc ... + */ +#define FIRST_TSS_ENTRY 4 +#define FIRST_LDT_ENTRY (FIRST_TSS_ENTRY+1) +#define _TSS(n) ((((unsigned long) n)<<4)+(FIRST_TSS_ENTRY<<3)) +#define _LDT(n) ((((unsigned long) n)<<4)+(FIRST_LDT_ENTRY<<3)) +#define ltr(n) __asm__("ltr %%ax"::"a" (_TSS(n))) +#define lldt(n) __asm__("lldt %%ax"::"a" (_LDT(n))) +#define str(n) \ +__asm__("str %%ax\n\t" \ + "subl %2,%%eax\n\t" \ + "shrl $4,%%eax" \ + :"=a" (n) \ + :"a" (0),"i" (FIRST_TSS_ENTRY<<3)) +/* + * switch_to(n) should switch tasks to task nr n, first + * checking that n isn't the current task, in which case it does nothing. + * This also clears the TS-flag if the task we switched to has used + * tha math co-processor latest. + */ +#define switch_to(n) {\ +struct {long a,b;} __tmp; \ +__asm__("cmpl %%ecx,current\n\t" \ + "je 1f\n\t" \ + "movw %%dx,%1\n\t" \ + "xchgl %%ecx,current\n\t" \ + "ljmp *%0\n\t" \ + "cmpl %%ecx,last_task_used_math\n\t" \ + "jne 1f\n\t" \ + "clts\n" \ + "1:" \ + ::"m" (*&__tmp.a),"m" (*&__tmp.b), \ + "d" (_TSS(n)),"c" ((long) task[n])); \ +} + +#define PAGE_ALIGN(n) (((n)+0xfff)&0xfffff000) + +#define _set_base(addr,base) \ +__asm__ ("push %%edx\n\t" \ + "movw %%dx,%0\n\t" \ + "rorl $16,%%edx\n\t" \ + "movb %%dl,%1\n\t" \ + "movb %%dh,%2\n\t" \ + "pop %%edx" \ + ::"m" (*((addr)+2)), \ + "m" (*((addr)+4)), \ + "m" (*((addr)+7)), \ + "d" (base) \ + ) + +#define _set_limit(addr,limit) \ +__asm__ ("push %%edx\n\t" \ + "movw %%dx,%0\n\t" \ + "rorl $16,%%edx\n\t" \ + "movb %1,%%dh\n\t" \ + "andb $0xf0,%%dh\n\t" \ + "orb %%dh,%%dl\n\t" \ + "movb %%dl,%1\n\t" \ + "pop %%edx" \ + ::"m" (*(addr)), \ + "m" (*((addr)+6)), \ + "d" (limit) \ + ) + +#define set_base(ldt,base) _set_base( ((char *)&(ldt)) , (base) ) +#define set_limit(ldt,limit) _set_limit( ((char *)&(ldt)) , (limit-1)>>12 ) + +static inline unsigned long _get_base(char * addr) +{ + unsigned long __base; + __asm__("movb %3,%%dh\n\t" + "movb %2,%%dl\n\t" + "shll $16,%%edx\n\t" + "movw %1,%%dx" + :"=&d" (__base) + :"m" (*((addr)+2)), + "m" (*((addr)+4)), + "m" (*((addr)+7))); + return __base; +} + +#define get_base(ldt) _get_base( ((char *)&(ldt)) ) + +#define get_limit(segment) ({ \ +unsigned long __limit; \ +__asm__("lsll %1,%0\n\tincl %0":"=r" (__limit):"r" (segment)); \ +__limit;}) + +#endif diff --git a/110_master/110/os/os/linux/include/linux/sys.h b/110_master/110/os/os/linux/include/linux/sys.h new file mode 100644 index 0000000..d1cb5bd --- /dev/null +++ b/110_master/110/os/os/linux/include/linux/sys.h @@ -0,0 +1,116 @@ +/* + * Why isn't this a .c file? Enquiring minds.... + */ + +extern int sys_setup(); +extern int sys_exit(); +extern int sys_fork(); +extern int sys_read(); +extern int sys_write(); +extern int sys_open(); +extern int sys_close(); +extern int sys_waitpid(); +extern int sys_creat(); +extern int sys_link(); +extern int sys_unlink(); +extern int sys_execve(); +extern int sys_chdir(); +extern int sys_time(); +extern int sys_mknod(); +extern int sys_chmod(); +extern int sys_chown(); +extern int sys_break(); +extern int sys_stat(); +extern int sys_lseek(); +extern int sys_getpid(); +extern int sys_mount(); +extern int sys_umount(); +extern int sys_setuid(); +extern int sys_getuid(); +extern int sys_stime(); +extern int sys_ptrace(); +extern int sys_alarm(); +extern int sys_fstat(); +extern int sys_pause(); +extern int sys_utime(); +extern int sys_stty(); +extern int sys_gtty(); +extern int sys_access(); +extern int sys_nice(); +extern int sys_ftime(); +extern int sys_sync(); +extern int sys_kill(); +extern int sys_rename(); +extern int sys_mkdir(); +extern int sys_rmdir(); +extern int sys_dup(); +extern int sys_pipe(); +extern int sys_times(); +extern int sys_prof(); +extern int sys_brk(); +extern int sys_setgid(); +extern int sys_getgid(); +extern int sys_signal(); +extern int sys_geteuid(); +extern int sys_getegid(); +extern int sys_acct(); +extern int sys_phys(); +extern int sys_lock(); +extern int sys_ioctl(); +extern int sys_fcntl(); +extern int sys_mpx(); +extern int sys_setpgid(); +extern int sys_ulimit(); +extern int sys_uname(); +extern int sys_umask(); +extern int sys_chroot(); +extern int sys_ustat(); +extern int sys_dup2(); +extern int sys_getppid(); +extern int sys_getpgrp(); +extern int sys_setsid(); +extern int sys_sigaction(); +extern int sys_sgetmask(); +extern int sys_ssetmask(); +extern int sys_setreuid(); +extern int sys_setregid(); +extern int sys_sigpending(); +extern int sys_sigsuspend(); +extern int sys_sethostname(); +extern int sys_setrlimit(); +extern int sys_getrlimit(); +extern int sys_getrusage(); +extern int sys_gettimeofday(); +extern int sys_settimeofday(); +extern int sys_getgroups(); +extern int sys_setgroups(); +extern int sys_select(); +extern int sys_symlink(); +extern int sys_lstat(); +extern int sys_readlink(); +extern int sys_uselib(); +extern int sys_execve2(); +extern int sys_getdents(); +extern int sys_pipe2(); +extern int sys_sleep(); +extern int sys_getcwd(); +fn_ptr sys_call_table[] = { sys_setup, sys_exit, sys_fork, sys_read, +sys_write, sys_open, sys_close, sys_waitpid, sys_creat, sys_link, +sys_unlink, sys_execve, sys_chdir, sys_time, sys_mknod, sys_chmod, +sys_chown, sys_break, sys_stat, sys_lseek, sys_getpid, sys_mount, +sys_umount, sys_setuid, sys_getuid, sys_stime, sys_ptrace, sys_alarm, +sys_fstat, sys_pause, sys_utime, sys_stty, sys_gtty, sys_access, +sys_nice, sys_ftime, sys_sync, sys_kill, sys_rename, sys_mkdir, +sys_rmdir, sys_dup, sys_pipe, sys_times, sys_prof, sys_brk, sys_setgid, +sys_getgid, sys_signal, sys_geteuid, sys_getegid, sys_acct, sys_phys, +sys_lock, sys_ioctl, sys_fcntl, sys_mpx, sys_setpgid, sys_ulimit, +sys_uname, sys_umask, sys_chroot, sys_ustat, sys_dup2, sys_getppid, +sys_getpgrp, sys_setsid, sys_sigaction, sys_sgetmask, sys_ssetmask, +sys_setreuid,sys_setregid, sys_sigsuspend, sys_sigpending, sys_sethostname, +sys_setrlimit, sys_getrlimit, sys_getrusage, sys_gettimeofday, +sys_settimeofday, sys_getgroups, sys_setgroups, sys_select, sys_symlink, +sys_lstat, sys_readlink, sys_uselib, sys_execve2, sys_getdents, sys_pipe2, +sys_sleep, sys_getcwd}; + +/* So we don't have to do any more manual updating.... */ +int NR_syscalls = sizeof(sys_call_table)/sizeof(fn_ptr); diff --git a/110_master/110/os/os/linux/include/linux/tty.h b/110_master/110/os/os/linux/include/linux/tty.h new file mode 100644 index 0000000..ad846b3 --- /dev/null +++ b/110_master/110/os/os/linux/include/linux/tty.h @@ -0,0 +1,77 @@ +/* + * 'tty.h' defines some structures used by tty_io.c and some defines. + * + * NOTE! Don't touch this without checking that nothing in rs_io.s or + * con_io.s breaks. Some constants are hardwired into the system (mainly + * offsets into 'tty_queue' + */ + +#ifndef _TTY_H +#define _TTY_H + +#include + +#define TTY_BUF_SIZE 1024 + +struct tty_queue { + unsigned long data; + unsigned long head; + unsigned long tail; + struct task_struct * proc_list; + char buf[TTY_BUF_SIZE]; +}; + +#define INC(a) ((a) = ((a)+1) & (TTY_BUF_SIZE-1)) +#define DEC(a) ((a) = ((a)-1) & (TTY_BUF_SIZE-1)) +#define EMPTY(a) ((a).head == (a).tail) +#define LEFT(a) (((a).tail-(a).head-1)&(TTY_BUF_SIZE-1)) +#define LAST(a) ((a).buf[(TTY_BUF_SIZE-1)&((a).head-1)]) +#define FULL(a) (!LEFT(a)) +#define CHARS(a) (((a).head-(a).tail)&(TTY_BUF_SIZE-1)) +#define GETCH(queue,c) \ +(void)({c=(queue).buf[(queue).tail];INC((queue).tail);}) +#define PUTCH(c,queue) \ +(void)({(queue).buf[(queue).head]=(c);INC((queue).head);}) + +#define INTR_CHAR(tty) ((tty)->termios.c_cc[VINTR]) +#define QUIT_CHAR(tty) ((tty)->termios.c_cc[VQUIT]) +#define ERASE_CHAR(tty) ((tty)->termios.c_cc[VERASE]) +#define KILL_CHAR(tty) ((tty)->termios.c_cc[VKILL]) +#define EOF_CHAR(tty) ((tty)->termios.c_cc[VEOF]) +#define START_CHAR(tty) ((tty)->termios.c_cc[VSTART]) +#define STOP_CHAR(tty) ((tty)->termios.c_cc[VSTOP]) +#define SUSPEND_CHAR(tty) ((tty)->termios.c_cc[VSUSP]) + +struct tty_struct { + struct termios termios; + int pgrp; + int stopped; + void (*write)(struct tty_struct * tty); + struct tty_queue read_q; + struct tty_queue write_q; + struct tty_queue secondary; + }; + +extern struct tty_struct tty_table[]; + +/* 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 +*/ +#define INIT_C_CC "\003\034\177\025\004\0\1\0\021\023\032\0\022\017\027\026\0" + +void rs_init(void); +void con_init(void); +void tty_init(void); + +int tty_read(unsigned c, char * buf, int n); +int tty_write(unsigned c, char * buf, int n); + +void rs_write(struct tty_struct * tty); +void con_write(struct tty_struct * tty); + +void copy_to_cooked(struct tty_struct * tty); + +#endif diff --git a/110_master/110/os/os/linux/include/new0.h b/110_master/110/os/os/linux/include/new0.h new file mode 100644 index 0000000..5f265eb --- /dev/null +++ b/110_master/110/os/os/linux/include/new0.h @@ -0,0 +1,30 @@ +#ifndef _NEW_H +#define _NEW_H + +#include + +struct linux_dirent { + long d_ino; + off_t d_off; + unsigned short d_reclen; + char d_name[14]; +}; + +/* Return value of `mmap' in case of an error. */ +#define MAP_FAILED ((void *) -1) + +#define PROT_READ 0x1 /* page can be read */ +#define PROT_WRITE 0x2 /* page can be written */ +#define PROT_EXEC 0x4 /* page can be executed */ +#define PROT_SEM 0x8 /* page may be used for atomic ops */ +#define PROT_NONE 0x0 /* page can not be accessed */ + +/* compatibility flags */ +#define MAP_FILE 0 + +#define MAP_SHARED 0x01 /* Share changes */ +#define MAP_PRIVATE 0x02 /* Changes are private */ + +#define CLONE_VM 0x00000100 /* set if VM shared between processes */ + +#endif \ No newline at end of file diff --git a/110_master/110/os/os/linux/include/signal.h b/110_master/110/os/os/linux/include/signal.h new file mode 100644 index 0000000..0eea9a3 --- /dev/null +++ b/110_master/110/os/os/linux/include/signal.h @@ -0,0 +1,68 @@ +#ifndef _SIGNAL_H +#define _SIGNAL_H + +#include + +typedef int sig_atomic_t; +typedef unsigned int sigset_t; /* 32 bits */ + +#define _NSIG 32 +#define NSIG _NSIG + +#define SIGHUP 1 +#define SIGINT 2 +#define SIGQUIT 3 +#define SIGILL 4 +#define SIGTRAP 5 +#define SIGABRT 6 +#define SIGIOT 6 +#define SIGUNUSED 7 +#define SIGFPE 8 +#define SIGKILL 9 +#define SIGUSR1 10 +#define SIGSEGV 11 +#define SIGUSR2 12 +#define SIGPIPE 13 +#define SIGALRM 14 +#define SIGTERM 15 +#define SIGSTKFLT 16 +#define SIGCHLD 17 +#define SIGCONT 18 +#define SIGSTOP 19 +#define SIGTSTP 20 +#define SIGTTIN 21 +#define SIGTTOU 22 + +/* Ok, I haven't implemented sigactions, but trying to keep headers POSIX */ +#define SA_NOCLDSTOP 1 +#define SA_NOMASK 0x40000000 +#define SA_ONESHOT 0x80000000 + +#define SIG_BLOCK 0 /* for blocking signals */ +#define SIG_UNBLOCK 1 /* for unblocking signals */ +#define SIG_SETMASK 2 /* for setting the signal mask */ + +#define SIG_DFL ((void (*)(int))0) /* default signal handling */ +#define SIG_IGN ((void (*)(int))1) /* ignore signal */ + +struct sigaction { + void (*sa_handler)(int); + sigset_t sa_mask; + int sa_flags; + void (*sa_restorer)(void); +}; + +void (*signal(int _sig, void (*_func)(int)))(int); +int raise(int sig); +int kill(pid_t pid, int sig); +int sigaddset(sigset_t *mask, int signo); +int sigdelset(sigset_t *mask, int signo); +int sigemptyset(sigset_t *mask); +int sigfillset(sigset_t *mask); +int sigismember(sigset_t *mask, int signo); /* 1 - is, 0 - not, -1 error */ +int sigpending(sigset_t *set); +int sigprocmask(int how, sigset_t *set, sigset_t *oldset); +int sigsuspend(sigset_t *sigmask); +int sigaction(int sig, struct sigaction *act, struct sigaction *oldact); + +#endif /* _SIGNAL_H */ diff --git a/110_master/110/os/os/linux/include/stdarg.h b/110_master/110/os/os/linux/include/stdarg.h new file mode 100644 index 0000000..fd79ec0 --- /dev/null +++ b/110_master/110/os/os/linux/include/stdarg.h @@ -0,0 +1,28 @@ +#ifndef _STDARG_H +#define _STDARG_H + +typedef char *va_list; + +/* Amount of space required in an argument list for an arg of type TYPE. + TYPE may alternatively be an expression whose type is used. */ + +#define __va_rounded_size(TYPE) \ + (((sizeof (TYPE) + sizeof (int) - 1) / sizeof (int)) * sizeof (int)) + +#ifndef __sparc__ +#define va_start(AP, LASTARG) \ + (AP = ((char *) &(LASTARG) + __va_rounded_size (LASTARG))) +#else +#define va_start(AP, LASTARG) \ + (__builtin_saveregs (), \ + AP = ((char *) &(LASTARG) + __va_rounded_size (LASTARG))) +#endif + +void va_end (va_list); /* Defined in gnulib */ +#define va_end(AP) + +#define va_arg(AP, TYPE) \ + (AP += __va_rounded_size (TYPE), \ + *((TYPE *) (AP - __va_rounded_size (TYPE)))) + +#endif /* _STDARG_H */ diff --git a/110_master/110/os/os/linux/include/stddef.h b/110_master/110/os/os/linux/include/stddef.h new file mode 100644 index 0000000..97f72ff --- /dev/null +++ b/110_master/110/os/os/linux/include/stddef.h @@ -0,0 +1,19 @@ +#ifndef _STDDEF_H +#define _STDDEF_H + +#ifndef _PTRDIFF_T +#define _PTRDIFF_T +typedef long ptrdiff_t; +#endif + +#ifndef _SIZE_T +#define _SIZE_T +typedef unsigned long size_t; +#endif + +#undef NULL +#define NULL ((void *)0) + +#define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER) + +#endif diff --git a/110_master/110/os/os/linux/include/string.h b/110_master/110/os/os/linux/include/string.h new file mode 100644 index 0000000..48b91e5 --- /dev/null +++ b/110_master/110/os/os/linux/include/string.h @@ -0,0 +1,405 @@ +#ifndef _STRING_H_ +#define _STRING_H_ + +#ifndef NULL +#define NULL ((void *) 0) +#endif + +#ifndef _SIZE_T +#define _SIZE_T +typedef unsigned int size_t; +#endif + +extern char * strerror(int errno); + +/* + * This string-include defines all string functions as inline + * functions. Use gcc. It also assumes ds=es=data space, this should be + * normal. Most of the string-functions are rather heavily hand-optimized, + * see especially strtok,strstr,str[c]spn. They should work, but are not + * very easy to understand. Everything is done entirely within the register + * set, making the functions fast and clean. String instructions have been + * used through-out, making for "slightly" unclear code :-) + * + * (C) 1991 Linus Torvalds + */ + +extern inline char * strcpy(char * dest,const char *src) +{ +__asm__("cld\n" + "1:\tlodsb\n\t" + "stosb\n\t" + "testb %%al,%%al\n\t" + "jne 1b" + ::"S" (src),"D" (dest)); +return dest; +} + +extern inline char * strncpy(char * dest,const char *src,int count) +{ +__asm__("cld\n" + "1:\tdecl %2\n\t" + "js 2f\n\t" + "lodsb\n\t" + "stosb\n\t" + "testb %%al,%%al\n\t" + "jne 1b\n\t" + "rep\n\t" + "stosb\n" + "2:" + ::"S" (src),"D" (dest),"c" (count)); +return dest; +} + +extern inline char * strcat(char * dest,const char * src) +{ +__asm__("cld\n\t" + "repne\n\t" + "scasb\n\t" + "decl %1\n" + "1:\tlodsb\n\t" + "stosb\n\t" + "testb %%al,%%al\n\t" + "jne 1b" + ::"S" (src),"D" (dest),"a" (0),"c" (0xffffffff)); +return dest; +} + +extern inline char * strncat(char * dest,const char * src,int count) +{ +__asm__("cld\n\t" + "repne\n\t" + "scasb\n\t" + "decl %1\n\t" + "movl %4,%3\n" + "1:\tdecl %3\n\t" + "js 2f\n\t" + "lodsb\n\t" + "stosb\n\t" + "testb %%al,%%al\n\t" + "jne 1b\n" + "2:\txorl %2,%2\n\t" + "stosb" + ::"S" (src),"D" (dest),"a" (0),"c" (0xffffffff),"g" (count) + ); +return dest; +} + +extern inline int strcmp(const char * cs,const char * ct) +{ +register int __res __asm__("ax"); +__asm__("cld\n" + "1:\tlodsb\n\t" + "scasb\n\t" + "jne 2f\n\t" + "testb %%al,%%al\n\t" + "jne 1b\n\t" + "xorl %%eax,%%eax\n\t" + "jmp 3f\n" + "2:\tmovl $1,%%eax\n\t" + "jl 3f\n\t" + "negl %%eax\n" + "3:" + :"=a" (__res):"D" (cs),"S" (ct)); +return __res; +} + +extern inline int strncmp(const char * cs,const char * ct,int count) +{ +register int __res __asm__("ax"); +__asm__("cld\n" + "1:\tdecl %3\n\t" + "js 2f\n\t" + "lodsb\n\t" + "scasb\n\t" + "jne 3f\n\t" + "testb %%al,%%al\n\t" + "jne 1b\n" + "2:\txorl %%eax,%%eax\n\t" + "jmp 4f\n" + "3:\tmovl $1,%%eax\n\t" + "jl 4f\n\t" + "negl %%eax\n" + "4:" + :"=a" (__res):"D" (cs),"S" (ct),"c" (count)); +return __res; +} + +extern inline char * strchr(const char * s,char c) +{ +register char * __res __asm__("ax"); +__asm__("cld\n\t" + "movb %%al,%%ah\n" + "1:\tlodsb\n\t" + "cmpb %%ah,%%al\n\t" + "je 2f\n\t" + "testb %%al,%%al\n\t" + "jne 1b\n\t" + "movl $1,%1\n" + "2:\tmovl %1,%0\n\t" + "decl %0" + :"=a" (__res):"S" (s),"0" (c)); +return __res; +} + +extern inline char * strrchr(const char * s,char c) +{ +register char * __res __asm__("dx"); +__asm__("cld\n\t" + "movb %%al,%%ah\n" + "1:\tlodsb\n\t" + "cmpb %%ah,%%al\n\t" + "jne 2f\n\t" + "movl %%esi,%0\n\t" + "decl %0\n" + "2:\ttestb %%al,%%al\n\t" + "jne 1b" + :"=d" (__res):"0" (0),"S" (s),"a" (c)); +return __res; +} + +extern inline int strspn(const char * cs, const char * ct) +{ +register char * __res __asm__("si"); +__asm__("cld\n\t" + "movl %4,%%edi\n\t" + "repne\n\t" + "scasb\n\t" + "notl %%ecx\n\t" + "decl %%ecx\n\t" + "movl %%ecx,%%edx\n" + "1:\tlodsb\n\t" + "testb %%al,%%al\n\t" + "je 2f\n\t" + "movl %4,%%edi\n\t" + "movl %%edx,%%ecx\n\t" + "repne\n\t" + "scasb\n\t" + "je 1b\n" + "2:\tdecl %0" + :"=S" (__res):"a" (0),"c" (0xffffffff),"0" (cs),"g" (ct) + ); +return __res-cs; +} + +extern inline int strcspn(const char * cs, const char * ct) +{ +register char * __res __asm__("si"); +__asm__("cld\n\t" + "movl %4,%%edi\n\t" + "repne\n\t" + "scasb\n\t" + "notl %%ecx\n\t" + "decl %%ecx\n\t" + "movl %%ecx,%%edx\n" + "1:\tlodsb\n\t" + "testb %%al,%%al\n\t" + "je 2f\n\t" + "movl %4,%%edi\n\t" + "movl %%edx,%%ecx\n\t" + "repne\n\t" + "scasb\n\t" + "jne 1b\n" + "2:\tdecl %0" + :"=S" (__res):"a" (0),"c" (0xffffffff),"0" (cs),"g" (ct) + ); +return __res-cs; +} + +extern inline char * strpbrk(const char * cs,const char * ct) +{ +register char * __res __asm__("si"); +__asm__("cld\n\t" + "movl %4,%%edi\n\t" + "repne\n\t" + "scasb\n\t" + "notl %%ecx\n\t" + "decl %%ecx\n\t" + "movl %%ecx,%%edx\n" + "1:\tlodsb\n\t" + "testb %%al,%%al\n\t" + "je 2f\n\t" + "movl %4,%%edi\n\t" + "movl %%edx,%%ecx\n\t" + "repne\n\t" + "scasb\n\t" + "jne 1b\n\t" + "decl %0\n\t" + "jmp 3f\n" + "2:\txorl %0,%0\n" + "3:" + :"=S" (__res):"a" (0),"c" (0xffffffff),"0" (cs),"g" (ct) + ); +return __res; +} + +extern inline char * strstr(const char * cs,const char * ct) +{ +register char * __res __asm__("ax"); +__asm__("cld\n\t" \ + "movl %4,%%edi\n\t" + "repne\n\t" + "scasb\n\t" + "notl %%ecx\n\t" + "decl %%ecx\n\t" /* NOTE! This also sets Z if searchstring='' */ + "movl %%ecx,%%edx\n" + "1:\tmovl %4,%%edi\n\t" + "movl %%esi,%%eax\n\t" + "movl %%edx,%%ecx\n\t" + "repe\n\t" + "cmpsb\n\t" + "je 2f\n\t" /* also works for empty string, see above */ + "xchgl %%eax,%%esi\n\t" + "incl %%esi\n\t" + "cmpb $0,-1(%%eax)\n\t" + "jne 1b\n\t" + "xorl %%eax,%%eax\n\t" + "2:" + :"=a" (__res):"0" (0),"c" (0xffffffff),"S" (cs),"g" (ct) + ); +return __res; +} + +extern inline int strlen(const char * s) +{ +register int __res ; +__asm__("cld\n\t" + "repne\n\t" + "scasb\n\t" + "notl %0\n\t" + "decl %0" + :"=c" (__res):"D" (s),"a" (0),"0" (0xffffffff)); +return __res; +} + +extern char * ___strtok; + +extern inline char * strtok(char * s,const char * ct) +{ +register char * __res __asm__("si"); +__asm__("testl %1,%1\n\t" + "jne 1f\n\t" + "testl %0,%0\n\t" + "je 8f\n\t" + "movl %0,%1\n" + "1:\txorl %0,%0\n\t" + "movl $-1,%%ecx\n\t" + "xorl %%eax,%%eax\n\t" + "cld\n\t" + "movl %4,%%edi\n\t" + "repne\n\t" + "scasb\n\t" + "notl %%ecx\n\t" + "decl %%ecx\n\t" + "je 7f\n\t" /* empty delimeter-string */ + "movl %%ecx,%%edx\n" + "2:\tlodsb\n\t" + "testb %%al,%%al\n\t" + "je 7f\n\t" + "movl %4,%%edi\n\t" + "movl %%edx,%%ecx\n\t" + "repne\n\t" + "scasb\n\t" + "je 2b\n\t" + "decl %1\n\t" + "cmpb $0,(%1)\n\t" + "je 7f\n\t" + "movl %1,%0\n" + "3:\tlodsb\n\t" + "testb %%al,%%al\n\t" + "je 5f\n\t" + "movl %4,%%edi\n\t" + "movl %%edx,%%ecx\n\t" + "repne\n\t" + "scasb\n\t" + "jne 3b\n\t" + "decl %1\n\t" + "cmpb $0,(%1)\n\t" + "je 5f\n\t" + "movb $0,(%1)\n\t" + "incl %1\n\t" + "jmp 6f\n" + "5:\txorl %1,%1\n" + "6:\tcmpb $0,(%0)\n\t" + "jne 7f\n\t" + "xorl %0,%0\n" + "7:\ttestl %0,%0\n\t" + "jne 8f\n\t" + "movl %0,%1\n" + "8:" + :"=b" (__res),"=S" (___strtok) + :"0" (___strtok),"1" (s),"g" (ct) + ); +return __res; +} + +extern inline void * memcpy(void * dest,const void * src, int n) +{ +__asm__("cld\n\t" + "rep\n\t" + "movsb" + ::"c" (n),"S" (src),"D" (dest) + ); +return dest; +} + +extern inline void * memmove(void * dest,const void * src, int n) +{ +if (dest + +struct stat { + dev_t st_dev; + ino_t st_ino; + umode_t st_mode; + nlink_t st_nlink; + uid_t st_uid; + gid_t st_gid; + dev_t st_rdev; + off_t st_size; + time_t st_atime; + time_t st_mtime; + time_t st_ctime; +}; + +#define S_IFMT 00170000 +#define S_IFLNK 0120000 +#define S_IFREG 0100000 +#define S_IFBLK 0060000 +#define S_IFDIR 0040000 +#define S_IFCHR 0020000 +#define S_IFIFO 0010000 +#define S_ISUID 0004000 +#define S_ISGID 0002000 +#define S_ISVTX 0001000 + +#define S_ISLNK(m) (((m) & S_IFMT) == S_IFLNK) +#define S_ISREG(m) (((m) & S_IFMT) == S_IFREG) +#define S_ISDIR(m) (((m) & S_IFMT) == S_IFDIR) +#define S_ISCHR(m) (((m) & S_IFMT) == S_IFCHR) +#define S_ISBLK(m) (((m) & S_IFMT) == S_IFBLK) +#define S_ISFIFO(m) (((m) & S_IFMT) == S_IFIFO) + +#define S_IRWXU 00700 +#define S_IRUSR 00400 +#define S_IWUSR 00200 +#define S_IXUSR 00100 + +#define S_IRWXG 00070 +#define S_IRGRP 00040 +#define S_IWGRP 00020 +#define S_IXGRP 00010 + +#define S_IRWXO 00007 +#define S_IROTH 00004 +#define S_IWOTH 00002 +#define S_IXOTH 00001 + +extern int chmod(const char *_path, mode_t mode); +extern int fstat(int fildes, struct stat *stat_buf); +extern int mkdir(const char *_path, mode_t mode); +extern int mkfifo(const char *_path, mode_t mode); +extern int stat(const char *filename, struct stat *stat_buf); +extern mode_t umask(mode_t mask); + +#endif diff --git a/110_master/110/os/os/linux/include/sys/times.h b/110_master/110/os/os/linux/include/sys/times.h new file mode 100644 index 0000000..68d5bfb --- /dev/null +++ b/110_master/110/os/os/linux/include/sys/times.h @@ -0,0 +1,15 @@ +#ifndef _TIMES_H +#define _TIMES_H + +#include + +struct tms { + time_t tms_utime; + time_t tms_stime; + time_t tms_cutime; + time_t tms_cstime; +}; + +extern time_t times(struct tms * tp); + +#endif diff --git a/110_master/110/os/os/linux/include/sys/types.h b/110_master/110/os/os/linux/include/sys/types.h new file mode 100644 index 0000000..557aa31 --- /dev/null +++ b/110_master/110/os/os/linux/include/sys/types.h @@ -0,0 +1,46 @@ +#ifndef _SYS_TYPES_H +#define _SYS_TYPES_H + +#ifndef _SIZE_T +#define _SIZE_T +typedef unsigned int size_t; +#endif + +#ifndef _TIME_T +#define _TIME_T +typedef long time_t; +#endif + +#ifndef _PTRDIFF_T +#define _PTRDIFF_T +typedef long ptrdiff_t; +#endif + +#ifndef NULL +#define NULL ((void *) 0) +#endif + +typedef int pid_t; +typedef unsigned short uid_t; +typedef unsigned char gid_t; +typedef unsigned short dev_t; +typedef unsigned short ino_t; +typedef unsigned short mode_t; +typedef unsigned short umode_t; +typedef unsigned char nlink_t; +typedef int daddr_t; +typedef long off_t; +typedef unsigned char u_char; +typedef unsigned short ushort; + +typedef struct { int quot,rem; } div_t; +typedef struct { long quot,rem; } ldiv_t; + +struct ustat { + daddr_t f_tfree; + ino_t f_tinode; + char f_fname[6]; + char f_fpack[6]; +}; + +#endif diff --git a/110_master/110/os/os/linux/include/sys/utsname.h b/110_master/110/os/os/linux/include/sys/utsname.h new file mode 100644 index 0000000..0a1c5a0 --- /dev/null +++ b/110_master/110/os/os/linux/include/sys/utsname.h @@ -0,0 +1,16 @@ +#ifndef _SYS_UTSNAME_H +#define _SYS_UTSNAME_H + +#include + +struct utsname { + char sysname[9]; + char nodename[9]; + char release[9]; + char version[9]; + char machine[9]; +}; + +extern int uname(struct utsname * utsbuf); + +#endif diff --git a/110_master/110/os/os/linux/include/sys/wait.h b/110_master/110/os/os/linux/include/sys/wait.h new file mode 100644 index 0000000..53190c2 --- /dev/null +++ b/110_master/110/os/os/linux/include/sys/wait.h @@ -0,0 +1,23 @@ +#ifndef _SYS_WAIT_H +#define _SYS_WAIT_H + +#include + +#define _LOW(v) ( (v) & 0377) +#define _HIGH(v) ( ((v) >> 8) & 0377) + +/* options for waitpid, WUNTRACED not supported */ +#define WNOHANG 1 +#define WUNTRACED 2 + +#define WIFEXITED(s) (!((s)&0xFF) +#define WIFSTOPPED(s) (((s)&0xFF)==0x7F) +#define WEXITSTATUS(s) (((s)>>8)&0xFF) +#define WTERMSIG(s) ((s)&0x7F) +#define WSTOPSIG(s) (((s)>>8)&0xFF) +#define WIFSIGNALED(s) (((unsigned int)(s)-1 & 0xFFFF) < 0xFF) + +pid_t wait(int *stat_loc); +pid_t waitpid(pid_t pid, int *stat_loc, int options); + +#endif diff --git a/110_master/110/os/os/linux/include/termios.h b/110_master/110/os/os/linux/include/termios.h new file mode 100644 index 0000000..2b7b913 --- /dev/null +++ b/110_master/110/os/os/linux/include/termios.h @@ -0,0 +1,228 @@ +#ifndef _TERMIOS_H +#define _TERMIOS_H + +#define TTY_BUF_SIZE 1024 + +/* 0x54 is just a magic number to make these relatively uniqe ('T') */ + +#define TCGETS 0x5401 +#define TCSETS 0x5402 +#define TCSETSW 0x5403 +#define TCSETSF 0x5404 +#define TCGETA 0x5405 +#define TCSETA 0x5406 +#define TCSETAW 0x5407 +#define TCSETAF 0x5408 +#define TCSBRK 0x5409 +#define TCXONC 0x540A +#define TCFLSH 0x540B +#define TIOCEXCL 0x540C +#define TIOCNXCL 0x540D +#define TIOCSCTTY 0x540E +#define TIOCGPGRP 0x540F +#define TIOCSPGRP 0x5410 +#define TIOCOUTQ 0x5411 +#define TIOCSTI 0x5412 +#define TIOCGWINSZ 0x5413 +#define TIOCSWINSZ 0x5414 +#define TIOCMGET 0x5415 +#define TIOCMBIS 0x5416 +#define TIOCMBIC 0x5417 +#define TIOCMSET 0x5418 +#define TIOCGSOFTCAR 0x5419 +#define TIOCSSOFTCAR 0x541A +#define TIOCINQ 0x541B + +struct winsize { + unsigned short ws_row; + unsigned short ws_col; + unsigned short ws_xpixel; + unsigned short ws_ypixel; +}; + +#define NCC 8 +struct termio { + unsigned short c_iflag; /* input mode flags */ + unsigned short c_oflag; /* output mode flags */ + unsigned short c_cflag; /* control mode flags */ + unsigned short c_lflag; /* local mode flags */ + unsigned char c_line; /* line discipline */ + unsigned char c_cc[NCC]; /* control characters */ +}; + +#define NCCS 17 +struct termios { + unsigned long c_iflag; /* input mode flags */ + unsigned long c_oflag; /* output mode flags */ + unsigned long c_cflag; /* control mode flags */ + unsigned long c_lflag; /* local mode flags */ + unsigned char c_line; /* line discipline */ + unsigned char c_cc[NCCS]; /* control characters */ +}; + +/* c_cc characters */ +#define VINTR 0 +#define VQUIT 1 +#define VERASE 2 +#define VKILL 3 +#define VEOF 4 +#define VTIME 5 +#define VMIN 6 +#define VSWTC 7 +#define VSTART 8 +#define VSTOP 9 +#define VSUSP 10 +#define VEOL 11 +#define VREPRINT 12 +#define VDISCARD 13 +#define VWERASE 14 +#define VLNEXT 15 +#define VEOL2 16 + +/* c_iflag bits */ +#define IGNBRK 0000001 +#define BRKINT 0000002 +#define IGNPAR 0000004 +#define PARMRK 0000010 +#define INPCK 0000020 +#define ISTRIP 0000040 +#define INLCR 0000100 +#define IGNCR 0000200 +#define ICRNL 0000400 +#define IUCLC 0001000 +#define IXON 0002000 +#define IXANY 0004000 +#define IXOFF 0010000 +#define IMAXBEL 0020000 + +/* c_oflag bits */ +#define OPOST 0000001 +#define OLCUC 0000002 +#define ONLCR 0000004 +#define OCRNL 0000010 +#define ONOCR 0000020 +#define ONLRET 0000040 +#define OFILL 0000100 +#define OFDEL 0000200 +#define NLDLY 0000400 +#define NL0 0000000 +#define NL1 0000400 +#define CRDLY 0003000 +#define CR0 0000000 +#define CR1 0001000 +#define CR2 0002000 +#define CR3 0003000 +#define TABDLY 0014000 +#define TAB0 0000000 +#define TAB1 0004000 +#define TAB2 0010000 +#define TAB3 0014000 +#define XTABS 0014000 +#define BSDLY 0020000 +#define BS0 0000000 +#define BS1 0020000 +#define VTDLY 0040000 +#define VT0 0000000 +#define VT1 0040000 +#define FFDLY 0040000 +#define FF0 0000000 +#define FF1 0040000 + +/* c_cflag bit meaning */ +#define CBAUD 0000017 +#define B0 0000000 /* hang up */ +#define B50 0000001 +#define B75 0000002 +#define B110 0000003 +#define B134 0000004 +#define B150 0000005 +#define B200 0000006 +#define B300 0000007 +#define B600 0000010 +#define B1200 0000011 +#define B1800 0000012 +#define B2400 0000013 +#define B4800 0000014 +#define B9600 0000015 +#define B19200 0000016 +#define B38400 0000017 +#define EXTA B19200 +#define EXTB B38400 +#define CSIZE 0000060 +#define CS5 0000000 +#define CS6 0000020 +#define CS7 0000040 +#define CS8 0000060 +#define CSTOPB 0000100 +#define CREAD 0000200 +#define CPARENB 0000400 +#define CPARODD 0001000 +#define HUPCL 0002000 +#define CLOCAL 0004000 +#define CIBAUD 03600000 /* input baud rate (not used) */ +#define CRTSCTS 020000000000 /* flow control */ + +#define PARENB CPARENB +#define PARODD CPARODD + +/* c_lflag bits */ +#define ISIG 0000001 +#define ICANON 0000002 +#define XCASE 0000004 +#define ECHO 0000010 +#define ECHOE 0000020 +#define ECHOK 0000040 +#define ECHONL 0000100 +#define NOFLSH 0000200 +#define TOSTOP 0000400 +#define ECHOCTL 0001000 +#define ECHOPRT 0002000 +#define ECHOKE 0004000 +#define FLUSHO 0010000 +#define PENDIN 0040000 +#define IEXTEN 0100000 + +/* modem lines */ +#define TIOCM_LE 0x001 +#define TIOCM_DTR 0x002 +#define TIOCM_RTS 0x004 +#define TIOCM_ST 0x008 +#define TIOCM_SR 0x010 +#define TIOCM_CTS 0x020 +#define TIOCM_CAR 0x040 +#define TIOCM_RNG 0x080 +#define TIOCM_DSR 0x100 +#define TIOCM_CD TIOCM_CAR +#define TIOCM_RI TIOCM_RNG + +/* tcflow() and TCXONC use these */ +#define TCOOFF 0 +#define TCOON 1 +#define TCIOFF 2 +#define TCION 3 + +/* tcflush() and TCFLSH use these */ +#define TCIFLUSH 0 +#define TCOFLUSH 1 +#define TCIOFLUSH 2 + +/* tcsetattr uses these */ +#define TCSANOW 0 +#define TCSADRAIN 1 +#define TCSAFLUSH 2 + +typedef int speed_t; + +extern speed_t cfgetispeed(struct termios *termios_p); +extern speed_t cfgetospeed(struct termios *termios_p); +extern int cfsetispeed(struct termios *termios_p, speed_t speed); +extern int cfsetospeed(struct termios *termios_p, speed_t speed); +extern int tcdrain(int fildes); +extern int tcflow(int fildes, int action); +extern int tcflush(int fildes, int queue_selector); +extern int tcgetattr(int fildes, struct termios *termios_p); +extern int tcsendbreak(int fildes, int duration); +extern int tcsetattr(int fildes, int optional_actions, + struct termios *termios_p); + +#endif diff --git a/110_master/110/os/os/linux/include/time.h b/110_master/110/os/os/linux/include/time.h new file mode 100644 index 0000000..d0a765d --- /dev/null +++ b/110_master/110/os/os/linux/include/time.h @@ -0,0 +1,42 @@ +#ifndef _TIME_H +#define _TIME_H + +#ifndef _TIME_T +#define _TIME_T +typedef long time_t; +#endif + +#ifndef _SIZE_T +#define _SIZE_T +typedef unsigned int size_t; +#endif + +#define CLOCKS_PER_SEC 100 + +typedef long clock_t; + +struct tm { + int tm_sec; + int tm_min; + int tm_hour; + int tm_mday; + int tm_mon; + int tm_year; + int tm_wday; + int tm_yday; + int tm_isdst; +}; + +clock_t clock(void); +time_t time(time_t * tp); +double difftime(time_t time2, time_t time1); +time_t mktime(struct tm * tp); + +char * asctime(const struct tm * tp); +char * ctime(const time_t * tp); +struct tm * gmtime(const time_t *tp); +struct tm *localtime(const time_t * tp); +size_t strftime(char * s, size_t smax, const char * fmt, const struct tm * tp); +void tzset(void); + +#endif diff --git a/110_master/110/os/os/linux/include/unistd.h b/110_master/110/os/os/linux/include/unistd.h new file mode 100644 index 0000000..d0ab29f --- /dev/null +++ b/110_master/110/os/os/linux/include/unistd.h @@ -0,0 +1,276 @@ +#ifndef _UNISTD_H +#define _UNISTD_H + +/* ok, this may be a joke, but I'm working on it */ +#define _POSIX_VERSION 198808L + +#define _POSIX_CHOWN_RESTRICTED /* only root can do a chown (I think..) */ +#define _POSIX_NO_TRUNC /* no pathname truncation (but see in kernel) */ +#define _POSIX_VDISABLE '\0' /* character to disable things like ^C */ +/*#define _POSIX_SAVED_IDS */ /* we'll get to this yet */ +/*#define _POSIX_JOB_CONTROL */ /* we aren't there quite yet. Soon hopefully */ + +#define STDIN_FILENO 0 +#define STDOUT_FILENO 1 +#define STDERR_FILENO 2 + +#ifndef NULL +#define NULL ((void *)0) +#endif + +/* access */ +#define F_OK 0 +#define X_OK 1 +#define W_OK 2 +#define R_OK 4 + +/* lseek */ +#define SEEK_SET 0 +#define SEEK_CUR 1 +#define SEEK_END 2 + +/* _SC stands for System Configuration. We don't use them much */ +#define _SC_ARG_MAX 1 +#define _SC_CHILD_MAX 2 +#define _SC_CLOCKS_PER_SEC 3 +#define _SC_NGROUPS_MAX 4 +#define _SC_OPEN_MAX 5 +#define _SC_JOB_CONTROL 6 +#define _SC_SAVED_IDS 7 +#define _SC_VERSION 8 + +/* more (possibly) configurable things - now pathnames */ +#define _PC_LINK_MAX 1 +#define _PC_MAX_CANON 2 +#define _PC_MAX_INPUT 3 +#define _PC_NAME_MAX 4 +#define _PC_PATH_MAX 5 +#define _PC_PIPE_BUF 6 +#define _PC_NO_TRUNC 7 +#define _PC_VDISABLE 8 +#define _PC_CHOWN_RESTRICTED 9 + +#include +#include +#include +#include + +#ifdef __LIBRARY__ + +#define __NR_setup 0 /* used only by init, to get system going */ +#define __NR_exit 1 +#define __NR_fork 2 +#define __NR_read 3 +#define __NR_write 4 +#define __NR_open 5 +#define __NR_close 6 +#define __NR_waitpid 7 +#define __NR_creat 8 +#define __NR_link 9 +#define __NR_unlink 10 +#define __NR_execve 11 +#define __NR_chdir 12 +#define __NR_time 13 +#define __NR_mknod 14 +#define __NR_chmod 15 +#define __NR_chown 16 +#define __NR_break 17 +#define __NR_stat 18 +#define __NR_lseek 19 +#define __NR_getpid 20 +#define __NR_mount 21 +#define __NR_umount 22 +#define __NR_setuid 23 +#define __NR_getuid 24 +#define __NR_stime 25 +#define __NR_ptrace 26 +#define __NR_alarm 27 +#define __NR_fstat 28 +#define __NR_pause 29 +#define __NR_utime 30 +#define __NR_stty 31 +#define __NR_gtty 32 +#define __NR_access 33 +#define __NR_nice 34 +#define __NR_ftime 35 +#define __NR_sync 36 +#define __NR_kill 37 +#define __NR_rename 38 +#define __NR_mkdir 39 +#define __NR_rmdir 40 +#define __NR_dup 41 +#define __NR_pipe 42 +#define __NR_times 43 +#define __NR_prof 44 +#define __NR_brk 45 +#define __NR_setgid 46 +#define __NR_getgid 47 +#define __NR_signal 48 +#define __NR_geteuid 49 +#define __NR_getegid 50 +#define __NR_acct 51 +#define __NR_phys 52 +#define __NR_lock 53 +#define __NR_ioctl 54 +#define __NR_fcntl 55 +#define __NR_mpx 56 +#define __NR_setpgid 57 +#define __NR_ulimit 58 +#define __NR_uname 59 +#define __NR_umask 60 +#define __NR_chroot 61 +#define __NR_ustat 62 +#define __NR_dup2 63 +#define __NR_getppid 64 +#define __NR_getpgrp 65 +#define __NR_setsid 66 +#define __NR_sigaction 67 +#define __NR_sgetmask 68 +#define __NR_ssetmask 69 +#define __NR_setreuid 70 +#define __NR_setregid 71 +#define __NR_sigsuspend 72 +#define __NR_sigpending 73 +#define __NR_sethostname 74 +#define __NR_setrlimit 75 +#define __NR_getrlimit 76 +#define __NR_getrusage 77 +#define __NR_gettimeofday 78 +#define __NR_settimeofday 79 +#define __NR_getgroups 80 +#define __NR_setgroups 81 +#define __NR_select 82 +#define __NR_symlink 83 +#define __NR_lstat 84 +#define __NR_readlink 85 +#define __NR_uselib 86 +#define __NR_execve2 87 +#define __NR_getdents 88 +#define __NR_pipe2 89 +#define __NR_sleep 90 +#define __NR_getcwd 91 +#define _syscall0(type,name) \ +type name(void) \ +{ \ +long __res; \ +__asm__ volatile ("int $0x80" \ + : "=a" (__res) \ + : "0" (__NR_##name)); \ +if (__res >= 0) \ + return (type) __res; \ +errno = -__res; \ +return -1; \ +} + +#define _syscall1(type,name,atype,a) \ +type name(atype a) \ +{ \ +long __res; \ +__asm__ volatile ("int $0x80" \ + : "=a" (__res) \ + : "0" (__NR_##name),"b" ((long)(a))); \ +if (__res >= 0) \ + return (type) __res; \ +errno = -__res; \ +return -1; \ +} + +#define _syscall2(type,name,atype,a,btype,b) \ +type name(atype a,btype b) \ +{ \ +long __res; \ +__asm__ volatile ("int $0x80" \ + : "=a" (__res) \ + : "0" (__NR_##name),"b" ((long)(a)),"c" ((long)(b))); \ +if (__res >= 0) \ + return (type) __res; \ +errno = -__res; \ +return -1; \ +} + +#define _syscall3(type,name,atype,a,btype,b,ctype,c) \ +type name(atype a,btype b,ctype c) \ +{ \ +long __res; \ +__asm__ volatile ("int $0x80" \ + : "=a" (__res) \ + : "0" (__NR_##name),"b" ((long)(a)),"c" ((long)(b)),"d" ((long)(c))); \ +if (__res>=0) \ + return (type) __res; \ +errno=-__res; \ +return -1; \ +} + +#endif /* __LIBRARY__ */ + +extern int errno; + +int access(const char * filename, mode_t mode); +int acct(const char * filename); +int alarm(int sec); +int brk(void * end_data_segment); +void * sbrk(ptrdiff_t increment); +int chdir(const char * filename); +int chmod(const char * filename, mode_t mode); +int chown(const char * filename, uid_t owner, gid_t group); +int chroot(const char * filename); +int close(int fildes); +int creat(const char * filename, mode_t mode); +int dup(int fildes); +int execve(const char * filename, char ** argv, char ** envp); +int execv(const char * pathname, char ** argv); +int execvp(const char * file, char ** argv); +int execl(const char * pathname, char * arg0, ...); +int execlp(const char * file, char * arg0, ...); +int execle(const char * pathname, char * arg0, ...); +volatile void exit(int status); +volatile void _exit(int status); +int fcntl(int fildes, int cmd, ...); +int fork(void); +int getpid(void); +int getuid(void); +int geteuid(void); +int getgid(void); +int getegid(void); +int ioctl(int fildes, int cmd, ...); +int kill(pid_t pid, int signal); +int link(const char * filename1, const char * filename2); +int lseek(int fildes, off_t offset, int origin); +int mknod(const char * filename, mode_t mode, dev_t dev); +int mount(const char * specialfile, const char * dir, int rwflag); +int nice(int val); +int open(const char * filename, int flag, ...); +int pause(void); +int pipe(int * fildes); +int read(int fildes, char * buf, off_t count); +int setpgrp(void); +int setpgid(pid_t pid,pid_t pgid); +int setuid(uid_t uid); +int setgid(gid_t gid); +void (*signal(int sig, void (*fn)(int)))(int); +int stat(const char * filename, struct stat * stat_buf); +int fstat(int fildes, struct stat * stat_buf); +int stime(time_t * tptr); +int sync(void); +time_t time(time_t * tloc); +time_t times(struct tms * tbuf); +int ulimit(int cmd, long limit); +mode_t umask(mode_t mask); +int umount(const char * specialfile); +int uname(struct utsname * name); +int unlink(const char * filename); +int ustat(dev_t dev, struct ustat * ubuf); +int utime(const char * filename, struct utimbuf * times); +pid_t waitpid(pid_t pid,int * wait_stat,int options); +pid_t wait(int * wait_stat); +int write(int fildes, const char * buf, off_t count); +int dup2(int oldfd, int newfd); +int getppid(void); +pid_t getpgrp(void); +pid_t setsid(void); +int sys_getdents(unsigned int fd, struct linux_dirent *d, unsigned int count); +int sys_pipe2(unsigned long * fildes,int flag); +int sys_sleep(unsigned int seconds); +#define __always_inline inline __attribute__((always_inline)) + +#endif diff --git a/110_master/110/os/os/linux/include/utime.h b/110_master/110/os/os/linux/include/utime.h new file mode 100644 index 0000000..83f07c7 --- /dev/null +++ b/110_master/110/os/os/linux/include/utime.h @@ -0,0 +1,13 @@ +#ifndef _UTIME_H +#define _UTIME_H + +#include /* I know - shouldn't do this, but .. */ + +struct utimbuf { + time_t actime; + time_t modtime; +}; + +extern int utime(const char *filename, struct utimbuf *times); + +#endif diff --git a/110_master/110/os/os/linux/init/main.c b/110_master/110/os/os/linux/init/main.c new file mode 100644 index 0000000..bd86a68 --- /dev/null +++ b/110_master/110/os/os/linux/init/main.c @@ -0,0 +1,216 @@ +/* + * linux/init/main.c + * + * (C) 1991 Linus Torvalds + */ + +#define __LIBRARY__ +#include +#include + +/* + * we need this inline - forking from kernel space will result + * in NO COPY ON WRITE (!!!), until an execve is executed. This + * is no problem, but for the stack. This is handled by not letting + * main() use the stack at all after fork(). Thus, no function + * calls - which means inline code for fork too, as otherwise we + * would use the stack upon exit from 'fork()'. + * + * Actually only pause and fork are needed inline, so that there + * won't be any messing with the stack from main(), but we define + * some others too. + */ + +__always_inline _syscall0(int,fork) +__always_inline _syscall0(int,pause) +__always_inline _syscall1(int,setup,void *,BIOS) +__always_inline _syscall0(int,sync) + +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include + +static char printbuf[1024]; + +extern int vsprintf(); +extern void init(void); +extern void blk_dev_init(void); +extern void chr_dev_init(void); +extern void hd_init(void); +extern void floppy_init(void); +extern void mem_init(long start, long end); +extern long rd_init(long mem_start, int length); +extern long kernel_mktime(struct tm * tm); +extern long startup_time; + +/* + * This is set up by the setup-routine at boot-time + */ +#define EXT_MEM_K (*(unsigned short *)0x90002) +#define DRIVE_INFO (*(struct drive_info *)0x90080) +#define ORIG_ROOT_DEV (*(unsigned short *)0x901FC) + +/* + * Yeah, yeah, it's ugly, but I cannot find how to do this correctly + * and this seems to work. I anybody has more info on the real-time + * clock I'd be interested. Most of this was trial and error, and some + * bios-listing reading. Urghh. + */ + +#define CMOS_READ(addr) ({ \ +outb_p(0x80|addr,0x70); \ +inb_p(0x71); \ +}) + +#define BCD_TO_BIN(val) ((val)=((val)&15) + ((val)>>4)*10) + +static void time_init(void) +{ + struct tm time; + + do { + time.tm_sec = CMOS_READ(0); + time.tm_min = CMOS_READ(2); + time.tm_hour = CMOS_READ(4); + time.tm_mday = CMOS_READ(7); + time.tm_mon = CMOS_READ(8); + time.tm_year = CMOS_READ(9); + } while (time.tm_sec != CMOS_READ(0)); + BCD_TO_BIN(time.tm_sec); + BCD_TO_BIN(time.tm_min); + BCD_TO_BIN(time.tm_hour); + BCD_TO_BIN(time.tm_mday); + BCD_TO_BIN(time.tm_mon); + BCD_TO_BIN(time.tm_year); + time.tm_mon--; + startup_time = kernel_mktime(&time); +} + +static long memory_end = 0; +static long buffer_memory_end = 0; +static long main_memory_start = 0; + +struct drive_info { char dummy[32]; } drive_info; + +void main(void) /* This really IS void, no error here. */ +{ /* The startup routine assumes (well, ...) this */ +/* + * Interrupts are still disabled. Do necessary setups, then + * enable them + */ + ROOT_DEV = ORIG_ROOT_DEV; + __asm__ volatile ("cld"); /* by wyj */ + drive_info = DRIVE_INFO; + memory_end = (1<<20) + (EXT_MEM_K<<10); + memory_end &= 0xfffff000; + if (memory_end > 16*1024*1024) + memory_end = 16*1024*1024; + if (memory_end > 12*1024*1024) + buffer_memory_end = 4*1024*1024; + else if (memory_end > 6*1024*1024) + buffer_memory_end = 2*1024*1024; + else + buffer_memory_end = 1*1024*1024; + main_memory_start = buffer_memory_end; +#ifdef RAMDISK + main_memory_start += rd_init(main_memory_start, RAMDISK*1024); +#endif + mem_init(main_memory_start,memory_end); + trap_init(); + blk_dev_init(); + chr_dev_init(); + tty_init(); + time_init(); + sched_init(); + buffer_init(buffer_memory_end); + hd_init(); + floppy_init(); + sti(); + move_to_user_mode(); + if (!fork()) { /* we count on this going ok */ + init(); + } +/* + * NOTE!! For any other task 'pause()' would mean we have to get a + * signal to awaken, but task0 is the sole exception (see 'schedule()') + * as task 0 gets activated at every idle moment (when no other tasks + * can run). For task0 'pause()' just means we go check if some other + * task can run, and if not we return here. + */ + for(;;) pause(); +} + +static int printf(const char *fmt, ...) +{ + va_list args; + int i; + + va_start(args, fmt); + write(1,printbuf,i=vsprintf(printbuf, fmt, args)); + va_end(args); + return i; +} + +static char * argv_rc[] = { "/bin/sh", NULL }; +static char * envp_rc[] = { "HOME=/", NULL, NULL }; + +static char * argv[] = { "-/bin/sh",NULL }; +static char * envp[] = { "HOME=/usr/root", NULL, NULL }; + +void init(void) +{ + int pid,i; + + setup((void *) &drive_info); + (void) open("/dev/tty0",O_RDWR,0); + (void) dup(0); + (void) dup(0); + printf("%d buffers = %d bytes buffer space\n\r",NR_BUFFERS, + NR_BUFFERS*BLOCK_SIZE); + printf("Free mem: %d bytes\n\r",memory_end-main_memory_start); + if (!(pid=fork())) { + close(0); + if (open("/etc/rc",O_RDONLY,0)) + _exit(1); + execve("/bin/sh",argv_rc,envp_rc); + _exit(2); + } + if (pid>0) + while (pid != wait(&i)) + /* nothing */; + while (1) { + if ((pid=fork())<0) { + printf("Fork failed in init\r\n"); + continue; + } + if (!pid) { + close(0);close(1);close(2); + setsid(); + (void) open("/dev/tty0",O_RDWR,0); + (void) dup(0); + (void) dup(0); + _exit(execve("/bin/sh",argv,envp)); + } + while (1) + if (pid == wait(&i)) + break; + printf("\n\rchild %d died with code %04x\n\r",pid,i); + sync(); + } + _exit(0); /* NOTE! _exit, not exit() */ +} + +void print_nr(int sid) +{ + if (sid > 86) + printk(" --syscall: sid=%d, pid=%d\n", sid, current->pid); +} diff --git a/110_master/110/os/os/linux/init/main.o b/110_master/110/os/os/linux/init/main.o new file mode 100644 index 0000000000000000000000000000000000000000..03263d3eb0949ce4e61a59fb169e9f5235d01092 GIT binary patch literal 12208 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 tmp_make + (for i in *.c;do echo -n `echo $$i | sed 's,\.c,\.s,'`" "; \ + $(CPP) -M $$i;done) >> tmp_make + cp tmp_make Makefile + (cd chr_drv; make dep) + (cd blk_drv; make dep) + +### Dependencies: +exit.s exit.o : exit.c ../include/errno.h ../include/signal.h \ + ../include/sys/types.h ../include/sys/wait.h ../include/linux/sched.h \ + ../include/linux/head.h ../include/linux/fs.h ../include/linux/mm.h \ + ../include/linux/kernel.h ../include/linux/tty.h ../include/termios.h \ + ../include/asm/segment.h +fork.s fork.o : fork.c ../include/errno.h ../include/linux/sched.h \ + ../include/linux/head.h ../include/linux/fs.h ../include/sys/types.h \ + ../include/linux/mm.h ../include/signal.h ../include/linux/kernel.h \ + ../include/asm/segment.h ../include/asm/system.h +mktime.s mktime.o : mktime.c ../include/time.h +panic.s panic.o : panic.c ../include/linux/kernel.h ../include/linux/sched.h \ + ../include/linux/head.h ../include/linux/fs.h ../include/sys/types.h \ + ../include/linux/mm.h ../include/signal.h +printk.s printk.o : printk.c ../include/stdarg.h ../include/stddef.h \ + ../include/linux/kernel.h +sched.s sched.o : sched.c ../include/linux/sched.h ../include/linux/head.h \ + ../include/linux/fs.h ../include/sys/types.h ../include/linux/mm.h \ + ../include/signal.h ../include/linux/kernel.h ../include/linux/sys.h \ + ../include/linux/fdreg.h ../include/asm/system.h ../include/asm/io.h \ + ../include/asm/segment.h +signal.s signal.o : signal.c ../include/linux/sched.h ../include/linux/head.h \ + ../include/linux/fs.h ../include/sys/types.h ../include/linux/mm.h \ + ../include/signal.h ../include/linux/kernel.h ../include/asm/segment.h +sys.s sys.o : sys.c ../include/errno.h ../include/linux/sched.h \ + ../include/linux/head.h ../include/linux/fs.h ../include/sys/types.h \ + ../include/linux/mm.h ../include/signal.h ../include/linux/tty.h \ + ../include/termios.h ../include/linux/kernel.h ../include/asm/segment.h \ + ../include/sys/times.h ../include/sys/utsname.h +traps.s traps.o : traps.c ../include/string.h ../include/linux/head.h \ + ../include/linux/sched.h ../include/linux/fs.h ../include/sys/types.h \ + ../include/linux/mm.h ../include/signal.h ../include/linux/kernel.h \ + ../include/asm/system.h ../include/asm/segment.h ../include/asm/io.h +vsprintf.s vsprintf.o : vsprintf.c ../include/stdarg.h ../include/string.h diff --git a/110_master/110/os/os/linux/kernel/asm.o b/110_master/110/os/os/linux/kernel/asm.o new file mode 100644 index 0000000000000000000000000000000000000000..a89ec75e6e7dea54ae5b8d9b94ba28158b48a77f GIT binary patch literal 1740 zcma)+O=uHQ5XWcRv}sSZ2!7VKN<_gLTB@F^9;`i75B*Zxid{F^*K{@67k4+Yil|sH zrv|)<7wbhmD2RBl?IjkWde90*5b+=$0#XkiyeY()eY^2xiRgpv|Nnb$W-{}d&9$S) z`xHe1e<@H4e+Zz*gMDtmZfJlym?EDGMTQ55PMti_THiEx4rWIp9YYK2@F4#&zm)${ zdN=d3q3K?@?aYKaK6ZL^#Z6j!Eo4c^qL61o9t*iIN>a0?YOGAXEIm;+mxxDna!+$#}~zPg>(|qFzDh#3ziNdZhm7_Gt$HGtt5$ zJb2(2L6$5XS6!9gLaHZMBo4WC>dM&)G@;K)yrt}^F9miX@AvkI_oDBSxC{Lei4UOf zm-sOHL5cg&k4j8uHzb}wuS$Fw{k+6C(HA7XgML}!hv?r*yy$rny5~3eqzG`)Jgcaa zE(!kRc@m2M7T_NN{u$t~^pB$a<^Z<^_)viR13VsJBf!@Kd@I0Ua+O&Yx70Y-8Aw() zvWCvYA?PfYNr0I$z%ZR|;8|u(Ciz8(@r %eax + xchgl %ebx,(%esp) # &function <-> %ebx + pushl %ecx + pushl %edx + pushl %edi + pushl %esi + pushl %ebp + push %ds + push %es + push %fs + pushl %eax # error code + lea 44(%esp),%eax # offset + pushl %eax + movl $0x10,%eax + mov %ax,%ds + mov %ax,%es + mov %ax,%fs + call *%ebx + addl $8,%esp + pop %fs + pop %es + pop %ds + popl %ebp + popl %esi + popl %edi + popl %edx + popl %ecx + popl %ebx + popl %eax + iret + +invalid_TSS: + pushl $do_invalid_TSS + jmp error_code + +segment_not_present: + pushl $do_segment_not_present + jmp error_code + +stack_segment: + pushl $do_stack_segment + jmp error_code + +general_protection: + pushl $do_general_protection + jmp error_code + diff --git a/110_master/110/os/os/linux/kernel/blk_drv/Makefile b/110_master/110/os/os/linux/kernel/blk_drv/Makefile new file mode 100644 index 0000000..1fb57f9 --- /dev/null +++ b/110_master/110/os/os/linux/kernel/blk_drv/Makefile @@ -0,0 +1,58 @@ +# +# Makefile for the FREAX-kernel block device drivers. +# +# Note! Dependencies are done automagically by 'make dep', which also +# removes any old dependencies. DON'T put your own dependencies here +# unless it's something special (ie not a .c file). +# + +AR =ar +AS =as +LD =ld +LDFLAGS =-s -x +CC =gcc -march=i386 +CFLAGS =-w -g -fstrength-reduce -fomit-frame-pointer -mcld \ + -finline-functions -nostdinc -fno-stack-protector -I../../include +CPP =gcc -E -nostdinc -I../../include + +.c.s: + $(CC) $(CFLAGS) \ + -S -o $*.s $< +.s.o: + $(AS) -o $*.o $< +.c.o: + $(CC) $(CFLAGS) \ + -c -o $*.o $< + +OBJS = ll_rw_blk.o floppy.o hd.o ramdisk.o + +blk_drv.a: $(OBJS) + $(AR) rcs blk_drv.a $(OBJS) + sync + +clean: + rm -f core *.o *.a tmp_make + for i in *.c;do rm -f `basename $$i .c`.s;done + +dep: + sed '/\#\#\# Dependencies/q' < Makefile > tmp_make + (for i in *.c;do echo -n `echo $$i | sed 's,\.c,\.s,'`" "; \ + $(CPP) -M $$i;done) >> tmp_make + cp tmp_make Makefile + +### Dependencies: +floppy.s floppy.o : floppy.c ../../include/linux/sched.h ../../include/linux/head.h \ + ../../include/linux/fs.h ../../include/sys/types.h ../../include/linux/mm.h \ + ../../include/signal.h ../../include/linux/kernel.h \ + ../../include/linux/fdreg.h ../../include/asm/system.h \ + ../../include/asm/io.h ../../include/asm/segment.h blk.h +hd.s hd.o : hd.c ../../include/linux/config.h ../../include/linux/sched.h \ + ../../include/linux/head.h ../../include/linux/fs.h \ + ../../include/sys/types.h ../../include/linux/mm.h ../../include/signal.h \ + ../../include/linux/kernel.h ../../include/linux/hdreg.h \ + ../../include/asm/system.h ../../include/asm/io.h \ + ../../include/asm/segment.h blk.h +ll_rw_blk.s ll_rw_blk.o : ll_rw_blk.c ../../include/errno.h ../../include/linux/sched.h \ + ../../include/linux/head.h ../../include/linux/fs.h \ + ../../include/sys/types.h ../../include/linux/mm.h ../../include/signal.h \ + ../../include/linux/kernel.h ../../include/asm/system.h blk.h diff --git a/110_master/110/os/os/linux/kernel/blk_drv/blk.h b/110_master/110/os/os/linux/kernel/blk_drv/blk.h new file mode 100644 index 0000000..7a69b71 --- /dev/null +++ b/110_master/110/os/os/linux/kernel/blk_drv/blk.h @@ -0,0 +1,140 @@ +#ifndef _BLK_H +#define _BLK_H + +#define NR_BLK_DEV 7 +/* + * NR_REQUEST is the number of entries in the request-queue. + * NOTE that writes may use only the low 2/3 of these: reads + * take precedence. + * + * 32 seems to be a reasonable number: enough to get some benefit + * from the elevator-mechanism, but not so much as to lock a lot of + * buffers when they are in the queue. 64 seems to be too many (easily + * long pauses in reading when heavy writing/syncing is going on) + */ +#define NR_REQUEST 32 + +/* + * Ok, this is an expanded form so that we can use the same + * request for paging requests when that is implemented. In + * paging, 'bh' is NULL, and 'waiting' is used to wait for + * read/write completion. + */ +struct request { + int dev; /* -1 if no request */ + int cmd; /* READ or WRITE */ + int errors; + unsigned long sector; + unsigned long nr_sectors; + char * buffer; + struct task_struct * waiting; + struct buffer_head * bh; + struct request * next; +}; + +/* + * This is used in the elevator algorithm: Note that + * reads always go before writes. This is natural: reads + * are much more time-critical than writes. + */ +#define IN_ORDER(s1,s2) \ +((s1)->cmd<(s2)->cmd || (s1)->cmd==(s2)->cmd && \ +((s1)->dev < (s2)->dev || ((s1)->dev == (s2)->dev && \ +(s1)->sector < (s2)->sector))) + +struct blk_dev_struct { + void (*request_fn)(void); + struct request * current_request; +}; + +extern struct blk_dev_struct blk_dev[NR_BLK_DEV]; +extern struct request request[NR_REQUEST]; +extern struct task_struct * wait_for_request; + +#ifdef MAJOR_NR + +/* + * Add entries as needed. Currently the only block devices + * supported are hard-disks and floppies. + */ + +#if (MAJOR_NR == 1) +/* ram disk */ +#define DEVICE_NAME "ramdisk" +#define DEVICE_REQUEST do_rd_request +#define DEVICE_NR(device) ((device) & 7) +#define DEVICE_ON(device) +#define DEVICE_OFF(device) + +#elif (MAJOR_NR == 2) +/* floppy */ +#define DEVICE_NAME "floppy" +#define DEVICE_INTR do_floppy +#define DEVICE_REQUEST do_fd_request +#define DEVICE_NR(device) ((device) & 3) +#define DEVICE_ON(device) floppy_on(DEVICE_NR(device)) +#define DEVICE_OFF(device) floppy_off(DEVICE_NR(device)) + +#elif (MAJOR_NR == 3) +/* harddisk */ +#define DEVICE_NAME "harddisk" +#define DEVICE_INTR do_hd +#define DEVICE_REQUEST do_hd_request +#define DEVICE_NR(device) (MINOR(device)/5) +#define DEVICE_ON(device) +#define DEVICE_OFF(device) + +#elif (MAJOR_NR > 3) +/* unknown blk device */ +#error "unknown blk device" + +#endif + +#define CURRENT (blk_dev[MAJOR_NR].current_request) +#define CURRENT_DEV DEVICE_NR(CURRENT->dev) + +#ifdef DEVICE_INTR +void (*DEVICE_INTR)(void) = NULL; +#endif +static void (DEVICE_REQUEST)(void); + +static inline void unlock_buffer(struct buffer_head * bh) +{ + if (!bh->b_lock) + printk(DEVICE_NAME ": free buffer being unlocked\n"); + bh->b_lock=0; + wake_up(&bh->b_wait); +} + +static inline void end_request(int uptodate) +{ + DEVICE_OFF(CURRENT->dev); + if (CURRENT->bh) { + CURRENT->bh->b_uptodate = uptodate; + unlock_buffer(CURRENT->bh); + } + if (!uptodate) { + printk(DEVICE_NAME " I/O error\n\r"); + printk("dev %04x, block %d\n\r",CURRENT->dev, + CURRENT->bh->b_blocknr); + } + wake_up(&CURRENT->waiting); + wake_up(&wait_for_request); + CURRENT->dev = -1; + CURRENT = CURRENT->next; +} + +#define INIT_REQUEST \ +repeat: \ + if (!CURRENT) \ + return; \ + if (MAJOR(CURRENT->dev) != MAJOR_NR) \ + panic(DEVICE_NAME ": request list destroyed"); \ + if (CURRENT->bh) { \ + if (!CURRENT->bh->b_lock) \ + panic(DEVICE_NAME ": block not locked"); \ + } + +#endif + +#endif diff --git a/110_master/110/os/os/linux/kernel/blk_drv/blk_drv.a b/110_master/110/os/os/linux/kernel/blk_drv/blk_drv.a new file mode 100644 index 0000000000000000000000000000000000000000..02751f123aa0c72fe90e820ca24599de825468be GIT binary patch literal 52212 zcmdUY34B%6wf?^6o;&6y1QH-Xgc}SJHG}{W5kUhYGHOIrCJh;GNFbBRy$lv{2v{Sc zqSo4q1{_+S6}5dG(9nvCAl0_Cwc6=f+Nv)UTiaq=94i0s+k5Ssn*eHu_kRC(e#!mT zT6^uahqKST*V=iLDq5;)&k2u?_T0vtamLuO6V50eGa(u+)=8N zjwhN~gcwUS##T3LbJk2vPLDV7#|9FZXbl{f%9gWU{lc7`S}Xl%&nI%a0>WoUMha7S~QaMx+aYy`F^(h90f6 ze}&wztIvjSex&y`dNN8w?HVGc*Q2t>3$Z^+oOpoXO$2suKppb!z^{U}9EfvN{8VJ0 zphryHcd!;JI#VLNcUrz4Y=?rRn3V}Co<;D)IfOWd>=2sJjsdv*??;d7B{=*b2}9DCB=wg;|KPjUv@SFEIv153fHHI6bwIJrxf|7nU2B{}ecI~tbMvoX zo1cp;s`bqzbqb0=Q<8T3(C!xKq>l4LUu3ZxOM`vBwVy`YxjS;vVvt66mrp+T>mN_*tr|s7npU!u0#f!QU+4@_aR+~uKN7^Ah5W7 zJ`AHr0~i*@a3;Di!pw)pLm|?>9~JT7$MI3PSK(Z7v{yn@CouUa@}e4%Ve6i6+nxEm zN}k(rIxni47_Cgy)Wlk%jZN_=&+xJ8aJo`cE2^XVgdfEPAX?Sb&`{A>T^Mahw8o>A zvFNn{fKBYmLVmp-PLRV4|)n2D3#Wr7$G0 zxt^`~^-KV_-AjQ|%T0=M3cv&%cRIjZp&TCx<*gLTRjwQO5Mvmy3A+*Sea-n!2l!kc zt`*940z;VQ2^PY-zlkZ)#W3S~{9lB`xfiMV-f5>GA<&QJ&nKw@hw$s2&Jx`Kd)#|L z9e#s>#i*QjMlt zU|>1rmynJGzDN1|ulrGc_{*d(r99IKw~@KL5=^!eo=;{0TbtvAznx@qo$zGHOiI*A zt87^zOuoZA5n&3PwC1{M&%}jN|Ja-sonv=GSYKy5h-3hOx0nN;C!gtfOW@b6zQ<$=Z)tTdj8(5ty z$dozZkC>vF`A+y$n%2w$Cp<8jvcw4=PBKfK@Mapgl7&_~Y4P|Pc^;#!9m*v###_qY!Nvp5MfUW&G znEfcHwN<&x>u_LqIT#6rFcEaykt@RD<{)4CTo6I!NJoZ7vTMaw~=&7pfBkr z(q{z1q?<{P56q_ht4N=zoT5a2L1H6cN6D&XlE+V~>v=jIR=~blNz-kt}n(D#8 z1uS^YD##<~Pj;g}0abrsKC|&?$@CY$Ld#|N@sIfxepSFFJy!4202}NdSBc+Xpoa32 zx9}TL8C2~`HGH$H=K1i^|(d`ZUt6H%|I=(m`)cU9)lv zNk_ajRTu@MNN0L$nwpebL^>NZ#nB%R}}Y8j{8 zvq|TAW32cj($T;k+L=r`-y5q~t=w}+7kFb;mM-+hsx4jYja6E@#2agcopY%_0dml# zq$fdMr`#!|OOY4!RMOKRSMGTvXL#9N(@4%iEtPvd$ue&>$mt~Kduu>mKyrb18ORwV zmw5G&HU}OX`{?1Ar zc*}8CO?xfvH0;_uWah|TpX=Zmb^eYvR9g*x}^$emTEJRK(UY87Ei{s5^S8GbeBGb}qw zJs&9SS?-%Yq2y2+#6jZee>ABuXdTNK%sp&!C{JI{h>WZ>Z^n>}zMg*mOguU|Ssrgj zTH3_4v(r3T7*XlU8zeI`YeE|KYraZLI|mtHLP(hR4^Z9=ql5u~9KtY1un%&~gr$%+ z?6Zb(zm`|2ED(&orP zY(Z(x-BYzzKVP!m4sN@%N_w!_NR>J=6+1PR9S|0l*NuTio^uBsw}_l$Q$BABAJlE{ z+(9e==TP)4cM^^ayV*NZ@^_*nN8Jg^v!bU~5%vOhoZD%`r+*zt*~CjTQBvF+}hx287;x zy6WE3Jd^WAE64Tx_VKp7xs$hdw!Jy;-0gYWw+HjK=d~?b$RvMo0l@J)GjN%3ouh4< z3(jI%u!g^Wr+`VGqq8*^oaJ}U?xV@a{0Cp#o;P5IvpBe2 zOB`l!wAcw=$3*`u|7yp@PSEdh_%?^Hru54y{8q#(lJBWn<1L9Qys3({RzXeEc+phB z{#LQZYNOm*ffr2`xG=<9Dym}Tm38rkie^<;-iV#Kq7_6%ysjap68aaHsj({2P|>VgX|jh+`RDVk7J5*^jR_kfe@#!VOxx~jf9 zI%-*TR83PuU3^qcOGQI$RCAMl(FI{0i;j(|NizW!{A!=+IrQ12Gxuq$Nw_{B$ zsZVmKWNR$80?^Quz!MNkIg_%wtMPsvUo`2!%+=Xs$)oOu4|5=*Q#`e7;nXE zq#u~uc2{LNTT))r5{s#(nws)B2O(axfjH)kVQh7*DiN=!tcP9m^3c3iqavOWRYi4m z_uED6vvPJY>Q~;{jE={PJC5&IwN%qotgakgfZne(Zy+066kY{3wX~WB^~i#KUx(Lv zb>)0sXsvB(iAQ^-H@C!AnxblJ)r0#l+0$ zL*py-?pE>!w!Eehx_WQ5##&o35L83OideD>@vva`Qlc?+FjlqdE<;|874;P@4c)zq z*RCx}cP<8OO&xYtO?fl!EI~G_#uf}Dj;>bJmfeLKG$tD4%%hr@wKS`kZlAmzZizL= zD&ndt(b9rP{$$;BA!h8TdK_&iYIJQ=Lu_!bI9v*u zVnE({sq-?Tbs4UfmxzqFW0YS7IWJ#x@Xz}Y-h)x@eaeFr+$iFo*9d!Og|uStR+GkZ z*5lva5HZcUG{dEwFWl^{4&>R+ESM{5UDJSr8yIgfSZk@4Sbb5PC%htk_ARQ!ZFo@& zd#?hB#OhdOVi`IOFY1M^sI27ZN=dC~;pYHmOlII&&}Kkcs)(Bng(qmNQi60+H}%fP3W z`^!AsAVS7+DYxY|fVO!+s-M8#=TiihtV3F=y|-bH^`<@Cize-@0nI$@M{f0fmD+4O z4LsBMzh2Pl{k^|Z`q2n-ZdPxT&{~L}k@zZ?x>1kYHvE&e`>g3NC$~2zem_8C{&uiqzfw$+f zWAodi7)sc@dPEr7@Ton`bdHqn&6}*9k$DvcU&`jyJ=ZPpsti>MHj4l2(6N2hpO5mm z;l_UMi(fuyM)A+%j(i2sZrl&cEdwNfRWF|7*KSO|7XS8q-4Fe-5xhN5lTY3f^1_yS zN6_>BAoV`1#~p>eh8}ZgC%1E|wLTVW#=Q@3jT+-Ca0`h05qxuPu4t@7i6{C}%<=2s zm^ugO!EQQ_JjO839}XUBug8Hx`Het6kG)DB1NMO62ZDSorkrnj`K)<5kaoX99)tWX z!9NjU@2^ZpIXuTP-^GF)DIV;8zT@}c+{XG5VM-&%p$BE=5iw{_5&2BPGQrCQuN15o zY!zHBxIvKb$XU+af)5BjF8H+I9>E_8zApGX!M_SR*yXgBAvjoYl;A|c>4NhFuM}J^ zxKgl9@OHub1RoXLE%>@1zn8H5BZ7PoCC_7&SSUDM@DjnLf(?RK3w~DcF2QYrj|;vi z$QRzU|Bm2?g8GFOkL4KB?{2IY_!Osb96WlKNl;8`3KNS2g!GnT-5%h3; z!G5~nAi)uWV+79;oF#afV5MNA;MIbg1n&`iNbpI)oq{h4{$6k{?gLn#<$@~(ZxH;V z;MW9yBe(?z2=hH6cu24hUU5-AL~x|wIKguTFB7a2ObA{tc&p%DMC`k-3jZzPUlIQ2 z!Vkv9o#jS}&>t;)Ot4jOjig^I{08A47yjFV&x`yW;Xfea{E>-E1k1@K;(U=O{3s&M zH|PfC37c~@>#>zQFbZ^lJkJw(ejxIEK)gwCtDu?bB9lun$LEvgmy8)de#}_tML)&- zlE|qj1RL*V@$MZHhq5@o1mB=#HpxFQWn>#~95$-9173cS=A;xO(KAPeSsLG-qc@d> zElbsnP{mj0s7j1Yon2s6Fw?@23SYZ}{FDx@Gf`G|8Ew0AY?(-7Q@Yd4CvPzpeUO!G zGZSOBQnAlBccI2-qrrM^10Rlb-aQ!I*iy}zZ2WRxY)d=TqkpzCN77(%JfsDflk@Z5 zDbAs%cKi+Jf%fO#zG+(iu$%F}e%G3;RMTeK2In>;OWQ&F{LFv(WtX(Qohfa~Mwdk1 z$E1kJ(W8CTx*|IPU@JRf(hG@`l6uc|(!dU0``e#wf3^KrA0B@AN&j2nL+X$++HWP? zC#N5Bo}Beogu=Jd_=_q;-f~Gji$a3OW3OlGlSkk3Y4i#@#x$m-WG=q4TxLBKqrs7F zyg|W)BInQ&PWfQ94vpRMuIUllfYK23%8<4LyFd=UZY};35lA9W^ZfaTL;0Aikjt4M zeMTy^ZuedvEuvxEV=Vx^6U~%}NhqQaB4tYr@8B$mgZvnRqyi=#s_#|$NR%}a`*Os7 zq@stTC@Xp$=!72~PsjyxCD!*8Y6YF?<~JY+=_jnD2_iZgK$Tc0G&U*{hH3L)b&QxIW*}eRu_C4{gmu zKC~C}Wo~*-n+@%kK%Z~!-?j^BXFV66&@J2bAY~{V z7F5?*){X+H`Ec+^;}x%K0Mksv`qS2K2w`hjw`|vgl<9=0c@q2s4-(thaM$zbGChk+ z?{193u&(C8c4RVp?q2La-7-unn~ZY#?A3KYcJ{~YzH6Dx-jFIcap;|n%(!b%T@@dn zc`A}^1$|w^QNdn&BM%B)ci@M6qhE4w9Dwb%BTEyI)b%ATTN`*{fU?tkC3fj4(sAv5Qo51#%r z3fJQ&c^UED&MN~a(^ai|SF0K&T!lFCF4tVxJ@%Y&Gaut%?MH3D@t(CmUaE7n9r*A8 zicO-N2ed>d8-pm(eHSAUwZwohwZzHns~G=mCoj?Ydwsm$;AVR>-1Py@wg-QSF5Sj< z;oqu80LJZFhvlxkD^%=Ku1JYfzvgLmTf3({Yeyam@4jW|gBy@OxD>S=c;;!Q{DBv-=Rtg$Z9hgN zO2m6H-qoA!H0M`pDTF**QeGzVA?jC{P1aK%byU>fih*M7SbfTmr+>2N`1+J%zPNs; z*t6Up=;NKoJgdSV^Q<#5$}fm^wrORIQ%228Da<$(o#@Qb7e)2gJxo5}#M2SQC94a~ zEYj!*PE76PNH8&4-BPzQrYEmj7X)Zs+Q?6koRQj!Z@kgUHF3>MpLQM+FNnqYK{U}C z~ z_=+jB_*Buf2H*Q^)6G=c?kTp~b0YaEbRs%pMPt*dMmy0~-HWq`%l^ZJ)$ifgGYR|b ze0_i`b)USpbk0Lc&}%2kdXp1n4drrb?6ufAI-A$O0NVZ$_^HKzfImm6vDk}3+`vpI zx~`8CP=d)hv^yyD1kXoRe204yN*b)A)`l%$K;n z^GT|34J$EyI!HG>lJX1I<2M-YhYN{s247)@!<(rylXP16bI9eJMLH7Z#30{n(&=Ho zwDHYZg5S*WW31EMO3>NiFk0xlkaSL%Gkts)kPB9L>Q1l!LK+FL zM!LU@O;X`{w&-Hryl@1G{&}Q>;g=}CgmfhQ5asg^pw^k`3DTERp6R4tOy=@yz+^k= z9x^hiHhp7~$#v2%f`UnjIvJc)YnXf|ou8KsQ{ZH9Qmua>O&2=pUtx-7ikRS)D7$lsV~JSg2;^JL$ZX8)ku%p2s{oWr>r%IhnH5 zN&gxRT**SKoeWN@^)F?=)jH`9Go^wl_2>gkjPzH24Q861^hVaYicH)|&%zG&SCd)o zq@Tx%%B0%#cF6oSe}wXNP6ns;`D^{SJKB$O@HNuE{Bx)WCe^073(zHLE{CpvJ$_ch zh&~=LsrDJ@Oz>S%2UFqKAouC2sxaS=`O2w{sm;jlGm~n=W1;9XlWM~cap+Z=VcQ5z zUzHiQ>uIN&x9J(-WvHF6hNCYUUPT=7wxWS%(#* zi^Dre*VF#k@Xe$fNRJEO%DOd@E(vo2s;`Ok8R0V0&7{YNkFcz(NMlkhpQJK6N6N@MX-finJRpVgpuFJs4htU*DQLAdjFw*^R#UkS!2sVm2NvnSo-S ze!>Cd3XDkuslpH7H!yYw^15N3lLF&70D|F@s8fPzVX)SRs+p9-FfH^=bNd3EJ+NQz zFW3NDPpb8w%CV^Qq+0)Jq|KyS|LLU7q*{L=X)~$TKZ>-ORO>GyZ6?+FN0ZJ8m!hfu zVw%rYeu_9~^x(jhs37Y6ihmqW0O9deETM)9|2OF~NSjHu{_&)P;kPM2leC#s>z_b6 zGkhn0{b!LjlWP4FNt;Qv{n|m3Ce`|q)i#^GNDRwf<=&^`u(=`6TtETK{yCdQz?b z0+M=Ct$zkdGpW`;ll0PX1%CarNLPo;vFrS^bI_l)%KtpNl1HlU+F^LDiUXDZ($#4$ zk3fC38epZERQo70=X(b7<*}Yr>&ekW#LG#woGe*zugii&J)(_xYZoJRXglt2{pjCu-m_+?ry;$T(b zE?OQWvz$k3VIWtf2G z%;!Ox9iC0Oru&CqhkZj2Q2nx4a*X!Rz`tk9Oq80%Ijk`@f-`vg(J98$z~rxLl?JF} zKgu>Yu#c$I|8Xi`^A=dXf%R;;on|o4%DF}#$WR&ZK2A5akrZN2V`-cyHD#Z8N$o8v)i^_(^7ByMAGeFHPqqXz2jibnsvl=XWZ8$sg`<{&;oz1u`4%tbnkTvjm`9M8nC~H2- z2so^UoXRQ`839fBnRzPg=`)C54Y>!rGj%K^K5q^cc-&T5g@77z5iMMLiB>?m8p3at zPO~w&i-JqopsS2vHwBZ}ik2_yEH6Tk=F;ep4IrJ?jrjF>hf$B`9Vc!CQ3~`CpD=A%r12w5 zFj72YM?*4_U!OcBJiirOi}rXbc+&ELMcRL|fyFdAatX=0hd>tG%aX4)1yQZwH^||9 zh9*qDe{EKJ>Qr>Uokbq7v&e(plh#98hO+T^W@mqM!g`vWupa3-VLd%X4Y@E$J2^2P zY#%#4J=082?`x)~_dCJ#^sJuK)3bZcM?ZFExlC&xkeV_xtH+f0fvMBhbJ8%kpHD!X zi!KxRIrCv~?+VG3^&#C;)~S};t=6lQlZ;`0tsGh;9hWlq9^dARluVfS^^iwJyQefy z3QCpI_He1TZ)O(jbFx%V*nDZKk2CZ~B>N<3L>hHUciYb$Gzl-aM|QW;2ntdKEa}~s2Xlv-c%kvH-GNr zU|#2&?=k|TBGkbC{t25E*4b3{IQ%~f7iZkE+!G8Wbf?1=3lRH;-E}XY) zXI@9!=HRzKt7pRBPK{aq!tZn}>R7aO{ra}NRZngn-4X0abeyIYX89lP=$t!w{pOC2 z;F}%GIufJ3YaIBKnrZaj@ckW~3+GPm+;@2AzMUNxFVph-{mz)IH-m}8KV7)6SW9mA zzZvX2+_`YoIyky>^TK)On3?|f`-6v}-LY`qj=^v z!MFkp(^+QuSHcfAk$oTySJP-ak zhXXsaTEFVzl=ZQgAKqNQ#(EwYUxZ`)4_ab)QB_yj!YS?l3%&?!o1Hxd4-4(cpd)se zmu*Vd<9JRAm{|>H0&{R-e)d1=v7q0{aWZ~)iPnn&Z{cF`s#@&}VJCQ}dNb%AO3BCf zg#U<(gRZ%Df}n2$b`#tfVpVV`_@_M^#L@l}Jsj}PvN;hi*A+J24&8Irwa3TD`#zX1 z@9waF!50D^GmWi?AAle(RXwA#$R7P4bC$3XXS%&6Oo_)tnZYoi3y=)XRG$jHx2$J{ zJw8Fkn0C=TREC}#`sMSn{u|mcHLxE@S!KV9uu#Ku2d-}hEMhi(Y{wnrx4~g)#e`TJ}*j_ z86P3OrNx1msHZ>BKjT2c#~yAU=Rd*+fBJ*aPlWm<__r?uD0j9Se~&qkzlDFk0HC~8 z^sB+zCw|C_of|UTV#wCw-#)~vDH*}fI#V(tH+rXJWVX39`&dTil;<-dQ}$#8r|cD5 zPa=Y;n%4ef-w)DMtPXGPon``~%( zgFV;>QRtRH*FJ<(x6L^(BgdHojpw0(?Nj;qX#X7T+Vg+e&nNYv0bQ#%eu&`<3%liy z!`pT|r199H4*Ll2LDZ?j>*r|D2k>0V4|R5n3NZqhYH$8oCO_>lueCQCH0@e@PvX&? zdF`h64HzE3tcQM(08($9tvq&Nqh z%|jbE48{v1TZxo3JrAA=vK`G;Dry;^wXq0vYPp4_=5-!T!?2OZ_lB7`&??!vn zFL+9dQcBvxLffiSkI{GRX7}4R2vXZItyHP4kg;F-;@`G|v>huT)e@Wto**F`>&A_k zQjA(#s8ke2`a=#<+sg#9%v5_@&~VPhx0|(Rd5fv?f7~C)XU%Bz;xhpEJvUyX=-RmO$iEBTUjN8@(J*`6BOd{8uXW^e!P{#Y z`O)C*HH`eZ;O(`G{2cK1nngZ!^Xk3QE%Ejk`5cdSG#DMP-t(#Y8Ql!1WBs#ulyq7yKx-x+pgWnuj$2K-;2Mc7tgQlX6zXIUjiS59b4W`@Z1Ny&!WH9 z%f0gR+Hdc-nEqC;blwBljr9wp9HZn1g17fM%s&#my(b}mUN8N*y?FZP*p2o$b;I5- zFn>$0^p(AMd2Yg8e@}pQz=oyfXFqr^hReo_F=V9u`o7c_Qxpdf_;aZ@nMH z4KJ;eKIrjkqx*@lm;YVQr>=4YYB)AJgPkE|QjU4(k@Av3T5Xr{NmA0}aX48sm3;cE z!-T8yq;p{JXWQN{&pz%klD>(Ynbjgbh4H$o6|LoQ8)}xmhf=w(PQF7mqsAC~k-C7st^+T|ob zmh&w6F_^0>{7aJls-X7ggZ}Tx;{x}0BFdvbAIl2@J!5fgBjO&kKjpAnK*Y&|vv(;U zPkw?@XOo8=o^P4&QsLW}j&|NHsQvg*?rx@|GdMrhgOd}dO0oW&!b|NO&Gc^x zK1W17_X1hZUx=Ku$f(yOcr_7v*8-_`J9*gOBKRLf=zpE*B}%;@@*j)*SAri3YJWQD z55+(8jS`$BIE#q#E&{T=`64eT5Buwc|11&pxSNP}-YY!6gwgJI@K60W$m0e{f7?eJ zwLcwX{GLlaPB|my3Kj}-o*v~3h^YGtLC(>k{2PKV3Vu(JpV*lG-$dkl8|X}gU#0L~ zzmZ1-2MQJlP7~xuP3B)9SS461xQd8!ZWg=~$a3x{kM=%5M0>w1={p7Y3I0OxJwZ;e zqP-l!^8~g3ALIp4^mpmZbeTvA(kUt0Kck<}(Ddf@L z7n4W+OGUnjSc-d8!D`|ZbC1t@WNvBJAf8M~YuK(q~Hgg@P*t zTLjk#epc{S!8--F3Vu`YIl=D>{#@`a!9NRrBpBxT8ub_;I9#wuQ2T)+eY)@q1#1Lb z1Udhgc5W8rb%Q+TfDm=GKOpa8$?NL}@Kxb?e@b~6eMIE_C{fR{0*(=$fjuc-Ajtbl z@|>?syhZQ}f?pEklq#n05@h5~@;?`RS1<$nl5#x*3|Jui8G>sBHwbPPyiZVHpOEhx z!apncJ;9#|zA5-8!M_WJFjiT9f5ALKecgimEa5q|ntD1e0q_dpmkX{Gyg~3*!7mDa zN$@Gb-GciCIq`({^>qyRuJD6!3{k#D@NU5e1RocqV-59Q7tG*!AN-4g41`I3AkWLd zvjr~@yhN~EaE0Ivf}a!ICb(VjX~8{$KN5UhP+t#F-d}~!2%7TwEXsO}6dXmwn3yGe zneco@rJlZC0OKOxEb@DW|CaFDZya`>6Zy|Yen5EbM_!=RMU{($g@g#WYfe;3~6`4sih=Y7-z5fsgNj0nC! z_;JEd6#jhS=Lmnf@K*|7Cw#N;n}okh_zvN}B>Xpo-!1r($n|vr_4ujq|1GF^eug|k z#MtdC{7J$O7rsdN^Mt=hczu3H{$}zxHWQM5z3?{*e~0j&7yd!v9~b^w+%}z9IObU@^}3v@=6+so+|{ zy96H-$h@e#g$Dk_f+xB1wT>u~&v0FB^rEbv8>S+@ZSk>i=r z8d65aaV)SEu+WAgGU$FD#`HTT;3yl4^#PjX$_o`tQl`P!GI-CV! z?fM;efPA_cKicng$5o)Zy#`N)*Wk&Bm@vH0H}Ny#k4Qv=@-^3Xpii&H4d`y1Z74D* zT^gep94bz>>G&=iuK!W!;cq@x=xBF;vJ?s@NRA-c?j#JU{7iO$yY6eOSG%;2qs;EWfx3y7N=^oQ|tviqnUkC$3ktkueuRKkFQAaF^FU>|JYM54)$hd-t#kJT&$kN33SF zKYtu?soVbS@x?sQiqWu~_k;S}ki8k!+vE9}?MtwJ%^ZaMkwtFqXS56LR}D9Q3?hC| zlB${r7W%4YBBh{qZAbiwed6Y`vR!MB;Gom#Oz^J5X?;HAX5bDT)bpi9TuYZo$4y+Vp#AOl0Zixt; zIjg-ab7N_yITN#Pj9+z#uJf!+*N^{(qPK%;+nv3*T$mm=LmL-X^e?fBlyFTeaZL=AYh z%V9y3^&0FtghA=k$fOX$0QoQ|Cmlym-~4o|O@LYn4*W?{_e^9h-o}xKKAddEAZ_mT z@p8ujU=(rd^x}?XH8nMVJNU!*+h2V4$goopyrCTzlsXKBgEv8Q8*{))i^&V-WApa7 z6)AO7k2jud!4rsh9MFg{qWhg88m6)6p$Ow~Fr7u41Ifj8tIvin8SNa7Ddf&B29F#Q z&{E!ol>m7^HwnnjDF!AjzWg2ne@x4t!;%iU=%+b2LC*OW9)PYLVNZ|}L1{EjlB03f zYCFIXU^8%inW5s}(|`amA7NA;T#NIAsoHTz^<}o&7^3H()Epjota0=osPSObSVw~3 zE|8PY{A8qu99YW6WAszaNbQW{M-K&@%x$EHTR$e!!-x-%-Nbreqjzir+kGj|KnG-? z14cYUEvDfr#E1|m<%AoecUM=}wXXR1hzeHglVd7$M@!J_cQs>WL_}+EYK-cM@6o0j z39_IAFrZdk8|)aR##E(NRo2tU2!vT!Q3OAp?zO^9kOh2WMT`a=%znl+gg?Mk(D%Kk0=tYYhVq}ojnru=hJ9S1wxuvPekyDv8$nUDJHI()g+@R zBKg5mXIHkDCPq&X!J%8>m>3Q=XhUr^D%ijU($r$qiKkEedicof;rrEHMxt)h2O%Co zW+CMh;x;V7$<{XzdMAwAP=dQC#BIohBH}izKsnuU8@@=PC)foQ-!7yi<2HN_RdHrO zj4%yTkPzZCuLW8UpR|N&h@3`7!ZbvF%-j;DA;P88 z43q0bE<@W56Lr#4!!$&OCsPWX^wcm7kw=*#VHzS$tc-+dh}=ul5~d;Ym1N2!Cp|Sx zLxeBfZJ370YiPa=(~zDTrXfOieH*4BqN5)yUXP+@Ig#J690}79xslb8FbxsL0=Hor zB8!vE0w=PUc_d6j1k1Jvv($-vl?JY)>1roEHB3X~A*M)}hIA9AVH+yd>_mP`165?= zPUHaFQ%z>I6Uk;dvFXUU)`{dn=CAn`cF%QAx(Ut824C`jXG=%7eE@2u%=aV*J8baTteH*5M>(^!a;_S~5FF_Kf zA@q6DCQL(!-&Q0{L+Du+wwmg}ke8K{Fb!ds-RRqcY!aq{M+?Fpvo+5p0n1;}IC_gq#L+EZa>mLZy5Nbua z|0lyV=m0(vrXjQlyUss5fc`|72FCf|k*d2EVH(~6&420Yu*)ORKLQ=)!+n>QB22?A z;4_0IH$xQafVtoq9Q7*1cp<^@q&=bEqtk8Oqaw#ELK%u)QeJ6J<%ffU(&QU)~~C1V2B8)8;Kvu^@NbU@9s z|0mnIFEEQN zqCN1#dXlT{Ux3;>I^2`9xpDwPV9dE*8>t?EuojNKk#III8F(w|kxfes9B>Usg0r~_ zo#}>M4#YuTmcNZfaKg`cpl8b-80xPhDLiD#UOn(WBqq&#*_c^{>{D2auTbmT(6~}( z=L`u}e7ngUAI#f2X6BR%U61X?z-QFJ50JzsFD?F>5x1gGPl4R|<`7u_y|(!vvSxvT zkfRoTmBnC5mUFZ8NRYH(mL4PDGMbToJZc=_GW#(EisiDi-s6tn!6D~t&gsvfJkHas zw`ZOj#P_Vu%jAMMsA?$P@_{t&`^Na{!TpiM#{Jed?uWK_22Mv(vT;8);+1F|KVdt+ zV5}xx(w34m(_#N*I;?)+H&QdcVKS~j#(PnY)5Qqm_vp%8j*R^nex%Ff#8-TNPIumE z!>(m_dA8*8ySel3-4I~X2L5d=cJX@~7E&4F*icVS0C2c0p9{=TV|umdE*N&S(#(4-H&~_OtJYad6L(s2CS1HT+aIX`!b-DtWbT zz$2grPsI<_`FNqTT#*cR4*r_b^sHJ}y)?(APc;PWm;`pGHbD1uNOfJY&%>R0)^jCjWSA<6#%%JG!& z6guK*N-H=>&1u2Uv*lcy&7($qp1Y@HG9*Ufe=F`pN*oF7im(kgk=8TZL?lHG6=n1Z zyAC7Re{nU$p5Z34lK~X4iej&D551R0?2f3wXbA&tl!+X+0;jfP!$wFbhQZxoBZedc zM5Hd-h{gf8S7vle}b>+-#7V-mNOa>xsN$#WOeS`sk3a?3MSuWqOp3Pb9z?roSkHYtb=FooZ#f0 z+N>$Z)bbUrf4hIRw^;{jV1@d%bhxi9d1J1iT0q`GX5P7rhxgCpa@WCU|zRcy=d3bU680i#B&SRoRPz zSo9LljQ;lIAJrhdzr3_H<`RW6lwfI&Qv)-|6Pe4@4*^}rgG zHL?=o376O8+gIcJuN&NJAx*s$qke~LbkJuUT?_)zJ0Qi!$D;TbVo#XT@XELxJ|kSw z(!M=LAQHYg?iqRlu|Qhtu)5%J*6Xa-%W?iYSM8iS^P)@i2&%?vpt5vl(jTZreNsFL z8%2UU%SJ9aZZHWhW(iN3ltnyKTx;~Mwk|O`f&?URbUNW0pY(V#j!rEMO@O1eyHEe= zFcMh&7~>+2HNtwX25LQ);L?P1!@n3Lg2$V7{Q9Ig5mgOMtyo9270deC!{4kIx~i^` zi+q}J40=J>UQ36v9Xx{3hZ0f5E+(29PeKB6w5mouI`uBVnwOs(LBa-)(A|-Yr1L+$ zzUUder9gax-ti&$%&%h%+?(M>LC(SdEBNO#zKt7D>fP?Ofdlve(u{xmxQ)Eo2=AaD zOm2eQK1WmTEHd#7wnA>7g>_j6jT~Rrl8>fZztYI}Lv9~0A=hyc3LxvkzkPb_8UMh! zJth2su1hu^KkQ>9%e+YH$oWF{X_E4*A*bzWklTk!+SYL{7+WFgY!=%LZ=rSheb7E` z_NYhH+0eTlTcB$nL{VPmWl|o$h1kc@9yXSG-*ZxoL{T@sVzrUR%TW2eev=kCt_m(RE$Kx~DRvUX><jI z_@TY{Q+n}Zz}xFH?au^nuW{rr?xjyZXS=a{+@1Y{u?Ng^GVVa_Q()1U2_+@RK1`(C zAIe>H%0t&NH_Ju^b6FHy*e|_-h3DX_D#B2>wFwO(G5;{k0F+7uNyuDp%xc$x6!l75r$cL?4q^6wB~XCD#m@#4me_68Ec-!HuOg@b&b z$o&zdqkU;Wwr>b|qz@w^A19xBFrn;J!6G8=U$EPiXAnQu19RoP0_-n5l5~FTV&%d8 z>?tCjDR`ma3PGM4a6b*O&uGlbVMIlxy4&pFY$zJePBHw)e`_!U8VWKjPF!CwjT^DgCn^fi%_V~A0~ ziGupP1$l+=oXbbO&j{Wm_&LD`1fLMxDY#EipU;s0@4|<@#@;}|d_k^!!*b$+*9kIC z73KE`J|xJ6F)80E_@dw|f(HcO7Ca*8VyrV?reLmMfnbSXso)&Jg@Q4`s|2qRY!~F@ zN!ouzP{#}b|BUc2334eV>it$Qh+~6%t>6YhegdZaK0zHD1iX$30{pwkzs2(;_~!+6 z%nk7Uczy#86+BIFs^Eo!iv()~TLjk$ZWMe%uv1XSz) z^B=HCaH8OJ!7Bxq3$_W~CaBM|$p47&j}tMrUK0L?!XFS``&>i+J&^}_J_J8Na5xcT zW1R3)1Z#<~t9`7Ye~0jlwZZ&P2)|eO9}54rU_j1~!-&uyA$*DO`uq!dnef_I8oWO5 z0`C_2LxPVJQ6GEWeM5L10|WYwoM*MqGxW|N5Bb?5Um*OI!q*AkB>dIFUnl%V;kC~* z>@f}|?L8#vPYC}_;eRE3gy(JOohEpeU?~xH&KJB=8AYQf};e_B1UmvBm5%b2)VxGnCEBK?;)PIflxKR#)4&nalu;zsZXEe zoq~MsA^)~u4$iyeIa7+r^E{FBGl^RTdEO@fhG0uY17AQV9h^VWx4C%y_>w5MrQvJO zpEKR#fg#x#!?2q}-T2}QTZ#Vt7k!)2?@8Zgq2V2)S9%w=9Ude-eVftm;tynVz_(eG zslLr;_0T$zZ!@!rZ?iELeUL~$y~{7dLaegZDtwc8>6KFS!m1wao5US!e3MM}TzJ+D zF>0l`-M&f9R&68iJj4!s5D$br`{9<7D>*VD0GlJ_&}{`PiRPk5a^M1!yD8#Gej4%Y zKkM1Gl(WZ&uFQH<%CJDqL{<`nR8i`iFbh=Rd-H*c%}A z@di$t)h=Xl90jJ3=M2Cs%A;p6mCe4Q0a+c_cW^3lY&2Hs1}4-DkIs&2W};J%qIQvu zcj=;8QMebn?c%1}zCQmk*lXLVK_%#t_p&YOAdkooH^J{4hN-quVHI**byfRo?XR~# zd-!3ITWe_Xq?*asX2pF6{{vZTz!$+`o;beGw|1FTYEk4?n9wzR_DJ|_!(LNh1?*th zrH-`yU68u%2QTsH<}&Ts17S(dhp@YAV15gd54w<|SyXk_ouBNPWFM9F>La)lvva!p zsdpb88nz9#)QJ_6otP`7N&V=bVXA)@^PBpintYxIr{ONszx|%VJ0vCJ8)@wHWapX@ zBSsmJNE^N0*kita*bw80Xl%Yi&;B7Ri(4^}9Jd7vl(!bMMEy zPKnYddrsk#EH4@@pnZPo zL;)ZxR>E=W)UcX^S41>pOQ+9N6AkKG6%`dli?OXx$;Eo3@D(%d8&O>tt*FF|1m@?f zrmzZf8&Oid!cf&sjj?E0G2RRIC^pxl-|x^-Dq$ol!b1?7;|4fc)ypZK@Rynka4VG8 zM?$%kLSZ7c8{oGNKoGZkj_aF>Tt2gkt>Xmvoa1^)_{&h9cL2os z?liuL3>47r`TCt?Uh}3{=jY!D~i1a3OVOl1>XSqLw?0bR_V3 z%4d^K576nzox}CdG6V0Co;x1D*?~(@xO*Y#oWS+ezld~h;0v@gpk906F7`AV)s0fh$>PwUb6~DBn`{Tdfn`z?2H6)T0mJ>Ef%r5jmTY!dh36i96vJ z*q&-KtDW$#+1D}l^;#!(CUphNCYU;7b;F8S~}`_@cqBC0!8U^hvjl777FWAnqG6U4Y5ywHXDaWj zs7j_AXMYA}Qz^j$RA2+?m86|O8Z)dS?FQ&B=B}oCFz^dDYz^N*N6??_MlV0y*Sl-4 zf>xlK$=4Wj&{6I>WA1d;_gZ7_$25H%X@6ibOXSfbwpGINQDB4-lC~-^s!ip7D|C zF49gwH~Mp=-GFZN-K3?_pC>JizK66l`U@$I{vzd>%FkC=fxrkbUY?KOZ^rcw1E;a@ zF@Nz&RpK`oD5Xxx4Cuh$jH-Po$F8G=%%FP#z`Kci&{xn2+NHml z?^GV`%55cm8fn*!lRlkv(5-nQl!}lkydj&IS$nXwo@>zren) znC5d;gd!f6x+k-g_Zqb572i0XVgtXXVhJ@=U=wzQ?+nte+uDkSkjIk_2JWEzOwtj^ z$0*+f(wTwl@asE^bT;H;m2V>H9Ji`vobsJbI@gV{;*&^615;40Z!+n8H&(G)`OYC- z;Kr&fUFgQDEnV!!DlJ{&V%DAVolE@*kb^EIJqhwU<(opf6nQ~UB|Qyt^Gq{;$wfjig#I&>1xPGRa;xB?1Y`*SwPyMMYqy|#FOrRFD&M2Xt&M1gxkX#}a z)k;e-4mM(!SxvXgtp0o5Q@Y(T=xWj1BPDg!Q}IV(2XrrhYFtyW@Tn|In&RYQ7e7r+ z>#?S4t~h$Yfy8)zoRsSM!6ik9rV38z3Syr*us8LGV#kC^^n8G2WbwicdtGrT6cvre zUtMEWeWE%xy1uS4v0C+%VVY=92`1{)uYeB+HhC!P?GJLCbwg8D6-`}26cbPJWCddw zix@Kwe^2ZXa__aXmf&&7<3EurLU0)!F+Bb^{O~GRw9gsdzccvP&d!DPr5&3$)A_v3||} zqW?j8L&a)Yu(bSYjAS!lT6;Mjq&OVtg)LO0dFg^B8Ly6+wE+24TbZcAI+|t{yHu~fd?MA>O3bpy?7MsL{CYx6qZ2!!9ld1j$1+Xy(|MoUE zIj{aky=Gw%*DOq3H*z&}?Y$@F%4a+CGTai#ZpXj9kxa3n*Pxu9vCHG_aC)r-i431= zeZ&9zbK+BPXL#?zZ3zBxY83Y*w%LocP*P@z4kzmdpCsavMO~JRnsJ3QJQ2 zmaIcsYCBfL9_vkexYbYETLYST*pJ*^z=3#k%06Kl|JMszy^98ax;gP{pqIMY`fU?? zcE7EK-tH7dwwGJ)Iq}z_9R-lH9qb?5FPt}O#}r6aiUIi*60+HHiMC88mEg(r0E9gM z&<5?%F8eOkUUr^*b%UInwP(2Q-&Fa(V@^Ex6*ta<=Nxc6bM%-KKLWfx*Zu!6M|>RW zV>kBWM9TolPwmCe>c#WD4fg^6`>H=5t(J7dyQ)!m0`0}|Z_nSH!@U;#QtV*903g2} zyxpk3$udClclF}$?Zu}&R-Jg!xt{kNpLSMt@+PPI8r@vch&vnb`WBsX&Zth_0%N9i zMRkRe3D=rqbvbT1M^ew31~Ur0(@*A1<3Kr|>A?Ad`Wym%zHWD*ujfo7{RTa{Rrp`#PNlLh4tzq7$qWo1d!>c zlgG3PzQv>76u~mV6_VaeMB{G}`IiJc1@{X6jtKkj0BOGu#t7}|IgOwh?vUm2RXgpS zCOp5Ok-ts&yM=$42z!qL*^f_<$9e20f=4LFc_JYBgAwWUqBSCd7gtjXj>i;N<1G^Z3f2p@3i95I`8EjN zEO@uz1A>nWJ}tOM@JE8L3;s^N)$Yr|=U6rwj5^5%sSWTrRj$uubrG z!TSUs72GZOx*%U-(%un4zEUASOt4UJy5J>(JbzKILGWt9&kEipxJ~eJL4FouzTXJG zBlw|Uh~oz7^a&v97s|kx@K*`)n*-C^1wSXK$0y|5g?~zriR7W}HB zg7*6go+NmxAivTxeTv{*!G(e`!5ai`75t*$mju5i_#MIT3cf1%8^L!3-xu`b0A>08 z1cwTqCU}wH6M`=b{#5V{!4CzqIrkR!rU`x|7!DfwT*0dZuMun){G8x6!5xBnZY}J- zCj4&&^?G-Z|CKz(re4Pg{2<(PkuM;EKT~kB$QKE(=hz~>QRJ-- zxnAE6`Ssje;CqsORMPc&MUd;cw!kZJE@ZuGh~QTW-XM6N;3I +#include +#include +#include +#include +#include +#include + +#define MAJOR_NR 2 +#include "blk.h" + +static int recalibrate = 0; +static int reset = 0; +static int seek = 0; + +extern unsigned char current_DOR; + +#define immoutb_p(val,port) \ +__asm__("outb %0,%1\n\tjmp 1f\n1:\tjmp 1f\n1:"::"a" ((char) (val)),"i" (port)) + +#define TYPE(x) ((x)>>2) +#define DRIVE(x) ((x)&0x03) +/* + * Note that MAX_ERRORS=8 doesn't imply that we retry every bad read + * max 8 times - some types of errors increase the errorcount by 2, + * so we might actually retry only 5-6 times before giving up. + */ +#define MAX_ERRORS 8 + +/* + * globals used by 'result()' + */ +#define MAX_REPLIES 7 +static unsigned char reply_buffer[MAX_REPLIES]; +#define ST0 (reply_buffer[0]) +#define ST1 (reply_buffer[1]) +#define ST2 (reply_buffer[2]) +#define ST3 (reply_buffer[3]) + +/* + * This struct defines the different floppy types. Unlike minix + * linux doesn't have a "search for right type"-type, as the code + * for that is convoluted and weird. I've got enough problems with + * this driver as it is. + * + * The 'stretch' tells if the tracks need to be boubled for some + * types (ie 360kB diskette in 1.2MB drive etc). Others should + * be self-explanatory. + */ +static struct floppy_struct { + unsigned int size, sect, head, track, stretch; + unsigned char gap,rate,spec1; +} floppy_type[] = { + { 0, 0,0, 0,0,0x00,0x00,0x00 }, /* no testing */ + { 720, 9,2,40,0,0x2A,0x02,0xDF }, /* 360kB PC diskettes */ + { 2400,15,2,80,0,0x1B,0x00,0xDF }, /* 1.2 MB AT-diskettes */ + { 720, 9,2,40,1,0x2A,0x02,0xDF }, /* 360kB in 720kB drive */ + { 1440, 9,2,80,0,0x2A,0x02,0xDF }, /* 3.5" 720kB diskette */ + { 720, 9,2,40,1,0x23,0x01,0xDF }, /* 360kB in 1.2MB drive */ + { 1440, 9,2,80,0,0x23,0x01,0xDF }, /* 720kB in 1.2MB drive */ + { 2880,18,2,80,0,0x1B,0x00,0xCF }, /* 1.44MB diskette */ +}; +/* + * Rate is 0 for 500kb/s, 2 for 300kbps, 1 for 250kbps + * Spec1 is 0xSH, where S is stepping rate (F=1ms, E=2ms, D=3ms etc), + * H is head unload time (1=16ms, 2=32ms, etc) + * + * Spec2 is (HLD<<1 | ND), where HLD is head load time (1=2ms, 2=4 ms etc) + * and ND is set means no DMA. Hardcoded to 6 (HLD=6ms, use DMA). + */ + +extern void floppy_interrupt(void); +extern char tmp_floppy_area[1024]; + +/* + * These are global variables, as that's the easiest way to give + * information to interrupts. They are the data used for the current + * request. + */ +static int cur_spec1 = -1; +static int cur_rate = -1; +static struct floppy_struct * floppy = floppy_type; +static unsigned char current_drive = 0; +static unsigned char sector = 0; +static unsigned char head = 0; +static unsigned char track = 0; +static unsigned char seek_track = 0; +static unsigned char current_track = 255; +static unsigned char command = 0; +unsigned char selected = 0; +struct task_struct * wait_on_floppy_select = NULL; + +void floppy_deselect(unsigned int nr) +{ + if (nr != (current_DOR & 3)) + printk("floppy_deselect: drive not selected\n\r"); + selected = 0; + wake_up(&wait_on_floppy_select); +} + +/* + * floppy-change is never called from an interrupt, so we can relax a bit + * here, sleep etc. Note that floppy-on tries to set current_DOR to point + * to the desired drive, but it will probably not survive the sleep if + * several floppies are used at the same time: thus the loop. + */ +int floppy_change(unsigned int nr) +{ +repeat: + floppy_on(nr); + while ((current_DOR & 3) != nr && selected) + interruptible_sleep_on(&wait_on_floppy_select); + if ((current_DOR & 3) != nr) + goto repeat; + if (inb(FD_DIR) & 0x80) { + floppy_off(nr); + return 1; + } + floppy_off(nr); + return 0; +} + +#define copy_buffer(from,to) \ +__asm__("cld ; rep ; movsl" \ + ::"c" (BLOCK_SIZE/4),"S" ((long)(from)),"D" ((long)(to)) \ + ) + +static void setup_DMA(void) +{ + long addr = (long) CURRENT->buffer; + + cli(); + if (addr >= 0x100000) { + addr = (long) tmp_floppy_area; + if (command == FD_WRITE) + copy_buffer(CURRENT->buffer,tmp_floppy_area); + } +/* mask DMA 2 */ + immoutb_p(4|2,10); +/* output command byte. I don't know why, but everyone (minix, */ +/* sanches & canton) output this twice, first to 12 then to 11 */ + __asm__("outb %%al,$12\n\tjmp 1f\n1:\tjmp 1f\n1:\t" + "outb %%al,$11\n\tjmp 1f\n1:\tjmp 1f\n1:":: + "a" ((char) ((command == FD_READ)?DMA_READ:DMA_WRITE))); +/* 8 low bits of addr */ + immoutb_p(addr,4); + addr >>= 8; +/* bits 8-15 of addr */ + immoutb_p(addr,4); + addr >>= 8; +/* bits 16-19 of addr */ + immoutb_p(addr,0x81); +/* low 8 bits of count-1 (1024-1=0x3ff) */ + immoutb_p(0xff,5); +/* high 8 bits of count-1 */ + immoutb_p(3,5); +/* activate DMA 2 */ + immoutb_p(0|2,10); + sti(); +} + +static void output_byte(char byte) +{ + int counter; + unsigned char status; + + if (reset) + return; + for(counter = 0 ; counter < 10000 ; counter++) { + status = inb_p(FD_STATUS) & (STATUS_READY | STATUS_DIR); + if (status == STATUS_READY) { + outb(byte,FD_DATA); + return; + } + } + reset = 1; + printk("Unable to send byte to FDC\n\r"); +} + +static int result(void) +{ + int i = 0, counter, status; + + if (reset) + return -1; + for (counter = 0 ; counter < 10000 ; counter++) { + status = inb_p(FD_STATUS)&(STATUS_DIR|STATUS_READY|STATUS_BUSY); + if (status == STATUS_READY) + return i; + if (status == (STATUS_DIR|STATUS_READY|STATUS_BUSY)) { + if (i >= MAX_REPLIES) + break; + reply_buffer[i++] = inb_p(FD_DATA); + } + } + reset = 1; + printk("Getstatus times out\n\r"); + return -1; +} + +static void bad_flp_intr(void) +{ + CURRENT->errors++; + if (CURRENT->errors > MAX_ERRORS) { + floppy_deselect(current_drive); + end_request(0); + } + if (CURRENT->errors > MAX_ERRORS/2) + reset = 1; + else + recalibrate = 1; +} + +/* + * Ok, this interrupt is called after a DMA read/write has succeeded, + * so we check the results, and copy any buffers. + */ +static void rw_interrupt(void) +{ + if (result() != 7 || (ST0 & 0xf8) || (ST1 & 0xbf) || (ST2 & 0x73)) { + if (ST1 & 0x02) { + printk("Drive %d is write protected\n\r",current_drive); + floppy_deselect(current_drive); + end_request(0); + } else + bad_flp_intr(); + do_fd_request(); + return; + } + if (command == FD_READ && (unsigned long)(CURRENT->buffer) >= 0x100000) + copy_buffer(tmp_floppy_area,CURRENT->buffer); + floppy_deselect(current_drive); + end_request(1); + do_fd_request(); +} + +inline void setup_rw_floppy(void) +{ + setup_DMA(); + do_floppy = rw_interrupt; + output_byte(command); + output_byte(head<<2 | current_drive); + output_byte(track); + output_byte(head); + output_byte(sector); + output_byte(2); /* sector size = 512 */ + output_byte(floppy->sect); + output_byte(floppy->gap); + output_byte(0xFF); /* sector size (0xff when n!=0 ?) */ + if (reset) + do_fd_request(); +} + +/* + * This is the routine called after every seek (or recalibrate) interrupt + * from the floppy controller. Note that the "unexpected interrupt" routine + * also does a recalibrate, but doesn't come here. + */ +static void seek_interrupt(void) +{ +/* sense drive status */ + output_byte(FD_SENSEI); + if (result() != 2 || (ST0 & 0xF8) != 0x20 || ST1 != seek_track) { + bad_flp_intr(); + do_fd_request(); + return; + } + current_track = ST1; + setup_rw_floppy(); +} + +/* + * This routine is called when everything should be correctly set up + * for the transfer (ie floppy motor is on and the correct floppy is + * selected). + */ +static void transfer(void) +{ + if (cur_spec1 != floppy->spec1) { + cur_spec1 = floppy->spec1; + output_byte(FD_SPECIFY); + output_byte(cur_spec1); /* hut etc */ + output_byte(6); /* Head load time =6ms, DMA */ + } + if (cur_rate != floppy->rate) + outb_p(cur_rate = floppy->rate,FD_DCR); + if (reset) { + do_fd_request(); + return; + } + if (!seek) { + setup_rw_floppy(); + return; + } + do_floppy = seek_interrupt; + if (seek_track) { + output_byte(FD_SEEK); + output_byte(head<<2 | current_drive); + output_byte(seek_track); + } else { + output_byte(FD_RECALIBRATE); + output_byte(head<<2 | current_drive); + } + if (reset) + do_fd_request(); +} + +/* + * Special case - used after a unexpected interrupt (or reset) + */ +static void recal_interrupt(void) +{ + output_byte(FD_SENSEI); + if (result()!=2 || (ST0 & 0xE0) == 0x60) + reset = 1; + else + recalibrate = 0; + do_fd_request(); +} + +void unexpected_floppy_interrupt(void) +{ + output_byte(FD_SENSEI); + if (result()!=2 || (ST0 & 0xE0) == 0x60) + reset = 1; + else + recalibrate = 1; +} + +static void recalibrate_floppy(void) +{ + recalibrate = 0; + current_track = 0; + current_drive = 1; /* by wyj, ?? */ + do_floppy = recal_interrupt; + output_byte(FD_RECALIBRATE); + output_byte(head<<2 | current_drive); + if (reset) + do_fd_request(); +} + +static void reset_interrupt(void) +{ + output_byte(FD_SENSEI); + (void) result(); + output_byte(FD_SPECIFY); + output_byte(cur_spec1); /* hut etc */ + output_byte(6); /* Head load time =6ms, DMA */ + do_fd_request(); +} + +/* + * reset is done by pulling bit 2 of DOR low for a while. + */ +static void reset_floppy(void) +{ + int i; + + reset = 0; + cur_spec1 = -1; + cur_rate = -1; + recalibrate = 1; + printk("Reset-floppy called\n\r"); + cli(); + do_floppy = reset_interrupt; + outb_p(current_DOR & ~0x04,FD_DOR); + for (i=0 ; i<100 ; i++) + __asm__("nop"); + outb(current_DOR,FD_DOR); + sti(); +} + +static void floppy_on_interrupt(void) +{ +/* We cannot do a floppy-select, as that might sleep. We just force it */ + selected = 1; + if (current_drive != (current_DOR & 3)) { + current_DOR &= 0xFC; + current_DOR |= current_drive; + outb(current_DOR,FD_DOR); + add_timer(2,&transfer); + } else + transfer(); +} + +void do_fd_request(void) +{ + unsigned int block; + + seek = 0; + if (reset) { + reset_floppy(); + return; + } + if (recalibrate) { + recalibrate_floppy(); + return; + } + INIT_REQUEST; + floppy = (MINOR(CURRENT->dev)>>2) + floppy_type; + if (current_drive != CURRENT_DEV) + seek = 1; + current_drive = CURRENT_DEV; + block = CURRENT->sector; + if (block+2 > floppy->size) { + end_request(0); + goto repeat; + } + sector = block % floppy->sect; + block /= floppy->sect; + head = block % floppy->head; + track = block / floppy->head; + seek_track = track << floppy->stretch; + if (seek_track != current_track) + seek = 1; + sector++; + if (CURRENT->cmd == READ) + command = FD_READ; + else if (CURRENT->cmd == WRITE) + command = FD_WRITE; + else + panic("do_fd_request: unknown command"); + add_timer(ticks_to_floppy_on(current_drive),&floppy_on_interrupt); +} + +void floppy_init(void) +{ + blk_dev[MAJOR_NR].request_fn = DEVICE_REQUEST; + set_trap_gate(0x26,&floppy_interrupt); + outb(inb_p(0x21)&~0x40,0x21); +} diff --git a/110_master/110/os/os/linux/kernel/blk_drv/floppy.o b/110_master/110/os/os/linux/kernel/blk_drv/floppy.o new file mode 100644 index 0000000000000000000000000000000000000000..33235bcdcc660371f0cfe6077089e24f2a1c3a96 GIT binary patch literal 16612 zcmb7q4SZGAmG3_1esDR-O#%T7Ccq5_iEX}ssED9J5cyO@P*CdSCOJv2N$!pJ1Bg$t z8mxv?$EbDM5u1S3zSpTOb*2sy)bJtbs4cJ4r`7tiv`=Vk9Bqp;GJZ7g|KDew05`hVrNpPO0n*oRVq{rD}@GR~;V|buBFk z?Wzgx>`!MO_m;41;PauOA&QUH1QoHPKd;kUqQxCYi;keuo=MQ_QXMBfZh<4IDY~aW zHN&O5)|Z6tTWh&2Rl8ui1{RM8D znf~f(#}&*EiLuZVbW$Ad1*vkM?T5#gqDLwAbu~n~^7Ge-2P8IN_8Io;J&3LGj`#-v%ft*)AW9h)8K?rB1qtT*^wKr zzpmqhJn7RUge3dZyKXPZ9vaG3J1UNYrD885x$vd*v|+u&eU$HK26P_ke53O>pPzYh zpZ~Nqs0Ky*blSUb*`T>^<>_n+PiOH77qU-#NgYBXfiGk4V(Gr2(>{$JLDMn)S;x`5 zn{EyxM|AAa;p{zma0F>#4sM3KMRaR$?*5ORh|mU<3K5mUj+6Z$&;9!C_@=WV$v*HO z(E4z&WC-=p>7v}(O6@p$+((NH8AdDtkjyMYs|(RY8AQr$)!NULc>ghKFD)r$(O}D% z)@P%w*%-@NCs2wAhtO8&>!8zq1fXm%LY`&m3gm8?e}_3ZuWNNl+5L+RXqWA$ml$2? ziyqQeW=}_-f5xnRK za(mBp1RW=n7`|)W@{W@x*o%f;awh4M(AE7JmXC4u*k?mSgT8?&7>$9~ycmV+ouoaT zE_0K15tDlBv;#1uTv_Ll(K-Aj=Gnu6MwlN+!R~MZ77ZLibdKw}J%|y~&E>wJWB9c% zhK72JQ4aw)bke-cnpaN$$$xZ&&!~?YP?eY zBaRY9yJ{wh=pDM|En#jBoM5p`65qf+xazDvMNkOPR0nXP`RJ1UrMddeHX1Mk_EfB!zkI4F;pbU+} zf*P1h?!5F7CLA0y8pTi;cnA-U#>C;#I0@SwXSd)jI=no&QxGL;;8#e~F_zx^6qc6%|5#$G zyGHcvrs-oojxT_VgyDqk0(8~wa2uNW8_~KJ#UmY_^Ve=x(ak-0z@Scv8LZKd#w5PE zPMJ;#50yVand4@e6Akbf&wf0a@yC5k3Wsu+DA+y%p&tHEoj#n4UMmrRUIX~h4?Zka$f9)yJqZ~>{$Cn$L~CsoJiH^8XYG;-%GJm zDC>Zh=winpTJ(O5OoW$62**n-WLF~Z#&CM#YObObKQnoId!rjoRkjdvV(iADFXHTA^q!W`c^0il47 z8u;)((4Q&{rc<`uOI5vufAXi!6MI86#KyZeW|W+vO{u_5Mn;9=;RA{)OOK-dxeTHAYNQQTin=apRwB)9nk8qdfB>Pq4m3poUwfm~^(4p9`R6sR! zo@h9r{;t#L%->&(#z(dcx!8c@;#Jgf^2Gxz`H(NMBOv}epA*PPw5XVvrBdN5=5N#% z2)SBPzENjevK73Tv??s}xc3geRzfAu;~hJVpB;pAxsOs&lp;=Yc+si_= z)C$e2htRPVuD6qRi(Qvm5UNi^x7wjtJQZ>zFcwrBVv*VwJCuq;7^@G}wx=|+Z0Qmd zUS+3}sYoiF45gy2b}|%CryyOb?aZnVMU$azi6|d#Q4#@lai)rA13K z`j)V7P20&-s3nRAyh|nG?RNce*PR~FOQ*xCJ|1qU4@<2D2t;!%zAYB2i?_B$V)g1V ztRh~v6S+fqrNzS1G@abhh<9%GaNS z*LlG-=?#?UnZawx+;9h&NoLR>vyr_mFoRvgOpzJ91~R84WaiW+nuRGbgN4H-rDjfB zv|jl)(R7&^{705(rpgTdg3f5B+6=x&)0&xY2FuYehgoRmq-o&Bov2x31|Mf9HFJd- zya~QL%u+L_k!m+lZJ8N-lcqJZ+zi&!v}RVC!OK~)neMDMgLl%MuaQ}626wYj&8#9{? z>b2%V(H9{du)fFCt98;g28plEN!y*YQ_pRBj@1b7d=1RLkhP6EjjUT@-ORd8q)V;I z)Q_^QGV4X!zlC&#^)vd=OuEY2Pr8Nn=UTf+x00S`JwV@Lq^qqPNXJQEXsspPM*1S_ zEZe%3^u@~LNh;5mVmz&Tsgz~|%6gXcR??<*Ju7S@?X@b{f$dZeSnYWF+8=^E8}Vcq zegB1OFCbmusY}dL{!2+0d2Bkq zkaWm;1d;SFB3_7Ddft(gyeD$!?l#;YIv#qSCU-osRy}?gGLeQJnIhFF{bh5G|A#V z-UN{QpODD-SILMjSySnyMs=c)er@Y^5;NXuhDV^lT}#*v|LG5uQFetA#>gN z0TlcbOq73G?qY`sf6 znx3L2=Cfs+_AkWO*u4U+=CczvJ7IQXfA&?>HCkEx6Rpw;l}SHfpIaFt>P-F-mG3wW zmN&4*?gwcmmViu8WT;H}lqy}UF%1U4q1E1U)w)FOoZqrz_lKZS(1-`GI;MuVD)V9X z!|aCIxusO;eFCM=Y9n93NZ|qs_cBe)?iMxi+l<@cO?Xmd>|T%E>ZA`*#XS7D*4bRh z*R^@n=|M~3QkK2sG;&KpJ1X)3pqu_zN7{@zwZ#vuU$V~6q4B&n{W45XjVkjE*OWFa zT$5v1xGmE@5ySgfiT(PuW4uunT#5J$xA|K~99C-j7xeS}Z=w_&x-$J@y80=vsXo$z z8Cd{q8s3KDAuS1=WlEf9@IqvhBbmwQUuf`PdLil?yF>5N%nb%l|0^9kdU=c(Nl31A zYCXWVZ!z{mQtL?GLJOPy~SJP9F; z&?#QbNbWUw{_(=3vHJvSo%a&k`<~$>LraNHh94WZLrKl5Vh{e+ScTrM(>8`sqhLE& zMr|g8`7@&nq}h$vV&OqjW%R)3;eonvIz2CU1Wc>K3+O_HBcKUCD_;S7dIj;T!f%5& zub2yo&r?7J&f7XyVVo+wh88wlrxj4H3d`6=n`5${g6r6!TOGks3Kp^#iSO$wFGG;! zrP0EBK$^)eJbj)S)Z@BirW`?t0zKo?j-Z$VJ?*zTf|(RtL~ph^g7YZ&fHt-}0v>h? z+vr}qBPfC3{3y0Kp7Coy`X7NCmm^Tp`PtRT6k~2BB(qIaGpf11mEMW|7!fX7KCmeJ zCw8!kCTDLZ8T}r}(#P2HZB9c}EBzg6nE!(&oO;TbV9d(N&+_CH=1edq`t!~~dA{Mv z$;w)gb!nE7kL5Y2JOMH*^5p1hOr`_`s0e#iu_7w21FCd zHeSonHjZa*6&lORg|QW=l&#zJxorkB)KDuY!v(Opla1L^*;JknO<_kdSck58 zO$)Q9vMV(Ok6xj*@_oY{Fp)l!z>3#oCs!DkPyNz*Q!-0djwMDWU`7>WA&NW! zO|2f)(z#XW)cGTQzkKRK49Dz|UOIx(OaU9h#thlUyp$6% zDfdWBdO7EbdJvRhe1;^zze?eQ!q=#%sKj41R@aiQw<}wsvGjH|T9#~2j+S8UY-z4& zqG9LwUr|T8$&S=R3Ztp^HaiIttu_!LO4c>mQksl5#v&~c>j~%6etS+SW6{%n9jDeT z3KaL9`Z#^?uE48j`ksEpYpz-p$nQ({dB(52tglj;UgJ4DOn+da|DiyBWnfX?*1k>a z8V?rtbaV%vzn2RB2dS~rU-m-JjXgK^?%df?ylr21Wlx|d-SZW#u+slzPv4qFJG*;& z0;hT!d(xGjc5{{?WghFhJ$;+jEb4pZ%)wU<_FUVj<=^$2bMj9G(r13PX;YP!Jm^0a z=sVN5Y1^VrJ!b-Mo;h=-FHjk%?CajN?y^3q6F39yo=xi(1s0v@J999wDDY+k`X2B*lxc2fMeEN!e0;`~C_V6)7 zS6S)b`gHM{%hG}LD}myt12=A3b5oDgo-Wpb*+}v|);U1xfIrY<&dd*N>N(Yi*xwlF z4m9GM4)mPrdAhIrm52HQr=qKR;Or^Whs?oEPF*;~%Or&hpmbX}u`TSRfx;b9A{EB7 zu36RMLTW3YkyM2FLKa1dbX^M9STG?pE~6ZsWCUg+*fggSkvcnE8%?!hzZVV1kdw_x z5E0%@skDC9r4tD|mI~{uE`<&KT$QlfTH3?TU7AX_Mv~2{A(Cpc6Dpmw>%*;}p@WO6 zXl){rvQ^C9o>Es`y&<$DR9!K@qB>OG8cEbOEsD;Ye-Y@qmikb6W2n3#-WtUL$Y?Pm0^HJ-*56Pmvmej>DPRG|>P4Z%hoTeZY-N64$F2I$w@sMZ#3vk~VyUEAh8 zhg=B8V;LqG1FS!(1EI z_k-ARyZ3+k4m9ZmU{qD)STvDRxU+0ar^4FdXqXo{h;$t3htTQxHN_Jt+$v@?S{rUl zASq}MpyIh zXhdUC44S_7Rdp@#q#efiFmTG=j&N#o^pk6+O45BNmBUmcI7eToF0fI!o>j|?#9w<*1?%ry48s%!-O}H zYHLiiDVrhJvBpATM^eL;+zG5bt&P;9nKtH00@n2!lExD`j$3ip_mM1W!QjDvS^p%0 zcwJUD#ar#lSh_w{8BdnS>}}4Qx4f!i&Ybd=NNr`6BdBb)6EVA`QX5EMJ=Omz&`TsU zQYStZ2CTYH%$;Whs~wg<*K=ep`WAK4xD~!LbunQ%&oJNg!jVD+cR2O@Ms~`0J6VNf zwwp8N2bOE(L46B*hneBdvr79? z<0+-CTC!w8sB}XuvLWrP*5z~4nwzs@PIX09^#zVppPaZCF>YI@jN1c7VYb(MAGRMn z4snyj4-fuoNlxh29IuvFi;R~6l$%fIc&Wb{-_!W=0)XwqTYMxZd-1WHz~bX#Yai;khk9)*;k3<@lzSqF zyvBUak)MRzJvq}S^CqY5vyi(7=r3#g)R(kfhPb##Y;Eg#rw!g5xCd=5-;m?wCUZ07 z?s1!P&m052aAM1U8@LB=U1ynN>p{rfe#qUUc&0voK;Rz8 zA+Ivq9sNH-?jFLmeq)Ze6g~y8t8|azjK?=P79Aec^n7k$431z7j=}p7bgQB39>S^H zVJ^ujFjqt4i0+@NNVd1)?FLLG9Bgu_gxyk+;zpu^l-}!9)Z%8aBEdILM8tM&x)JlB zA+9RwH65v~<+|ilawK?XG~%K$L&P11TLJB<3cd-k=}{H zqt5+=gqQ`)w732er#|hmu4}InH0`?f_TlKxy6%U1{LpXup$`&3>dkYV2k+|DfX)!B z{~J`Q2fFUZEn5gdrhl8^-wEk2?i7ao{u_#v^Kr{s!DiZ9STho5cH50JFLPLjYZyPx zNQ|VL6yRCL?|p)<-n$r#uR!L0Ts_>4j`A;XzN_IN_4s)bU(&AY)LZW|kh|ly2XtmX zmewfM3mM}w0bjQtq}^NrsWxLF_%R9jxb0@P$)elKlnTMfWY8eBy*wb>%(S-~9ltlj zKi3}AMtw5nUiGJ;%)-&XN~ZnH7RdWD)xrDq*i*>&mWhaQEp{)j$(Mk4$J0Q4jt~83 zT*zMpWUO5NQqZ))TxR)lAV2;1@^{ngg?98kiurpKUzcwL{c;A+|LeJH3GMMc7{Zrv zAm0Hj&fu9xGc))HK%bYve+Tqy!@Ng*A9Tqu@6%)IzGvD0=TPRpL&?7c-hFqHr!DuL zN&YSH?z@uwY4Gm5g8awe-S;1P4?5z$_sD01ci(m7i@>|@GV+z+-FF!I%fY+vF7m6v zyYDRWnIDfHl@W<&ROT~3xDt$fJbL6ad0Z!Ed^|c6Mg$%`V>0<%wMAUu_)frh-IC!F z^N9c3bwA|W$MAQJ;lDYC=YQLs+;Qwb1wH^fZhHs8a}2o8nuvJ3Hl{w`{qBB?<)_D# za}VHt=-;@EIZFN<@a{f`^=E^3_ax+(jL}~+hQDqM&!29%`vuldj49tbh9BAWk3J`j zx*f>4m~f8J`ch!jorY}3^-g)@U_E?xl2eg;WOHstLdHG5>F$qG;lbQJ^EpS*QCAxyCqf*@ zW2t7`J~Z1nl8iZZg>j4V*H;(AN9Hd-^hnHykI!z%c#@PdISvblL-X+IFN!;|aI(d= z+i=!bW6!ouoJTIt{?;)PCue=YOQ^O;ELx{h(YoejIOQINX zi^$Jc>QeHs!}XT+HVEIra`f|2!5>f#KaUa-4E{dVz~aQ8N>R?Auu}es$ZgDTmj8?3 zVIurI4y2#I7CC=KM!mS;ZA9qZ38dbGAOBs- z`Ttz%@h4}*BEd32{!WkbjYRm~EXd#JQ2tZFmjz!J8UD8>H;llS-? z%oaRHuvBoVApfaJ{f&Zkf=zxqk=k@g@UY;|1m6}sE%;}_zX)1fui@tu!I^>;f(rzf32qW>5KIX2_rJ8WOOWpk^85`5 z@yCMP$CB6Y58xZZbAL*?g%}aJA0_HvSpnw=ze;eUAorEjIP^e@1GrNUn**e-aFV7K7og8Kc0dOsEZkl^crZwa0f{FC4pg5!~^ zY=5#~v7ml$L4Jww{Ao4yt`+>6;4Ok%1@9JoK=2;~pAvjd@TlMkLH_WB_Vs%V__6R) zF^4E`7kpH3ui%daj|sjjn8S4+^ zSnzF;pA`Nh;r}A&<$8;D^NFQcF9a(E7fJaB;lsk;Cj5PZkBa;!g0G1D=fb}&{7K;l zh5xhgUkLBzdJ2E^x(|P*2wzMDUn=}O;TH&hrSPkTzd`t$g^vo~Cj9-vKO%gO@J|W< zQ{j&azAAG4UVtCJ68`ssit97v*+k^-1mUL%KU4S$;g<-1jqrMXNBuVPn44)Szf1UU z2>+1qe=qzK!v9G414Oj{qVTT@e?s_og#WGZ|1SKWh5w82{52c|;i>hqjI{8%s>wDw2v{{acGz*hhO literal 0 HcmV?d00001 diff --git a/110_master/110/os/os/linux/kernel/blk_drv/hd.c b/110_master/110/os/os/linux/kernel/blk_drv/hd.c new file mode 100644 index 0000000..c0e908f --- /dev/null +++ b/110_master/110/os/os/linux/kernel/blk_drv/hd.c @@ -0,0 +1,351 @@ +/* + * linux/kernel/hd.c + * + * (C) 1991 Linus Torvalds + */ + +/* + * This is the low-level hd interrupt support. It traverses the + * request-list, using interrupts to jump between functions. As + * all the functions are called within interrupts, we may not + * sleep. Special care is recommended. + * + * modified by Drew Eckhardt to check nr of hd's from the CMOS. + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#define MAJOR_NR 3 +#include "blk.h" + +#define CMOS_READ(addr) ({ \ +outb_p(0x80|addr,0x70); \ +inb_p(0x71); \ +}) + +/* Max read/write errors/sector */ +#define MAX_ERRORS 7 +#define MAX_HD 2 + +static void recal_intr(void); + +static int recalibrate = 0; /* 1, wen */ +static int reset = 0; + +/* + * This struct defines the HD's and their types. + */ +struct hd_i_struct { + int head,sect,cyl,wpcom,lzone,ctl; + }; +#ifdef HD_TYPE +struct hd_i_struct hd_info[] = { HD_TYPE }; +#define NR_HD ((sizeof (hd_info))/(sizeof (struct hd_i_struct))) +#else +struct hd_i_struct hd_info[] = { {0,0,0,0,0,0},{0,0,0,0,0,0} }; +static int NR_HD = 0; +#endif + +static struct hd_struct { + long start_sect; + long nr_sects; +} hd[5*MAX_HD]={{0,0},}; + +#define port_read(port,buf,nr) \ +__asm__("cld;rep;insw"::"d" (port),"D" (buf),"c" (nr)) + +#define port_write(port,buf,nr) \ +__asm__("cld;rep;outsw"::"d" (port),"S" (buf),"c" (nr)) + +extern void hd_interrupt(void); +extern void rd_load(void); + +/* This may be used only once, enforced by 'static int callable' */ +int sys_setup(void * BIOS) +{ + static int callable = 1; + int i,drive; + unsigned char cmos_disks; + struct partition *p; + struct buffer_head * bh; + + if (!callable) + return -1; + callable = 0; +#ifndef HD_TYPE + for (drive=0 ; drive<2 ; drive++) { + hd_info[drive].cyl = *(unsigned short *) BIOS; + hd_info[drive].head = *(unsigned char *) (2+BIOS); + hd_info[drive].wpcom = *(unsigned short *) (5+BIOS); + hd_info[drive].ctl = *(unsigned char *) (8+BIOS); + hd_info[drive].lzone = *(unsigned short *) (12+BIOS); + hd_info[drive].sect = *(unsigned char *) (14+BIOS); + BIOS += 16; + } + if (hd_info[1].cyl) + NR_HD=2; + else + NR_HD=1; +#endif + for (i=0 ; i are the primary drives in the system, and + the ones reflected as drive 1 or 2. + + The first drive is stored in the high nibble of CMOS + byte 0x12, the second in the low nibble. This will be + either a 4 bit drive type or 0xf indicating use byte 0x19 + for an 8 bit type, drive 1, 0x1a for drive 2 in CMOS. + + Needless to say, a non-zero value means we have + an AT controller hard disk for that drive. + + + */ + + if ((cmos_disks = CMOS_READ(0x12)) & 0xf0) + if (cmos_disks & 0x0f) + NR_HD = 2; + else + NR_HD = 1; + else + NR_HD = 0; + for (i = NR_HD ; i < 2 ; i++) { + hd[i*5].start_sect = 0; + hd[i*5].nr_sects = 0; + } + for (drive=0 ; driveb_data[510] != 0x55 || (unsigned char) + bh->b_data[511] != 0xAA) { + printk("Bad partition table on drive %d\n\r",drive); + panic(""); + } + p = 0x1BE + (void *)bh->b_data; + for (i=1;i<5;i++,p++) { + hd[i+5*drive].start_sect = p->start_sect; + hd[i+5*drive].nr_sects = p->nr_sects; + } + brelse(bh); + } + if (NR_HD) + printk("Partition table%s ok.\n\r",(NR_HD>1)?"s":""); + rd_load(); + mount_root(); + return (0); +} + +static int controller_ready(void) +{ + /* int retries=10000; */ + int retries=100000; + + /* while (--retries && (inb_p(HD_STATUS)&0xc0)!=0x40); */ + while (--retries && (inb_p(HD_STATUS)&0x80)); + return (retries); +} + +static int win_result(void) +{ + int i=inb_p(HD_STATUS); + + if ((i & (BUSY_STAT | READY_STAT | WRERR_STAT | SEEK_STAT | ERR_STAT)) + == (READY_STAT | SEEK_STAT)) + return(0); /* ok */ + if (i&1) i=inb(HD_ERROR); + return (1); +} + +static void hd_out(unsigned int drive,unsigned int nsect,unsigned int sect, + unsigned int head,unsigned int cyl,unsigned int cmd, + void (*intr_addr)(void)) +{ + register int port asm("dx"); + + if (drive>1 || head>15) + panic("Trying to write bad sector"); + if (!controller_ready()) + panic("HD controller not ready"); + do_hd = intr_addr; + outb_p(hd_info[drive].ctl,HD_CMD); + port=HD_DATA; + outb_p(hd_info[drive].wpcom>>2,++port); + outb_p(nsect,++port); + outb_p(sect,++port); + outb_p(cyl,++port); + outb_p(cyl>>8,++port); + outb_p(0xA0|(drive<<4)|head,++port); + outb(cmd,++port); +} + +static int drive_busy(void) +{ + unsigned int i; + + for (i = 0; i < 10000; i++) + if (READY_STAT == (inb_p(HD_STATUS) & (BUSY_STAT|READY_STAT))) + break; + i = inb(HD_STATUS); + i &= BUSY_STAT | READY_STAT | SEEK_STAT; + if (i == READY_STAT | SEEK_STAT) + return(0); + printk("HD controller times out\n\r"); + return(1); +} + +static void reset_controller(void) +{ + int i; + + outb(4,HD_CMD); + for(i = 0; i < 100; i++) nop(); + outb(hd_info[0].ctl & 0x0f ,HD_CMD); + if (drive_busy()) + printk("HD-controller still busy\n\r"); + if ((i = inb(HD_ERROR)) != 1) + printk("HD-controller reset failed: %02x\n\r",i); +} + +static void reset_hd(int nr) +{ + reset_controller(); + hd_out(nr,hd_info[nr].sect,hd_info[nr].sect,hd_info[nr].head-1, + hd_info[nr].cyl,WIN_SPECIFY,&recal_intr); +} + +void unexpected_hd_interrupt(void) +{ + printk("Unexpected HD interrupt\n\r"); +} + +static void bad_rw_intr(void) +{ + if (++CURRENT->errors >= MAX_ERRORS) + end_request(0); + if (CURRENT->errors > MAX_ERRORS/2) + reset = 1; +} + +static void read_intr(void) +{ + if (win_result()) { + bad_rw_intr(); + do_hd_request(); + return; + } + port_read(HD_DATA,CURRENT->buffer,256); + CURRENT->errors = 0; + CURRENT->buffer += 512; + CURRENT->sector++; + if (--CURRENT->nr_sectors) { + do_hd = &read_intr; + return; + } + end_request(1); + do_hd_request(); +} + +static void write_intr(void) +{ + if (win_result()) { + bad_rw_intr(); + do_hd_request(); + return; + } + if (--CURRENT->nr_sectors) { + CURRENT->sector++; + CURRENT->buffer += 512; + do_hd = &write_intr; + port_write(HD_DATA,CURRENT->buffer,256); + return; + } + end_request(1); + do_hd_request(); +} + +static void recal_intr(void) +{ + if (win_result()) + bad_rw_intr(); + do_hd_request(); +} + +void do_hd_request(void) +{ + int i,r; + unsigned int block,dev; + unsigned int sec,head,cyl; + unsigned int nsect; + + INIT_REQUEST; + dev = MINOR(CURRENT->dev); + block = CURRENT->sector; + if (dev >= 5*NR_HD || block+2 > hd[dev].nr_sects) { + end_request(0); + goto repeat; + } + block += hd[dev].start_sect; + dev /= 5; + __asm__("divl %4":"=a" (block),"=d" (sec):"0" (block),"1" (0), + "r" (hd_info[dev].sect)); + __asm__("divl %4":"=a" (cyl),"=d" (head):"0" (block),"1" (0), + "r" (hd_info[dev].head)); + sec++; + nsect = CURRENT->nr_sectors; + if (reset) { + reset = 0; + recalibrate = 1; + reset_hd(CURRENT_DEV); + return; + } + if (recalibrate) { + recalibrate = 0; + hd_out(dev,hd_info[CURRENT_DEV].sect,0,0,0, + WIN_RESTORE,&recal_intr); + return; + } + if (CURRENT->cmd == WRITE) { + hd_out(dev,nsect,sec,head,cyl,WIN_WRITE,&write_intr); + for(i=0 ; i<3000 && !(r=inb_p(HD_STATUS)&DRQ_STAT) ; i++) + /* nothing */ ; + if (!r) { + bad_rw_intr(); + goto repeat; + } + port_write(HD_DATA,CURRENT->buffer,256); + } else if (CURRENT->cmd == READ) { + hd_out(dev,nsect,sec,head,cyl,WIN_READ,&read_intr); + } else + panic("unknown hd-command"); +} + +void hd_init(void) +{ + blk_dev[MAJOR_NR].request_fn = DEVICE_REQUEST; + set_intr_gate(0x2E,&hd_interrupt); + outb_p(inb_p(0x21)&0xfb,0x21); + outb(inb_p(0xA1)&0xbf,0xA1); +} diff --git a/110_master/110/os/os/linux/kernel/blk_drv/hd.o b/110_master/110/os/os/linux/kernel/blk_drv/hd.o new file mode 100644 index 0000000000000000000000000000000000000000..bf2b0d10bc58477ea1758f63f765ba3eab8d6225 GIT binary patch literal 15520 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 literal 0 HcmV?d00001 diff --git a/110_master/110/os/os/linux/kernel/blk_drv/ll_rw_blk.c b/110_master/110/os/os/linux/kernel/blk_drv/ll_rw_blk.c new file mode 100644 index 0000000..f57d998 --- /dev/null +++ b/110_master/110/os/os/linux/kernel/blk_drv/ll_rw_blk.c @@ -0,0 +1,165 @@ +/* + * linux/kernel/blk_dev/ll_rw.c + * + * (C) 1991 Linus Torvalds + */ + +/* + * This handles all read/write requests to block devices + */ +#include +#include +#include +#include + +#include "blk.h" + +/* + * The request-struct contains all necessary data + * to load a nr of sectors into memory + */ +struct request request[NR_REQUEST]; + +/* + * used to wait on when there are no free requests + */ +struct task_struct * wait_for_request = NULL; + +/* blk_dev_struct is: + * do_request-address + * next-request + */ +struct blk_dev_struct blk_dev[NR_BLK_DEV] = { + { NULL, NULL }, /* no_dev */ + { NULL, NULL }, /* dev mem */ + { NULL, NULL }, /* dev fd */ + { NULL, NULL }, /* dev hd */ + { NULL, NULL }, /* dev ttyx */ + { NULL, NULL }, /* dev tty */ + { NULL, NULL } /* dev lp */ +}; + +static inline void lock_buffer(struct buffer_head * bh) +{ + cli(); + while (bh->b_lock) + sleep_on(&bh->b_wait); + bh->b_lock=1; + sti(); +} + +static inline void unlock_buffer(struct buffer_head * bh) +{ + if (!bh->b_lock) + printk("ll_rw_block.c: buffer not locked\n\r"); + bh->b_lock = 0; + wake_up(&bh->b_wait); +} + +/* + * add-request adds a request to the linked list. + * It disables interrupts so that it can muck with the + * request-lists in peace. + */ +static void add_request(struct blk_dev_struct * dev, struct request * req) +{ + struct request * tmp; + + req->next = NULL; + cli(); + if (req->bh) + req->bh->b_dirt = 0; + if (!(tmp = dev->current_request)) { + dev->current_request = req; + sti(); + (dev->request_fn)(); + return; + } + for ( ; tmp->next ; tmp=tmp->next) + if ((IN_ORDER(tmp,req) || + !IN_ORDER(tmp,tmp->next)) && + IN_ORDER(req,tmp->next)) + break; + req->next=tmp->next; + tmp->next=req; + sti(); +} + +static void make_request(int major,int rw, struct buffer_head * bh) +{ + struct request * req; + int rw_ahead; + +/* WRITEA/READA is special case - it is not really needed, so if the */ +/* buffer is locked, we just forget about it, else it's a normal read */ + if (rw_ahead = (rw == READA || rw == WRITEA)) { + if (bh->b_lock) + return; + if (rw == READA) + rw = READ; + else + rw = WRITE; + } + if (rw!=READ && rw!=WRITE) + panic("Bad block dev command, must be R/W/RA/WA"); + lock_buffer(bh); + if ((rw == WRITE && !bh->b_dirt) || (rw == READ && bh->b_uptodate)) { + unlock_buffer(bh); + return; + } +repeat: +/* we don't allow the write-requests to fill up the queue completely: + * we want some room for reads: they take precedence. The last third + * of the requests are only for reads. + */ + if (rw == READ) + req = request+NR_REQUEST; + else + req = request+((NR_REQUEST*2)/3); +/* find an empty request */ + while (--req >= request) + if (req->dev<0) + break; +/* if none found, sleep on new requests: check for rw_ahead */ + if (req < request) { + if (rw_ahead) { + unlock_buffer(bh); + return; + } + sleep_on(&wait_for_request); + goto repeat; + } +/* fill up the request-info, and add it to the queue */ + req->dev = bh->b_dev; + req->cmd = rw; + req->errors=0; + req->sector = bh->b_blocknr<<1; + req->nr_sectors = 2; + req->buffer = bh->b_data; + req->waiting = NULL; + req->bh = bh; + req->next = NULL; + add_request(major+blk_dev,req); +} + +void ll_rw_block(int rw, struct buffer_head * bh) +{ + unsigned int major; + + if ((major=MAJOR(bh->b_dev)) >= NR_BLK_DEV || + !(blk_dev[major].request_fn)) { + printk("Trying to read nonexistent block-device\n\r"); + return; + } + make_request(major,rw,bh); +} + +void blk_dev_init(void) +{ + int i; + + for (i=0 ; iYkGs}N`|^F* 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 + +#include +#include +#include +#include +#include +#include +#include + +#define MAJOR_NR 1 +#include "blk.h" + +char *rd_start; +int rd_length = 0; + +void do_rd_request(void) +{ + int len; + char *addr; + + INIT_REQUEST; + addr = rd_start + (CURRENT->sector << 9); + len = CURRENT->nr_sectors << 9; + if ((MINOR(CURRENT->dev) != 1) || (addr+len > rd_start+rd_length)) { + end_request(0); + goto repeat; + } + if (CURRENT-> cmd == WRITE) { + (void ) memcpy(addr, + CURRENT->buffer, + len); + } else if (CURRENT->cmd == READ) { + (void) memcpy(CURRENT->buffer, + addr, + len); + } else + panic("unknown ramdisk-command"); + end_request(1); + goto repeat; +} + +/* + * Returns amount of memory which needs to be reserved. + */ +long rd_init(long mem_start, int length) +{ + int i; + char *cp; + + blk_dev[MAJOR_NR].request_fn = DEVICE_REQUEST; + rd_start = (char *) mem_start; + rd_length = length; + cp = rd_start; + for (i=0; i < length; i++) + *cp++ = '\0'; + return(length); +} + +/* + * If the root device is the ram disk, try to load it. + * In order to do this, the root device is originally set to the + * floppy, and we later change it to be ram disk. + */ +void rd_load(void) +{ + struct buffer_head *bh; + struct super_block s; + int block = 256; /* Start at block 256 */ + int i = 1; + int nblocks; + char *cp; /* Move pointer */ + + if (!rd_length) + return; + printk("Ram disk: %d bytes, starting at 0x%x\n", rd_length, + (int) rd_start); + if (MAJOR(ROOT_DEV) != 2) + return; + bh = breada(ROOT_DEV,block+1,block,block+2,-1); + if (!bh) { + printk("Disk error while looking for ramdisk!\n"); + return; + } + __asm__ volatile ("cld"); /* by wyj */ + *((struct d_super_block *) &s) = *((struct d_super_block *) bh->b_data); + brelse(bh); + if (s.s_magic != SUPER_MAGIC) + /* No ram disk image present, assume normal floppy boot */ + return; + nblocks = s.s_nzones << s.s_log_zone_size; + if (nblocks > (rd_length >> BLOCK_SIZE_BITS)) { + printk("Ram disk image too big! (%d blocks, %d avail)\n", + nblocks, rd_length >> BLOCK_SIZE_BITS); + return; + } + printk("Loading %d bytes into ram disk... 0000k", + nblocks << BLOCK_SIZE_BITS); + cp = rd_start; + while (nblocks) { + if (nblocks > 2) + bh = breada(ROOT_DEV, block, block+1, block+2, -1); + else + bh = bread(ROOT_DEV, block); + if (!bh) { + printk("I/O error on block %d, aborting load\n", + block); + return; + } + (void) memcpy(cp, bh->b_data, BLOCK_SIZE); + brelse(bh); + printk("\010\010\010\010\010%4dk",i); + cp += BLOCK_SIZE; + block++; + nblocks--; + i++; + } + printk("\010\010\010\010\010done \n"); + ROOT_DEV=0x0101; +} diff --git a/110_master/110/os/os/linux/kernel/blk_drv/ramdisk.o b/110_master/110/os/os/linux/kernel/blk_drv/ramdisk.o new file mode 100644 index 0000000000000000000000000000000000000000..d37a922496b20c46741e78e22466958ee16e9dcd GIT binary patch literal 10664 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 azd^gt2s%I$JikGRTt|uA(-65=A^s1$?rygL literal 0 HcmV?d00001 diff --git a/110_master/110/os/os/linux/kernel/chr_drv/Makefile b/110_master/110/os/os/linux/kernel/chr_drv/Makefile new file mode 100644 index 0000000..9d4d8d1 --- /dev/null +++ b/110_master/110/os/os/linux/kernel/chr_drv/Makefile @@ -0,0 +1,68 @@ +# +# Makefile for the FREAX-kernel character device drivers. +# +# Note! Dependencies are done automagically by 'make dep', which also +# removes any old dependencies. DON'T put your own dependencies here +# unless it's something special (ie not a .c file). +# + +AR =ar +AS =as +LD =ld +LDFLAGS =-s -x +CC =gcc -march=i386 +CFLAGS =-w -g -fstrength-reduce -fomit-frame-pointer -mcld \ + -finline-functions -nostdinc -fno-stack-protector -I../../include +CPP =gcc -E -nostdinc -I../../include + +.c.s: + $(CC) $(CFLAGS) \ + -S -o $*.s $< +.s.o: + $(AS) -o $*.o $< +.c.o: + $(CC) $(CFLAGS) \ + -c -o $*.o $< + +OBJS = tty_io.o console.o keyboard.2.o serial.o rs_io.o \ + tty_ioctl.o + +chr_drv.a: $(OBJS) + $(AR) rcs chr_drv.a $(OBJS) + sync + +keyboard.2.s: keyboard.S ../../include/linux/config.h + $(CPP) -traditional keyboard.S -o keyboard.2.s + +clean: + rm -f core *.o *.a tmp_make keyboard.2.s + for i in *.c;do rm -f `basename $$i .c`.s;done + +dep: + sed '/\#\#\# Dependencies/q' < Makefile > tmp_make + (for i in *.c;do echo -n `echo $$i | sed 's,\.c,\.s,'`" "; \ + $(CPP) -M $$i;done) >> tmp_make + cp tmp_make Makefile + +### Dependencies: +console.s console.o : console.c ../../include/linux/sched.h \ + ../../include/linux/head.h ../../include/linux/fs.h \ + ../../include/sys/types.h ../../include/linux/mm.h ../../include/signal.h \ + ../../include/linux/tty.h ../../include/termios.h ../../include/asm/io.h \ + ../../include/asm/system.h +serial.s serial.o : serial.c ../../include/linux/tty.h ../../include/termios.h \ + ../../include/linux/sched.h ../../include/linux/head.h \ + ../../include/linux/fs.h ../../include/sys/types.h ../../include/linux/mm.h \ + ../../include/signal.h ../../include/asm/system.h ../../include/asm/io.h +tty_io.s tty_io.o : tty_io.c ../../include/ctype.h ../../include/errno.h \ + ../../include/signal.h ../../include/sys/types.h \ + ../../include/linux/sched.h ../../include/linux/head.h \ + ../../include/linux/fs.h ../../include/linux/mm.h ../../include/linux/tty.h \ + ../../include/termios.h ../../include/asm/segment.h \ + ../../include/asm/system.h +tty_ioctl.s tty_ioctl.o : tty_ioctl.c ../../include/errno.h ../../include/termios.h \ + ../../include/linux/sched.h ../../include/linux/head.h \ + ../../include/linux/fs.h ../../include/sys/types.h ../../include/linux/mm.h \ + ../../include/signal.h ../../include/linux/kernel.h \ + ../../include/linux/tty.h ../../include/asm/io.h \ + ../../include/asm/segment.h ../../include/asm/system.h diff --git a/110_master/110/os/os/linux/kernel/chr_drv/chr_drv.a b/110_master/110/os/os/linux/kernel/chr_drv/chr_drv.a new file mode 100644 index 0000000000000000000000000000000000000000..d2f3869a9d5cd226117476be64275b50d1cf4aa7 GIT binary patch literal 68902 zcmeFa3w#yT)iypeXU@qaImrnm+@qX8P|%PI1PC`dK+u4oh^Pe65RwxT$&KV3F5bWf zDj{OQ*0#1-#7nDHTHC6nqLzyawrcUMR(-WCUQ3MHBDTd_^F7brYfesrR(;?1dw>7$ z_h*th&suA*z4m4Hp4oe5_L{6otYyKeYFFLGi!A;ONns z4+fVc8HUlvFw7gi++O-~!|1u+gSh+W>HUxI83y;)=S3oG$|B`UYr}^6Evv0*ju;fy z)YrH~q{&!SUK1&+YG^839$wSf6mD)dDjFIQv!Se_p<#KrQblPBmuq5GQ%xjnR5p}p zLy>S(Q?xN+R8%*WRfbn;(-qA%Wp%JpU#7K5sWh9{G%pQ@8=E5yjRuK|hG>1nK)OpC z%9|>oA~A7X!- zy@AYzJ&{RqY}=MX%P=I`_GPd%eaZL+UEI_=V$kCo$K#}sg|p<{Zp>_am!gZ-_K1D0 zhf0QZdQ=Xrj!FO4>M5TWx8?ZSl?UAf4%pdq9m6=X0F|WE%xSOks?z4Sg^Ey>`J0NZ z(8l8I!LUbBNM)dPAKBKqMeDB09-Ixyjz zqx4U#x8{Oe+a>K*0b7(FYv!xR2<0$=){N}VL)!X$90`4VrFyqeqQbhUbqgRv8=3Oi zaW<__TLJ~vg{tXDzqktMBNbrdXt%FLJBkZSmoN*J^EpXQ{E|tg$C=ehM!oH6NKVE7 z|9XA5S9NbS169RDdEUrB5E_o^G1{khR~gV<1sX z=_hqbzhu+bU0HRA6JxaRLm5<83w+~iQk=Gsf0%)KV0LbIWj#C8WnV5Io6y}`_JuY+ z%g(j&dewXXUCfR#U7?J!X?FJDFA+^e`ph02XM{abTW3e^UKg>hJ-1NXDnh3|O_5vJ z#k=CgpY{VAmVVUP$uRF?D78wPX?ZLMmkVCBid&1bbI`1^QH=&JLLqBa0-(fLle7!H zzO#J_`{DfTQ0pOck9lbCVQ=fcy{~!AL+b2`$iW?q*|u&rjt5wE3EC9u8+hW z(ID=Rq=K75{m?eS4Mz(7jmX7-;YRd)B(J&&*i0kRyA4AuRi6Ilp^30~b;2$*Iith7 zi*iKIhGMo6>8Ddpp%gjnZ~mrr3v+>_h9h3dHEdTUOs;(l#O?X`(J{}^G1-cO>gq8- z3v|Ns{OjKOGcL>RNr>QTqCn%A~v!_bhajhiSs?y-OKq+hr z>9c7h0sW_6QdDB;{>?^#2xLx(5FM=SyQS%c#B(4iW}e$~b-r?NifDygMMfpttr^)z z?)V3q%;u<|JIib=58#18|6|{w__!OfHAp9y#L5|-EO`#*8kKg?4 z%vjs#I!dW-xzLmPb_{komJ;n}_*GU%vdVwp8;^h5+1bOAW;q~>q`NUO*h|>O@neVI z713DBW0TO^Sc8SAsQ$2-uX|Zhte17LQh9a%oL-jE{&Q+zDC!O2q~3}~l7hO9%Y?W6 z`_O3T*%@m6sp0&+vr`5+7{S_V6ckwh61oe|rzz1sw5I|%o{>S=Ky`VDrpLm9Z2D@% zr9&2|MA57{1lG}Qs7yVe&Im|eWivLu$&e8dJ7b2H#x>cDRy87OZ*!wDn;46I(Rhw3 zGM+mUKc2%-x<49Vk?0mKPiOAm&r)>XP|2#YAx-9- z)RVckkBzZ(uk?XN??Au4-L+40Cu`tj4Vo5${lwtbf(%(VjPw5FK(R^UP! zP|N}=FeJt-wgOH}ZHX0FL<5&G(Ml@~i=hnP64qO_6*!L}u>xzEok}vRt-#lq(J<@!Dl2e36RjGB!?VsxtF4R}zUmS%hma1|iTN&n0dbC4 zXbD_%<7Ywx5u+Cyh+}xCA+#vr(qw?|LzqoanKXQP5G0gQ+wyhdH(?2rvwgXUn@~>L z@ug9J=~U2u-#F@2kWTSEN_k}xG*f-Qqn#?YyPz*bon?%h?fVBZlTb~1xR2{75^9)M zj_(%QznpZg?_$PXPCDN=k#sHXkMfzM>qw9GWztSP=|bNT{3bMz9^-qJbR+4pzL~VY zg7i4U8$kkT2@%$$uaAjNlU!BPX!vqS`;)6GaC}CRPD`$8XfS-a zq%%N6o=3XB?-1tZV6G>+#hnew7q=UX^s6Ux> zc5=9Uwc$I9^zh_xg-hoohbvt=KRLYAr3;h8&9F0t`bCg~4w0S&d5z(lN;-tNpr?^8 zhTQN?Cs~rr>MABV8@V)mGf2)&t^|2D$@$4uAkQJWAbA)_k+yy3lO9jn@o~kDGl8_<=OC^#aVqFE-w4u^Xr`Cpr|1zkku)Rq?^Ll9 z(-IP3xvzywLoZq|e1Al&#NMQB-}fj_C++wyK`MzE>~sF)rO_%Qu}?eXurvt)OZ$5Q_a zl8BA`vJM8mN6oLj4y|&fxh1CgHCMC$Lh4*!jOgh~XV6|++R6jB8!vd9+n$YOZmVQ2 zqr$MhNwKxH0pk(hZxJzb02-zB7Bkr!MW}~WbK9CkSiPMIyv6Yda@LQHz#4SBZq@k4u_bM#h}XK5L5CPWFB=iWHM_LYbRS-@ggxb}cBRTmjh%h=85?1WKh9`AG^2FqsXk^}W)03Ku^Iq3{AkI8O)8e9o z?WJPDPVZb~ig8XKFf*Nn3HATZG?kBZZ!CWndVEGN& zmSTHnrc*U21rat&3<*0#Dn;0#@pfayWVW+o6@V0DHHD^~g%){QSMH_^n1pIMeT=Hy z;qh{21_KbZH0)?u>X$$6>Pz5rbMx?DQ(sXVtqkXtH`f{6 zC2%^>UDBP)tF5Vzt~QM3@UpsaeI&PNuP68%LXOGOxZRgzU|KLH=SiKh{b42SC|t7?V*~z zz_-(>-rk}s5b35PBfCpg97oylDFe5hYYk0z(ib5IIxN>0)n)TJxxN>i3}@%gd=&y4 zJB46O%crdLNOAp}FYL~9vZ&`N%k>PsS6B8!zTHtAi}hXcR4GcG^xdVU$Fx2w=LJ?Z zYv~1@Q6#x+J8Ed5E^GHgHd~j?)8N)v#OFyzeH~LqJj)h%2Hm^c(`(jb=h&QdETcEg z=16%{qzu0m%ZS8A~g;5%@EZ$ zj8vH(+1S(&30FiKnpFP_R|YGp%Rz_XR;04LX$>;i91brB)G2o&NN=3#z$>ERXqcfj zSA>zla`-K&ZKz)sl-HIw!C^^R1M9&EbF!}^^E@EcRV9^FQC6X} zkgE#qQiTb+T4kz_8x2)eWf4PFRd{u{BC6f6R5U3Y-JPYxPBqHWN!bcxDGn42*Dp8d zbOnMQ?pT^}FdK28jA%X2N2m`L2zgQ2s)E-RI#sDbPI%N*iMwgml<_WwKJwKKO_5-? z(8eg7!8DgGU4z=fbSj@e1^gKWlhH;*Q+0_JRly2uY^rI1M;IOixPLL~;O3<+%BrkU zxe@;_wGGYTGB|-@T^Qlj@He9(N6KqzaZIlW^So#@Gg~N8b2x&!TUy&tLFY3yWmh!R zBP(dEDo&Von@@B=gNWs-=@<>QmHK$HK_H9GaA|`k#Tr5rb5G3%ZeX|vt)f{~6^?8L z(yLPp4~sr(<&~9a>26)Cwub}Cy8SHAIjDPdjH()V-MPG`s;UN4%&M|ROuF^asi|!= zmZ5-d6{DB2x~j|T>%-!|rXD_dRHLAmp5|J($w6h7h3gto%lZOjG%jmuG{USeUWFLF z$*2W|lw%R9qO~x{&Wb}*(*#rMJfJeJ%gaQRUmu(RR8v)9ILfe#)>FrG0FQ!E2WLB~ zCd;9Zp5BCX(7seVV+w9P=2bV;h4bp8m65!L=8^T`Rr=aGGC#MVU}SCi(!6{v$Xgz6 zLUHqy)1ao6s;&PtBYdSXbig|{4m17R_+xA9W^4(Dg!#Ec-rlvYA z*6jVMxSTUik;tiMOiy*@BY^U`*xi{R)U_|u4 z3-)#Fk!#Jz(|wEYL{vX*XBmTt0P7(DRr93 zU5Z;Onhh_FF2jMXYA|vu6d}+gva1dZ}1^d#M!89K|zY*?UlfXR|#aa$GEP&JkYf3+AA6rKThtV*{0mQf;6c2 zG-h}1=7zC+@#$_sx`&Y%(`6mF=@x@_>#boCxS$1u)-%-vkQRtQMD+gs3!-`ucUASCTp*%9cmFT0zYg_|LWFULld zV+mv|2kXbJ7v61(s|F)yreXXDGIw)L$EV4#%sD6E~@(u|Qjcm8T^e|9)y07FsFu++Cu&B^a$V9ga1Vj zo(}}wYYO8(4c@($kbk9z{%bw>_8$CE@b2}7@p-4s-I!mx^K!2_4Cg~ocVjr8mAKa( zhMxxBz21=5;~~z+Ti=htTC{2y7T&IOK@U&Q_^TE-k3{5_3jM&Y)q8@3Ij2Ena@>RN_)`-Fc}koV!3UaH_gLH1$FM+u%KsM-;4v_$zY1@{a7PVi;HzX%=^#0wfK zo*!+M@%syA3+4+>5~M>S>Mau7E%>6~8-jlm#NB+QkNe09=L#mF;nGfD!BWAn;0nR3 z1zQDg65Jv9sNin}Ul4p<@UMan&lgCqk6@PINWt-fGXyUXyiBk~a5E9dber(|1P_Y* zP2oQf{7B?po{x}zG7<5I3qM_OrpW0|k9u{2%_9Gr@LL7HBl6pXzf1V%gnvo!b& z{8XOzVE=r%9)61F@*M z16LX4{crD)M7TqQ)(}_0jlp5s|y8(wtrC~l^JFZIVRoKhxt~8k}|aQ$%&JY76~ra@F}};Wz~*sC1h=F zp4Hjb#{m)e>9eiRKHJ{bhXrjrg{E6yX#LYC$L?%PVfeACdvutpw-Nhx&@fWe_8G|y zV16Vks@7CCJBGNa(pcLmDq4yk^oZZKKHK`|PhkJZS~y&5e+n|uO$kxA59?&av#r00 z&+D^qx1GY+Z7B>5{Pd-^6lU4{trl!vVYVsjfuA0gkY{uXiAdk6a)JWlRl z_Q&sQ9;^f*>5M(wZHM>B8*sz8U%DxeD_U!oic``v4*l_|9*bB%K(j$CWl#6!Sm*&S z1>E+ljt&Qe!*@`z<%p%CD`|;3PbhioK3z>!t=9faF4T_1Gh2?EkuzJ4TamL7-|A?R z{zN-W>DeQ25b4*^ajxl@Bza+jj0-0VMW-WE_c+zD13%rTBD;ZG{?JNGM}mvZ zo>d#urO|(zV^kpg#ImCr9W!wvrt|eBU|Nn3S~W%-v3DMR0z(_T$IvlU6M>F_F40R9 zjUA5YY@yqAcwqGJC_xmo59NG4cGkvq)IA5Q=J3U5?ZD^6_>8kQyn&)HnT?3?QAZw1 z15fFN$V=v?B>d)YoNa|f80RY!?$ZmAXF5~O++?iZ6Fu-Tm0DxIBI#2yO*KQ-rrY|8 zvy2*SH>O|7VbD=x*9I$aJ6s!nQQz6`jvj2pPSfT5oY+74tk|k#NaG9BzW=jgGeHhwzA)|QJ}Wjm`R#Y$ zM<3F=K%rGRJ4m1zAiBgvNIcHlZ6P1qY&gYP^HU$lb;UlSp$jns8-L?h!^ z=0cC%x<)rj#`bsQ&JW>3SGB}__{UdWl!9RJ*14ZpN`|sGzUck2fWM~ z+d+FTktRh_8JMgbE)ViYla3T4f%f;ILwO1W+bMVz0{Tr>1>Y3XuJjRjI|CmRZ6|t$ zTxbI8?}M!8^~JsJw7-YSruoF^l}e}OaKgrY_c>C|XMwt=q zuP^27VfeZPRgW}(02j&^Gk8uk;mBAd(osUL7~K2tjomSU+`?!o8xEV|y>N2gF-({K z_&8`4!eMhqh6sv~ts)58AHzhu{nz+8;4NW7*g6KO)Bgc|F`-29q1&mT$d==Ql`nTi z&;@`ERiY_@Z|%XD{PtU^%^!6YU5sGnaAI_zm`Gif7H7AePe`bcca18^__d?k`ot1! z^KV!JORWd#KK&pL)n0wf4z?UYVQ*qs`$wojofA}YTrDfjmLs8-<6{EX@tsF>nCqd@ zd3XooA$Q4&D7l@ijE_jVo%;Cus3+b~5&fvv58Y0sIDHJ;*<{>kdl@bKxzQL|9cGy& zxzRQ;8ei)DtkhJ5wiL$I9U2ba(MVe1XM7&xaqYmriO1}<^t{Dkm~LipBde)|V*6CQ<_)iE_j@Ub{fgkYpgYlA2DS0qnGLxsCJK`n3pybAQNd+bA;w8_sYpzh9 zt~)N5W6`aQlILiW9vAe;G6wR)+WJtaubBH*^;JgnNP_a)L-^?kbfg?vio`p7M;ZZJ z(Cstz^){0;+&dsUGF@Gba`t0j+aDL`4Bo8V<--#sj&}AQaRR^GbGyTo_+#$5og>Ku zUS2GDdv=$tHE+uRQ+2?b4G1Q<@evoDyybX8GX19Ie1$iR)CsSn}=GCIB4x@9jBsV)AX<}4P&m1&9ltb+1VMJdT&g_ zuqzFr8EWA9V%KcEtq-d(b|-|DBUAYUUXBO3>0=)PwaY{e@sm7`Z$lF;wX(YU7LVwLI3JUxZ5Q5ie%_6IxfXWbFD`iY*5{-Hh*I z?|Nvuo7OHq1AJ&&jKxJ#*aK?D!h=EUxKpXO{SZHe{jah=A4mTwj&{TUJNOsa8?{nv{1@?Eb55*kmj|guA-VL4K0bj*_ z47(RRW!(G4(XQ;PAk$#FZk$E1&%C(ly7G7|`iwNEK(zGf+$1T5yMyn>7YMj%A+>@RZ}>841IKWe19~4cks= zv``Z~)|PJpetpC6Q;j`=Kb_P#A0q+4xlpui@3&2u)JslnE8#W@P3NCb@$y?Fp5RJE z!~3UKAUi%j<#_;mqO#>Nl59$n1IXsX9{apsBZ7Ym?Adb}%kZZll6`@);D3>p=aF{& ziz&a5wBOI=IrjX?$Z=W<*M!;^QJ!X{gveZSHJA)5Yekj~Jqud@H4bnNdukmGTpsR!otVa!V{^l9kH0 z%j|{g5i?|^>}DYqGtEl*A&Re=Vk?!e-Pwz%cD9vLO#_N4u~HV$v|?siDLZLkF|#w< zO1X~Nxs=RYE9F7PQOtZRg|DG#W`UJ*hz3;1Vk_mISjZCOng%XgkKalw6%T_AdkO2U z+Df^ZA>|CIMIB%@puIGJn2lD-&zb8AG7&2!jn!L8X0??vis^(|*H>97XF+CH&B5VW zXQgsIn_XQ2<`B}sYg_i^?;{**Jd(nVH?fAa~JKm*jp#6T?V^4~$aj`V2% z51F@m(uMwN(ha1?_~(&sBt6#u811hhJwdFUN~9d!yDsBQ$PnnpPc(?YK#yB=V@hiui_!(RjK;TlqV1Zਞ(_ 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 E8yu$yWB>pF literal 0 HcmV?d00001 diff --git a/110_master/110/os/os/linux/kernel/chr_drv/console.c b/110_master/110/os/os/linux/kernel/chr_drv/console.c new file mode 100644 index 0000000..a12ffbf --- /dev/null +++ b/110_master/110/os/os/linux/kernel/chr_drv/console.c @@ -0,0 +1,710 @@ +/* + * linux/kernel/console.c + * + * (C) 1991 Linus Torvalds + */ + +/* + * console.c + * + * This module implements the console io functions + * 'void con_init(void)' + * 'void con_write(struct tty_queue * queue)' + * Hopefully this will be a rather complete VT102 implementation. + * + * Beeping thanks to John T Kohl. + */ + +/* + * NOTE!!! We sometimes disable and enable interrupts for a short while + * (to put a word in video IO), but this will work even for keyboard + * interrupts. We know interrupts aren't enabled when getting a keyboard + * interrupt, as we use trap-gates. Hopefully all is well. + */ + +/* + * Code to check for different video-cards mostly by Galen Hunt, + * + */ + +#include +#include +#include +#include + +/* + * These are set up by the setup-routine at boot-time: + */ + +#define ORIG_X (*(unsigned char *)0x90000) +#define ORIG_Y (*(unsigned char *)0x90001) +#define ORIG_VIDEO_PAGE (*(unsigned short *)0x90004) +#define ORIG_VIDEO_MODE ((*(unsigned short *)0x90006) & 0xff) +#define ORIG_VIDEO_COLS (((*(unsigned short *)0x90006) & 0xff00) >> 8) +#define ORIG_VIDEO_LINES (25) +#define ORIG_VIDEO_EGA_AX (*(unsigned short *)0x90008) +#define ORIG_VIDEO_EGA_BX (*(unsigned short *)0x9000a) +#define ORIG_VIDEO_EGA_CX (*(unsigned short *)0x9000c) + +#define VIDEO_TYPE_MDA 0x10 /* Monochrome Text Display */ +#define VIDEO_TYPE_CGA 0x11 /* CGA Display */ +#define VIDEO_TYPE_EGAM 0x20 /* EGA/VGA in Monochrome Mode */ +#define VIDEO_TYPE_EGAC 0x21 /* EGA/VGA in Color Mode */ + +#define NPAR 16 + +extern void keyboard_interrupt(void); + +static unsigned char video_type; /* Type of display being used */ +static unsigned long video_num_columns; /* Number of text columns */ +static unsigned long video_size_row; /* Bytes per row */ +static unsigned long video_num_lines; /* Number of test lines */ +static unsigned char video_page; /* Initial video page */ +static unsigned long video_mem_start; /* Start of video RAM */ +static unsigned long video_mem_end; /* End of video RAM (sort of) */ +static unsigned short video_port_reg; /* Video register select port */ +static unsigned short video_port_val; /* Video register value port */ +static unsigned short video_erase_char; /* Char+Attrib to erase with */ + +static unsigned long origin; /* Used for EGA/VGA fast scroll */ +static unsigned long scr_end; /* Used for EGA/VGA fast scroll */ +static unsigned long pos; +static unsigned long x,y; +static unsigned long top,bottom; +static unsigned long state=0; +static unsigned long npar,par[NPAR]; +static unsigned long ques=0; +static unsigned char attr=0x07; + +static void sysbeep(void); + +/* + * this is what the terminal answers to a ESC-Z or csi0c + * query (= vt100 response). + */ +#define RESPONSE "\033[?1;2c" + +/* NOTE! gotoxy thinks x==video_num_columns is ok */ +static inline void gotoxy(unsigned int new_x,unsigned int new_y) +{ + if (new_x > video_num_columns || new_y >= video_num_lines) + return; + x=new_x; + y=new_y; + pos=origin + y*video_size_row + (x<<1); +} + +static inline void set_origin(void) +{ + cli(); + outb_p(12, video_port_reg); + outb_p(0xff&((origin-video_mem_start)>>9), video_port_val); + outb_p(13, video_port_reg); + outb_p(0xff&((origin-video_mem_start)>>1), video_port_val); + sti(); +} + +static void scrup(void) +{ + if (video_type == VIDEO_TYPE_EGAC || video_type == VIDEO_TYPE_EGAM) + { + if (!top && bottom == video_num_lines) { + origin += video_size_row; + pos += video_size_row; + scr_end += video_size_row; + if (scr_end > video_mem_end) { + __asm__("cld\n\t" + "rep\n\t" + "movsl\n\t" + "movl video_num_columns,%1\n\t" + "rep\n\t" + "stosw" + ::"a" (video_erase_char), + "c" ((video_num_lines-1)*video_num_columns>>1), + "D" (video_mem_start), + "S" (origin) + ); + scr_end -= origin-video_mem_start; + pos -= origin-video_mem_start; + origin = video_mem_start; + } else { + __asm__("cld\n\t" + "rep\n\t" + "stosw" + ::"a" (video_erase_char), + "c" (video_num_columns), + "D" (scr_end-video_size_row) + ); + } + set_origin(); + } else { + __asm__("cld\n\t" + "rep\n\t" + "movsl\n\t" + "movl video_num_columns,%%ecx\n\t" + "rep\n\t" + "stosw" + ::"a" (video_erase_char), + "c" ((bottom-top-1)*video_num_columns>>1), + "D" (origin+video_size_row*top), + "S" (origin+video_size_row*(top+1)) + ); + } + } + else /* Not EGA/VGA */ + { + __asm__("cld\n\t" + "rep\n\t" + "movsl\n\t" + "movl video_num_columns,%%ecx\n\t" + "rep\n\t" + "stosw" + ::"a" (video_erase_char), + "c" ((bottom-top-1)*video_num_columns>>1), + "D" (origin+video_size_row*top), + "S" (origin+video_size_row*(top+1)) + ); + } +} + +static void scrdown(void) +{ + if (video_type == VIDEO_TYPE_EGAC || video_type == VIDEO_TYPE_EGAM) + { + __asm__("std\n\t" + "rep\n\t" + "movsl\n\t" + "addl $2,%%edi\n\t" /* %edi has been decremented by 4 */ + "movl video_num_columns,%%ecx\n\t" + "rep\n\t" + "stosw" + ::"a" (video_erase_char), + "c" ((bottom-top-1)*video_num_columns>>1), + "D" (origin+video_size_row*bottom-4), + "S" (origin+video_size_row*(bottom-1)-4) + ); + } + else /* Not EGA/VGA */ + { + __asm__("std\n\t" + "rep\n\t" + "movsl\n\t" + "addl $2,%%edi\n\t" /* %edi has been decremented by 4 */ + "movl video_num_columns,%%ecx\n\t" + "rep\n\t" + "stosw" + ::"a" (video_erase_char), + "c" ((bottom-top-1)*video_num_columns>>1), + "D" (origin+video_size_row*bottom-4), + "S" (origin+video_size_row*(bottom-1)-4) + ); + } +} + +static void lf(void) +{ + if (y+1top) { + y--; + pos -= video_size_row; + return; + } + scrdown(); +} + +static void cr(void) +{ + pos -= x<<1; + x=0; +} + +static void del(void) +{ + if (x) { + pos -= 2; + x--; + *(unsigned short *)pos = video_erase_char; + } +} + +static void csi_J(int par) +{ + long count __asm__("cx"); + long start __asm__("di"); + + switch (par) { + case 0: /* erase from cursor to end of display */ + count = (scr_end-pos)>>1; + start = pos; + break; + case 1: /* erase from start to cursor */ + count = (pos-origin)>>1; + start = origin; + break; + case 2: /* erase whole display */ + count = video_num_columns * video_num_lines; + start = origin; + break; + default: + return; + } + __asm__("cld\n\t" + "rep\n\t" + "stosw\n\t" + ::"c" (count), + "D" (start),"a" (video_erase_char) + ); +} + +static void csi_K(int par) +{ + long count __asm__("cx"); + long start __asm__("di"); + + switch (par) { + case 0: /* erase from cursor to end of line */ + if (x>=video_num_columns) + return; + count = video_num_columns-x; + start = pos; + break; + case 1: /* erase from start of line to cursor */ + start = pos - (x<<1); + count = (x>9), video_port_val); + outb_p(15, video_port_reg); + outb_p(0xff&((pos-video_mem_start)>>1), video_port_val); + sti(); +} + +static void respond(struct tty_struct * tty) +{ + char * p = RESPONSE; + + cli(); + while (*p) { + PUTCH(*p,tty->read_q); + p++; + } + sti(); + copy_to_cooked(tty); +} + +static void insert_char(void) +{ + int i=x; + unsigned short tmp, old = video_erase_char; + unsigned short * p = (unsigned short *) pos; + + while (i++=video_num_columns) + return; + i = x; + while (++i < video_num_columns) { + *p = *(p+1); + p++; + } + *p = video_erase_char; +} + +static void delete_line(void) +{ + int oldtop,oldbottom; + + oldtop=top; + oldbottom=bottom; + top=y; + bottom = video_num_lines; + scrup(); + top=oldtop; + bottom=oldbottom; +} + +static void csi_at(unsigned int nr) +{ + if (nr > video_num_columns) + nr = video_num_columns; + else if (!nr) + nr = 1; + while (nr--) + insert_char(); +} + +static void csi_L(unsigned int nr) +{ + if (nr > video_num_lines) + nr = video_num_lines; + else if (!nr) + nr = 1; + while (nr--) + insert_line(); +} + +static void csi_P(unsigned int nr) +{ + if (nr > video_num_columns) + nr = video_num_columns; + else if (!nr) + nr = 1; + while (nr--) + delete_char(); +} + +static void csi_M(unsigned int nr) +{ + if (nr > video_num_lines) + nr = video_num_lines; + else if (!nr) + nr=1; + while (nr--) + delete_line(); +} + +static int saved_x=0; +static int saved_y=0; + +static void save_cur(void) +{ + saved_x=x; + saved_y=y; +} + +static void restore_cur(void) +{ + gotoxy(saved_x, saved_y); +} + +void con_write(struct tty_struct * tty) +{ + int nr; + char c; + + nr = CHARS(tty->write_q); + while (nr--) { + GETCH(tty->write_q,c); + switch(state) { + case 0: + if (c>31 && c<127) { + if (x>=video_num_columns) { + x -= video_num_columns; + pos -= video_size_row; + lf(); + } + __asm__("movb attr,%%ah\n\t" + "movw %%ax,%1\n\t" + ::"a" (c),"m" (*(short *)pos) + ); + pos += 2; + x++; + } else if (c==27) + state=1; + else if (c==10 || c==11 || c==12) + lf(); + else if (c==13) + cr(); + else if (c==ERASE_CHAR(tty)) + del(); + else if (c==8) { + if (x) { + x--; + pos -= 2; + } + } else if (c==9) { + c=8-(x&7); + x += c; + pos += c<<1; + if (x>video_num_columns) { + x -= video_num_columns; + pos -= video_size_row; + lf(); + } + c=9; + } else if (c==7) + sysbeep(); + break; + case 1: + state=0; + if (c=='[') + state=2; + else if (c=='E') + gotoxy(0,y+1); + else if (c=='M') + ri(); + else if (c=='D') + lf(); + else if (c=='Z') + respond(tty); + else if (x=='7') + save_cur(); + else if (x=='8') + restore_cur(); + break; + case 2: + for(npar=0;npar='0' && c<='9') { + par[npar]=10*par[npar]+c-'0'; + break; + } else state=4; + case 4: + state=0; + switch(c) { + case 'G': case '`': + if (par[0]) par[0]--; + gotoxy(par[0],y); + break; + case 'A': + if (!par[0]) par[0]++; + gotoxy(x,y-par[0]); + break; + case 'B': case 'e': + if (!par[0]) par[0]++; + gotoxy(x,y+par[0]); + break; + case 'C': case 'a': + if (!par[0]) par[0]++; + gotoxy(x+par[0],y); + break; + case 'D': + if (!par[0]) par[0]++; + gotoxy(x-par[0],y); + break; + case 'E': + if (!par[0]) par[0]++; + gotoxy(0,y+par[0]); + break; + case 'F': + if (!par[0]) par[0]++; + gotoxy(0,y-par[0]); + break; + case 'd': + if (par[0]) par[0]--; + gotoxy(x,par[0]); + break; + case 'H': case 'f': + if (par[0]) par[0]--; + if (par[1]) par[1]--; + gotoxy(par[1],par[0]); + break; + case 'J': + csi_J(par[0]); + break; + case 'K': + csi_K(par[0]); + break; + case 'L': + csi_L(par[0]); + break; + case 'M': + csi_M(par[0]); + break; + case 'P': + csi_P(par[0]); + break; + case '@': + csi_at(par[0]); + break; + case 'm': + csi_m(); + break; + case 'r': + if (par[0]) par[0]--; + if (!par[1]) par[1] = video_num_lines; + if (par[0] < par[1] && + par[1] <= video_num_lines) { + top=par[0]; + bottom=par[1]; + } + break; + case 's': + save_cur(); + break; + case 'u': + restore_cur(); + break; + } + } + } + set_cursor(); +} + +/* + * void con_init(void); + * + * This routine initalizes console interrupts, and does nothing + * else. If you want the screen to clear, call tty_write with + * the appropriate escape-sequece. + * + * Reads the information preserved by setup.s to determine the current display + * type and sets everything accordingly. + */ +void con_init(void) +{ + register unsigned char a; + char *display_desc = "????"; + char *display_ptr; + + video_num_columns = ORIG_VIDEO_COLS; + video_size_row = video_num_columns * 2; + video_num_lines = ORIG_VIDEO_LINES; + video_page = ORIG_VIDEO_PAGE; + video_erase_char = 0x0720; + + if (ORIG_VIDEO_MODE == 7) /* Is this a monochrome display? */ + { + video_mem_start = 0xb0000; + video_port_reg = 0x3b4; + video_port_val = 0x3b5; + if ((ORIG_VIDEO_EGA_BX & 0xff) != 0x10) + { + video_type = VIDEO_TYPE_EGAM; + video_mem_end = 0xb8000; + display_desc = "EGAm"; + } + else + { + video_type = VIDEO_TYPE_MDA; + video_mem_end = 0xb2000; + display_desc = "*MDA"; + } + } + else /* If not, it is color. */ + { + video_mem_start = 0xb8000; + video_port_reg = 0x3d4; + video_port_val = 0x3d5; + if ((ORIG_VIDEO_EGA_BX & 0xff) != 0x10) + { + video_type = VIDEO_TYPE_EGAC; + video_mem_end = 0xbc000; + display_desc = "EGAc"; + } + else + { + video_type = VIDEO_TYPE_CGA; + video_mem_end = 0xba000; + display_desc = "*CGA"; + } + } + + /* Let the user known what kind of display driver we are using */ + + display_ptr = ((char *)video_mem_start) + video_size_row - 8; + while (*display_desc) + { + *display_ptr++ = *display_desc++; + display_ptr++; + } + + /* Initialize the variables used for scrolling (mostly EGA/VGA) */ + + origin = video_mem_start; + scr_end = video_mem_start + video_num_lines * video_size_row; + top = 0; + bottom = video_num_lines; + + gotoxy(ORIG_X,ORIG_Y); + set_trap_gate(0x21,&keyboard_interrupt); + outb_p(inb_p(0x21)&0xfd,0x21); + a=inb_p(0x61); + outb_p(a|0x80,0x61); + outb(a,0x61); +} +/* from bsd-net-2: */ + +void sysbeepstop(void) +{ + /* disable counter 2 */ + outb(inb_p(0x61)&0xFC, 0x61); +} + +int beepcount = 0; + +static void sysbeep(void) +{ + /* enable counter 2 */ + outb_p(inb_p(0x61)|3, 0x61); + /* set command for counter 2, 2 byte write */ + outb_p(0xB6, 0x43); + /* send 0x637 for 750 HZ */ + outb_p(0x37, 0x42); + outb(0x06, 0x42); + /* 1/8 second */ + beepcount = HZ/8; +} diff --git a/110_master/110/os/os/linux/kernel/chr_drv/console.o b/110_master/110/os/os/linux/kernel/chr_drv/console.o new file mode 100644 index 0000000000000000000000000000000000000000..cdb09cf249a683c556a1bd6a57bcc3dbe96270a4 GIT binary patch literal 20896 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" +# 1 "" +# 1 "keyboard.S" + + + + + + + + + + + + + +# 1 "../../include/linux/config.h" 1 + + + + + + + + + + + + + + + + + + + + + +# 36 "../../include/linux/config.h" + +# 47 "../../include/linux/config.h" + +# 14 "keyboard.S" 2 + +.text +.globl keyboard_interrupt + + + + +size = 1024 + +head = 4 +tail = 8 +proc_list = 12 +buf = 16 + +mode: .byte 0 +leds: .byte 2 +e0: .byte 0 + + + + + + +keyboard_interrupt: + pushl %eax + pushl %ebx + pushl %ecx + pushl %edx + push %ds + push %es + movl $0x10,%eax + mov %ax,%ds + mov %ax,%es + xor %al,%al + inb $0x60,%al + cmpb $0xe0,%al + je set_e0 + cmpb $0xe1,%al + je set_e1 + call key_table(,%eax,4) + movb $0,e0 +e0_e1: inb $0x61,%al + jmp 1f +1: jmp 1f +1: orb $0x80,%al + jmp 1f +1: jmp 1f +1: outb %al,$0x61 + jmp 1f +1: jmp 1f +1: andb $0x7F,%al + outb %al,$0x61 + movb $0x20,%al + outb %al,$0x20 + pushl $0 + call do_tty_interrupt + addl $4,%esp + pop %es + pop %ds + popl %edx + popl %ecx + popl %ebx + popl %eax + iret +set_e0: movb $1,e0 + jmp e0_e1 +set_e1: movb $2,e0 + jmp e0_e1 + + + + + + +put_queue: + pushl %ecx + pushl %edx + movl table_list,%edx # read-queue for console + movl head(%edx),%ecx +1: movb %al,buf(%edx,%ecx) + incl %ecx + andl $size-1,%ecx + cmpl tail(%edx),%ecx # buffer full - discard everything + je 3f + shrdl $8,%ebx,%eax + je 2f + shrl $8,%ebx + jmp 1b +2: movl %ecx,head(%edx) + movl proc_list(%edx),%ecx + testl %ecx,%ecx + je 3f + movl $0,(%ecx) +3: popl %edx + popl %ecx + ret + +ctrl: movb $0x04,%al + jmp 1f +alt: movb $0x10,%al +1: cmpb $0,e0 + je 2f + addb %al,%al +2: orb %al,mode + ret +unctrl: movb $0x04,%al + jmp 1f +unalt: movb $0x10,%al +1: cmpb $0,e0 + je 2f + addb %al,%al +2: notb %al + andb %al,mode + ret + +lshift: + orb $0x01,mode + ret +unlshift: + andb $0xfe,mode + ret +rshift: + orb $0x02,mode + ret +unrshift: + andb $0xfd,mode + ret + +caps: testb $0x80,mode + jne 1f + xorb $4,leds + xorb $0x40,mode + orb $0x80,mode +set_leds: + call kb_wait + movb $0xed,%al + outb %al,$0x60 + call kb_wait + movb leds,%al + outb %al,$0x60 + ret +uncaps: andb $0x7f,mode + ret +scroll: + xorb $1,leds + jmp set_leds +num: xorb $2,leds + jmp set_leds + + + + + +cursor: + subb $0x47,%al + jb 1f + cmpb $12,%al + ja 1f + jne cur2 + testb $0x0c,mode + je cur2 + testb $0x30,mode + jne reboot +cur2: cmpb $0x01,e0 + je cur + testb $0x02,leds + je cur + testb $0x03,mode + jne cur + xorl %ebx,%ebx + movb num_table(%eax),%al + jmp put_queue +1: ret + +cur: movb cur_table(%eax),%al + cmpb $'9,%al + ja ok_cur + movb $'~,%ah +ok_cur: shll $16,%eax + movw $0x5b1b,%ax + xorl %ebx,%ebx + jmp put_queue + + + + + +num_table: + .ascii "789 456 1230," + +cur_table: + .ascii "HA5 DGC YB623" + + + + +func: + pushl %eax + pushl %ecx + pushl %edx + call show_stat + popl %edx + popl %ecx + popl %eax + subb $0x3B,%al + jb end_func + cmpb $9,%al + jbe ok_func + subb $18,%al + cmpb $10,%al + jb end_func + cmpb $11,%al + ja end_func +ok_func: + cmpl $4,%ecx + jl end_func + movl func_table(,%eax,4),%eax + xorl %ebx,%ebx + jmp put_queue +end_func: + ret + + + + +func_table: + .long 0x415b5b1b,0x425b5b1b,0x435b5b1b,0x445b5b1b + .long 0x455b5b1b,0x465b5b1b,0x475b5b1b,0x485b5b1b + .long 0x495b5b1b,0x4a5b5b1b,0x4b5b5b1b,0x4c5b5b1b + +# 294 "keyboard.S" + +key_map: + .byte 0,27 + .ascii "1234567890-=" + .byte 127,9 + .ascii "qwertyuiop[]" + .byte 13,0 + .ascii "asdfghjkl;'" + .byte '`,0 + .ascii "\\zxcvbnm,./" + .byte 0,'*,0,32 /* 36-39 */ + .fill 16,1,0 + .byte '-,0,0,0,'+ + .byte 0,0,0,0,0,0,0 + .byte '< + .fill 10,1,0 + + +shift_map: + .byte 0,27 + .ascii "!@#$%^&*()_+" + .byte 127,9 + .ascii "QWERTYUIOP{}" + .byte 13,0 + .ascii "ASDFGHJKL:\"" + .byte '~,0 + .ascii "|ZXCVBNM<>?" + .byte 0,'*,0,32 /* 36-39 */ + .fill 16,1,0 + .byte '-,0,0,0,'+ + .byte 0,0,0,0,0,0,0 + .byte '> + .fill 10,1,0 + +alt_map: + .byte 0,0 + .ascii "\0@\0$\0\0{[]}\\\0" + .byte 0,0 + .byte 0,0,0,0,0,0,0,0,0,0,0 + .byte '~,13,0 + .byte 0,0,0,0,0,0,0,0,0,0,0 + .byte 0,0 + .byte 0,0,0,0,0,0,0,0,0,0,0 + .byte 0,0,0,0 + .fill 16,1,0 + .byte 0,0,0,0,0 + .byte 0,0,0,0,0,0,0 + .byte '| + .fill 10,1,0 + +# 449 "keyboard.S" + + + + +do_self: + lea alt_map,%ebx + testb $0x20,mode + jne 1f + lea shift_map,%ebx + testb $0x03,mode + jne 1f + lea key_map,%ebx +1: movb (%ebx,%eax),%al + orb %al,%al + je none + testb $0x4c,mode + je 2f + cmpb $'a,%al + jb 2f + cmpb $'},%al + ja 2f + subb $32,%al +2: testb $0x0c,mode + je 3f + cmpb $64,%al + jb 3f + cmpb $64+32,%al + jae 3f + subb $64,%al +3: testb $0x10,mode + je 4f + orb $0x80,%al +4: andl $0xff,%eax + xorl %ebx,%ebx + call put_queue +none: ret + + + + + + +minus: cmpb $1,e0 + jne do_self + movl $'/,%eax + xorl %ebx,%ebx + jmp put_queue + + + + + + +key_table: + .long none,do_self,do_self,do_self + .long do_self,do_self,do_self,do_self + .long do_self,do_self,do_self,do_self + .long do_self,do_self,do_self,do_self + .long do_self,do_self,do_self,do_self + .long do_self,do_self,do_self,do_self + .long do_self,do_self,do_self,do_self + .long do_self,ctrl,do_self,do_self + .long do_self,do_self,do_self,do_self + .long do_self,do_self,do_self,do_self + .long do_self,do_self,lshift,do_self + .long do_self,do_self,do_self,do_self + .long do_self,do_self,do_self,do_self + .long do_self,minus,rshift,do_self + .long alt,do_self,caps,func + .long func,func,func,func + .long func,func,func,func + .long func,num,scroll,cursor + .long cursor,cursor,do_self,cursor + .long cursor,cursor,do_self,cursor + .long cursor,cursor,cursor,cursor + .long none,none,do_self,func + .long func,none,none,none + .long none,none,none,none + .long none,none,none,none + .long none,none,none,none + .long none,none,none,none + .long none,none,none,none + .long none,none,none,none + .long none,none,none,none + .long none,none,none,none + .long none,none,none,none + .long none,none,none,none + .long none,none,none,none + .long none,none,none,none + .long none,none,none,none + .long none,none,none,none + .long none,none,none,none + .long none,none,none,none + .long none,unctrl,none,none + .long none,none,none,none + .long none,none,none,none + .long none,none,unlshift,none + .long none,none,none,none + .long none,none,none,none + .long none,none,unrshift,none + .long unalt,none,uncaps,none + .long none,none,none,none + .long none,none,none,none + .long none,none,none,none + .long none,none,none,none + .long none,none,none,none + .long none,none,none,none + .long none,none,none,none + .long none,none,none,none + .long none,none,none,none + .long none,none,none,none + .long none,none,none,none + .long none,none,none,none + .long none,none,none,none + .long none,none,none,none + .long none,none,none,none + .long none,none,none,none + .long none,none,none,none + + + + + +kb_wait: + pushl %eax +1: inb $0x64,%al + testb $0x02,%al + jne 1b + popl %eax + ret + + + + +reboot: + call kb_wait + movw $0x1234,0x472 + movb $0xfc,%al + outb %al,$0x64 +die: jmp die diff --git a/110_master/110/os/os/linux/kernel/chr_drv/keyboard.S b/110_master/110/os/os/linux/kernel/chr_drv/keyboard.S new file mode 100644 index 0000000..25210b4 --- /dev/null +++ b/110_master/110/os/os/linux/kernel/chr_drv/keyboard.S @@ -0,0 +1,588 @@ +/* + * linux/kernel/keyboard.S + * + * (C) 1991 Linus Torvalds + */ + +/* + * Thanks to Alfred Leung for US keyboard patches + * Wolfgang Thiel for German keyboard patches + * Marc Corsini for the French keyboard + */ + +#include + +.text +.globl keyboard_interrupt + +/* + * these are for the keyboard read functions + */ +size = 1024 /* must be a power of two ! And MUST be the same + as in tty_io.c !!!! */ +head = 4 +tail = 8 +proc_list = 12 +buf = 16 + +mode: .byte 0 /* caps, alt, ctrl and shift mode */ +leds: .byte 2 /* num-lock, caps, scroll-lock mode (nom-lock on) */ +e0: .byte 0 + +/* + * con_int is the real interrupt routine that reads the + * keyboard scan-code and converts it into the appropriate + * ascii character(s). + */ +keyboard_interrupt: + pushl %eax + pushl %ebx + pushl %ecx + pushl %edx + push %ds + push %es + movl $0x10,%eax + mov %ax,%ds + mov %ax,%es + xor %al,%al /* %eax is scan code */ + inb $0x60,%al + cmpb $0xe0,%al + je set_e0 + cmpb $0xe1,%al + je set_e1 + call key_table(,%eax,4) + movb $0,e0 +e0_e1: inb $0x61,%al + jmp 1f +1: jmp 1f +1: orb $0x80,%al + jmp 1f +1: jmp 1f +1: outb %al,$0x61 + jmp 1f +1: jmp 1f +1: andb $0x7F,%al + outb %al,$0x61 + movb $0x20,%al + outb %al,$0x20 + pushl $0 + call do_tty_interrupt + addl $4,%esp + pop %es + pop %ds + popl %edx + popl %ecx + popl %ebx + popl %eax + iret +set_e0: movb $1,e0 + jmp e0_e1 +set_e1: movb $2,e0 + jmp e0_e1 + +/* + * This routine fills the buffer with max 8 bytes, taken from + * %ebx:%eax. (%edx is high). The bytes are written in the + * order %al,%ah,%eal,%eah,%bl,%bh ... until %eax is zero. + */ +put_queue: + pushl %ecx + pushl %edx + movl table_list,%edx # read-queue for console + movl head(%edx),%ecx +1: movb %al,buf(%edx,%ecx) + incl %ecx + andl $size-1,%ecx + cmpl tail(%edx),%ecx # buffer full - discard everything + je 3f + shrdl $8,%ebx,%eax + je 2f + shrl $8,%ebx + jmp 1b +2: movl %ecx,head(%edx) + movl proc_list(%edx),%ecx + testl %ecx,%ecx + je 3f + movl $0,(%ecx) +3: popl %edx + popl %ecx + ret + +ctrl: movb $0x04,%al + jmp 1f +alt: movb $0x10,%al +1: cmpb $0,e0 + je 2f + addb %al,%al +2: orb %al,mode + ret +unctrl: movb $0x04,%al + jmp 1f +unalt: movb $0x10,%al +1: cmpb $0,e0 + je 2f + addb %al,%al +2: notb %al + andb %al,mode + ret + +lshift: + orb $0x01,mode + ret +unlshift: + andb $0xfe,mode + ret +rshift: + orb $0x02,mode + ret +unrshift: + andb $0xfd,mode + ret + +caps: testb $0x80,mode + jne 1f + xorb $4,leds + xorb $0x40,mode + orb $0x80,mode +set_leds: + call kb_wait + movb $0xed,%al /* set leds command */ + outb %al,$0x60 + call kb_wait + movb leds,%al + outb %al,$0x60 + ret +uncaps: andb $0x7f,mode + ret +scroll: + xorb $1,leds + jmp set_leds +num: xorb $2,leds + jmp set_leds + +/* + * curosr-key/numeric keypad cursor keys are handled here. + * checking for numeric keypad etc. + */ +cursor: + subb $0x47,%al + jb 1f + cmpb $12,%al + ja 1f + jne cur2 /* check for ctrl-alt-del */ + testb $0x0c,mode + je cur2 + testb $0x30,mode + jne reboot +cur2: cmpb $0x01,e0 /* e0 forces cursor movement */ + je cur + testb $0x02,leds /* not num-lock forces cursor */ + je cur + testb $0x03,mode /* shift forces cursor */ + jne cur + xorl %ebx,%ebx + movb num_table(%eax),%al + jmp put_queue +1: ret + +cur: movb cur_table(%eax),%al + cmpb $'9,%al + ja ok_cur + movb $'~,%ah +ok_cur: shll $16,%eax + movw $0x5b1b,%ax + xorl %ebx,%ebx + jmp put_queue + +#if defined(KBD_FR) +num_table: + .ascii "789 456 1230." +#else +num_table: + .ascii "789 456 1230," +#endif +cur_table: + .ascii "HA5 DGC YB623" + +/* + * this routine handles function keys + */ +func: + pushl %eax + pushl %ecx + pushl %edx + call show_stat + popl %edx + popl %ecx + popl %eax + subb $0x3B,%al + jb end_func + cmpb $9,%al + jbe ok_func + subb $18,%al + cmpb $10,%al + jb end_func + cmpb $11,%al + ja end_func +ok_func: + cmpl $4,%ecx /* check that there is enough room */ + jl end_func + movl func_table(,%eax,4),%eax + xorl %ebx,%ebx + jmp put_queue +end_func: + ret + +/* + * function keys send F1:'esc [ [ A' F2:'esc [ [ B' etc. + */ +func_table: + .long 0x415b5b1b,0x425b5b1b,0x435b5b1b,0x445b5b1b + .long 0x455b5b1b,0x465b5b1b,0x475b5b1b,0x485b5b1b + .long 0x495b5b1b,0x4a5b5b1b,0x4b5b5b1b,0x4c5b5b1b + +#if defined(KBD_FINNISH) +key_map: + .byte 0,27 + .ascii "1234567890+'" + .byte 127,9 + .ascii "qwertyuiop}" + .byte 0,13,0 + .ascii "asdfghjkl|{" + .byte 0,0 + .ascii "'zxcvbnm,.-" + .byte 0,'*,0,32 /* 36-39 */ + .fill 16,1,0 /* 3A-49 */ + .byte '-,0,0,0,'+ /* 4A-4E */ + .byte 0,0,0,0,0,0,0 /* 4F-55 */ + .byte '< + .fill 10,1,0 + +shift_map: + .byte 0,27 + .ascii "!\"#$%&/()=?`" + .byte 127,9 + .ascii "QWERTYUIOP]^" + .byte 13,0 + .ascii "ASDFGHJKL\\[" + .byte 0,0 + .ascii "*ZXCVBNM;:_" + .byte 0,'*,0,32 /* 36-39 */ + .fill 16,1,0 /* 3A-49 */ + .byte '-,0,0,0,'+ /* 4A-4E */ + .byte 0,0,0,0,0,0,0 /* 4F-55 */ + .byte '> + .fill 10,1,0 + +alt_map: + .byte 0,0 + .ascii "\0@\0$\0\0{[]}\\\0" + .byte 0,0 + .byte 0,0,0,0,0,0,0,0,0,0,0 + .byte '~,13,0 + .byte 0,0,0,0,0,0,0,0,0,0,0 + .byte 0,0 + .byte 0,0,0,0,0,0,0,0,0,0,0 + .byte 0,0,0,0 /* 36-39 */ + .fill 16,1,0 /* 3A-49 */ + .byte 0,0,0,0,0 /* 4A-4E */ + .byte 0,0,0,0,0,0,0 /* 4F-55 */ + .byte '| + .fill 10,1,0 + +#elif defined(KBD_US) + +key_map: + .byte 0,27 + .ascii "1234567890-=" + .byte 127,9 + .ascii "qwertyuiop[]" + .byte 13,0 + .ascii "asdfghjkl;'" + .byte '`,0 + .ascii "\\zxcvbnm,./" + .byte 0,'*,0,32 /* 36-39 */ + .fill 16,1,0 /* 3A-49 */ + .byte '-,0,0,0,'+ /* 4A-4E */ + .byte 0,0,0,0,0,0,0 /* 4F-55 */ + .byte '< + .fill 10,1,0 + + +shift_map: + .byte 0,27 + .ascii "!@#$%^&*()_+" + .byte 127,9 + .ascii "QWERTYUIOP{}" + .byte 13,0 + .ascii "ASDFGHJKL:\"" + .byte '~,0 + .ascii "|ZXCVBNM<>?" + .byte 0,'*,0,32 /* 36-39 */ + .fill 16,1,0 /* 3A-49 */ + .byte '-,0,0,0,'+ /* 4A-4E */ + .byte 0,0,0,0,0,0,0 /* 4F-55 */ + .byte '> + .fill 10,1,0 + +alt_map: + .byte 0,0 + .ascii "\0@\0$\0\0{[]}\\\0" + .byte 0,0 + .byte 0,0,0,0,0,0,0,0,0,0,0 + .byte '~,13,0 + .byte 0,0,0,0,0,0,0,0,0,0,0 + .byte 0,0 + .byte 0,0,0,0,0,0,0,0,0,0,0 + .byte 0,0,0,0 /* 36-39 */ + .fill 16,1,0 /* 3A-49 */ + .byte 0,0,0,0,0 /* 4A-4E */ + .byte 0,0,0,0,0,0,0 /* 4F-55 */ + .byte '| + .fill 10,1,0 + +#elif defined(KBD_GR) + +key_map: + .byte 0,27 + .ascii "1234567890\\'" + .byte 127,9 + .ascii "qwertzuiop@+" + .byte 13,0 + .ascii "asdfghjkl[]^" + .byte 0,'# + .ascii "yxcvbnm,.-" + .byte 0,'*,0,32 /* 36-39 */ + .fill 16,1,0 /* 3A-49 */ + .byte '-,0,0,0,'+ /* 4A-4E */ + .byte 0,0,0,0,0,0,0 /* 4F-55 */ + .byte '< + .fill 10,1,0 + + +shift_map: + .byte 0,27 + .ascii "!\"#$%&/()=?`" + .byte 127,9 + .ascii "QWERTZUIOP\\*" + .byte 13,0 + .ascii "ASDFGHJKL{}~" + .byte 0,'' + .ascii "YXCVBNM;:_" + .byte 0,'*,0,32 /* 36-39 */ + .fill 16,1,0 /* 3A-49 */ + .byte '-,0,0,0,'+ /* 4A-4E */ + .byte 0,0,0,0,0,0,0 /* 4F-55 */ + .byte '> + .fill 10,1,0 + +alt_map: + .byte 0,0 + .ascii "\0@\0$\0\0{[]}\\\0" + .byte 0,0 + .byte '@,0,0,0,0,0,0,0,0,0,0 + .byte '~,13,0 + .byte 0,0,0,0,0,0,0,0,0,0,0 + .byte 0,0 + .byte 0,0,0,0,0,0,0,0,0,0,0 + .byte 0,0,0,0 /* 36-39 */ + .fill 16,1,0 /* 3A-49 */ + .byte 0,0,0,0,0 /* 4A-4E */ + .byte 0,0,0,0,0,0,0 /* 4F-55 */ + .byte '| + .fill 10,1,0 + + +#elif defined(KBD_FR) + +key_map: + .byte 0,27 + .ascii "&{\"'(-}_/@)=" + .byte 127,9 + .ascii "azertyuiop^$" + .byte 13,0 + .ascii "qsdfghjklm|" + .byte '`,0,42 /* coin sup gauche, don't know, [*|mu] */ + .ascii "wxcvbn,;:!" + .byte 0,'*,0,32 /* 36-39 */ + .fill 16,1,0 /* 3A-49 */ + .byte '-,0,0,0,'+ /* 4A-4E */ + .byte 0,0,0,0,0,0,0 /* 4F-55 */ + .byte '< + .fill 10,1,0 + +shift_map: + .byte 0,27 + .ascii "1234567890]+" + .byte 127,9 + .ascii "AZERTYUIOP<>" + .byte 13,0 + .ascii "QSDFGHJKLM%" + .byte '~,0,'# + .ascii "WXCVBN?./\\" + .byte 0,'*,0,32 /* 36-39 */ + .fill 16,1,0 /* 3A-49 */ + .byte '-,0,0,0,'+ /* 4A-4E */ + .byte 0,0,0,0,0,0,0 /* 4F-55 */ + .byte '> + .fill 10,1,0 + +alt_map: + .byte 0,0 + .ascii "\0~#{[|`\\^@]}" + .byte 0,0 + .byte '@,0,0,0,0,0,0,0,0,0,0 + .byte '~,13,0 + .byte 0,0,0,0,0,0,0,0,0,0,0 + .byte 0,0 + .byte 0,0,0,0,0,0,0,0,0,0,0 + .byte 0,0,0,0 /* 36-39 */ + .fill 16,1,0 /* 3A-49 */ + .byte 0,0,0,0,0 /* 4A-4E */ + .byte 0,0,0,0,0,0,0 /* 4F-55 */ + .byte '| + .fill 10,1,0 + +#else +#error "KBD-type not defined" +#endif +/* + * do_self handles "normal" keys, ie keys that don't change meaning + * and which have just one character returns. + */ +do_self: + lea alt_map,%ebx + testb $0x20,mode /* alt-gr */ + jne 1f + lea shift_map,%ebx + testb $0x03,mode + jne 1f + lea key_map,%ebx +1: movb (%ebx,%eax),%al + orb %al,%al + je none + testb $0x4c,mode /* ctrl or caps */ + je 2f + cmpb $'a,%al + jb 2f + cmpb $'},%al + ja 2f + subb $32,%al +2: testb $0x0c,mode /* ctrl */ + je 3f + cmpb $64,%al + jb 3f + cmpb $64+32,%al + jae 3f + subb $64,%al +3: testb $0x10,mode /* left alt */ + je 4f + orb $0x80,%al +4: andl $0xff,%eax + xorl %ebx,%ebx + call put_queue +none: ret + +/* + * minus has a routine of it's own, as a 'E0h' before + * the scan code for minus means that the numeric keypad + * slash was pushed. + */ +minus: cmpb $1,e0 + jne do_self + movl $'/,%eax + xorl %ebx,%ebx + jmp put_queue + +/* + * This table decides which routine to call when a scan-code has been + * gotten. Most routines just call do_self, or none, depending if + * they are make or break. + */ +key_table: + .long none,do_self,do_self,do_self /* 00-03 s0 esc 1 2 */ + .long do_self,do_self,do_self,do_self /* 04-07 3 4 5 6 */ + .long do_self,do_self,do_self,do_self /* 08-0B 7 8 9 0 */ + .long do_self,do_self,do_self,do_self /* 0C-0F + ' bs tab */ + .long do_self,do_self,do_self,do_self /* 10-13 q w e r */ + .long do_self,do_self,do_self,do_self /* 14-17 t y u i */ + .long do_self,do_self,do_self,do_self /* 18-1B o p } ^ */ + .long do_self,ctrl,do_self,do_self /* 1C-1F enter ctrl a s */ + .long do_self,do_self,do_self,do_self /* 20-23 d f g h */ + .long do_self,do_self,do_self,do_self /* 24-27 j k l | */ + .long do_self,do_self,lshift,do_self /* 28-2B { para lshift , */ + .long do_self,do_self,do_self,do_self /* 2C-2F z x c v */ + .long do_self,do_self,do_self,do_self /* 30-33 b n m , */ + .long do_self,minus,rshift,do_self /* 34-37 . - rshift * */ + .long alt,do_self,caps,func /* 38-3B alt sp caps f1 */ + .long func,func,func,func /* 3C-3F f2 f3 f4 f5 */ + .long func,func,func,func /* 40-43 f6 f7 f8 f9 */ + .long func,num,scroll,cursor /* 44-47 f10 num scr home */ + .long cursor,cursor,do_self,cursor /* 48-4B up pgup - left */ + .long cursor,cursor,do_self,cursor /* 4C-4F n5 right + end */ + .long cursor,cursor,cursor,cursor /* 50-53 dn pgdn ins del */ + .long none,none,do_self,func /* 54-57 sysreq ? < f11 */ + .long func,none,none,none /* 58-5B f12 ? ? ? */ + .long none,none,none,none /* 5C-5F ? ? ? ? */ + .long none,none,none,none /* 60-63 ? ? ? ? */ + .long none,none,none,none /* 64-67 ? ? ? ? */ + .long none,none,none,none /* 68-6B ? ? ? ? */ + .long none,none,none,none /* 6C-6F ? ? ? ? */ + .long none,none,none,none /* 70-73 ? ? ? ? */ + .long none,none,none,none /* 74-77 ? ? ? ? */ + .long none,none,none,none /* 78-7B ? ? ? ? */ + .long none,none,none,none /* 7C-7F ? ? ? ? */ + .long none,none,none,none /* 80-83 ? br br br */ + .long none,none,none,none /* 84-87 br br br br */ + .long none,none,none,none /* 88-8B br br br br */ + .long none,none,none,none /* 8C-8F br br br br */ + .long none,none,none,none /* 90-93 br br br br */ + .long none,none,none,none /* 94-97 br br br br */ + .long none,none,none,none /* 98-9B br br br br */ + .long none,unctrl,none,none /* 9C-9F br unctrl br br */ + .long none,none,none,none /* A0-A3 br br br br */ + .long none,none,none,none /* A4-A7 br br br br */ + .long none,none,unlshift,none /* A8-AB br br unlshift br */ + .long none,none,none,none /* AC-AF br br br br */ + .long none,none,none,none /* B0-B3 br br br br */ + .long none,none,unrshift,none /* B4-B7 br br unrshift br */ + .long unalt,none,uncaps,none /* B8-BB unalt br uncaps br */ + .long none,none,none,none /* BC-BF br br br br */ + .long none,none,none,none /* C0-C3 br br br br */ + .long none,none,none,none /* C4-C7 br br br br */ + .long none,none,none,none /* C8-CB br br br br */ + .long none,none,none,none /* CC-CF br br br br */ + .long none,none,none,none /* D0-D3 br br br br */ + .long none,none,none,none /* D4-D7 br br br br */ + .long none,none,none,none /* D8-DB br ? ? ? */ + .long none,none,none,none /* DC-DF ? ? ? ? */ + .long none,none,none,none /* E0-E3 e0 e1 ? ? */ + .long none,none,none,none /* E4-E7 ? ? ? ? */ + .long none,none,none,none /* E8-EB ? ? ? ? */ + .long none,none,none,none /* EC-EF ? ? ? ? */ + .long none,none,none,none /* F0-F3 ? ? ? ? */ + .long none,none,none,none /* F4-F7 ? ? ? ? */ + .long none,none,none,none /* F8-FB ? ? ? ? */ + .long none,none,none,none /* FC-FF ? ? ? ? */ + +/* + * kb_wait waits for the keyboard controller buffer to empty. + * there is no timeout - if the buffer doesn't empty, we hang. + */ +kb_wait: + pushl %eax +1: inb $0x64,%al + testb $0x02,%al + jne 1b + popl %eax + ret +/* + * This routine reboots the machine by asking the keyboard + * controller to pulse the reset-line low. + */ +reboot: + call kb_wait + movw $0x1234,0x472 /* don't do memory check */ + movb $0xfc,%al /* pulse reset and A20 low */ + outb %al,$0x64 +die: jmp die diff --git a/110_master/110/os/os/linux/kernel/chr_drv/rs_io.o b/110_master/110/os/os/linux/kernel/chr_drv/rs_io.o new file mode 100644 index 0000000000000000000000000000000000000000..9d7d5b3a22aa1a7d33dea95b723af176ee68e951 GIT binary patch literal 1320 zcma)5O=}ZT6upy7lN1_>vDAuUi$oC$(TZ-YF8rt{7SvR*(+bl`=7mYg$1w9^jTe}J1pL8J+VS-DUc@11#5ry}TuH|L!9&O7g8W*$#YU6UjU z!jd2kzZJlJAu zYUu}^X)*0615dy3#7CS5;3%o*n6o2-mX*|mBJ()SkJ>Kxy3mDOdS@N-cB{sLjja`nuw?{k1!T?BECWK1Ur++2eHxq=#!x{gli&& zBRH@@L{yj;>c8RMuaxqliKJ!!PW(mv0M`reH^_6neMo3eLAl-mBy=A^x!y36flz|$ z9Yaq056bmU5ZT?V>*Z0VgF%1b96oaqeG&Pkh$c>dL{JjkL^3ZF1^Vqn>-rt20MOw)mDl`5E4qoh_V zHiu%f3^vy+-ZaTqsdKQH=_9M_uuwBq{86e5Y7L#$RJ8J@4U1NVGqq%B7P>V(VAV>U z?KNO{nOQ2UnY@MR;}pv*t7+mQ_L+$Cmk2hbH&o7BkuiEb(opct5uPWFopkSn(*o}a PoD +#include +#include +#include + +#define WAKEUP_CHARS (TTY_BUF_SIZE/4) + +extern void rs1_interrupt(void); +extern void rs2_interrupt(void); + +static void init(int port) +{ + outb_p(0x80,port+3); /* set DLAB of line control reg */ + outb_p(0x30,port); /* LS of divisor (48 -> 2400 bps */ + outb_p(0x00,port+1); /* MS of divisor */ + outb_p(0x03,port+3); /* reset DLAB */ + outb_p(0x0b,port+4); /* set DTR,RTS, OUT_2 */ + outb_p(0x0d,port+1); /* enable all intrs but writes */ + (void)inb(port); /* read data port to reset things (?) */ +} + +void rs_init(void) +{ + set_intr_gate(0x24,rs1_interrupt); + set_intr_gate(0x23,rs2_interrupt); + init(tty_table[1].read_q.data); + init(tty_table[2].read_q.data); + outb(inb_p(0x21)&0xE7,0x21); +} + +/* + * This routine gets called when tty_write has put something into + * the write_queue. It must check wheter the queue is empty, and + * set the interrupt register accordingly + * + * void _rs_write(struct tty_struct * tty); + */ +void rs_write(struct tty_struct * tty) +{ + cli(); + if (!EMPTY(tty->write_q)) + outb(inb_p(tty->write_q.data+1)|0x02,tty->write_q.data+1); + sti(); +} diff --git a/110_master/110/os/os/linux/kernel/chr_drv/serial.o b/110_master/110/os/os/linux/kernel/chr_drv/serial.o new file mode 100644 index 0000000000000000000000000000000000000000..bf80e08be94a19c3982f10989e20a6e929a1d240 GIT binary patch literal 6752 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 +#include +#include + +#define ALRMMASK (1<<(SIGALRM-1)) +#define KILLMASK (1<<(SIGKILL-1)) +#define INTMASK (1<<(SIGINT-1)) +#define QUITMASK (1<<(SIGQUIT-1)) +#define TSTPMASK (1<<(SIGTSTP-1)) + +#include +#include +#include +#include + +#define _L_FLAG(tty,f) ((tty)->termios.c_lflag & f) +#define _I_FLAG(tty,f) ((tty)->termios.c_iflag & f) +#define _O_FLAG(tty,f) ((tty)->termios.c_oflag & f) + +#define L_CANON(tty) _L_FLAG((tty),ICANON) +#define L_ISIG(tty) _L_FLAG((tty),ISIG) +#define L_ECHO(tty) _L_FLAG((tty),ECHO) +#define L_ECHOE(tty) _L_FLAG((tty),ECHOE) +#define L_ECHOK(tty) _L_FLAG((tty),ECHOK) +#define L_ECHOCTL(tty) _L_FLAG((tty),ECHOCTL) +#define L_ECHOKE(tty) _L_FLAG((tty),ECHOKE) + +#define I_UCLC(tty) _I_FLAG((tty),IUCLC) +#define I_NLCR(tty) _I_FLAG((tty),INLCR) +#define I_CRNL(tty) _I_FLAG((tty),ICRNL) +#define I_NOCR(tty) _I_FLAG((tty),IGNCR) + +#define O_POST(tty) _O_FLAG((tty),OPOST) +#define O_NLCR(tty) _O_FLAG((tty),ONLCR) +#define O_CRNL(tty) _O_FLAG((tty),OCRNL) +#define O_NLRET(tty) _O_FLAG((tty),ONLRET) +#define O_LCUC(tty) _O_FLAG((tty),OLCUC) + +struct tty_struct tty_table[] = { + { + {ICRNL, /* change incoming CR to NL */ + OPOST|ONLCR, /* change outgoing NL to CRNL */ + 0, + ISIG | ICANON | ECHO | ECHOCTL | ECHOKE, + 0, /* console termio */ + INIT_C_CC}, + 0, /* initial pgrp */ + 0, /* initial stopped */ + con_write, + {0,0,0,0,""}, /* console read-queue */ + {0,0,0,0,""}, /* console write-queue */ + {0,0,0,0,""} /* console secondary queue */ + },{ + {0, /* no translation */ + 0, /* no translation */ + B2400 | CS8, + 0, + 0, + INIT_C_CC}, + 0, + 0, + rs_write, + {0x3f8,0,0,0,""}, /* rs 1 */ + {0x3f8,0,0,0,""}, + {0,0,0,0,""} + },{ + {0, /* no translation */ + 0, /* no translation */ + B2400 | CS8, + 0, + 0, + INIT_C_CC}, + 0, + 0, + rs_write, + {0x2f8,0,0,0,""}, /* rs 2 */ + {0x2f8,0,0,0,""}, + {0,0,0,0,""} + } +}; + +/* + * these are the tables used by the machine code handlers. + * you can implement pseudo-tty's or something by changing + * them. Currently not done. + */ +struct tty_queue * table_list[]={ + &tty_table[0].read_q, &tty_table[0].write_q, + &tty_table[1].read_q, &tty_table[1].write_q, + &tty_table[2].read_q, &tty_table[2].write_q + }; + +void tty_init(void) +{ + rs_init(); + con_init(); +} + +void tty_intr(struct tty_struct * tty, int mask) +{ + int i; + + if (tty->pgrp <= 0) + return; + for (i=0;ipgrp==tty->pgrp) + task[i]->signal |= mask; +} + +static void sleep_if_empty(struct tty_queue * queue) +{ + cli(); + while (!current->signal && EMPTY(*queue)) + interruptible_sleep_on(&queue->proc_list); + sti(); +} + +static void sleep_if_full(struct tty_queue * queue) +{ + if (!FULL(*queue)) + return; + cli(); + while (!current->signal && LEFT(*queue)<128) + interruptible_sleep_on(&queue->proc_list); + sti(); +} + +void wait_for_keypress(void) +{ + sleep_if_empty(&tty_table[0].secondary); +} + +void copy_to_cooked(struct tty_struct * tty) +{ + signed char c; + + while (!EMPTY(tty->read_q) && !FULL(tty->secondary)) { + GETCH(tty->read_q,c); + if (c==13) + if (I_CRNL(tty)) + c=10; + else if (I_NOCR(tty)) + continue; + else ; + else if (c==10 && I_NLCR(tty)) + c=13; + if (I_UCLC(tty)) + c=tolower(c); + if (L_CANON(tty)) { + if (c==KILL_CHAR(tty)) { + /* deal with killing the input line */ + while(!(EMPTY(tty->secondary) || + (c=LAST(tty->secondary))==10 || + c==EOF_CHAR(tty))) { + if (L_ECHO(tty)) { + if (c<32) + PUTCH(127,tty->write_q); + PUTCH(127,tty->write_q); + tty->write(tty); + } + DEC(tty->secondary.head); + } + continue; + } + if (c==ERASE_CHAR(tty)) { + if (EMPTY(tty->secondary) || + (c=LAST(tty->secondary))==10 || + c==EOF_CHAR(tty)) + continue; + if (L_ECHO(tty)) { + if (c<32) + PUTCH(127,tty->write_q); + PUTCH(127,tty->write_q); + tty->write(tty); + } + DEC(tty->secondary.head); + continue; + } + if (c==STOP_CHAR(tty)) { + tty->stopped=1; + continue; + } + if (c==START_CHAR(tty)) { + tty->stopped=0; + continue; + } + } + if (L_ISIG(tty)) { + if (c==INTR_CHAR(tty)) { + tty_intr(tty,INTMASK); + continue; + } + if (c==QUIT_CHAR(tty)) { + tty_intr(tty,QUITMASK); + continue; + } + } + if (c==10 || c==EOF_CHAR(tty)) + tty->secondary.data++; + if (L_ECHO(tty)) { + if (c==10) { + PUTCH(10,tty->write_q); + PUTCH(13,tty->write_q); + } else if (c<32) { + if (L_ECHOCTL(tty)) { + PUTCH('^',tty->write_q); + PUTCH(c+64,tty->write_q); + } + } else + PUTCH(c,tty->write_q); + tty->write(tty); + } + PUTCH(c,tty->secondary); + } + wake_up(&tty->secondary.proc_list); +} + +int tty_read(unsigned channel, char * buf, int nr) +{ + struct tty_struct * tty; + char c, * b=buf; + int minimum,time,flag=0; + long oldalarm; + + if (channel>2 || nr<0) return -1; + tty = &tty_table[channel]; + oldalarm = current->alarm; + time = 10L*tty->termios.c_cc[VTIME]; + minimum = tty->termios.c_cc[VMIN]; + if (time && !minimum) { + minimum=1; + if (flag=(!oldalarm || time+jiffiesalarm = time+jiffies; + } + if (minimum>nr) + minimum=nr; + while (nr>0) { + if (flag && (current->signal & ALRMMASK)) { + current->signal &= ~ALRMMASK; + break; + } + if (current->signal) + break; + if (EMPTY(tty->secondary) || (L_CANON(tty) && + !tty->secondary.data && LEFT(tty->secondary)>20)) { + sleep_if_empty(&tty->secondary); + continue; + } + do { + GETCH(tty->secondary,c); + if (c==EOF_CHAR(tty) || c==10) + tty->secondary.data--; + if (c==EOF_CHAR(tty) && L_CANON(tty)) + return (b-buf); + else { + put_fs_byte(c,b++); + if (!--nr) + break; + } + } while (nr>0 && !EMPTY(tty->secondary)); + if (time && !L_CANON(tty)) + if (flag=(!oldalarm || time+jiffiesalarm = time+jiffies; + else + current->alarm = oldalarm; + if (L_CANON(tty)) { + if (b-buf) + break; + } else if (b-buf >= minimum) + break; + } + current->alarm = oldalarm; + if (current->signal && !(b-buf)) + return -EINTR; + return (b-buf); +} + +int tty_write(unsigned channel, char * buf, int nr) +{ + static cr_flag=0; + struct tty_struct * tty; + char c, *b=buf; + + if (channel>2 || nr<0) return -1; + tty = channel + tty_table; + while (nr>0) { + sleep_if_full(&tty->write_q); + if (current->signal) + break; + while (nr>0 && !FULL(tty->write_q)) { + c=get_fs_byte(b); + if (O_POST(tty)) { + if (c=='\r' && O_CRNL(tty)) + c='\n'; + else if (c=='\n' && O_NLRET(tty)) + c='\r'; + if (c=='\n' && !cr_flag && O_NLCR(tty)) { + cr_flag = 1; + PUTCH(13,tty->write_q); + continue; + } + if (O_LCUC(tty)) + c=toupper(c); + } + b++; nr--; + cr_flag = 0; + PUTCH(c,tty->write_q); + } + tty->write(tty); + if (nr>0) + schedule(); + } + return (b-buf); +} + +/* + * Jeh, sometimes I really like the 386. + * This routine is called from an interrupt, + * and there should be absolutely no problem + * with sleeping even in an interrupt (I hope). + * Of course, if somebody proves me wrong, I'll + * hate intel for all time :-). We'll have to + * be careful and see to reinstating the interrupt + * chips before calling this, though. + * + * I don't think we sleep here under normal circumstances + * anyway, which is good, as the task sleeping might be + * totally innocent. + */ +void do_tty_interrupt(int tty) +{ + copy_to_cooked(tty_table+tty); +} + +void chr_dev_init(void) +{ +} diff --git a/110_master/110/os/os/linux/kernel/chr_drv/tty_io.o b/110_master/110/os/os/linux/kernel/chr_drv/tty_io.o new file mode 100644 index 0000000000000000000000000000000000000000..37e2b15961ebc5713d826d6c25e53571ac6fbb83 GIT binary patch literal 22504 zcmeHPdvFu?o&W7hTCXi(8OvY;P7ol#OdhNBe^l>-sHDRXH%cPl*ri7$T`li$LXr|X`jx-dXJH6!6_R_Rh?(_NW zZ)Mp@n)JW>Lpx}{@5k@^d+rMP@Qs__qiLFOFHLyF7$wB>8y!iT1WjU!s1>&jcSg+Q zkU0MI@t^K~df?Yy(#O4#A#Y@OdnAxNt`9up1wU}*Pgk#AmA8Rs0$|iYv2M5{a_rn; zeRR*Wosj^&j@}A(VAy+%#IbYssuFVeM4K*zGFx%J5H6J=)^Od&Xf?bo;NKo;7~C4T z3ReU7MFMN?|MI{yHHg{x#%K^m;em63L2pDR^EqkK5jb|PP)pJ9R<_Cy6mOEWnF)Vnb;tw;&yyV7+J5A|$jnKF>!eW3Ww)Vv72kq>)o8Qg z9zk2dy>=u3&oro#ZEhVF121+!;G_B^*9B?~-m)R^KF=b3mbc)O=Q?04#E=L+dT!uF z4JuWiC1c=Rc+@Acu_OZnFY3q61&`hbU%@B0JGl>a)WLMc`QR}FS&sZOY-Pv}Xq#~N zer7iF@M6h4(&>d5t^d|heJjwzW885CI3e{|nZMqmV<7_!);MmAWX)UK3>~f60|nMXR@$yFDZms}055ubZ3kf9Q{ zPRN39qz2)n{r~rRkEF(rn(4AI1+E*d&vrDSJYr=1c$I16RiGh8!cZx;m&0{ONmV90 z2Gg+oc%dg12i3|jav32?bZbj=F%rk?J`P={pWmYB^)mhuPVf(H)kqAUAW=*U!#;R) zo$I2IcJwC<{i-qUyBzw?RF)Is%@!l)(FQryf**cBHD|aZFjt@sOy>(OZ{mcy``zU+ zgy}wTzT^0hIJu5LC};0qvK(DHCZ);H=E%%_?Pf}2+7U}t0@hE)V*6xf71^!*h8 z8^pn?$1v-!j;!H4+#cx|yr7-aEcw>-ibU(YGWtWzB71&Ss+vs>^9ubakYWrMwWs-(u$j7d7Wd)Q52TD z$25oG1l|@na`_k7mPe{!;A&z*`bPesN$=rdcXC1MbKX^bL!2kRnN z{^|D^GMghCQ05JyppVXx$o9&X7PMer%ptijCBsTWXRSH$`jGZuxrLNaTa^0^Bh&w zdG1Q-c@9VE1`NPlHI_=+HIuMts-dwJ8ZNgbQe&mIC7v z1!sVJE9OGry9~6(+xjoSjfWA#yXX<1!kA5baU7`En8o{&CAgc$Ci2_P0uP7^s+#1B zN-sTBReB!>@G(cz=e-2rj|-oVi12qQ%*%BCjNAgdzOppbBMIv@UAeuAi0DBG6w##D^rw@;*h$w5_270&B+;q| zf6Qbg(FU6$(XI!7RU}sFH3d4@bv-OQ^xz^kQWER*;CIk`hv?L6x~aCCYVXm5Kcxdn zY|w*WV%Cz_qzC8F!JSNJvmV^QbnYUtRS$;fO%mJn;B9mui5+@yc9FPK51K`_J$i6A z9o)^JNxjCl4+>)s>(-+OZ=obkNd`68kKDSp!?Irw{u>=6NZ5MtFw;qrIG_g~V4@al zeV-nDkU>+6(LG1>noQCbM$ZNi7Z4|(7sfpoVRJ>tNZ@a70t_@A7Lz$ZOyOGxX?w+8 zegNYSa9bgh6h;de6)|e-##P)a_As2+h{CoaPTVwVsNb~~c)(arodoeo#*^eHtDsqJ z{E&W99Cu-(gF4-`jTpa2G8H|(54Mu3_Mo0T-CXb=<_Ko~a>-$z_G zenWgeaj)?;20K7?)A%5hJIKKhKs{MTUmU6#qv=`5{fYhPy#*X4!k;I89dWPUCjK|X zO@AugFN}r61O8M3{nJdm#-GY&g%KrQ2ORts;tj?H_%~YVzEK3oVt2~U3khF6GI-ut z!l`L|g^F#|5XSXru(6c5*PqX~3S${@(^y0Pa^eB-7YU=Cc#Y9X{tDuC;4g*);tl>p zZiz5f5^wZdOnepbu<--xuO=SxTk!+JxPf?+-%7anLcf)C@m9ap<>GCAD-Scz# zMDO&=IkA!W9^*RPjZMUp#w)~c-i3Phh(HDe=a4MzOc7WIoF7%{N-t+f;3;VBaJjnh z1!r;mtTSg1_3(5Y$xtDZY92gxM}bgJLdJo1BMA(bLCp#HO2zstLSF3 z2$1!4H%N`B{vB1kl{FO=@H|z=)-ahKgzA5 zwohmtYH7E@@(FOK>;g44ibS+&G~;ffoq7$D`hD>Xn3U@$4>*pdy&);DXm|vE_4GWD zlcmM9hselsow6lk9ew~&&!t$;GF?Ou9YVA8ESs*M^wyq8Gg)Gn=4 zunsMw{vo2UM!u}U^xshPftR2amzpPvnh&^|4ZEoGU?d!FVbo}G=v=P5@$V$M&P(Cyks0vOM*)K1Mp9${&JyY$Gei+qF; zc59DA3mCNIEW81#bH%(~u&O340WohW+EZ1{NCD2TBzSU#SR>~B3AAy1JGFiWEn|oZ z^A3_bd<@+AEJ}b=;*+kGE}E7>t}ht^$7xxBW8|!>;1f;XU>DBLnhL5k4d4zn${B+Fty0&6`l2hi%ET@i{k29`^vC5X(4NEJk*}gppXeC+Z0?LVTPR6msl;uIl3j!3RX;GDYm2JBv1TjPnX1{ojUlRr zRYMdxOF2^HY*iFR&MEaNC?n`6}NvkEE?-k=Y`GfiKobgmk zCf!#!AVl8k?zQ^tXb&eTrf@8sjV2h{KG<*N!A5%dba!7o1031(Sn(t~q7WvtI(QGkSgECj|rn+Gpz`M;^GS2eQ8FMuQu9~7RRWTnqtS{A|svBn5 zKpn8gnxQQ>3>=d@JSlrM+c<5Wec9~3s5}-1#$;v~xQA-q9mW~6=k$P6K*S9pk+VCc zjVb*Y(!r;1*5`!G&~9Yl$f8EUX`5k2jf-ZTdFD*3l)%Rsh0szrq?ZX1kG_2IY>PRI zdY)L+Gv{Ha*pC}$3+RiZV|KC?JI&D9ojYH1^iiCPEH$fi(Mc2`yHBG+yPUR;@3PHK z+dNsfVz%K4pIEa4yybEN-&?Q>7NzM!77~oxmdIrLy2E_;l7e!Q!v1u>CE}TQu2&>t zS=K>VeAsu4xelmurBsm;v4qq@R*6_9op%DdS}{4tMK+a+*+Q1eI$$LVcDyTNi9}BN z5Q&~#ENShFrTfzM*iy4Um$t3gy`l>p1;>4RMGi|07>R8E!I+(mC9>JQC~+R0*^iDA zg+8uFs0SN_Tx41)sL3iI6ZV>H@i@(NjBhENp6|)#?C>~gf5DEW^0BUis1_clT6tT< z+hP=}&<`_NON^)l3)r7aXOTBM0WA`}Xi{&1rA*6gWSc}Hlg(SPY+sDE5Y~aTGPdLC z4Epqt#dT5SnHE}8)vy8E7VDwW0~W-8W?hi<2L(wTnIjRv|U#w=sGdg6V3 zR>m0%eRfVE7#;bHW%Z+&F{`&9RdzNY(chix7Z&TqU5Ms6kpYItMT1l!1BaZf=$dp6 zuH-r(6L;FnCUS^z0gyvg%FxU3i_z1|HGsV!dNERECF9V?OwS=sT8%SCaO>F8lkK%y z`U*+AC7W;Vv-UfCYjbOK(W2%|ysM?vVYKYEa%gUgoCmpmvbD}gK_)0gGQ$$8pt2L3 ziI!((=@`o{a@i~feIb{_o-M>p>(^f&ZhBuAs$XzcpXS8{NiDj6QCqaNZGpqZc3#Il z9hY`!o6znvwHX1g_c*qE_Y^`Ip9RI*YI8u}{B$+8bK0~kKJ~=EyPf^C>jr+JH?W%PtV{UxmK1L_yN@p* z@%}7-uooQzXy+W*<6=206Sb`awulmw%S^NjQ^O&xu0l6DHkB38q{QQ0T{$cqCDM2< z-q($3Q^JxHR~aCVh$gbVJgkXmAGU@lHXUcHaBQrenA~1urtj)D6Iy7Zz$3Q2+HfyD zeNx7220nPcEM6DT`3E4xIau1W{&+YN3lxpRpL5}F2(m@hQ1APAx^pjA#`cxQJ%P9{A{gVc25#I=;I0i&;ae@l zLFbrGvM9T~1SkLgH9~}msLS<%FyrF(-@#W$PF&{W#!UlvZGei;z~4%@@g*_~cxgM1 zz#r?xcHj}P=&t~r{#x8n0t&QFhYxfTTAOV)5YD4BAZmzwApY_$VRrKC9p}glN}K6#WYYUnPWH9z?4{@G0O*D836g1Z&$QLvyOzyGHGDFykz5=cL--~|PLuHX!hBcHF}5(W7u&S-bD zf_EsGP%x|D`xWF@9n}A*f~OVaS4-r7O~I!X{GozBQ}9;`zNR4lgNC#VV64)>F;6(*rQt-bNG`U_N-V_CADcG#w3I%Ue@VyG&t>A!yA0kAbo>KIA1)o#= zmlge61>aD7AJ-$q_Y=atNzv;S+^G2cb9&V4RWPsk4=DPif*)7>&nx;%ihf?vFDUqu z;{Ugz*K*y1|63KjOToPg9#ZfaA@cltMW0jf`-JG*KPlS7brO2B3E_8vqSq*TlY*9l z{R+Nc!A~jpMMA85Pbm61LM&qFKA{2U{?9niD;NgUL9bG9yMh@7k1BXd!ABJQo`P2t O^kQA0pRj`M3jQCx0hyNo literal 0 HcmV?d00001 diff --git a/110_master/110/os/os/linux/kernel/chr_drv/tty_ioctl.c b/110_master/110/os/os/linux/kernel/chr_drv/tty_ioctl.c new file mode 100644 index 0000000..e4e3745 --- /dev/null +++ b/110_master/110/os/os/linux/kernel/chr_drv/tty_ioctl.c @@ -0,0 +1,204 @@ +/* + * linux/kernel/chr_drv/tty_ioctl.c + * + * (C) 1991 Linus Torvalds + */ + +#include +#include + +#include +#include +#include + +#include +#include +#include + +static unsigned short quotient[] = { + 0, 2304, 1536, 1047, 857, + 768, 576, 384, 192, 96, + 64, 48, 24, 12, 6, 3 +}; + +static void change_speed(struct tty_struct * tty) +{ + unsigned short port,quot; + + if (!(port = tty->read_q.data)) + return; + quot = quotient[tty->termios.c_cflag & CBAUD]; + cli(); + outb_p(0x80,port+3); /* set DLAB */ + outb_p(quot & 0xff,port); /* LS of divisor */ + outb_p(quot >> 8,port+1); /* MS of divisor */ + outb(0x03,port+3); /* reset DLAB */ + sti(); +} + +static void flush(struct tty_queue * queue) +{ + cli(); + queue->head = queue->tail; + sti(); +} + +static void wait_until_sent(struct tty_struct * tty) +{ + /* do nothing - not implemented */ +} + +static void send_break(struct tty_struct * tty) +{ + /* do nothing - not implemented */ +} + +static int get_termios(struct tty_struct * tty, struct termios * termios) +{ + int i; + + verify_area(termios, sizeof (*termios)); + for (i=0 ; i< (sizeof (*termios)) ; i++) + put_fs_byte( ((char *)&tty->termios)[i] , i+(char *)termios ); + return 0; +} + +static int set_termios(struct tty_struct * tty, struct termios * termios) +{ + int i; + + for (i=0 ; i< (sizeof (*termios)) ; i++) + ((char *)&tty->termios)[i]=get_fs_byte(i+(char *)termios); + change_speed(tty); + return 0; +} + +static int get_termio(struct tty_struct * tty, struct termio * termio) +{ + int i; + struct termio tmp_termio; + + verify_area(termio, sizeof (*termio)); + tmp_termio.c_iflag = tty->termios.c_iflag; + tmp_termio.c_oflag = tty->termios.c_oflag; + tmp_termio.c_cflag = tty->termios.c_cflag; + tmp_termio.c_lflag = tty->termios.c_lflag; + tmp_termio.c_line = tty->termios.c_line; + for(i=0 ; i < NCC ; i++) + tmp_termio.c_cc[i] = tty->termios.c_cc[i]; + for (i=0 ; i< (sizeof (*termio)) ; i++) + put_fs_byte( ((char *)&tmp_termio)[i] , i+(char *)termio ); + return 0; +} + +/* + * This only works as the 386 is low-byt-first + */ +static int set_termio(struct tty_struct * tty, struct termio * termio) +{ + int i; + struct termio tmp_termio; + + for (i=0 ; i< (sizeof (*termio)) ; i++) + ((char *)&tmp_termio)[i]=get_fs_byte(i+(char *)termio); + *(unsigned short *)&tty->termios.c_iflag = tmp_termio.c_iflag; + *(unsigned short *)&tty->termios.c_oflag = tmp_termio.c_oflag; + *(unsigned short *)&tty->termios.c_cflag = tmp_termio.c_cflag; + *(unsigned short *)&tty->termios.c_lflag = tmp_termio.c_lflag; + tty->termios.c_line = tmp_termio.c_line; + for(i=0 ; i < NCC ; i++) + tty->termios.c_cc[i] = tmp_termio.c_cc[i]; + change_speed(tty); + return 0; +} + +int tty_ioctl(int dev, int cmd, int arg) +{ + struct tty_struct * tty; + if (MAJOR(dev) == 5) { + dev=current->tty; + if (dev<0) + panic("tty_ioctl: dev<0"); + } else + dev=MINOR(dev); + tty = dev + tty_table; + switch (cmd) { + case TCGETS: + return get_termios(tty,(struct termios *) arg); + case TCSETSF: + flush(&tty->read_q); /* fallthrough */ + case TCSETSW: + wait_until_sent(tty); /* fallthrough */ + case TCSETS: + return set_termios(tty,(struct termios *) arg); + case TCGETA: + return get_termio(tty,(struct termio *) arg); + case TCSETAF: + flush(&tty->read_q); /* fallthrough */ + case TCSETAW: + wait_until_sent(tty); /* fallthrough */ + case TCSETA: + return set_termio(tty,(struct termio *) arg); + case TCSBRK: + if (!arg) { + wait_until_sent(tty); + send_break(tty); + } + return 0; + case TCXONC: + return -EINVAL; /* not implemented */ + case TCFLSH: + if (arg==0) + flush(&tty->read_q); + else if (arg==1) + flush(&tty->write_q); + else if (arg==2) { + flush(&tty->read_q); + flush(&tty->write_q); + } else + return -EINVAL; + return 0; + case TIOCEXCL: + return -EINVAL; /* not implemented */ + case TIOCNXCL: + return -EINVAL; /* not implemented */ + case TIOCSCTTY: + return -EINVAL; /* set controlling term NI */ + case TIOCGPGRP: + verify_area((void *) arg,4); + put_fs_long(tty->pgrp,(unsigned long *) arg); + return 0; + case TIOCSPGRP: + tty->pgrp=get_fs_long((unsigned long *) arg); + return 0; + case TIOCOUTQ: + verify_area((void *) arg,4); + put_fs_long(CHARS(tty->write_q),(unsigned long *) arg); + return 0; + case TIOCINQ: + verify_area((void *) arg,4); + put_fs_long(CHARS(tty->secondary), + (unsigned long *) arg); + return 0; + case TIOCSTI: + return -EINVAL; /* not implemented */ + case TIOCGWINSZ: + return -EINVAL; /* not implemented */ + case TIOCSWINSZ: + return -EINVAL; /* not implemented */ + case TIOCMGET: + return -EINVAL; /* not implemented */ + case TIOCMBIS: + return -EINVAL; /* not implemented */ + case TIOCMBIC: + return -EINVAL; /* not implemented */ + case TIOCMSET: + return -EINVAL; /* not implemented */ + case TIOCGSOFTCAR: + return -EINVAL; /* not implemented */ + case TIOCSSOFTCAR: + return -EINVAL; /* not implemented */ + default: + return -EINVAL; + } +} diff --git a/110_master/110/os/os/linux/kernel/chr_drv/tty_ioctl.o b/110_master/110/os/os/linux/kernel/chr_drv/tty_ioctl.o new file mode 100644 index 0000000000000000000000000000000000000000..6fcf766d95e129c53038533553e2124de8516b4b GIT binary patch literal 10648 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 literal 0 HcmV?d00001 diff --git a/110_master/110/os/os/linux/kernel/exec2.o b/110_master/110/os/os/linux/kernel/exec2.o new file mode 100644 index 0000000000000000000000000000000000000000..8c4add44fe837910ad6661ad07b87365c26ffc38 GIT binary patch literal 15272 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 brvwiOo)&ydkmor1sS%th*dxgOm-_z?t#1c? literal 0 HcmV?d00001 diff --git a/110_master/110/os/os/linux/kernel/execve2.c b/110_master/110/os/os/linux/kernel/execve2.c new file mode 100644 index 0000000..03c522f --- /dev/null +++ b/110_master/110/os/os/linux/kernel/execve2.c @@ -0,0 +1,359 @@ +/* + * linux/fs/exec.c + * + * (C) 1991 Linus Torvalds + */ + +/* + * #!-checking implemented by tytso. + */ + +/* + * Demand-loading implemented 01.12.91 - no need to read anything but + * the header into memory. The inode of the executable is put into + * "current->executable", and page faults do the actual loading. Clean. + * + * Once more I can proudly say that linux stood up to being changed: it + * was less than 2 hours work to get demand-loading completely implemented. + */ + +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +extern int sys_exit(int exit_code); +extern int sys_close(int fd); + +/* + * MAX_ARG_PAGES defines the number of pages allocated for arguments + * and envelope for the new program. 32 should suffice, this gives + * a maximum env+arg of 128kB ! + */ +#define MAX_ARG_PAGES 32 + +/* + * create_tables() parses the env- and arg-strings in new user + * memory and creates the pointer tables from them, and puts their + * addresses on the "stack", returning the new stack pointer value. + */ +static unsigned long * create_tables(char * p,int argc,int envc) +{ + unsigned long *argv,*envp; + unsigned long * mq; + + mq = (unsigned long *) (0xfffffffc & (unsigned long) p); + mq -= envc+1; + envp = mq; + mq -= argc+1; + argv = mq; + put_fs_long((unsigned long)envp,--mq); + put_fs_long((unsigned long)argv,--mq); + put_fs_long((unsigned long)argc,--mq); + while (argc-->0) { + put_fs_long((unsigned long) p,argv++); + while (get_fs_byte(p++)) /* nothing */ ; + } + put_fs_long(0,argv); + while (envc-->0) { + put_fs_long((unsigned long) p,envp++); + while (get_fs_byte(p++)) /* nothing */ ; + } + put_fs_long(0,envp); + return mq; +} + +/* + * count() counts the number of arguments/envelopes + */ +static int count(char ** argv) +{ + int i=0; + char ** tmp; + + if (tmp = argv) + while (get_fs_long((unsigned long *) (tmp++))) + i++; + + return i; +} + +/* + * 'copy_string()' copies argument/envelope strings from user + * memory to free pages in kernel mem. These are in a format ready + * to be put directly into the top of new user memory. + * + * Modified by TYT, 11/24/91 to add the from_kmem argument, which mqecifies + * whether the string and the string array are from user or kernel segments: + * + * from_kmem argv * argv ** + * 0 user mqace user mqace + * 1 kernel mqace user mqace + * 2 kernel mqace kernel mqace + * + * We do this by playing games with the fs segment register. Since it + * it is expensive to load a segment register, we try to avoid calling + * set_fs() unless we absolutely have to. + */ +static unsigned long copy_strings(int argc,char ** argv,unsigned long *page, + unsigned long p, int from_kmem) +{ + char *tmp, *pag; + int len, offset = 0; + unsigned long old_fs, new_fs; + + if (!p) + return 0; /* bullet-proofing */ + new_fs = get_ds(); + old_fs = get_fs(); + if (from_kmem==2) + set_fs(new_fs); + while (argc-- > 0) { + if (from_kmem == 1) + set_fs(new_fs); + if (!(tmp = (char *)get_fs_long(((unsigned long *)argv)+argc))) + panic("argc is wrong"); + if (from_kmem == 1) + set_fs(old_fs); + len=0; /* remember zero-padding */ + do { + len++; + } while (get_fs_byte(tmp++)); + if (p-len < 0) { /* this shouldn't happen - 128kB */ + set_fs(old_fs); + return 0; + } + while (len) { + --p; --tmp; --len; + if (--offset < 0) { + offset = p % PAGE_SIZE; + if (from_kmem==2) + set_fs(old_fs); + if (!(pag = (char *) page[p/PAGE_SIZE]) && + !(pag = (char *) (page[p/PAGE_SIZE] = + (unsigned long *) get_free_page()))) + return 0; + if (from_kmem==2) + set_fs(new_fs); + + } + *(pag + offset) = get_fs_byte(tmp); + } + } + if (from_kmem==2) + set_fs(old_fs); + return p; +} + +static unsigned long change_ldt(unsigned long text_size,unsigned long * page) +{ + unsigned long code_limit,data_limit,code_base,data_base; + int i; + + code_limit = text_size+PAGE_SIZE -1; + code_limit &= 0xFFFFF000; + data_limit = 0x4000000; + code_base = get_base(current->ldt[1]); + data_base = code_base; + set_base(current->ldt[1],code_base); + set_limit(current->ldt[1],code_limit); + set_base(current->ldt[2],data_base); + set_limit(current->ldt[2],data_limit); +/* make sure fs points to the NEW data segment */ + __asm__("pushl $0x17\n\tpop %%fs"::); + data_base += data_limit; + for (i=MAX_ARG_PAGES-1 ; i>=0 ; i--) { + data_base -= PAGE_SIZE; + if (page[i]) + put_page(page[i],data_base); + } + return data_limit; +} + +/* + * 'do_execve()' executes a new program. + */ +int do_execve2(unsigned long * eip,long tmp,char * filename, + char ** argv, char ** envp) +{ + struct m_inode * inode; + struct buffer_head * sp; + struct exec ex; + unsigned long page[MAX_ARG_PAGES]; + int i,argc,envc; + int e_uid, e_gid; + int retval; + unsigned long currentaddr; + int sh_bang = 0; + unsigned long p=PAGE_SIZE*MAX_ARG_PAGES-4; + + if ((0xffff & eip[1]) != 0x000f) + panic("execve called from supervisor mode"); + for (i=0 ; ii_mode)) { /* must be regular file */ + retval = -EACCES; + goto exec_error2; + } + i = inode->i_mode; + e_uid = (i & S_ISUID) ? inode->i_uid : current->euid; + e_gid = (i & S_ISGID) ? inode->i_gid : current->egid; + if (current->euid == inode->i_uid) + i >>= 6; + else if (current->egid == inode->i_gid) + i >>= 3; + if (!(i & 1) && + !((inode->i_mode & 0111) && suser())) { + retval = -ENOEXEC; + goto exec_error2; + } + if (!(sp = bread(inode->i_dev,inode->i_zone[0]))) { + retval = -EACCES; + goto exec_error2; + } + ex = *((struct exec *) sp->b_data); /* read exec-header */ + if ((sp->b_data[0] == '#') && (sp->b_data[1] == '!') && (!sh_bang)) { + /* + * This section does the #! interpretation. + * Sorta complicated, but hopefully it will work. -TYT + */ + + char buf[1023], *cp, *interp, *i_name, *i_arg; + unsigned long old_fs; + + strncpy(buf, sp->b_data+2, 1022); + brelse(sp); + iput(inode); + buf[1022] = '\0'; + if (cp = strchr(buf, '\n')) { + *cp = '\0'; + for (cp = buf; (*cp == ' ') || (*cp == '\t'); cp++); + } + if (!cp || *cp == '\0') { + retval = -ENOEXEC; /* No interpreter name found */ + goto exec_error1; + } + interp = i_name = cp; + i_arg = 0; + for ( ; *cp && (*cp != ' ') && (*cp != '\t'); cp++) { + if (*cp == '/') + i_name = cp+1; + } + if (*cp) { + *cp++ = '\0'; + i_arg = cp; + } + /* + * OK, we've parsed out the interpreter name and + * (optional) argument. + */ + if (sh_bang++ == 0) { + p = copy_strings(envc, envp, page, p, 0); + p = copy_strings(--argc, argv+1, page, p, 0); + } + /* + * mqlice in (1) the interpreter's name for argv[0] + * (2) (optional) argument to interpreter + * (3) filename of shell script + * + * This is done in reverse order, because of how the + * user environment and arguments are stored. + */ + p = copy_strings(1, &filename, page, p, 1); + argc++; + if (i_arg) { + p = copy_strings(1, &i_arg, page, p, 2); + argc++; + } + p = copy_strings(1, &i_name, page, p, 2); + argc++; + if (!p) { + retval = -ENOMEM; + goto exec_error1; + } + /* + * OK, now restart the process with the interpreter's inode. + */ + old_fs = get_fs(); + set_fs(get_ds()); + if (!(inode=namei(interp))) { /* get executables inode */ + set_fs(old_fs); + retval = -ENOENT; + goto exec_error1; + } + set_fs(old_fs); + goto restart_interp; + } + brelse(sp); + if (N_MAGIC(ex) != ZMAGIC || ex.a_trsize || ex.a_drsize || + ex.a_text+ex.a_data+ex.a_bss>0x3000000 || + inode->i_size < ex.a_text+ex.a_data+ex.a_syms+N_TXTOFF(ex)) { + retval = -ENOEXEC; + goto exec_error2; + } + if (N_TXTOFF(ex) != BLOCK_SIZE) { + printk("%s: N_TXTOFF != BLOCK_SIZE. See a.out.h.", filename); + retval = -ENOEXEC; + goto exec_error2; + } + if (!sh_bang) { + p = copy_strings(envc,envp,page,p,0); + p = copy_strings(argc,argv,page,p,0); + if (!p) { + retval = -ENOMEM; + goto exec_error2; + } + } +/* OK, This is the point of no return */ + if (current->executable) + iput(current->executable); + current->executable = inode; + for (i=0 ; i<32 ; i++) + current->sigaction[i].sa_handler = NULL; + for (i=0 ; iclose_on_exec>>i)&1) + sys_close(i); + current->close_on_exec = 0; + free_page_tables(get_base(current->ldt[1]),get_limit(0x0f)); + free_page_tables(get_base(current->ldt[2]),get_limit(0x17)); + if (last_task_used_math == current) + last_task_used_math = NULL; + current->used_math = 0; + p += change_ldt(ex.a_text,page)-MAX_ARG_PAGES*PAGE_SIZE; + p = (unsigned long) create_tables((char *)p,argc,envc); + current->brk = ex.a_bss + + (current->end_data = ex.a_data + + (current->end_code = ex.a_text)); + current->start_stack = p & 0xfffff000; + current->euid = e_uid; + current->egid = e_gid; + + //add brk 用于指明进程当前数据段(包括未初始化数据部分)末端位置,供内核为进程分配内存时指定分配开始位置。 + for (currentaddr=0; currentaddrbrk; currentaddr+=0x1000) + do_no_pagex(6, currentaddr+current->start_code);//error code=6表示执行一般代码,由写操作引起。 + + i = ex.a_text+ex.a_data; + while (i&0xfff) + put_fs_byte(0,(char *) (i++)); + eip[0] = ex.a_entry; /* eip, magic happens :-) */ + eip[3] = p; /* stack pointer */ + return 0; +exec_error2: + iput(inode); +exec_error1: + for (i=0 ; iU+r=6ZZRV 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 T7W}Coj*Hq)t>A3IUcvtWAfDs5 literal 0 HcmV?d00001 diff --git a/110_master/110/os/os/linux/kernel/exit.c b/110_master/110/os/os/linux/kernel/exit.c new file mode 100644 index 0000000..2406ebe --- /dev/null +++ b/110_master/110/os/os/linux/kernel/exit.c @@ -0,0 +1,197 @@ +/* + * linux/kernel/exit.c + * + * (C) 1991 Linus Torvalds + */ + +#include +#include +#include + +#include +#include +#include +#include + +int sys_pause(void); +int sys_close(int fd); + +void release(struct task_struct * p) +{ + int i; + + if (!p) + return; + for (i=1 ; i32) + return -EINVAL; + if (priv || (current->euid==p->euid) || suser()) + p->signal |= (1<<(sig-1)); + else + return -EPERM; + return 0; +} + +static void kill_session(void) +{ + struct task_struct **p = NR_TASKS + task; + + while (--p > &FIRST_TASK) { + if (*p && (*p)->session == current->session) + (*p)->signal |= 1<<(SIGHUP-1); + } +} + +/* + * XXX need to check permissions needed to send signals to process + * groups, etc. etc. kill() permissions semantics are tricky! + */ +int sys_kill(int pid,int sig) +{ + struct task_struct **p = NR_TASKS + task; + int err, retval = 0; + + if (!pid) while (--p > &FIRST_TASK) { + if (*p && (*p)->pgrp == current->pid) + if (err=send_sig(sig,*p,1)) + retval = err; + } else if (pid>0) while (--p > &FIRST_TASK) { + if (*p && (*p)->pid == pid) + if (err=send_sig(sig,*p,0)) + retval = err; + } else if (pid == -1) while (--p > &FIRST_TASK) + if (err = send_sig(sig,*p,0)) + retval = err; + else while (--p > &FIRST_TASK) + if (*p && (*p)->pgrp == -pid) + if (err = send_sig(sig,*p,0)) + retval = err; + return retval; +} + +static void tell_father(int pid) +{ + int i; + + if (pid) + for (i=0;ipid != pid) + continue; + task[i]->signal |= (1<<(SIGCHLD-1)); + return; + } +/* if we don't find any fathers, we just release ourselves */ +/* This is not really OK. Must change it to make father 1 */ + printk("BAD BAD - no father found\n\r"); + release(current); +} + +int do_exit(long code) +{ + int i; + + free_page_tables(get_base(current->ldt[1]),get_limit(0x0f)); + free_page_tables(get_base(current->ldt[2]),get_limit(0x17)); + for (i=0 ; ifather == current->pid) { + task[i]->father = 1; + if (task[i]->state == TASK_ZOMBIE) + /* assumption task[1] is always init */ + (void) send_sig(SIGCHLD, task[1], 1); + } + for (i=0 ; ifilp[i]) + sys_close(i); + iput(current->pwd); + current->pwd=NULL; + iput(current->root); + current->root=NULL; + iput(current->executable); + current->executable=NULL; + if (current->leader && current->tty >= 0) + tty_table[current->tty].pgrp = 0; + if (last_task_used_math == current) + last_task_used_math = NULL; + if (current->leader) + kill_session(); + current->state = TASK_ZOMBIE; + current->exit_code = code; + tell_father(current->father); + schedule(); + return (-1); /* just to suppress warnings */ +} + +int sys_exit(int error_code) +{ + return do_exit((error_code&0xff)<<8); +} + +int sys_waitpid(pid_t pid,unsigned long * stat_addr, int options) +{ + int flag, code; + struct task_struct ** p; + + verify_area(stat_addr,4); +repeat: + flag=0; + for(p = &LAST_TASK ; p > &FIRST_TASK ; --p) { + if (!*p || *p == current) + continue; + if ((*p)->father != current->pid) + continue; + if (pid>0) { + if ((*p)->pid != pid) + continue; + } else if (!pid) { + if ((*p)->pgrp != current->pgrp) + continue; + } else if (pid != -1) { + if ((*p)->pgrp != -pid) + continue; + } + switch ((*p)->state) { + case TASK_STOPPED: + if (!(options & WUNTRACED)) + continue; + put_fs_long(0x7f,stat_addr); + return (*p)->pid; + case TASK_ZOMBIE: + current->cutime += (*p)->utime; + current->cstime += (*p)->stime; + flag = (*p)->pid; + code = (*p)->exit_code; + release(*p); + put_fs_long(code,stat_addr); + return flag; + default: + flag=1; + continue; + } + } + if (flag) { + if (options & WNOHANG) + return 0; + current->state=TASK_INTERRUPTIBLE; + schedule(); + if (!(current->signal &= ~(1<<(SIGCHLD-1)))) + goto repeat; + else + return -EINTR; + } + return -ECHILD; +} + + diff --git a/110_master/110/os/os/linux/kernel/exit.o b/110_master/110/os/os/linux/kernel/exit.o new file mode 100644 index 0000000000000000000000000000000000000000..97c5057fd4da000378b2c23ca0dba2b274e9b855 GIT binary patch literal 11164 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 + +#include +#include +#include +#include + +extern void write_verify(unsigned long address); + +long last_pid=0; + +void verify_area(void * addr,int size) +{ + unsigned long start; + + start = (unsigned long) addr; + size += start & 0xfff; + start &= 0xfffff000; + start += get_base(current->ldt[2]); + while (size>0) { + size -= 4096; + write_verify(start); + start += 4096; + } +} + +int copy_mem(int nr,struct task_struct * p) +{ + unsigned long old_data_base,new_data_base,data_limit; + unsigned long old_code_base,new_code_base,code_limit; + + code_limit=get_limit(0x0f); + data_limit=get_limit(0x17); + old_code_base = get_base(current->ldt[1]); + old_data_base = get_base(current->ldt[2]); + if (old_data_base != old_code_base) + panic("We don't support separate I&D"); + if (data_limit < code_limit) + panic("Bad data_limit"); + new_data_base = new_code_base = nr * 0x4000000; + p->start_code = new_code_base; + set_base(p->ldt[1],new_code_base); + set_base(p->ldt[2],new_data_base); + if (copy_page_tables(old_data_base,new_data_base,data_limit)) { + free_page_tables(new_data_base,data_limit); + return -ENOMEM; + } + return 0; +} + +/* + * Ok, this is the main fork-routine. It copies the system process + * information (task[nr]) and sets up the necessary registers. It + * also copies the data segment in it's entirety. + */ +int copy_process(int nr,long ebp,long edi,long esi,long gs,long none, + long ebx,long ecx,long edx, + long fs,long es,long ds, + long eip,long cs,long eflags,long esp,long ss) +{ + struct task_struct *p; + int i; + struct file *f; + + p = (struct task_struct *) get_free_page(); + if (!p) + return -EAGAIN; + task[nr] = p; + __asm__ volatile ("cld"); /* by wyj */ + *p = *current; /* NOTE! this doesn't copy the supervisor stack */ + p->state = TASK_UNINTERRUPTIBLE; + p->pid = last_pid; + p->father = current->pid; + p->counter = p->priority; + p->signal = 0; + p->alarm = 0; + p->leader = 0; /* process leadership doesn't inherit */ + p->utime = p->stime = 0; + p->cutime = p->cstime = 0; + p->start_time = jiffies; + p->tss.back_link = 0; + p->tss.esp0 = PAGE_SIZE + (long) p; + p->tss.ss0 = 0x10; + p->tss.eip = eip; + p->tss.eflags = eflags; + p->tss.eax = 0; + p->tss.ecx = ecx; + p->tss.edx = edx; + p->tss.ebx = ebx; + p->tss.esp = esp; + p->tss.ebp = ebp; + p->tss.esi = esi; + p->tss.edi = edi; + p->tss.es = es & 0xffff; + p->tss.cs = cs & 0xffff; + p->tss.ss = ss & 0xffff; + p->tss.ds = ds & 0xffff; + p->tss.fs = fs & 0xffff; + p->tss.gs = gs & 0xffff; + p->tss.ldt = _LDT(nr); + p->tss.trace_bitmap = 0x80000000; + if (last_task_used_math == current) + __asm__("clts ; fnsave %0"::"m" (p->tss.i387)); + if (copy_mem(nr,p)) { + task[nr] = NULL; + free_page((long) p); + return -EAGAIN; + } + for (i=0; ifilp[i]) + f->f_count++; + if (current->pwd) + current->pwd->i_count++; + if (current->root) + current->root->i_count++; + if (current->executable) + current->executable->i_count++; + set_tss_desc(gdt+(nr<<1)+FIRST_TSS_ENTRY,&(p->tss)); + set_ldt_desc(gdt+(nr<<1)+FIRST_LDT_ENTRY,&(p->ldt)); + p->state = TASK_RUNNING; /* do this last, just in case */ + return last_pid; +} + +int find_empty_process(void) +{ + int i; + + repeat: + if ((++last_pid)<0) last_pid=1; + for(i=0 ; ipid == last_pid) goto repeat; + for(i=1 ; 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 iRJf6deFDP}8v5Y +#include +#include +#include + +#include +#include +#include +#include +#include + +struct linux_dirent { + long d_ino; + off_t d_off; + unsigned short d_reclen; + char d_name[14]; +}; + +int sys_getdents(unsigned int fd, struct linux_dirent *d, unsigned int count) +{ + struct file *f; + struct m_inode * m; + struct buffer_head * b; + struct dir_entry * dir; + int i,j,k,res; + struct linux_dirent usrd; + i=0; + res=0; + f=current->filp[fd]; + m=f->f_inode; + b=bread(m->i_dev,m->i_zone[0]); + dir=(struct dir_entry*)b->b_data; + while(dir[i].inode>0) + { + if(res+sizeof(struct linux_dirent)>count) + break; + usrd.d_ino=dir[i].inode; + usrd.d_off=0; + usrd.d_reclen=sizeof(struct linux_dirent); + for(j=0;j<14;j++) + usrd.d_name[j]=dir[i].name[j]; + for(k=0;kroot->i_dev; + inode=current->pwd; + inum=inode->i_num; + b=bread(dev,inode->i_zone[0]); + d=(struct dir_entry*) b->b_data; + i=0; + l=0; + while(inum!=1) + { + inode=iget(dev, d[1].inode); + b=bread(dev,inode->i_zone[0]); + d=(struct dir_entry*) b->b_data; + j=0; + while(d[j].inode!=inum) j++; + inum=inode->i_num; + path[i]=d[j].name; + i++; + } + while(i>0) + { + i--; + put_fs_byte('/',buf+l); + l++; + k=0; + while(path[i][k]!='\0') + { + put_fs_byte(path[i][k],buf+l); + l++; + if(l>=size) break; + k++; + } + if(l>=size) break; + } + return buf; +} + + + diff --git a/110_master/110/os/os/linux/kernel/getdents.o b/110_master/110/os/os/linux/kernel/getdents.o new file mode 100644 index 0000000000000000000000000000000000000000..8c229382a25f1271e059251c4723ef8bbad4cc77 GIT binary patch literal 7672 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 PP1RR4m`jAML+Aeit}rS> literal 0 HcmV?d00001 diff --git a/110_master/110/os/os/linux/kernel/math/Makefile b/110_master/110/os/os/linux/kernel/math/Makefile new file mode 100644 index 0000000..b35d488 --- /dev/null +++ b/110_master/110/os/os/linux/kernel/math/Makefile @@ -0,0 +1,43 @@ +# +# Makefile for the FREAX-kernel character device drivers. +# +# Note! Dependencies are done automagically by 'make dep', which also +# removes any old dependencies. DON'T put your own dependencies here +# unless it's something special (ie not a .c file). +# + +AR =ar +AS =as +LD =ld +LDFLAGS =-s -x +CC =gcc -march=i386 +CFLAGS =-w -g -fstrength-reduce -fomit-frame-pointer -mcld \ + -nostdinc -fno-stack-protector -I../../include +CPP =gcc -E -nostdinc -I../../include + +.c.s: + $(CC) $(CFLAGS) \ + -S -o $*.s $< +.s.o: + $(AS) -o $*.o $< +.c.o: + $(CC) $(CFLAGS) \ + -c -o $*.o $< + +OBJS = math_emulate.o + +math.a: $(OBJS) + $(AR) rcs math.a $(OBJS) + sync + +clean: + rm -f core *.o *.a tmp_make + for i in *.c;do rm -f `basename $$i .c`.s;done + +dep: + sed '/\#\#\# Dependencies/q' < Makefile > tmp_make + (for i in *.c;do echo -n `echo $$i | sed 's,\.c,\.s,'`" "; \ + $(CPP) -M $$i;done) >> tmp_make + cp tmp_make Makefile + +### Dependencies: diff --git a/110_master/110/os/os/linux/kernel/math/math.a b/110_master/110/os/os/linux/kernel/math/math.a new file mode 100644 index 0000000000000000000000000000000000000000..f92fb43a9c019f8e75bf744c65f88b59c8d4ba88 GIT binary patch literal 6628 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 + +#include +#include +#include + +void math_emulate(long edi, long esi, long ebp, long sys_call_ret, + long eax,long ebx,long ecx,long edx, + unsigned short fs,unsigned short es,unsigned short ds, + unsigned long eip,unsigned short cs,unsigned long eflags, + unsigned short ss, unsigned long esp) +{ + unsigned char first, second; + +/* 0x0007 means user code space */ + if (cs != 0x000F) { + printk("math_emulate: %04x:%08x\n\r",cs,eip); + panic("Math emulation needed in kernel"); + } + first = get_fs_byte((char *)((*&eip)++)); + second = get_fs_byte((char *)((*&eip)++)); + printk("%04x:%08x %02x %02x\n\r",cs,eip-2,first,second); + current->signal |= 1<<(SIGFPE-1); +} + +void math_error(void) +{ + __asm__("fnclex"); + if (last_task_used_math) + last_task_used_math->signal |= 1<<(SIGFPE-1); +} diff --git a/110_master/110/os/os/linux/kernel/math/math_emulate.o b/110_master/110/os/os/linux/kernel/math/math_emulate.o new file mode 100644 index 0000000000000000000000000000000000000000..8a98b22720edd26bc9b196e2d1b86549665ddef0 GIT binary patch literal 6464 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 + +/* + * This isn't the library routine, it is only used in the kernel. + * as such, we don't care about years<1970 etc, but assume everything + * is ok. Similarly, TZ etc is happily ignored. We just do everything + * as easily as possible. Let's find something public for the library + * routines (although I think minix times is public). + */ +/* + * PS. I hate whoever though up the year 1970 - couldn't they have gotten + * a leap-year instead? I also hate Gregorius, pope or no. I'm grumpy. + */ +#define MINUTE 60 +#define HOUR (60*MINUTE) +#define DAY (24*HOUR) +#define YEAR (365*DAY) + +/* interestingly, we assume leap-years */ +static int month[12] = { + 0, + DAY*(31), + DAY*(31+29), + DAY*(31+29+31), + DAY*(31+29+31+30), + DAY*(31+29+31+30+31), + DAY*(31+29+31+30+31+30), + DAY*(31+29+31+30+31+30+31), + DAY*(31+29+31+30+31+30+31+31), + DAY*(31+29+31+30+31+30+31+31+30), + DAY*(31+29+31+30+31+30+31+31+30+31), + DAY*(31+29+31+30+31+30+31+31+30+31+30) +}; + +long kernel_mktime(struct tm * tm) +{ + long res; + int year; + if (tm->tm_year < 70 ) tm->tm_year += 100; /* gohigh */ + year = tm->tm_year - 70; +/* magic offsets (y+1) needed to get leapyears right.*/ + res = YEAR*year + DAY*((year+1)/4); + res += month[tm->tm_mon]; +/* and (y+2) here. If it wasn't a leap-year, we have to adjust */ + if (tm->tm_mon>1 && ((year+2)%4)) + res -= DAY; + res += DAY*(tm->tm_mday-1); + res += HOUR*tm->tm_hour; + res += MINUTE*tm->tm_min; + res += tm->tm_sec; + return res; +} diff --git a/110_master/110/os/os/linux/kernel/mktime.o b/110_master/110/os/os/linux/kernel/mktime.o new file mode 100644 index 0000000000000000000000000000000000000000..6694bf8258168567f68b2aba8bfc5ed630e30698 GIT binary patch literal 2872 zcma)8U1%It6h3!mHraGH+f8=c=BL9R=z+QC zJLlZh2X+aMEv_t>trhe7 zs=+FMvsh7H_c`1WH#v6H&lF#_7Ezv9*R)o}g{=tMS}|I;&BYZj{7N|;Z9Xl?_laJb zy7!+sbi64(04lkZ^z#JEw@~X^<|*sGoj9@%qYI3-zKwt5w^gpqUj~T!PEd383^f<8 z5*2O|-T9N6-}eamWL(gJl4$n6A(|h2E>b)kOL|%2Nt}5PFW*T8(P1??!wQYF%COpD zFue+;jqZ;aTKk|*0Ft#II4RZEhrnBa!&WCpF}4Cntxo8-0mrQn^gX~ys}K5K;2vui za3An?3&%40fm0N+LM7Luwrebj!QH%qP@{PFZ$|B0mly;xE>pPX)Jg2cF5~jqj<1=E zhY-iO?9nD!cLZXD-J@6{INm?3=}2O4-(6lqCNC^>iQTb8#EkXFxcneQzY^j ztGFErVTL1-{gDF^k>ECTk{N?AnHY_52(>Xx)Mkr=y}s?i-pK?)jrF|qcrU!#Lu7`1 zFQbQ>HnKtNU{S?{b<<`}KFMAYAtn=WkM5+&M3&Rhc76;Lt)>d3#|T{J#~|E3A@0UH zd6kzHO|T+#TCCnYx$DpU%wJs-Bbgsx@RQRvR@s?bKYSJna`l3rj$BF>73&&%scXkDpCbUrK1xQ`%?p_ zW*V;7@Q;*vxFMzC3&SJ!(8!>#<*R`SFo|;~Nt_Rh{-|ZW&eP)8K+YOAIp2v`(i|5t zd6(__LdDC?kX`p`J}+uibIP{oob|{qJbHHN9lg{A-$Y1?s@gL!-S zBN1mE^5T3tFW>nM@!sQj^Q_aP`$J4UrLA^zH?rA;v#(!9l zgBc)OgxP>F5Bw(!k}2Q7b&W~#cYaM_$_cND?5(5uI+LR7MnXh#w zG`P#%nAqCq-~V;k_#GyCi}wmH8{YxJ+xEdL7= CPoF&i literal 0 HcmV?d00001 diff --git a/110_master/110/os/os/linux/kernel/panic.c b/110_master/110/os/os/linux/kernel/panic.c new file mode 100644 index 0000000..7d8a06b --- /dev/null +++ b/110_master/110/os/os/linux/kernel/panic.c @@ -0,0 +1,24 @@ +/* + * linux/kernel/panic.c + * + * (C) 1991 Linus Torvalds + */ + +/* + * This function is used through-out the kernel (includeinh mm and fs) + * to indicate a major problem. + */ +#include +#include + +void sys_sync(void); /* it's really int */ + +volatile void panic(const char * s) +{ + printk("Kernel panic: %s\n\r",s); + if (current == task[0]) + printk("In swapper task - not syncing\n\r"); + else + sys_sync(); + for(;;); +} diff --git a/110_master/110/os/os/linux/kernel/panic.o b/110_master/110/os/os/linux/kernel/panic.o new file mode 100644 index 0000000000000000000000000000000000000000..da42b57864ffc04172b2020b3f3f9096af53eb86 GIT binary patch literal 5424 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 D&gTd! literal 0 HcmV?d00001 diff --git a/110_master/110/os/os/linux/kernel/pipe2.c b/110_master/110/os/os/linux/kernel/pipe2.c new file mode 100644 index 0000000..8ee1c43 --- /dev/null +++ b/110_master/110/os/os/linux/kernel/pipe2.c @@ -0,0 +1,55 @@ +/* + * linux/fs/pipe.c + * + * (C) 1991 Linus Torvalds + */ + +#include + +#include +#include /* for get_free_page */ +#include + + +int sys_pipe2(unsigned long * fildes,int flag) +{ + struct m_inode * inode; + struct file * f[2]; + int fd[2]; + int i,j; + if(flag==0){ + j=0; + for(i=0;j<2 && if_count++; + if (j==1) + f[0]->f_count=0; + if (j<2) + return -1; + j=0; + for(i=0;j<2 && ifilp[i]) { + current->filp[ fd[j]=i ] = f[j]; + j++; + } + if (j==1) + current->filp[fd[0]]=NULL; + if (j<2) { + f[0]->f_count=f[1]->f_count=0; + return -1; + } + if (!(inode=get_pipe_inode())) { + current->filp[fd[0]] = + current->filp[fd[1]] = NULL; + f[0]->f_count = f[1]->f_count = 0; + return -1; + } + f[0]->f_inode = f[1]->f_inode = inode; + f[0]->f_pos = f[1]->f_pos = 0; + f[0]->f_mode = 1; /* read */ + f[1]->f_mode = 2; /* write */ + put_fs_long(fd[0],0+fildes); + put_fs_long(fd[1],1+fildes); + } + return 0; +} diff --git a/110_master/110/os/os/linux/kernel/pipe2.o b/110_master/110/os/os/linux/kernel/pipe2.o new file mode 100644 index 0000000000000000000000000000000000000000..1b0316d42205c62f784943d6b258ed5cf8d40171 GIT binary patch literal 6280 zcma)A3v3+K6@4>1`@GJ2*G}v>j^dJ~ILZ?2^(Q6?At7tWB+iE@1Va<@*^GB*?Tz=x z&TM{)plL`O*NTJ-rIdma1gZ)G(IP6*pF|RrNL4E#)QVO@6^aT9rL^LwR-)jZGxNsT zpjPdZX3n|y-Fx4C|Ji-u_N^NZww`-Fl9dQKe zJa^eRexCJ{BM-Ju@fkFd*~vj;2EGU$*B+L4fw`rKBN*S3T#I8I<>` z|0#pvr`)E|&hhhSL8pv|kVC@P#;3M+bWU!4qy?FPD;#;G{rEXrPqv&w7V$4-(tQ7O zUM8)6m=-ViCF3DDsjL{@ml}xeHVJ`gus-b7@CE* z_6J>v`2klW7J{?rM%@mL5d1TwfDz0U9ii)W-=b0rO~B0fDtI8q1qAEAyA|?fR(uX_ z)Ga|pa0%olqvu(0xdUw&y)T0b8Kp^|32Mme`Ch&p?~weI{{6oIZxD4f4N))Z4Mvz# zZ~Pn(PV_GeGCw^3gc3S*clmfVaXnhjWrW!e%}488g_!bhhe|VG4UG zY}X@i(8m=<^vID}VW%Fsb5_`+M=s3@`}N3f2H3|&GkVl;~W;jkWglY(^_KF9RPV{9k82-EX*J(|xrLXP)BcpdH7 zwvY#2h0hfo3+Fx9H?pAs0yo_S5)whKh*foaKVe(l;B{`2LcUF&qO~sH#Jg_)WxNf! zlX{apB#$GFy3qmf2Dy?pY4V7S(kAmU-cfk~f$OqtB_@-!8KZB99HZ|zd0bv3&#|pe z`6Mjs4v;6LM&AkY9{DcydB*RPuaXzYm&;G^t}BxFOP*16CGwl)1@bca3i+%CejoWt z5j+LwraFfsDL^cWmnrf?*RB<}p$!iwD4anzrayhrATu#G&S_t_#`OV};*tUCwTtOa^XQ*FE-T-~CkgLd> zpOCA`+rsI}av^UeZx35cd<}U_UWaz&TJnytWgZstHu8AbO8dMsY-N1j z6ShWu-XFGX#92rCRnUVc$=5)i6LNq&319F*@*(JjTu(Y2=5P&>ZbgDVW`#bNF8cJI)@(-T^S*F}k=C5h zn;BW3&bJ(^2LnF6KnrNg^6jz`xvxnFD@;b5LH|Sj5)3jJ{8=98i<}Mc6Ty06T zIUI;Ciq6&M$)*KpsY8Urw?T!YMbQwJUaJU1SBGy6Z)(OqY1RVKaG0V7QATF#R)x{Z zd~NAM>O(<6>-t6nB$+c`EM17*1oMy=islV&u%I6-QWFfHZP6NIh>e=IshP2xu1D-{ zxX(=>7dkIp$Q~ryzBlMLJ})@iijF(08KTOcVoO3>x6t?7)a-da>UqxZzs9r`qDq&Z z3$E6#Tet?@!B)ng;lUueZ@&ER4e~GW=;Hf$Yuab%559OY7lMl|k?779)A?$~>Nf3y zs1fZWc8yp=yYsnX^{^1OHCC{SPGX#a%DJ-Dmq;V3aE_EM8(L&!=f;X=9vn+y+%hv@ z$k0xYTZ(3B=q4R>I}o@*YktAd1G(7V7fzfBt<~dA_~_8&X1sMr9;%+Ho`HUszN~p; zZN-slXje6~CoEH_%2T zq%x*s3foL&^Cot=Q!&$4YBc8*%(BR(isB?5jg4IT;9qDpyL5m3B%Mq+nat1fWo=;*$}PS5lWdY6+M+mdKZiV=;bB zW?_=CP{~OVX5Oq6gvGC!tm-2=>-K;#{E;YSvnh@r43REwNkE2COWdr76x0}PX!$~6|b6u*<~@lwT!T~mScyGP*F%U2(gu9h(& zZl5q?X?CPs$(1TOeB|U(8S9|P=JHm`%Q2lV*;cAlOfhdHpHm(j6)r%%eFBgB3-Riu+jxSfc)V~+ipi;=wXqG znwbpNgFi6oakBzfx85BdEEeXDX(;1HW}B4VRaPyiy&}qEm9nsyw(FnAu7MwVo~t;V zXbg%Q(QDt|b{IBzE1`z5R)v{u@0leph=%JGw(?$3oho2E#aoV}(DzdAhOiYGdIK z>>fP+RVN0bp>OH~(S{R&_0eP?s7D(HE<{5E7o#{>684b-)(X(6csTB}ij_||)?r5^ z+!G)%ijRN?WIXYUw%B!h0D`s&F15%^nCiWfBhDfAK1s;$hQN$ij z;B@fzwC7`ur`&UZJ^KI3VwmyR#+B=qe!Oc>dDgKk!c*@u?-iOaL=to!9@_A@#eFLH zGmL}cVhxY%=j`{dGfC|RD8MnP({5sBEZGOYZuMNSOA1>J0{F30l z52*MCoQ7%?KHc#pyNh##h|xh6-;TeGYTMn9yOisT?XrLVxLDx652$z-@$?#nPfgU- z#w#Np<1ijvX5-xlP9OH0I^@Uaww5+LwN z=f>l>v(4Igui+3FfX**|JYV*)R&R(8XM8>J+JEmT*S0_z-^|K^=ZAjHNV1+Q@M;N& zngtAXz@6dRdd~FK5|}-uJYB%;ac%vzlNAsVf#pAYmd!&x+~_J_7U8;L*47VX~4s~uL#0oqbQoBdtPlyP9Ng@ALqP!WXVA|@cN^xX>ADjZU{Nuiq${P!w(RAE8k5ryuafZeo`pHz5W z;X4ZdqVOLI1I!%ym!uJ#g zFedbCQuq~x%M`9uIHZvO2+@9@LjGMy`J}=#3ZGZVKeSkXQK5nD;I^l*U13~dzrv)# ztqON4%qT1?Jf`rJ!bcRIRrtKZR}{Xc@O6c6DZHZaQ-vB19p)KPxKQB|g}n-g6h5Qy zoWkEK{G-AT71m>WGwv-4KUO%Sa1aZb^}|GrnWf~T3LjMZhn4)4!WR`T#vY*mGKEkJ T4KMCf#`~ed7*L1IJCpct-OJBB literal 0 HcmV?d00001 diff --git a/110_master/110/os/os/linux/kernel/printk.c b/110_master/110/os/os/linux/kernel/printk.c new file mode 100644 index 0000000..0daa097 --- /dev/null +++ b/110_master/110/os/os/linux/kernel/printk.c @@ -0,0 +1,41 @@ +/* + * linux/kernel/printk.c + * + * (C) 1991 Linus Torvalds + */ + +/* + * When in kernel-mode, we cannot use printf, as fs is liable to + * point to 'interesting' things. Make a printf with fs-saving, and + * all is well. + */ +#include +#include + +#include + +static char buf[1024]; + +extern int vsprintf(char * buf, const char * fmt, va_list args); + +int printk(const char *fmt, ...) +{ + va_list args; + int i; + + va_start(args, fmt); + i=vsprintf(buf,fmt,args); + va_end(args); + __asm__("push %%fs\n\t" + "push %%ds\n\t" + "pop %%fs\n\t" + "pushl %0\n\t" + "pushl $buf\n\t" + "pushl $0\n\t" + "call tty_write\n\t" + "addl $8,%%esp\n\t" + "popl %0\n\t" + "pop %%fs" + ::"r" (i):"ax","cx","dx"); + return i; +} diff --git a/110_master/110/os/os/linux/kernel/printk.o b/110_master/110/os/os/linux/kernel/printk.o new file mode 100644 index 0000000000000000000000000000000000000000..93ce6e40ca451b8b2b024367e2fd7f575b694368 GIT binary patch literal 2424 zcma)7&2Jk;6o2DgCr+F=bwa44L}e?vC4jtkz$&FcNl74zT1BEwQKbUW+Fsk+*lV-9 zPLry@Ap#ObAoTzO!66j~E?kfhSCAS$gv5Ou_hxtEEfNw>nt8wXJ@aOE z_N^B#y(okrMS?WyOGHgQw3H>Ar3WZWSGNC{eQz;e-d)Vk>@DU?d#m}G-PL>wvi^gf zXV2gNK0G{xoZEXPpBvjhF?RP#ll3=3%l1L)`q*8>=C%)Juisi90ly z>aykdDJiyw91=P9O5ADEu%2|>07X85BF&XXc={4!l&3=tH3#1S8mjc_B(nQ}NevS+ zX2q$@L|V&CXR=~^;Mj4be2}!vx%AWNhz0-DrLfy04cA?ur zdfS82aa)dS7wSE?8aN%-hsx~~{J^TN7rI_2u&Y7GqgKal7(Lf_8m?V4_zbZkpEj(u zmg5KHJGbm$t7}uS*=gHFw^s{_9lzk(H;c&L+bopKxw%5isuWA1qPT8*uH6dra=N4a zR-2X=NkmHv3+Ig4tCgM`^uoOr9`8wM?#;QfSt>sgY6;&}NaEII61P)gdPLWE&{P9z zJ`yH*3>Pw~?ZiT+l(?8lUAUK#--hXLwF9d{rXP4AZz|;3Eiec z$O^M5i?7IF5RtO2K#teF2H_ZVT$lH!>e|3629V~E?;3-Ml+A)1&)0;&c{txNhRXLk zFvsw|nRb!ymk`RCZ9HyAT=~6`G|KE@(H-d7eQUg`kCXV589b>lVJwlj!6Ly5PP@Nmnz+;^@S&-W3E%tEI~ z@kn{1j;@ME+C(083(}ch`{!E#R3zOA&vW cIpTsy{wm_%F-Lt_7ZcwB_FIU!0iJ;T4?BzyrvLx| literal 0 HcmV?d00001 diff --git a/110_master/110/os/os/linux/kernel/sched.c b/110_master/110/os/os/linux/kernel/sched.c new file mode 100644 index 0000000..15d839b --- /dev/null +++ b/110_master/110/os/os/linux/kernel/sched.c @@ -0,0 +1,412 @@ +/* + * linux/kernel/sched.c + * + * (C) 1991 Linus Torvalds + */ + +/* + * 'sched.c' is the main kernel file. It contains scheduling primitives + * (sleep_on, wakeup, schedule etc) as well as a number of simple system + * call functions (type getpid(), which just extracts a field from + * current-task + */ +#include +#include +#include +#include +#include +#include +#include + +#include + +#define _S(nr) (1<<((nr)-1)) +#define _BLOCKABLE (~(_S(SIGKILL) | _S(SIGSTOP))) + +void show_task(int nr,struct task_struct * p) +{ + int i,j = 4096-sizeof(struct task_struct); + + printk("%d: pid=%d, state=%d, ",nr,p->pid,p->state); + i=0; + while (i>2 ] ; + +struct { + long * a; + short b; + } stack_start = { & user_stack [PAGE_SIZE>>2] , 0x10 }; +/* + * 'math_state_restore()' saves the current math information in the + * old math state array, and gets the new ones from the current task + */ +void math_state_restore() +{ + if (last_task_used_math == current) + return; + __asm__("fwait"); + if (last_task_used_math) { + __asm__("fnsave %0"::"m" (last_task_used_math->tss.i387)); + } + last_task_used_math=current; + if (current->used_math) { + __asm__("frstor %0"::"m" (current->tss.i387)); + } else { + __asm__("fninit"::); + current->used_math=1; + } +} + +/* + * 'schedule()' is the scheduler function. This is GOOD CODE! There + * probably won't be any reason to change this, as it should work well + * in all circumstances (ie gives IO-bound processes good response etc). + * The one thing you might take a look at is the signal-handler code here. + * + * NOTE!! Task 0 is the 'idle' task, which gets called when no other + * tasks can run. It can not be killed, and it cannot sleep. The 'state' + * information in task[0] is never used. + */ +void schedule(void) +{ + int i,next,c; + struct task_struct ** p; + +/* check alarm, wake up any interruptible tasks that have got a signal */ + + for(p = &LAST_TASK ; p > &FIRST_TASK ; --p) + if (*p) { + if ((*p)->alarm && (*p)->alarm < jiffies) { + (*p)->signal |= (1<<(SIGALRM-1)); + (*p)->alarm = 0; + } + if (((*p)->signal & ~(_BLOCKABLE & (*p)->blocked)) && + (*p)->state==TASK_INTERRUPTIBLE) + (*p)->state=TASK_RUNNING; + } + +/* this is the scheduler proper: */ + + while (1) { + c = -1; + next = 0; + i = NR_TASKS; + p = &task[NR_TASKS]; + while (--i) { + if (!*--p) + continue; + if ((*p)->state == TASK_RUNNING && (*p)->counter > c) + c = (*p)->counter, next = i; + } + if (c) break; + for(p = &LAST_TASK ; p > &FIRST_TASK ; --p) + if (*p) + (*p)->counter = ((*p)->counter >> 1) + + (*p)->priority; + } + switch_to(next); +} + +int sys_pause(void) +{ + current->state = TASK_INTERRUPTIBLE; + schedule(); + return 0; +} + +void sleep_on(struct task_struct **p) +{ + struct task_struct *tmp; + + if (!p) + return; + if (current == &(init_task.task)) + panic("task[0] trying to sleep"); + tmp = *p; + *p = current; + current->state = TASK_UNINTERRUPTIBLE; + schedule(); + if (tmp) + tmp->state=0; +} + +void interruptible_sleep_on(struct task_struct **p) +{ + struct task_struct *tmp; + + if (!p) + return; + if (current == &(init_task.task)) + panic("task[0] trying to sleep"); + tmp=*p; + *p=current; +repeat: current->state = TASK_INTERRUPTIBLE; + schedule(); + if (*p && *p != current) { + (**p).state=0; + goto repeat; + } + *p=NULL; + if (tmp) + tmp->state=0; +} + +void wake_up(struct task_struct **p) +{ + if (p && *p) { + (**p).state=0; + *p=NULL; + } +} + +/* + * OK, here are some floppy things that shouldn't be in the kernel + * proper. They are here because the floppy needs a timer, and this + * was the easiest way of doing it. + */ +static struct task_struct * wait_motor[4] = {NULL,NULL,NULL,NULL}; +static int mon_timer[4]={0,0,0,0}; +static int moff_timer[4]={0,0,0,0}; +unsigned char current_DOR = 0x0C; + +int ticks_to_floppy_on(unsigned int nr) +{ + extern unsigned char selected; + unsigned char mask = 0x10 << nr; + + if (nr>3) + panic("floppy_on: nr>3"); + moff_timer[nr]=10000; /* 100 s = very big :-) */ + cli(); /* use floppy_off to turn it off */ + mask |= current_DOR; + if (!selected) { + mask &= 0xFC; + mask |= nr; + } + if (mask != current_DOR) { + outb(mask,FD_DOR); + if ((mask ^ current_DOR) & 0xf0) + mon_timer[nr] = HZ/2; + else if (mon_timer[nr] < 2) + mon_timer[nr] = 2; + current_DOR = mask; + } + sti(); + return mon_timer[nr]; +} + +void floppy_on(unsigned int nr) +{ + cli(); + while (ticks_to_floppy_on(nr)) + sleep_on(nr+wait_motor); + sti(); +} + +void floppy_off(unsigned int nr) +{ + moff_timer[nr]=3*HZ; +} + +void do_floppy_timer(void) +{ + int i; + unsigned char mask = 0x10; + + for (i=0 ; i<4 ; i++,mask <<= 1) { + if (!(mask & current_DOR)) + continue; + if (mon_timer[i]) { + if (!--mon_timer[i]) + wake_up(i+wait_motor); + } else if (!moff_timer[i]) { + current_DOR &= ~mask; + outb(current_DOR,FD_DOR); + } else + moff_timer[i]--; + } +} + +#define TIME_REQUESTS 64 + +static struct timer_list { + long jiffies; + void (*fn)(); + struct timer_list * next; +} timer_list[TIME_REQUESTS], * next_timer = NULL; + +void add_timer(long jiffies, void (*fn)(void)) +{ + struct timer_list * p; + + if (!fn) + return; + cli(); + if (jiffies <= 0) + (fn)(); + else { + for (p = timer_list ; p < timer_list + TIME_REQUESTS ; p++) + if (!p->fn) + break; + if (p >= timer_list + TIME_REQUESTS) + panic("No more time requests free"); + p->fn = fn; + p->jiffies = jiffies; + p->next = next_timer; + next_timer = p; + while (p->next && p->next->jiffies < p->jiffies) { + p->jiffies -= p->next->jiffies; + fn = p->fn; + p->fn = p->next->fn; + p->next->fn = fn; + jiffies = p->jiffies; + p->jiffies = p->next->jiffies; + p->next->jiffies = jiffies; + p = p->next; + } + } + sti(); +} + +void do_timer(long cpl) +{ + extern int beepcount; + extern void sysbeepstop(void); + + if (beepcount) + if (!--beepcount) + sysbeepstop(); + + if (cpl) + current->utime++; + else + current->stime++; + + if (next_timer) { + next_timer->jiffies--; + while (next_timer && next_timer->jiffies <= 0) { + void (*fn)(void); + + fn = next_timer->fn; + next_timer->fn = NULL; + next_timer = next_timer->next; + (fn)(); + } + } + if (current_DOR & 0xf0) + do_floppy_timer(); + if ((--current->counter)>0) return; + current->counter=0; + if (!cpl) return; + schedule(); +} + +int sys_alarm(long seconds) +{ + int old = current->alarm; + + if (old) + old = (old - jiffies) / HZ; + current->alarm = (seconds>0)?(jiffies+HZ*seconds):0; + return (old); +} + +int sys_getpid(void) +{ + return current->pid; +} + +int sys_getppid(void) +{ + return current->father; +} + +int sys_getuid(void) +{ + return current->uid; +} + +int sys_geteuid(void) +{ + return current->euid; +} + +int sys_getgid(void) +{ + return current->gid; +} + +int sys_getegid(void) +{ + return current->egid; +} + +int sys_nice(long increment) +{ + if (current->priority-increment>0) + current->priority -= increment; + return 0; +} + +void sched_init(void) +{ + int i; + struct desc_struct * p; + + if (sizeof(struct sigaction) != 16) + panic("Struct sigaction MUST be 16 bytes"); + set_tss_desc(gdt+FIRST_TSS_ENTRY,&(init_task.task.tss)); + set_ldt_desc(gdt+FIRST_LDT_ENTRY,&(init_task.task.ldt)); + p = gdt+2+FIRST_TSS_ENTRY; + for(i=1;ia=p->b=0; + p++; + p->a=p->b=0; + p++; + } +/* Clear NT, so that we won't have troubles with that later on */ + __asm__("pushfl ; andl $0xffffbfff,(%esp) ; popfl"); + ltr(0); + lldt(0); + outb_p(0x36,0x43); /* binary, mode 3, LSB/MSB, ch 0 */ + outb_p(LATCH & 0xff , 0x40); /* LSB */ + outb(LATCH >> 8 , 0x40); /* MSB */ + set_intr_gate(0x20,&timer_interrupt); + outb(inb_p(0x21)&~0x01,0x21); + set_system_gate(0x80,&system_call); +} diff --git a/110_master/110/os/os/linux/kernel/sched.o b/110_master/110/os/os/linux/kernel/sched.o new file mode 100644 index 0000000000000000000000000000000000000000..11112c0c588cd0587908cb992ab9c69f343c68e4 GIT binary patch literal 22936 zcmeHv3zSsVneINPP8VfW)7{Vwf;3VMjetORgRKGzG!Ic;N)Qd;qo}S&ciGidWj%N( zYGXsB)4|Y*i7_DoUo&QnI3{B<2*!XK@sTl@@kVEo$#oftx|(Z@aiURU-|yS!Kh?zv zGr4Qlx_8|*i?i(W{olX;{qKK2&OYb-b?~-JRxB|LLpg_`JZg|BwRpB&(yU>!8mX#P z_lapo7uSzkT&`5_;`-*^Dt+#nW-8UQroOyqalH?kCZKiHs%OQwKOGntK%H8Wero^{ zENU-;ms>_s+O_)$kL}Gk_C>Y*aQ;`&juKC`;%SuQsr#8}PuoG*4jbsA*V;kvI}Yc^ zlu%YB?Xl{05Nx`8YklqfTVJG?-Vv;GFHf_dDwzE%zNKY2325Qp9$kgFw0M8fvbQUW zuEt?B)Hd2jqyDO2{zlXIQC)5*#27@Ut3E}|cfNrW0;%dngq7PFs?B=4R=^p2%@Mwv zTsxZm)GZT5xds)7_pUDQdMVhms@zr{)ioKF7&!&KT~%-~ap1F020lDicMQHqi-qd` z$S63~SyOc<>#MA7TkESxD(_ft&r=P6^TiQYoVOMmtGG7$7wAg1%N>U?YE6!NuzHbO zEX;1rts{yQGf@M=$s9GX!kz_Hcnp(Kqw;3|QfH(bZwR|iDogLJo|j+#Q?C%8@j}lk z>!k2EJ^M}z;zp%WM_#vftqM|-WzlnF_E2^vKRV7edWR+h$$FoyE|`_x?q`Be>v2D- zuK>MV4zLc_8p3Q+=;{^PVs014p-_(1-GXv$iME=06*^aIuPO4LD)EQuu&ucCRNjxm z+N026{OzS|yDxjE3#$K83y7yQ4h-H{9g!Wu?5FY-c7S%P{m+w01g8vXYrUoN96*Z; zHqVO`l3jzcEpcS%=^&TS&LjW)M$fUGi|fa+H=d0gp0%Z69kq5$1FxE-)W`cEC?9OK zu>EjhXjim;+^2L_)XqY2e(e`=KKMQ^uy?iTOwh_79-jCf>LajWtO3W|2xj81e;gH< zbSkjgZ>uaZ;55+PeL(d|siB^Q+K>CWLW4(MH_NcMsUF!gsB>hj@Lzq>{Y>rCP-1t} z9h!#0$4JyXySToxip!Yp-+2_LeU!#SjSiN*^K}qZtCHvt{k#&oYZX^+RZoo$y`%t5 zhDhCE^)D484l0c5(6!1BkL`SFAGoSJrhBPnd-(e8UBHfcur=1ku2^*}T3?BYtMXLd zc?qtf?q_Ob-8U=5J`8>QSg+FC0%*2*;MhBVMnz|D=pPPcZEuT(IL!XaZjf^9Dzz<` zx9pomiA$m#)toD)7FTmKE@NGJ4KJA95v)Sqvx;|-+WX1-v)Y0;8Z_eTRa2hQCZe!# z*)=<5wl~Kqj7yr}^~udjJJFTVqENeeo9N5f7BNd_IwrO)?i7_@N@9qx4tO7`)fX)6 zMr+}+`_V!BBF12p>8@hnf+}C5%X@dP!a7{oqoIGe=+@Xe!oBP<+%4BaZ`HD%s{X0A z+`^ugYx!u4rQ6ZN)#B5`ggDCwjyd%Mb{)97^~gTjmRvS=Sa#d1tYsW6&fTqM|5;io z-gVrVQ0WDhefJ4_N3m~Pj0QI4DqnB=!qz(Fsh*b)jN8%wxewnt@^M+ub4NZJ2h}l} z+B+jE)Tmp>_pYd~LFwzJ@!YO*ed{*JdX8vM#&i8;dh_kMo%cibtoxZNdw=fLj~b5L zgknc-fn52Ihiw|~?ON#KOG@Ga7oB4sCR`Z#Z)hb){9LZ>ixK8(e&_(64NkI_?opbpBOr%uobZWu$ba}B}j z?0)^TgDiRXafLxRWZ~ql{ySF3O1S3w&~;DK_37jP=?GkViqI6VUYAC3Tj2>H*BzgGUA)%|Z#h8IS@GxGO@Qymkd zbAp*fbne9Hv|uhD&d0QbU+<#9$?14-VsuI{(jLy{g7IuD7EGjq9kFaGmZWW@!#`Bz z!?})Ynyw4xvs)6WwqQOT%q3&7jEX1Inaq|@IyEPl%Fa7aU7ikhrn9kNKG7KqW@9%N zV!6ESRDF!tkZHqV8IR*^Tvw*lFKmtK@#_+0GE3<*tt9|YSea!Ml&4iBOIg;CDM+W5 zjfC3tuEp8Qq$sofLwFjX#UEh-P#Ve>V(s{>vP3GcEOSVNO2hY4B)`iZM2RQ35!Eci zdp<%r;{}|a@K~2W1S|i=D7IFySozVJ?fR#W!*$D)FDCFOGeGTN+J=*3h7 zMp3?s`YJPUf)zf03rLL__$J9(_G^?GXrh@WwPt|7f!ic#mbYd*gw&gXx?;&>vmEoN ztaWrf%?#{ei6%{E06(S)X*L6`bgfHfnSnXQl8epq0v)X1j+!lIAjD2;vd|2~FeNrw zY?imt>>8RaF#}WRK$FYNzyQ0T$ucvrjt;J6I4jJ+ZiaIm$tp7tVI57@n1Kh1WUU$a zI%Cr%*P4N~#gYwX;C?!|eml-lvpk>QqO1)Zw|3NFNth)`jKL)Zuk)8Z<}hU^#JU> zZ0Jc;*Q?5>%snWbRd(Iq!?Ax2PGves<=+8)S%}uA|9rGvwt>xA{>Nz(rtI@y2R~)4 zy^zcOx8YnCp*++-g*MSgP+H-?0i7s|bKM2~J89F#y7m4MtlLg`vY(b^3AQ!Oe zUME%FrX?`)k47!;3bxs1}P%Dk|FxuP%VYo6kBIKks`7JO{gezwXSE%yjD4$E&^5iK`rR?*>6B%Vq zqg?KZN3b@gQ?ByF(`jWjP_BUteIw;j{tw~bYNGpE<)w;CNiUpgW%i;!uUO}CTkyX@ z!)972|LqtR>wLwkx%JrUDc(bzRQJ(CHMI3pWCl+<&CQq!@k()iS9Q@3u{VeDq zw@|(q`h>C;P;Nn8$O|bihF)2VC|>5_a4n{|0#PdK5{j!lQHV<@uJObnUP^JTrw!s| z6tDH@>v1XN4gM_7)-uXbe-lS+Ip?umd3go%`qe`_PI+4)^G}9)sKu*O-w!rBT2oaY zfl^f&=kI~8W(8ar7d!w>O$(NlaUr$J`)!=|LmHv)A(d*R&$#3TaNL88B@~pWRT-Ba zgJfZWF*eIAdkj-@<_SbtZupJB5X{CWXv+u~ELWrBDP@!!!=blEJqCp_)EEWgQ)f{( z9DZ15sP!tmj)}sJaTe?Cpy{3%ifU6?=(v#0K2@86%>BXav&JTrQETgyV{a(R?P?5v zr!^+h#S-o24!EK9B(YX!-_C|szKGK6wZ%C87;Lmpf%^L_+B3puSGmEivN@<@7nUCz zQHIEwu?VSy=4M~AZZF)-f=3M9t}^I2bi4FGaOkvTso>Aq#ICmymDv|%=h>t2y_}WZ zZ10z#BXwM3DyY2s_fT*%F!pSKQx3x2c8h9kz7y;odq|RMjLG@@TYe+;Rc-$*vH#nX z?7u7a6B_9Ld%L(e#x=3(6Tg8xSy%m$RDD9Ks`?ewzr+XwsK?PW_WYSvoT8WXw$`U6 z208l2xPb=$jvalOqS=>LW45v6Z9eWa>bk)*r0&~NSB+c1fZi)ZD14GL_AGKt-g8XG ze2q^3eFRKi(Iz>VaCSd*rb@T^k=^PhbQp?GOgL4~-9k92fsZMnjmr3@(F@V+i|_)O2r>8y-Ob^yR_5t~KQCADb*QViK935n=D0t< z5}Gm(hsMj!r49JeQt)5dmltitG}hoY^r%x~zG~#gW>gsabd?rZG+L}u zp;t$lhdYgzo6K<-*!!kOO}qwL)AtHgO$j_=nP;qoMN?Z*)PavgggWr~YKGpB7kHs5 zLsg|_Jjh1ovwx!4LdCoigoJ90PD|IQ88^VskZ`70 zZN_D&F(l7{k{a~$4=8tfGvn{L3KrcrSOv4BjLUeZkl;45)t~kjeUxkg=PsnNeO)MH zm@%=UI^d}oQ!&gK?ybU)b7r;SsR#t-1TG2~)z~kGDvyt3Y4t1&AHHY}1m>Xvni{D* z6?O@R+%T3_(|$;uT3X!*OP^R`shy!+mN_o*;^tJO%RmXmaw#uq5OioI8e9s;6(fvE zquD}b8Ct+~GD1xnjR&d`((v$6=vVcb48GV>&7f-xpNCgK^}d=fpoK{@s8T6Zr*561na zH|W_;5Y=Ub>8&n+=^Bnn9zW=3(&(kt#R!y|;FlWwVy(W^afumSPaJeTfAqzO;+&#! znX6Be&?iQLF<=yvrHewRNEd~kD}F(3zf+5`!Y><|R@#sgm2`M|sc}ge-X=SQZW=~{iQg! zpN59UL@JUjL}QJ~M5?eE;T09REx8h^R4&pUi#9~)u{{=!Hnb~v$ZyHSauCskU9Pop zs!*Csw57sH$k-a-&Q{`r)6sg)GUjeKr&V`1D$_ES;$(Wi6?{VKAYQ4+6 zn>^!}RUdDx>w9GHA6{sD%`-H(@cCDD+52AKa^La~D4XN)CSV!c)_XP|)MabEo{C>| z<7hmt-FpvukF&tH*Vp*vtHt`hb>^(751*2 zUsz|$+Uz^t*u;rLhT_OF~f;mUt$+Ucb;r%g)xLGdeRE&%Z1ml(o!;*Clt1hVEJIUug-7=8pC%FAixBoc z-`D7C+wZG>b?@=#srPJt7+`uI_Id)oc-_jDKHuE+1>Zd1_`ba}4jr;>Zi;K0-CoZb z5BsXuX@9;3Z{r~?q37#X&i!q{thamd9F5KKc#X3>YkBgv@w^;^F@gWRIsw7+KL~&D zEnhd`CiCKI{MXHTdwJr(n!W?<-#Cgy!&*fQz0hGvMQeqM`EGYM7}eeQHf9rYrP`}Ay!KrvS-;N4} zTr3*ugskGJP$r*Mso3Vcy7cm^f{TL94YL}WgVQ_1*+~1`#CfwWfE-CigVWoB)8pyR zM1Fca8}5uv&!mwOi)Eoqu))~$cp(+ZC(@}LRH^iI-M{IXY&su{AxJK9lOCFUOeNDu5;EZyheAme zxWYqr2(6g85C<9agYk!$<79_&8O(z!q_{7{qS6CBu4JLz5(1PxS?&e9>dSw(c zdYshdt3$Akgp$I1rD?eUHz)43QjwjmCiifx8oJLL3n zw^TXWb3MsyV=!_t5Y?JYM>=8%K9~`isdbFg>hZuvcQ}} z%_uWr^bnk*uR1ZaoPI2Ly*1>pdf^u(SfKi9lu6gI>4A`Is8tt?{Rtq+UY$20RV7m(yM*urldpH$MqKgpa%FL=w;f@$qCoGJF{a$IcH)LkJs&rC?BHopMU%O$!lJ%ebbM#g`h^u1 z-vL+P??wDE9l`@oE@}h*oQw!;>phPcOh@Q<#;rgnO#xB2$-K9dsnEW!vD$-2Cj>$rgZWAETgi(gUy^Wge@r z*dM0RoGbu+dxCac0=d9e>=Jd zpmW~79o+%woOf?W_fzPcH*ZJxI&{u^x1;+2I_IsMx{LAW!;_lxj;$6{_;#2JD$4Kh zEU2jZg0-Ncrn`)Dx6P=iS@3j4)q-a$$`>51@Gba>o=eq`+tP{K1~8wsvE7lfv1CJ@ zx6}qo`kvm3w9$~lt+oL-ar@S5*NL@<^zE8G{y#g$!3;yC@cyC?uKUu*ZI2c-=kNcJ}S{4>pK1#A=9tpuWPJA z3KrGXrO#&4HFhX5TP>mir6``lXlnqj-lCphDBV@Vx|YApVp z!|qeG+ljJLf3LwG$CLipZO0!I8;qd|e?0a>*oe1s=U^HCb_zOn6E0BdT*pYtXxAsQ zQ?wFxr3Ya}{P)m!#n$u37!BBC8S8tQ!zY7J!=J;?gWQ5YHbwh+~{YQlT02aTr>_^cD~Hp|!~DK6SWw z-o?3|orCr7a0rlmw~K$%#s9{|A9eA^UHlmr|Cx*bi;KVE;wN1Ek1mc$DjtmA@8Z=i zJ{H`$?+!<0{)+1ytUuGm=eqc1;LiP+^{;f5U+3cO;LiP@_E}dsp97rdAeMi@RnBJu z=U{yIxcGf8z8~DVzti6jUFC;e{COAWPfO0h_WsSq-*WNayZE16+$`C%=&#(x`OCa> zu$(_HI0yM;aOb&({W;H7J`db^7Gn7_aOata{A!nd$i>@T{6-hQ*~NFb_%0W}$HgCT zaejT^9PHl#7k}Et|H;LF0q#5_vVU*5%HMVIKe_mjk}Z|(*SL6{i#NFVMJ~?I5S)Yl z*134X#W%V54j2Ebi$CDvKXCDdwLV2VC6m+-On8@{uk+!NsS$ z_=PUM5S)8C)!ff7m+~FpoKOCO=p1Y>1kN(PZ?T*|;O*nh96ne-<+3jbCk(^=i=Tr~ zcK8<|bfLb@J?bkE_}t@^{|$s7I6FH`y+80h@O^krr48Hr5xDc7$9Rr`JMVbp{{rs3 z!;!xM?i}pT+u+W-9Lop5op(6$A-Lr}g!Z_Nu)S(<=Y5Xl=YTs0{WXF+?{zGn4eq?p zkuL^!-sQ;GfIIJSYoowlSDFE(W7 zg|yFNv^jn5vjIV2*rrOiFd@*$R%no)5 z&AC`17jCm>4P~5@bUYfimjbGutbj#ZHeJZrLyO{*7<0RJ2wOUfmrJrZNWA)rY9uC; ziB@fGUq!|7iz1aR%L18yTWxpQ7k>~yW;>O~3Zg&)4zXbUnZf2GGC-R$=`Z;lnQok1dmf-uM|4{g+!pm_Jr2QDd zCL;VZr)X?a>VF9TL~uQx^;mwF;G=?k#-yL02>y(Sczz}PEueWT@;$;mcm^`?S58EK zhXKtl{Gv||Khp#+q#pG)2#*o*mm;EG4#;}lZXCP1c`Eg#9An`ZFNt zHwf<#yjidtXx@%@W#RV{QU4*q{ep+3{3XFkue2w4zTi9}Y!(4c^#6L%rv!%~vBr;? z&Jqj?P84hanqN|C4mrm8a={Hm^dliy5ZorXOYm!g`vku$_!trW`U%k7sniSP@c%yr zKcF7-$cIDfM-s6vFA}~%_*UUN1@98PU+^CUpBDVN;2VN(3tC9_7I>EjUVW ztl)T}2l*V~mk2Hsyh3n|;5xzUiKus*@Vkh(uIiEAF}{rFUBL$8Zlxl^+XXv`eHa%U z#t8e_+8Aj+LmT*JiTOoil>I(ojJES?{Av{{WgwwkOT;NiM83A3c(#02iNrMXS4Pmz zNg8$bZ!*Ss`@>OVf}PVhP^m@1ZX)uA#B=anF>#XpTa7Up&*9`#@HsK@TzpGRM4t9q zA{yC1L_Ri3#OBvdMB+I~Y{GjCaRxpQA-Vcatc*1{IVg89%WB!Ss$NUr5V*ZKiF#p8$n1A9mn1AB6 zn1AARn1AB+n15mj^H1D>`6q@k|HM|zKQV&&Cq^;<#2DtE7{~k*+w9+}jCRaFc>?oK zyaDr1?7;jJlbC-Z66N}SlfwLyr!oJ;4F5F%(1ZCUZp3`!y^?&NgTujZwtqu0hRV9H z;(HzRKwKIcaS15H#QlX>iI2NPkEzk+7Qt$=A zUkJV-_^#k5f_mNdvs^m_!6$EL`7j!DGVnf;WrZ7lr>o@CniXtMK0nzAO46e!HFFM7Aru zMR2+3uNEE_o)o@G`0c`X3IB%h`-MLu{BhyW2>+SzUkiU%@ZUv$cEFBnE)nZ%DG_V- zdf_(^vG#5g-Ya~!@IAu6C;Um_PYXXL{I|l-EVtX4KrG-sA-tK0=lt2iFCk*nTqgW# zBA(Ya2u~6>E45AdE@F*RUlINt;*Gf93O`K5{{9o;FB7*SA1C|`Vz*Ln34dP@mw_@M zV`%jJ>HQk>7zF3<1+xTK2}T9G1n&}jSnwIa*96}a2p$uBQ}81}?#rzIzX9MEfYty2 literal 0 HcmV?d00001 diff --git a/110_master/110/os/os/linux/kernel/signal.c b/110_master/110/os/os/linux/kernel/signal.c new file mode 100644 index 0000000..8d5a65f --- /dev/null +++ b/110_master/110/os/os/linux/kernel/signal.c @@ -0,0 +1,129 @@ +/* + * linux/kernel/signal.c + * + * (C) 1991 Linus Torvalds + */ + +#include +#include +#include +#include +#include + +volatile void do_exit(int error_code); + +int sys_sgetmask() +{ + return current->blocked; +} + +int sys_ssetmask(int newmask) +{ + int old=current->blocked; + + current->blocked = newmask & ~(1<<(SIGKILL-1)); + return old; +} + +int sys_sigpending() +{ + return -ENOSYS; +} + +int sys_sigsuspend() +{ + return -ENOSYS; +} + +static inline void save_old(char * from,char * to) +{ + int i; + + verify_area(to, sizeof(struct sigaction)); + for (i=0 ; i< sizeof(struct sigaction) ; i++) { + put_fs_byte(*from,to); + from++; + to++; + } +} + +static inline void get_new(char * from,char * to) +{ + int i; + + for (i=0 ; i< sizeof(struct sigaction) ; i++) + *(to++) = get_fs_byte(from++); +} + +int sys_signal(int signum, long handler, long restorer) +{ + struct sigaction tmp; + + if (signum<1 || signum>32 || signum==SIGKILL) + return -1; + tmp.sa_handler = (void (*)(int)) handler; + tmp.sa_mask = 0; + tmp.sa_flags = SA_ONESHOT | SA_NOMASK; + tmp.sa_restorer = (void (*)(void)) restorer; + handler = (long) current->sigaction[signum-1].sa_handler; + current->sigaction[signum-1] = tmp; + return handler; +} + +int sys_sigaction(int signum, const struct sigaction * action, + struct sigaction * oldaction) +{ + struct sigaction tmp; + + if (signum<1 || signum>32 || signum==SIGKILL) + return -1; + tmp = current->sigaction[signum-1]; + get_new((char *) action, + (char *) (signum-1+current->sigaction)); + if (oldaction) + save_old((char *) &tmp,(char *) oldaction); + if (current->sigaction[signum-1].sa_flags & SA_NOMASK) + current->sigaction[signum-1].sa_mask = 0; + else + current->sigaction[signum-1].sa_mask |= (1<<(signum-1)); + return 0; +} + +void do_signal(long signr,long eax, long ebx, long ecx, long edx, + long fs, long es, long ds, + long eip, long cs, long eflags, + unsigned long * esp, long ss) +{ + unsigned long sa_handler; + long old_eip=eip; + struct sigaction * sa = current->sigaction + signr - 1; + int longs; + unsigned long * tmp_esp; + + sa_handler = (unsigned long) sa->sa_handler; + if (sa_handler==1) + return; + if (!sa_handler) { + if (signr==SIGCHLD) + return; + else + do_exit(1<<(signr-1)); + } + if (sa->sa_flags & SA_ONESHOT) + sa->sa_handler = NULL; + *(&eip) = sa_handler; + longs = (sa->sa_flags & SA_NOMASK)?7:8; + *(&esp) -= longs; + verify_area(esp,longs*4); + tmp_esp=esp; + put_fs_long((long) sa->sa_restorer,tmp_esp++); + put_fs_long(signr,tmp_esp++); + if (!(sa->sa_flags & SA_NOMASK)) + put_fs_long(current->blocked,tmp_esp++); + put_fs_long(eax,tmp_esp++); + put_fs_long(ecx,tmp_esp++); + put_fs_long(edx,tmp_esp++); + put_fs_long(eflags,tmp_esp++); + put_fs_long(old_eip,tmp_esp++); + current->blocked |= sa->sa_mask; +} diff --git a/110_master/110/os/os/linux/kernel/signal.o b/110_master/110/os/os/linux/kernel/signal.o new file mode 100644 index 0000000000000000000000000000000000000000..1970f39f72c6b0c63a277c6955a88089975ca4d3 GIT binary patch literal 8960 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 literal 0 HcmV?d00001 diff --git a/110_master/110/os/os/linux/kernel/sys.c b/110_master/110/os/os/linux/kernel/sys.c new file mode 100644 index 0000000..3069d63 --- /dev/null +++ b/110_master/110/os/os/linux/kernel/sys.c @@ -0,0 +1,299 @@ +/* + * linux/kernel/sys.c + * + * (C) 1991 Linus Torvalds + */ +#define SIGALRM 14 +#include +#include +#include +#include +#include +#include +#include + +int sys_ftime() +{ + return -ENOSYS; +} + +int sys_break() +{ + return -ENOSYS; +} + +int sys_ptrace() +{ + return -ENOSYS; +} + +int sys_stty() +{ + return -ENOSYS; +} + +int sys_gtty() +{ + return -ENOSYS; +} + +int sys_rename() +{ + return -ENOSYS; +} + +int sys_prof() +{ + return -ENOSYS; +} + +int sys_setregid(int rgid, int egid) +{ + if (rgid>0) { + if ((current->gid == rgid) || + suser()) + current->gid = rgid; + else + return(-EPERM); + } + if (egid>0) { + if ((current->gid == egid) || + (current->egid == egid) || + suser()) { + current->egid = egid; + current->sgid = egid; + } else + return(-EPERM); + } + return 0; +} + +int sys_setgid(int gid) +{ +/* return(sys_setregid(gid, gid)); */ + if (suser()) + current->gid = current->egid = current->sgid = gid; + else if ((gid == current->gid) || (gid == current->sgid)) + current->egid = gid; + else + return -EPERM; + return 0; +} + +int sys_acct() +{ + return -ENOSYS; +} + +int sys_phys() +{ + return -ENOSYS; +} + +int sys_lock() +{ + return -ENOSYS; +} + +int sys_mpx() +{ + return -ENOSYS; +} + +int sys_ulimit() +{ + return -ENOSYS; +} + +int sys_time(long * tloc) +{ + int i; + + i = CURRENT_TIME; + if (tloc) { + verify_area(tloc,4); + put_fs_long(i,(unsigned long *)tloc); + } + return i; +} + +/* + * Unprivileged users may change the real user id to the effective uid + * or vice versa. + */ +int sys_setreuid(int ruid, int euid) +{ + int old_ruid = current->uid; + + if (ruid>0) { + if ((current->euid==ruid) || + (old_ruid == ruid) || + suser()) + current->uid = ruid; + else + return(-EPERM); + } + if (euid>0) { + if ((old_ruid == euid) || + (current->euid == euid) || + suser()) { + current->euid = euid; + current->suid = euid; + } else { + current->uid = old_ruid; + return(-EPERM); + } + } + return 0; +} + +int sys_setuid(int uid) +{ +/* return(sys_setreuid(uid, uid)); */ + if (suser()) + current->uid = current->euid = current->suid = uid; + else if ((uid == current->uid) || (uid == current->suid)) + current->euid = uid; + else + return -EPERM; + return(0); +} + +int sys_stime(long * tptr) +{ + if (!suser()) + return -EPERM; + startup_time = get_fs_long((unsigned long *)tptr) - jiffies/HZ; + return 0; +} + +int sys_times(struct tms * tbuf) +{ + if (tbuf) { + verify_area(tbuf,sizeof *tbuf); + put_fs_long(current->utime,(unsigned long *)&tbuf->tms_utime); + put_fs_long(current->stime,(unsigned long *)&tbuf->tms_stime); + put_fs_long(current->cutime,(unsigned long *)&tbuf->tms_cutime); + put_fs_long(current->cstime,(unsigned long *)&tbuf->tms_cstime); + } + return jiffies; +} + +int sys_brk(unsigned long end_data_seg) +{ + if (end_data_seg >= current->end_code && + end_data_seg < current->start_stack - 16384) + current->brk = end_data_seg; + return current->brk; +} + +/* + * This needs some heave checking ... + * I just haven't get the stomach for it. I also don't fully + * understand sessions/pgrp etc. Let somebody who does explain it. + */ +int sys_setpgid(int pid, int pgid) +{ + int i; + + if (!pid) + pid = current->pid; + if (!pgid) + pgid = current->pid; + for (i=0 ; ipid==pid) { + if (task[i]->leader) + return -EPERM; + if (task[i]->session != current->session) + return -EPERM; + task[i]->pgrp = pgid; + return 0; + } + return -ESRCH; +} + +int sys_getpgrp(void) +{ + return current->pgrp; +} + +int sys_setsid(void) +{ + if (current->leader && !suser()) + return -EPERM; + current->leader = 1; + current->session = current->pgrp = current->pid; + current->tty = -1; + return current->pgrp; +} + +int sys_getgroups() +{ + return -ENOSYS; +} + +int sys_setgroups() +{ + return -ENOSYS; +} + +int sys_uname(struct utsname * name) +{ + static struct utsname thisname = { + "linux .0","nodename","release ","version ","machine " + }; + int i; + + if (!name) return -ERROR; + verify_area(name,sizeof *name); + for(i=0;iumask; + + current->umask = mask & 0777; + return (old); +} + +int sys_sleep(unsigned int seconds) +{ + sys_signal(SIGALRM,SIG_IGN,NULL); + sys_alarm(seconds); + sys_pause(); + return 0; +} diff --git a/110_master/110/os/os/linux/kernel/sys.o b/110_master/110/os/os/linux/kernel/sys.o new file mode 100644 index 0000000000000000000000000000000000000000..dfa95feba02b68d81a619cb10b80b86298586b60 GIT binary patch literal 13576 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 G{Qm&3UrH7L literal 0 HcmV?d00001 diff --git a/110_master/110/os/os/linux/kernel/system_call.o b/110_master/110/os/os/linux/kernel/system_call.o new file mode 100644 index 0000000000000000000000000000000000000000..7f18738326d585dc583de8d6575122ff94f92c89 GIT binary patch literal 2640 zcma)8U1%It6h523R*BhEqxGlS6(hzr#w1#;R>d@%)WS+PS(0vBb(rkTcGv9gEHigw z76g$rL=6eS2kC5D&aNT z&pG$pvp0A0(ok$T6bg}VA!?+$B8oP+GY>k@Mcb*FR&3aMdMR@RgIE57NH5L&dE$ki z?`R1xkB%f(+cCcQ-Qp*!JDFUH|H3{=yJMD<#Lw`1W6Ho|LPHL2}dgLHld90DK2HgfO3kZGE=TMQ?!)n8$@Q&cBYl-Qr{LL2sdMGZl`CdHi|6hJPBp*;GUoR8S{8Aa^rA{Gn1fBmgq;6nXgU9D&~pAapm`0~s`gtxbudI{f%W(heGJW4 zrE4KN590T;9lzf9&@t~Yu>J}9H`f{a2+{B0-O@aU=rKvRf@_k#1$p zrGdPhe-!$(w4R@fhq#Yj8Zspf3gVuK_Lp z@$&wztDOyZzc&Q*-hkd0(3CiQNEv)87NwzqBn=(JGl(aeq~Qb&B`Avb;W!NfhGPSV z5_BXM9ZJL*5(%<|Ds)O2rGn5+Dwn|$DpP})+o?K&PYw_8d<86Q43lQ z&Y*eKnq*Ap)RPtyQ@4a+VzOW=R@oAIUP-CBoJA9=#siKbc%?GBR?6w1LP?uOzCJ01 z5l5sAbCN_hubWDii!@6`;Y{e$dTL6SXg_5%$tRsNip8=tP*hFSqUWR`O`po9bfsVj zMV(T!IduXxrHrC!q;$(NOa<#1*s5PH8dMNU0VCdC6nvyOq-2_UL6G2vXolkTFRzM> zm%^b=xBVuOJDV@%_$PQin@(qSi-VobGVyj;WBruQ7BofA7e!g|YUFC`0c^nsR8^%INwj0>+0P-^81ALHiAJNl{58+;8d>HwFAzaK$jE@kVV?+_3Gaf)b R&U-J>2aNX<{m9r$^f#OT6iNU9 literal 0 HcmV?d00001 diff --git a/110_master/110/os/os/linux/kernel/system_call.s b/110_master/110/os/os/linux/kernel/system_call.s new file mode 100644 index 0000000..7872a77 --- /dev/null +++ b/110_master/110/os/os/linux/kernel/system_call.s @@ -0,0 +1,298 @@ +/* + * linux/kernel/system_call.s + * + * (C) 1991 Linus Torvalds + */ + +/* + * system_call.s contains the system-call low-level handling routines. + * This also contains the timer-interrupt handler, as some of the code is + * the same. The hd- and flopppy-interrupts are also here. + * + * NOTE: This code handles signal-recognition, which happens every time + * after a timer-interrupt and after each system call. Ordinary interrupts + * don't handle signal-recognition, as that would clutter them up totally + * unnecessarily. + * + * Stack layout in 'ret_from_system_call': + * + * 0(%esp) - %eax + * 4(%esp) - %ebx + * 8(%esp) - %ecx + * C(%esp) - %edx + * 10(%esp) - %fs + * 14(%esp) - %es + * 18(%esp) - %ds + * 1C(%esp) - %eip + * 20(%esp) - %cs + * 24(%esp) - %eflags + * 28(%esp) - %oldesp + * 2C(%esp) - %oldss + */ + +SIG_CHLD = 17 + +EAX = 0x00 +EBX = 0x04 +ECX = 0x08 +EDX = 0x0C +FS = 0x10 +ES = 0x14 +DS = 0x18 +EIP = 0x1C +CS = 0x20 +EFLAGS = 0x24 +OLDESP = 0x28 +OLDSS = 0x2C + +state = 0 # these are offsets into the task-struct. +counter = 4 +priority = 8 +signal = 12 +sigaction = 16 # MUST be 16 (=len of sigaction) +blocked = (33*16) + +# offsets within sigaction +sa_handler = 0 +sa_mask = 4 +sa_flags = 8 +sa_restorer = 12 + +nr_system_calls = 92 /* 72 */ + +/* + * Ok, I get parallel printer interrupts while using the floppy for some + * strange reason. Urgel. Now I just ignore them. + */ +.globl system_call,sys_fork,timer_interrupt,sys_execve,sys_execve2 +.globl hd_interrupt,floppy_interrupt,parallel_interrupt +.globl device_not_available, coprocessor_error + +.align 4 +bad_sys_call: + movl $-1,%eax + iret +.align 4 +reschedule: + pushl $ret_from_sys_call + jmp schedule +.align 4 +system_call: + cmpl $nr_system_calls-1,%eax + ja bad_sys_call + push %ds + push %es + push %fs + pushl %edx + pushl %ecx # push %ebx,%ecx,%edx as parameters + pushl %ebx # to the system call + movl $0x10,%edx # set up ds,es to kernel space + mov %dx,%ds + mov %dx,%es + movl $0x17,%edx # fs points to local data space + mov %dx,%fs + + pushl %eax #by wyj + call print_nr + popl %eax + + call sys_call_table(,%eax,4) + pushl %eax + movl current,%eax + cmpl $0,state(%eax) # state + jne reschedule + cmpl $0,counter(%eax) # counter + je reschedule +ret_from_sys_call: + movl current,%eax # task[0] cannot have signals + cmpl task,%eax + je 3f + cmpw $0x0f,CS(%esp) # was old code segment supervisor ? + jne 3f + cmpw $0x17,OLDSS(%esp) # was stack segment = 0x17 ? + jne 3f + movl signal(%eax),%ebx + movl blocked(%eax),%ecx + notl %ecx + andl %ebx,%ecx + bsfl %ecx,%ecx + je 3f + btrl %ecx,%ebx + movl %ebx,signal(%eax) + incl %ecx + pushl %ecx + call do_signal + popl %eax +3: popl %eax + popl %ebx + popl %ecx + popl %edx + pop %fs + pop %es + pop %ds + iret + +.align 4 +coprocessor_error: + push %ds + push %es + push %fs + pushl %edx + pushl %ecx + pushl %ebx + pushl %eax + movl $0x10,%eax + mov %ax,%ds + mov %ax,%es + movl $0x17,%eax + mov %ax,%fs + pushl $ret_from_sys_call + jmp math_error + +.align 2 +device_not_available: + push %ds + push %es + push %fs + pushl %edx + pushl %ecx + pushl %ebx + pushl %eax + movl $0x10,%eax + mov %ax,%ds + mov %ax,%es + movl $0x17,%eax + mov %ax,%fs + pushl $ret_from_sys_call + clts # clear TS so that we can use math + movl %cr0,%eax + testl $0x4,%eax # EM (math emulation bit) + je math_state_restore + pushl %ebp + pushl %esi + pushl %edi + call math_emulate + popl %edi + popl %esi + popl %ebp + ret + +.align 4 +timer_interrupt: + push %ds # save ds,es and put kernel data space + push %es # into them. %fs is used by _system_call + push %fs + pushl %edx # we save %eax,%ecx,%edx as gcc doesn't + pushl %ecx # save those across function calls. %ebx + pushl %ebx # is saved as we use that in ret_sys_call + pushl %eax + movl $0x10,%eax + mov %ax,%ds + mov %ax,%es + movl $0x17,%eax + mov %ax,%fs + incl jiffies + movb $0x20,%al # EOI to interrupt controller #1 + outb %al,$0x20 + movl CS(%esp),%eax + andl $3,%eax # %eax is CPL (0 or 3, 0=supervisor) + pushl %eax + call do_timer # 'do_timer(long CPL)' does everything from + addl $4,%esp # task switching to accounting ... + jmp ret_from_sys_call + +.align 4 +sys_execve: + lea EIP(%esp),%eax + pushl %eax + call do_execve + addl $4,%esp + ret + +.align 4 +sys_execve2: + lea EIP(%esp),%eax + pushl %eax + call do_execve2 + addl $4,%esp + ret + +.align 4 +sys_fork: + call find_empty_process + testl %eax,%eax + js 1f + push %gs + pushl %esi + pushl %edi + pushl %ebp + pushl %eax + call copy_process + addl $20,%esp +1: ret + +hd_interrupt: + pushl %eax + pushl %ecx + pushl %edx + push %ds + push %es + push %fs + movl $0x10,%eax + mov %ax,%ds + mov %ax,%es + movl $0x17,%eax + mov %ax,%fs + movb $0x20,%al + outb %al,$0xA0 # EOI to interrupt controller #1 + jmp 1f # give port chance to breathe +1: jmp 1f +1: xorl %edx,%edx + xchgl do_hd,%edx + testl %edx,%edx + jne 1f + movl $unexpected_hd_interrupt,%edx +1: outb %al,$0x20 + call *%edx # "interesting" way of handling intr. + pop %fs + pop %es + pop %ds + popl %edx + popl %ecx + popl %eax + iret + +floppy_interrupt: + pushl %eax + pushl %ecx + pushl %edx + push %ds + push %es + push %fs + movl $0x10,%eax + mov %ax,%ds + mov %ax,%es + movl $0x17,%eax + mov %ax,%fs + movb $0x20,%al + outb %al,$0x20 # EOI to interrupt controller #1 + xorl %eax,%eax + xchgl do_floppy,%eax + testl %eax,%eax + jne 1f + movl $unexpected_floppy_interrupt,%eax +1: call *%eax # "interesting" way of handling intr. + pop %fs + pop %es + pop %ds + popl %edx + popl %ecx + popl %eax + iret + +parallel_interrupt: + pushl %eax + movb $0x20,%al + outb %al,$0x20 + popl %eax + iret diff --git a/110_master/110/os/os/linux/kernel/traps.c b/110_master/110/os/os/linux/kernel/traps.c new file mode 100644 index 0000000..f9bd8f1 --- /dev/null +++ b/110_master/110/os/os/linux/kernel/traps.c @@ -0,0 +1,208 @@ +/* + * linux/kernel/traps.c + * + * (C) 1991 Linus Torvalds + */ + +/* + * 'Traps.c' handles hardware traps and faults after we have saved some + * state in 'asm.s'. Currently mostly a debugging-aid, will be extended + * to mainly kill the offending process (probably by giving it a signal, + * but possibly by killing it outright if necessary). + */ +#include + +#include +#include +#include +#include +#include +#include + +#define get_seg_byte(seg,addr) ({ \ +register char __res; \ +__asm__("push %%fs;mov %%ax,%%fs;movb %%fs:%2,%%al;pop %%fs" \ + :"=a" (__res):"0" (seg),"m" (*(addr))); \ +__res;}) + +#define get_seg_long(seg,addr) ({ \ +register unsigned long __res; \ +__asm__("push %%fs;mov %%ax,%%fs;movl %%fs:%2,%%eax;pop %%fs" \ + :"=a" (__res):"0" (seg),"m" (*(addr))); \ +__res;}) + +#define _fs() ({ \ +register unsigned short __res; \ +__asm__("mov %%fs,%%ax":"=a" (__res):); \ +__res;}) + +int do_exit(long code); + +void page_exception(void); + +void divide_error(void); +void debug(void); +void nmi(void); +void int3(void); +void overflow(void); +void bounds(void); +void invalid_op(void); +void device_not_available(void); +void double_fault(void); +void coprocessor_segment_overrun(void); +void invalid_TSS(void); +void segment_not_present(void); +void stack_segment(void); +void general_protection(void); +void page_fault(void); +void coprocessor_error(void); +void reserved(void); +void parallel_interrupt(void); +void irq13(void); + +static void die(char * str,long esp_ptr,long nr) +{ + long * esp = (long *) esp_ptr; + int i; + + printk("%s: %04x\n\r",str,nr&0xffff); + printk("EIP:\t%04x:%p\nEFLAGS:\t%p\nESP:\t%04x:%p\n", + esp[1],esp[0],esp[2],esp[4],esp[3]); + printk("fs: %04x\n",_fs()); + printk("base: %p, limit: %p\n",get_base(current->ldt[1]),get_limit(0x17)); + if (esp[4] == 0x17) { + printk("Stack: "); + for (i=0;i<4;i++) + printk("%p ",get_seg_long(0x17,i+(long *)esp[3])); + printk("\n"); + } + str(i); + printk("Pid: %d, process nr: %d\n\r",current->pid,0xffff & i); + for(i=0;i<10;i++) + printk("%02x ",0xff & get_seg_byte(esp[1],(i+(char *)esp[0]))); + printk("\n\r"); + do_exit(11); /* play segment exception */ +} + +void do_double_fault(long esp, long error_code) +{ + die("double fault",esp,error_code); +} + +void do_general_protection(long esp, long error_code) +{ + die("general protection",esp,error_code); +} + +void do_divide_error(long esp, long error_code) +{ + die("divide error",esp,error_code); +} + +void do_int3(long * esp, long error_code, + long fs,long es,long ds, + long ebp,long esi,long edi, + long edx,long ecx,long ebx,long eax) +{ + int tr; + + __asm__("str %%ax":"=a" (tr):"0" (0)); + printk("eax\t\tebx\t\tecx\t\tedx\n\r%8x\t%8x\t%8x\t%8x\n\r", + eax,ebx,ecx,edx); + printk("esi\t\tedi\t\tebp\t\tesp\n\r%8x\t%8x\t%8x\t%8x\n\r", + esi,edi,ebp,(long) esp); + printk("\n\rds\tes\tfs\ttr\n\r%4x\t%4x\t%4x\t%4x\n\r", + ds,es,fs,tr); + printk("EIP: %8x CS: %4x EFLAGS: %8x\n\r",esp[0],esp[1],esp[2]); +} + +void do_nmi(long esp, long error_code) +{ + die("nmi",esp,error_code); +} + +void do_debug(long esp, long error_code) +{ + die("debug",esp,error_code); +} + +void do_overflow(long esp, long error_code) +{ + die("overflow",esp,error_code); +} + +void do_bounds(long esp, long error_code) +{ + die("bounds",esp,error_code); +} + +void do_invalid_op(long esp, long error_code) +{ + die("invalid operand",esp,error_code); +} + +void do_device_not_available(long esp, long error_code) +{ + die("device not available",esp,error_code); +} + +void do_coprocessor_segment_overrun(long esp, long error_code) +{ + die("coprocessor segment overrun",esp,error_code); +} + +void do_invalid_TSS(long esp,long error_code) +{ + die("invalid TSS",esp,error_code); +} + +void do_segment_not_present(long esp,long error_code) +{ + die("segment not present",esp,error_code); +} + +void do_stack_segment(long esp,long error_code) +{ + die("stack segment",esp,error_code); +} + +void do_coprocessor_error(long esp, long error_code) +{ + if (last_task_used_math != current) + return; + die("coprocessor error",esp,error_code); +} + +void do_reserved(long esp, long error_code) +{ + die("reserved (15,17-47) error",esp,error_code); +} + +void trap_init(void) +{ + int i; + + set_trap_gate(0,÷_error); + set_trap_gate(1,&debug); + set_trap_gate(2,&nmi); + set_system_gate(3,&int3); /* int3-5 can be called from all */ + set_system_gate(4,&overflow); + set_system_gate(5,&bounds); + set_trap_gate(6,&invalid_op); + set_trap_gate(7,&device_not_available); + set_trap_gate(8,&double_fault); + set_trap_gate(9,&coprocessor_segment_overrun); + set_trap_gate(10,&invalid_TSS); + set_trap_gate(11,&segment_not_present); + set_trap_gate(12,&stack_segment); + set_trap_gate(13,&general_protection); + set_trap_gate(14,&page_fault); + set_trap_gate(15,&reserved); + set_trap_gate(16,&coprocessor_error); + for (i=17;i<48;i++) + set_trap_gate(i,&reserved); + set_trap_gate(45,&irq13); + outb_p(inb_p(0x21)&0xfb,0x21); + outb(inb_p(0xA1)&0xdf,0xA1); + set_trap_gate(39,¶llel_interrupt); +} diff --git a/110_master/110/os/os/linux/kernel/traps.o b/110_master/110/os/os/linux/kernel/traps.o new file mode 100644 index 0000000000000000000000000000000000000000..51de46fe88ac98ea479385c2c283bf030d1f46cd GIT binary patch literal 12972 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 +#include + +/* we use this so that we can do without the ctype library */ +#define is_digit(c) ((c) >= '0' && (c) <= '9') + +static int skip_atoi(const char **s) +{ + int i=0; + + while (is_digit(**s)) + i = i*10 + *((*s)++) - '0'; + return i; +} + +#define ZEROPAD 1 /* pad with zero */ +#define SIGN 2 /* unsigned/signed long */ +#define PLUS 4 /* show plus */ +#define SPACE 8 /* space if plus */ +#define LEFT 16 /* left justified */ +#define SPECIAL 32 /* 0x */ +#define SMALL 64 /* use 'abcdef' instead of 'ABCDEF' */ + +#define do_div(n,base) ({ \ +int __res; \ +__asm__("divl %4":"=a" (n),"=d" (__res):"0" (n),"1" (0),"r" (base)); \ +__res; }) + +static char * number(char * str, int num, int base, int size, int precision + ,int type) +{ + char c,sign,tmp[36]; + const char *digits="0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"; + int i; + + if (type&SMALL) digits="0123456789abcdefghijklmnopqrstuvwxyz"; + if (type&LEFT) type &= ~ZEROPAD; + if (base<2 || base>36) + return 0; + c = (type & ZEROPAD) ? '0' : ' ' ; + if (type&SIGN && num<0) { + sign='-'; + num = -num; + } else + sign=(type&PLUS) ? '+' : ((type&SPACE) ? ' ' : 0); + if (sign) size--; + if (type&SPECIAL) + if (base==16) size -= 2; + else if (base==8) size--; + i=0; + if (num==0) + tmp[i++]='0'; + else while (num!=0) + tmp[i++]=digits[do_div(num,base)]; + if (i>precision) precision=i; + size -= precision; + if (!(type&(ZEROPAD+LEFT))) + while(size-->0) + *str++ = ' '; + if (sign) + *str++ = sign; + if (type&SPECIAL) + if (base==8) + *str++ = '0'; + else if (base==16) { + *str++ = '0'; + *str++ = digits[33]; + } + if (!(type&LEFT)) + while(size-->0) + *str++ = c; + while(i0) + *str++ = tmp[i]; + while(size-->0) + *str++ = ' '; + return str; +} + +int vsprintf(char *buf, const char *fmt, va_list args) +{ + int len; + int i; + char * str; + char *s; + int *ip; + + int flags; /* flags to number() */ + + int field_width; /* width of output field */ + int precision; /* min. # of digits for integers; max + number of chars for from string */ + int qualifier; /* 'h', 'l', or 'L' for integer fields */ + + for (str=buf ; *fmt ; ++fmt) { + if (*fmt != '%') { + *str++ = *fmt; + continue; + } + + /* process flags */ + flags = 0; + repeat: + ++fmt; /* this also skips first '%' */ + switch (*fmt) { + case '-': flags |= LEFT; goto repeat; + case '+': flags |= PLUS; goto repeat; + case ' ': flags |= SPACE; goto repeat; + case '#': flags |= SPECIAL; goto repeat; + case '0': flags |= ZEROPAD; goto repeat; + } + + /* get field width */ + field_width = -1; + if (is_digit(*fmt)) + field_width = skip_atoi(&fmt); + else if (*fmt == '*') { + /* it's the next argument */ + field_width = va_arg(args, int); + if (field_width < 0) { + field_width = -field_width; + flags |= LEFT; + } + } + + /* get the precision */ + precision = -1; + if (*fmt == '.') { + ++fmt; + if (is_digit(*fmt)) + precision = skip_atoi(&fmt); + else if (*fmt == '*') { + /* it's the next argument */ + precision = va_arg(args, int); + } + if (precision < 0) + precision = 0; + } + + /* get the conversion qualifier */ + qualifier = -1; + if (*fmt == 'h' || *fmt == 'l' || *fmt == 'L') { + qualifier = *fmt; + ++fmt; + } + + switch (*fmt) { + case 'c': + if (!(flags & LEFT)) + while (--field_width > 0) + *str++ = ' '; + *str++ = (unsigned char) va_arg(args, int); + while (--field_width > 0) + *str++ = ' '; + break; + + case 's': + s = va_arg(args, char *); + len = strlen(s); + if (precision < 0) + precision = len; + else if (len > precision) + len = precision; + + if (!(flags & LEFT)) + while (len < field_width--) + *str++ = ' '; + for (i = 0; i < len; ++i) + *str++ = *s++; + while (len < field_width--) + *str++ = ' '; + break; + + case 'o': + str = number(str, va_arg(args, unsigned long), 8, + field_width, precision, flags); + break; + + case 'p': + if (field_width == -1) { + field_width = 8; + flags |= ZEROPAD; + } + str = number(str, + (unsigned long) va_arg(args, void *), 16, + field_width, precision, flags); + break; + + case 'x': + flags |= SMALL; + case 'X': + str = number(str, va_arg(args, unsigned long), 16, + field_width, precision, flags); + break; + + case 'd': + case 'i': + flags |= SIGN; + case 'u': + str = number(str, va_arg(args, unsigned long), 10, + field_width, precision, flags); + break; + + case 'n': + ip = va_arg(args, int *); + *ip = (str - buf); + break; + + default: + if (*fmt != '%') + *str++ = '%'; + if (*fmt) + *str++ = *fmt; + else + --fmt; + break; + } + } + *str = '\0'; + return str-buf; +} diff --git a/110_master/110/os/os/linux/kernel/vsprintf.o b/110_master/110/os/os/linux/kernel/vsprintf.o new file mode 100644 index 0000000000000000000000000000000000000000..5acfe6576413e77d5a31e400e048fdd1e4ad4bf8 GIT binary patch literal 6156 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 tmp_make + (for i in *.c;do echo -n `echo $$i | sed 's,\.c,\.s,'`" "; \ + $(CPP) -M $$i;done) >> tmp_make + cp tmp_make Makefile + +### Dependencies: +_exit.s _exit.o : _exit.c ../include/unistd.h ../include/sys/stat.h \ + ../include/sys/types.h ../include/sys/times.h ../include/sys/utsname.h \ + ../include/utime.h +close.s close.o : close.c ../include/unistd.h ../include/sys/stat.h \ + ../include/sys/types.h ../include/sys/times.h ../include/sys/utsname.h \ + ../include/utime.h +ctype.s ctype.o : ctype.c ../include/ctype.h +dup.s dup.o : dup.c ../include/unistd.h ../include/sys/stat.h \ + ../include/sys/types.h ../include/sys/times.h ../include/sys/utsname.h \ + ../include/utime.h +errno.s errno.o : errno.c +execve.s execve.o : execve.c ../include/unistd.h ../include/sys/stat.h \ + ../include/sys/types.h ../include/sys/times.h ../include/sys/utsname.h \ + ../include/utime.h +malloc.s malloc.o : malloc.c ../include/linux/kernel.h ../include/linux/mm.h \ + ../include/asm/system.h +open.s open.o : open.c ../include/unistd.h ../include/sys/stat.h \ + ../include/sys/types.h ../include/sys/times.h ../include/sys/utsname.h \ + ../include/utime.h ../include/stdarg.h +setsid.s setsid.o : setsid.c ../include/unistd.h ../include/sys/stat.h \ + ../include/sys/types.h ../include/sys/times.h ../include/sys/utsname.h \ + ../include/utime.h +string.s string.o : string.c ../include/string.h +wait.s wait.o : wait.c ../include/unistd.h ../include/sys/stat.h \ + ../include/sys/types.h ../include/sys/times.h ../include/sys/utsname.h \ + ../include/utime.h ../include/sys/wait.h +write.s write.o : write.c ../include/unistd.h ../include/sys/stat.h \ + ../include/sys/types.h ../include/sys/times.h ../include/sys/utsname.h \ + ../include/utime.h diff --git a/110_master/110/os/os/linux/lib/_exit.c b/110_master/110/os/os/linux/lib/_exit.c new file mode 100644 index 0000000..c0c9d69 --- /dev/null +++ b/110_master/110/os/os/linux/lib/_exit.c @@ -0,0 +1,13 @@ +/* + * linux/lib/_exit.c + * + * (C) 1991 Linus Torvalds + */ + +#define __LIBRARY__ +#include + +volatile void _exit(int exit_code) +{ + __asm__("int $0x80"::"a" (__NR_exit),"b" (exit_code)); +} diff --git a/110_master/110/os/os/linux/lib/_exit.o b/110_master/110/os/os/linux/lib/_exit.o new file mode 100644 index 0000000000000000000000000000000000000000..3941812ad719da7d5634486aad433784a57edec3 GIT binary patch literal 1988 zcma)7&2QX96n|syCQCNmHVKGEsgNTTHI&$!&;^y!@|8dZRFNoDJ)kP}?oM_sVmq?E zkXDEfaRG7a0dYa%(m#PiCAd{W;($1C;)3`WICFsCZ|vDPCwS7#`@N5O@6Gef_>%M($X_*O_t=8yz_t_U%h*__2qBBeEQzQ98$yB8|pT=TEY|HgW{fgP@@SOk zp~szD|9qTgg?G%<9jCGGCX->&P4n)4luQo&jbL-r-w*rUUa7#`mprX^MhW6-e{YfuiYQHTsFKvr zi*WG1e~_hx9u#SIRPkUOX0o3qBU3xKx;sdRT8v(R4?8>tL4GGL!ajJBm3(Yb zp$`iQhG7v((9d%TGQA%Rb$>G2jgq|-CWFI%Khq!7tzi}>BYkWETVfX=z666bjx|13 zkf0+0x?Fas45P=prmL*@{}GQmZw~JPiFc}gzGx$@Vh~qXPqwM7k@Y(V9gg>Z`fb3+ zu3;F)`;ed_Yg>o>h*g5G&x#y^FJSO9a4_Fx47&zUe!zH}pdxGAfow5N^AJ3OimdHT z$o0JUk(Yg8UchPI5ZJB(lywNt6I5hvw;mBuSRaYp=A?WX2k}qvMT`>|%*(zrXFc8- + +_syscall1(int,close,int,fd) diff --git a/110_master/110/os/os/linux/lib/close.o b/110_master/110/os/os/linux/lib/close.o new file mode 100644 index 0000000000000000000000000000000000000000..4c8ffdcb6a0e11b2f875544cd6eeed6da4ac0498 GIT binary patch literal 2220 zcma)7&2Jl35TCcZ{%D*UCn*psNEj&LRZn__k zRskwSNL1;iLMTG&t^5tB2X5tr1P6LSfbZlOU5Oi0BtH^R%Q`q60KTZ*JeO-73Pc^VZ`0)jQu`xq51GdV6benl_6& zQ18{4|M}BR9&_sfX#3mRySG0Fve-nHcpqGR2i9Z^dLa{JSS8jBtFRx!vKSn3dP1dlSouK?5;Njp zb*^Go7pgO2wpe=K9C55}R*zI(tUOsiGsnTl=XX!m#T<$i$Skwx z%$zY#RBTZen8DHn9;?4pM{T(rNZk?EbPHIQ^P}gW3Gr8TKe*f@?2K@nrXO^MY1bp_ z48z!SIy@o`{5a`4gKYN-2HVVi;x)8V6wBzLW%PbG3docOvEL88Zi8Dp41>N@WGadW zVU#rXL^KEC$ZG~^H))1(bLa=@roHT}tk^@h-E3tB@HTl-6ohp8?D@u8qvfnRt%f~v zqt4){e|YuzhTU)2y>R3wb}w>Ap1l#Gycfaf2T1DKy)@_~ei+0s1)&`$Zs&r%5rv7@ zNy3QM*CQ{+D%IRO12-BkKlU$s$)ydCq?JyutsQABoo}Z>l4dippG_rN`FN$}EVmA2 zR&LP&W*~9-9Eq*6SeUk~&(LPxApV%-#+;~@w~e*x{Kabd#On1Ka?Kmcfja{#u_SgNO7s4fVx807s5At3&a)Ulrnj66F(F0I}oK83z zdDuKBKzAH;JnL3A#v8254rg=!Km2h7@tNl%&BSLt|7X8$@tga5a0GubC?`ar0{=edQK6(u2;e5NSDAK-V;Qaiik^Bm5Jih`yJ-_47^%$tQ zS8#k-QKWt6fVIx94*?piDAK;O!1=n@P`3sf*X8x;x;U_V^6etQd$4KJ`CJ(C`EDQy z=iz))_;kLD(0L56o9PdLyHd*-`}o^ZQperFE5PW(aGtl*a04l8l++;-&&yR`axF+?TChhfvC^J%PQ-fq!v544@--dB-vz5-*eJ|R>7 + +char _ctmp; +unsigned char _ctype[] = {0x00, /* EOF */ +_C,_C,_C,_C,_C,_C,_C,_C, /* 0-7 */ +_C,_C|_S,_C|_S,_C|_S,_C|_S,_C|_S,_C,_C, /* 8-15 */ +_C,_C,_C,_C,_C,_C,_C,_C, /* 16-23 */ +_C,_C,_C,_C,_C,_C,_C,_C, /* 24-31 */ +_S|_SP,_P,_P,_P,_P,_P,_P,_P, /* 32-39 */ +_P,_P,_P,_P,_P,_P,_P,_P, /* 40-47 */ +_D,_D,_D,_D,_D,_D,_D,_D, /* 48-55 */ +_D,_D,_P,_P,_P,_P,_P,_P, /* 56-63 */ +_P,_U|_X,_U|_X,_U|_X,_U|_X,_U|_X,_U|_X,_U, /* 64-71 */ +_U,_U,_U,_U,_U,_U,_U,_U, /* 72-79 */ +_U,_U,_U,_U,_U,_U,_U,_U, /* 80-87 */ +_U,_U,_U,_P,_P,_P,_P,_P, /* 88-95 */ +_P,_L|_X,_L|_X,_L|_X,_L|_X,_L|_X,_L|_X,_L, /* 96-103 */ +_L,_L,_L,_L,_L,_L,_L,_L, /* 104-111 */ +_L,_L,_L,_L,_L,_L,_L,_L, /* 112-119 */ +_L,_L,_L,_P,_P,_P,_P,_C, /* 120-127 */ +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 128-143 */ +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 144-159 */ +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 160-175 */ +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 176-191 */ +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 192-207 */ +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 208-223 */ +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 224-239 */ +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}; /* 240-255 */ + diff --git a/110_master/110/os/os/linux/lib/ctype.o b/110_master/110/os/os/linux/lib/ctype.o new file mode 100644 index 0000000000000000000000000000000000000000..acd65e6a3869dcf4ecb16245dcd9f21e6856c20c GIT binary patch literal 1908 zcmcgtOK;Oa5Z;Yl`bZlRr97$%luE4#2s;S`RJF8FBB+9@9*}xLf?_*PViDVs<3Ni9 z`~q(L0B%U!xbSDVaN!4lxFJ-&+4Ux_=z$X>&CcuFnf2_$Z|?2f=bSS|oM~)qG4@WA zk-89NmS=McD&>@-GLbUI@_qg|=_5+~TY|8Lzeob^3d)>76rVc2n*VRvD5;CGI)4bs z*HdfA+<;+%H5$-ZU7u_~(fO1CG4YX{GZ#n|eV*7M$MlntL+7VH!C<_=S8~OymRro_ z&oP$ayjkQ$?>nnU-72u4kLY+Y6cVm^}~9P?}_=LdCEQ&ajIZ zIscWL!zfMy_MbB+KJ2@uBcPRT=)09**orIRzzEzIm7W(24~(i=s~J7Zu2iK1qs@lF z!0QBVtK@X8Xq0B)y>uxf+jnBW&$f5>N{v$8Ts7+@!?z-*yWw45y;(9kC8HhsUTm}@ z%Xf`_=moJG!RZC4=^E`};KW`S4B!evV-Q=;Gov4cvFpTPMA@l`D9yGTjkQvF&mIQx zP}VZ84TV*EU8|eb`eo_G77Y&l*s>wxNXo9#V)r0sX3L5#X4-=RGb6WWwp@GI+4q8W zh>*}N+m77l>8KT1LC3`e382+09l4q5gud?v$Q@wuCK@6?Ml}52hDF*q@TmkY@9220 zy2nciF1gC=4%sRQy#yw@1g86>a9b%1#g$o2>EtI|o0NnU?kenQ<%FD_Wb7#<&Zszu zbZw~KEwGvcm3@G*NlHR0whLS76#52(j<+HedjLneZVz>-4%LM!YLopKtmZ&vzhRU~ zNl3*!*rd~U6RqGbeU_>iDMlP8QsKS;cSRuNpm47eoC?XiudMN!3UH~tpeW(qj$xy< zQ(k$!WpEw`;w#kC;8`&BIS;0ur1Sj*?ks$YD9=fh_Ur8XQ5tjnZ$bIfD + +_syscall1(int,dup,int,fd) diff --git a/110_master/110/os/os/linux/lib/dup.o b/110_master/110/os/os/linux/lib/dup.o new file mode 100644 index 0000000000000000000000000000000000000000..a354c34721c94522d7e1f903b03506ad1aee4c85 GIT binary patch literal 2196 zcma)7O>7%g5T3WY{%M>VCkBxyNEj)F1iI^lS`ZaVQ&Ol3s7QryfJ3yl*Y>LRZn{5^ zR^dkqNL1;iLMTGw)-xwAy`pjf353*3kG+>e3zay4RK9upUc5QMNbk*jGxKKV&D;0( z)7Rd5T?j#%1er8OM8BDtr6t({JxWvb&d%?(8;elvzB@m2<<>8sT{%5JxwAb#Nn6ET zh<9r||8@I1uetFMwDV)_gPUIgS*#*UtYa33F+I%~^kT-yuu3c$R^bOQ(<=BuLWWVQ zvr?45m$uT+5*2TOS>1G##KbX(OdLmiyNkKd>ngo*jf&r~e&Q%*<61(cw^{gAE)rAX zNVQ%ut8>*UF%+1&Wh7&*dsUU3{LpR zR$ge>{f6BOM}A`WB6sB3n<27#5tM#_pq|}JgHGayK@3$8+HvA`F4&ttjFN=@;%U*J6(<7;-Giz(d8w>00G)U5{6#My9qUBGPTh3BzG1C&h z;f%!P^CY&*Vs6s1zC>&JPijCc+Ww}{{Q92_2@MmhvV(Bph(-6fb;eJgZj3hI}_#1HXhrGYrmiHBs?oUvPt`Wq5QPz&+JvwaKH9%l%F;~fUvUf zmDR`aYmEFpuIBdf2yA*EQ;_vH0FjOYTxUTM*T=+M=VW{jAM8DFyt%~x501xu=bZU? zckmr>4oy0q#+v8#7TtfS^~?|c2^r@zFy`!IGUXSS$MRpcuQ26_?nA8SlO2;ulVbqM zB>aGKWD<99OeQ*@Gw|J=Mz<A6zzyJk0W040f&c&j literal 0 HcmV?d00001 diff --git a/110_master/110/os/os/linux/lib/errno.c b/110_master/110/os/os/linux/lib/errno.c new file mode 100644 index 0000000..50aca2e --- /dev/null +++ b/110_master/110/os/os/linux/lib/errno.c @@ -0,0 +1,7 @@ +/* + * linux/lib/errno.c + * + * (C) 1991 Linus Torvalds + */ + +int errno; diff --git a/110_master/110/os/os/linux/lib/errno.o b/110_master/110/os/os/linux/lib/errno.o new file mode 100644 index 0000000000000000000000000000000000000000..2b68237de5d516e34b24195231b0aca298879d71 GIT binary patch literal 1472 zcma)6OK;Oa5T1=w3Ydmg1wmB_8L5aA;Z4#;RaIVx3Mvrltw)6HWYZdIyK>f04m|FN zQzg#)0?zylPW%tJawy;IdK)8wV5HfZ`R3c5eT@C~{^JKi2y!CGqe(;*G;F4COq*tD zhF0J=P23c#u;RT5?9d1qnU)x*JchjHRFY|6bK+WS-uGIIt=UUNjXrs;4gZ$^aQ@yx z<1%g4zI(q1Z~h2j6(cu&0sWJ$A$%|qR4VNU>bGy@>F%Qa;Q7` zILy?`&VG`WhhbOtdf|Q)ce)n97~6@owY?K;27S3M`$3pS#bEDFvbw$&gu6jF%F{%L zqasRGc#z{XssNZ|SX70hG8^b5&&GhVJRIw2@H{*ya;*kBFDBdC+T7d-+BC)B- zS4tE0-t_vi+h4XQksQBDbri$u!rDFOX?3Vc4kI0rjK^b=h1!=x6_>kDlWdeDW&9|P z3-zL&jfyDSRhVE2ymRMcZIXjLO%oAA%n@OM*0>xf%W?lD%bcN^;Fz@=wUp6kTr zwgEVwb048-;uCSXM?mUzzo0JH;kwgMSN92gHwP|#hPK(M#N`si?DM%dHD^0`P{Vn9=cGS3H+G;zUhcI0wwV1*e(!;SW6KSHBFC{e%O4g?Ao$4$9}9h4P)$ z*E_(yFvp3j>tbi?c$2;#JDlzBe=d&eJK?xqkz?M?M7)#kwU}pKsGhICB+oxPNy78Y z2`7+8zBwmXVV$EN$0z>-^SiR&i@-<2cO$So-!t2bm0e(qhB5y<;QWRHWd6 + +_syscall3(int,execve,const char *,file,char **,argv,char **,envp) diff --git a/110_master/110/os/os/linux/lib/execve.o b/110_master/110/os/os/linux/lib/execve.o new file mode 100644 index 0000000000000000000000000000000000000000..00b88ef1b942c5e6836f7ddd415189ecc5a043c3 GIT binary patch literal 2336 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 literal 0 HcmV?d00001 diff --git a/110_master/110/os/os/linux/lib/malloc.c b/110_master/110/os/os/linux/lib/malloc.c new file mode 100644 index 0000000..d7c95d5 --- /dev/null +++ b/110_master/110/os/os/linux/lib/malloc.c @@ -0,0 +1,232 @@ +/* + * malloc.c --- a general purpose kernel memory allocator for Linux. + * + * Written by Theodore Ts'o (tytso@mit.edu), 11/29/91 + * + * This routine is written to be as fast as possible, so that it + * can be called from the interrupt level. + * + * Limitations: maximum size of memory we can allocate using this routine + * is 4k, the size of a page in Linux. + * + * The general game plan is that each page (called a bucket) will only hold + * objects of a given size. When all of the object on a page are released, + * the page can be returned to the general free pool. When malloc() is + * called, it looks for the smallest bucket size which will fulfill its + * request, and allocate a piece of memory from that bucket pool. + * + * Each bucket has as its control block a bucket descriptor which keeps + * track of how many objects are in use on that page, and the free list + * for that page. Like the buckets themselves, bucket descriptors are + * stored on pages requested from get_free_page(). However, unlike buckets, + * pages devoted to bucket descriptor pages are never released back to the + * system. Fortunately, a system should probably only need 1 or 2 bucket + * descriptor pages, since a page can hold 256 bucket descriptors (which + * corresponds to 1 megabyte worth of bucket pages.) If the kernel is using + * that much allocated memory, it's probably doing something wrong. :-) + * + * Note: malloc() and free() both call get_free_page() and free_page() + * in sections of code where interrupts are turned off, to allow + * malloc() and free() to be safely called from an interrupt routine. + * (We will probably need this functionality when networking code, + * particularily things like NFS, is added to Linux.) However, this + * presumes that get_free_page() and free_page() are interrupt-level + * safe, which they may not be once paging is added. If this is the + * case, we will need to modify malloc() to keep a few unused pages + * "pre-allocated" so that it can safely draw upon those pages if + * it is called from an interrupt routine. + * + * Another concern is that get_free_page() should not sleep; if it + * does, the code is carefully ordered so as to avoid any race + * conditions. The catch is that if malloc() is called re-entrantly, + * there is a chance that unecessary pages will be grabbed from the + * system. Except for the pages for the bucket descriptor page, the + * extra pages will eventually get released back to the system, though, + * so it isn't all that bad. + */ + +#include +#include +#include + +struct bucket_desc { /* 16 bytes */ + void *page; + struct bucket_desc *next; + void *freeptr; + unsigned short refcnt; + unsigned short bucket_size; +}; + +struct _bucket_dir { /* 8 bytes */ + int size; + struct bucket_desc *chain; +}; + +/* + * The following is the where we store a pointer to the first bucket + * descriptor for a given size. + * + * If it turns out that the Linux kernel allocates a lot of objects of a + * specific size, then we may want to add that specific size to this list, + * since that will allow the memory to be allocated more efficiently. + * However, since an entire page must be dedicated to each specific size + * on this list, some amount of temperance must be exercised here. + * + * Note that this list *must* be kept in order. + */ +struct _bucket_dir bucket_dir[] = { + { 16, (struct bucket_desc *) 0}, + { 32, (struct bucket_desc *) 0}, + { 64, (struct bucket_desc *) 0}, + { 128, (struct bucket_desc *) 0}, + { 256, (struct bucket_desc *) 0}, + { 512, (struct bucket_desc *) 0}, + { 1024, (struct bucket_desc *) 0}, + { 2048, (struct bucket_desc *) 0}, + { 4096, (struct bucket_desc *) 0}, + { 0, (struct bucket_desc *) 0}}; /* End of list marker */ + +/* + * This contains a linked list of free bucket descriptor blocks + */ +struct bucket_desc *free_bucket_desc = (struct bucket_desc *) 0; + +/* + * This routine initializes a bucket description page. + */ +static inline void init_bucket_desc() +{ + struct bucket_desc *bdesc, *first; + int i; + + first = bdesc = (struct bucket_desc *) get_free_page(); + if (!bdesc) + panic("Out of memory in init_bucket_desc()"); + for (i = PAGE_SIZE/sizeof(struct bucket_desc); i > 1; i--) { + bdesc->next = bdesc+1; + bdesc++; + } + /* + * This is done last, to avoid race conditions in case + * get_free_page() sleeps and this routine gets called again.... + */ + bdesc->next = free_bucket_desc; + free_bucket_desc = first; +} + +void *malloc(unsigned int len) +{ + struct _bucket_dir *bdir; + struct bucket_desc *bdesc; + void *retval; + + /* + * First we search the bucket_dir to find the right bucket change + * for this request. + */ + for (bdir = bucket_dir; bdir->size; bdir++) + if (bdir->size >= len) + break; + if (!bdir->size) { + printk("malloc called with impossibly large argument (%d)\n", + len); + panic("malloc: bad arg"); + } + /* + * Now we search for a bucket descriptor which has free space + */ + cli(); /* Avoid race conditions */ + for (bdesc = bdir->chain; bdesc; bdesc = bdesc->next) + if (bdesc->freeptr) + break; + /* + * If we didn't find a bucket with free space, then we'll + * allocate a new one. + */ + if (!bdesc) { + char *cp; + int i; + + if (!free_bucket_desc) + init_bucket_desc(); + bdesc = free_bucket_desc; + free_bucket_desc = bdesc->next; + bdesc->refcnt = 0; + bdesc->bucket_size = bdir->size; + bdesc->page = bdesc->freeptr = (void *) (cp = get_free_page()); + if (!cp) + panic("Out of memory in kernel malloc()"); + /* Set up the chain of free objects */ + for (i=PAGE_SIZE/bdir->size; i > 1; i--) { + *((char **) cp) = cp + bdir->size; + cp += bdir->size; + } + *((char **) cp) = 0; + bdesc->next = bdir->chain; /* OK, link it in! */ + bdir->chain = bdesc; + } + retval = (void *) bdesc->freeptr; + bdesc->freeptr = *((void **) retval); + bdesc->refcnt++; + sti(); /* OK, we're safe again */ + return(retval); +} + +/* + * Here is the free routine. If you know the size of the object that you + * are freeing, then free_s() will use that information to speed up the + * search for the bucket descriptor. + * + * We will #define a macro so that "free(x)" is becomes "free_s(x, 0)" + */ +void free_s(void *obj, int size) +{ + void *page; + struct _bucket_dir *bdir; + struct bucket_desc *bdesc, *prev; + + /* Calculate what page this object lives in */ + page = (void *) ((unsigned long) obj & 0xfffff000); + /* Now search the buckets looking for that page */ + for (bdir = bucket_dir; bdir->size; bdir++) { + prev = 0; + /* If size is zero then this conditional is always false */ + if (bdir->size < size) + continue; + for (bdesc = bdir->chain; bdesc; bdesc = bdesc->next) { + if (bdesc->page == page) + goto found; + prev = bdesc; + } + } + panic("Bad address passed to kernel free_s()"); +found: + cli(); /* To avoid race conditions */ + *((void **)obj) = bdesc->freeptr; + bdesc->freeptr = obj; + bdesc->refcnt--; + if (bdesc->refcnt == 0) { + /* + * We need to make sure that prev is still accurate. It + * may not be, if someone rudely interrupted us.... + */ + if ((prev && (prev->next != bdesc)) || + (!prev && (bdir->chain != bdesc))) + for (prev = bdir->chain; prev; prev = prev->next) + if (prev->next == bdesc) + break; + if (prev) + prev->next = bdesc->next; + else { + if (bdir->chain != bdesc) + panic("malloc bucket chains corrupted"); + bdir->chain = bdesc->next; + } + free_page((unsigned long) bdesc->page); + bdesc->next = free_bucket_desc; + free_bucket_desc = bdesc; + } + sti(); + return; +} + diff --git a/110_master/110/os/os/linux/lib/malloc.o b/110_master/110/os/os/linux/lib/malloc.o new file mode 100644 index 0000000000000000000000000000000000000000..83667757057ff0915c7c4ad6ae9f4d0c0160ea5d GIT binary patch literal 4880 zcma)AS!`Ta89sOBdNTId@?Fn#g3%ipE_#~_of1bL9E?Nob`ab!I zi+!(7T-}TyePri5q3N3vn|36JywH3rg7ig|=;VdqFN>4|Y6uD0$b_k=Ozh-m4gGIv zI%LD9cRm58cWNkl@`4|l?@)}?Ahli*ydk0WLLZY-Bqxr*atWsx2y&Iz zQ1g(^z4->@t0pdP##;1&99S)`$%Svb1UW~T9|qN>$66&9Xz+Mw{to(0$ucMAd%z^5 zsx45e1P1PsQe}d~6C!wxTZ1Ve4odw4tl?9LEbGU0OQ?zs$Z02#;(*FHF*VeDKiCAS z-K?TEkDk2Hdh$HH5xPtGEf9AhAMBq*z}?ygU-|`*FUMK ztQwMHeY;T9`P+36j^gt$ylB#2GF+vqk9thnNjbH}1CY=vxtnf0Gl3(3^_R`jIHd8* z8W#_1NDFL@QH>^mWin7}?XuCyX7W@C@xE~mx?b5WIx02> zLEA>-eBN_wHK&@X)i9V}akSy6=ei>`X{hs2NjkalOrczJauv@Ds=k{SJ(#+hwQa3M zSSyK3=UF}9VptKO1z?*sSO$bsFtF|*DZ*bMeP}EFgIxg~u_Au} z6Mq+-b?$9Q4&$><&7*IwWFLi44Io-&J8t<=Zfh zuznSU0PRfU2DBaQ8kyeDA?b9`Sr0OU2D#py6BO)cJS7lTyR|yr84Jf(#@nrqNZYL_ zL8ldt$6^~}n_^ZcR;)#Y<79SrZouN(ts(|!Anb%Xk_5380fbngNgT0g8Zqd^phJo0 zwskX9Cju zNweIX?UuE(lL>Y7h@GANm`>+XX7_Z{UhooUY0ViTWeyGLH}QqUZRjoQM!W^R{I!7S zmOl0A9PLml87BOOu!f?Y!K?_`p&53U+3iDTMRrAw%}qZTZrnUG+b0DNM^4W~x4zOd zcUJLdB42u8`jP3`nak1Z!OL`vZdvM2=^#gDF8}!K-1VLZ!cDuj{c`4s+5WlN{u5Gp zCQ_03a3mc2&dZ2<{T<2s=tIAV1aot9W~9TxTXVCoU7q`DPfy6kyhbZQIWKC3$6VpL zqd6SdEH6aCo2cr0!d#LCPu%yZhn(%sV0uG(&`FgtUT%C#;S(F~bW&qZYP3=+_^DAZ zQ*u+)3eLUjL0Bjk3uQMo8kBQ>p@RD>HCnEuYJMhnFje&`zMJzao*b(FG8X;gm6F?E z4)T6~rIsqYhx-vGIFcGjuUnTYX0rVQN`O9#bdehK_m5UN2mer}C~#eR;^s?UEDiz> zb<-|Rk5iU+tf-AwJl_e*wZd2#cQdarbroa9tC=y^xX6-KJ@=4UW;)r#jsR(Dn0prXBggk@H{;7>{|~kFP%76)3yw1cv>#(bDMt54>`qijVOamt&f}2U75-!=og0Gw}>>uwHJ9zw?*k zVq5;#Fyq&cK;Fz+xr9Z7Fy$*i6k1kU+M82p?76~AExfF9wCBn%wXkSeVnBsu1(rl% zS&4c+F3&k7!}!|a@iDDt=IzM;F3l5I$9r$$9{|s}@Luh}eD>U=e+0a_Td6;AlYZ&d zc;7oz_om8c$nboG#_$)36w0@znkg4@I+Cb*c#IC3mutyL?S&9F)`yXU)gZ)2fg$X_ z&ydIDG8(HyY@X+dusaJ3VMD#B`IpGU@1Nx1XJhWfE{*Ge9Ov`o;eUWU>>IIB8MjD; z{EI-!*J9g{9{`fyP5gimdniZTtVZq*-Z%J91Yu$6c}9r*KN4a$5ixs+*l1i!%GYb$ zs&SV_-ci(NHOjjK{NtMcipJ+O{!rr!M2z!_=6|j6ipGCveJkgWcpuWZR^#17_>XAb z( +#include + +int open(const char * filename, int flag, ...) +{ + register int res; + va_list arg; + + va_start(arg,flag); + __asm__("int $0x80" + :"=a" (res) + :"0" (__NR_open),"b" (filename),"c" (flag), + "d" (va_arg(arg,int))); + if (res>=0) + return res; + errno = -res; + return -1; +} diff --git a/110_master/110/os/os/linux/lib/open.o b/110_master/110/os/os/linux/lib/open.o new file mode 100644 index 0000000000000000000000000000000000000000..8d78c9dd4a63d212cd5944be48fef65ab261893d GIT binary patch literal 2364 zcma)7U1%It6h3!mHoM6t+x%2bNWc+NjXyJ+*hNc!Qxh#AO@!7eq8Mj)XLkp8XX4Ck zNlUGfSTID)XiHh2Esxxpwm?|?SG8hmN{HoOGi5c9CblMpV~E$MNYcGW2KhHgY+fL(F6*9n^>O3%w&4BRhZ^)YzyIE4PK1Q$c%Kxw3? zm&Qv&Vz_7UJ|Im}v3MLI6s2YXOT3r#(&6Hf;=%|Pxeq05^w{FWSQ39|Y+-~UW=F3* zH71bD=XOVEqeKNT^;SqPBq$u~dyp8Vh-iv^V(jP`>L$P%ST&n1)m^q<0c$i1Da1de z0Z4fva1DfQmp#AM?$%wRVAb{Q8mcIY>*$Bw;+xX-J-CUDy~ug=qFDZ9>HFJ@i&tON za=_!ERBi_BBgNL3lt)^);f{qtkjSz#Z)c_a74H5KwOyXLNu3wA2z>g5}11pN1 z+H2No7{qQZ4njKbthBKOY$WoUzFRkIEhnU?6@;<58{<3IXgkflDvl(T-bFXQuD1iZVRPzSwd=>-WX0CwUFpqSo~hW=m4}lkTDhP52@)62khoM3vI?C3%#cB*7YahT|qvO>3Q$L?B8cHM~`va3-J3w4G`-bkAqAPU!ee-2Th}?xY%kImoUBosNsm+CCa-<8YG3CS%;ziad;D z{r^Yak0NY4d8^R;f0MnVoMRdX_ev`fZ{s!LN5f#Q;l8kcAoX=5@51hROK!C@T6>jNvi*J1M*-ZxVNcz-0O zl$>L}lxkJ?92)+JtVo2ayOP$a)Ma%rX@KjPJ_55X|8JnzQFjzt5wDNwLvVHex?5kZTqx9Wxsq(Sd4C(Sj_X4^+*{t8c=fKhlU$G47#2wrt9Ub61!n6P$ z#tCsx6mehFf4cl4B!BF51YrSa{!R-Bo>icMd?u{#Ni~1V1P=TG)|hB2jh9n>EY + +_syscall0(pid_t,setsid) diff --git a/110_master/110/os/os/linux/lib/setsid.o b/110_master/110/os/os/linux/lib/setsid.o new file mode 100644 index 0000000000000000000000000000000000000000..7326d9cd51e2bc48d357c3c7806290fb07f04be0 GIT binary patch literal 2240 zcma)7&2QX96rZu3O`1)Y%?E9wfG{W(;ltj9u25AH#4n4oLk6IOf8sTtVW7xN@n018|`dhw}T4XLen2fG5xUp7&3A=W>`cn1sJXWCfQ^@4Yb4!Kg>7~o_oOyon^9xH7Zk6U}jhP5yhSUup2hAy-bWn%nI`? z>iQi<$oF=_%QUX}-) zZEq({^01R9sc5y*FvDi`7COBk75yaMDmD{c4_OkS)Z)^{#%Xu;T6-Ah!(u7k3qvKX zf4JWC*P721TAc9$(?hY75&n9Bn__8{|P7G*1iKGh7<> z{XE>wh2IVGK=|zp?W3|Awuf7-DBet9Qhd;Er{Q~LYmf%<7WP+~z@nH5$RYerG8lyD zoFAhmKI&Z5sF)M>TB@$an*R@e0#3aD746J>Up}O?5tcEID6T+t+zxzV4ud|t@RUzz z*#;%3b6T(pn|RMbqW^#SaXn@Z12EoaWHcBX-f)V*#8k@QW&e zEm*-Z*rPBs&9tj|pe|&d@qYk(%KV7{ literal 0 HcmV?d00001 diff --git a/110_master/110/os/os/linux/lib/string.c b/110_master/110/os/os/linux/lib/string.c new file mode 100644 index 0000000..1182e63 --- /dev/null +++ b/110_master/110/os/os/linux/lib/string.c @@ -0,0 +1,14 @@ +/* + * linux/lib/string.c + * + * (C) 1991 Linus Torvalds + */ + +#ifndef __GNUC__ +#error I want gcc! +#endif + +#define extern +#define inline +#define __LIBRARY__ +#include diff --git a/110_master/110/os/os/linux/lib/string.o b/110_master/110/os/os/linux/lib/string.o new file mode 100644 index 0000000000000000000000000000000000000000..840f038b2beb337cf418b004cd61fe5f8badc3b6 GIT binary patch literal 6380 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 b$T5+-MNW%6E;57|# +#include + +_syscall3(pid_t,waitpid,pid_t,pid,int *,wait_stat,int,options) + +pid_t wait(int * wait_stat) +{ + return waitpid(-1,wait_stat,0); +} diff --git a/110_master/110/os/os/linux/lib/wait.o b/110_master/110/os/os/linux/lib/wait.o new file mode 100644 index 0000000000000000000000000000000000000000..69f2ed6dfe014cec8c0f238dd83b4e502c1fb143 GIT binary patch literal 2580 zcma)8U5Hdw96$GCX2+e~an?26MWKmC(sJ&&IhB~7t!BnzVOfF2cxUGB&ZV7uw|npS zh4jG^BufuMC4q0^qYwlkJp~%}ViCPWFHuiM2HA^5lKp#>5MYH_A&h)wP#~U|f2&IIn1;&^@u;;&`$Ti>5&=A}EJ#Vh5*mlto0T-{SG&R`b8>Nq_HAtF)#xW~|7USEGDY6pK4xLeMHC4+)z~ss)fcq>ayjSi^Yfkt>Q;% z#o{1m=j66Yta>em$>pnqqI85z(NUl&4uBiRU!_rSdBu;(YW*~smAwS^E@%Zp(21C;h^v;Cl*_+b#k6oj=naoexg7NRim+DRD6 z4K-m*u#4EA3%pLH-E|`oF32Picf%;D-1YI^vImm!D&FIfnX!M;V{^oO7|d0e&}>Ft ze7AM`rl+@7)*ov1gQTBssP<@IYEy4cHJnY24XKq)UP%TrP97A-se-X)#J1l<$9cFM zB;I4OyHr>-r%MyZN`>8*OE&YiDIf2+m@bu@C48|?e4>}QEnpI**ws?x%{z&AJP}UE zObpWB88ov0JBf3rPAP zg}YqWdjuB7|5qH>qjOk<^?swENc%QH&#rG9luuye`f?b0eY+s*9Ejo_D4$VKq3KcKI)^1*M!l016ltFeJzMWK6xQKBhB0)#Hy|^I z`zC#hdVi;)Gg@2WWM`cof_GBA$xF$QJ%JOOVb?s=dlu8;H~ zMs^=I7GH*q`&f>l_b~=JJJk#v=V8;N=grPZUztsT5ihzJ#b7U!5{mL+f8pn@g%2Vy{$JkhMqlO2#HMg|HbOW+qWLze8| zz+j;RYzK+&*a|d;z0gE?6^8z;re8m#e1`b~r@s>NQ5O7 + +_syscall3(int,write,int,fd,const char *,buf,off_t,count) diff --git a/110_master/110/os/os/linux/lib/write.o b/110_master/110/os/os/linux/lib/write.o new file mode 100644 index 0000000000000000000000000000000000000000..0d4504785067360dab5e22df170e3bc4a698f092 GIT binary patch literal 2372 zcma)7&2QXP5T9pzKax$i`QRf_Dq*B8q`-O;x}Yd+X-f(vs47ySJwU6-yX(zb?AodA zZIdbjq<|<22O_?N#HA{K0pbvGKu84v5^zI8LgK`Y9tsx@J(S-(zn67SFxodWznOV6 z@6FiW*Pl7{tPp}U2{LJbh+0r`dm4*RywS0=Y!s@Olh@y?0L z$mT|6gx2y~Q2!id{?D)1dFRd@(B?OzuiW?+D9ve!L(s(^>{oO|Ny9393DvN2zd)E) z&JPkYjKVcGisJha)&bV-$Cz7%AEhJz9YpR6Ffn`(oQYG4Pd^9Gw_D0?Y*W6`Zv(O2 z*tQBajv9VWqGIuPiDc^Sgodmg;Nh3SN>6~9Kg--=OzbaDl+5yUc}$GwNAE|b3YAJv z!Gs{C7ID)1$Sg0E4waTBa5_gEol4=uQ%e)P^VsCaPfrQ>@;Ne#X`nGlQ~*@_7#8by z!J)mV#TkbmA{M2A`{>l+DV%d3mVu@F&6;j7>k*bgFMtbiySxWnJ_ne-aGaVSG`szl zSBuwU8bG4Uk)L=@lM^KCt6uDM_<89Eew?(R%Yr${%^~qTW+U>&?;(u#-$o8KYMrp> z)q;L2sfBT^>j(X{>Z~(2SM9ouT0J#@Hz;hkmlJA+eT?3Vq9CM`r_b7pcHNnG>UOo~ zM$OI<|KR+Sc6G(Bw!@yERNIl;^Qx;M9v3fy(GO6-tG4?=Gx5V9hA9ZEapE>#t*%C4 z;x&^n!r^0oCGc8yv*Sh-cfu&KcWwOS$vY3i*p!C)S3GV4b;DrAX7loLaAnG?VE*Q0 zA6WJ=O=As7EoJZGCBu)#u{ef5FO2sqY(g?!OvNtO`5uLZmSnW~brkJpBhI_?4*{)mi7 znT~r)#c9{udN9hsaZI0Jv7Ub9h^``To*jz#d`ur=W$$q~bC137>3fVp&zAZc;5uxY zblq%C_Ptpkx&?`^FzvzOeB5`gna!7=dH2GmN$1m8%dFj^zwT%|%e()b8D}dn*0)Y~ znevGnWH1Sb&5$W4Ixv`WvROPb0MJarpIe4Z;tmeTL@;rEP`Rp8bUP&9$0R9)xBoVOy literal 0 HcmV?d00001 diff --git a/110_master/110/os/os/linux/mm/Makefile b/110_master/110/os/os/linux/mm/Makefile new file mode 100644 index 0000000..e0bcd73 --- /dev/null +++ b/110_master/110/os/os/linux/mm/Makefile @@ -0,0 +1,38 @@ +AR =ar +AS =as +LD =ld +LDFLAGS =-m elf_i386 -Ttext 0 -e startup_32 +CC =gcc -march=i386 +CFLAGS =-w -g -fstrength-reduce -fomit-frame-pointer -mcld \ + -finline-functions -nostdinc -fno-stack-protector -I../include +CPP =gcc -E -nostdinc -I../include + +.c.o: + $(CC) $(CFLAGS) \ + -c -o $*.o $< +.s.o: + $(AS) -o $*.o $< +.c.s: + $(CC) $(CFLAGS) \ + -S -o $*.s $< + +OBJS = memory.o page.o + +all: mm.o + +mm.o: $(OBJS) + $(LD) -r -o mm.o $(OBJS) + +clean: + rm -f core *.o *.a tmp_make + for i in *.c;do rm -f `basename $$i .c`.s;done + +dep: + sed '/\#\#\# Dependencies/q' < Makefile > tmp_make + (for i in *.c;do $(CPP) -M $$i;done) >> tmp_make + cp tmp_make Makefile + +### Dependencies: +memory.o : memory.c ../include/signal.h ../include/sys/types.h \ + ../include/asm/system.h ../include/linux/sched.h ../include/linux/head.h \ + ../include/linux/fs.h ../include/linux/mm.h ../include/linux/kernel.h diff --git a/110_master/110/os/os/linux/mm/memory.c b/110_master/110/os/os/linux/mm/memory.c new file mode 100644 index 0000000..7cf53a4 --- /dev/null +++ b/110_master/110/os/os/linux/mm/memory.c @@ -0,0 +1,468 @@ +/* + * linux/mm/memory.c + * + * (C) 1991 Linus Torvalds + */ + +/* + * demand-loading started 01.12.91 - seems it is high on the list of + * things wanted, and it should be easy to implement. - Linus + */ + +/* + * Ok, demand-loading was easy, shared pages a little bit tricker. Shared + * pages started 02.12.91, seems to work. - Linus. + * + * Tested sharing by executing about 30 /bin/sh: under the old kernel it + * would have taken more than the 6M I have free, but it worked well as + * far as I could see. + * + * Also corrected some "invalidate()"s - I wasn't doing enough of them. + */ + +#include + +#include + +#include +#include +#include + +volatile void do_exit(long code); + +static inline volatile void oom(void) +{ + printk("out of memory\n\r"); + do_exit(SIGSEGV); +} + +#define invalidate() \ +__asm__("movl %%eax,%%cr3"::"a" (0)) + +/* these are not to be changed without changing head.s etc */ +#define LOW_MEM 0x100000 +#define PAGING_MEMORY (15*1024*1024) +#define PAGING_PAGES (PAGING_MEMORY>>12) +#define MAP_NR(addr) (((addr)-LOW_MEM)>>12) +#define USED 100 + +#define CODE_SPACE(addr) ((((addr)+4095)&~4095) < \ +current->start_code + current->end_code) + +static long HIGH_MEMORY = 0; + +#define copy_page(from,to) \ +__asm__("cld ; rep ; movsl"::"S" (from),"D" (to),"c" (1024)) + +static unsigned char mem_map [ PAGING_PAGES ] = {0,}; + +/* + * Get physical address of first (actually last :-) free page, and mark it + * used. If no free pages left, return 0. + */ +unsigned long get_free_page(void) +{ +register unsigned long __res asm("ax"); + +__asm__("std ; repne ; scasb\n\t" + "jne 1f\n\t" + "movb $1,1(%%edi)\n\t" + "sall $12,%%ecx\n\t" + "addl %2,%%ecx\n\t" + "movl %%ecx,%%edx\n\t" + "movl $1024,%%ecx\n\t" + "leal 4092(%%edx),%%edi\n\t" + "rep ; stosl\n\t" + "movl %%edx,%%eax\n\t" + "1:" + "cld\n\t" /* by wyj */ + :"=a" (__res) + :"0" (0),"i" (LOW_MEM),"c" (PAGING_PAGES), + "D" (mem_map+PAGING_PAGES-1) + ); +return __res; +} + +/* + * Free a page of memory at physical address 'addr'. Used by + * 'free_page_tables()' + */ +void free_page(unsigned long addr) +{ + if (addr < LOW_MEM) return; + if (addr >= HIGH_MEMORY) + panic("trying to free nonexistent page"); + addr -= LOW_MEM; + addr >>= 12; + if (mem_map[addr]--) return; + mem_map[addr]=0; + panic("trying to free free page"); +} + +/* + * This function frees a continuos block of page tables, as needed + * by 'exit()'. As does copy_page_tables(), this handles only 4Mb blocks. + */ +int free_page_tables(unsigned long from,unsigned long size) +{ + unsigned long *pg_table; + unsigned long * dir, nr; + + if (from & 0x3fffff) + panic("free_page_tables called with wrong alignment"); + if (!from) + panic("Trying to free up swapper memory space"); + size = (size + 0x3fffff) >> 22; + dir = (unsigned long *) ((from>>20) & 0xffc); /* _pg_dir = 0 */ + for ( ; size-->0 ; dir++) { + if (!(1 & *dir)) + continue; + pg_table = (unsigned long *) (0xfffff000 & *dir); + for (nr=0 ; nr<1024 ; nr++) { + if (1 & *pg_table) + free_page(0xfffff000 & *pg_table); + *pg_table = 0; + pg_table++; + } + free_page(0xfffff000 & *dir); + *dir = 0; + } + invalidate(); + return 0; +} + +/* + * Well, here is one of the most complicated functions in mm. It + * copies a range of linerar addresses by copying only the pages. + * Let's hope this is bug-free, 'cause this one I don't want to debug :-) + * + * Note! We don't copy just any chunks of memory - addresses have to + * be divisible by 4Mb (one page-directory entry), as this makes the + * function easier. It's used only by fork anyway. + * + * NOTE 2!! When from==0 we are copying kernel space for the first + * fork(). Then we DONT want to copy a full page-directory entry, as + * that would lead to some serious memory waste - we just copy the + * first 160 pages - 640kB. Even that is more than we need, but it + * doesn't take any more memory - we don't copy-on-write in the low + * 1 Mb-range, so the pages can be shared with the kernel. Thus the + * special case for nr=xxxx. + */ +int copy_page_tables(unsigned long from,unsigned long to,long size) +{ + unsigned long * from_page_table; + unsigned long * to_page_table; + unsigned long this_page; + unsigned long * from_dir, * to_dir; + unsigned long nr; + + if ((from&0x3fffff) || (to&0x3fffff)) + panic("copy_page_tables called with wrong alignment"); + from_dir = (unsigned long *) ((from>>20) & 0xffc); /* _pg_dir = 0 */ + to_dir = (unsigned long *) ((to>>20) & 0xffc); + size = ((unsigned) (size+0x3fffff)) >> 22; + for( ; size-->0 ; from_dir++,to_dir++) { + if (1 & *to_dir) + panic("copy_page_tables: already exist"); + if (!(1 & *from_dir)) + continue; + from_page_table = (unsigned long *) (0xfffff000 & *from_dir); + if (!(to_page_table = (unsigned long *) get_free_page())) + return -1; /* Out of memory, see freeing */ + *to_dir = ((unsigned long) to_page_table) | 7; + nr = (from==0)?0xA0:1024; + for ( ; nr-- > 0 ; from_page_table++,to_page_table++) { + this_page = *from_page_table; + if (!(1 & this_page)) + continue; + this_page &= ~2; + *to_page_table = this_page; + if (this_page > LOW_MEM) { + *from_page_table = this_page; + this_page -= LOW_MEM; + this_page >>= 12; + mem_map[this_page]++; + } + } + } + invalidate(); + return 0; +} + +/* + * This function puts a page in memory at the wanted address. + * It returns the physical address of the page gotten, 0 if + * out of memory (either when trying to access page-table or + * page.) + */ +unsigned long put_page(unsigned long page,unsigned long address) +{ + unsigned long tmp, *page_table; + +/* NOTE !!! This uses the fact that _pg_dir=0 */ + + if (page < LOW_MEM || page >= HIGH_MEMORY) + printk("Trying to put page %p at %p\n",page,address); + if (mem_map[(page-LOW_MEM)>>12] != 1) + printk("mem_map disagrees with %p at %p\n",page,address); + page_table = (unsigned long *) ((address>>20) & 0xffc); + if ((*page_table)&1) + page_table = (unsigned long *) (0xfffff000 & *page_table); + else { + if (!(tmp=get_free_page())) + return 0; + *page_table = tmp|7; + page_table = (unsigned long *) tmp; + } + page_table[(address>>12) & 0x3ff] = page | 7; +/* no need for invalidate */ + return page; +} + +void un_wp_page(unsigned long * table_entry) +{ + unsigned long old_page,new_page; + + old_page = 0xfffff000 & *table_entry; + if (old_page >= LOW_MEM && mem_map[MAP_NR(old_page)]==1) { + *table_entry |= 2; + invalidate(); + return; + } + if (!(new_page=get_free_page())) + oom(); + if (old_page >= LOW_MEM) + mem_map[MAP_NR(old_page)]--; + *table_entry = new_page | 7; + invalidate(); + copy_page(old_page,new_page); +} + +/* + * This routine handles present pages, when users try to write + * to a shared page. It is done by copying the page to a new address + * and decrementing the shared-page counter for the old page. + * + * If it's in code space we exit with a segment error. + */ +void do_wp_page(unsigned long error_code,unsigned long address) +{ +#if 0 +/* we cannot do this yet: the estdio library writes to code space */ +/* stupid, stupid. I really want the libc.a from GNU */ + if (CODE_SPACE(address)) + do_exit(SIGSEGV); +#endif + un_wp_page((unsigned long *) + (((address>>10) & 0xffc) + (0xfffff000 & + *((unsigned long *) ((address>>20) &0xffc))))); + +} + +void write_verify(unsigned long address) +{ + unsigned long page; + + if (!( (page = *((unsigned long *) ((address>>20) & 0xffc)) )&1)) + return; + page &= 0xfffff000; + page += ((address>>10) & 0xffc); + if ((3 & *(unsigned long *) page) == 1) /* non-writeable, present */ + un_wp_page((unsigned long *) page); + return; +} + +void get_empty_page(unsigned long address) +{ + unsigned long tmp; + + if (!(tmp=get_free_page()) || !put_page(tmp,address)) { + free_page(tmp); /* 0 is ok - ignored */ + oom(); + } +} + +/* + * try_to_share() checks the page at address "address" in the task "p", + * to see if it exists, and if it is clean. If so, share it with the current + * task. + * + * NOTE! This assumes we have checked that p != current, and that they + * share the same executable. + */ +static int try_to_share(unsigned long address, struct task_struct * p) +{ + unsigned long from; + unsigned long to; + unsigned long from_page; + unsigned long to_page; + unsigned long phys_addr; + + from_page = to_page = ((address>>20) & 0xffc); + from_page += ((p->start_code>>20) & 0xffc); + to_page += ((current->start_code>>20) & 0xffc); +/* is there a page-directory at from? */ + from = *(unsigned long *) from_page; + if (!(from & 1)) + return 0; + from &= 0xfffff000; + from_page = from + ((address>>10) & 0xffc); + phys_addr = *(unsigned long *) from_page; +/* is the page clean and present? */ + if ((phys_addr & 0x41) != 0x01) + return 0; + phys_addr &= 0xfffff000; + if (phys_addr >= HIGH_MEMORY || phys_addr < LOW_MEM) + return 0; + to = *(unsigned long *) to_page; + if (!(to & 1)) + if (to = get_free_page()) + *(unsigned long *) to_page = to | 7; + else + oom(); + to &= 0xfffff000; + to_page = to + ((address>>10) & 0xffc); + if (1 & *(unsigned long *) to_page) + panic("try_to_share: to_page already exists"); +/* share them: write-protect */ + *(unsigned long *) from_page &= ~2; + *(unsigned long *) to_page = *(unsigned long *) from_page; + invalidate(); + phys_addr -= LOW_MEM; + phys_addr >>= 12; + mem_map[phys_addr]++; + return 1; +} + +/* + * share_page() tries to find a process that could share a page with + * the current one. Address is the address of the wanted page relative + * to the current data space. + * + * We first check if it is at all feasible by checking executable->i_count. + * It should be >1 if there are other tasks sharing this inode. + */ +static int share_page(unsigned long address) +{ + struct task_struct ** p; + + if (!current->executable) + return 0; + if (current->executable->i_count < 2) + return 0; + for (p = &LAST_TASK ; p > &FIRST_TASK ; --p) { + if (!*p) + continue; + if (current == *p) + continue; + if ((*p)->executable != current->executable) + continue; + if (try_to_share(address,*p)) + return 1; + } + return 0; +} + +void do_no_page(unsigned long error_code,unsigned long address) +{ + int nr[4]; + unsigned long tmp; + unsigned long page; + int block,i; + + if (current->pid > 5) + printk(" --do_no_page: address=%x, pid=%d\n", address, current->pid); + + address &= 0xfffff000; + tmp = address - current->start_code; + if (!current->executable || tmp >= current->end_data) { + get_empty_page(address); + return; + } + if (share_page(tmp)) + return; + if (!(page = get_free_page())) + oom(); +/* remember that 1 block is used for header */ + block = 1 + tmp/BLOCK_SIZE; + for (i=0 ; i<4 ; block++,i++) + nr[i] = bmap(current->executable,block); + bread_page(page,current->executable->i_dev,nr); + i = tmp + 4096 - current->end_data; + tmp = page + 4096; + while (i-- > 0) { + tmp--; + *(char *)tmp = 0; + } + if (put_page(page,address)) + return; + free_page(page); + oom(); +} + +void do_no_pagex(unsigned long error_code,unsigned long address) +{ + int nr[4]; + unsigned long tmp; + unsigned long page; + int block,i; + + address &= 0xfffff000; + tmp = address - current->start_code; + if (!current->executable || tmp >= current->end_data) { + get_empty_page(address); + return; + } + if (share_page(tmp)) + return; + if (!(page = get_free_page())) + oom(); +/* remember that 1 block is used for header */ + block = 1 + tmp/BLOCK_SIZE; + for (i=0 ; i<4 ; block++,i++) + nr[i] = bmap(current->executable,block); + bread_page(page,current->executable->i_dev,nr); + i = tmp + 4096 - current->end_data; + tmp = page + 4096; + while (i-- > 0) { + tmp--; + *(char *)tmp = 0; + } + if (put_page(page,address)) + return; + free_page(page); + oom(); +} + +void mem_init(long start_mem, long end_mem) +{ + int i; + + HIGH_MEMORY = end_mem; + for (i=0 ; i>= 12; + while (end_mem-->0) + mem_map[i++]=0; +} + +void calc_mem(void) +{ + int i,j,k,free=0; + long * pg_tbl; + + for(i=0 ; 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 T!PSDjg1ZDC7v%qTv)+FKQ=t$V literal 0 HcmV?d00001 diff --git a/110_master/110/os/os/linux/mm/mm.o b/110_master/110/os/os/linux/mm/mm.o new file mode 100644 index 0000000000000000000000000000000000000000..549d06c1dc3c93101ef2aeffa85a31b5def277d2 GIT binary patch literal 13936 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 M(++mG>`3K50pD0JzW@LL literal 0 HcmV?d00001 diff --git a/110_master/110/os/os/linux/mm/page.o b/110_master/110/os/os/linux/mm/page.o new file mode 100644 index 0000000000000000000000000000000000000000..da4852668a6d8b88d91c428ae8572bb3d4d2090d GIT binary patch literal 640 zcmb<-^>JflWMqH=Mh0dE1doAX4phPfOlvT3Ft9STv#10H$+7V-*d+iI?Yq@?sP7TK z!lj^ql^~s^>@WWO|Ns9rE0}6N!ok0gT|O!@;yi<1ab<2vViJ%pDT2@$Fji4&j$TP> zMG1pmN@7VOgI-c`G1OurD0!e7kj-pRwIH{eL)jn-<{xPwn-fXAfQf+ts z<^W< +#include + +#define NAME_MAX 80 +#include + +int main(int argc, char *argv[]) +{ + DIR *dir ; + struct dirent *de; + + if (argc != 1) + exit(1); + + if ((dir = opendir(".")) == NULL) + exit(1); + + while ((de = readdir(dir)) != NULL) + printf("%s\t", de->d_name); + + printf("\n"); + closedir(dir); + exit(0); +} diff --git a/110_master/110/os/os/linux/tools/build b/110_master/110/os/os/linux/tools/build new file mode 100644 index 0000000000000000000000000000000000000000..0fa6ae7f877d2483ad12f6df98491878b0f38b14 GIT binary patch literal 15144 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 N^|Cbi(V*L${{d;jp)>#h literal 0 HcmV?d00001 diff --git a/110_master/110/os/os/linux/tools/build.c b/110_master/110/os/os/linux/tools/build.c new file mode 100644 index 0000000..8b8c7ab --- /dev/null +++ b/110_master/110/os/os/linux/tools/build.c @@ -0,0 +1,171 @@ +/* + * linux/tools/build.c + * + * (C) 1991 Linus Torvalds + */ + +/* + * This file builds a disk-image from three different files: + * + * - bootsect: max 510 bytes of 8086 machine code, loads the rest + * - setup: max 4 sectors of 8086 machine code, sets up system parm + * - system: 80386 code for actual system + * + * It does some checking that all files are of the correct type, and + * just writes the result to stdout, removing headers and padding to + * the right amount. It also writes some system data to stderr. + */ + +/* + * Changes by tytso to allow root device specification + */ + +#include /* fprintf */ +#include +#include /* contains exit */ +#include /* unistd.h needs this */ +#include +#include +#include /* contains read/write */ +#include + +#define MAJOR(a) (((unsigned)(a))>>8) +#define MINOR(a) ((a)&0xff) + +#define MINIX_HEADER 32 +#define GCC_HEADER 0x80 /* 0x1000 */ /* by wyj */ + +#define SYS_SIZE 0x3000 + +#define DEFAULT_MAJOR_ROOT 0x03 //0x02 /* by wyj */ +#define DEFAULT_MINOR_ROOT 0x00 //0x1d + +/* max nr of sectors of setup: don't change unless you also change + * bootsect etc */ +#define SETUP_SECTS 4 + +#define STRINGIFY(x) #x + +void die(char * str) +{ + fprintf(stderr,"%s\n",str); + exit(1); +} + +void usage(void) +{ + die("Usage: build bootsect setup system [rootdev] [> image]"); +} + +int main(int argc, char ** argv) +{ + int i,c,id; + char buf[1024*4]; /* by wyj */ + char major_root, minor_root; + struct stat sb; + + if ((argc != 4) && (argc != 5)) + usage(); + if (argc == 5) { + if (strcmp(argv[4], "FLOPPY")) { + if (stat(argv[4], &sb)) { + perror(argv[4]); + die("Couldn't stat root device."); + } + major_root = MAJOR(sb.st_rdev); + minor_root = MINOR(sb.st_rdev); + } else { + major_root = 0; + minor_root = 0; + } + } else { + major_root = DEFAULT_MAJOR_ROOT; + minor_root = DEFAULT_MINOR_ROOT; + } + fprintf(stderr, "Root device is (%d, %d)\n", major_root, minor_root); + if ((major_root != 2) && (major_root != 3) && + (major_root != 0)) { + fprintf(stderr, "Illegal root device (major = %d)\n", + major_root); + die("Bad root device --- major #"); + } + for (i=0;i0 ; i+=c ) + if (write(1,buf,c)!=c) + die("Write call failed"); + close (id); + if (i > SETUP_SECTS*512) + die("Setup exceeds " STRINGIFY(SETUP_SECTS) + " sectors - rewrite build/boot/setup"); + fprintf(stderr,"Setup is %d bytes.\n",i); + for (c=0 ; c sizeof(buf)) + c = sizeof(buf); + if (write(1,buf,c) != c) + die("Write call failed"); + i += c; + } + + if ((id=open(argv[3],O_RDONLY,0))<0) + die("Unable to open 'system'"); + if (read(id,buf,GCC_HEADER) != GCC_HEADER) + die("Unable to read header of 'system'"); +// if (((long *) buf)[5] != 0) +// die("Non-GCC header of 'system'"); + for (i=0 ; (c=read(id,buf,sizeof buf))>0 ; i+=c ) + if (write(1,buf,c)!=c) + die("Write call failed"); + close(id); + fprintf(stderr,"System is %d bytes.\n",i); + if (i > SYS_SIZE*16) + die("System is too big"); + return(0); +} diff --git a/110_master/110/os/os/linux/tools/system b/110_master/110/os/os/linux/tools/system new file mode 100644 index 0000000000000000000000000000000000000000..f61bee765ca166b1564cdc94650cf3f220f28eed GIT binary patch literal 306090 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�b&Xfwa62;M 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�@?)L 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 t{&|{e*<55HtTR{-why#uvf|8mX0epaId_#6