From 6085e6a4763a1555ca31a36213b9e87c482f02c2 Mon Sep 17 00:00:00 2001 From: forever-learner <2360561713@qq.com> Date: Tue, 28 Jun 2022 16:17:42 +0800 Subject: [PATCH] push --- README.md | 2 - linux/.vscode/settings.json | 54 ++ linux/Image | Bin 0 -> 135792 bytes linux/Image.bkp | Bin 0 -> 131556 bytes linux/Makefile | 125 ++++ linux/System.map | 591 +++++++++++++++ linux/System.map.2 | 1107 +++++++++++++++++++++++++++++ linux/boot/bootsect | Bin 0 -> 544 bytes linux/boot/bootsect.o | Bin 0 -> 923 bytes linux/boot/bootsect.s | 260 +++++++ linux/boot/head.o | Bin 0 -> 27012 bytes linux/boot/head.s | 240 +++++++ linux/boot/setup | Bin 0 -> 344 bytes linux/boot/setup.o | Bin 0 -> 596 bytes linux/boot/setup.s | 231 ++++++ linux/execve2.patch | 41 ++ linux/fs/Makefile | 101 +++ linux/fs/bitmap.c | 168 +++++ linux/fs/bitmap.o | Bin 0 -> 10276 bytes linux/fs/block_dev.c | 73 ++ linux/fs/block_dev.o | Bin 0 -> 7292 bytes linux/fs/buffer.c | 384 ++++++++++ linux/fs/buffer.o | Bin 0 -> 13344 bytes linux/fs/char_dev.c | 104 +++ linux/fs/char_dev.o | Bin 0 -> 8284 bytes linux/fs/exec.c | 367 ++++++++++ linux/fs/exec.o | Bin 0 -> 15304 bytes linux/fs/fcntl.c | 75 ++ linux/fs/fcntl.o | Bin 0 -> 6744 bytes linux/fs/file_dev.c | 90 +++ linux/fs/file_dev.o | Bin 0 -> 7824 bytes linux/fs/file_table.c | 9 + linux/fs/file_table.o | Bin 0 -> 2644 bytes linux/fs/fs.o | Bin 0 -> 143225 bytes linux/fs/inode.c | 340 +++++++++ linux/fs/inode.o | Bin 0 -> 14068 bytes linux/fs/ioctl.c | 46 ++ linux/fs/ioctl.o | Bin 0 -> 5824 bytes linux/fs/namei.c | 783 ++++++++++++++++++++ linux/fs/namei.o | Bin 0 -> 20752 bytes linux/fs/open.c | 208 ++++++ linux/fs/open.o | Bin 0 -> 11180 bytes linux/fs/pipe.c | 111 +++ linux/fs/pipe.o | Bin 0 -> 8100 bytes linux/fs/read_write.c | 103 +++ linux/fs/read_write.o | Bin 0 -> 7516 bytes linux/fs/select.c | 10 + linux/fs/select.o | Bin 0 -> 1776 bytes linux/fs/stat.c | 66 ++ linux/fs/stat.o | Bin 0 -> 7208 bytes linux/fs/super.c | 282 ++++++++ linux/fs/super.o | Bin 0 -> 12280 bytes linux/fs/truncate.c | 65 ++ linux/fs/truncate.o | Bin 0 -> 6844 bytes linux/include/a.out.h | 220 ++++++ linux/include/asm/io.h | 24 + linux/include/asm/memory.h | 15 + linux/include/asm/segment.h | 65 ++ linux/include/asm/system.h | 66 ++ linux/include/const.h | 15 + linux/include/ctype.h | 34 + linux/include/errno.h | 60 ++ linux/include/fcntl.h | 55 ++ linux/include/linux/config.h | 48 ++ linux/include/linux/fdreg.h | 71 ++ linux/include/linux/fs.h | 202 ++++++ linux/include/linux/hdreg.h | 65 ++ linux/include/linux/head.h | 20 + linux/include/linux/kernel.h | 22 + linux/include/linux/mm.h | 10 + linux/include/linux/sched.h | 239 +++++++ linux/include/linux/sys.h | 121 ++++ linux/include/linux/tty.h | 77 ++ linux/include/new.h | 30 + linux/include/signal.h | 68 ++ linux/include/stdarg.h | 28 + linux/include/stddef.h | 19 + linux/include/string.h | 405 +++++++++++ linux/include/sys/stat.h | 60 ++ linux/include/sys/times.h | 15 + linux/include/sys/types.h | 46 ++ linux/include/sys/utsname.h | 16 + linux/include/sys/wait.h | 23 + linux/include/termios.h | 228 ++++++ linux/include/time.h | 42 ++ linux/include/unistd.h | 277 ++++++++ linux/include/utime.h | 13 + linux/init/main.c | 217 ++++++ linux/init/main.o | Bin 0 -> 9176 bytes linux/kernel/Makefile | 83 +++ linux/kernel/asm.o | Bin 0 -> 1740 bytes linux/kernel/asm.s | 146 ++++ linux/kernel/blk_drv/Makefile | 58 ++ linux/kernel/blk_drv/blk.h | 140 ++++ linux/kernel/blk_drv/blk_drv.a | Bin 0 -> 52200 bytes linux/kernel/blk_drv/floppy.c | 463 ++++++++++++ linux/kernel/blk_drv/floppy.o | Bin 0 -> 16608 bytes linux/kernel/blk_drv/hd.c | 351 +++++++++ linux/kernel/blk_drv/hd.o | Bin 0 -> 15516 bytes linux/kernel/blk_drv/ll_rw_blk.c | 165 +++++ linux/kernel/blk_drv/ll_rw_blk.o | Bin 0 -> 8736 bytes linux/kernel/blk_drv/ramdisk.c | 126 ++++ linux/kernel/blk_drv/ramdisk.o | Bin 0 -> 10664 bytes linux/kernel/chr_drv/Makefile | 68 ++ linux/kernel/chr_drv/chr_drv.a | Bin 0 -> 68886 bytes linux/kernel/chr_drv/console.c | 710 ++++++++++++++++++ linux/kernel/chr_drv/console.o | Bin 0 -> 20892 bytes linux/kernel/chr_drv/keyboard.2.o | Bin 0 -> 6024 bytes linux/kernel/chr_drv/keyboard.2.s | 466 ++++++++++++ linux/kernel/chr_drv/keyboard.S | 588 +++++++++++++++ linux/kernel/chr_drv/rs_io.o | Bin 0 -> 1320 bytes linux/kernel/chr_drv/rs_io.s | 147 ++++ linux/kernel/chr_drv/serial.c | 59 ++ linux/kernel/chr_drv/serial.o | Bin 0 -> 6748 bytes linux/kernel/chr_drv/tty_io.c | 349 +++++++++ linux/kernel/chr_drv/tty_io.o | Bin 0 -> 22500 bytes linux/kernel/chr_drv/tty_ioctl.c | 204 ++++++ linux/kernel/chr_drv/tty_ioctl.o | Bin 0 -> 10644 bytes linux/kernel/exit.c | 197 +++++ linux/kernel/exit.o | Bin 0 -> 11160 bytes linux/kernel/fork.c | 148 ++++ linux/kernel/fork.o | Bin 0 -> 9636 bytes linux/kernel/kernel.o | Bin 0 -> 89688 bytes linux/kernel/math/Makefile | 43 ++ linux/kernel/math/math.a | Bin 0 -> 6628 bytes linux/kernel/math/math_emulate.c | 42 ++ linux/kernel/math/math_emulate.o | Bin 0 -> 6464 bytes linux/kernel/mktime.c | 58 ++ linux/kernel/mktime.o | Bin 0 -> 2872 bytes linux/kernel/panic.c | 24 + linux/kernel/panic.o | Bin 0 -> 5420 bytes linux/kernel/printk.c | 41 ++ linux/kernel/printk.o | Bin 0 -> 2424 bytes linux/kernel/sched.c | 412 +++++++++++ linux/kernel/sched.o | Bin 0 -> 23040 bytes linux/kernel/signal.c | 129 ++++ linux/kernel/signal.o | Bin 0 -> 8956 bytes linux/kernel/sys.c | 489 +++++++++++++ linux/kernel/sys.o | Bin 0 -> 18540 bytes linux/kernel/system_call.o | Bin 0 -> 2640 bytes linux/kernel/system_call.s | 298 ++++++++ linux/kernel/traps.c | 208 ++++++ linux/kernel/traps.o | Bin 0 -> 12968 bytes linux/kernel/vsprintf.c | 233 ++++++ linux/kernel/vsprintf.o | Bin 0 -> 6156 bytes linux/lib/Makefile | 73 ++ linux/lib/_exit.c | 13 + linux/lib/_exit.o | Bin 0 -> 1988 bytes linux/lib/close.c | 10 + linux/lib/close.o | Bin 0 -> 2220 bytes linux/lib/ctype.c | 35 + linux/lib/ctype.o | Bin 0 -> 1908 bytes linux/lib/dup.c | 10 + linux/lib/dup.o | Bin 0 -> 2196 bytes linux/lib/errno.c | 7 + linux/lib/errno.o | Bin 0 -> 1472 bytes linux/lib/execve.c | 10 + linux/lib/execve.o | Bin 0 -> 2336 bytes linux/lib/lib.a | Bin 0 -> 34138 bytes linux/lib/malloc.c | 232 ++++++ linux/lib/malloc.o | Bin 0 -> 4880 bytes linux/lib/open.c | 25 + linux/lib/open.o | Bin 0 -> 2364 bytes linux/lib/setsid.c | 10 + linux/lib/setsid.o | Bin 0 -> 2240 bytes linux/lib/string.c | 14 + linux/lib/string.o | Bin 0 -> 6380 bytes linux/lib/wait.c | 16 + linux/lib/wait.o | Bin 0 -> 2580 bytes linux/lib/write.c | 10 + linux/lib/write.o | Bin 0 -> 2372 bytes linux/mm/Makefile | 38 + linux/mm/memory.c | 468 ++++++++++++ linux/mm/memory.c.orig | 464 ++++++++++++ linux/mm/memory.o | Bin 0 -> 13960 bytes linux/mm/mm.o | Bin 0 -> 14089 bytes linux/mm/page.o | Bin 0 -> 640 bytes linux/mm/page.s | 40 ++ linux/tools/build | Bin 0 -> 15144 bytes linux/tools/build.c | 171 +++++ linux/tools/system | Bin 0 -> 294247 bytes linux_lab_os_exp2 | 1 - 182 files changed, 17041 insertions(+), 3 deletions(-) delete mode 100644 README.md create mode 100644 linux/.vscode/settings.json create mode 100644 linux/Image create mode 100644 linux/Image.bkp create mode 100644 linux/Makefile create mode 100644 linux/System.map create mode 100644 linux/System.map.2 create mode 100644 linux/boot/bootsect create mode 100644 linux/boot/bootsect.o create mode 100644 linux/boot/bootsect.s create mode 100644 linux/boot/head.o create mode 100644 linux/boot/head.s create mode 100644 linux/boot/setup create mode 100644 linux/boot/setup.o create mode 100644 linux/boot/setup.s create mode 100644 linux/execve2.patch create mode 100644 linux/fs/Makefile create mode 100644 linux/fs/bitmap.c create mode 100644 linux/fs/bitmap.o create mode 100644 linux/fs/block_dev.c create mode 100644 linux/fs/block_dev.o create mode 100644 linux/fs/buffer.c create mode 100644 linux/fs/buffer.o create mode 100644 linux/fs/char_dev.c create mode 100644 linux/fs/char_dev.o create mode 100644 linux/fs/exec.c create mode 100644 linux/fs/exec.o create mode 100644 linux/fs/fcntl.c create mode 100644 linux/fs/fcntl.o create mode 100644 linux/fs/file_dev.c create mode 100644 linux/fs/file_dev.o create mode 100644 linux/fs/file_table.c create mode 100644 linux/fs/file_table.o create mode 100644 linux/fs/fs.o create mode 100644 linux/fs/inode.c create mode 100644 linux/fs/inode.o create mode 100644 linux/fs/ioctl.c create mode 100644 linux/fs/ioctl.o create mode 100644 linux/fs/namei.c create mode 100644 linux/fs/namei.o create mode 100644 linux/fs/open.c create mode 100644 linux/fs/open.o create mode 100644 linux/fs/pipe.c create mode 100644 linux/fs/pipe.o create mode 100644 linux/fs/read_write.c create mode 100644 linux/fs/read_write.o create mode 100644 linux/fs/select.c create mode 100644 linux/fs/select.o create mode 100644 linux/fs/stat.c create mode 100644 linux/fs/stat.o create mode 100644 linux/fs/super.c create mode 100644 linux/fs/super.o create mode 100644 linux/fs/truncate.c create mode 100644 linux/fs/truncate.o create mode 100644 linux/include/a.out.h create mode 100644 linux/include/asm/io.h create mode 100644 linux/include/asm/memory.h create mode 100644 linux/include/asm/segment.h create mode 100644 linux/include/asm/system.h create mode 100644 linux/include/const.h create mode 100644 linux/include/ctype.h create mode 100644 linux/include/errno.h create mode 100644 linux/include/fcntl.h create mode 100644 linux/include/linux/config.h create mode 100644 linux/include/linux/fdreg.h create mode 100644 linux/include/linux/fs.h create mode 100644 linux/include/linux/hdreg.h create mode 100644 linux/include/linux/head.h create mode 100644 linux/include/linux/kernel.h create mode 100644 linux/include/linux/mm.h create mode 100644 linux/include/linux/sched.h create mode 100644 linux/include/linux/sys.h create mode 100644 linux/include/linux/tty.h create mode 100644 linux/include/new.h create mode 100644 linux/include/signal.h create mode 100644 linux/include/stdarg.h create mode 100644 linux/include/stddef.h create mode 100644 linux/include/string.h create mode 100644 linux/include/sys/stat.h create mode 100644 linux/include/sys/times.h create mode 100644 linux/include/sys/types.h create mode 100644 linux/include/sys/utsname.h create mode 100644 linux/include/sys/wait.h create mode 100644 linux/include/termios.h create mode 100644 linux/include/time.h create mode 100644 linux/include/unistd.h create mode 100644 linux/include/utime.h create mode 100644 linux/init/main.c create mode 100644 linux/init/main.o create mode 100644 linux/kernel/Makefile create mode 100644 linux/kernel/asm.o create mode 100644 linux/kernel/asm.s create mode 100644 linux/kernel/blk_drv/Makefile create mode 100644 linux/kernel/blk_drv/blk.h create mode 100644 linux/kernel/blk_drv/blk_drv.a create mode 100644 linux/kernel/blk_drv/floppy.c create mode 100644 linux/kernel/blk_drv/floppy.o create mode 100644 linux/kernel/blk_drv/hd.c create mode 100644 linux/kernel/blk_drv/hd.o create mode 100644 linux/kernel/blk_drv/ll_rw_blk.c create mode 100644 linux/kernel/blk_drv/ll_rw_blk.o create mode 100644 linux/kernel/blk_drv/ramdisk.c create mode 100644 linux/kernel/blk_drv/ramdisk.o create mode 100644 linux/kernel/chr_drv/Makefile create mode 100644 linux/kernel/chr_drv/chr_drv.a create mode 100644 linux/kernel/chr_drv/console.c create mode 100644 linux/kernel/chr_drv/console.o create mode 100644 linux/kernel/chr_drv/keyboard.2.o create mode 100644 linux/kernel/chr_drv/keyboard.2.s create mode 100644 linux/kernel/chr_drv/keyboard.S create mode 100644 linux/kernel/chr_drv/rs_io.o create mode 100644 linux/kernel/chr_drv/rs_io.s create mode 100644 linux/kernel/chr_drv/serial.c create mode 100644 linux/kernel/chr_drv/serial.o create mode 100644 linux/kernel/chr_drv/tty_io.c create mode 100644 linux/kernel/chr_drv/tty_io.o create mode 100644 linux/kernel/chr_drv/tty_ioctl.c create mode 100644 linux/kernel/chr_drv/tty_ioctl.o create mode 100644 linux/kernel/exit.c create mode 100644 linux/kernel/exit.o create mode 100644 linux/kernel/fork.c create mode 100644 linux/kernel/fork.o create mode 100644 linux/kernel/kernel.o create mode 100644 linux/kernel/math/Makefile create mode 100644 linux/kernel/math/math.a create mode 100644 linux/kernel/math/math_emulate.c create mode 100644 linux/kernel/math/math_emulate.o create mode 100644 linux/kernel/mktime.c create mode 100644 linux/kernel/mktime.o create mode 100644 linux/kernel/panic.c create mode 100644 linux/kernel/panic.o create mode 100644 linux/kernel/printk.c create mode 100644 linux/kernel/printk.o create mode 100644 linux/kernel/sched.c create mode 100644 linux/kernel/sched.o create mode 100644 linux/kernel/signal.c create mode 100644 linux/kernel/signal.o create mode 100644 linux/kernel/sys.c create mode 100644 linux/kernel/sys.o create mode 100644 linux/kernel/system_call.o create mode 100644 linux/kernel/system_call.s create mode 100644 linux/kernel/traps.c create mode 100644 linux/kernel/traps.o create mode 100644 linux/kernel/vsprintf.c create mode 100644 linux/kernel/vsprintf.o create mode 100644 linux/lib/Makefile create mode 100644 linux/lib/_exit.c create mode 100644 linux/lib/_exit.o create mode 100644 linux/lib/close.c create mode 100644 linux/lib/close.o create mode 100644 linux/lib/ctype.c create mode 100644 linux/lib/ctype.o create mode 100644 linux/lib/dup.c create mode 100644 linux/lib/dup.o create mode 100644 linux/lib/errno.c create mode 100644 linux/lib/errno.o create mode 100644 linux/lib/execve.c create mode 100644 linux/lib/execve.o create mode 100644 linux/lib/lib.a create mode 100644 linux/lib/malloc.c create mode 100644 linux/lib/malloc.o create mode 100644 linux/lib/open.c create mode 100644 linux/lib/open.o create mode 100644 linux/lib/setsid.c create mode 100644 linux/lib/setsid.o create mode 100644 linux/lib/string.c create mode 100644 linux/lib/string.o create mode 100644 linux/lib/wait.c create mode 100644 linux/lib/wait.o create mode 100644 linux/lib/write.c create mode 100644 linux/lib/write.o create mode 100644 linux/mm/Makefile create mode 100644 linux/mm/memory.c create mode 100644 linux/mm/memory.c.orig create mode 100644 linux/mm/memory.o create mode 100644 linux/mm/mm.o create mode 100644 linux/mm/page.o create mode 100644 linux/mm/page.s create mode 100644 linux/tools/build create mode 100644 linux/tools/build.c create mode 100644 linux/tools/system delete mode 160000 linux_lab_os_exp2 diff --git a/README.md b/README.md deleted file mode 100644 index d8d3c5c..0000000 --- a/README.md +++ /dev/null @@ -1,2 +0,0 @@ -# linux_lab_os_exp2 - diff --git a/linux/.vscode/settings.json b/linux/.vscode/settings.json new file mode 100644 index 0000000..427eac4 --- /dev/null +++ b/linux/.vscode/settings.json @@ -0,0 +1,54 @@ +{ + "files.associations": { + "iostream": "cpp", + "algorithm": "cpp", + "array": "cpp", + "atomic": "cpp", + "*.tcc": "cpp", + "cctype": "cpp", + "clocale": "cpp", + "cmath": "cpp", + "cstdarg": "cpp", + "cstddef": "cpp", + "cstdint": "cpp", + "cstdio": "cpp", + "cstdlib": "cpp", + "ctime": "cpp", + "cwchar": "cpp", + "cwctype": "cpp", + "deque": "cpp", + "unordered_map": "cpp", + "vector": "cpp", + "exception": "cpp", + "memory": "cpp", + "memory_resource": "cpp", + "optional": "cpp", + "string": "cpp", + "string_view": "cpp", + "system_error": "cpp", + "tuple": "cpp", + "type_traits": "cpp", + "utility": "cpp", + "fstream": "cpp", + "initializer_list": "cpp", + "iomanip": "cpp", + "iosfwd": "cpp", + "istream": "cpp", + "limits": "cpp", + "new": "cpp", + "ostream": "cpp", + "sstream": "cpp", + "stdexcept": "cpp", + "streambuf": "cpp", + "typeinfo": "cpp", + "forward_list": "cpp", + "list": "cpp", + "random": "cpp", + "queue": "cpp", + "kernel.h": "c", + "sys.h": "c", + "segment.h": "c", + "stat.h": "c", + "sched.h": "c" + } +} \ No newline at end of file diff --git a/linux/Image b/linux/Image new file mode 100644 index 0000000000000000000000000000000000000000..672d4c978c56614c659914091312258f79cd47b5 GIT binary patch literal 135792 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 literal 0 HcmV?d00001 diff --git a/linux/Image.bkp b/linux/Image.bkp new file mode 100644 index 0000000000000000000000000000000000000000..9869a43badb77318312737429c1972e920db1e68 GIT binary patch literal 131556 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 Cri=yv literal 0 HcmV?d00001 diff --git a/linux/Makefile b/linux/Makefile new file mode 100644 index 0000000..ecbcf30 --- /dev/null +++ b/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/linux/System.map b/linux/System.map new file mode 100644 index 0000000..2687f12 --- /dev/null +++ b/linux/System.map @@ -0,0 +1,591 @@ +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 +00006bd4 T show_task +00006c59 T show_stat +00006c9f T math_state_restore +00006cfd T schedule +00006eaf T sys_pause +00006ec5 T sleep_on +00006f24 T interruptible_sleep_on +00006fdf T ticks_to_floppy_on +000070aa T floppy_on +000070d9 T floppy_off +000070e9 T do_floppy_timer +000072e1 T do_timer +000073d0 T sys_alarm +0000744f T sys_getpid +0000745b T sys_getppid +00007467 T sys_getuid +00007476 T sys_geteuid +00007486 T sys_getgid +00007496 T sys_getegid +000074a5 T sys_nice +000074d0 T sched_init +00007660 t bad_sys_call +00007668 t reschedule +00007674 T system_call +000076af t ret_from_sys_call +000076f8 T coprocessor_error +0000771a T device_not_available +00007754 T timer_interrupt +0000778c T sys_execve +0000779c T sys_execve2 +000077ac T sys_fork +000077c4 T hd_interrupt +00007800 T floppy_interrupt +00007836 T parallel_interrupt +0000783d t _get_base +0000786f t die +00007a51 T do_double_fault +00007a74 T do_general_protection +00007a97 T do_divide_error +00007aba T do_int3 +00007b82 T do_nmi +00007ba5 T do_debug +00007bc8 T do_overflow +00007beb T do_bounds +00007c0e T do_invalid_op +00007c31 T do_device_not_available +00007c54 T do_coprocessor_segment_overrun +00007c77 T do_invalid_TSS +00007c9a T do_segment_not_present +00007cbd T do_stack_segment +00007ce0 T do_coprocessor_error +00007d14 T do_reserved +00007d37 T trap_init +0000801b T divide_error +00008020 t no_error_code +00008050 T debug +00008057 T nmi +0000805e T int3 +00008065 T overflow +0000806c T bounds +00008073 T invalid_op +0000807a T coprocessor_segment_overrun +00008081 T reserved +00008088 T irq13 +0000809d T double_fault +000080a2 t error_code +000080d4 T invalid_TSS +000080db T segment_not_present +000080e2 T stack_segment +000080e9 T general_protection +000080f0 t _get_base +00008122 T verify_area +00008189 T copy_mem +000082e3 T copy_process +00008790 T find_empty_process +00008824 T panic +0000885f T printk +000088b0 t skip_atoi +0000890b t number +00008b7c T vsprintf +00009008 t get_fs_long +0000901e t put_fs_byte +00009036 t put_fs_long +00009042 T sys_getcwd +000094e6 T sys_getdents +00009777 T sys_pipe2 +0000977d T sys_sleep +00009833 T sys_mmap +00009839 T sys_munmap +0000983f T sys_clone +00009845 T sys_ftime +0000984b T sys_break +00009851 T sys_ptrace +00009857 T sys_stty +0000985d T sys_gtty +00009863 T sys_rename +00009869 T sys_prof +0000986f T sys_setregid +00009928 T sys_setgid +000099bf T sys_acct +000099c5 T sys_phys +000099cb T sys_lock +000099d1 T sys_mpx +000099d7 T sys_ulimit +000099dd T sys_time +00009a39 T sys_setreuid +00009b1b T sys_setuid +00009bb0 T sys_stime +00009c06 T sys_times +00009ca6 T sys_brk +00009ce8 T sys_setpgid +00009dc1 T sys_getpgrp +00009dcd T sys_setsid +00009e47 T sys_getgroups +00009e4d T sys_setgroups +00009e53 T sys_uname +00009ebc T sys_sethostname +00009ec2 T sys_getrlimit +00009ec8 T sys_setrlimit +00009ece T sys_getrusage +00009ed4 T sys_gettimeofday +00009eda T sys_settimeofday +00009ee0 T sys_umask +00009f13 t _get_base +00009f45 t put_fs_long +00009f51 T release +00009fb5 t send_sig +0000a034 t kill_session +0000a08e T sys_kill +0000a23e t tell_father +0000a2c8 T do_exit +0000a4fc T sys_exit +0000a515 T sys_waitpid +0000a73b t get_fs_byte +0000a749 t put_fs_byte +0000a761 t put_fs_long +0000a76d T sys_sgetmask +0000a779 T sys_ssetmask +0000a7a5 T sys_sigpending +0000a7ab T sys_sigsuspend +0000a7b1 t save_old +0000a804 t get_new +0000a844 T sys_signal +0000a8c8 T sys_sigaction +0000a9d2 T do_signal +0000abbe T kernel_mktime +0000ad03 t oom +0000ad22 T get_free_page +0000ad5e T free_page +0000adcd T free_page_tables +0000aecc T copy_page_tables +0000b04d T put_page +0000b139 T un_wp_page +0000b1f1 T do_wp_page +0000b27c T get_empty_page +0000b2bc t try_to_share +0000b44e t share_page +0000b502 T do_no_page +0000b664 T mem_init +0000b6d8 T do_execve2 +0000b852 T calc_mem +0000b947 T page_fault +0000b97e t get_fs_long +0000b994 T sys_ustat +0000b99a T sys_utime +0000ba47 T sys_access +0000bb23 T sys_chdir +0000bb97 T sys_chroot +0000bc0b T sys_chmod +0000bca5 T sys_chown +0000bd20 T sys_open +0000bfc3 T sys_creat +0000bfe6 T sys_close +0000c0b5 T sys_lseek +0000c1cc T sys_read +0000c3bf T sys_write +0000c56d t lock_inode +0000c59a t unlock_inode +0000c5b8 T invalidate_inodes +0000c627 T sync_inodes +0000c67e t _bmap +0000ca6a T bmap +0000ca8d T create_block +0000cab0 T iput +0000cc1f T get_empty_inode +0000cd74 T get_pipe_inode +0000cde9 T iget +0000cfae t read_inode +0000d1e4 T sys_sync +0000d247 T sync_dev +0000d340 T invalidate_buffers +0000d3b2 T check_disk_change +0000d45c t remove_from_queues +0000d553 t insert_into_queues +0000d618 t find_buffer +0000d680 T get_hash_table +0000d702 T getblk +0000d8a0 T brelse +0000d8e9 T bread +0000d96e T bread_page +0000da90 T breada +0000db85 T buffer_init +0000dcb4 t lock_super +0000dce1 t free_super +0000dd26 T get_super +0000dd95 T put_super +0000de68 t read_super +0000e1ab T sys_umount +0000e30c T sys_mount +0000e47d T mount_root +0000e68b t get_fs_byte +0000e699 t put_fs_byte +0000e6b1 T block_write +0000e803 T block_read +0000e92e t get_fs_byte +0000e93c t put_fs_byte +0000e954 t rw_ttyx +0000e99c t rw_tty +0000e9ec t rw_ram +0000e9f2 t rw_mem +0000e9f8 t rw_kmem +0000e9fe t rw_port +0000ea98 t rw_memory +0000eb6e T rw_char +0000ebd8 t get_fs_byte +0000ebe6 t put_fs_byte +0000ebfe T file_read +0000eda9 T file_write +0000efa3 t put_fs_byte +0000efbb t cp_stat +0000f092 T sys_stat +0000f0dc T sys_lstat +0000f0f7 T sys_fstat +0000f154 T sys_readlink +0000f15a t _get_base +0000f18c t get_fs_byte +0000f19a t get_fs_long +0000f1b0 t put_fs_byte +0000f1c8 t put_fs_long +0000f1d4 t get_fs +0000f1e8 t get_ds +0000f1fc t set_fs +0000f203 T sys_uselib +0000f209 t create_tables +0000f354 t count +0000f393 t copy_strings +0000f54f t change_ldt +0000f6d2 T do_execve +000101f7 t get_fs_byte +00010205 t put_fs_byte +0001021d t put_fs_long +00010229 T read_pipe +000104fe T sys_pipe +00010700 t get_fs_byte +0001070e t permission +000107af t match +00010817 t find_entry +00010c71 t get_dir +00010e5e t dir_namei +00010edd T namei +00010ff3 T open_namei +00011346 T sys_mknod +00011576 T sys_mkdir +00011927 t empty_dir +00011b05 T sys_rmdir +00011e5d T sys_unlink +000120fe T sys_symlink +00012104 T sys_link +0001235e T free_block +000124d0 T new_block +00012674 T free_inode +000127db T new_inode +000129b5 t dupfd +00012a8f T sys_dup2 +00012ab6 T sys_dup +00012ad1 T sys_fcntl +00012c10 T sys_ioctl +00012ce1 t free_ind +00012d80 t free_dind +00012e1f T truncate +00012f54 T sys_select +00012f5a t lock_buffer +00012f87 t unlock_buffer +00013179 t make_request +0001331d T ll_rw_block +00013376 T blk_dev_init +000133c4 t unlock_buffer +000133f9 t end_request +000134aa T floppy_deselect +000134e1 T floppy_change +00013567 t setup_DMA +0001361d t output_byte +00013693 t result +00013750 t bad_flp_intr +000137af t rw_interrupt +0001389e T setup_rw_floppy +0001395f t seek_interrupt +000139b8 t transfer +00013aed t recal_interrupt +00013b37 T unexpected_floppy_interrupt +00013b7c t recalibrate_floppy +00013bde t reset_interrupt +00013c23 t reset_floppy +00013ca0 t floppy_on_interrupt +00013d0b t do_fd_request +00013f0f T floppy_init +00013f61 t unlock_buffer +00013f96 t end_request +00014035 T sys_setup +000143e8 t controller_ready +0001447c t hd_out +00014569 t drive_busy +000145cf t reset_controller +0001464c t reset_hd +000146e4 T unexpected_hd_interrupt +000146f7 t bad_rw_intr +00014735 t read_intr +0001485b t recal_intr +00014875 t do_hd_request +00014b76 T hd_init +00014bf0 t unlock_buffer +00014c25 t end_request +00014cc4 t do_rd_request +00014dfa T rd_init +00014e50 T rd_load +000150fc t get_fs_byte +0001510a t put_fs_byte +00015122 T tty_init +00015133 T tty_intr +000151a7 t sleep_if_empty +000151df t sleep_if_full +00015253 T copy_to_cooked +0001580e T tty_read +00015b7c T tty_write +00015d8e T do_tty_interrupt +00015db6 T chr_dev_init +00015db7 t gotoxy +00015e05 t set_origin +00015e6b t scrup +0001605b t scrdown +00016152 t lf +00016188 t ri +000161be t cr +000161df t del +00016211 t csi_J +000162a2 t csi_K +00016354 T csi_m +000163bb t set_cursor +00016421 t respond +00016479 t insert_char +000164dc t insert_line +00016520 t delete_char +0001657e t delete_line +000165c2 t csi_at +00016600 t csi_L +0001663e t csi_P +0001667c t csi_M +000166ba t save_cur +000166cf t restore_cur +000166ee T con_write +00016d7c T con_init +00016fb3 T sysbeepstop +00016fdc t sysbeep +0001703a t mode +0001703b t leds +0001703c t e0 +0001703d T keyboard_interrupt +00017066 t e0_e1 +00017091 t set_e0 +0001709a t set_e1 +000170a3 t put_queue +000170dc t ctrl +000170f4 t unctrl +000170f8 t unalt +0001710e t lshift +00017116 t unlshift +0001711e t rshift +00017126 t unrshift +0001712e t caps +00017150 t set_leds +00017166 t uncaps +0001716e t scroll +00017177 t num +00017180 t cursor +000171a0 t cur2 +000171c9 t cur +000171d5 t ok_cur +000171e3 t num_table +000171f0 t cur_table +000171fd t func +0001721a t ok_func +0001722d t end_func +0001722e t func_table +0001725e t key_map +000172bf t shift_map +00017381 t do_self +000173e9 t none +000173ea t minus +000173ff t key_table +000177ff t kb_wait +00017808 t reboot +0001781a t die +0001781c t init +00017891 T rs_init +00017914 T rs_write +00017964 T rs1_interrupt +0001796c T rs2_interrupt +00017971 t rs_int +00017988 t rep_int +000179a5 t end +000179b3 t jmp_table +000179c4 t modem_status +000179cc t line_status +000179d4 t read_char +00017a5b t get_fs_byte +00017a69 t get_fs_long +00017a7f t put_fs_byte +00017a97 t put_fs_long +00017aa3 t change_speed +00017b21 t flush +00017b33 t send_break +00017b34 t get_termios +00017b90 t set_termios +00017be0 t get_termio +00017ca8 t set_termio +00017d6c T tty_ioctl +0001806a t get_fs_byte +00018078 T math_emulate +0001815b T math_error +0001817b T _exit +0001818b T open +000181d4 T close +00018248 T dup +0001827f T setsid +000182ae T execve +0001834b T strcpy +00018367 T strncpy +0001838c T strcat +000183b7 T strncat +000183ec T strcmp +00018413 T strncmp +00018441 T strchr +0001846e T strrchr +0001849d T strspn +000184da T strcspn +00018517 T strpbrk +0001854e T strstr +00018587 T strlen +000185aa T strtok +0001862d T memcpy +0001864d T memmove +000186a1 T memcmp +000186cb T memchr +00018703 T memset +00018727 t init_bucket_desc +00018790 T malloc +0001891c T free_s +0001cb48 d envp_rc +0001cb5c d envp +0001cb80 D sys_call_table +0001ccfc D NR_syscalls +0001cd00 d init_task +0001dd00 D current +0001dd20 D task +0001de20 D stack_start +0001de28 D current_DOR +0001de40 d thisname.2345 +0001de80 d month +0001dec0 d last_inode.1935 +0001dec4 D start_buffer +0001dee0 d crw_table +0001df00 d ioctl_table +0001df20 d floppy_type +0001dfe0 d cur_spec1 +0001dfe4 d cur_rate +0001dfe8 d floppy +0001dfec d current_track +0001dff0 d callable.1844 +0001e000 D tty_table +00020520 D table_list +00020540 d quotient +00020560 D _ctype +00020680 D bucket_dir +000206d0 B __bss_start +000206d0 D _edata +000206e0 b printbuf +00020ae0 b memory_end +00020ae4 b buffer_memory_end +00020ae8 b main_memory_start +00020b00 B jiffies +00020b04 B startup_time +00020b08 B last_task_used_math +00020b1c b mon_timer +00020b2c b moff_timer +00020b40 b timer_list +00020e40 b next_timer +00020e44 B last_pid +00020e60 b buf +00021260 b HIGH_MEMORY +00021280 b mem_map +00022180 B inode_table +00022880 B nr_buffers +00022884 b free_list +00022888 b buffer_wait +0002288c B ROOT_DEV +000228c0 B blk_dev +000228f8 B do_floppy +000228fc B selected +00022904 b recalibrate +00022908 b reset +0002290c b seek +00022910 b reply_buffer +00022917 b current_drive +00022918 b sector +00022919 b head +0002291a b track +0002291b b seek_track +0002291c b command +00022920 B do_hd +00022940 B hd_info +00022970 b recalibrate +00022974 b reset +00022978 b NR_HD +00022980 b hd +000229d0 B rd_length +000229d4 b cr_flag.1923 +000229e0 B beepcount +000229e4 b video_type +000229e8 b video_num_columns +000229ec b video_size_row +000229f0 b video_num_lines +000229f4 b video_page +000229f8 b video_mem_start +000229fc b video_mem_end +00022a00 b video_port_reg +00022a02 b video_port_val +00022a04 b video_erase_char +00022a08 b origin +00022a0c b scr_end +00022a10 b pos +00022a14 b x +00022a18 b y +00022a1c b top +00022a20 b bottom +00022a24 b state +00022a28 b npar +00022a40 b par +00022a80 b ques +00022a84 b saved_x +00022a88 b saved_y +00022a8c B free_bucket_desc +00022aa0 B drive_info +00022ac0 B user_stack +00023ac0 B hash_table +00023fa0 B super_block +00024300 B file_table +00024700 B request +00024b80 B rd_start +00024b84 B _ctmp +00024b88 B errno +00024b8c B ___strtok +00024b90 B end +00024b90 B _end diff --git a/linux/System.map.2 b/linux/System.map.2 new file mode 100644 index 0000000..447337a --- /dev/null +++ b/linux/System.map.2 @@ -0,0 +1,1107 @@ +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 (strcpy) +lib/lib.a(malloc.o) kernel/kernel.o (malloc) + +分配公共符号 +公共符号 大小 文件 + +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) + .note.GNU-stack + 0x0000000000000000 0x0 lib/lib.a(malloc.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 0x18a93 + *(.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 0x714 init/main.o + 0x00000000000064c0 fork + 0x00000000000064ef pause + 0x000000000000651e setup + 0x0000000000006555 sync + 0x0000000000006799 main + 0x000000000000695b init + 0x0000000000006bd3 print_nr + .text 0x0000000000006bd4 0x412f kernel/kernel.o + 0x0000000000006bd4 show_task + 0x0000000000006c59 show_stat + 0x0000000000006c9f math_state_restore + 0x0000000000006cfd schedule + 0x0000000000006eaf sys_pause + 0x0000000000006ec5 sleep_on + 0x0000000000006f24 interruptible_sleep_on + 0x0000000000006fb7 wake_up + 0x0000000000006fdf ticks_to_floppy_on + 0x00000000000070aa floppy_on + 0x00000000000070d9 floppy_off + 0x00000000000070e9 do_floppy_timer + 0x00000000000071bd add_timer + 0x00000000000072e1 do_timer + 0x00000000000073d0 sys_alarm + 0x000000000000744f sys_getpid + 0x000000000000745b sys_getppid + 0x0000000000007467 sys_getuid + 0x0000000000007476 sys_geteuid + 0x0000000000007486 sys_getgid + 0x0000000000007496 sys_getegid + 0x00000000000074a5 sys_nice + 0x00000000000074d0 sched_init + 0x0000000000007674 system_call + 0x00000000000076f8 coprocessor_error + 0x000000000000771a device_not_available + 0x0000000000007754 timer_interrupt + 0x000000000000778c sys_execve + 0x000000000000779c sys_execve2 + 0x00000000000077ac sys_fork + 0x00000000000077c4 hd_interrupt + 0x0000000000007800 floppy_interrupt + 0x0000000000007836 parallel_interrupt + 0x0000000000007a51 do_double_fault + 0x0000000000007a74 do_general_protection + 0x0000000000007a97 do_divide_error + 0x0000000000007aba do_int3 + 0x0000000000007b82 do_nmi + 0x0000000000007ba5 do_debug + 0x0000000000007bc8 do_overflow + 0x0000000000007beb do_bounds + 0x0000000000007c0e do_invalid_op + 0x0000000000007c31 do_device_not_available + 0x0000000000007c54 do_coprocessor_segment_overrun + 0x0000000000007c77 do_invalid_TSS + 0x0000000000007c9a do_segment_not_present + 0x0000000000007cbd do_stack_segment + 0x0000000000007ce0 do_coprocessor_error + 0x0000000000007d14 do_reserved + 0x0000000000007d37 trap_init + 0x000000000000801b divide_error + 0x0000000000008050 debug + 0x0000000000008057 nmi + 0x000000000000805e int3 + 0x0000000000008065 overflow + 0x000000000000806c bounds + 0x0000000000008073 invalid_op + 0x000000000000807a coprocessor_segment_overrun + 0x0000000000008081 reserved + 0x0000000000008088 irq13 + 0x000000000000809d double_fault + 0x00000000000080d4 invalid_TSS + 0x00000000000080db segment_not_present + 0x00000000000080e2 stack_segment + 0x00000000000080e9 general_protection + 0x0000000000008122 verify_area + 0x0000000000008189 copy_mem + 0x00000000000082e3 copy_process + 0x0000000000008790 find_empty_process + 0x0000000000008824 panic + 0x000000000000885f printk + 0x0000000000008b7c vsprintf + 0x0000000000009042 sys_getcwd + 0x00000000000094e6 sys_getdents + 0x0000000000009777 sys_pipe2 + 0x000000000000977d sys_sleep + 0x0000000000009833 sys_mmap + 0x0000000000009839 sys_munmap + 0x000000000000983f sys_clone + 0x0000000000009845 sys_ftime + 0x000000000000984b sys_break + 0x0000000000009851 sys_ptrace + 0x0000000000009857 sys_stty + 0x000000000000985d sys_gtty + 0x0000000000009863 sys_rename + 0x0000000000009869 sys_prof + 0x000000000000986f sys_setregid + 0x0000000000009928 sys_setgid + 0x00000000000099bf sys_acct + 0x00000000000099c5 sys_phys + 0x00000000000099cb sys_lock + 0x00000000000099d1 sys_mpx + 0x00000000000099d7 sys_ulimit + 0x00000000000099dd sys_time + 0x0000000000009a39 sys_setreuid + 0x0000000000009b1b sys_setuid + 0x0000000000009bb0 sys_stime + 0x0000000000009c06 sys_times + 0x0000000000009ca6 sys_brk + 0x0000000000009ce8 sys_setpgid + 0x0000000000009dc1 sys_getpgrp + 0x0000000000009dcd sys_setsid + 0x0000000000009e47 sys_getgroups + 0x0000000000009e4d sys_setgroups + 0x0000000000009e53 sys_uname + 0x0000000000009ebc sys_sethostname + 0x0000000000009ec2 sys_getrlimit + 0x0000000000009ec8 sys_setrlimit + 0x0000000000009ece sys_getrusage + 0x0000000000009ed4 sys_gettimeofday + 0x0000000000009eda sys_settimeofday + 0x0000000000009ee0 sys_umask + 0x0000000000009f51 release + 0x000000000000a08e sys_kill + 0x000000000000a2c8 do_exit + 0x000000000000a4fc sys_exit + 0x000000000000a515 sys_waitpid + 0x000000000000a76d sys_sgetmask + 0x000000000000a779 sys_ssetmask + 0x000000000000a7a5 sys_sigpending + 0x000000000000a7ab sys_sigsuspend + 0x000000000000a844 sys_signal + 0x000000000000a8c8 sys_sigaction + 0x000000000000a9d2 do_signal + 0x000000000000abbe kernel_mktime + .text 0x000000000000ad03 0xc7b mm/mm.o + 0x000000000000ad22 get_free_page + 0x000000000000ad5e free_page + 0x000000000000adcd free_page_tables + 0x000000000000aecc copy_page_tables + 0x000000000000b04d put_page + 0x000000000000b139 un_wp_page + 0x000000000000b1f1 do_wp_page + 0x000000000000b223 write_verify + 0x000000000000b27c get_empty_page + 0x000000000000b502 do_no_page + 0x000000000000b664 mem_init + 0x000000000000b6d8 do_execve2 + 0x000000000000b852 calc_mem + 0x000000000000b947 page_fault + .text 0x000000000000b97e 0x75dc fs/fs.o + 0x000000000000b994 sys_ustat + 0x000000000000b99a sys_utime + 0x000000000000ba47 sys_access + 0x000000000000bb23 sys_chdir + 0x000000000000bb97 sys_chroot + 0x000000000000bc0b sys_chmod + 0x000000000000bca5 sys_chown + 0x000000000000bd20 sys_open + 0x000000000000bfc3 sys_creat + 0x000000000000bfe6 sys_close + 0x000000000000c0b5 sys_lseek + 0x000000000000c1cc sys_read + 0x000000000000c3bf sys_write + 0x000000000000c5b8 invalidate_inodes + 0x000000000000c627 sync_inodes + 0x000000000000ca6a bmap + 0x000000000000ca8d create_block + 0x000000000000cab0 iput + 0x000000000000cc1f get_empty_inode + 0x000000000000cd74 get_pipe_inode + 0x000000000000cde9 iget + 0x000000000000d1e4 sys_sync + 0x000000000000d247 sync_dev + 0x000000000000d340 invalidate_buffers + 0x000000000000d3b2 check_disk_change + 0x000000000000d680 get_hash_table + 0x000000000000d702 getblk + 0x000000000000d8a0 brelse + 0x000000000000d8e9 bread + 0x000000000000d96e bread_page + 0x000000000000da90 breada + 0x000000000000db85 buffer_init + 0x000000000000dd26 get_super + 0x000000000000dd95 put_super + 0x000000000000e1ab sys_umount + 0x000000000000e30c sys_mount + 0x000000000000e47d mount_root + 0x000000000000e6b1 block_write + 0x000000000000e803 block_read + 0x000000000000eb6e rw_char + 0x000000000000ebfe file_read + 0x000000000000eda9 file_write + 0x000000000000f092 sys_stat + 0x000000000000f0dc sys_lstat + 0x000000000000f0f7 sys_fstat + 0x000000000000f154 sys_readlink + 0x000000000000f203 sys_uselib + 0x000000000000f6d2 do_execve + 0x0000000000010229 read_pipe + 0x000000000001037f write_pipe + 0x00000000000104fe sys_pipe + 0x0000000000010edd namei + 0x0000000000010ff3 open_namei + 0x0000000000011346 sys_mknod + 0x0000000000011576 sys_mkdir + 0x0000000000011b05 sys_rmdir + 0x0000000000011e5d sys_unlink + 0x00000000000120fe sys_symlink + 0x0000000000012104 sys_link + 0x000000000001235e free_block + 0x00000000000124d0 new_block + 0x0000000000012674 free_inode + 0x00000000000127db new_inode + 0x0000000000012a8f sys_dup2 + 0x0000000000012ab6 sys_dup + 0x0000000000012ad1 sys_fcntl + 0x0000000000012c10 sys_ioctl + 0x0000000000012e1f truncate + 0x0000000000012f54 sys_select + .text 0x0000000000012f5a 0x46a kernel/blk_drv/blk_drv.a(ll_rw_blk.o) + 0x000000000001331d ll_rw_block + 0x0000000000013376 blk_dev_init + .text 0x00000000000133c4 0xb9d kernel/blk_drv/blk_drv.a(floppy.o) + 0x00000000000134aa floppy_deselect + 0x00000000000134e1 floppy_change + 0x000000000001389e setup_rw_floppy + 0x0000000000013b37 unexpected_floppy_interrupt + 0x0000000000013f0f floppy_init + .text 0x0000000000013f61 0xc8f kernel/blk_drv/blk_drv.a(hd.o) + 0x0000000000014035 sys_setup + 0x00000000000146e4 unexpected_hd_interrupt + 0x0000000000014b76 hd_init + .text 0x0000000000014bf0 0x50c kernel/blk_drv/blk_drv.a(ramdisk.o) + 0x0000000000014dfa rd_init + 0x0000000000014e50 rd_load + .text 0x00000000000150fc 0xcbb kernel/chr_drv/chr_drv.a(tty_io.o) + 0x0000000000015122 tty_init + 0x0000000000015133 tty_intr + 0x0000000000015240 wait_for_keypress + 0x0000000000015253 copy_to_cooked + 0x000000000001580e tty_read + 0x0000000000015b7c tty_write + 0x0000000000015d8e do_tty_interrupt + 0x0000000000015db6 chr_dev_init + .text 0x0000000000015db7 0x1283 kernel/chr_drv/chr_drv.a(console.o) + 0x0000000000016354 csi_m + 0x00000000000166ee con_write + 0x0000000000016d7c con_init + 0x0000000000016fb3 sysbeepstop + .text 0x000000000001703a 0x7e2 kernel/chr_drv/chr_drv.a(keyboard.2.o) + 0x000000000001703d keyboard_interrupt + .text 0x000000000001781c 0x145 kernel/chr_drv/chr_drv.a(serial.o) + 0x0000000000017891 rs_init + 0x0000000000017914 rs_write + *fill* 0x0000000000017961 0x3 + .text 0x0000000000017964 0xf7 kernel/chr_drv/chr_drv.a(rs_io.o) + 0x0000000000017964 rs1_interrupt + 0x000000000001796c rs2_interrupt + .text 0x0000000000017a5b 0x60f kernel/chr_drv/chr_drv.a(tty_ioctl.o) + 0x0000000000017d6c tty_ioctl + .text 0x000000000001806a 0x111 kernel/math/math.a(math_emulate.o) + 0x0000000000018078 math_emulate + 0x000000000001815b math_error + .text 0x000000000001817b 0x0 lib/lib.a(ctype.o) + .text 0x000000000001817b 0x10 lib/lib.a(_exit.o) + 0x000000000001817b _exit + .text 0x000000000001818b 0x49 lib/lib.a(open.o) + 0x000000000001818b open + .text 0x00000000000181d4 0x37 lib/lib.a(close.o) + 0x00000000000181d4 close + .text 0x000000000001820b 0x0 lib/lib.a(errno.o) + .text 0x000000000001820b 0x3d lib/lib.a(write.o) + 0x000000000001820b write + .text 0x0000000000018248 0x37 lib/lib.a(dup.o) + 0x0000000000018248 dup + .text 0x000000000001827f 0x2f lib/lib.a(setsid.o) + 0x000000000001827f setsid + .text 0x00000000000182ae 0x3d lib/lib.a(execve.o) + 0x00000000000182ae execve + .text 0x00000000000182eb 0x60 lib/lib.a(wait.o) + 0x00000000000182eb waitpid + 0x0000000000018328 wait + .text 0x000000000001834b 0x3dc lib/lib.a(string.o) + 0x000000000001834b strcpy + 0x0000000000018367 strncpy + 0x000000000001838c strcat + 0x00000000000183b7 strncat + 0x00000000000183ec strcmp + 0x0000000000018413 strncmp + 0x0000000000018441 strchr + 0x000000000001846e strrchr + 0x000000000001849d strspn + 0x00000000000184da strcspn + 0x0000000000018517 strpbrk + 0x000000000001854e strstr + 0x0000000000018587 strlen + 0x00000000000185aa strtok + 0x000000000001862d memcpy + 0x000000000001864d memmove + 0x00000000000186a1 memcmp + 0x00000000000186cb memchr + 0x0000000000018703 memset + .text 0x0000000000018727 0x36c lib/lib.a(malloc.o) + 0x0000000000018790 malloc + 0x000000000001891c free_s + *(.gnu.warning) + +.fini + *(SORT(.fini)) + 0x0000000000018a93 PROVIDE (__etext, .) + 0x0000000000018a93 PROVIDE (_etext, .) + 0x0000000000018a93 PROVIDE (etext, .) + +.rodata 0x0000000000018a94 0x14ef + *(.rodata .rodata.* .gnu.linkonce.r.*) + .rodata 0x0000000000018a94 0xad init/main.o + *fill* 0x0000000000018b41 0x3 + .rodata 0x0000000000018b44 0x438 kernel/kernel.o + .rodata 0x0000000000018f7c 0x18f mm/mm.o + *fill* 0x000000000001910b 0x1 + .rodata 0x000000000001910c 0x67c fs/fs.o + .rodata 0x0000000000019788 0x7a kernel/blk_drv/blk_drv.a(ll_rw_blk.o) + *fill* 0x0000000000019802 0x2 + .rodata 0x0000000000019804 0x133 kernel/blk_drv/blk_drv.a(floppy.o) + *fill* 0x0000000000019937 0x1 + .rodata 0x0000000000019938 0x19b kernel/blk_drv/blk_drv.a(hd.o) + *fill* 0x0000000000019ad3 0x1 + .rodata 0x0000000000019ad4 0x188 kernel/blk_drv/blk_drv.a(ramdisk.o) + .rodata 0x0000000000019c5c 0x17d kernel/chr_drv/chr_drv.a(console.o) + *fill* 0x0000000000019dd9 0x3 + .rodata 0x0000000000019ddc 0x80 kernel/chr_drv/chr_drv.a(tty_ioctl.o) + .rodata 0x0000000000019e5c 0x52 kernel/math/math.a(math_emulate.o) + *fill* 0x0000000000019eae 0x2 + .rodata 0x0000000000019eb0 0xd3 lib/lib.a(malloc.o) + +.rodata1 + *(.rodata1) + +.eh_frame_hdr + *(.eh_frame_hdr) + +.eh_frame 0x0000000000019f84 0x2bb0 + *(.eh_frame) + .eh_frame 0x0000000000019f84 0x104 init/main.o + .eh_frame 0x000000000001a088 0xbc8 kernel/kernel.o + 0xcb8 (size before relaxing) + .eh_frame 0x000000000001ac50 0x1b0 mm/mm.o + 0x1c8 (size before relaxing) + .eh_frame 0x000000000001ae00 0xdd8 fs/fs.o + 0xf70 (size before relaxing) + .eh_frame 0x000000000001bbd8 0x98 kernel/blk_drv/blk_drv.a(ll_rw_blk.o) + 0xb0 (size before relaxing) + .eh_frame 0x000000000001bc70 0x23c kernel/blk_drv/blk_drv.a(floppy.o) + 0x254 (size before relaxing) + .eh_frame 0x000000000001beac 0x1e8 kernel/blk_drv/blk_drv.a(hd.o) + 0x200 (size before relaxing) + .eh_frame 0x000000000001c094 0xac kernel/blk_drv/blk_drv.a(ramdisk.o) + 0xc4 (size before relaxing) + .eh_frame 0x000000000001c140 0x12c kernel/chr_drv/chr_drv.a(tty_io.o) + 0x144 (size before relaxing) + .eh_frame 0x000000000001c26c 0x2c0 kernel/chr_drv/chr_drv.a(console.o) + 0x2d8 (size before relaxing) + .eh_frame 0x000000000001c52c 0x54 kernel/chr_drv/chr_drv.a(serial.o) + 0x6c (size before relaxing) + .eh_frame 0x000000000001c580 0x148 kernel/chr_drv/chr_drv.a(tty_ioctl.o) + 0x160 (size before relaxing) + .eh_frame 0x000000000001c6c8 0x5c kernel/math/math.a(math_emulate.o) + 0x74 (size before relaxing) + .eh_frame 0x000000000001c724 0x1c lib/lib.a(_exit.o) + 0x34 (size before relaxing) + .eh_frame 0x000000000001c740 0x24 lib/lib.a(open.o) + 0x3c (size before relaxing) + .eh_frame 0x000000000001c764 0x20 lib/lib.a(close.o) + 0x38 (size before relaxing) + .eh_frame 0x000000000001c784 0x20 lib/lib.a(write.o) + 0x38 (size before relaxing) + .eh_frame 0x000000000001c7a4 0x20 lib/lib.a(dup.o) + 0x38 (size before relaxing) + .eh_frame 0x000000000001c7c4 0x18 lib/lib.a(setsid.o) + 0x30 (size before relaxing) + .eh_frame 0x000000000001c7dc 0x20 lib/lib.a(execve.o) + 0x38 (size before relaxing) + .eh_frame 0x000000000001c7fc 0x38 lib/lib.a(wait.o) + 0x50 (size before relaxing) + .eh_frame 0x000000000001c834 0x2b0 lib/lib.a(string.o) + 0x2c8 (size before relaxing) + .eh_frame 0x000000000001cae4 0x50 lib/lib.a(malloc.o) + 0x68 (size before relaxing) + +.gcc_except_table + *(.gcc_except_table .gcc_except_table.*) + +.exception_ranges + *(.exception_ranges .exception_ranges*) + 0x000000000001cb34 . = . + +.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 0x000000000001cb34 0x0 + 0x000000000001cb34 PROVIDE (__preinit_array_start, .) + *(.preinit_array) + 0x000000000001cb34 PROVIDE (__preinit_array_end, .) + +.init_array 0x000000000001cb34 0x0 + 0x000000000001cb34 PROVIDE (__init_array_start, .) + *(SORT(.init_array.*) SORT(.ctors.*)) + *(.init_array EXCLUDE_FILE(*crtend?.o *crtend.o *crtbegin?.o *crtbegin.o) .ctors) + 0x000000000001cb34 PROVIDE (__init_array_end, .) + +.fini_array 0x000000000001cb34 0x0 + 0x000000000001cb34 PROVIDE (__fini_array_start, .) + *(SORT(.fini_array.*) SORT(.dtors.*)) + *(.fini_array EXCLUDE_FILE(*crtend?.o *crtend.o *crtbegin?.o *crtbegin.o) .dtors) + 0x000000000001cb34 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 0x000000000001cb34 0x0 + *(.got.plt) + *(.igot.plt) + .igot.plt 0x0000000000000000 0x0 boot/head.o + +.data 0x000000000001cb40 0x3b90 + *(.data .data.* .gnu.linkonce.d.*) + .data 0x000000000001cb40 0x0 boot/head.o + .data 0x000000000001cb40 0x28 init/main.o + *fill* 0x000000000001cb68 0x18 + .data 0x000000000001cb80 0x1330 kernel/kernel.o + 0x000000000001cb80 sys_call_table + 0x000000000001ccfc NR_syscalls + 0x000000000001dd00 current + 0x000000000001dd20 task + 0x000000000001de20 stack_start + 0x000000000001de28 current_DOR + .data 0x000000000001deb0 0x0 mm/mm.o + *fill* 0x000000000001deb0 0x10 + .data 0x000000000001dec0 0x60 fs/fs.o + 0x000000000001dec4 start_buffer + .data 0x000000000001df20 0x0 kernel/blk_drv/blk_drv.a(ll_rw_blk.o) + .data 0x000000000001df20 0xcd kernel/blk_drv/blk_drv.a(floppy.o) + *fill* 0x000000000001dfed 0x3 + .data 0x000000000001dff0 0x4 kernel/blk_drv/blk_drv.a(hd.o) + .data 0x000000000001dff4 0x0 kernel/blk_drv/blk_drv.a(ramdisk.o) + *fill* 0x000000000001dff4 0xc + .data 0x000000000001e000 0x2538 kernel/chr_drv/chr_drv.a(tty_io.o) + 0x000000000001e000 tty_table + 0x0000000000020520 table_list + .data 0x0000000000020538 0x1 kernel/chr_drv/chr_drv.a(console.o) + .data 0x0000000000020539 0x0 kernel/chr_drv/chr_drv.a(keyboard.2.o) + .data 0x0000000000020539 0x0 kernel/chr_drv/chr_drv.a(serial.o) + .data 0x0000000000020539 0x0 kernel/chr_drv/chr_drv.a(rs_io.o) + *fill* 0x0000000000020539 0x7 + .data 0x0000000000020540 0x20 kernel/chr_drv/chr_drv.a(tty_ioctl.o) + .data 0x0000000000020560 0x0 kernel/math/math.a(math_emulate.o) + .data 0x0000000000020560 0x101 lib/lib.a(ctype.o) + 0x0000000000020560 _ctype + .data 0x0000000000020661 0x0 lib/lib.a(_exit.o) + .data 0x0000000000020661 0x0 lib/lib.a(open.o) + .data 0x0000000000020661 0x0 lib/lib.a(close.o) + .data 0x0000000000020661 0x0 lib/lib.a(errno.o) + .data 0x0000000000020661 0x0 lib/lib.a(write.o) + .data 0x0000000000020661 0x0 lib/lib.a(dup.o) + .data 0x0000000000020661 0x0 lib/lib.a(setsid.o) + .data 0x0000000000020661 0x0 lib/lib.a(execve.o) + .data 0x0000000000020661 0x0 lib/lib.a(wait.o) + .data 0x0000000000020661 0x0 lib/lib.a(string.o) + *fill* 0x0000000000020661 0x1f + .data 0x0000000000020680 0x50 lib/lib.a(malloc.o) + 0x0000000000020680 bucket_dir + +.data1 + *(.data1) + 0x00000000000206d0 _edata = . + 0x00000000000206d0 PROVIDE (edata, .) + 0x00000000000206d0 . = . + 0x00000000000206d0 __bss_start = . + +.bss 0x00000000000206e0 0x44b0 + *(.dynbss) + *(.bss .bss.* .gnu.linkonce.b.*) + .bss 0x00000000000206e0 0x0 boot/head.o + .bss 0x00000000000206e0 0x40c init/main.o + *fill* 0x0000000000020aec 0x14 + .bss 0x0000000000020b00 0x760 kernel/kernel.o + 0x0000000000020b00 jiffies + 0x0000000000020b04 startup_time + 0x0000000000020b08 last_task_used_math + 0x0000000000020e44 last_pid + .bss 0x0000000000021260 0xf20 mm/mm.o + .bss 0x0000000000022180 0x710 fs/fs.o + 0x0000000000022180 inode_table + 0x0000000000022880 nr_buffers + 0x000000000002288c ROOT_DEV + *fill* 0x0000000000022890 0x10 + .bss 0x00000000000228a0 0x58 kernel/blk_drv/blk_drv.a(ll_rw_blk.o) + 0x00000000000228a0 wait_for_request + 0x00000000000228c0 blk_dev + .bss 0x00000000000228f8 0x25 kernel/blk_drv/blk_drv.a(floppy.o) + 0x00000000000228f8 do_floppy + 0x00000000000228fc selected + 0x0000000000022900 wait_on_floppy_select + *fill* 0x000000000002291d 0x3 + .bss 0x0000000000022920 0xb0 kernel/blk_drv/blk_drv.a(hd.o) + 0x0000000000022920 do_hd + 0x0000000000022940 hd_info + .bss 0x00000000000229d0 0x4 kernel/blk_drv/blk_drv.a(ramdisk.o) + 0x00000000000229d0 rd_length + .bss 0x00000000000229d4 0x4 kernel/chr_drv/chr_drv.a(tty_io.o) + *fill* 0x00000000000229d8 0x8 + .bss 0x00000000000229e0 0xac kernel/chr_drv/chr_drv.a(console.o) + 0x00000000000229e0 beepcount + .bss 0x0000000000022a8c 0x0 kernel/chr_drv/chr_drv.a(keyboard.2.o) + .bss 0x0000000000022a8c 0x0 kernel/chr_drv/chr_drv.a(serial.o) + .bss 0x0000000000022a8c 0x0 kernel/chr_drv/chr_drv.a(rs_io.o) + .bss 0x0000000000022a8c 0x0 kernel/chr_drv/chr_drv.a(tty_ioctl.o) + .bss 0x0000000000022a8c 0x0 kernel/math/math.a(math_emulate.o) + .bss 0x0000000000022a8c 0x0 lib/lib.a(ctype.o) + .bss 0x0000000000022a8c 0x0 lib/lib.a(_exit.o) + .bss 0x0000000000022a8c 0x0 lib/lib.a(open.o) + .bss 0x0000000000022a8c 0x0 lib/lib.a(close.o) + .bss 0x0000000000022a8c 0x0 lib/lib.a(errno.o) + .bss 0x0000000000022a8c 0x0 lib/lib.a(write.o) + .bss 0x0000000000022a8c 0x0 lib/lib.a(dup.o) + .bss 0x0000000000022a8c 0x0 lib/lib.a(setsid.o) + .bss 0x0000000000022a8c 0x0 lib/lib.a(execve.o) + .bss 0x0000000000022a8c 0x0 lib/lib.a(wait.o) + .bss 0x0000000000022a8c 0x0 lib/lib.a(string.o) + .bss 0x0000000000022a8c 0x4 lib/lib.a(malloc.o) + 0x0000000000022a8c free_bucket_desc + *(COMMON) + *fill* 0x0000000000022a90 0x10 + COMMON 0x0000000000022aa0 0x20 init/main.o + 0x0000000000022aa0 drive_info + COMMON 0x0000000000022ac0 0x1000 kernel/kernel.o + 0x0000000000022ac0 user_stack + COMMON 0x0000000000023ac0 0xc40 fs/fs.o + 0x0000000000023ac0 hash_table + 0x0000000000023fa0 super_block + 0x0000000000024300 file_table + COMMON 0x0000000000024700 0x480 kernel/blk_drv/blk_drv.a(ll_rw_blk.o) + 0x0000000000024700 request + COMMON 0x0000000000024b80 0x4 kernel/blk_drv/blk_drv.a(ramdisk.o) + 0x0000000000024b80 rd_start + COMMON 0x0000000000024b84 0x1 lib/lib.a(ctype.o) + 0x0000000000024b84 _ctmp + *fill* 0x0000000000024b85 0x3 + COMMON 0x0000000000024b88 0x4 lib/lib.a(errno.o) + 0x0000000000024b88 errno + COMMON 0x0000000000024b8c 0x4 lib/lib.a(string.o) + 0x0000000000024b8c ___strtok + 0x0000000000024b90 . = ALIGN ((. != 0x0)?0x4:0x1) + 0x0000000000024b90 . = ALIGN (0x4) + 0x0000000000024b90 . = SEGMENT_START ("ldata-segment", .) + 0x0000000000024b90 . = ALIGN (0x4) + 0x0000000000024b90 _end = . + 0x0000000000024b90 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 0x1a4 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) + .comment 0x0000000000000000 0x2a lib/lib.a(malloc.o) + +.debug + *(.debug) + +.line + *(.line) + +.debug_srcinfo + *(.debug_srcinfo) + +.debug_sfnames + *(.debug_sfnames) + +.debug_aranges 0x0000000000000000 0x648 + *(.debug_aranges) + .debug_aranges + 0x0000000000000000 0x20 init/main.o + .debug_aranges + 0x0000000000000020 0x140 kernel/kernel.o + .debug_aranges + 0x0000000000000160 0x20 mm/mm.o + .debug_aranges + 0x0000000000000180 0x238 fs/fs.o + .debug_aranges + 0x00000000000003b8 0x20 kernel/blk_drv/blk_drv.a(ll_rw_blk.o) + .debug_aranges + 0x00000000000003d8 0x20 kernel/blk_drv/blk_drv.a(floppy.o) + .debug_aranges + 0x00000000000003f8 0x20 kernel/blk_drv/blk_drv.a(hd.o) + .debug_aranges + 0x0000000000000418 0x20 kernel/blk_drv/blk_drv.a(ramdisk.o) + .debug_aranges + 0x0000000000000438 0x20 kernel/chr_drv/chr_drv.a(tty_io.o) + .debug_aranges + 0x0000000000000458 0x20 kernel/chr_drv/chr_drv.a(console.o) + .debug_aranges + 0x0000000000000478 0x20 kernel/chr_drv/chr_drv.a(serial.o) + .debug_aranges + 0x0000000000000498 0x20 kernel/chr_drv/chr_drv.a(tty_ioctl.o) + .debug_aranges + 0x00000000000004b8 0x20 kernel/math/math.a(math_emulate.o) + .debug_aranges + 0x00000000000004d8 0x18 lib/lib.a(ctype.o) + .debug_aranges + 0x00000000000004f0 0x20 lib/lib.a(_exit.o) + .debug_aranges + 0x0000000000000510 0x20 lib/lib.a(open.o) + .debug_aranges + 0x0000000000000530 0x20 lib/lib.a(close.o) + .debug_aranges + 0x0000000000000550 0x18 lib/lib.a(errno.o) + .debug_aranges + 0x0000000000000568 0x20 lib/lib.a(write.o) + .debug_aranges + 0x0000000000000588 0x20 lib/lib.a(dup.o) + .debug_aranges + 0x00000000000005a8 0x20 lib/lib.a(setsid.o) + .debug_aranges + 0x00000000000005c8 0x20 lib/lib.a(execve.o) + .debug_aranges + 0x00000000000005e8 0x20 lib/lib.a(wait.o) + .debug_aranges + 0x0000000000000608 0x20 lib/lib.a(string.o) + .debug_aranges + 0x0000000000000628 0x20 lib/lib.a(malloc.o) + +.debug_pubnames + *(.debug_pubnames) + +.debug_info 0x0000000000000000 0x1749a + *(.debug_info .gnu.linkonce.wi.*) + .debug_info 0x0000000000000000 0x577 init/main.o + .debug_info 0x0000000000000577 0x50fa kernel/kernel.o + .debug_info 0x0000000000005671 0xc15 mm/mm.o + .debug_info 0x0000000000006286 0xa290 fs/fs.o + .debug_info 0x0000000000010516 0x932 kernel/blk_drv/blk_drv.a(ll_rw_blk.o) + .debug_info 0x0000000000010e48 0xc9f kernel/blk_drv/blk_drv.a(floppy.o) + .debug_info 0x0000000000011ae7 0xd5f kernel/blk_drv/blk_drv.a(hd.o) + .debug_info 0x0000000000012846 0xad5 kernel/blk_drv/blk_drv.a(ramdisk.o) + .debug_info 0x000000000001331b 0xacd kernel/chr_drv/chr_drv.a(tty_io.o) + .debug_info 0x0000000000013de8 0xdb0 kernel/chr_drv/chr_drv.a(console.o) + .debug_info 0x0000000000014b98 0x85c kernel/chr_drv/chr_drv.a(serial.o) + .debug_info 0x00000000000153f4 0xb47 kernel/chr_drv/chr_drv.a(tty_ioctl.o) + .debug_info 0x0000000000015f3b 0x7b5 kernel/math/math.a(math_emulate.o) + .debug_info 0x00000000000166f0 0x66 lib/lib.a(ctype.o) + .debug_info 0x0000000000016756 0x77 lib/lib.a(_exit.o) + .debug_info 0x00000000000167cd 0xd0 lib/lib.a(open.o) + .debug_info 0x000000000001689d 0x97 lib/lib.a(close.o) + .debug_info 0x0000000000016934 0x36 lib/lib.a(errno.o) + .debug_info 0x000000000001696a 0xc9 lib/lib.a(write.o) + .debug_info 0x0000000000016a33 0x97 lib/lib.a(dup.o) + .debug_info 0x0000000000016aca 0x95 lib/lib.a(setsid.o) + .debug_info 0x0000000000016b5f 0xcb lib/lib.a(execve.o) + .debug_info 0x0000000000016c2a 0xed lib/lib.a(wait.o) + .debug_info 0x0000000000016d17 0x55e lib/lib.a(string.o) + .debug_info 0x0000000000017275 0x225 lib/lib.a(malloc.o) + +.debug_abbrev 0x0000000000000000 0x457f + *(.debug_abbrev) + .debug_abbrev 0x0000000000000000 0x1ed init/main.o + .debug_abbrev 0x00000000000001ed 0xfc2 kernel/kernel.o + .debug_abbrev 0x00000000000011af 0x23f mm/mm.o + .debug_abbrev 0x00000000000013ee 0x19f1 fs/fs.o + .debug_abbrev 0x0000000000002ddf 0x169 kernel/blk_drv/blk_drv.a(ll_rw_blk.o) + .debug_abbrev 0x0000000000002f48 0x27d kernel/blk_drv/blk_drv.a(floppy.o) + .debug_abbrev 0x00000000000031c5 0x23c kernel/blk_drv/blk_drv.a(hd.o) + .debug_abbrev 0x0000000000003401 0x1a8 kernel/blk_drv/blk_drv.a(ramdisk.o) + .debug_abbrev 0x00000000000035a9 0x279 kernel/chr_drv/chr_drv.a(tty_io.o) + .debug_abbrev 0x0000000000003822 0x26b kernel/chr_drv/chr_drv.a(console.o) + .debug_abbrev 0x0000000000003a8d 0x175 kernel/chr_drv/chr_drv.a(serial.o) + .debug_abbrev 0x0000000000003c02 0x18d kernel/chr_drv/chr_drv.a(tty_ioctl.o) + .debug_abbrev 0x0000000000003d8f 0x163 kernel/math/math.a(math_emulate.o) + .debug_abbrev 0x0000000000003ef2 0x3e lib/lib.a(ctype.o) + .debug_abbrev 0x0000000000003f30 0x51 lib/lib.a(_exit.o) + .debug_abbrev 0x0000000000003f81 0x97 lib/lib.a(open.o) + .debug_abbrev 0x0000000000004018 0x75 lib/lib.a(close.o) + .debug_abbrev 0x000000000000408d 0x2c lib/lib.a(errno.o) + .debug_abbrev 0x00000000000040b9 0xa1 lib/lib.a(write.o) + .debug_abbrev 0x000000000000415a 0x75 lib/lib.a(dup.o) + .debug_abbrev 0x00000000000041cf 0x73 lib/lib.a(setsid.o) + .debug_abbrev 0x0000000000004242 0x85 lib/lib.a(execve.o) + .debug_abbrev 0x00000000000042c7 0xb6 lib/lib.a(wait.o) + .debug_abbrev 0x000000000000437d 0xe9 lib/lib.a(string.o) + .debug_abbrev 0x0000000000004466 0x119 lib/lib.a(malloc.o) + +.debug_line 0x0000000000000000 0x4808 + *(.debug_line .debug_line.* .debug_line_end) + .debug_line 0x0000000000000000 0x1a9 init/main.o + .debug_line 0x00000000000001a9 0xfbf kernel/kernel.o + .debug_line 0x0000000000001168 0x2af mm/mm.o + .debug_line 0x0000000000001417 0x1c5f fs/fs.o + .debug_line 0x0000000000003076 0x197 kernel/blk_drv/blk_drv.a(ll_rw_blk.o) + .debug_line 0x000000000000320d 0x24c kernel/blk_drv/blk_drv.a(floppy.o) + .debug_line 0x0000000000003459 0x2bf kernel/blk_drv/blk_drv.a(hd.o) + .debug_line 0x0000000000003718 0x160 kernel/blk_drv/blk_drv.a(ramdisk.o) + .debug_line 0x0000000000003878 0x33b kernel/chr_drv/chr_drv.a(tty_io.o) + .debug_line 0x0000000000003bb3 0x3ab kernel/chr_drv/chr_drv.a(console.o) + .debug_line 0x0000000000003f5e 0xd9 kernel/chr_drv/chr_drv.a(serial.o) + .debug_line 0x0000000000004037 0x1db kernel/chr_drv/chr_drv.a(tty_ioctl.o) + .debug_line 0x0000000000004212 0xe1 kernel/math/math.a(math_emulate.o) + .debug_line 0x00000000000042f3 0x28 lib/lib.a(ctype.o) + .debug_line 0x000000000000431b 0x39 lib/lib.a(_exit.o) + .debug_line 0x0000000000004354 0x62 lib/lib.a(open.o) + .debug_line 0x00000000000043b6 0x5c lib/lib.a(close.o) + .debug_line 0x0000000000004412 0x28 lib/lib.a(errno.o) + .debug_line 0x000000000000443a 0x76 lib/lib.a(write.o) + .debug_line 0x00000000000044b0 0x5a lib/lib.a(dup.o) + .debug_line 0x000000000000450a 0x77 lib/lib.a(setsid.o) + .debug_line 0x0000000000004581 0x5d lib/lib.a(execve.o) + .debug_line 0x00000000000045de 0x7a lib/lib.a(wait.o) + .debug_line 0x0000000000004658 0xc6 lib/lib.a(string.o) + .debug_line 0x000000000000471e 0xea lib/lib.a(malloc.o) + +.debug_frame + *(.debug_frame) + +.debug_str 0x0000000000000000 0x2286 + *(.debug_str) + .debug_str 0x0000000000000000 0x1c5 init/main.o + 0x204 (size before relaxing) + .debug_str 0x00000000000001c5 0xc37 kernel/kernel.o + 0x24a4 (size before relaxing) + .debug_str 0x0000000000000dfc 0x19f mm/mm.o + 0x509 (size before relaxing) + .debug_str 0x0000000000000f9b 0x891 fs/fs.o + 0x496b (size before relaxing) + .debug_str 0x000000000000182c 0xec kernel/blk_drv/blk_drv.a(ll_rw_blk.o) + 0x48d (size before relaxing) + .debug_str 0x0000000000001918 0x1cf kernel/blk_drv/blk_drv.a(floppy.o) + 0x66f (size before relaxing) + .debug_str 0x0000000000001ae7 0x15e kernel/blk_drv/blk_drv.a(hd.o) + 0x5e4 (size before relaxing) + .debug_str 0x0000000000001c45 0x7b kernel/blk_drv/blk_drv.a(ramdisk.o) + 0x58a (size before relaxing) + .debug_str 0x0000000000001cc0 0xf7 kernel/chr_drv/chr_drv.a(tty_io.o) + 0x4df (size before relaxing) + .debug_str 0x0000000000001db7 0x1b9 kernel/chr_drv/chr_drv.a(console.o) + 0x5b3 (size before relaxing) + .debug_str 0x0000000000001f70 0x1a kernel/chr_drv/chr_drv.a(serial.o) + 0x3f8 (size before relaxing) + .debug_str 0x0000000000001f8a 0x8b kernel/chr_drv/chr_drv.a(tty_ioctl.o) + 0x4a3 (size before relaxing) + .debug_str 0x0000000000002015 0x70 kernel/math/math.a(math_emulate.o) + 0x392 (size before relaxing) + .debug_str 0x0000000000002085 0x8d lib/lib.a(ctype.o) + 0xb6 (size before relaxing) + .debug_str 0x0000000000002112 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 0x0000000000002143 0x8 lib/lib.a(close.o) + 0xe0 (size before relaxing) + .debug_str 0x000000000000214b 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 0x0000000000002153 0x6 lib/lib.a(dup.o) + 0xd8 (size before relaxing) + .debug_str 0x0000000000002159 0x9 lib/lib.a(setsid.o) + 0xe8 (size before relaxing) + .debug_str 0x0000000000002162 0x9 lib/lib.a(execve.o) + 0xf1 (size before relaxing) + .debug_str 0x000000000000216b 0x11 lib/lib.a(wait.o) + 0xfe (size before relaxing) + .debug_str 0x000000000000217c 0x93 lib/lib.a(string.o) + 0x147 (size before relaxing) + .debug_str 0x000000000000220f 0x77 lib/lib.a(malloc.o) + 0x162 (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/linux/boot/bootsect b/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/linux/boot/bootsect.o b/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/linux/boot/bootsect.s b/linux/boot/bootsect.s new file mode 100644 index 0000000..711f103 --- /dev/null +++ b/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/linux/boot/head.o b/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/linux/boot/setup b/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/linux/boot/setup.s b/linux/boot/setup.s new file mode 100644 index 0000000..2329d00 --- /dev/null +++ b/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/linux/execve2.patch b/linux/execve2.patch new file mode 100644 index 0000000..7d99d4f --- /dev/null +++ b/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/linux/fs/Makefile b/linux/fs/Makefile new file mode 100644 index 0000000..970acd4 --- /dev/null +++ b/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/linux/fs/bitmap.c b/linux/fs/bitmap.c new file mode 100644 index 0000000..73951a8 --- /dev/null +++ b/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/linux/fs/bitmap.o b/linux/fs/bitmap.o new file mode 100644 index 0000000000000000000000000000000000000000..e2ff6c81c16c1eb4d774536e968d9c30d54d4546 GIT binary patch literal 10276 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 literal 0 HcmV?d00001 diff --git a/linux/fs/block_dev.c b/linux/fs/block_dev.c new file mode 100644 index 0000000..a50ae3f --- /dev/null +++ b/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/linux/fs/block_dev.o b/linux/fs/block_dev.o new file mode 100644 index 0000000000000000000000000000000000000000..cdf73318e1c2982d43e13f2b6bfecf1c6b439a14 GIT binary patch literal 7292 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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; +} +//buffer release +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;iLB*g=Pj~f9OHX&(4<0T) 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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/linux/fs/char_dev.o b/linux/fs/char_dev.o new file mode 100644 index 0000000000000000000000000000000000000000..c7f8402c1f0282705e51af77991c05336e864f2d GIT binary patch literal 8284 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 Qso-A-o)>&Y@EyVb1*ZoUcK`qY literal 0 HcmV?d00001 diff --git a/linux/fs/exec.c b/linux/fs/exec.c new file mode 100644 index 0000000..80be710 --- /dev/null +++ b/linux/fs/exec.c @@ -0,0 +1,367 @@ +/* + * 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_execve2()' immdiate loading +*/ + +/* + * '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())) { + printk("(inode->i_mode & 0111):%d,suser:%d",(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; + printk("start_cod: %x\n",current->start_code); + printk("brk : %x\n",current->start_code+current->brk); + printk("start_sta: %x\n",current->start_stack+current->start_code); + 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 ; 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 +#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/linux/fs/fcntl.o b/linux/fs/fcntl.o new file mode 100644 index 0000000000000000000000000000000000000000..c82831d0ba1e338fe2c2cb69a13e2f6a93017d1a GIT binary patch literal 6744 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 +#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/linux/fs/file_dev.o b/linux/fs/file_dev.o new file mode 100644 index 0000000000000000000000000000000000000000..08829927f02514a0c6e50ae669391d73afe423ce GIT binary patch literal 7824 zcma)B3vgW3c|P~-y?fWYtLMtL{AgK{HI}iok}cVm!45K(!FFU2SOm-1S?%MlcG14P zd)KxY6UZp;SQc*LNt;ZkCWcAc(xgn1X)+MfVT_&TMLHp!3vK^W87(5xQ2{Qms>Jml4=yjs{dQ$07--SW%@w6S`2 zET%UY#b6W@^`TW5xe~A2lMkV>pC+!53{b57asXB{miOfUhTfRs=*6u{XloRaQXcIsrj;#%$AeS zv!sdreD;QuSMT}HD=+-cnEl}k@7=KO;*-=OJa%Ddb~FYUxfNZoo58vfCokCSE^@CUuHdEPkR#RU3`3VQ4D4d(_lH87H?UoZjYd(gx9ES@!|cd{ zMp<-eZce&U#!ha%cr=1ajyOB2Q~Uj)eho;==+)@lp;+w9P7T%BsyFnr7|Yi%y-xXP zxj4{2gV@PJPG|5a0vTy}?8hH^^a7}K-GJ0LQpX@UKR?tQ=t5GX!uB%)3_N1Nzz;rf z>6w7wAmh@t89cTBz~hXhLWmc!D0xZU{5(cY>P8d5ryKc_Eu=Kxpi&Dgfth{?+#l_B ztq;S2)ci+KAf>S!VBCO`fKQ(V_>;nCkO+TDF`aEZ2N%W^s>bx;9&oc0Ci*T?VSWQo z{SMaB&2~QTyamsI`LAqz_YUx&`6_MpkcZ3|`Cjs{xe7k@kCQi9F8PV>K5_ipml<}UJ4@~8;t2jOGM4nR*yZ#!l1+Y7>KltAZ} zL}e&dol-(f2H{c(T{2Y3XM{0M*WEH$Wr-v7$>1b|afAUGe3`BtVNeDiUMSfnLv=bh z$Q%#JU^hGI2)E0i5A($phGl4yW)INp4jC-afg|je!7N=n!d}#2$svX_B7;eWbC|-Y z41R$njxZ*J-&qh2$lw(^a7qrz;M_vVgbYs8!6(^hMuu#AS{M_|TMiMhB*~Hja&Qc> zrOqJSiVU_e>NEvg2J7rkhQe_f+{Jb*=K6#TZeu&y7m>?HWvGy`g^~LegqP4xttN~I zD~1r4C1yfDTm{pKIgPlQ$;19^8nd8>yw#sAmxU20 z?*NCsm%P(F4gW?T-LDp5syJz!$q^C8zo17yH~P5&n2*wMfEL1RgWlLguKR1XK4EMo z517lS-$EXSeuFRu$y?1yJdLg79nfzS#x3NX{&clp7`KwI_FD{m8+p`xo_@BI$NX0E zxG+9O-sQK_9`E*B8ISk*t(3Vn@+J`BAuc9QP) zGhM@^BZyKMyGTd<8PGdO$NX8)J4p}tCqZ|U9`ZXYZx8u|xgAeqFL}m%oBZSNVia>C z{3QTas*~CqMEDoryj7|LI#*yghbr%QS}EFgV2Wtk4rqBb}aw8CCla6d~M0Ix>!C%(#Cms z6Yj4;(#~O<5bf{5m2BfOK!fevd1M>oN3CV4dKQxFBf$5aav{%#J3pXhgbwA|Lg#*> zl5&w!bwM~3N#%s>;HyiX&8&DIc4N3B6(K+BI-U?>`8|xTkIsGu_B$uK^9#}ST@zj3 zHPQ856P@D%(M2j)334MBG^0Dn)}6&E&mM}T7kJJIZom!h0At$Zy30iJLT+|DHz8KW zQQw&RDgs)?8L;vv2+(+pRA_D5n&wEz*SxB^O>6hJE=Nl-5ej__Dx6XjMNNH~@HO8O zx;3;Xg31xi*BlB_)FAqsgfHNh4Ti7`Au3afffo2bi+FvHpoH8_D7*0enl zI&ZpB?1}WkPxDf3?FwpI3}~=?mx{G3glLN+7W!PfVo!v980!4u?T%f$u@HyEJc|r0 zL`kvZCdbRt#p>5oUWUr5Pqbbh*KS*JeLG)p+v$X3)nA&f2qCHMn1U-8^|!6qhEP{+ za+<`BhAcDt>eNW)9TUk%IGw~fFirdK<|aIy--ZbFHbTMwB|PQJ{_%Zxp9*aM`u$Ij%k`0Qco`4W-<|o9V-kq^-<^5= z>Ceo#PX6r;$4lusU&qVv64?H@~K|DAp?pWthoVZFGSr=vuB^wWHSg{tCy?CK>COUCg?mR@klFl4}BWK`hR;`99A#kSl#wcBL(gFh)OYBE7lc|biAz3Xh zW}VYlC5%(SNk8T*M^8MM&t~&DePk1S3qe&8lNehscWzD*M5$hMyQsDWQJJh(gvBg4 z?%fF^3P=T9BZ(X;XZYN~b7RFib5;yS02TA@a1;}HCv;38&Iim3XI|S_T3%OCFPAK3 z3UHmm;Mrw&_>zgLRl|~CXOxqIl|{R*cV{4~<+3frojZ5l679M#g{`6PF3g^dbw}Fp zsSN}1zJYbFmOEVsAGoxK?iJdJfVL{E>!+}bVz+lTbC&TmBX%?gX5`4FX6%owGpO{m z6FZv&V<;dW#qFJApda%6mBuO}io1Z@J4LwuXz&}YIk3a=E8?~3BGwhquDY1>Sk)@T zZLCrecQ&?o3dhAbl^H8lpF}>gWfVC)nMz@4G?pf-$gVWnaFLI*zN#qSwNqrl73xd!lTd=avY*DBmg9Ogb+SK>?y$}=5p zm^++N#2O{zRpng#Ali6&{`mW!_FnPtvtvA79r~f&cUe(gURfXH#`r3T?=ox|AI>rh z@eP4{bwI^)VIlZ4+Pge@FBBeUSuZA6ltf)#*P62UOe* zf1?cwk0w#p=r0F<^h19^+@8N9;H<-b^E%&x`OZRhv5fZ#g`VBt;@EbxvLSeOCl&XK z{uy?S7wvfc8E$g-@Fc`9VfPpd)a8Znr;r=_Q9(bV(6Ju~b)g?^;NBbn6$LEXFO#Ut zYqzmY7WH8fSD<8=oO@d^C+YPfvPh%YL9&d4{)UTdz-=k9z920kYv3nJoc5;2J0 ze%Fq8;)})3eC@wZ-g=!pbe+8WI{7}x-kwSS6W5iy#}fCr+xRYPJQFOQTv9ygVRz&! z9Ghot@s)VZ;lrum9)i*^wsA;w&Jt)li(6ts%n>okoC7^3AOE%CFPJBZm}@Z;c z186s_aF4=IC_Jn%qcE?KYmN2JDtuhwUn~5!!WR_&gThx8zOL{ch5w^)3G>1D72c?D zK;aIB`xK5Vv=kmu_^?8LJfgoZD*TGVZz_CI;p+;2t#Dpp7`bEpn-umd+^6uM!byd; z!cQywV}*aN@F|7-2u;8Iph@J{S>kUM@(VBJR)zfNNO?jbzYSA9u896!3V*8bHwwq_5@j4m6h5qQR^gKhzoYPq!Y^Z?u-?}d{#xPtMC3e#t&im!6mB6x zKc?ig!lKfjQ1WSof2r_W3NI>rlgKf}8m0db5%NkUcPSiJIHB+fh2Kz!FogzRe7CT^ Sv(A7~$P&0s;h4gT!v6)R(Kq`5 literal 0 HcmV?d00001 diff --git a/linux/fs/file_table.c b/linux/fs/file_table.c new file mode 100644 index 0000000..e0589ac --- /dev/null +++ b/linux/fs/file_table.c @@ -0,0 +1,9 @@ +/* + * linux/fs/file_table.c + * + * (C) 1991 Linus Torvalds + */ + +#include + +struct file file_table[NR_FILE]; diff --git a/linux/fs/file_table.o b/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/linux/fs/fs.o b/linux/fs/fs.o new file mode 100644 index 0000000000000000000000000000000000000000..5f0541be433ca1e5228acd67d8a7966794584693 GIT binary patch literal 143225 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 +#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/linux/fs/inode.o b/linux/fs/inode.o new file mode 100644 index 0000000000000000000000000000000000000000..37ed3bd7ff00fac837394067a5a9cfe2e204c68f GIT binary patch literal 14068 zcmc&)Ym`*gl|FUrcHOeNx@qVJ8z`Z`MnU@pv`D~~<{^TB0RaVq7S+|ax=XsN+IsLB zBx+%_XkR#vW@glm#v~>IHEW#F*qIEVqOO=F!|sz>A}yF1r)r^MZ!wwb#RWKX4dPg@H{9dtEj1Wq!0 zNX)`Xi`veRCb}VA3z5$-)h1O#CN0r} zF1S;$20F{3Q&@CSf4(pG=%~=srq4M+%47qp)%+ z0ZH-83Fy6ajj#(V-rGUC>$_;vz}YW21dLtE?6oR30DXz{{=(4ZFLaUK2T zarHS40*^E1qqiH1Q`rpZh{ujNlykh+gF7SEuI6OBk?}P zNLdLw*Yg1(m77yyaL^caLMnS28V5}t>^PV=Xtr?DJWoE^ z&XTkN^`HF2MdrpPe|7clJlBAhwfKUK~_Gh+&m0JG#-C0d3*x zPo3S?+2L~BIND&v-QlncV?WAXL5C$9DOvPbg4Bhv5}SqR9$9wuznmzbP+T}{#~#_N z!^2LkcTHf6I{HFUyPnlMdbsJM54j3lSX0#Rm1TRrwQO7^r>V6z=ZvfwV268hLIM~RzrQR!QzGYEEQgPUV_QK>W;w>dMyeP7>R zfVE)^;@H~z@U8L(W`CQgnO0>fl@2^pMhP!1mC2Z-85TTTg!D}!SK*MnH5$jtPb_yg zqz9b(OVSzb99xCCsVy8~t@3m5HE&rMax7sa?Ab4F>}v}$nak_^EHaeBCiKvyfLoj1 z`6ljq5aP|Qn86f~h;u(dB5GakYV7SUeHvOwJJJ7&q%*n^*T3@T6DL@;vtbR0ybgAA zH#-)MM;nusprb)_L5w%3aC~OGl6jlZ0)sY5RcW8l zuR=_Gn^WV{hs#bKf) z8^G}(H2dfTQ7y3OK6VoHW!)-@PTrCnA%|@U821Ui_>kUnb{`nAdmoyi>r}wB!AZWk z=4rIx#(eNKqiiE>D8v)eB_uOz?K*;C)>^x!VuEjniXI_EH7d*FNR1BGIk1F|K1ds| zP!tx6ZHTLtRBJO?RJbW2vKEYd@Z2@_e=vV+IZg#3E{ze_eIHe#)!ez}W>W)m&h6jH zK|N$Gl8;6=F7BA5Svi+ox;p=x@aJHg3rPCDk95+9-6m-iu5i2NHuwm-J7q;*dJs3S zcf!SV~$Mll7sJ-L4>p3-*IRbuy4E=vn4myEV|+YH4~XwU=H1K{Wf z`)^GrvK%?bUt%B;v(@j)mC}2&GCen=lV>;1og=Wt^V%A8&@inhu(S=ctPbEc%M!_~ zG7M`ObPbRHF{qn2qNOa1=On0E|E3#!t6{mU2_nB?UI*|+l~G1Q`Pzjtsr~``zK%Y1 z-bH7Cwx&YGdjUyhy^L?~V)inv$&_C>2j70{Lm2linGZT(O-5huQqtwtTXkf3SJ%r*jlRctxWD9_Qr2IjcU2rT3vHM777EW$a)VHO$XomBf8)fO9p zMjFt}5+m>mhoG5@jKBl*vytH}Hv&9an3t1TX#~E_KAKr$1P&LOb%>gMbjwB~@Xcb& zCL@rifh*{=!zj;Yw<~iK^VVeqwy-72mTu%=D`IPZ2R(a@z-5d&MkZ?n?&5el$ZRtL zk1|l3x!!36KBLq4I84tqMtOHfR+(MRV2;2~CZo(N|HX%`(Lg2C!-U@~pjX-JuoL#K zz6V{cc6@o)FaTx!2y*XQ(uQ>^)V-I|iD}J*L+@pz{niDf*UbkVv^L<|yPkA~<)@tu zG+C*FG_fCK#cB|KRrXUDp6$K-UV!6J=RzDtN*r!-9PXj9Xo*u65lWw*iBi&8=Gpw6P_mG}x z@qpk>l5Vj~(kasCSRdot+e>`T?6?HWzHd8>x-plDswLB zkk4k|=aCLuZSZThlCJaF(QV2+pY&9p9dqe=pWWfo%|5%`rCWS<26pCAe>UWx`Fc^E z2YEu7^GUa%FX#oN7eTJfg(R2wn65=6mm^ALUO;lCuLI;_l52c%kQb6%=j#Nygycq_ z-p`hj-ej%7w|Noi4lBrvEn9$mcB$a|n11emI<*s3@GQ{$NUHrNx1C@V9ot-~p+-(b zFHa4GiWTO$y8~^bZbx=JHLPW0uTmqAu_eUz2CZ{rQ72T?`5C)RxdiPKw9dYw&Jaaf_$ zZyln4zN>%g(~M{d8)qR+zae+`R`hX3w?v{E6{1_c#RP8vX?IyC5L7lDx+Fvw&(-7lY4aQaN4;aK=_PU_h>&;@Xy+e9wHTJ5$AK`oM z>_U$esk=wvaOn)NQrt@W6s9NIm1f4ykr*J4D~{x$VJBzqt9p4QIZfu1w1A3F9_O)?EF zhcTTvJ{A*WMzW7^9phFZ8~fmGJhJWgxZ$YK9G1=*o;XbZRtGa12jA0lg`DAWOsVmi zcIBDsVT-Z1dpsv^n#Y;FjtP32&njB9K4Q!(5+RbGBRMCdOhX2Tq#yp?mx=aw(6 zhRbS?x3avPtOu;GLV5j88}ns>6;-nS5wOQzr|4c~ZZAA$71dCVz{+6Qdg`FJrPV|H)s{LK);2aEMp&QY%8~R@SWV-_Q`ypLnhuHS zvS9-`O$H)r6C@yECl0dn#-4|Kga-qjHP@U4IFV`(=wHYJj=?p%l6)SXD?wy6?9W_zZD#fgNEnvF49?838aBUTb# zPG%g;#JX$|Ww-a*l)`H!(V2{PgGS+IvS~bHJ2Wa!2kfo!v`%Wm)1v3ihbFBkl6lbi zw^y{~`v;B>4EV=W!FQW)rqlYu7f`SC}N`}g-RTQTo=&fnR;1;+AV zaszww>$U11eE#b78=N3X=QkXGr{6fey52RE8^{gZK7gU*^UXP}=Z(g_lm0!I%Om_{ zE4B~#k@Ed-c0pxea;JZZf5pJS*6ohPeZGN#4JGZ9I+3nCIvN(LDicZWNF{Nw$wU%( z?E>I!Jd=&4vk`p9Hmi0m!FMzpRULLF26;Lc%PKqB;RrL)NW43WQ%*J=joFd*M3$Bk zktE7yX@$2y9g!Z;>cWfHh8Kog8fQ1Qgd2LI z=~!25V&?2wpkv(~;fBs|Lp;@!$Tq~&(H^^@H-)z!b{fJ2J=qQMTr!qTq>>qklBotA zenW3Mm9=BpR9f+UQbaEZgp{%E%_@f1HCY>658wYN_&QhFJ-v9Gg+gM7%{-vJJB9a5 zeA5z#Vh8nm6TLPP6Vu&nKB#9ff^E_%*K4OE&f6bmRV&3MMfBk&usxErw`C)IeWg}_@|m*ra}{kBWBVP_Q+iHpU}S4Ff%)d<7?CXN z6se}JRFB=1%ynd&QWFTL}nzKNRP|_6QJJ|N_wN+(R7a#tJGC7%dxI#+IdBaf+(qQ zT@F}W@dQff%0xV#z#5N7dhs~NQteE{*wl+uaE1_MGS{Q~gY_XE}2neJ7# zo@c#NxRcQxMMXNRDsA^-Jt-X$P3fg1ZJF)Km_xFnSof+MQ-TO15#}SCVnOIis}-%*5(O#@YfSxq=4)FalhR#^3@e!bYTP;`^*)+jcqu4uBO8y?$Hc-fRLJxJ4b z2D<~q*!o!Lak0s_(28}!N^=I7iNq7>OqM$#7ZiFVGC9n(vjIp^>(WZ6Qdy-gT)1#f zcWJHe$V)zso&&Mu7CIfPQgbl ztPDphO|9P|GCs>uo)GzRuXKzrmPa8T^KKeq~kOq8XbjW{22&ZxsW z!IO)cCOi(4`q~#PJ@F3GtnE^JJ25HjPkZd^+S5N`hzy_(z#f0Wbg!@wjGJ-jBP)=4 zqut=a(;lxjd`iUXr3$5v_xZl0M+ zcN|wsAFd5v%keU3BgX4q^u^DOg09|!r{i6ft0ZmI!`r7J@x2JW(#wtgJEG@?{tM_m z;x?kqowxfymyTmM#?cEI^Dyyn7OjGLj5R3-R5B)Ol z^jT`}j(Vjoca5N}gakKumC8-^!HK~Z+AD1(U+RH;S#higA8~pV-WBNk0r!6LlY#D@ zPrmf>Vl{K!xceL1`6HIQx09bQ9XL+@pL7+_-9t~dSF+%s=PgF(81d@LbZCBi@zT2V z^5Pej(#xweJ1Ft$Su5p7sEsZQ*CUaSE|&*#UalI(ZwJqM;QPr@7*XG_cK-Fkz2~w0 z-eK(z4CDFtDEFeje{vZh`6q|*&kf^`fOqeg^!E~Y_dZGf4e;*$k^DQu`hPHt|8yAd zEtzu0QwiR^r_vsOBy}&gPXX`VSJ|%rF(L|VUx0S^MIhTR9M+$2xZI2S#Y6ni6I02F zbjb0v^mwa(?^lE8$j0eknR$*XeY_|+r)RotyB8-ioXj@cILE>7@COz=J0!DsP%1fb z_C}L9@Fwl8a(s3V#6uo^aQEdi0&dP3JV5dE=R6-uAO7n=@mVd>8|}o|kLLMof`{Q` zjE^z8%{eFzKmFoQ2Y9X|Me@le^E0jaO9vchWV?^lRLWKNRA|Hc$3+1;18Sh=> z5$}(P80YK6I;EE4U}8+cKaPlJK#zE)Qttyj@b!`4r-CPl$d846gYD%+@c8S2=1&vc zEb~oqr(4~JmMOIHUswv{xoe&#ZjMlwo(rP+3z37Lyv!+Vf#}+`kjUw z2r*5>=KVKBwEZ2Be)!Xaak^561b@YL=>3t1enH&y***?P{s!`m$TxY|xtBcr9wj2b zpNU-IOhb7q5qZ9ch<*}gnRcHLJS_O4;H!e~ z34SbSu-?&+`z3LlAb;Z~KSyw};3a}wKWx8JaEoAG@HWAF1b-m-l;Ep^#{@qSxj_XD}2A;LxPV>`!mA7B>0x#d(!?V;Vtf~h@*lCyVb&#09~FFF@GU_cEw!DHAkU$+yHaqs;C};? CH#8mq literal 0 HcmV?d00001 diff --git a/linux/fs/ioctl.c b/linux/fs/ioctl.c new file mode 100644 index 0000000..36fc976 --- /dev/null +++ b/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/linux/fs/ioctl.o b/linux/fs/ioctl.o new file mode 100644 index 0000000000000000000000000000000000000000..c5a5b15f6dc28af173801b3e56682f611ec101d4 GIT binary patch literal 5824 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 literal 0 HcmV?d00001 diff --git a/linux/fs/namei.c b/linux/fs/namei.c new file mode 100644 index 0000000..f8a02b9 --- /dev/null +++ b/linux/fs/namei.c @@ -0,0 +1,783 @@ +/* + * linux/fs/namei.c + * + * (C) 1991 Linus Torvalds + */ + +/* + * Some corrections by tytso. + */ + +#include +#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/linux/fs/namei.o b/linux/fs/namei.o new file mode 100644 index 0000000000000000000000000000000000000000..24adb056d9030e61a1ab7dbd9a1749977eecd847 GIT binary patch literal 20752 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 V8w7g<`M27ve@5^vLGBYQ|9=}pflvSd literal 0 HcmV?d00001 diff --git a/linux/fs/open.c b/linux/fs/open.c new file mode 100644 index 0000000..3695ff1 --- /dev/null +++ b/linux/fs/open.c @@ -0,0 +1,208 @@ +/* + * linux/fs/open.c + * + * (C) 1991 Linus Torvalds + */ + +#include +#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/linux/fs/open.o b/linux/fs/open.o new file mode 100644 index 0000000000000000000000000000000000000000..23086fdba1f943e20967d4a70703d41490d069a2 GIT binary patch literal 11180 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 literal 0 HcmV?d00001 diff --git a/linux/fs/pipe.c b/linux/fs/pipe.c new file mode 100644 index 0000000..dfc4480 --- /dev/null +++ b/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/linux/fs/pipe.o b/linux/fs/pipe.o new file mode 100644 index 0000000000000000000000000000000000000000..106606a8b562f82924a575b0a399c92a910bc50d GIT binary patch literal 8100 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 +#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/linux/fs/read_write.o b/linux/fs/read_write.o new file mode 100644 index 0000000000000000000000000000000000000000..b74e2a05827516e27ad7055b5197ab3d1de7f83d GIT binary patch literal 7516 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 literal 0 HcmV?d00001 diff --git a/linux/fs/select.c b/linux/fs/select.c new file mode 100644 index 0000000..cef8b43 --- /dev/null +++ b/linux/fs/select.c @@ -0,0 +1,10 @@ +/* nothing , only the stub */ +/* gohigh */ + +#include + +int sys_select() +{ + return -ENOSYS; +} + diff --git a/linux/fs/select.o b/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/linux/fs/stat.o b/linux/fs/stat.o new file mode 100644 index 0000000000000000000000000000000000000000..3d976fc85e572d4c79b6b135ac0d16da32884718 GIT binary patch literal 7208 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 literal 0 HcmV?d00001 diff --git a/linux/fs/super.c b/linux/fs/super.c new file mode 100644 index 0000000..6a4ccb1 --- /dev/null +++ b/linux/fs/super.c @@ -0,0 +1,282 @@ +/* + * linux/fs/super.c + * + * (C) 1991 Linus Torvalds + */ + +/* + * super.c contains code to handle the super-block tables. + */ +#include +#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/linux/fs/super.o b/linux/fs/super.o new file mode 100644 index 0000000000000000000000000000000000000000..25ac49b6aea1170f1153f2279086249f062fde29 GIT binary patch literal 12280 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 literal 0 HcmV?d00001 diff --git a/linux/fs/truncate.c b/linux/fs/truncate.c new file mode 100644 index 0000000..36f3ea2 --- /dev/null +++ b/linux/fs/truncate.c @@ -0,0 +1,65 @@ +/* + * linux/fs/truncate.c + * + * (C) 1991 Linus Torvalds + */ + +#include + +#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/linux/fs/truncate.o b/linux/fs/truncate.o new file mode 100644 index 0000000000000000000000000000000000000000..63af350a448e032c96a39ec52a400dfeb6fa8198 GIT binary patch literal 6844 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 literal 0 HcmV?d00001 diff --git a/linux/include/a.out.h b/linux/include/a.out.h new file mode 100644 index 0000000..3e67974 --- /dev/null +++ b/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/linux/include/asm/io.h b/linux/include/asm/io.h new file mode 100644 index 0000000..d5cc42a --- /dev/null +++ b/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/linux/include/asm/memory.h b/linux/include/asm/memory.h new file mode 100644 index 0000000..51b69e7 --- /dev/null +++ b/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/linux/include/asm/segment.h b/linux/include/asm/segment.h new file mode 100644 index 0000000..94dd102 --- /dev/null +++ b/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/linux/include/asm/system.h b/linux/include/asm/system.h new file mode 100644 index 0000000..0b5a21d --- /dev/null +++ b/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/linux/include/const.h b/linux/include/const.h new file mode 100644 index 0000000..7828e61 --- /dev/null +++ b/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/linux/include/ctype.h b/linux/include/ctype.h new file mode 100644 index 0000000..7acf55d --- /dev/null +++ b/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/linux/include/errno.h b/linux/include/errno.h new file mode 100644 index 0000000..c282f69 --- /dev/null +++ b/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/linux/include/fcntl.h b/linux/include/fcntl.h new file mode 100644 index 0000000..a5bf9af --- /dev/null +++ b/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/linux/include/linux/config.h b/linux/include/linux/config.h new file mode 100644 index 0000000..c979fb3 --- /dev/null +++ b/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/linux/include/linux/fdreg.h b/linux/include/linux/fdreg.h new file mode 100644 index 0000000..01355af --- /dev/null +++ b/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/linux/include/linux/fs.h b/linux/include/linux/fs.h new file mode 100644 index 0000000..7a90b10 --- /dev/null +++ b/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/linux/include/linux/hdreg.h b/linux/include/linux/hdreg.h new file mode 100644 index 0000000..e6c593f --- /dev/null +++ b/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/linux/include/linux/head.h b/linux/include/linux/head.h new file mode 100644 index 0000000..db3dda2 --- /dev/null +++ b/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/linux/include/linux/kernel.h b/linux/include/linux/kernel.h new file mode 100644 index 0000000..cb40dd5 --- /dev/null +++ b/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/linux/include/linux/mm.h b/linux/include/linux/mm.h new file mode 100644 index 0000000..5a160f3 --- /dev/null +++ b/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/linux/include/linux/sched.h b/linux/include/linux/sched.h new file mode 100644 index 0000000..772646a --- /dev/null +++ b/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/linux/include/linux/sys.h b/linux/include/linux/sys.h new file mode 100644 index 0000000..d0bb537 --- /dev/null +++ b/linux/include/linux/sys.h @@ -0,0 +1,121 @@ +/* + * 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_execve2(); +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 long sys_getcwd(); +extern long sys_mmap(); +extern int sys_munmap(); +extern int sys_clone(); + +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,sys_mmap ,sys_munmap ,sys_clone}; + +/* So we don't have to do any more manual updating.... */ +int NR_syscalls = sizeof(sys_call_table)/sizeof(fn_ptr); diff --git a/linux/include/linux/tty.h b/linux/include/linux/tty.h new file mode 100644 index 0000000..ad846b3 --- /dev/null +++ b/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/linux/include/new.h b/linux/include/new.h new file mode 100644 index 0000000..c508915 --- /dev/null +++ b/linux/include/new.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 diff --git a/linux/include/signal.h b/linux/include/signal.h new file mode 100644 index 0000000..4e5887e --- /dev/null +++ b/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/linux/include/stdarg.h b/linux/include/stdarg.h new file mode 100644 index 0000000..fd79ec0 --- /dev/null +++ b/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/linux/include/stddef.h b/linux/include/stddef.h new file mode 100644 index 0000000..97f72ff --- /dev/null +++ b/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/linux/include/string.h b/linux/include/string.h new file mode 100644 index 0000000..48b91e5 --- /dev/null +++ b/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/linux/include/sys/times.h b/linux/include/sys/times.h new file mode 100644 index 0000000..68d5bfb --- /dev/null +++ b/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/linux/include/sys/types.h b/linux/include/sys/types.h new file mode 100644 index 0000000..557aa31 --- /dev/null +++ b/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/linux/include/sys/utsname.h b/linux/include/sys/utsname.h new file mode 100644 index 0000000..0a1c5a0 --- /dev/null +++ b/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/linux/include/sys/wait.h b/linux/include/sys/wait.h new file mode 100644 index 0000000..53190c2 --- /dev/null +++ b/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/linux/include/termios.h b/linux/include/termios.h new file mode 100644 index 0000000..2b7b913 --- /dev/null +++ b/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/linux/include/time.h b/linux/include/time.h new file mode 100644 index 0000000..d0a765d --- /dev/null +++ b/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/linux/include/unistd.h b/linux/include/unistd.h new file mode 100644 index 0000000..4a9a3f7 --- /dev/null +++ b/linux/include/unistd.h @@ -0,0 +1,277 @@ +#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 __NR_mmap 92 +#define __NR_munmap 93 +#define __NR_clone 94 +#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); + +#define __always_inline inline __attribute__((always_inline)) + +#endif diff --git a/linux/include/utime.h b/linux/include/utime.h new file mode 100644 index 0000000..83f07c7 --- /dev/null +++ b/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/linux/init/main.c b/linux/init/main.c new file mode 100644 index 0000000..dd6a3f0 --- /dev/null +++ b/linux/init/main.c @@ -0,0 +1,217 @@ +/* + * 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/linux/init/main.o b/linux/init/main.o new file mode 100644 index 0000000000000000000000000000000000000000..df34f02656549750eccada73419d78cc7219b1e9 GIT binary patch literal 9176 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 Yxgc?+!cK*|6dqJ~QsH|Ff2Z*O0Fn}IrvLx| literal 0 HcmV?d00001 diff --git a/linux/kernel/Makefile b/linux/kernel/Makefile new file mode 100644 index 0000000..29b8f8d --- /dev/null +++ b/linux/kernel/Makefile @@ -0,0 +1,83 @@ +# +# Makefile for the FREAX-kernel. +# +# 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 =-m elf_i386 -Ttext 0 -e startup_32 +CC =gcc -march=i386 +CFLAGS =-w -g -fomit-frame-pointer -finline-functions \ + -nostdinc -fno-stack-protector -mcld -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 = sched.o system_call.o traps.o asm.o fork.o \ + panic.o printk.o vsprintf.o sys.o exit.o \ + signal.o mktime.o + +kernel.o: $(OBJS) + $(LD) -r -o kernel.o $(OBJS) + sync + +clean: + rm -f core *.o *.a tmp_make keyboard.s + for i in *.c;do rm -f `basename $$i .c`.s;done + (cd chr_drv; make clean) + (cd blk_drv; make clean) + (cd math; make clean) + +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 + (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/linux/kernel/asm.o b/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/linux/kernel/blk_drv/Makefile b/linux/kernel/blk_drv/Makefile new file mode 100644 index 0000000..1fb57f9 --- /dev/null +++ b/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/linux/kernel/blk_drv/blk.h b/linux/kernel/blk_drv/blk.h new file mode 100644 index 0000000..7a69b71 --- /dev/null +++ b/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/linux/kernel/blk_drv/blk_drv.a b/linux/kernel/blk_drv/blk_drv.a new file mode 100644 index 0000000000000000000000000000000000000000..9479e6f79caf09f3708135c9718675f393f499e3 GIT binary patch literal 52200 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 QA#xri@|uRoYZc=E10mD6iU0rr literal 0 HcmV?d00001 diff --git a/linux/kernel/blk_drv/floppy.c b/linux/kernel/blk_drv/floppy.c new file mode 100644 index 0000000..b1a7f3a --- /dev/null +++ b/linux/kernel/blk_drv/floppy.c @@ -0,0 +1,463 @@ +/* + * linux/kernel/floppy.c + * + * (C) 1991 Linus Torvalds + */ + +/* + * 02.12.91 - Changed to static variables to indicate need for reset + * and recalibrate. This makes some things easier (output_byte reset + * checking etc), and means less interrupt jumping in case of errors, + * so the code is hopefully easier to understand. + */ + +/* + * This file is certainly a mess. I've tried my best to get it working, + * but I don't like programming floppies, and I have only one anyway. + * Urgel. I should check for more errors, and do more graceful error + * recovery. Seems there are problems with several drives. I've tried to + * correct them. No promises. + */ + +/* + * As with hd.c, all routines within this file can (and will) be called + * by interrupts, so extreme caution is needed. A hardware interrupt + * handler may not sleep, or a kernel panic will happen. Thus I cannot + * call "floppy-on" directly, but have to set a special timer interrupt + * etc. + * + * Also, I'm not certain this works on more than 1 floppy. Bugs may + * abund. + */ + +#include +#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/linux/kernel/blk_drv/floppy.o b/linux/kernel/blk_drv/floppy.o new file mode 100644 index 0000000000000000000000000000000000000000..b4871a5df233fa5926607b6a5d161d3d293fb7e5 GIT binary patch literal 16608 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 Z75swW*93X)pgzwT#192CL2G{m{}&|+x&Z(H literal 0 HcmV?d00001 diff --git a/linux/kernel/blk_drv/hd.c b/linux/kernel/blk_drv/hd.c new file mode 100644 index 0000000..c0e908f --- /dev/null +++ b/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/linux/kernel/blk_drv/hd.o b/linux/kernel/blk_drv/hd.o new file mode 100644 index 0000000000000000000000000000000000000000..5ac5783d7fdc4d39f17d41386cc27f187ee31410 GIT binary patch literal 15516 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 literal 0 HcmV?d00001 diff --git a/linux/kernel/blk_drv/ll_rw_blk.c b/linux/kernel/blk_drv/ll_rw_blk.c new file mode 100644 index 0000000..f57d998 --- /dev/null +++ b/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 ; 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 J#}pn@_ + +#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/linux/kernel/blk_drv/ramdisk.o b/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/linux/kernel/chr_drv/Makefile b/linux/kernel/chr_drv/Makefile new file mode 100644 index 0000000..9d4d8d1 --- /dev/null +++ b/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/linux/kernel/chr_drv/chr_drv.a b/linux/kernel/chr_drv/chr_drv.a new file mode 100644 index 0000000000000000000000000000000000000000..c0ac46b3636637c2888f7bf2e53d0ed9f7fb2b78 GIT binary patch literal 68886 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 XTi9PPJYjgskXPDlpKIve1WErlmo5PG literal 0 HcmV?d00001 diff --git a/linux/kernel/chr_drv/console.c b/linux/kernel/chr_drv/console.c new file mode 100644 index 0000000..a12ffbf --- /dev/null +++ b/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/linux/kernel/chr_drv/console.o b/linux/kernel/chr_drv/console.o new file mode 100644 index 0000000000000000000000000000000000000000..201b995c8b2cfcd0b623e4c53db4d36891325e2e GIT binary patch literal 20892 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 literal 0 HcmV?d00001 diff --git a/linux/kernel/chr_drv/keyboard.2.o b/linux/kernel/chr_drv/keyboard.2.o new file mode 100644 index 0000000000000000000000000000000000000000..031174bedf6e5d505616ece4312873277e2a897e GIT binary patch literal 6024 zcmeI#e@vA39S88wa~u>bD0IWd5iG3IN(IWPxG|4bR1~PJf@9^R^fvbklw!D>pTL?RpQ+*Mn* zGU;48w;s8AWVm>EqS<*&@?`N8oR_q?$>S<71X zqpQhU;>c|B>|}qn{cv?^^rDvZp)vE_uF)a;tZgVgQf5p+v(a!e&zk68+i!oIV{VD0 z$qveBBu~6MYUVcNcSdg;yG52o2Y7R&Lo%_2xmI$m;#$r11+F_NiwEVgc?!jaWqm1K-D*hd(S5D({u2 zo>`smUelLS`%*>SH(d2qFYbJ!H;u}7ZQZuLvigM`U;FX_+P}MD%QrWFy~g?6^Pe}s zb8!Rkt)*2&Z!|XbzI6@kYn>>G%03Hi{=n zKXUF_qjl!{-1=kwC2jvN*YEN04?E`X9^#lGKA#Ef{{#35JIW98gVZwKZ#~y-aaHE~ zpK@!PTu5U{h;Lu z-jVMJ@d9TQ`L6iWBS;w8CMAn&iV>NADwp!>m>c9c*@q{~-y%e^TuaWsKBFwh_X^U* z{$vG_O`o@4M%+HqhxAu00g5$0k>AgYOi%*W(9Ev7UddzABgmu5aDbK|L?%*VdOk+hj*KDN>d z4HbHly*F2dR&##u{1sz`erfR-h1PQ19G91JET4sDQD_SX1y;&ES8?o%%Xe`s%Y|7K zYT!U#>1I(#R%Cgdm_?yh4&*0q7RBgGmJTcLKhzg9$6;@gp3|tHUe`^>ZLg zhglRl!ol*z3!u=qIUiemZWVf$b9vR6MKR_oONo`A=0KJgD?h`5EFD&Uj)S(i`~v5{ ziR=FZ&c7A6{a2jJC!kpr`Yi|Y8EEBluJ6R8h?$s}}N;$FGszVT5{zB>r%_uT9zzgsdDvtEV$;3}Fnn zr^Vgv@flqh?X97p-%lNSfLirXI2aPvQb=tH1~rLg6Q;u%qTn94Y-;0qklNvO8v!>O z${*|}rxNgVk})GA;t3migYK~EZ=;T2he`oohaM)cPnC0T33@_ax35D}Lm|CWBi>Wf zdg2<4Yhzx?aC@-Z9o9S=-;Z3b@^9qRP=3!gehIjcx4?k7j_5t)XW=j4NAUOXk8le9 z72bvkJf@7h1ZKcISOhn~=V2Xegzc~k?t@Wy6w1GtHeR%*kyr6UD&xNh8{jMORj9$Y z;CJ9ppu8KUpNsGkybQ0vYw!jfhm&vy&cS(j3ogJrP~k;F#!ZANFb!tFOt=DO!(5mL z^I;)$z!F#r%V0UIfK{*t*1~$|f=$o^Rp^5O*adai1AE~?7=`_C03LV2lHVebifi=3d>+QtbkRp2G+uQ=z>kq16AmQ0oVm~*aLgvK^TSoZ~z{K z$KY{z0-l7Y;2=B=&%m?rJiGu$;269JFTu<33cLnyz;QSUXW$&1hqvGYyaN^f<}&U- zOo3@I17^Y%FdOE=JeUs)p#zq{QdkDdVFj#$HLw=eLl" +# 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/linux/kernel/chr_drv/keyboard.S b/linux/kernel/chr_drv/keyboard.S new file mode 100644 index 0000000..25210b4 --- /dev/null +++ b/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/linux/kernel/chr_drv/rs_io.o b/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/linux/kernel/chr_drv/serial.o b/linux/kernel/chr_drv/serial.o new file mode 100644 index 0000000000000000000000000000000000000000..08791804f7d2c1e2d886e733b271b9853a625921 GIT binary patch literal 6748 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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/linux/kernel/chr_drv/tty_io.o b/linux/kernel/chr_drv/tty_io.o new file mode 100644 index 0000000000000000000000000000000000000000..649bc7813ba9c2ba657f367e157600043549baf1 GIT binary patch literal 22500 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 NtP8XgR +#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/linux/kernel/chr_drv/tty_ioctl.o b/linux/kernel/chr_drv/tty_ioctl.o new file mode 100644 index 0000000000000000000000000000000000000000..6d9237dada723dc47381236cfebe028c99834d58 GIT binary patch literal 10644 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 tv&ImRdz$Ank>@Uv=PB`k#z!>r+@k!X# +#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/linux/kernel/exit.o b/linux/kernel/exit.o new file mode 100644 index 0000000000000000000000000000000000000000..cbe7c24cbc0eaa9d0ea78c184eef47914af32877 GIT binary patch literal 11160 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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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 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/linux/kernel/math/math.a b/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/linux/kernel/math/math_emulate.o b/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/linux/kernel/mktime.o b/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/linux/kernel/panic.c b/linux/kernel/panic.c new file mode 100644 index 0000000..7d8a06b --- /dev/null +++ b/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/linux/kernel/panic.o b/linux/kernel/panic.o new file mode 100644 index 0000000000000000000000000000000000000000..8c9e7191b1c2d678c3dc637c3db2a206b7de8cbe GIT binary patch literal 5420 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 +#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/linux/kernel/printk.o b/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/linux/kernel/sched.c b/linux/kernel/sched.c new file mode 100644 index 0000000..15d839b --- /dev/null +++ b/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/linux/kernel/sched.o b/linux/kernel/sched.o new file mode 100644 index 0000000000000000000000000000000000000000..3e51d5111c02cd791639e6bbfcdfeddaadde6a1f GIT binary patch literal 23040 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

R)0H1E|O78N2>WD^Af%dRyyL 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 +#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/linux/kernel/signal.o b/linux/kernel/signal.o new file mode 100644 index 0000000000000000000000000000000000000000..e61cc198f58cc6060834a14d11ff0dcba193ad49 GIT binary patch literal 8956 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 u@H*k1%Q!y}3dnH7Wp literal 0 HcmV?d00001 diff --git a/linux/kernel/sys.c b/linux/kernel/sys.c new file mode 100644 index 0000000..7aa825f --- /dev/null +++ b/linux/kernel/sys.c @@ -0,0 +1,489 @@ +/* + * linux/kernel/sys.c + * + * (C) 1991 Linus Torvalds + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#define MAP_FAILED +//ADD FOR getcwd + +long sys_getcwd(char *buf,size_t size) +{ + int block=current->pwd->i_zone[0]; + int idev=current->pwd->i_dev; + int flag=0; + struct buffer_head * bh; + struct dir_entry * de; + struct m_inode *dir=current->pwd,*rdir=current->root; + if(dir==rdir) + { + flag=1; + goto mytag; + } + unsigned short curinode,finode,tempfi; + char name[128],base[128]; + int entries,i; + + if (!(block = current->pwd->i_zone[0])) + return NULL; + if (!(bh = bread(current->pwd->i_dev,block))) + return NULL; + de = (struct dir_entry *) bh->b_data; + curinode=de->inode; + de++; + finode=de->inode; + while (rdir!=dir) + { + //update father + dir=iget(idev,finode); + if (!(block = dir->i_zone[0])) + return NULL; + if (!(bh = bread(dir->i_dev,block))) + return NULL; + i = 0; + entries = dir->i_size / (sizeof (struct dir_entry)); + de = (struct dir_entry *) bh->b_data; + tempfi=(de+1)->inode; + 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(de->inode==curinode) + { + memset(base,'\0',sizeof(base)); + strcat(base,"/"); + strcat(base,de->name); + strcat(base,name); + strcpy(name,base); + break; + } + de++; + i++; + } + curinode=finode; + finode=tempfi; + } +mytag: + if(flag) strcpy(name,"/"); + size_t len=strlen(name); + if(sizefilp[fd]->f_inode; + int block,i,entries,sizdir=sizeof(struct dir_entry); + struct buffer_head * bh; + struct dir_entry * de; + struct linux_dirent *initmp,*temp; + if(!(temp=(struct linux_dirent *)malloc(count+64))) + return -1; + initmp=temp; + int size=sizeof(long)+sizeof(off_t)+sizeof(unsigned short); + + if (!(block = filenode->i_zone[0])) + return -1; + if (!(bh = bread(filenode->i_dev,block))) + return -1; + de = (struct dir_entry *) bh->b_data; + entries=filenode->i_size/(sizeof(struct dir_entry)); + i=0; + int nread=0,pos=0; + while(i= BLOCK_SIZE+bh->b_data) { + brelse(bh); + bh = NULL; + if (!(block = bmap(filenode,i/DIR_ENTRIES_PER_BLOCK)) || + !(bh = bread(filenode->i_dev,block))) { + i += DIR_ENTRIES_PER_BLOCK; + continue; + } + pos+=((char*) bh->b_data-(char*)(de)); + de = (struct dir_entry *) bh->b_data; + } + temp->d_ino=de->inode; + temp->d_off=pos; + strcpy(temp->d_name,de->name); + temp->d_reclen=sizeof(de); + nread+=temp->d_reclen; + temp=(struct linux_dirent*)((char*)temp+temp->d_reclen); + de++; + pos+=sizdir; + i++; + } + if(countsigaction[SIGALRM-1] = tmp; + current->alarm=(seconds>0)?(jiffies+HZ*seconds):0; + current->state=TASK_INTERRUPTIBLE; + current->counter=(current->counter>>1)+current->priority; + schedule(); + return 0; +} +long sys_mmap(void * start,size_t len, int prot,int flags,int fd,off_t off) +{ + if(!len || off<0 || !(off%PAGE_SIZE)) return MAP_FAILED; + void * buf=start; + if(start<=current->brk || start>=current->start_stack-0x8000 || start==NULL) + { + buf=current->brk+0x2000000; + } + if(!(prot& PROT_READ)) return MAP_FAILED; + //permissions of the file + struct m_inode *inode=current->filp[fd]->f_inode; + int mode = inode->i_mode; + 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 & prot & 0007) == prot) || suser()) + { + printk("error permission."); + return MAP_FAILED; + } + + + return MAP_FAILED; +} +int sys_munmap() +{ + + return -1; +} +int sys_clone() +{ + + return -1; +} + +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); +} diff --git a/linux/kernel/sys.o b/linux/kernel/sys.o new file mode 100644 index 0000000000000000000000000000000000000000..68d413cf0a65488548c3d6241ebb1bc222ba9008 GIT binary patch literal 18540 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 + +#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/linux/kernel/traps.o b/linux/kernel/traps.o new file mode 100644 index 0000000000000000000000000000000000000000..a7a72cc2319eef77fbf69f1ed66582325114b5ab GIT binary patch literal 12968 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 F{{z1=W#<3@ literal 0 HcmV?d00001 diff --git a/linux/kernel/vsprintf.c b/linux/kernel/vsprintf.c new file mode 100644 index 0000000..06b910e --- /dev/null +++ b/linux/kernel/vsprintf.c @@ -0,0 +1,233 @@ +/* + * linux/kernel/vsprintf.c + * + * (C) 1991 Linus Torvalds + */ + +/* vsprintf.c -- Lars Wirzenius & Linus Torvalds. */ +/* + * Wirzenius wrote this portably, Torvalds fucked it up :-) + */ + +#include +#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/linux/kernel/vsprintf.o b/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/linux/lib/_exit.c b/linux/lib/_exit.c new file mode 100644 index 0000000..c0c9d69 --- /dev/null +++ b/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/linux/lib/_exit.o b/linux/lib/_exit.o new file mode 100644 index 0000000000000000000000000000000000000000..0448d24f31c808c626f8782087f0ca1f3d0d1a1a GIT binary patch literal 1988 zcma)7&2QX96n|syCQCNmHVKGEsgNTTHI&$!&;^y!@|8dZRFNoDJ)kP}?mD{`u^ri7 zNGrsLxPUnIfVd!W>7T%%65J{waX=h6aY6hGoH@YnH=fxzCwS7#`@N5O@6Gef_>%M%F@$pO_t=8yz_t_U%h*__2qBBeEQzQ0#ZZU8|pT=TEeuV6$1B) zoW|@7kke@X1m-rHaaxMw%x+VuS`V~s_NJC*eh1SL)f|wHp}uYY3aI8TV0P{iE~qCv zOKrEa(pgZ8Gp8Ph{;agyFG7V32DT6>P%kaJolET(+UJ((`ts>-UR@SxHl@NZME#grc z4L$DM`gg}!5_Qwbu7b0Ww16tj z{Gtp8@B0UNRz`y|%a1A^jKf^^vvj0u=T>(I*)S5Vm#bS_m%Ozb{YhF*sw(_vCR*D3 zc(WI5^q#7;Y|W#bKxD9}J`ZWV9Qndl^g`hy8vYeNeZCd6g_%fV6I_*ND+iTDyV1L zIM{=_-xjX-dF@e6*6%apXH7}FqPWvrV`UUoBllRRxV~MpQsxei$Q5?*h+LVUMqm#X*)97>SMRs3 zK%r;zuq!l)eJ6j+aQsq4VOy)@IB;u5-!=S-;oFA4W%zZ&`SW8uo?pfp8=3EgYF6Kd N`lpTE1IPbG{sjn%%bNfI literal 0 HcmV?d00001 diff --git a/linux/lib/close.c b/linux/lib/close.c new file mode 100644 index 0000000..afd8364 --- /dev/null +++ b/linux/lib/close.c @@ -0,0 +1,10 @@ +/* + * linux/lib/close.c + * + * (C) 1991 Linus Torvalds + */ + +#define __LIBRARY__ +#include + +_syscall1(int,close,int,fd) diff --git a/linux/lib/close.o b/linux/lib/close.o new file mode 100644 index 0000000000000000000000000000000000000000..53b8b469c0a1e8ba52c54787adb158b024ebf131 GIT binary patch literal 2220 zcma)7&2Jl35TCcZ{%D*UCn*psNEj& zeti1%SA-CxNsvhsMD&xHd0J8|(E*yFH@5HBZWm$Ld2@08+P!bDUOTloy}h+KO`F9X zsK3;h|M|l$o^$&FX!~yMojacaS!^Opyaz760eg%w=!Hy>VU<`jtipZ>(<=BuLWWT~ z%|=oFTKY=gOH}+3!g>TuOdSSi;ymK!4tSy0Rd(YB6~AKp)HC45jf6^Xv+|vsBxc0H z>RiRFE>vg4Y_awzJd0GRybKdopwu!dIpSE|tRAVnSb4I3c8-IO&+neBi#Zf4kXdHW z**RmLsMw+`FoUHDJXU|Hj@rC!14DO&HQfT%<@)G3XhQr|-48C$2qz;Pr|AcsVcPYG zI>RvboDR=O13yl>&LBIzf=q7i6R)C`qF6=`Eu;6lQ9!0Ni2Z)xbsOB;VHotKB2!Uw z5RSZNkam-17&nK0kZ#(`&dQ2Cblc74%mCh|co0TOV^1nCih_{NoV(CiYqXqIr`51W zZqykZ^$)K;->~})yBCi9#O_7z$g?*>l=mVS{Qz}5yO#!?#1DfQrXaNA#O++PH=;1{ zI!PGO`g-KW*ri%~XW&NT?Z^HVFS)$ok+jm8wY4LSr3>veNYZR2_Oq!(D<7@2oaNS` z%*t&$zzig=oF}nW77Nps^(orS2ejwEd7@h0HrA^1m#XCxcd8aS@#RtCwjq-!lLM_q z-q1t09Q8f;vb_owUP!tTkpiv;h&rb*{>VaVsZi6oqd z^G#vse3zi}9Nst69{@i~Eo1ECv8AMryNAc&sVqct9ruZf)2@HA7fQqN+P_e7V>b?P zbsUwgkKyMS`F(tu+s8xj>3z&V*Z%>iv7X9`>+ga}YDl*PjV9eDgWXgYB9?S3A*kH;N9Yf6Llbw)B z(-Q#ABz%l=WD<99LMA$(d(C%u7TwB6a9_snW%kx*?={SaFa*-`{TEP9KaJSah6NU-c<6alBbk>O-Xr=F#j!uU6#o6p~Badl=X2@d9Ca}sbmAv0R9)` CulFDT literal 0 HcmV?d00001 diff --git a/linux/lib/ctype.c b/linux/lib/ctype.c new file mode 100644 index 0000000..877e629 --- /dev/null +++ b/linux/lib/ctype.c @@ -0,0 +1,35 @@ +/* + * linux/lib/ctype.c + * + * (C) 1991 Linus Torvalds + */ + +#include + +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/linux/lib/ctype.o b/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/linux/lib/dup.o b/linux/lib/dup.o new file mode 100644 index 0000000000000000000000000000000000000000..191ad6f7d96e3f7c25d20f49e1d25ae9cd944d03 GIT binary patch literal 2196 zcma)7O>7%g5T3WY{%M>VCk7EKNEj&<33S&9wIC`jO-Z3DpjIk`1015Yy|!14chmiW zv@19a%X#PlD3Mw z5Pz@n{MX%^yyn&;(9RFF_iuj*WU-1Yv4&Y3##CnvdMRUMSS6MWtMEOTX%+k+A;T!0 zV5KO3CvBylBr4tkvwGKL$4So_W@lHBq0K|$4Kz{|%jlqG^#3plh?54fKM1^DlN+0@Zw+@W|FMoIHP1TTt$kj|c8Ypyoi&a%^P+9NmW4o~{W zmS1ezgQndNM}A`WBX{K4n<27#5tM#_Jf7W8gKpx7K@3$8+HvA`FWH+>n0VbJjA(s5 z@?vaGmE0Y=5p9IQKo%eSSH0xQrbkjuXIEE`H|N(nX^^B@DfSDgL`xqpwVlQGLZ&5r z!x@RI7fEcF#q6YIeSy~Uq3~dmhjF@E-Z56IGncF7)3>V@Iq{WI;&#B3DC0vdMc#&! zcv}fMJvVX5>BKQPtn7K6bg=FR{SYQ8yPZzteUP`hksA!K(cA*=j$VKqxsKS(-`c-7n<=A zh1GLGmw@x6<2?^0`~R08*Q3{P9FDigf+B5O1kTs@59-^3j_WI6==xS5>opMZmf+H` zph(*;0&AH~9|AO4P^4|=f%AD2Y^nww=jHwBytt$X;_V^8d(dgp@mwhK@jgQkj>GXL zFm$}jka-R7o9O|--At4-+jwj%uKj+*lklAM$R_Rgx$@JdKeJa!!~NR7R({(25W@1l zS5_axuQ2laxSrd`W3cIcOhMM)07Ne6aVy@#Yf$KR6!uopa{n z{f6&=b7<1>G}b(?x9Gtmt!IAlPsli*fiY(vlPSNrJeL2meT6AcbRS|ppX``Snj8a2 zCgBH^Ba^s;V=~bJoq_M}G`dw8n`K|r6VE@%?5T!*0Ye}(-+h6JvkEkj`^EeT#ra1i w(EMkZ;~eLezNPp{#m^}IrsDDrA&$!!>pxQZ>x#>~xSV`$Y+q5l32p%Y3$$zWmjD0& literal 0 HcmV?d00001 diff --git a/linux/lib/errno.c b/linux/lib/errno.c new file mode 100644 index 0000000..50aca2e --- /dev/null +++ b/linux/lib/errno.c @@ -0,0 +1,7 @@ +/* + * linux/lib/errno.c + * + * (C) 1991 Linus Torvalds + */ + +int errno; diff --git a/linux/lib/errno.o b/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/linux/lib/execve.o b/linux/lib/execve.o new file mode 100644 index 0000000000000000000000000000000000000000..acc081243ed081e41353b132934f9182d6227b31 GIT binary patch literal 2336 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 ; 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 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; +} + +int do_execve2(unsigned long * eip,long tmp,char * filename, + char ** argv, char ** envp) +{ + int ans=0; + if((ans=do_execve(eip,tmp,filename,argv,envp))) + return ans; + int nr[4]; + unsigned long temp; + unsigned long page; + int block,i; + unsigned long address=current->start_code; + //this part comes from do_no_page as achievement of immediate loading of cs and ds + while(address<=current->brk+current->start_code) + { + address &= 0xfffff000; + temp = address - current->start_code; + if (share_page(temp)) + return -1; + if (!(page = get_free_page())) + oom(); + block = 1 + temp/BLOCK_SIZE; + for (i=0 ; i<4 ; block++,i++) + nr[i] = bmap(current->executable,block); + bread_page(page,current->executable->i_dev,nr); + if (!put_page(page,address)) + { + free_page(page); + oom(); + } + address+=PAGE_SIZE; + } + return 0; +} +void calc_mem(void) +{ + int i,j,k,free=0; + long * pg_tbl; + + for(i=0 ; i + +#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; + + 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; +} +int do_execve2(unsigned long * eip,long tmp,char * filename, + char ** argv, char ** envp) +{ + int ans=0; + if(!(ans=do_execve(eip,tmp,filename,argv,envp))) + return ans; + int nr[4]; + unsigned long temp; + unsigned long page; + int block,i; + unsigned long address=current->start_code; + while(address<=current->brk) + { + address &= 0xfffff000; + temp = address - current->start_code; + if (share_page(temp)) + return; + if (!(page = get_free_page())) + oom(); + block = 1 + temp/BLOCK_SIZE; + for (i=0 ; i<4 ; block++,i++) + nr[i] = bmap(current->executable,block); + bread_page(page,current->executable->i_dev,nr); + if (!put_page(page,address)) + { + free_page(page); + oom(); + return -1; + } + address+=PAGE_SIZE; + } + return 0; +} +void calc_mem(void) +{ + int i,j,k,free=0; + long * pg_tbl; + + for(i=0 ; iHht(;n*IOJ{qAJIc7MC~ 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 literal 0 HcmV?d00001 diff --git a/linux/mm/mm.o b/linux/mm/mm.o new file mode 100644 index 0000000000000000000000000000000000000000..2b72085e5156eb46aac1869ee5c40fdd8e4e63d2 GIT binary patch literal 14089 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 Zl#74j-0u_Tt)1+wc9Dm!rxhQ*{4YErJuUzM literal 0 HcmV?d00001 diff --git a/linux/mm/page.o b/linux/mm/page.o new file mode 100644 index 0000000000000000000000000000000000000000..da4852668a6d8b88d91c428ae8572bb3d4d2090d GIT binary patch literal 640 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 N^|Cbi(V*L${{d;jp)>#h literal 0 HcmV?d00001 diff --git a/linux/tools/build.c b/linux/tools/build.c new file mode 100644 index 0000000..8b8c7ab --- /dev/null +++ b/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/linux/tools/system b/linux/tools/system new file mode 100644 index 0000000000000000000000000000000000000000..962aa7a98c24e35a79ecbfb8f810279fc652bedd GIT binary patch literal 294247 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�aSZqa&1FyF@o5`2sZ7VYi9Cu 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 literal 0 HcmV?d00001 diff --git a/linux_lab_os_exp2 b/linux_lab_os_exp2 deleted file mode 160000 index 757ebd7..0000000 --- a/linux_lab_os_exp2 +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 757ebd74db03ae6cd3e805ca049ad90d1525fb9c